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

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

相关推荐
blessing。。33 分钟前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
嵌新程2 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin2012302 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)2 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII2 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件
美式小田5 小时前
单片机学习笔记 9. 8×8LED点阵屏
笔记·单片机·嵌入式硬件·学习
兰_博5 小时前
51单片机-独立按键与数码管联动
单片机·嵌入式硬件·51单片机
时光の尘6 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
嵌入式大圣8 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv
日晨难再9 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件