扫描关注一起学嵌入式,一起学习,一起成长
本期话题
(资料图片仅供参考)
现在越来越多的嵌入式设备支持远程自动升级,不需要再借助下载器。这样对于设备的维护非常方便。
当然若使设备支持远程升级,需要编写支持升级的程序代码,可以称之为 BootLoader。
也就是说,将设备的程序代码分为两部分:BootLoader 和 APP。
BootLoader 负责升级 APP 以及引导APP运行。APP 负责实现设备的业务处理功能,也就是设备的核心功能代码。
对于Cortex-M 系列的单片机来说,若要实现 BootLoader 安全跳转到 APP,需要进行一些配置。
本文就以 STM32 单片机为例,来聊一聊实现 BootLoader 跳转的关键配置步骤。
聊一聊
在程序开发设计阶段,要根据具体应用情况,对程序存储的 Flash 进行分区。
即,BootLoader 存储的位置以及需要分配的空间大小,以及 APP 的存储的位置和大小。这个存储位置直接关系到程序的执行和跳转。
最简单的一种升级方案是:一个 BootLoader 和 一个 APP ,BootLoader 实现跳转和升级APP 的功能。本文以这个升级方案为例进行介绍。
对于 STM32 单片机来说,程序启动的映射地址为 0x8000000。
可以将 BootLoader 存储在 0x8000000 地址,分配的空间可以根据芯片具体的Flash大小进行调整。比如 0x10000,64K 字节。
APP 存储的地址,安排在 BootLoader 后边,即存储地址为 0x8010000,Flash 剩余的空间都可以分配给APP。
BootLoader 工程配置
BootLoader 的工程需要进行一些配置,以MDK为例,如下图所示,BootLoader 程序存放的 FLASH 地址为 0x8000000,大小为 0x10000。
/* 定义类型 */typedef void (*pFunction)(void);/* APP flash address */#define APP_FLASH_ADDR (0x8010000)void jump_to_app(void){ uint32_t JumpAddress; pFunction Jump_To_Application; /* 检查栈顶地址是否合法 */ if(((*(__IO uint32_t *)APP_FLASH_ADDR) & 0x2FFE0000) == 0x20000000) { /* 屏蔽所有中断,防止在跳转过程中,中断干扰出现异常 */ __disable_irq(); /* 用户代码区第二个 字 为程序开始地址(复位地址) */ JumpAddress = *(__IO uint32_t *) (APP_FLASH_ADDR + 4); /* Initialize user application"s Stack Pointer */ /* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */ __set_MSP(*(__IO uint32_t *) APP_FLASH_ADDR); /* 类型转换 */ Jump_To_Application = (pFunction) JumpAddress; /* 跳转到 APP */ Jump_To_Application(); }}
APP 工程配置
APP 的工程需要进行一些配置,以MDK为例,如下图所示,APP 程序存放的 FLASH 地址为 0x8010000,大小为 0x30000。
APP程序代码需要进行如下配置:
修改APP 内部 Flash 向量表重定位 SCB->VTOR
APP运行后,初始化函数中,开启中断,否则程序会运行异常
正常来说,在启动文件中执行调用 SystemInit()
函数,这个函数会配置 Flash 的接口信息。SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET
。
修改宏定义 VECT_TAB_OFFSET
的值为 0x10000。
APP程序启动之后,需要先使能全局中断,可将下边的代码放在初始化的地方:
/* 使能中断 */__enable_irq();
最后
设备运行期间,APP 在运行处理业务功能。如果要升级 APP ,需要从 APP 切换到 BootLoader 中。
那么如何实现 APP 跳转到 BootLoader 呢?有两种方法:
硬件方式,设备断电重启或复位按键
软件方式,通过软件控制复位MCU
软件方式,可以在APP代码中添加控制指令,当APP接收到跳转指令(或者升级指令)后,复位 MCU。如下代码可以复位MCU:
/* 复位芯片 */HAL_NVIC_SystemReset();
好了,就这些内容。欢迎探讨交流。
感谢阅读,加油~
觉得文章不错,点击“分享”、“赞”、“在看” 呗!