单片机0xFFFFFFFE死机问题解决

问题描述

最近在忙公司项目的时候,要调试一个新功能,防止BootLoader的干扰,故将BootLoader屏蔽了,直接将app的中断向量表改为默认的,发现运行不了,将所有代码屏蔽掉,只留一个系统滴答定时器,和一个gpio控制灯光闪烁。发现还是运行不了。卡死在如下界面:


0xFFFFFFFE 0000 MOVS r0,r0 卡死在了这一句汇编代码。很明显这个地址已经超出了mcu内存的寻址范围。经过多次测试都是这个问题。

问题排查

反复编译验证后,发现如果将delay函数改为硬件延时同时屏蔽掉系统滴答定时器的初始化,就是工作正常。上图中的delay是调用了系统滴答定时器的计数值。

疑似跟系统定时器有关系,最终发现滴答定时器的中断怎么都进不了。换另外一块板子上的程序也改成只有一个闪灯和系统滴答定时器,然而在另外一块板子上的程序能正常运行。与硬件同事排查了晶振是否起振,都正常。

百度这个问题,也没有发现如何解决,基本分析都是指针指向了内存以外的地址,可能是野指针问题,但是,明显跟我这情况不同,我这代码不可能存在野指针(都没有用到指针)。

问题解决

排查了一圈后,发现领一块板子上的程序运行正常,且这两块板子的单片机型号是一样的,不同的是两块板子的晶振频率不一样。仅此区别,最后还是怀疑代码中哪里有问题。于是从.s文件开始查找。

单片机上电后先是调用了SystemInit函数,该函数执行完毕后,才跳转到main函数执行。找到该函数的定义。

void SystemInit(void)
{
    /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 20) | (3UL << 22)); /* set CP10 and CP11 Full Access */
#endif
    SystemCoreClockUpdate();
#if defined (ROM_EXT_QSPI)
    SystemInit_QspiMem();
#endif /* ROM_EXT_QSPI */
    /* Configure the Vector Table relocation */
    SCB->VTOR = VECT_TAB_OFFSET;    /* Vector Table Relocation */
}

这个函数的最后一句指定了中断向量表的地址。一般来说都是单片机运行的起始地址,对于stm32 或gd32等中断向量表默认是0x8000000,对于hc32是0x0。接着看下VECT_TAB_OFFSET发现该值不是默认值,而被改到了app的中断向量表位置。到这里虎躯一震,感觉问题找到了,立刻将改宏定义改为0x0,编译运行,一切正常,led灯按照2s的周期稳定闪烁。至此问题解决!

吐槽:感谢前同事写的一手好代码。正常使用了bootloader后都是在main函数中,改变中断向量表的位置。而SystemInit这是系统起来前的硬件初始化,基本上不会去动它。很难想象前同事为什么要改这里。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值