1
控制/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条评论
快来发表一下你的评论吧 !