1. 首先启用 Flash模式.
a)确认 stm32f7xx_hal_conf.h 中 启用了 #define HAL_FLASH_MODULE_ENABLED
b)在 Drivers/STM32F7xx_HAL_Drivers中确认添加了源码 stm32f7xx_hal_cortex/flash/flash_ex.c 三个文件.
2. 对flash进行分区.
512K 共 8个扇区. 擦除的时候只能根据删除擦除. /* Base address of the Flash sectors Bank 1 */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */ #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */ #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */ #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */ #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */ #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */ 我们的要求. l 我们自己的 bootloader. <16K l 信息区. <16K. l 程序区. 自己的程序 < 64K. l OTA升级区. < 64K. 所以设定 #define NDADDR_BOOT ADDR_FLASH_SECTOR_0 //SECTOR_0 16K #define NDADDR_INFO ADDR_FLASH_SECTOR_1 //SECTOR_1 16K #define NDADDR_FW_APP ADDR_FLASH_SECTOR_5 //SECTOR_5 128K #define NDADDR_FW_OTA ADDR_FLASH_SECTOR_6 //SECTOR_6 128K #define FW_MAX_SIZE ((uint32_t)0x00020000) //固件最大 128K |
3. Flash 操作代码
#ifndef _FIRMWARE_OTA_CONF_INC_H_ #define _FIRMWARE_OTA_CONF_INC_H_ #include #include /* Exported types ------------------------------------------------------------*/ typedef void (*pFunction)(void); /* Base address of the Flash sectors Bank 1 */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */ #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */ #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */ #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */ #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */ #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */ #if 0 #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */ #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */ #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */ #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */ /* Base address of the Flash sectors Bank 2 */ #define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */ #define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */ #define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */ #define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */ #define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */ #define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */ #define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes */ #define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes */ #define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */ #define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */ #endif #define NDADDR_BOOT ADDR_FLASH_SECTOR_0 //SECTOR_0 16K #define NDADDR_INFO ADDR_FLASH_SECTOR_1 //SECTOR_1 16K #define NDADDR_FW_APP ADDR_FLASH_SECTOR_5 //SECTOR_5 128K #define NDADDR_FW_OTA ADDR_FLASH_SECTOR_6 //SECTOR_6 128K #define FW_MAX_SIZE ((uint32_t)0x00020000) //固件最大 128K #define FW_PAGE_SIZE ((uint32_t)0x00000800) //写入的单位 2K. /* * 固件升级步骤. * 确定当前的 FW的位置是那个, FW1/FW2, 确定完毕后就知道要写那个. * YMODEM 获取满 2K 数据. FMC_FLASH_PAGE_SIZE, 然后写入一个页中. * 最后改写配置, 引导的 APROM 起始地址. */ void nd_FlashUnlock(void); void nd_FlashLock(void); bool ota_EraseSector(void); bool app_EraseSector(void); bool config_EraseSector(void); bool nd_flash_write(uint32_t Address, uint8_t *pData, uint32_t size); void nd_flash_read(uint32_t Address, uint8_t *pData, uint32_t size); /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /* 出厂设置内容. 保证4字节对齐. */ typedef struct { uint32_t fw_addr; //最新有效的固件的flash地址. uint32_t page_cnt; //最新有效的固件的页数 (2K计数) uint64_t sn; }nd_ota_config_t; extern nd_ota_config_t g_ota_conf ; void load_factory_config(void); void save_factory_config(void); #endif //_FIRMWARE_OTA_CONF_INC_H_ |
Flash部分的封装 实现
#include 'main.h' #include 'fw_ota.h' void NVIC_SetVectorTable(uint32_t ApplicationFlashAddress) { SCB->VTOR = ApplicationFlashAddress; } //Unlocks the Flash to enable the flash control register access. void nd_FlashUnlock(void) { HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR); } void nd_FlashLock(void) { HAL_FLASH_Lock(); } /*对指定地址上写入4字节数据. Address + data 必须 4字节对齐. 写完之后下次写入的 Address 和 data 都要+4. * @retval true: Data successfully written to Flash memory * false: Error occurred while writing data in Flash memory */ static bool flash_Write_Word(uint32_t Address, uint32_t *Data) { return (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, *Data)); } static bool flash_Write_HalfWord(uint32_t Address, uint16_t *Data) { return (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, *Data)); } bool nd_flash_write(uint32_t Address, uint8_t *pData, uint32_t size) { if ((size % 4) != 0) return false; uint32_t nbWrites = size / 4; uint32_t idx;
for (idx = 0; idx < nbWrites; idx++) { if (false == flash_Write_Word(Address, (uint32_t *)pData)) return false; pData+=4; Address+=4; } return true; } //读 不需要做 unlock. void nd_flash_read(uint32_t Address, uint8_t *pData, uint32_t size) { uint32_t idx; for (idx = 0; idx < size; idx++) { *pData = *(__IO uint8_t *)Address; pData++; Address++; } } /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// 关键字:STM32 IAP 引用地址:STM32 IAP example
上一篇:Stm32空指令使用
小广播
推荐内容
热门活动
换一批 更多
设计资源 培训 开发板 精华推荐
最新单片机文章
更多开源项目推荐
更多精选电路图
更多热门文章
更多每日新闻
更多往期活动
11月13日历史上的今天
厂商技术中心
|