简体   繁体   English

为什么在为 Cortex-M 中断处理程序生成的程序集中存在死循环?

[英]Why there is a dead loop in the generated assembly for a Cortex-M interrupt handler?

I am learning the Cortex-M with the MDK uVision IDE.我正在使用 MDK uVision IDE 学习 Cortex-M。 I wrote a simple SysTick_Handler() to replace the WEAK default SysTick_Handler() which is a simple dead loop.我编写了一个简单的SysTick_Handler()来替换 WEAK 默认的SysTick_Handler() ,这是一个简单的死循环。

My SysTick_Handler() :我的SysTick_Handler()

在此处输入图片说明

The disassembly:拆解:

在此处输入图片说明

I am confused by the the highlighted assembly line.我对突出显示的装配线感到困惑。 It is simply a dead loop.这简直就是一个死循环。

Why is it there?为什么会在那里? Why the toolchain still generated it despite that I already overwrite the WEAK default implementation with my own SysTick_Handler ?尽管我已经用自己的SysTick_Handler覆盖了 WEAK 默认实现,但为什么工具链仍然生成它?

I can still place a breakpoint at that line and it can be hit .我仍然可以在该行上放置一个断点,并且它可以被 hit And in that case, my code will never be executed.在这种情况下,我的代码将永远不会被执行。

But strange thing is, if I removed the breakpoint at that line, my code can then be reached.但奇怪的是,如果我删除了该行的断点,则可以访问我的代码。 How is that possible?这怎么可能?

(Thanks to all the hints the community provided. I think I can explain it now.) (感谢社区提供的所有提示。我想我现在可以解释了。)

The dead loop is part of my main() function, which is like below.死循环是我的main()函数的一部分,如下所示。 The main() function is just above my SysTick_Handler in the same C file. main()函数就在同一个 C 文件中我的SysTick_Handler之上。

int main (void)
{
    LED_Initialize();
    SysTick->VAL = 0x9000;                                                                                   
    //Start value for the sys Tick counter
    SysTick->LOAD = 0x9000;                                                                                  
    //Reload value 
    SysTick->CTRL = SYSTICK_INTERRUPT_ENABLE|SYSTICK_COUNT_ENABLE;  //Start and enable interrupt
    while(1)
    {
        ;  // <========= This is the dead loop I saw!
    }
}

To double confirm, I modified the while loop to below:为了再次确认,我将 while 循环修改为以下内容:

int main (void)
{
    volatile int32_t jj = 0;
    LED_Initialize();
    SysTick->VAL = 0x9000;                                                                                  //Start value for the sys Tick counter
    SysTick->LOAD = 0x9000;                                                                                 //Reload value 
    SysTick->CTRL = SYSTICK_INTERRUPT_ENABLE|SYSTICK_COUNT_ENABLE;  //Start and enable interrupt
    while(1)
    {
        ;
        jj+=0x12345; // <====== add some landmark value
    }
}

The generated code is like this now:现在生成的代码是这样的:

在此处输入图片说明

Though it is still placed under the SysTick_Handler .虽然它仍然放在SysTick_Handler I place a break point there to check what's really going on:我在那里放置了一个断点来检查真正发生了什么:

在此处输入图片说明

在此处输入图片说明

The R1 is the constant 0x12345 . R1是常数0x12345 The R0 is the local variable jj . R0是局部变量jj We can see the R1 does contain the landmark value 0x12345 , which is added to R0 ( jj ).我们可以看到R1确实包含地标值0x12345 ,它被添加到R0 ( jj )。 So it must be part of my while(1) loop in the main() .所以它必须是我在main()中的while(1)循环的一部分。

So, the disassembly is correct.所以,拆解是正确的。 Only that the debugger failed to provide a correct interleaving between the source and the disassembly.只是调试器未能在源代码和反汇编之间提供正确的交错。

And btw, remember to rebuild the target after modifying the code otherwise the uVision IDE debugger will not reflect the latest change....顺便说一句,请记住在修改代码后重建目标,否则 uVision IDE 调试器将不会反映最新的更改....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM