当前位置:网站首页>【STM32】标准库-自定义BootLoader
【STM32】标准库-自定义BootLoader
2022-08-03 19:35:00 【熠熠L】
Bootloader
bootloader其实就是一段启动程序,它在芯片启动的时候最先被执行,可以用来做一些硬件的初始化或者用作固件热更新,当初始化完成之后跳转到对应的应用程序中去。
bootloader程序需要通过下载器烧写到芯片中,而APP则可以通过有线方式的UART、IIC、USB、SPI等总线来通过bootloader来更新,视所设计的bootloader程序而定。另外,对于无线方式热更新APP,一般是用WiFi、bluetooth通过UART透传的方式烧写芯片APP程序。
Bootloader的实现
本次采用STM32F429IGT6单片机,Flash共有1MB大小,SRAM共有256KB。
本次设计一个Bootloader和一个APP程序,空间分别如下:
BOOTloader程序起始地址0x0800 0000分配大小为0xA000,40KB,注意按照扇区对齐(比如4KB一个扇区)
APP程序起始地址0x0800 A000分配的大小为0xF6000,984KB。
| 起始地址 | 存储的内容 |
|---|---|
| 0x0800 0000 | BOOTloader程序 |
| 0x0800 A000 | APP程序 |
STM32的中断向量表和栈顶地址
STM32Fx有一个中断向量表,这个中断向量表存放代码开始部分的后4个字节处(即0x08000004),代码开始的4个字节存放的是栈顶地址。
栈是从高到低分配,高地址到低地址
堆是从低到高分配,低地址到高地址
排列格式如下:
| 栈顶地址 | 占用4个字节 |
|---|---|
| Reset_Handler | 复位中断向量 |
| 中断向量表 | 每一个中断向量表占用4个字节 |
| 程序 |
BOOTloader工程
bootloader和App都是完整的STM32工程,区别在于工程所实现的功能和占用Flash的大小。由于Bootloader的功能比较单一,并且为了节约Flash留给用户App,Bootloader一般不带操作系统,所占用的Flash较小。APP是完整的用户程序,按照正常的设计流程进行设计,只需要在工程配置和部分初始化代码处进行修改。
设置工程起始地址,及其大小

中断向量表的地址偏移
调用函数NVIC_SetVectorTable()进行配置。BOOT工程一般不需要配置
执行BOOT后,跳转到APP程序中
注意点:
检查堆栈地址是否有效,单片机的RAM大小为0x30000,0x3000 0000 - 0x3000 = 0x2FFD 0000,也可以用其他方法来计算RAM是否超过单片机的范围
关闭全局中断,__set_PRIMASK(1);仅只剩下NMI 和硬 fault 可以响应,记得在APP工程设置__set_PRIMASK(0);
复位BOOT工程中用到的外设
函数指针赋值为Reset_Handler向量的地址
设置堆栈地址
跳转到APP中
typedef void (*Run_APP_t)(void);
/** * @brief 跳转并执行到APP程序 * @param APPProgramAddr : APP程序的地址 * @retval None */
static void Jump_to_APP(uint32_t APPProgramAddr)
{
Run_APP_t run_app = (Run_APP_t)(*(uint32_t*)(APPProgramAddr + 4));
/* 检查堆栈地址(RAM地址)是否有效,然后跳转到用户应用程序 */
if((*(uint32_t*)APPProgramAddr & 0x2FFD0000) == 0x20000000)
{
/* 关闭所有中断, 在它被置 1 后,就关掉所有可屏蔽的异常,只剩下NMI 和硬 fault 可以响应。 它的缺省值是 0,表示没有关中断。 */
__set_PRIMASK(1);
/* 复位所有已经开启的外设 */
GPIO_DeInit(GPIOH);
GPIO_DeInit(GPIOA);
GPIO_DeInit(GPIOC);
EXTI_DeInit();
CRC_ResetDR();
USART_DeInit(USART1);
/* 设置堆栈指针 */
// __set_PSP(*(uint32_t*)APPProgramAddr);
// __set_CONTROL(0);
__set_MSP(*(uint32_t*)APPProgramAddr);
/* 跳转到APP程序中执行 */
run_app();
}
else
{
USART1Printf("BOOT_ERROR1!\r\n");
}
}
APP工程
Flash的起始地址,大小

中断向量表偏移地址和开启全局中断
/* 设置中断向量表 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0xA000);//中断向量表偏移
/* 关闭所有中断, 在它被置 1 后,就关掉所有可屏蔽的异常,只剩下NMI 和硬 fault 可以响应。 它的缺省值是 0,表示没有关中断。 */
__set_PRIMASK(0);
Keil5生成BIN文件
fromelf --bin -o "[email protected]" "#L"

工程文件下载链接
边栏推荐
- APT级全面免杀与企业纵深防御体系的红蓝对抗
- 建模该从哪一步开始?给你分析,给零基础的你一些学习建议
- 友宏医疗与Actxa签署Pre-M Diabetes TM 战略合作协议
- Unity获取canvas 下ui 在屏幕中的实际坐标
- Force is brushed buckle problem for the sum of two Numbers
- 数据驱动的软件智能化开发| ChinaOSC
- 盘点在线帮助中心对企业能够起到的作用
- Compose原理-compose中是如何实现事件分法的
- Network protocol-TCP, UDP difference and TCP three-way handshake, four wave
- MySQL读写分离的三种实现方案
猜你喜欢
随机推荐
微信小程序分享功能
安装anaconda并创建虚拟环境
高效目标检测:动态候选较大程度提升检测精度(附论文下载)
go语言实现导出string字符串到文件中
docker mysql 容器中执行mysql脚本文件并解决乱码
傅里叶变换(深入浅出)
X86函数调用模型分析
【leetcode】剑指 Offer II 007. 数组中和为 0 的三个数(双指针)
图像超分——Real-ESRGAN快速上手
系统太多,多账号互通如何实现?
【C语言学习笔记(五)】while循环与for循环
The ecological environmental protection management system based on mobile GIS
基于移动GIS的环保生态管理系统
LeetCode 622. Designing Circular Queues
CS免杀姿势
【Azure 事件中心】使用Azure AD认证方式创建Event Hub Consume Client + 自定义Event Position
Brush the topic of mobile zero power button
1-php学习笔记之数据类型
1161 最大层内元素和——Leetcode天天刷【BFS】(2022.7.31)
Word另存为PDF后无导航栏解决办法









