我有一个用于半主机的ATSAMD21E18A micro。为了使半主机正常工作,需要在第一个bkpt指令之前“附加” GDB。另一方面,我莫名其妙地发现,如果在配置GDB时已经附加了SysTick中断,则不会触发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行为异常的原因! 最佳答案
我将访问《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重新加载值寄存器)是否设置为正常。
我没有销售代表就您的问题发表评论,但我希望这可以使您朝着富有成效的方向发展:)