背景

当前产品硬件: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

目前需要在1052上也实现此类功能。

实施过程

1、跳转功能调试

先了解了1052的存储结构,了解了FDBC\DCD等,完成了跳转功能:
镜像结构:
关于i.MX RT1052 的技术咨询2 - 图1
通过修改编译链接文件,使bootloader和app镜像按照如上分部。目前已完成了从bootloader 跳转到app,app目前运行正常

  1. \ | /
  2. - RT - Thread Operating System
  3. / | \ 4.1.0 build May 27 2022 18:12:44
  4. 2006 - 2022 Copyright by RT-Thread team
  5. Here is boot.[I/main]
  6. Firmware Download Complete,Jump App.
  7. \ | /
  8. - RT - Thread Operating System
  9. / | \ 4.1.0 build May 29 2022 20:51:39
  10. 2006 - 2022 Copyright by RT-Thread team
  11. msh >This's app
  12. This's app
  13. This's app
  14. This's app

但是这是分两个工程分别用调试器下载进去的,仅仅验证了跳转功能。

2、操作norflash

方案1

开机就将系统加载到sdram中运行,这样操作用与XIP的norflash也不会影响到系统运行
修改了链接脚本(keil MDK ARMCC):

  1. #define m_flash_config_start 0x60000000
  2. #define m_flash_config_size 0x00001000
  3. #define m_ivt_start 0x60001000
  4. #define m_ivt_size 0x00001000
  5. #define m_interrupts_start 0x60002000
  6. #define m_interrupts_size 0x00000400
  7. #define m_text_start 0x60002400
  8. #define m_text_size 0x03FFDC00
  9. ;在SDRAM中存放代码的空间
  10. ;中断向量表
  11. #define m_sdram_interrupts_start 0x80000000
  12. #define m_sdram_interrupts_size 0x00000400
  13. ;SDRAM中的主体代码
  14. #define m_sdram_text_start 0x80000400
  15. #define m_sdram_text_size 0x003FFC00
  16. #define m_data_start 0x80400000
  17. #define m_data_size 0x01A00000
  18. #define m_ncache_start 0x81E00000
  19. #define m_ncache_size 0x00200000
  20. #define m_data2_start 0x20000000
  21. #define m_data2_size 0x00020000
  22. #define m_data3_start 0x20200000
  23. #define m_data3_size 0x00040000
  24. /* Sizes */
  25. #if (defined(__stack_size__))
  26. #define Stack_Size __stack_size__
  27. #else
  28. #define Stack_Size 0x0400
  29. #endif
  30. #if (defined(__heap_size__))
  31. #define Heap_Size __heap_size__
  32. #else
  33. #define Heap_Size 0x0400
  34. #endif
  35. LR_m_rom_config m_flash_config_start m_flash_config_size { ; load region size_region
  36. RW_m_config_text m_flash_config_start m_flash_config_size { ; load address = execution address
  37. * (.boot_hdr.conf, +FIRST)
  38. }
  39. }
  40. LR_m_rom_ivt m_ivt_start m_ivt_size { ; load region size_region
  41. RW_m_ivt_text m_ivt_start m_ivt_size { ; load address = execution address
  42. * (.boot_hdr.ivt, +FIRST)
  43. * (.boot_hdr.boot_data)
  44. * (.boot_hdr.dcd_data)
  45. }
  46. }
  47. LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_size { ; load region size_region
  48. ; FALSH中的中断向量表
  49. VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
  50. * (RESET,+FIRST)
  51. }
  52. ; * (InRoot$$Sections)是__main中从加载域复制代码到执行域的程序scatter_copy
  53. ; 启动时运行的startup_mimxrt1052tsystem_mimxrt1052中的代码要存放在FLASH
  54. ER_m_text m_text_start m_text_size { ; load address = execution address
  55. * (InRoot$$Sections)
  56. startup_mimxrt1052.o(+RO)
  57. system_mimxrt1052.o(+RO)
  58. }
  59. ; EMPTY表示这段空间留空,防止其它应用占用或编译提示warning
  60. VECTOR_RAM m_sdram_interrupts_start EMPTY m_sdram_interrupts_size { ;execution address
  61. ;这部分内容由board.c文件中的CopyAndUseRAMVectorTable函数从VECTOR_ROM中复制得到
  62. ;得到SDRAM版本的中断向量表
  63. }
  64. ;存放主体程序的SDRAM空间,由__main函数从FLASH中加载
  65. ER_m_ram_text m_sdram_text_start m_sdram_text_size { ;execution address
  66. .ANY (+RO)
  67. }
  68. RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
  69. .ANY (+RW +ZI)
  70. *(m_usb_dma_init_data)
  71. *(m_usb_dma_noninit_data)
  72. }
  73. ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up
  74. }
  75. ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
  76. }
  77. RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data
  78. * (NonCacheable.init)
  79. * (NonCacheable)
  80. }
  81. }

借鉴了野火开发板的例程,开机后__main中从加载域复制代码到执行域的程序scatter_copy,