在 RTOS 中安排帧的传输

Scheduling the transmision of frames in RTOS

我打算使用我的 STM32 开发板发送 CAN 帧。我实现了一个简单的调度器,包含10个任务;一个任务将负责发送帧。

为了完成这项工作,我为 CAN 帧声明了一个结构:

typedef struct
{
    unsigned int id;
    unsigned char data[];
    unsigned char dlc;
    unsigned int timeOfSend  //This is the time in ms in which a frame should be sent
}tFrame;

然后我声明了 table 个要发送的帧

aubFrames[MAX_FRAMES] = {
    {0x12, 0xAABBCC, 4,  100},
    {0x12, 0xAABBCC, 4, 1000},
    {0x12, 0xAABBCC, 4, 2000},
    {0x12, 0xAABBCC, 4, 2010}
};

这会告诉开发板在 100 毫秒后发送第一帧,在 1000 毫秒后发送第二帧,依此类推。

我实际做的事情:

我在调度程序中添加了一个周期为 10 毫秒的新任务。此任务将检查 aubFrames table,如果到了发送帧的时间,它会发送相关帧,否则什么也不做。这个解决方案的问题是会浪费大量时间。例如,发送第一帧调度程序访问此任务九次,但无事可做。

有没有其他方案可以让调度更有效?

我想使用定时器中断,但我认为这不是好的解决方案,因为板上只有四个定时器,而且帧数超过四个,所以我认为将定时器配置为为不同的时间段生成中断将不起作用。

大多数 RTOS 都有一些看起来很合适的功能。

一种方法是让任务自行暂停适当的时间(而不是定期唤醒以轮询是否到了时间)。例如,FreeRTOS has the vTaskDelay 函数,它会在指定的时间内阻止任务。您的任务知道它不必在 100 或 1000 毫秒内执行任何操作,因此它应该将自身延迟这段时间。

另一种方法是使用软件定时器而不是硬件定时器。 RTOS 显然已经获得周期性滴答,因为它知道每 10 毫秒唤醒您的任务。它可能还有一个软件定时器服务,例如来自 FreeRTOS 的 this one。软件定时器服务由 RTOS 调度程序使用的硬件定时器驱动。它允许您设置各种周期性和单次软件定时器,而无需另一个硬件定时器。您的任务可以读取 aubFrames 数组并为每一帧设置一个一次性计时器,该计时器会在适当的时间到期。如果您不喜欢所有这些软件定时器的想法 运行 则设置下一个定时器,前一个定时器到期。