stm32f103bootloader程序
时间: 2025-05-27 22:25:18 浏览: 22
### STM32F103 Bootloader 的实现方法
STM32F103 芯片上的 Bootloader 是一种用于加载和更新固件的应用程序。其实现通常涉及以下几个方面:
#### 1. Flash 地址分配
为了确保 Bootloader 和应用程序之间的独立性,Flash 需要被划分为多个区域。对于 STM32F103C8T6(闪存容量为 64 KB),可以按照如下方式划分:
- **Bootloader 区域**: `0x08000000` 到 `0x08001FFF` (8 KB),这部分存储 Bootloader 程序。
- **应用程序区域**: `0x08002000` 开始,剩余的 Flash 存储用户应用程序。
这种分区可以通过修改链接脚本 (`ld`) 来定义不同区域的起始地址和大小[^5]。
#### 2. 初始化过程
在系统启动时,Bootloader 应该检测是否需要进入升级模式还是直接跳转到应用程序。这通常通过以下几种方式进行判断:
- 检查特定标志位(如 GPIO 输入状态)。
- 检测串口是否有数据输入(适用于 XMODEM 协议等通信方式)。
如果满足条件,则留在 Bootloader 中等待新固件上传;否则跳转至应用代码入口地址 `0x08002000`[^4]。
```c
// 跳转函数声明
typedef void (*pFunction)(void);
// 主函数逻辑
int main(void) {
HAL_Init(); // 初始化HAL库
if (!isUpgradeMode()) { // 如果不需要升级则跳过bootloader
pFunction JumpAddress;
uint32_t AppAddr = 0x08002000;
JumpAddress = (pFunction *)(*(uint32_t *)(AppAddr + 4)); // 获取向量表中的初始SP值作为目标地址
__set_MSP(*(uint32_t *)AppAddr); // 设置栈指针指向APP区堆栈顶部
JumpAddress(); // 执行跳转操作
}
while (1){
HandleUpgradeProcess(); // 处理固件升级流程
}
}
```
#### 3. 数据传输协议支持
常见的固件更新协议包括 UART 上使用的 XMODEM/CRC 或者 USB DFU(Device Firmware Upgrade)。这里以 XMODEM 为例说明如何接收并保存二进制文件内容到指定位置[^2]。
```c
#include "usart.h"
#define PACKET_SIZE_XMODEM 128
static uint8_t buffer[PACKET_SIZE_XMODEM];
static uint16_t packet_count = 0;
void ReceivePacket() {
uint8_t c, i;
do{
c = USART_ReceiveData(USART1);
}while(c != SOH || c != STX); // 等待包头到来
for(i=0;i<PACKET_SIZE_XMODEM;i++)
buffer[i]=USART_ReceiveData(USART1);
WriteToFlash(buffer,packet_count++ * PACKET_SIZE_XMODEM);
}
void StartReceiving(){
while(!IsEndOfTransmission()){
ReceivePacket();
}
}
```
以上片段展示了基本的数据接收框架以及调用写入 Flash 函数的部分伪码表示形式[^3]。
#### 4. 写入 Flash 功能封装
利用 HAL 提供的相关 API 完成实际物理层面的操作前需先配置好参数结构体实例化对象以便后续调用方便快捷高效准确无误地完成整个烧录动作[^3]。
```c
Loader_agreement loaderConfig = {0};
void ConfigureAndWrite(uint8_t* pData,uint32_t Address,uint16_t Length){
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError = 0;
/* Unlock the Flash to enable the flash control register access */
HAL_FLASH_Unlock();
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = TYPEERASE_PAGES ;
EraseInitStruct.PageAddress = Address / FLASH_PAGE_SIZE;
EraseInitStruct.NbPages = LENGTH_TO_PAGES(Length);
if(HAL_OK == HAL_FLASHEx_Erase(&EraseInitStruct,&PageError)){
HAL_FLASH_Program(TYPEPROGRAM_WORD,(uint32_t)pData,Address);
}
/* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) */
HAL_FLASH_Lock();
}
```
---
###
阅读全文
相关推荐


















