我有一个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不是将下一个字节存储在120上,而是将head递增到121,head再次变成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++;
}
最佳答案
您在错误的抽象级别上工作尽管使用C来编写这些东西是完全可以的,但是基于C代码本身发现似乎不可能的问题意味着您需要降低一个级别。
这意味着进入汇编/机器架构领域。
以下是一般性的建议,只是因为我不知道你的机器架构。
检查编译器生成的实际汇编语言看到翻译后的代码可能会很明显地看出是什么导致了这个问题,比如缓存值的使用(即使您声明您已经标记了变量volatile
)。
运行ISR时,请确保禁用进一步的中断我不知道我的头顶上的任何架构,情况并非如此,但它们可能存在,要求您禁用和重新启用手动。
即使中断在ISR中被自动禁用,也有一些体系结构具有中断的优先级,在这些体系结构中,较高优先级的中断可以中断正在进行的较低优先级的ISR也有NMI,不可屏蔽的中断,可以中断任何事情(尽管它们往往用于更严重的事情)。
如果要在ISR外部修改变量,请确保在执行此操作时禁用中断这是为了防止ISR在更新的中途运行,如果更新本身不是原子操作中断这种情况很可能发生,因为使用潜在的循环缓冲区包装递增指针几乎肯定是一个多指令(因此是可中断的)过程。
关于c - ISR中的变量未增加,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19330947/