前言

嵌入式项目只要是物联网,基本上都需要用到远程升级,可以说是我们最重要的功能之一了。

升级方式:

我们使用串口和物联网模块进行IAP远程升级。

测试环境:

硬件平台:使用自制stm32f103c8t6公板。
软件环境:cubemx + keil + vscodeHAL库

参考文档:

深入浅出讲解单片机的BootLoader
大佬写的非常系统、详细,从原理到过程。非常推荐

一、ROM划分

ROM大小64K(0x10000)
boot占16K(0x4000)
app占48K(0xC000)

二、新建工程

2.1 新建工程

通过cubemx新建两个keil工程,过程不再赘述,打开调试口、外部时钟、USART3,一个GPIO(LED)、TIM3。

2.2 修改ROM起始位置

app工程改为:
app工程
boot工程改为:
boot工程

三、boot跳转APP

3.1 boot工程

boot工程中添加指示灯,闪烁频率10Hz用来判断是否跳转APP,定义APP跳转函数:

typedef void (*BootToApp)(void);    //定义了一个函数指针类型 BootToApp,用于后续跳转APP的入口点。
BootToApp jump2app;

void Jump_To_Application(void) 
{
  jump2app = (BootToApp) * (volatile uint32_t *)(APP_START_ADDR + 4);	//应用程序起始地址偏移4字节,这里存储的是复位向量表中的程序入口地址
  __set_MSP(*(volatile uint32_t *)APP_START_ADDR);  //设置主堆栈指针(MSP)为应用程序的堆栈起始地址
  NVIC->ICER[0] = 0xFFFFFFFF;    //关闭所有中断并清除所有中断标志
  NVIC->ICPR[0] = 0xFFFFFFFF; 	//这是为了确保跳转到应用程序时不会有中断干扰
  jump2app();
}

这段代码的主要作用是实现从bootloader跳转到应用程序的功能。在STM32中,程序的起始地址存储了两个重要信息:

  • 地址0x0:存储初始堆栈指针(MSP)的值
  • 地址0x4:存储程序入口点的地址

3.2 APP工程

APP程序中,主要注意中断向量表的偏移问题。

#define VECT_TAB_OFFSET  0x4000		//宏定义偏移地址
  1. STM32标准库设置中断向量表:
NVIC_SetVectorTable(NVIC_VectTab_FLASH, VECT_TAB_OFFSET);
  1. STM32HAL库设置中断向量表:
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;

重点注意:在重新设置中断向量表位置时,一定要注意关总中断,设置完成后,在打开总中断。
然后添加2Hz的指示灯用以区分是否跳转。

四、测试

在这里插入图片描述

使用keil烧录APP程序,指示灯不运行,然后烧录boot,指示灯快速闪烁,随后进入2Hz闪烁,说明boot跳转APP成功。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐