如果GDB在启用之前连接,则不会触发SysTick中断

问题描述 投票:4回答:1

我有一个ATSAMD21E18A微型,我正在使用半主机。为了使半主机工作,GDB需要在第一个bkpt指令之前“附加”。另一方面,我莫名其妙地发现,如果在配置GDB时已经连接了SysTick中断,则不会触发。如果我想要触发SysTick中断,我必须执行复位(通过按钮关闭电源)并告诉GDB在尚未配置微控制器时继续(也就是说,它没有发送断点或其他任何事情),然后在SysTick配置之后但在我们到达initialise_monitor_handles之前按Ctrl-C初始化调试模式。

我已经验证了start函数只是复制可重定位数据段,将零段归零,并设置正确的初始堆栈指针值。我们正在编写没有像CMSIS这样的库的代码。

此外,我可以确认在没有连接调试器时没有问题(JLinkGDBServer通过Atmel SAM-ICE),除了需要删除半主机的东西。

此外,即使中断本身不触发,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时会出现问题,然后load在GDB中运行,没有明确的硬重置或软重置。在这种情况下,SysTick不会触发中断。我的大多数调试都是这样的,加载新代码并立即期望它能够工作,所以我可以评估它。刚刚运行monitor reset是比以前更好的解决方法,但我仍然更愿意知道SysTick不当行为的原因!

arm embedded cortex-m gdbserver
1个回答
3
投票

我将访问ARM®v6-M架构参考手册,看看是否可以从中获得一些指导。 https://static.docs.arm.com/ddi0419/d/DDI0419D_armv6m_arm.pdf

观察您未在问题中包含的与Systick相关的寄存器状态。如果您无法根据这些寄存器找出问题,请编辑您的问题并在此处发布寄存器值(NVIC ISER,与systick配置相关的所有寄存器,DHCSR以及您认为相关的任何其他寄存器)。它们将是获得更多反馈的关键。

调试暂停控制和状态寄存器(DHCSR)能够屏蔽包括systick在内的中断。也许这是由调试器设置的?

bit 3 of the DHCSR looks relevant

我还要检查SYST_RVR(Systick重载值寄存器)是否设置为理智。

我没有代表对您的问题发表评论,但我希望这可以让您朝着富有成效的方向前进:)

© www.soinside.com 2019 - 2024. All rights reserved.