调试学习章节
重要的3张图片
一.CPU模式
Thread:正常运行时,处于Thread模式
Handler:发生异常时,进入Handler模式
二.SP寄存器
代码里使用SP寄存器时,它可能是MSP或PSP,这由CONTROL寄存器决定:
一般而言, 裸机只使用MSP, RTOS里任务使用PSP, 异常处理函数必定使用MSP
栈的使用:
Thread模式下:可以使用MSP、PSP
Handler模式下:必定使用MSP
三.栈帧
栈帧指的是当异常发生时,硬件会帮我们自动把一些寄存器压栈,这些寄存器被称为栈帧。
说明
当异常发生时,硬件在自动压栈的同时,会将 LR(链接寄存器)赋值为一个特殊的“异常返回标志”(EXC_RETURN),而不是保存普通函数调用的返回地址。
当异常处理函数执行完毕,CPU 执行 BX LR 指令试图跳转到 LR 所存的地址时,它发现该值是一个 32 位的特殊值(而非普通的 PC 地址),于是硬件不会真的去该地址取指,而是触发“异常返回流程”:从堆栈中自动弹出(恢复)之前硬件压栈的寄存器,并将 PC 设置为被中断前的下一条指令地址,从而实现无缝恢复现场。
根据这个特殊值,我们可以发现:
bit[0]:1
bit[1]:0
bif[2]: 1:说明发生异常前的sp为psp;0:说明发生异常前的sp为msp,但此时异常时sp为msp
bit[3]: 1:说明发生异常前,cpu为Thread模式;0:说明发生异常前,cpu为Handler模式
bit[4]: 1:说明使用了FPU,用的栈帧多一些寄存器(如上图);0:说明没使用FPU,用的栈帧(如上图)。
四.BUG
当发生bug时,观察sp指向的栈
1.看PC值
2.看LR值
3.如果PC和LR都被破坏了的话,看疑似LR值
。bit0肯定为1,因为为1才是Thumb指令,Cortex-M系列只支持Thumb指令
。一般为0x08开头,因为位于ROM上
。addr-4:为BL或者BLX指令