我有一个ISR,它增加了数组的变量'head'。问题是在几个小时后,即使在增加后该变量也会回到之前的值。类似的东西:
array[head] = val;
head++;
/*val is the byte that came from ISR and I am assigning it to my buffer 'array' at head position*/
现在,当我运行代码几个小时后,我观察到如果头部说119,则存储来自ISR的字节,变为120,并且在下一个中断而不是将下一个字节存储在120并且将头部增加到121,再次变为120并覆盖我的数组中的该字节。可能是什么问题呢?欢迎任何建议!
注意:
代码段:
/*before storing on to the circular buffer check whether it is full*/
if ((COM1RxBufHead == COM1RxBufTail - 1) ||((COM1RxBufHead == (COM1RXBUFSIZE - 1)) && (COM1RxBufTail == 0)))
{
logDEBUG("[FULL]");
U1STAbits.OERR = 0;
return;
}
else
{
/* Byte can be safely stored on to buffer*/
COM1RxBuf[COM1RxBufHead] = U1RXREG;
if (COM1RxBufHead == (COM1RXBUFSIZE - 1))
{
COM1RxBufHead = 0;
}
else
{
COM1RxBufHead++;
}
答案 0 :(得分:1)
您正在错误的抽象级别工作。虽然使用 C对这些东西进行编码是完全可以的,但根据C代码本身找到似乎不可能的问题意味着你需要降低一个级别。
这意味着进入汇编程序/机器架构领域。
以下是一般性建议,因为我实际上知道您的机器架构。
检查编译器生成的实际汇编语言。查看已翻译的代码可能明确可能导致此问题的原因,例如使用缓存值(即使您声明您已标记变量volatile
)。
让确定在您运行ISR时禁用其他中断。我不知道任何架构的情况,但可能存在,需要您手动禁用和重新启用。
即使在ISR中自动禁用了中断 ,也存在具有优先级中断的体系结构,其中较高优先级的中断可以中断正在进行的较低优先级ISR。还有NMI,不可屏蔽的中断,可以中断任何事情(虽然它们往往用于更严重的事情)。
如果您正在修改ISR之外的变量,请确保在执行此操作时禁用中断。如果更新本身不是中断的原子操作,则可以防止ISR在更新中途运行的可能性。这可能是这种情况,因为增加带有潜在循环缓冲区环绕的指针几乎肯定会是一个多指令(因此也是可中断的)进程。