第五章-BootLoader和OTABootLoader刷写流程 STM32 BootLoader STM32 BootLoader 和APP跳转 STM32 iap BootLoader

5.1-BootLoater前要知道

抛开BootLoater问自己从自己的C程序工程到单片机可以运行大概是怎么回事???

编译器如何处理C工程的
在这里插入图片描述
单片机如何保存和执行程序
在这里插入图片描述
相关存储器

一般启动执行流程

  1. 复位后,从0x0800 0000取出来复位中断地址,并且跳转到复位中断程序,
  2. 中断执行完,跳转到main 函数,然后一直在mian 循环
  3. 如果中断发送,pc指针调转中断表,然后根据中断函数执行中断,
  4. 然后回到main函数
    在这里插入图片描述

5.2-BootLoater是什么

了解上面启动流程后,如果我们想给板子更新一个程序,就可以下载两个APP,一个APP检测更新,一个APP是我们的应用程序

在这里插入图片描述
我们总结下BootLoater程序要做的事情

在这里插入图片描述

5.3-写一个BootLoater程序(不含Flash操作)

这是一个BootLoater程序功能是可以跳转,回跳转到指定位置执行,相应程序。

我们还是使用第零章的代码

为了方便调试我先加入串口发送功能
在这里插入图片描述
添加一下重映射
在这里插入图片描述

/**
* @brief 重定向printf (重定向fputc),
					使用时候记得勾选上魔法棒->Target->UseMicro LIB 
					可能需要在C文件加typedef struct __FILE FILE;
					包含这个文件#include "stdio.h"
* @param 
* @return 
*/
int fputc(int ch,FILE *stream)
{
	HAL_UART_Transmit(&huart1,( uint8_t *)&ch,1,0xFFFF);
	return ch;
}

在这里插入图片描述
我们的IAP.c内容如下


/* Includes ------------------------------------------------------------------*/
#include "MyApp.h"
/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/

/* Public variables-----------------------------------------------------------*/

/* Private function prototypes------------------------------------------------*/      
/*******************
*  @brief  这是 C语言内嵌汇编
//MSR MSP, r0 意思是将r0寄存器中的值加载到MSP(主栈寄存器,
//复位时默认使用)寄存器中,r0中保存的是参数值,即addr的值
//BX r14 跳转到连接寄存器保存的地址中,即退出函数,跳转到函数调用地址

*  @param  
*  @return  
*
*******************/
__asm void MSR_MSP (uint32_t ulAddr)
{
	MSR MSP,r0 //set Main Stack value
	BX r14
}
/*******************
*  @brief  跳转到应用程序
*  @param  ulAddr_App:应用程序的起始端地址
*  @return  
*
*******************/
void IAP_ExecuteApp(uint32_t ulAddr_App)
{
	void (*pFunApp)(void);//定义一个函数指针
	
	//检查栈顶地址是否合法
	//if(((*(__IO uint32_t*)ulAddr_App) & 0x2FFE0000) == 0x20000000)	
	if(((*(__IO uint32_t *)ulAddr_App) & 0x2FFF5000) == 0x20000000)
	{
		printf("地址合法开始跳转\r\n");
		pFunApp = (iapfun) *(__IO uint32_t *)(ulAddr_App + 4); //赋值函数指针、指向新APP的复位中断函数地址
		MSR_MSP(*(__IO uint32_t *)ulAddr_App);					//初始化APP堆栈指针,对APP程序的堆栈进行重构,就是重新分配RAM
		pFunApp();    			//执行APP的复位中断函数,最终便会跳转到APP的main函数
	}
	else
	{
		printf("地址不合法\r\n");
		//错误栈顶地址不合法!
	}
}

/********************************************************
  End Of File
********************************************************/

IAP.h内容如下

#ifndef  __IAP_H_
#define  __IAP_H_

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

typedef void (* iapfun)(void);     //定义一个函数指针(指向一个返回为空形参为空的函数)
#define APP_Start			FLASH_BASE+0x400  	//这是APP开始位置

void IAP_ExecuteApp(uint32_t ulAddr_App);

#endif
/********************************************************
  End Of File
********************************************************/

然后主函数内容如下
在这里插入图片描述

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(500);
	HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	
	//跳转流程如下几步
	
	/****关闭中断********/
	HAL_SuspendTick();
	
	/****清除中断位******/
	
	/****加载栈地址******/
	/****程序跳转********/
	IAP_ExecuteApp(APP_Start);//程序跳转,里面有加载栈地址和程序跳转操作
	
  }

然后这个就是我们的BootLoater程序了

我们需要使用MDK设置一下BootLoater的下载的位置和占用大小

先确定自己使用单片机的ROM(Flash)大小、

通过编译后的提示,把各个数据段和代码段加一起,然后就是最后程序大小,我们比这个分配更大一些
在这里插入图片描述
通过魔术棒设置大小、这里设置16K、用来保存boot程序
在这里插入图片描述
然后这个bootloater程序就可以下载到单片机了

然后设置一下APP1 程序

自己的APP程序需要的注意点

  1. 设置MDK生产bin文件。

  2. 设置中断向量偏移 SCB->VTOR = FLASH_BASE | 0x1000;//设置中断向量表地址偏移量。

  3. 设置程序下载的起始位置和大小。

  4. 设置脚本生成bin 文件

在这里插入图片描述

fromelf.exe --bin --output "@L.bin" "#L"

fromelf.exe --bin --output “@L.bin” “#L”
在这里插入图片描述
设置中断向量偏移

  SCB->VTOR = FLASH_BASE | 0x1000;//设置中断向量表地址偏移量

在这里插入图片描述
设置程序下载的起始位置和大小
在这里插入图片描述
为了方便观察实验现象我们更改一下小灯的闪烁频率、还有添加串口输出

这里省略串口一初始化和重映射printf步骤

	HAL_Delay(100);
	HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	printf("这是APP1正在执行中");

在这里插入图片描述开始实验

把bootloater程序先通过MDK烧录到单片机,然后烧录APP1,然后按下复位键

是不是串口

先输出

printf(“地址合法开始跳转\r\n”);

然后输出

printf(“这是APP1正在执行中”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值