ISR中的变量不会增加

时间:2013-10-12 05:37:44

标签: 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*/

现在,当我运行代码几个小时后,我观察到如果头部说119,则存储来自ISR的字节,变为120,并且在下一个中断而不是将下一个字节存储在120并且将头部增加到121,再次变为120并覆盖我的数组中的该字节。可能是什么问题呢?欢迎任何建议!

注意:

  • 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++;
        }

1 个答案:

答案 0 :(得分:1)

您正在错误的抽象级别工作。虽然使用 C对这些东西进行编码是完全可以的,但根据C代码本身找到似乎不可能的问题意味着你需要降低一个级别。

这意味着进入汇编程序/机器架构领域。

以下是一般性建议,因为我实际上知道您的机器架构。

  • 检查编译器生成的实际汇编语言。查看已翻译的代码可能明确可能导致此问题的原因,例如使用缓存值(即使您声明您已标记变量volatile)。

  • 确定在您运行ISR时禁用其他中断。我不知道任何架构的情况,但可能存在,需要您手动禁用和重新启用。

  • 即使在ISR中自动禁用了中断 ,也存在具有优先级中断的体系结构,其中较高优先级的中断可以中断正在进行的较低优先级ISR。还有NMI,不可屏蔽的中断,可以中断任何事情(虽然它们往往用于更严重的事情)。

  • 如果您正在修改ISR之外的变量,请确保在执行此操作时禁用中断。如果更新本身不是中断的原子操作,则可以防止ISR在更新中途运行的可能性。这可能是这种情况,因为增加带有潜在循环缓冲区环绕的指针几乎肯定会是一个多指令(因此也是可中断的)进程。