控制/MCU
有时候那些天天写理论的博主,很大程度是拉高了初学者的入门门槛,让不少初学者望而却步,并不利于信息的传播和初学者的学习。
| 有啥用
认识一个东西最直接的方法就是看作用,知道使用的场景或者需求才知道这个东西存在的意义;BootLoader程序其实是MCU上电之后运行的第一个程序,在这个程序中可以通过条件判断跳转进入不同的Flash地址的程序,简单理解就是可以随意跳到想要执行的程序,这就是为啥聊的BootLoader的第一印象就说它是用于刷程序的,实际上它的功能不止用于刷程序。
| 怎么用
由于需求不同自然导致使用不同,这里主要介绍BootLoader是怎么跳到App,然后执行需要指定执行的App的。
硬件介绍
主控使用的是STM32F103ZET6,下载器使用的是ST-LINK V2,使用LED跳动来体现测试效果。
内存配置

项目搭建
BootLoader项目程序和App项目程序是分开的,所以需要分别搭建对应的项目工程文件,分开搭建文件是为了好配置,同时也是方便对项目进行管理。

BootLoader项目的main.c文件
#include "stm32f10x.h"
uint32_t JumpAddress =0;
typedef void(*pFunction)(void);
pFunction Jump_To_Application;
// flash基地址
#define FLASH_BASE_ADDRESS ((uint32_t)(0x08000000))
// 目标app地址
#define ApplicationAddress ((uint32_t)(0x08000800))
int main( void )
{
// 取ApplicationAddress + 4地址的值
JumpAddress = *(__IO uint32_t*)(ApplicationAddress + 4);
// 强制转换
Jump_To_Application = (pFunction) JumpAddress;
// 设置堆栈指针指向目标app地址
__set_MSP(*(__IO uint32_t*)ApplicationAddress);
// 跳转到app
Jump_To_Application();
}
BootLoader项目的配置:

选择部分擦除:

App项目的main.c文件
#include "stm32f10x.h"
void LED_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOE,&GPIO_InitStructure); /* 初始化GPIO */
GPIO_SetBits(GPIOE,GPIO_Pin_5); //将LED端口拉高,熄灭所有LED
}
int main( void )
{
// 设置中断向量偏移表
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x800);
uint32_t i = 0;
LED_Init();
while(1)
{
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
for(i = 0; i< 0xfffff; i++);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
for(i = 0; i< 0xfffff; i++);
}
}
App项目的配置:

选择部分擦除:

| 看效果
搭建的两个项目都需要下到开发板中,先下BootLoader项目到开发板,再下App项目到开发板;
BootLoader项目示意图:

App项目示意图:

仿真示意图:

注意事项:
如果下载不能自动复位运行,就需要进行以下配置。

实测发现程序能正常跳转到目标App运行,LED灯正常按周期运行闪烁;
审核编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !