我计划用我的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;
然后我宣布要发送的帧表
aubFrames[MAX_FRAMES] = {
{0x12, 0xAABBCC, 4, 100},
{0x12, 0xAABBCC, 4, 1000},
{0x12, 0xAABBCC, 4, 2000},
{0x12, 0xAABBCC, 4, 2010}
};
这告诉电路板在100毫秒后发送第一帧,在1000毫秒后发送第二帧,等等。
我实际做的是:
我在调度程序中添加了一个周期为10毫秒的新任务。此任务将检查aubFrames表,如果是发送帧的时间,则发送相关帧,否则将不执行任何操作。这个解决方案的问题是时间损失很大。例如,要将第一帧发送给调度程序访问此任务九次,但无需执行任何操作。
是否有其他的解决方案使计划更有效?
我想使用定时器中断,但我不认为这是一个好的解决方案,因为板上只有4个定时器,帧数超过4,所以在我看来,配置定时器来生成不同时间段的中断是行不通的。
最佳答案
大多数实时操作系统都有一些功能,似乎它们是合适的。
一种方法是让任务在适当的时间内暂停自身(而不是周期性地唤醒以轮询是否是时间)。例如,FreeRTOS具有vTaskDelay
函数,该函数在指定的时间段内阻塞任务。你的任务知道它在100或1000毫秒内不需要做任何事情,因此它应该在这段时间内延迟自己。
另一种方法是使用软件定时器而不是硬件定时器。RTOS显然已经得到了一个周期性的计时,因为它知道每10毫秒唤醒一次您的任务。它可能还有一个软件定时器服务,比如FreeRTOS的this one。软件定时器服务由RTOS调度器使用的硬件定时器驱动。它允许您设置各种周期性和单点软件计时器,而无需另一个硬件计时器您的任务可以读取aubFrames
数组并为每帧设置一个一次性计时器,该计时器将在适当的时间过期。如果你不喜欢所有那些软件定时器同时运行的想法,那么用前一个定时器过期设置下一个定时器。
关于c - 在RTOS中安排帧的传输,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32037577/