一、目的
S32K118 系列中,如果因为某些功能,比如说低功耗、禁用调试器或者其他不方便 Debug 的场景,恰好代码可能会进入 DefaultISR 中,怎么了解到相应的信息来判断是那里出现了问题这个是比较头疼的问题,本文的目的是通过串口打印出这些信息。当然这种方式是有局限的,必须是进入 DefaultISR 的时候串口还能正常运行。
二、异常处理方式
如图1,对于 M0+ 核来说,当异常(tail-chained 或者 late-arriving 异常除外)发生之后,会在栈里面进行以下方式的压栈,所以可以利用这个特性,获取 LR,PC 值。
图 1
对于特殊寄存器,可以直接获取 PSR 寄存器来看(图 1 压栈虽然也有 xPSR,理论上也是有显示异常向量号的,但是这里实际打印出来没有异常向量号,原因暂且未知)。PSR 寄存器如图 2所示。
图 2,引用于 ARM:《DDI0419E_armv6m_arm.pdf》
三、代码
对于 S32K118 芯片,使用 S32DS 作为开发软件平台,所以首先需要在 Project_Settings->Startup_Code->Startup_S32K118.S ,在 label DefaultISR里面写入(注意这里面最好不大于):
mrs r0, msp /* 将 SP 寄存器存到 r0 */
add r4, sp, #20
ldr r1,[r4] /* 将 lr 寄存器存到 r1 */
add r4, sp, #24
ldr r2,[r4] /* 将 pc 寄存器存到 r2 */
// add r4, sp, #28
mrs r3, psr /* 将 psr 寄存器存到 r3 */
blx resgisterPrintf /* 这里的 label resgisterPrintf 取决于自己的实现 */
如图 3。
图 3
对于 resgisterPrintf 的实现如图 4,这里的打印函数可以自己实现,推荐串口不使用中断的方式发送,而是使用轮询标志位的方式实现发送:
图 4
使用 PIT 中断进入 DeafultISR ,打印如图 5。可以看到 sp,lr,pc 和 psr。psr 一般看最后的异常向量号,这里是 0x24,可以找参考手册 pdf 里面的附件 S32K1xx_DMA_Interrupt_mapping.xlsx,如图 6,0x24 对应的是 PIT。
图 5
图 6,引用于 NXP: 《S32K-RM》
四、参考文档
(1) ARM:《DDI0419E_armv6m_arm.pdf》
(2) NXP: 《S32K-RM》
评论