瑞萨RL78单片机非法内存访问异常:如何获取复位前程序计数器值?
获取单片机复位前程序计数器(PC)值的方法(以瑞萨RL78为例)
瑞萨RL78系列的具体操作
- 利用硬件自带的PC捕获功能
RL78的G13、G14等主流型号内置了复位状态寄存器RSTSR和PC捕获机制。当非法内存访问触发复位时,硬件会自动把复位前的PC值锁存到PCL/PCH(部分型号是CAPPCL/CAPPCH)寄存器里。要注意:- 复位后得第一时间读这些寄存器,不然后续初始化代码很可能把它们覆盖了
- 必须在编译器配置里开PC捕获功能——比如用CS+开发的话,要在硬件配置或调试选项里勾选对应开关
- 软件备份+PC值日志
如果你的RL78型号没硬件PC捕获,就自己做个简单的日志:在UART中断、内存操作这类关键代码里,定期把当前PC值存到内部EEPROM里。复位后先读EEPROM的最后备份,再结合RSTSR判断是不是非法访问复位,能帮你缩小问题范围。
其他单片机的通用方案
- 异常服务例程(ISR)抓PC
像STM32、TI MSP430这类中高端单片机,遇到非法内存访问不会直接复位,会先进入HardFault或BusFault异常。这时候在异常服务函数里,能从栈帧里读出复位前的PC值——栈里会自动保存R0-R3、LR、PC这些寄存器。你可以把这个PC值写到EEPROM,或者如果UART还能工作,直接发出来。 - RAM环形缓冲区存PC日志
低端单片机没异常捕获的话,搞个RAM环形缓冲区,在主循环、各个中断里定期把当前PC值写进去。要是程序跑飞触发看门狗复位,复位后先读RAM里的最后有效PC值(很多单片机复位后RAM数据不会立刻丢失),再存到非易失性存储里留底。 - 在线调试器实时抓
用E2 emulator、J-Link这类调试器连单片机,开“halt on reset”功能。复位的时候调试器会自动停在复位入口,这时候看调试器的调用栈或者寄存器窗口,就能回溯到复位前的PC值。不过偶发问题可能得挂着调试器等很久才能抓到。
内容的提问来源于stack exchange,提问作者Nayan Bhatia
相关产品推荐
相关产品推荐

