禁用中断让freeRTOS在stm32上运行

Posted

技术标签:

【中文标题】禁用中断让freeRTOS在stm32上运行【英文标题】:Disable interrupt to let freeRTOS run on stm32 【发布时间】:2021-04-01 11:13:14 【问题描述】:

我正在开展一个项目,我正在通过 STM32f4 上的 DMA 连续获取数字样本。在我做一些 DSP 的每个样本之后,DMA 都会生成一个完整的回调中断。我的计划是允许 freeRTOS 在 DMA 等待回调时处理其他任务。但是,DMA 过于频繁地生成回调,不允许 freeRTOS 运行。我想让它在每次 DMA 完成回调后,允许 freeRTOS 任务运行 6 毫秒。我想从完整的回调中调用__disable_irq(),从其中一项任务中调用__enable_irq(),但这不能保证6ms,而且我有一个高优先级的按钮中断。我还尝试禁用仅调用 __set_BASEPRI(priority<<(8-__NVIC_PRIO_BITS)) 的 DMA 中断,然后启动一个 6 毫秒的计时器。在调用__set_BASEPRI(0) 中的定时器周期已过回调以启用 DMA 中断。但由于某种原因,这根本不允许 freeRTOS 运行。它在 DMA 完成回调和 Timer period elapsed 回调之间来回切换。

我是嵌入式编程的新手,因此对此的任何评论都会有所帮助。谢谢。

【问题讨论】:

你的采样率是多少? 这有点 X-Y 问题。您正在询问如何实施您认为的解决方案,此时您可能应该退后一步,更全面地询问如何在您拥有的硬件上实现任务调度和 DSP 截止日期。您的描述可能不清楚,但我想说您没有正确使用 RTOS。您明显的 RTOS/DSP 划分是错误的。在 RTOS 中,您应该在任务中做几乎所有事情,而在中断中几乎什么都不做。中断中的任何重要处理都会损害 RTOS 确定性响应的能力。 【参考方案1】:

您不应该认为 DSP 进程与 RTOS 任务是分开的,将 DSP in 执行为 RTOS 任务 - 信号处理是系统中时间最关键的方面,您必须处理数据尽快到达,不会丢失。

如果 DSP 在中断上下文中完成并且使您的任务处于饥饿状态,那么显然您在中断上下文中做了太多工作,并且中断率太高。你需要修正你的设计,让它更有计划性。

如果您的 DMA 传输是单个样本,您将在每个样本中获得一个中断 - ADC 将自行完成;因此以这种方式使用 DMA 与直接 ADC 中断处理相比没有任何优势。

相反,您应该使用块处理,因此您循环地对一个包含 80 个样本样本的块进行 DMA,为此您会在 40 个样本时获得半传输中断,在 80 个样本时获得全传输中断。因此,对于每个中断,您可能会触发一个任务事件或信号量,以将 DSP 处理推迟到 高优先级 RTOS 任务。这实现了两件事;

    在整个 n 个样本块采集时间内,RTOS 可以:
正在为前一个块执行 DSP 处理, 利用剩余时间处理优先级较低的任务。
    上下文切换等所花费的任何中断开销都减少了 1/n,从而有更多时间执行核心信号处理和后台任务。

除了减少中断数量和软件开销外,信号处理算法本身在执行块处理时可以更容易地进行优化。

上面的一个变体不是从 DMA 中断处理程序触发任务事件或信号量,您可以将新的样本块放在消息队列中,然后提供一些缓冲。如果 DSP 处理可能不太确定,这很有用,因此不能总是保证在下一个块准备好之前完成一个块的处理。但总体而言,平均而言,您仍然需要在获取块所需的时间内完成块处理,并留出时间用于其他任务。

如果您的低优先级任务仍然处于饥饿状态,那么明确的迹象是您的 DSP 进程对于您的处理器来说实在是太多了。可能有优化的余地,但那将是一个不同的问题。

使用建议的块处理策略,我过去曾将应用程序从以 200MHz 和 98% CPU 负载运行的 TI C2000 DSP 迁移到以 60% CPU 负载运行的 72MHz STM32F1xx。如果你做对了,性能改进可能非常显着。

关于您的“高优先级”按钮中断,我会质疑您的优先级分配。按钮是手动操作的,人类响应和感知时间以 10 毫秒甚至 100 毫秒为单位。这几乎不是您的时间关键任务,而缺少几 微秒 的 ADC 样本会导致您的信号处理出现严重错误。

您可能会误将“高优先级”与“重要”混淆。在上下文或实时系统中,它们不是一回事。您可以简单地在 低优先级 任务中轮询按钮,或者如果您使用中断,中断应该不会超过发出任务信号(或者更实际地触发去抖动计时器)(请参阅以Rising edge interrupt triggering multiple times on STM32 Nucleo 为例)。

【讨论】:

以上是关于禁用中断让freeRTOS在stm32上运行的主要内容,如果未能解决你的问题,请参考以下文章

在 STM32 上使用 FreeRTOS 处理多个中断

带有 STM32 HAL 驱动程序的 FreeRTOS 中的 UART 中断

STM32G0学习手册——Cortex M0+ NVIC 与FreeRTOS中断管理

STM32G0学习手册——Cortex M0+ NVIC 与FreeRTOS中断管理

STM32G0学习手册——Cortex M0+ NVIC 与FreeRTOS中断管理

STM32G0学习手册——Cortex M0+ NVIC 与FreeRTOS中断管理