C 变量在ISR中不递增
我有一个ISR,它增加一个数组的变量“head”。问题是,几个小时后,即使在递增后,该变量也会返回到其以前的值。比如:C 变量在ISR中不递增,c,embedded,C,Embedded,我有一个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*/ 现在,当我运行代码几个小时时,我观察到,如果head是119,存储了来自ISR的字节,变成了120,在下一次中断时,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*/
现在,当我运行代码几个小时时,我观察到,如果head是119,存储了来自ISR的字节,变成了120,在下一次中断时,head再次变成120,并覆盖了数组中的该字节,而不是将下一个字节存储在120上,并将head增加到121。有什么问题吗?欢迎提出任何建议
注:
- head是一个不稳定的变量
- 中断的速度非常高
/*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++;
}
您在错误的抽象级别上工作。尽管使用C来编写代码是完全可以的,但是基于C代码本身发现似乎不可能的问题意味着您需要降低一个级别 这意味着进入汇编程序/机器体系结构领域 以下是一般性的建议,因为我并不了解您的机器架构
- 检查编译器生成的实际汇编语言。查看翻译后的代码可以清楚地看出是什么导致了此问题,例如使用缓存值(即使您声明已将变量
)标记为volatile
- 确保在运行ISR时禁用更多中断。我不知道有哪种架构不是这样的,但它们可能存在,需要您手动禁用和重新启用
- 即使中断在ISR中自动禁用,也存在具有中断优先级的体系结构,其中优先级较高的体系结构可以中断正在进行的优先级较低的ISR。还有NMI,即不可屏蔽的中断,它可以中断任何事情(尽管它们往往用于更严重的事情)
- 如果要在ISR之外修改变量,请确保在修改时禁用中断。这是为了防止ISR在更新中途运行的可能性,如果更新本身不是原子操作中断。很可能是这样的,因为用可能的循环缓冲区环绕来递增指针几乎肯定是一个多指令(因此是可中断的)过程
volatile
无法确保从内存中读取、修改和写回该变量。您可能需要使用某种锁定?据我所知,这种ISR是原子的。在阅读时,我也会锁定以避免任何其他中断。请详细解释一下你的其他意思。那么你确定ISR没有嵌套?你有任何[完整]日志条目吗?logDEBUG()调用是否可以从中断处理程序安全地工作?