3

我正在 stm32f4xx uC 上用 C 语言开发一个嵌入式项目。

我有一段代码连续执行循环操作 XYZ,有时 TIM4 中断会更改一些全局参数并导致操作 XYZ 重新启动。

代码是这样的:

for (;;) {
       //line A
    XYZ;
       //line B
}

XYZ 是一项复杂的操作,涉及在缓冲区和其他缓冲区之间传输数据。

TIM4 中断处理程序执行此操作:停止 XYZ 并更改一些影响 XYZ 操作的全局变量。

所以基本上我希望 XYZ 重复执行,TIM4 中断来停止 XYZ,更改参数,然后必须通过使用新的全局参数重新启动 XYZ 来重新启动循环。

问题是:由于 XYZ 有许多指令,TIM4 IRQ 可能会在它的中间出现,并且在 IRQHandler 更改全局变量之后,操作从 XYZ 的中间恢复,这会破坏程序。

我的初始解决方案:使用 __disable_irq() 禁用线路 A 上的中断,并使用 __enable_irq() 在线路 B 上恢复它们

失败,因为 XYZ 复杂操作必须使用其他中断(TIM4 除外)。

下一个解决方案仅禁用线路 A 上的 TIM4 中断:

TIM_ITConfig(TIM4, TIM_IT_Update , DISABLE) 

并在 B 行重新启用它:

TIM_ITConfig(TIM4, TIM_IT_Update , ENABLE)

失败,因为我丢失了中断:当 int 恢复时,在 XYZ 期间到达的中断被忽略。这是一个大问题(其中一个原因是 TIM4 IRQHandler 更改了全局变量,然后再次激活 TIM4 以便稍后发出中断,我这样做是因为中断之间的周期不同)。

谁能给我一个解决这个问题的方法?有没有更好的方法来禁用/恢复 TIM4 IRQ 而不会丢失任何中断?

4

5 回答 5

1

有几个选项可能可用(我不是 100% 了解 ARM 架构):

  • 更改中断优先级/级别屏蔽寄存器以仅屏蔽 TIM4,让其他中断发生。希望如果 TIM4 在被屏蔽时被触发,在恢复关卡掩码时它会记住并触发 ISR。
  • 屏蔽中断并手动检查在 XYZ 期间设置的 TIM4 中断标志
  • 将 XYZ 分成更小的部分,仅在绝对必要时屏蔽 TIM4。
  • 对数据副本进行操作,可选择检查 TIM4 中断标志​​以决定是继续/保留结果还是丢弃并重新启动。
  • 如果 TIM4 可能很快触发,请检查时间并避免启动 XYZ,或者仅在 TIM4 触发后运行 XYZ N 次。
于 2012-12-11T14:47:40.643 回答
1

完成 XYZ 后,您可以对全局变量的副本进行操作并从中断中换入新值。

从问题中不清楚是否需要在全局变量更改时立即停止处理 XYZ,或者是否可以等到 XYZ 完成处理以交换变量的新副本。我将在您需要摆脱处理 XYZ 的假设下进行操作,但这很容易做到。

代码看起来像这样:

volatile int x;
int x_prime;

int main(void)
{
    while(1)
    {
        //copy in new global parameter value
        x_prime = x;

        while(1)
        {
            //do stuff with x_prime
            if (x_prime != x)
            {
                break;
            }

            //do more stuff with x_prime
            if (x_prime != x)
            {
                break;
            }
        }
    }
}

// interrupt handler
void TIM_IT_Update(void)
{
    x++;
}

这些break模式假设你没有改变x_prime。如果需要修改x_prime,则需要另一个副本。

由于永远不会禁用中断,因此您永远不必担心丢失任何中断。而且由于您正在操作由中断更改的参数的副本,因此中断是否在执行过程中更改参数并不重要,因为您在制作副本之前不会查看这些值。

于 2012-12-11T13:37:55.383 回答
1

当我发现自己处于类似情况时,处理可能需要比中断时间更长的时间,我使用 FIFO 将处理与传入数据分离。IE:TIM4 填充一个 FIFO。XYZ(或管理器)使用 FIFO 并处理数据。

(我觉得你的设计可能是错误的,因为你不应该使用全局变量来控制数据或流程。研究此事的书籍参考:制作嵌入式系统:伟大软件的设计模式)

于 2013-03-11T14:47:49.027 回答
0

在 XYZ 从缓冲区复制所有内容并使用副本之前。我相信这是最好的方法,在编写 gps 解析器时有所帮助。

于 2013-11-06T14:25:07.750 回答
0

您是否考虑过为您的系统使用 RTOS?我意识到这需要进行一些重组,但它可以为您提供系统所需的任务处理灵活性和分辨率。如果您使用的是 STM32 的 CubeIDE,启用、配置和运行 RTOS 非常简单。

于 2021-02-15T18:50:10.133 回答