50 KHz 的 FreeRTOS ISR

FreeRTOS ISR at 50 KHz

我想使 LED 闪烁(切换 GPIO 引脚)同步,硬件定时器配置为在 50KHz 时触发中断ARM Cortex M4。

在我当前的代码中,我将一个 GPIO 引脚切换到一个由 50KHz 外部时钟信号触发的特定 ISR 处理程序。结果是 GPIO 引脚在 1KHz 到 96KHz 的随机频率下非常不稳定地切换。

操作系统不是 运行 除了定时器节拍中断(100Hz 最低优先级)、空闲任务和我的特定 ISR 处理程序之外的任何其他任务。

否则,此 "toggling solution" 可与同一 MCU 上的裸机实现完美配合。所以,我的问题似乎来自于我对 FreeRTOS 环境缺乏了解。

  1. 将 LED 切换为 50 KHz 的 FreeRTOS ISR 是否可行?
  2. 是否需要做成等待50KHz中断信号的任务 ?
  3. 我是否应该创建一个 50KHz 的定时切换任务并同步它 周期性地使用外部时钟信号 ?

您无法通过 FreeRTOS 机制获得 50 KHz。

Оf 当然,你可以试试这个坏主意。所以你应该改变系统节拍至少 10uS(1 / 50KHz / 2 ) 在这种情况下你的任务会有很小的延迟(它允许反应 "immediately"),但是上下文切换 ISR 会被经常调用,这会降低性能。

正确的方法是使用硬件定时器产生中断(用于切换 GPIO)或使用带 PWM 输出的定时器,在这种情况下频率精度取决于时钟源。 为了从外部源同步定时器,您应该使用高精度(至少 10uS)的外部中断和附加定时器

如果您希望 50K 准确(无抖动),中断的优先级必须等于或高于 configMAX_SYSCALL_INTERRUPT_PRIORITY:https://www.freertos.org/a00110.html#kernel_priority and https://www.freertos.org/RTOS-Cortex-M3-M4.html(假设您使用的端口支持中断嵌套)。

我终于发现 指令缓存 在我的 50KHz ISR 的 FreeRTOS 实现中没有启用,这与裸机版本不同。它现在几乎按预期工作(仍然存在一些抖动)。

在回答我的问题时,我建议如下:

  1. Is it feasible to toggle a LED into a FreeRTOS ISR at 50 KHz ?

肯定是。 FreeRTOS 可以以任何频率执行 ISR。可行性仅取决于添加到指令和数据访问性能的 MCU 的计算能力。与处理 ISR(ISR 开销和端口效率)的 Bare Metal 实现相比,FreeRTOS 肯定会增加一些延迟,但同样,这或多或少会很重要,具体取决于 MCU 的计算性能和周到的频率。

  1. Do I need to do it into a task waiting for the 50KHz interrupt signal ?

不一定。无论如何,如果需要不规则或相当重要的处理,这是一个很好的选择。然而,FreeRTOS 延迟指令会花费时间,并且可能会在下一个 ISR 之前结束处理。更有弹性但效率较低。就我而言,在 50KHz 时,对于每个 ISR 的平均处理量来说,这花费了太多时间。

  1. Should I create a timed toggling task at 50KHz and synchronize it periodically with the external clock signal ?

不可行,除非显着降低系统节拍频率,这会导致严重的性能损失。