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

Arm 如果在启用之前连接了GDB,SysTick中断不会触发,arm,embedded,cortex-m,gdbserver,Arm,Embedded,Cortex M,Gdbserver,我有一个ATSAMD21E18A micro,我正在与半托管一起使用。为了使半托管工作,GDB需要在第一条bkpt指令之前“连接”。另一方面,我莫名其妙地发现,如果在配置时已经连接了GDB,SysTick中断将不会触发。如果我想触发SysTick中断,我必须执行重置(通过按钮关闭电源),并在GDB尚未配置micro(即,它尚未发送断点或其他任何东西)时告诉GDB继续,然后在SysTick配置完成后,但在我们开始初始化监视器句柄之前,点击Ctrl-C以初始化调试模式 我已经验证了start函数只在

我有一个ATSAMD21E18A micro,我正在与半托管一起使用。为了使半托管工作,GDB需要在第一条bkpt指令之前“连接”。另一方面,我莫名其妙地发现,如果在配置时已经连接了GDB,SysTick中断将不会触发。如果我想触发SysTick中断,我必须执行重置(通过按钮关闭电源),并在GDB尚未配置micro(即,它尚未发送断点或其他任何东西)时告诉GDB继续,然后在SysTick配置完成后,但在我们开始初始化监视器句柄之前,点击Ctrl-C以初始化调试模式


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

此外,我还可以确认,当调试器未连接(通过Atmel SAM-ICE连接JLinkGDBServer)时,我没有任何问题,此外,我还需要删除半托管内容

此外,即使中断本身没有触发,SysTick计数仍然正确计数。此外,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
}
对于调用SysTick处理程序的运行(在SysTick配置后连接GDB进行硬重置):

所以这里的寄存器值似乎还没有向我揭示任何新的东西。。。请帮助通知我要检查的其他潜在相关登记册

只是出于兴趣,这对我很重要的原因是因为我已经让gprof在这个芯片上工作,基于 虽然我必须在硬重置后的正确时间点击Ctrl-C,但它确实是这样工作的

编辑 我发现我有一个误解,我认为在GDB中运行
load
执行了软重置。此后我发现,尽管它返回执行重置向量,但各种外围设备和其他寄存器实际上并没有重置。如果我在GDB中使用
监视器重置
执行软重置,那么在连接GDB的延迟期间,我不需要Ctrl-C,SysTick和SemiHosting都可以工作


当配置SysTick,然后在GDB中运行
load
时,在没有显式硬复位或软复位的情况下,就会出现问题。在这种情况下,SysTick不会触发中断。我的大部分调试都是这样进行的,加载新代码并立即期望它能够工作,这样我就可以对它进行评估。仅仅运行
监视器重置
是比以前更好的解决方法,但我仍然希望知道SysTick行为不当的原因

我将访问ARM®v6-M体系结构参考手册,看看您能否从中获得一些指导

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

调试停止控制和状态寄存器(DHCSR)能够屏蔽中断,包括systick。这可能是由调试器设置的

我还要检查SYST_RVR(Systick重新加载值寄存器)是否设置为正常状态


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

“我已经验证了start函数只是在可重定位数据段上进行复制,将零段归零,并设置正确的初始堆栈指针值。”它不调用SystemCoreClockUpdate()还有其他CMSIS的东西?@Lundin没错,我们没有使用CMSIS和时钟更新,其他外设配置将在代码后面执行。我已经添加了您请求的所有寄存器信息!请让我知道要检查的任何其他相关寄存器,DHCSR的该位不是S_暂停位吗,表明处理器在重置后不再处于调试状态?今晚下班后我会看看arm,但它似乎要么是调试模式,要么是调试器如何与调试模式交互,都会禁用您的系统。你说得对!我差一个字节。(我将在上面修复它)我不怀疑这与GDB交互有关,我只知道确切的方式。我的意思是,在这两种情况下,我都在GDB中暂停了micro!你能读懂PRIMASK和IPSR的值吗?我想确认调试器在比systick优先级更高的异常处理程序中执行应用程序代码时没有发生奇怪的事情。如果你想进一步挖掘,我认为你必须检查调试器正在执行的所有操作(寄存器写入等)IPSR应该在异常进入和退出时更新,所以我不明白为什么在两个regdump中IPSR都表示您处于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)
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