上位机图像处理和嵌入式模块部署(f407 mcu内部flash编程)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

对于f407这样的mcu来说,有的时候我们需要对mcu内部的flash进行编程处理。有两种情况需要对flash进行编程,一种情况是可能一部分参数需要放在了flash上面;还有一种情况,就是我们需要对mcu的固件进行升级,同时又不太希望暴露swd接口。这种状况下,一般就是先启动bootloader,然后利用bootloader对固件进行升级处理。

1、flash编程的注意事项

需要注意的地方,主要就是flash的起始地址和范围,其他的按部就班去做就好了。

2、测试代码

我们测试的时候,把flash当成是一般的nor flash就可以了。也就是说,如果需要对这部分flash进行编程的话,首先需要erase处理,然后进行编程,最后下读取相关区域的数据,确认下是否正确。

复制代码
int InternalFlash_Test(void)
{
	uint32_t uwStartSector = 0;
	uint32_t uwEndSector = 0;
	
	uint32_t uwAddress = 0;
	uint32_t uwSectorCounter = 0;

	__IO uint32_t uwData32 = 0;
	__IO uint32_t uwMemoryProgramStatus = 0;
	
    FLASH_Unlock(); 
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 
                  FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); 


	uwStartSector = GetSector(FLASH_USER_START_ADDR);
	uwEndSector = GetSector(FLASH_USER_END_ADDR);
    uwSectorCounter = uwStartSector;
    while (uwSectorCounter <= uwEndSector) 
    {
      if (FLASH_EraseSector(uwSectorCounter, VoltageRange_3) != FLASH_COMPLETE)
      { 
			return -1;
      }

      if (uwSectorCounter == FLASH_Sector_11)
      {
            uwSectorCounter += 40;
      } 
      else 
      {
            uwSectorCounter += 8;
      }
    }

    uwAddress = FLASH_USER_START_ADDR;
    while (uwAddress < FLASH_USER_END_ADDR)
    {
      if (FLASH_ProgramWord(uwAddress, DATA_32) == FLASH_COMPLETE)
      {
            uwAddress = uwAddress + 4;
      }
      else
      { 
		    return -1;
      }
    }
	
    FLASH_Lock(); 

    uwAddress = FLASH_USER_START_ADDR;
    uwMemoryProgramStatus = 0; 
    while (uwAddress < FLASH_USER_END_ADDR)
    {
         uwData32 = *(__IO uint32_t*)uwAddress;

         if (uwData32 != DATA_32)
         {
             uwMemoryProgramStatus++;  
         }

         uwAddress = uwAddress + 4;
    }  

    if(uwMemoryProgramStatus)
    {    
		return -1;
    }
    else
    { 
		return 0;   
    }
}

这中间比较奇怪的地方,就是uwSectorCounter递增的方法,看上去很奇怪。也就是说sector的number不是按照1来递增处理的,而是其他方式。从代码上看,sector11和sector12之间的间距是40,在这之前、之后都是8。另外,大家还需要记住这几个函数,

复制代码
FLASH_Unlock
FLASH_ClearFlag
FLASH_EraseSector
FLASH_ProgramWord
FLASH_Lock

读取数据的话,就直接地址访问即可,不需要函数的操作。

3、地址到sector的转化

我们编写代码的时候,还需要实现一个函数,那就是地址到sector number的转换。这边基本上直接用的映射的办法来完成的。

复制代码
static uint32_t GetSector(uint32_t Address)
{
  uint32_t sector = 0;
  
  if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  {
    sector = FLASH_Sector_0;  
  }
  else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  {
    sector = FLASH_Sector_1;  
  }
  else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  {
    sector = FLASH_Sector_2;  
  }
  else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  {
    sector = FLASH_Sector_3;  
  }
  else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  {
    sector = FLASH_Sector_4;  
  }
  else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  {
    sector = FLASH_Sector_5;  
  }
  else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  {
    sector = FLASH_Sector_6;  
  }
  else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  {
    sector = FLASH_Sector_7;  
  }
  else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  {
    sector = FLASH_Sector_8;  
  }
  else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  {
    sector = FLASH_Sector_9;  
  }
  else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  {
    sector = FLASH_Sector_10;  
  }
  else /*if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11))*/
  {
    sector = FLASH_Sector_11;  
  }
  return sector;
}

从代码上也可以看出来,这里只是考虑了 sector11之前的情况。

4、测试和实验

测试相对而言,测试还是比较简单的。不管测试结果如何,直接通过串口打印出来就可以了。

相关推荐
菥蓂寻生16 小时前
STM32移植到GD32中以105为例
stm32·单片机·嵌入式硬件
橘为己有4411 天前
51单片机:定时/计数器
单片机·51单片机
杯子不吃紫菜1 天前
LangGraph 体系实战(下):中断恢复、流式、子图与设计模式
单片机·嵌入式硬件·设计模式
qq_448011161 天前
中断服务函数简介
嵌入式硬件
Risehuxyc1 天前
STM32程序逻辑---入口函数逻辑和NVIC嵌套向量中断控制器初始化
stm32·单片机·嵌入式硬件
【 STM32开发 】1 天前
CubeMX+STM32】SD卡U盘实现__USB+FATFS (F103 篇)
stm32·单片机·嵌入式硬件
jianqiang.xue1 天前
3倍向量算力:Arm给最小MCU装上本地AI
arm开发·人工智能·单片机
无敌最俊朗-2 天前
【电感专题2:电感的感抗、电路的阻抗、电流的滞后】
单片机·嵌入式硬件·元器件·电感
wuyk5552 天前
嵌入式故障诊断-Bug002-局部大数组压栈高温必死机
stm32·单片机·嵌入式硬件·mcu·物联网·51单片机·嵌入式实时数据库
Zwawa2 天前
嵌入式OLED表驱动菜单:用一张表、一个栈和一个窗口重写表驱动菜单
c语言·单片机·嵌入式