硬件: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(" \r\n STM32F1-APP start running*******************");

 

打开连接的串口,并根据终端提示进行操作,最终下载固件 STM32F1-APP 成功,并成功运行;