开发环境
KEIL5
板载环境
stm32f103c8
一、bootloader初始化
1、定时器初始化
作用:定时自动跳转至应用,一般设置为1~2秒
2、通讯方式初始化
CAN、UART等
3、板载初始化(重要)
(1)确定应用跳转地址
跳转地址即应用储存起始地址,在应用中设置启动偏移地址与该地址一致
(2)确定应用存储空间大小
1)存储空间大小不可以超过芯片FLASH大小
2)存储空间大小应设置为整数,该“整数”理解为扇区大小*扇区数量
中、小容量单片机一个扇区1KB (存储空间小于256K)
大容量单片机一个扇区2KB (存储空间大于等于256K)
3)存储空间大小应该去除bootloader所占用空间
#define APP_ADDR 0x8002000
#define FLASH_SECTOR_SIZE 1024
#define APP_FLASH_SECTORS 50
#define APP_SIZE_MAX (APP_FLASH_SECTORS*FLASH_SECTOR_SIZE)
注:stm32f103c8 FLASH 大小64K,bootloader占用8K,预留8K用于存储软件参数, 剩余50K用于存放固件
4、跳转函数
typedef void (*pFunction)(void);
//Addr 传参即为上述定义的APP_ADDR
void iap_load_app(uint32_t Addr)
{
static pFunction Jump_To_Application;
__IO uint32_t JumpAddress;
// __enable_irq();
/* Test if user code is programmed starting from address "ApplicationAddress" */
if (((*(__IO uint32_t*)Addr) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (Addr + 4);
Jump_To_Application = (pFunction) JumpAddress;
//__set_PRIMASK(1);//关闭所有中断
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*)Addr);
Jump_To_Application();
}
}
bootloader在进入app之前使用__set_PRIMASK(1);函数关闭了中断,在app中需要将中断打开__set_PRIMASK(0);因为我的bootloader中并未使用任何中断,因此将该函数屏蔽。
bootloader在进入跳转函数之前,应该注销硬件初始化。
5、定义固件升级协议
此协议内容根据需要自定义,不再赘述,但应包含如下协议内容:
(1)握手
告知上位机,板载进入bootloader,可以开始应用升级
(2)FLASH擦除
擦除应用存储空间所有内容
(3)固件升级
将应用写入指FLASH地址
(4)程序校验
告知上位机。应用升级失败