当断点设置时,薛定谔虫就会消失

vsz*_*vsz 8 c embedded atmega jtag

我的代码中有一个奇怪的错误,当我尝试调试时会消失.

在我的计时器中断(总是运行系统自动收报机)我有这样的事情:

 if (a && lot && of && conditions)
 {
     some_global_flag = 1;                   // breakpoint 2
 }
Run Code Online (Sandbox Code Playgroud)

在我的主循环中我有

 if (some_global_flag)
 {
     some_global_flag = 0;
     do_something_very_important();   // breakpoint 1
 }
Run Code Online (Sandbox Code Playgroud)

当计时器中的条件(我认为)满足时,主循环中的这种情况永远不会被调用.条件是外部的(portpins,ADC结果等).首先,我在位置1处放置一个断点,它永远不会被触发.

为了检查它,我把断点nr.2在线some_global_flag = 1;,在这种情况下代码工作:当条件为真时触发两个断点.

更新1:

要研究是否有一些时间条件负责,并且if如果在没有调试的情况下运行,则永远不会输入计时器,我在计时器中添加了以下内容:

 if (a && lot && of && conditions)
 {
     some_global_flag = 1;                   // breakpoint 2
 }


 if (some_global_flag)
 {
     #asm("NOP");    // breakpoint 3
 }
Run Code Online (Sandbox Code Playgroud)

该标志不会在代码中的任何其他位置使用.它在RAM中,RAM在开始时清零.

现在,当所有断点都被禁用时(或者只启用了main中的断点1),代码无法正常工作,则不执行该功能.但是,如果我只在NOP上启用断点3,则代码可以正常工作!断点被触发,继续后,执行该功能.(它有可见和可听的输出,所以它很明显,如果它运行)

更新2:

定时器中断通过其开头的"SEI"是可中断的.我删除了该行,但行为没有以任何明显的方式改变.

更新3:

我没有使用任何外部存储器.因为我非常接近flash中的限制,所以我在编译器中进行了最大化优化.

编译器(CodeVision)可以负责,还是我做错了什么?

Dip*_*tch 5

这可能是典型的优化/调试错误。确保将some_global_flag其标记为易失性。无论您喜欢什么,都可以是int uint8 uint64。

volatile int some_global_flag
Run Code Online (Sandbox Code Playgroud)

这样,您告诉编译器不要对some_global_flag的值进行任何假设。您必须执行此操作,因为编译器/优化器看不到对中断例程的任何调用,因此它假定some_global_flag始终为0(初始状态)且从未更改。

抱歉,误读了您已经尝试过的部分...

您可以尝试使用av​​r-gcc编译代码,看看您是否具有相同的行为...


old*_*mer 5

调试器可以更改处理器运行和代码执行的方式,因此这并不奇怪。

分而治之。开始删除东西,直到它起作用。与此并行的是,不添加任何内容,仅添加计时器中断和主循环中的几行代码,其中do_something_very_important()很简单,例如使led闪烁或将某些东西吐出uart。如果这样不起作用,您将无法使用更大的应用程序。如果这样行得通,那就开始在中断中添加初始化代码和更多条件,但不要使主循环复杂化,只需要描述以下几行。通过添加更多代码直到失败,增加中断处理程序的条件。

当到达边界时,您可以添加一件事,然后失败然后将其删除,然后再失败,那么请进行一些反汇编以查看它是否是编译器。如果不明显,这可能需要另外一张SO票证,“为什么添加时我的avr中断处理程序会中断...”

如果您能够将其分解为少量的代码行(大约十二个主代码行)和少量的中断代码行,请发布该代码,以便其他人可以在自己的硬件上进行尝试并可能并行解决。


vsz*_*vsz 4

这可能看起来很奇怪,但最终证明是由其中一条输入线路上的强瞬变引起的(该输入线路为系统供电,但其 ADC 测量也用作条件)。

系统可能会出现短时间的周期性断电,重要的临时数据保存在部分内部SRAM中,启动后不会被清除,并且设计为随使用保留数据(长达10分钟或更长时间)当CPU处于欠压状态时,使用一个小电容器。

我没有在问题中发布此内容,因为我测试了系统的这一部分并且运行良好,所以我不想让您偏离路线。

我最后发现,在一个产生非常强瞬变的环境中使用了一项新功能,而我的问题中的条件之一取决于“永久 RAM”中的这些变量之一的状态,最后使用断点使我免受瞬变的影响。

最后通过调整时间解决了问题。

编辑:帮助我找到问题所在的是,我在“永久 RAM”区域中记录了最重要变量的值,并且可以看到其中一些变量已损坏。

  • 这实际上是此类问题的一般原因——调试往往会以某种方式扰乱时序,如果您遇到对时序问题敏感的情况,那么调试肯定会影响它。不过,调试如何影响它通常没有太多有意义的信息(部分原因是很难判断调试如何影响时序)。 (2认同)
  • 我确实认为在这个答案中添加一些内容来描述您最终如何诊断问题以及您发现的内容会很有趣。另外,由于您知道这是正确的答案,因此您应该接受它的完整性。:) (2认同)