写一个STM32 BootLoader-1

  • 1. 概述
  • 2. 定义基本功能
  • 3. 通讯协议
  • 4. BOOTLOADER和用户程序切换
  • 5. 内部FLASH分配(以STM32F103VET6为例)
  • 6. 参考
  • 1. 概述

    某些定制的产品交付使用之后,用户方难免会提出一些功能更改的要求,所以也就避免不了对MCU里面的程序进行更新。一般情况下,例如STM32,会在内部FLASH前面放一段BOOTLOADER的代码。在启动时,如果没有某个操作(如串口输入或按键输入)的话,则正常跳转到用户程序中进行执行。如果有相关操作的话,则运行BOOTLOADER程序,在BOOTLOADER里面嵌有操作FLASH的程序,通过该程序可以将新的用户程序更新进FLASH里面。

    ST官方有基于UART进行更新用户程序的BOOTLOADER工程。该工程启动的时候,如果串口收到输入,则进入更新用户程序状态,上位机利用Ymodem协议,把编译好的用户程序通过串口写入到STM32中。如果启动过程中,串口没有收到数据,则正常跳转到用户程序中去执行。

    笔者之前项目使用的BOOTLOADER是在官方发布的工程基础上修改的。基本流程是这样:在启动三秒内,如果串口没有输入的话,则跳转到用户程序;如果串口有输入的话,则运行Ymodem协议软件进行用户程序更新。

    但是最近有些项目在执行过程中遇到了一些新的需求。比如启动时间,用户方要求一上电就默认进入用户程序,而不必等三秒;再者,也出现过这样的情况,在某些强干扰的情况下,启动过程中,串口接收到了一些干扰信号,导致误触发了下载更新流程。于是萌发了自己给STM32写一个BOOTLOADER的想法。

    2. 定义基本功能

    1、串口下载不用采用Ymodem协议了,采用自定义的协议,该协议同时跑在BOOTLOADER和用户程序中,通过指令操作选择执行BOOTLOADER或者用户程序。
    2、因为BOOTLOADER是在FLASH开头执行的程序,想从用户程序切换回去,最简单的方式是让软件进行重启,这样让软件可以从FLASH开头进行运动。
    3、重启后必须有一种机制来选择是执行BOOTLOADER或者用户程序,可以通过在内存设置标志位的方式。例如在用户程序执行的过程中,如果收到进入BOOTLOADER的指令,则设置该标志位,然后重启,重启后BOOTLOADER开头读取该标志位,通过该标志位来选择是进入BOOTLOADER或者用户程序。因此该标志位必须不受软件复位的影响,同时在上电复位时能复位到一个明确的状态。
    4、串口需要接收不等长的数据包。因为更新用户程序时,数据量较大,一帧数据要尽可能加长。同时也要兼顾到其他短包的指令

    3. 通讯协议

    帧头采用0x41,帧尾采用0x2b,如下图所示

    通讯协议格式

    如果在数据中遇到0x41,0x2b,则采用转义的方式:

    0x41 => 0x2d 0x21
    0x2b => 0x2d 0x0b
    0x2d => 0x2d 0x0d

    协议中数据的组织形式为

    typedef struct {
    	uint8_t id;			// 板子ID号,如果系统有多个板子的话,防止更新错程序
    	uint8_t cmd;		// 协议命令
    	uint8_t subcmd;		// 协议子命令
    	uint8_t len;		// 后面数据的长度,以字节为单位
    	uint8_t dat[65];	// 数据,烧写的数据长度要保证4的倍数,最长的数据为64个字节,最后一个字节是CRC校验
    						// CRC校验从dat[0]开始
    }
    

    4. BOOTLOADER和用户程序切换

    将标志位设置在内部的FLASH中应该是一种比较好的选择,因为FLASH中的数据不会因为系统复位而发生改变。但是FLASH是按页进行擦除的,在写入数据之前需要对整页进行擦除操作。因为要写入一个数据的原因,而导致要去操作整页FLASH,这样对于嵌入式系统来说有点浪费资源

    在STM32系统的芯片中,有个更好的办法,即利用STM32中的备份寄存器就可以完成这个操作。STM32F1中有42个两字节的备份寄存器。这些寄存器里面写入的内容不会受到系统软件复位的影响,同时,当系统断电后重新上电时,又可以初始化到一个明确的状态,所以很适合把操作切换的标志位放在这个寄存器里面。

    5. 内部FLASH分配(以STM32F103VET6为例)

    STM32F103VET6 FLASH的组织形式如下图

    FLASH组织方式

    本设计中,将Page0~Page3共8KB的空间分配给BOOTLOADER,用户程序从Page4开始,也就是从地址0x08002000开始,后面所有的FLASH都分配给用户程序。

    6. 参考

    1. https://blog.csdn.net/MQ0522/article/details/123422553

    作者:Cesaroy

    物联沃分享整理
    物联沃-IOTWORD物联网 » 写一个STM32 BootLoader-1

    发表回复