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

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

相关推荐
宁静致远202114 小时前
stm32 freertos下基于hal库的模拟I2C驱动实现
stm32·嵌入式硬件·freertos
Wave84518 小时前
STM32--智能小车
stm32·单片机·嵌入式硬件
wdfk_prog21 小时前
[Linux]学习笔记系列 -- lib/timerqueue.c Timer Queue Management 高精度定时器的有序数据结构
linux·c语言·数据结构·笔记·单片机·学习·安全
充哥单片机设计1 天前
【STM32项目开源】基于STM32的智能家居环境(空气质量)检测系统
stm32·单片机·嵌入式硬件
夜月yeyue1 天前
ART 加速器、流水线与指令预测的关系详解
linux·服务器·c语言·单片机·嵌入式硬件·性能优化·嵌入式高阶技巧
糖糖单片机设计1 天前
硬件开发_基于物联网的生态环境检测系统
stm32·单片机·嵌入式硬件·物联网·51单片机
A9better1 天前
嵌入式开发学习日志35——stm32之超声波测距
stm32·单片机·嵌入式硬件·学习
Janspran1 天前
监控系统1 - 项目框架 | 线程邮箱
网络·单片机·嵌入式硬件·硬件架构
常州晟凯电子科技1 天前
海思Hi3516CV610/Hi3516CV608开发笔记之环境搭建和SDK编译
人工智能·笔记·嵌入式硬件·物联网
qq_397562311 天前
STC8H8K64,使用0.96寸oled屏幕. 进行硬件iic和硬件spi驱动(spi开启DMA)---(代码)
单片机·嵌入式硬件