【问题标题】:Scheduling the transmision of frames in RTOS在 RTOS 中调度帧的传输
【发布时间】:2015-08-16 16:48:59
【问题描述】:

我打算使用我的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 表,如果是发送帧的时间,则发送相关帧,否则无需执行任何操作。这个解决方案的问题是浪费了大量的时间。例如,发送第一帧调度程序访问此任务九次,但无事可做。

是否有其他解决方案可以使调度更有效?

我想使用定时器中断,但我认为这不是一个好的解决方案,因为板上只有四个定时器并且帧数超过四个,所以我认为配置定时器以产生中断不同的时间段都行不通。

【问题讨论】:

  • 你使用的是什么实时操作系统?
  • 帧数多于定时器无关紧要。一个计时器就可以完成这项工作。为第一帧设置计时器,当它触发时,为第二帧重置它,依此类推。不确定这是否是您已经设置的方式,但是(以防万一)使用“差分”时间而不是绝对时间通常更容易。因此,就计时器服务例程而言,不要使用与前一帧或“现在”相比的“差分”时间,而不是每个帧从开始(100、1000、2000、2010)开始的精确时间。示例:100, 900, 1000, 10。使工作更轻松,当前条目下次提供。
  • @kkrambo 我自己设计了操作系统你有什么建议可以帮助我的操作系统

标签: c timer embedded rtos can-bus


【解决方案1】:

大多数 RTOS 都有一些看似合适的功能。

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

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

【讨论】:

  • 感谢 kkrambo 的澄清,我宁愿使用软件计时器。我有一个额外的问题:想象一下,如果我必须检查传输的帧是否被宣告无罪(如在 TCP/IP 中),那么我应该发送一个帧并等待一段时间来检查我是否收到无罪。对我来说,我在结构 tFrame 中添加了一个回调,用于检查你同意我的观点吗? ,我觉得它变得有点复杂,你有什么建议或参考可以帮助我摆脱这个问题
猜你喜欢
  • 2011-03-04
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2019-09-12
相关资源
最近更新 更多