1.boot
程序根据分区一引导分区二,可以方便分区二应用升级维护,所以两个分区有利于升级维护(跟uboot和kernel原理一样)。
2实现原理分析
2.1引导程序
确认应用程序的起始位置
升级的过程被称为 IAP(In Application Programming) ,每个芯片的 Flash 的扇区不同,我这里使用的是 STM32F767,上官网查看有关资料:STM32F76xxx and STM32F77xxx advanced Arm®-based 32-bit MCUs.pdf 里面有关于 Flash 扇区的地址信息:
在步骤2.1已经知道 BootLoader 的 bin文件大小是22 KB,我们可以根据上面的 Flash 扇区进行分配,我将应用程序的起始位置定在 扇区1,起始地址为 0x0800 8000
编写引导程序
#include "stm32f7xx.h"
typedef void (*pFunction)(void);
/*!
* @brief 跳转到应用程序段
* 执行条件:无
* @param[in1] : 用户代码起始地址.
*
* @retval: 无
*/
void jump_to_app(uint32_t app_addr)
{
pFunction jump_to_application;
uint32_t jump_address;
/* Check if valid stack address (RAM address) then jump to user application */
if (((*(__IO uint32_t*)app_addr) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
jump_address = *(__IO uint32_t*) (app_addr + 4);
jump_to_application = (pFunction) jump_address;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) jump_address);
jump_to_application();
}
}
#define FLASH_JUMP_ADDR (0x08008000)
int main(void)
{
/*
初始化程序省略.....
*/
if(((FLASH_JUMP_ADDR+4)&0xFF000000)==0x08000000) //Judge if start at 0X08XXXXXX.
{
jump_to_app(FLASH_JUMP_ADDR); // Jump to APP
}
while(1)
{
}
}
2.2 第二分区
第二分区根据第一个分区的0x0800 8000,将加载起始地址改为0x0800 8000,就可以顺利引导第二分区程序。
修改分区地址
修改向量表
搜索宏定义 VECT_TAB_OFFSET,将 0x00 改为距离 0x8000的偏移量
/*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x8000 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
加入 App 循环打印提示
void StartDefaultTask(void const * argument)
{
/* USER CODE BEGIN StartDefaultTask */
segger_rtt_init("APP enter!");
/* Infinite loop */
for(;;)
{
print_log("You are in App now !!\n");
osDelay(1000);
}
/* USER CODE END StartDefaultTask */
}
烧录
确认烧录过程是 Erase Sectors!
依次烧录 BootLoader 和 App 的程序;