关于STM32的IAP编程的一些记录

您所在的位置:网站首页 beap异常啥意思 关于STM32的IAP编程的一些记录

关于STM32的IAP编程的一些记录

2024-01-29 00:49| 来源: 网络整理| 查看: 265

背景

在给STM32单片机做IAP(Flash分为两部分:BootLoader+APP)升级功能时,有如下需求- -

系统上电默认先进入BootLoader中,BootLoader会停留几百毫秒;停留期间,系统会判断是否具有IAP请求,如果有则进行IAP升级,否则超时后跳转到APP中即可;

这样得逻辑很简单,但是有一个缺陷,就是不管上电还是复位后始终必须停留几百毫秒后才能跳转至APP,对于是实现要求高的、跑飞后需要立刻进行复位重启的系统,是不合理的。因此可以进行一个优化:

在需求2的基础上,先判断复位类型是上电店复位还是软件复位,如果是软件复位,直接跳转至APP,不停留。 关键代码实现

以stm32f4为例,修改system_stm32f4xx.c中的SystemInit函数

void SystemInit(void) { /* USER CODE BEGIN 1 */ // 判断 app是否存在标志,app存在时跳转的前提 uint8_t isAppExistFalg = *(__IO uint8_t*)(标记app是否存在的地址)); // 判断是否为软件复位,软件复位就直接跳转到app中 if( (1 == isAppExistFalg) && ((RCC->CSR) & 0x10000000) ) { __HAL_RCC_CLEAR_RESET_FLAGS(); extern void jump2aplication(void); jump2aplication(); } /* USER CODE END 1 */ ... 省略 ... // 注意:编译APP时,宏VECT_TAB_OFFSET要设定正确的偏移量,设定方法见文末 /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif }

其中 函数jump2aplication()实现为:

typedef void (* pFunc)(void); void jump2aplication(void) { // 确定应用程序入口地址 pFunc jump_to_application = (pFunc)(*(__IO uint32_t*)(APP的起始地址值 + 4)); // 检查应用程序堆栈地址是否合法 if(((*(__IO uint32_t *)APP的起始地址值) & 0x2FF80000) == 0x20000000) { // 初始化MSP __set_MSP(*(__IO UINT32 *)APP的起始地址值); // 跳转到应用程序 jump_to_application(); } }

通过以上的修改,就可以实现BootLoader到APP的跳转。

更高级功能

现在,仔细思考后发现:如果想升级,就只能将设备断电,然后在上电的几百毫秒内握手升级(不然超时跳转到APP中)。能不能做到让APP主动跳转到BootLoader里面,这样不就可以随时进行升级?当然可以。 直接上代码:

typedef void (* pFunc)(void); void jump2bootloader(void) { // 确定应用程序入口地址, FLASH_BASE=0x08000000,即stm32代码默认起始地址 pFunc jump_to_bootloader = (pFunc)(*(__IO uint32_t*)(FLASH_BASE + 4)); // 检查应用程序堆栈地址是否合法 if(((*(__IO uint32_t *)FLASH_BASE ) & 0x2FF80000) == 0x20000000) { // 是所有设备的设置恢复到初始状态,否则跳转后可能产生硬错误 __disable_irq(); HAL_RCC_DeInit(); // 初始化MSP __set_MSP(*(__IO UINT32 *)FLASH_BASE ); // 跳转到应用程序 jump_to_bootloader(); } }

注意:APP中一般会对外设、始终及中断做一系列配置,跳转至BootLoader后,并未经过复位操作,所以必须要调用HAL_RCC_DeInit()将所有外设和始终配置恢复初始化状态。我初次应用时就没有调用HAL_RCC_DeInit(),导致在main函数的 void SystemClock_Config(void)函数中进入错误死循环。至于APP,跳转至APP一般在复位或上电时刻,所有不执行HAL_RCC_DeInit()也无所谓。

参考

做APP跳转到BootLoader功能时,碰到上面提到的死循环问题时,多亏这篇博主的文章:关于STM32的IAP与APP互相跳转

如果发现跳转至APP后始终跑飞的,可以思考一下app的相关偏移是否修改?修改方法可以参考我的另一篇博客STM32 CubeIDE中修改APP起始地址的方法



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3