硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0
1 预备知识
2 Bootloader
- 2.1 启动流程
- 2.2 校验跳转地址是否有效
- 2.3 Keil 工程 IAP 的相关设置
3 Application
- 3.1 启动流程
- 3.2 IAP 中的引导部分
- 3.3 关于 VTOR
- 3.4 Keil 工程设置
4 附件
1 预备知识
基于标准外设库(STM32F10x_StdPeriph_Lib_V3.5.0)的 IAP 升级相关资料可以参考 IAP ST 官方资料汇总。
STM32 升级的三种方式:IAP,ICP,ISP;具体有什么区别可以自行 Google;
本文需要实现 STM32 的 Bootloader(后面 Bootloader/IAP 不加以区分),文件传输基于 ymodem 协议通过串口进行传输,这里参考了 ST 官方的 DEMO —— STM32F10xxx in-application programming using the USART AN2557,在此基础上做了部分修改,增加了延时启动的功能,最终可以实现想要的效果。
整体架构分为两个部分;Bootloader 和 Application,具体如下图所示;
由上图可知,STM32 内置的 Flash 被分成了两个部分,分别用来保存 Bootloader 和 Application 程序,这里有两个有两个 FLASH 起始地址 0x8000000 和 0x8003000;
为什么是 0x8000000 这个地址呢?而不是其他地址呢?这是由 M3 内核硬件上的设计就已经这么做了,人为设计好了,可以参考 M3 内核权威指南;
0x8003000 这个地址则是由我们自己来规定的,这个地址的范围必须在 0x8000000 和 0x8020000 之间,所以一般根据 Bootloader 程序的最终大小,在这范围之间取一个比较合理的值即可。如下图所示;
注意:本文使用的stm32f103cb
,属于中等大小 Flash,128K = 0x20000,所以地址范围是 0x8000000~0x8020000;
2 Bootloader
2.1 启动流程
这里的 Bootloader 即为 IAP 程序,它具备以下几个功能;
支持文件传输;本文基于 ymodem 协议通过串口通讯接收或发送的 bin 文件;当然也可以通过 I2C,SPI,USB,WiFi,蓝牙等等进行文件传输;
对内置 Flash 进行读写,擦除和编程;
启动 Application 程序;
前面分析 STM32 启动文件的时候,我们可以知道,正常一个系统的启动流程,可以参考 《STM32 标准库 V3.5 启动文件 startup_stm32f10xxx.s 分析》;
由该图可以知道程序正常启动流程;以下表格一四个向量是必须的,从图中也可以了解到;
2.2 校验跳转地址是否有效
在主函数中可以看到如下程序;甚是不解和迷茫;沉思一会儿才恍然大悟;
本文中 ApplicationAddress = 0x8000000;那么*(__IO uint32_t*)ApplicationAddress)则是这个地址中所保存的值,由表格一可以知道,程序起始地址的第一个向量地址保存的栈顶的,因此,地址 0x800_0000 和 0x800_3000 中保存的值都是指向栈顶,如下图所示;
栈是在 RAM 上分配,因此 RAM 的有效范围要做一个检测,栈顶地址和 0x2FFE0000 做与运算可以推算出,要校验的 RAM 范围是 0x2000_0000—0x2001_FFFF,所以 RAM 大小是 128K,官方 DEMO 默认使用 HD 高密度系列,所以是 128K,本文是 CBT6,20K 的 RAM,则需要改成 0x2FFFB000:
计算方式:20K = 20*1024= 0x5000,0x2FFF_FFFF - (0x5000 - 1) = 0x2FFF_B000
2.3 Keil 工程 IAP 的相关设置
2.3.1 修改 Flash 地址
设置程序起始地址 0x800000 和大小 0x3000;
设置 Debug 工具烧写时 Flash 的起始地址 0x800000 和大小 0x3000;
2.3.2 使用自己的链接脚本
该项为选配,与上述配置二选一即可,如果仍然想使用自己的链接脚本,在 Option-->Linker 下将 Use Memort Layout from Target Dialog 选项勾选去掉,然后选择自己的链接脚本,如下图进行配置;
参考 ARMCC 的链接脚本编写方法,可以自己编写的 srt 文件,参考 ARM 分散加载技术;
如果用的 gcc 工具链,则要编写 gcc 的链接脚本 ld 文件;
2.3.3 下载固件
配置完成之后进行 Build,然后通过 SWD 的方式先下载固件,进行实验;
3 Application
3.1 启动流程
用户的 Application 需要在 IAP 启动完成后,才能正常执行;具体启动过程,比正常应用的启动多了一个 IAP 启动的过程,并最终通过 IAP 引导进入 Application;具体如下图所示;白色部分为 IAP; 灰色部分为 Application;
图中的 0x8000004+N+M 就等于 0x8003004,所以 Application 的启动地址需要进行修改,另外还有其他需要修改的地方,下面会详细指出。
3.2 IAP 中的引导部分
参考 IAP 中的引导程序;
可以发现的是 SP 的值为 0x8003000,指向栈顶,而 0x8003004 则为 ResetHander 的地址,系统会进行复位,然后开始 Application 正常启动流程;
3.3 关于 VTOR
VTOR 是向量表偏移量寄存器,它将用来告诉 CPU,从 Flash 的哪个地方去取向量地址,第一个要取的是 MSP 的值,然后就是复位向量地址 ResetHandler,如果这里设置错误,那么程序是无法正常启动的。下面是标准库中与其相关的代码片段;
所以 Application 中还需要修改 VECT_TAB_OFFSET 的值为 0x3000;
参考 M3 权威指南:
如果需要动态地更改向量表,则对于任何器件来说,向量表的起始处都必须包含以下向量:
主堆栈指针(MSP)的初始值
复位向量
NMI
硬 fault 服务例程 后两者也是必需的,因为有可能在引导过程中发生这两种异常。可以在 SRAM 中开出一块空间用于存储向量表。在引导期间先填写好各向量,然后在引导完成后,就可以启用内存中的新向量表,从而实现向量可动态调整的能力。
3.4 Keil 工程设置
3.4.1 Flash 地址设置
与 IAP 工程设置类似,这里的 Application 是另一个 Keil 工程,同样的需要对 Flash 进行设置,如下图所示;
这里 Application 工程的 Flash 地址偏移了 0x3000,正是之前 Bootloader 所占用的 Flash 空间大小,这里和 VTOR 的设置也必须保持一致;
3.4.2 hex2bin
配置工程最终生成hex
文件,如下图所示;
最终我们需要使用的是 bin 文件,所以,这里需要使用将 hex 文件转成 bin 文件,本文使用 hex2bin 的工具;配置工程运行之后执行转换文件的脚本;
create_bin.bat
copy_firmware.bat
最终在 Build 之后,可以在 Firmware 中找到 STM321-APP.bin,这个文件就是要用来 IAP 程序进行串口下载的程序。
3.4.3 用户程序串口下载测试
SecureCRT 软件支持 ymodem 协议,可以安装该软件,打开串口连接,设置 ymodem 的协议;打开菜单选项:Options--Session Options,配置如下;
为了便于测试,在 STM32F1-APP 进行串口发送以下信息,便于观察 APP 是否正常启动;
usart_printf(" rn STM32F1-APP start running*******************");
打开连接的串口,并根据终端提示进行操作,最终下载固件 STM32F1-APP 成功,并成功运行;