上位机图像处理和嵌入式模块部署(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、测试和实验

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

相关推荐
sramdram1 天前
基于MCU微控制器的电子血压计应用解决方案
单片机·嵌入式硬件·mcu·mcu微控制器
Szime1 天前
AD9218 国产替代方向:双通道 10 位 105MSPS ADC 选型支持
单片机·嵌入式硬件·fpga开发·汽车
凡人叶枫1 天前
Effective C++ 条款15:在资源管理类中提供对原始资源的访问
linux·开发语言·c++·stm32·单片机
数智工坊1 天前
机器人控制总线深度解析:CAN与EtherCAT,谁在决定机器人的稳定性?
嵌入式硬件·学习·机器人
张海森-1688201 天前
库里搜索函数 api接口__grep命令
单片机
mmmayang1 天前
从简单的 CC 显示器入门嵌入式
嵌入式硬件·计算机外设
xxwxx__1 天前
51单片机定时器/计数器中断详解(T0和T1)——从入门到精通
c语言·单片机·嵌入式硬件·51单片机
飞猿_SIR1 天前
RK3288 Android11平台移植RTL8733BU-WiFi模组
android·嵌入式硬件
国产化创客1 天前
嵌入式视觉完整技术体系--ESP32/K230/RDK-X5/树莓派四层架构全解析
嵌入式硬件·物联网·架构·开源·智能硬件
cft56200_ln1 天前
TDA4时间同步3 网卡添加虚拟时间戳
c语言·开发语言·arm开发·驱动开发·嵌入式硬件·网络协议