UART中断中释放信号量引发的HardFault

背景

项目需要增加一路串口,用来传输BAP IPC message。

BAP:Operator And Display Protocol(Bedien und Anzeigeprotokoll),操作和显示协议。BAP是大众汽车上一种ECU之间通信的协议。 BAP通常用于传输各种车辆信息,从而实现泊车交互、空调调节和仪表控制等功能。该协议通常运行在CAN、LIN总线上,但进年来也被部署到了新兴的车载以太网上。

串口驱动不需要移植,之前代码屏蔽了,直接打开就能使用。只需要在初始化的时候,创建对应的ipc_uart thread即可。但是在实际调试的过程中,遇到了问题。

问题表现:接收到soc发送的串口数据后,进入了HardFault_Handler,进而看门狗复位。

仿真

MCU重启后,查看串口复位原因的打印,关键字rst_source

复位原因有:MCU_SWT0_RST_RESET: SWT0 Timeout,软件看门狗定时器0超时复位。

接上仿真器运行一段时间后,仿真进入了HardFault_Handler

从IDE仿真窗口可以看到进入HardFault_Handler之前的函数调用关系,可以看出代码在uxListRemove这里挂了,这个是freertos模块的api。

Tips:暂停仿真时,S32DS可以查看之前的函数调用情况,不需要查看pc和lr寄存器。实际查看寄存器,得出的结论也是一样的, 在跑uxListRemove函数时出现了问题。

代码分析

UART Reset脚/DMA产生中断后,中断服务函数里面调用了操作系统内核接口(…FromISR()),释放信号量。但是外设的中断优先级高于操作系统内核中断优先级,就会出现系统内核无法抢占当前中断的情况,从而导致系统出错。

解决方案

将FreeRTOS里面的调用中断安全的FreeRTOS API 函数的最高中断优先级调高。

因为FreeRTOS的应用手册中有明确说明,对于可以在中断中调用的api函数,必须保证中断优先级不高于configMAX_SYSCALL_INTERRUPT_PRIORITY,违反操作会导致系统调度出现问题。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2025 wrd
  • 访问人数: | 浏览次数:

      请我喝杯咖啡吧~

      支付宝
      微信