【发布时间】:2012-02-29 15:37:54
【问题描述】:
我的代码中有一个奇怪的错误,当我尝试调试它时它消失了。
在我的计时器中断(始终运行系统代码)中,我有这样的事情:
if (a && lot && of && conditions)
{
some_global_flag = 1; // breakpoint 2
}
在我的主循环中
if (some_global_flag)
{
some_global_flag = 0;
do_something_very_important(); // breakpoint 1
}
当计时器中的条件(我认为)满足时,永远不会调用主循环中的这个条件。条件是外部的(端口引脚、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
}
该标志不在代码中的其他任何地方使用。它在RAM中,并且在开始时RAM被清零。
现在,当所有断点都被禁用时(或者只启用main中的断点1),代码不能正常工作,函数没有执行。但是,如果我只启用 NOP 上的断点 3,代码就可以工作!断点被触发,继续后,函数被执行。 (它有可见和可听的输出,所以如果它运行起来就很明显了)
更新 2:
定时器中断是可中断的,在其开始时通过一个“SEI”。我删除了该行,但行为并没有以任何明显的方式改变。
更新 3:
我没有使用任何外部存储器。 由于我非常接近闪存中的限制,因此我在编译器中进行了大小优化。
编译器(CodeVision)能负责吗,还是我做错了什么?
【问题讨论】:
-
有什么方法可以尝试添加某种日志记录,而不是设置断点?我通常会犹豫是否建议这样做,但在这种情况下,它可能对系统的干扰较小。特别是,我要记录的是每次通过定时器中断代码时的条件状态。
-
some_global_flag 是如何定义的?你在用
volatile int some_global_flag吗? -
您使用的是外部存储器吗?还是只是内部SRAM?你具体用的是什么芯片?
-
@DipSwitch:我只是在使用一个全局的
unsigned char some_global_flag;,它只在一个源文件中使用。以前我使用了一个位变量,但改变了它以使调试更容易。我非常接近闪光灯的极限。使用volatile并没有改变行为。 -
由于您正在处理中断和并发执行,因此调试器对代码执行的影响是不可忽视的。这不是解决您的问题的方法,而是解释为什么这种行为(错误消失)是完全正常的,而不是使用的工具的缺陷,而是您的应用程序的缺陷(除非您知道自己在做什么,我不知道) t假设)。