pedropeng 发表于 2019-8-19 00:37:05

ucosii跑飞到HardFault_Handler

main里面创建一个启动任务
OSInit();
OSTaskCreate(startTask,0,&START_TASK_STK,START_TASK_PRIO);
OSStart();

startTask里调用了两次OSTimeDly就程序就跑飞了,其中systick的初始化再startTask里。
查看fault report发现这个hardfault是由usagefault上访造成的,定位错误代码

引起异常的代码如下:
void _LibDwLoadLde(void)
{
................
OSTimeDly(50);
...............
OSTimeDly(450);
...............
}程序在退出该函数是出现异常的。然后我开始查看OSTimeDly前后的寄存器
这是OSTimeDly执行之前的psp
这个事执行OSTimeDly时跳到OS_CPU_PendSVHandler里时的psp,注意这是psp已经发生变化,超过了芯片自动保存的值
这是延时时间到返回到OSTimeDly下一行时的psp,此时的psp和执行之前的psp应该一致程序才不会跑飞,这的新的psp导致退出该函数时出栈值错误
这是通过错误的psp退出函数时,出栈的值,此时的pc为0x00000000,肯定是不对的,其值应该是随机的,因此报出异常,最终导致该错误是第三张图,psp为0x20001c98,这个地方错了,导致后面已练成的出栈错误。
问题分析到这里卡住了,不知道这里的psp为什么会莫名其妙的被修改,正常情况应该是中断后自动保存r0-r4,r11,cpsr(好像就这些了,记不太清了),psp应该减小24即20001CE8。

butterflyspring 发表于 2019-9-9 17:04:28

看看OSTimeDly(50);这个函数的源码,是不是代码原理导致调用时需要注意一下呢:)

stock999 发表于 2020-1-18 00:06:08

PendSVC中断优先级要设置为最低,且在 PendSVC 的第1条语句要关中断
   CPSID   I                                                   ; Prevent interruption during context switch
页: [1]
查看完整版本: ucosii跑飞到HardFault_Handler