0

我在 Raspberry Pi Pico(RP2040,Cortex-M0+ 内核,使用 JLink SWD 通过 VSCode cortex-debug 进行调试)上运行,我看到有关 PendSV 的奇怪行为。

紧接着,SVCall 异常处理程序通过 ICSR 寄存器请求 PendSV。但是在异常返回时,不是尾链 PendSV,而是执行返回到调用代码并继续非异常执行。

ICSR 寄存器始终显示待处理的 PendSV,即使在重复执行线程代码指令时也是如此。系统处理程序优先级全部为零,IRQ 优先级较低。

在此处输入图像描述

根据 ARMv6-M 参考手册,PendSV 不能被禁用。

那么,我错过了什么会导致这种行为?

编辑添加:

也许这是一个调试器交互?JLink 软件 (v4.95d) 仍处于测试阶段...

我看到调试器实际上可以禁用 PendSV 和 Systick - C1.5.1 调试步进:“可选地,调试器可以将 DHCSR.C_MASKINTS 设置为 1 以防止发生 PendSV、SysTick 和外部可配置中断。这被描述为屏蔽这些中断. C1-326 页的表 C1-7 总结了指令步进控制。

4

1 回答 1

0

事实证明,问题是由单步执行写入 ICSR 中 PENDSVSET 位的指令引起的:该位已设置,并且 VECTPENDING 字段显示0xe,但 PendSV 从未触发。

在该指令上自由运行到稍后的断点会看到 PendSV 正确触发。

所以它确实是一个调试器交互。

这是否与@cooperised 建议的那样与禁止中断有关尚不清楚 - DHCSR 的 C_MASKINTS 位始终读取为零,但在实际步进操作期间如何操作该位在此级别不可见。

这让我想知道 JLink 执行该步骤的方式是否会导致不可预测/不确定的行为 - 例如,根据 C_MASKINTS 描述中的警告。或者这可能只是在这种情况下在 M0+ 中发生的事情,而我以前从未单步执行过这条指令。

在任何情况下,解决方法都是不单步执行设置 PENDSVSET 的指令。

编辑添加:

最后,@cooperised 是正确的。

在更加注意准确区分单步执行(包括跳过函数调用)和运行(包括运行到下一条指令)之间,很明显单步执行会禁用包括 PendSV 在内的中断。

于 2021-02-17T12:41:53.393 回答