Sam2016 发表于 2019-7-31 10:34:15

STM32F429串口IAP,APP程序HardFault_Handler死机

请教大侠:
bootloader裸机,实现串口数据接收与FLASH烧写;
APP使用MDK自带的RTX做系统,实现点灯功能;
问题:
当跳转到APP程序执行完启动文件的SystemInit函数后,再执行__main函数就会死机。
具体是因为__main会去执行RTOS的初始化,函数如下:
osKernelInitialize();
osThreadCreate(&os_thread_def_main, NULL);
osKernelStart();
在执行osKernelStart();时死机。

如果APP不做IAP,烧录不做地址偏移,可以顺利执行。
如果APP使用IAP,设置物理地址偏移,但不使用RTX系统,也能顺利执行。
网上的很多说法都尝试过,例如关闭总中断,设置SCB->VTOR。但仍无法解决。

toofree 发表于 2019-7-31 12:16:52

改一下堆栈大小试试看。有时候开得太小,程序也有可能跑飞。

Sam2016 发表于 2019-7-31 13:17:48

toofree 发表于 2019-7-31 12:16
改一下堆栈大小试试看。有时候开得太小,程序也有可能跑飞。

先谢谢的的回答。
已经试过了,没有用,程序还没有调到main函数里面。
RTX也是选择了特权级模式。

奏奏奏 发表于 2019-7-31 16:34:54

如果楼主用的是STM32CubeMX配置FreeRTOS,然后做串口IAP,我还是可以分析一下的,因为我现在在做。
但是RTX系统我就没办法了。

Sam2016 发表于 2019-7-31 18:54:42

奏奏奏 发表于 2019-7-31 16:34
如果楼主用的是STM32CubeMX配置FreeRTOS,然后做串口IAP,我还是可以分析一下的,因为我现在在做。
但是RTX ...

可惜不是哎,用的RTX,标准库。你配置FreeRTOS的APP有什么要注意设置的吗?

奏奏奏 发表于 2019-7-31 20:01:10

(1)上面沙发的大佬已经讲过最重要一点:“改一下堆栈大小试试看。有时候开得太小,程序也有可能跑飞。”
就是将每个任务的分配堆栈(Stack Size)调大,原来我设置64Words跑飞的,设置到128Words就正常跑通了。
(2)MDK的option->target 配置IROM1,例如将中断向量表偏移地址改到0x8005000,在MDK的option->target 配置IROM1为0x8005000
(3)设置system_stm32f1xx.c文件#define VECT_TAB_OFFSET0x5000

Sam2016 发表于 2019-7-31 20:12:22

经过一个多星期的煎熬,问题终于解决了!
原因:如问题中描述,当启动文件执行到__main会去执行RTOS的初始化(RTX官方搞的代码,改不了),到osKernelStart();会死机是因为它需要中断服务
解决:bootloader跳转前,需要开启全局中断
缺点:要更改官方文件system_stm32f4xx.c中的地址偏移(VECT_TAB_OFFSET)。因为启动文件的系统初始化函数会设置SCB->VTOR,而后紧接着初始化RTOS,需要使用中断,所以在bootloader跳转前设置,或者在APP的main里面设置,都不可行。

Sam2016 发表于 2019-8-1 16:40:44

奏奏奏 发表于 2019-7-31 20:01
(1)上面沙发的大佬已经讲过最重要一点:“改一下堆栈大小试试看。有时候开得太小,程序也有可能跑飞。”
...

感谢你的回答,问题基本解决了,主要是RTX的初始化需要开启中断。

Sam2016 发表于 2019-8-1 16:51:28

睡了一觉回来,今早又发现死机了,用RTX做点灯程序可以,实际项目APP死机。
经过一天的研究发现,bootloader勾选了RTX,且#include "cmsis_os.h",跳转时开启中断,在APP那边也是会死机的,bootloader不选RTX,注释include,则能成功。或者关闭中断再跳转,在APP的系统初始化函数结束前,开启中断,也可以。
现在问题基本解决。估计后面从APP跳转到bootloader也需要关注这个中断的问题。

发表于 2019-8-1 18:33:52

我认为是你的操作问题,建议进入APP前关闭中断,在APP里面重新初始化中断。另外看一下你的中断关闭是否正确。
页: [1] 2
查看完整版本: STM32F429串口IAP,APP程序HardFault_Handler死机