背景
当前产品硬件:STM32F429IGT6( 内部ROM:1MB)+norflash(16MB)+sdram(32MB)+其他外围(RGB565\UART\SPI\IIC\等等)。操作系统为RTT,之前产品都是基于RTT开发的。
由于STM32F429价格太高,使用 i.MX RT1052 作为替代芯片。不仅仅是替换后续的产品,之前的产品硬件也要替换掉。
在ST上,0-128K作为bootloader区域,128K-1024K作为APP区域,FOTA大概过程:
- APP从服务器下载固件,保存到norflash,检验 MD5
- 重启设备
- bootloader 发现有新固件,解密,校验MD5,校验HASH等,检验通过则刷APP区域并跳入;检验不通过则删除固件,直接跳入APP
实施过程
1、跳转功能调试
先了解了1052的存储结构,了解了FDBC\DCD等,完成了跳转功能:
镜像结构:
通过修改编译链接文件,使bootloader和app镜像按照如上分部。目前已完成了从bootloader 跳转到app,app目前运行正常
\ | /- RT - Thread Operating System/ | \ 4.1.0 build May 27 2022 18:12:442006 - 2022 Copyright by RT-Thread teamHere is boot.[I/main]Firmware Download Complete,Jump App.\ | /- RT - Thread Operating System/ | \ 4.1.0 build May 29 2022 20:51:392006 - 2022 Copyright by RT-Thread teammsh >This's appThis's appThis's appThis's app
但是这是分两个工程分别用调试器下载进去的,仅仅验证了跳转功能。
2、操作norflash
方案1
开机就将系统加载到sdram中运行,这样操作用与XIP的norflash也不会影响到系统运行
修改了链接脚本(keil MDK ARMCC):
#define m_flash_config_start 0x60000000#define m_flash_config_size 0x00001000#define m_ivt_start 0x60001000#define m_ivt_size 0x00001000#define m_interrupts_start 0x60002000#define m_interrupts_size 0x00000400#define m_text_start 0x60002400#define m_text_size 0x03FFDC00;在SDRAM中存放代码的空间;中断向量表#define m_sdram_interrupts_start 0x80000000#define m_sdram_interrupts_size 0x00000400;SDRAM中的主体代码#define m_sdram_text_start 0x80000400#define m_sdram_text_size 0x003FFC00#define m_data_start 0x80400000#define m_data_size 0x01A00000#define m_ncache_start 0x81E00000#define m_ncache_size 0x00200000#define m_data2_start 0x20000000#define m_data2_size 0x00020000#define m_data3_start 0x20200000#define m_data3_size 0x00040000/* Sizes */#if (defined(__stack_size__))#define Stack_Size __stack_size__#else#define Stack_Size 0x0400#endif#if (defined(__heap_size__))#define Heap_Size __heap_size__#else#define Heap_Size 0x0400#endifLR_m_rom_config m_flash_config_start m_flash_config_size { ; load region size_regionRW_m_config_text m_flash_config_start m_flash_config_size { ; load address = execution address* (.boot_hdr.conf, +FIRST)}}LR_m_rom_ivt m_ivt_start m_ivt_size { ; load region size_regionRW_m_ivt_text m_ivt_start m_ivt_size { ; load address = execution address* (.boot_hdr.ivt, +FIRST)* (.boot_hdr.boot_data)* (.boot_hdr.dcd_data)}}LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_size { ; load region size_region; 在FALSH中的中断向量表VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address* (RESET,+FIRST)}; * (InRoot$$Sections)是__main中从加载域复制代码到执行域的程序scatter_copy,; 启动时运行的startup_mimxrt1052t和system_mimxrt1052中的代码要存放在FLASH中ER_m_text m_text_start m_text_size { ; load address = execution address* (InRoot$$Sections)startup_mimxrt1052.o(+RO)system_mimxrt1052.o(+RO)}; EMPTY表示这段空间留空,防止其它应用占用或编译提示warningVECTOR_RAM m_sdram_interrupts_start EMPTY m_sdram_interrupts_size { ;execution address;这部分内容由board.c文件中的CopyAndUseRAMVectorTable函数从VECTOR_ROM中复制得到;得到SDRAM版本的中断向量表};存放主体程序的SDRAM空间,由__main函数从FLASH中加载ER_m_ram_text m_sdram_text_start m_sdram_text_size { ;execution address.ANY (+RO)}RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data.ANY (+RW +ZI)*(m_usb_dma_init_data)*(m_usb_dma_noninit_data)}ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up}ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down}RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data* (NonCacheable.init)* (NonCacheable)}}
借鉴了野火开发板的例程,开机后__main中从加载域复制代码到执行域的程序scatter_copy,
