前言
在嵌入式开发的过程中,我们经常遇到需要在产品中加入OTA功能的需求,用以支持产品发布后,后续固件的升级维护等。而在MCU开发过程中,实现OTA功能,必不可少的是需要实现BootLoader以支持固件升级。今天这一篇,就简单讲述下HC32F460 上BootLoader的实现。
一、Bootloader是什么?
要实现BootLoader功能,首先我们需要了解bootloader是什么。BootLoader,引导加载程序,就如同它字面上的意思一样,它所起到的最主要的功能就是引导并加载我们的APP程序,使之能够顺利运行起来。当然,它的功能也不止于此,在不同的项目上根据需求有所不同。对于给电脑装过系统的小伙伴而言,可能会更好理解点,其实BootLoader就类似于电脑的BIOS,在电脑开机时,是需要BIOS的引导启动,最后才会来到我们熟悉的window界面。同理,在我们的嵌入式设备上,BootLoader就是启动引导我们APP程序的”BIOS”。
二、FLASH分区
了解完BootLoader是什么后,接下来该介绍BootLoader的实现。而在讲解BootLoader的实现之前,我们需要先对flash做一个分区处理的规划,方便后续的开发及项目后期一些新增需求预留的扩展。
从芯片的相关资料我们可以知道,HC32F460有着高达512kb的flash,对于芯片内部flash,用户手册介绍如下:
- 容量高达 512 KBytes(其中有 32bytes 为功能保留位),分为 64 个扇区,每个扇区为 8KBytes。
- OTP(One Time Program)区域共 1020Bytes,分为 960Bytes 数据区,并配有 60Byte的锁存区。
- 128 位宽数据读取。
- 编程单位为 4bytes,擦除单位为 8Kbytes。
FLASH地址结构如下:
对于扇区63,部分地址为功能保留位
根据应用需要,以及考虑到后续的扩展,对于Flash的分区及说明如下:
sector | 0~4 | 5~41 | 42~61 | 62 | 63 |
---|---|---|---|---|---|
addr | 0x0000~0x9fff | 0xa000~0x53fff | 0x54000~0x7BFFF | 0x7c000~0x7dfff | 0x7e000~0x7ffff |
- sector 0~4:占5个sector,共40 KB,用来存储BootLoader程序,预留有一定的空间,后续如有需求,这部分空间可利用。
- sector 5~41 :占49个sector,共392 KB,应用程序存储区域。
- sector 42~61:占20个sector,共160 KB,OTA升级包存储区域。
- sector 62:占1个sector,共8 KB,用来存储APP更新标志位。
- sector 63:占1个sector,共8 KB,预留。
三、BootLoader的实现
在对flash分区做好规划后,下面就开始介绍BootLoader的实现。
对于BootLoader的实现,我们需要思考两个问题:
- 如何实现应用程序的跳转;
- 应用程序中断向量表的处理;
1.如何实现应用程序的跳转
根据上面对flash的分区介绍,我们预先将APP应用程序烧录到sector5~41。
0xA000这个地址开始的第二个字,实际上就是我们用户应用程序开始的地址。因此,我们只需要将对应的这个地址定义为函数指针去调用,就可以跳转到我们用户程序中去执行。
应用程序跳转代码如下:
#define APP1_START_ADDR 0xA000 //用户程序地址
static void gotoApp(void)
{
PRO_LOG(LOG_INFO, "Start Application...\r\n\r\n");
uint32_t app_start_address;
/* Load the Reset Handler address of the application */
app_start_address = *(uint32_t *)(APP1_START_ADDR + 4);
/* Rebase the Stack Pointer */
__set_MSP(*(uint32_t *) APP1_START_ADDR);
/* Jump to application Reset Handler in the application */
(*((void(*)(void))app_start_address))();
}
2.应用程序中断向量表的处理
中断向量表,简单说,就是存储MCU中所有中断服务程序地址的一块区域。默认偏移量为0,我们将BootLoader烧录到sector0,则被BootLoader所使用。若是用户程序需要用到中断等相关功能,则需要将中断向量表进行偏移,偏移地址为用户程序烧录的起始地址(0xA000)。那么如何对中断向量表进行偏移呢,我们可以通过SCB->VTOR这个寄存器来对中断向量表偏移量进行设置。
代码如下:
SCB->VTOR = ((uint32_t) APP1_START_ADDR & SCB_VTOR_TBLOFF_Msk);
最后,我们只需要在用户程序的main开头对中断向量表进行偏移,基本工作也就完成了。
上电烧录测试,LOG输出如下:
总结
对于HC32F460 BootLoader的实现就简单的介绍到这里,工程源文件已上传,需要的可以去下载HC32F460 Bootloader。如果所说内容有错或者不同见解,欢迎各位在评论区指出,谢谢!