2

我有一个 ISR,它增加了一个数组的变量“头”。问题是几个小时后,这个变量即使在增加之后也会恢复到以前的值。就像是:

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,并且在下一个中断时,而不是将下一个字节存储在 120 并将 head 增加到 121,head 再次变为 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++;
        }
4

1 回答 1

1

您在错误的抽象级别上工作。尽管使用C 对这些东西进行编码是完全可以的,但是发现基于 C 代码本身似乎不可能的问题意味着您需要降级。

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

以下只是一般性建议,因为我实际上并不了解您的机器架构。

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

  • 确保在运行 ISR 时禁用更多中断我不知道任何架构不是这种情况,但它们可能存在,需要您手动禁用和重新启用。

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

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

于 2015-01-21T02:45:45.740 回答