我有一个用于半主机的ATSAMD21E18A微型计算机。为了使半主机正常工作,需要在第一个bkpt指令之前“附加” GDB。另一方面,我莫名其妙地发现,如果在配置GDB时已经附加了SysTick中断,则不会触发。如果我想触发SysTick中断,我必须执行一次重置(通过按钮关闭电源),并告诉GDB在尚未配置Micro的情况下继续运行(也就是说,它尚未发送断点或),然后在SysTick配置之后但到达initialise_monitor_handles
之前按Ctrl-C初始化调试模式。
我已经验证了start函数仅在可重定位数据段上复制,将零段清零并设置正确的初始堆栈指针值。我们正在编写没有CMSIS这样的库的代码。
除了无需删除调试器(通过Atmel SAM-ICE的JLinkGDBServer),我还可以确认我没有问题,除了需要删除半托管的东西。
此外,即使中断本身不触发,SysTick COUNT仍然可以正确计数。实际上,发生这种情况时,也会设置ICSR中的SysTick挂起中断位PENDSTSET。
我的代码如下:
int main()
{
// enable system timer interrupt
SYS_TICK->STATUS = 0; // (CSR)
SYS_TICK->PERIOD = 48000; // (RVR) fire at 1khz for 48mhz clock
SYS_TICK->STATUS = 0b111; // use processor clock, w/ interrupt, and enabled
SYS_TICK->COUNT = 1; // (CVR) avoid high unknown value
// dumb busy loop
util_idle_ms(2000); // <<< I hit Ctrl-C to break here!
initialise_monitor_handles();
// ... more system initialization and everything else
}
我在StackOverflow上看到了一些类似的看似问题,但是它们似乎太模糊而无法获得好的答案。
编辑: 这可能是在繁忙循环期间为未调用SysTick处理程序的运行获取的相关寄存器值(无硬重置,在配置SysTick之前已附加GDB):
SYS_TICK_CSR/STATUS: 0x10007
SYS_TICK_RVR/PERIOD: 48000
SYS_TICK_CVR/COUNT: 5245 (varies of course)
NVC_ISER: 0 (and we expect this since SysTick is considered an exception, and not an interrupt)
DHCSR: 0x30003/0x1030003 (C_MASKINTS is not set; I've seen both values show up)
ICSR: 0x400f00f (it really wants to run the SysTick handler)
PRIMASK: 0
xPSR: 0x2100000f (IPSR is 0x0f/SysTick)
对于调用SysTick处理程序的运行就很好了(在SysTick配置后通过GDB进行硬重置):
SYS_TICK_CSR/STATUS: 0x10007
SYS_TICK_RVR/PERIOD: 48000
SYS_TICK_CVR/COUNT: 16892 (varies of course)
NVC_ISER: 0
DHCSR: 0x10003/0x1030003 (I've seen both values show up)
ICSR: 0 (SysTick handler already run)
PRIMASK: 0
xPSR: 0x2100000f
所以这里的寄存器值似乎还没有向我透露任何新信息...请帮助我通知其他可能相关的寄存器以供检查!
出于兴趣,这对我很重要的原因是因为我已经基于https://mcuoneclipse.com/2015/08/23/tutorial-using-gnu-profiling-gprof-with-arm-cortex-m/使gprof在该芯片上工作 而且尽管在硬重置后我确实必须在正确的时间点按Ctrl-C,但它确实可以像这样工作!
修改
我发现我误以为我认为在GDB中运行load
会执行软重置。从那以后,我发现尽管它返回执行以复位向量,但实际上各种外设和其他寄存器都没有复位。如果我使用monitor reset
在GDB中执行软重置,那么在延迟连接GDB时不需要Ctrl-C,并且SysTick和SemiHosting都可以工作。
当配置SysTick然后在没有显式的硬复位或软复位的情况下在GDB中运行load
时,会发生问题。在这种情况下,SysTick不会触发中断。我的大部分调试工作都是这样,加载新代码并立即期望它能工作,因此我可以对其进行评估。仅运行monitor reset
是比以前更好的解决方法,但是我仍然希望知道SysTick行为不当的原因!
答案 0 :(得分:3)
我将访问《ARM®v6-M体系结构参考手册》,看看您是否可以从中获得一些指导。 https://static.docs.arm.com/ddi0419/d/DDI0419D_armv6m_arm.pdf
观察与您未在问题中包括的Systick有关的寄存器状态。如果您无法根据这些寄存器找出问题,请编辑您的问题,然后在此处发布寄存器值(NVIC ISER,与systick config相关的所有寄存器,DHCSR以及您认为相关的任何其他寄存器)。它们将是获得更多反馈的关键。
调试停止控制和状态寄存器(DHCSR)具有屏蔽包括systick在内的中断的功能。也许这是由调试器设置的吗?
bit 3 of the DHCSR looks relevant
我还要检查SYST_RVR(Systick重新加载值寄存器)是否设置为正常。
我没有代表对您的问题发表评论,但我希望这可以使您朝着富有成效的方向发展:)