STM32进debug判断方法及debug寄存器详解与验证过程
STM32如何判断进debug?
进入仿真时,在断点的情况下,我们的一些硬件看门狗可能会无法喂狗,并且我们无法与各个模块通讯,会导致子模块认为断联。
硬件看门狗断点无法喂狗的问题可以通过仿真时控制寄存器关看门狗解决,
但子模块怎么判断进仿真了呢?今天来进行研究验证一下。
Debug system registers
debug的寄存器归属于内核,用的STM32H7,因此我们找到cotex-m7技术手册,可以看到debug的寄存器如下可以大致分为DFSR,DHCSR,DCRSR,DCRDR,DEMCR。
Debug Fault Status Register, DFSR
debug故障状态寄存器,可以检测debug事件由什么触发,比如DWT,BKPT,assertion触发等。
Debug Halting Control and Status Register, DHCSR
debug暂停控制和状态寄存器,这个寄存器中就有我们所需要的debug状态信息,可以判断是否进入debug以及是否断点。
Debug Core Register Selector Register, DCRSR
debug核心寄存器选择寄存器,能够对特定的寄存器进行选择传输,仅在debug下可以使用,比如选择对LR,MSP等寄存器进行传输。
Debug Core Register Data Register, DCRDR
debug核心寄存器数据寄存器,与DCRSR配合使用。
验证DHCSR标志位能否判断进debug
步骤一
进入硬件仿真后通过ozone,查看DHCSR:0xE000EDF0的memory和寄存器,可以看到刚进入仿真时,
S_RETIRE_ST会被置1、
S_REGRDY 会被置1、
C_DEBUGEN 会被置1。
S_RETIRE_ST:每次处理器退出一个或多个指令时,设置为1。
S_REGRDY : 通过DCRDR传输的握手标志:写入DCRSR将清除位到0。完成DCRDR传输,然后将该位设置为1。
C_DEBUGEN :停止调试启用位:0已禁用。1个已启用。如果调试器写入DHCSR以将此位的值从0更改为1,那么它还必须将0写入C_MASKINTS位,否则行为是不可预测的。这个位只能由DAP写入,它会忽略来自软件的写入。在开机复位后,此位为0。
打个断点
打了个断点,让调试阻塞住,观察寄存器和memory,看到多了S_HALT和C_HALT被置为1。
S_HALT:1表明处理器是否处于Debug状态。
C_HALT:处理器停止位 1为停止。
步骤二
根据步骤一,我们知道了,进入调试时会有S_RETIRE_ST,S_REGRDY
,C_DEBUGEN置位,而进入断点暂停后,S_HALT和C_HALT会置位,
而我们的需求是一旦进入调试,不论断不断点,都需要知道此时以及进入调试状态,根据手册猜想C_DEBUGEN应当是符合要求的,但由于我们未进入调试状态时无法读取寄存器的内存,这里需要采用一个简单的验证措施。
首先这里调用core_cm7.h里的coreDebug
然后设置了两个全局变量,若C_DEBUGEN位为1则debug_test2++,若C_DEBUGEN位为0,则debug_test1++
通过ozone进入Debug,此时,只有debug_test2在不断累加,说明C_DEBUGEN为1.
退出debug,过一段时间后再次进入
发现此时debug_test 由1024增长到了5800,说明在关闭debug的时候C_DEBUGEN为0.
总结
我们可以通过DHCSR的C_DEBUGEN位来判断此时是否正在进行调试,与是否正断点和暂停无关。
最后写出的判断代码如下