嵌入式系统的实时操作系统


57

我看过很多文章,告诉我应该将RTOS用于时间管理和资源管理。我的时间不允许进行自己的研究,因此我向Chiphacker寻求建议。

我使用低资源微控制器(MSP430,PIC),并正在寻找可以使用的RTOS。

要点:

  1. 系统资源成本
  2. 系统优势
  3. 系统的缺点
  4. 实施技巧
  5. 不应/不应使用RTOS的情况。

我没有使用像arduino这样的系统,我从事的项目无法支持这种系统的成本。


2
我对此感到困惑。如果选民能给我反馈,我将在以后避免这种行为。
Kortuk

1
同上。这是一个很大的问题....
贾森小号

我接受了一个问题,因为,即使认为这是开放式的,我也收到了许多好评,并想为此付出至少一位作家。
Kortuk 2010年

Answers:


29

除了QNX以外,我在RTOS方面没有太多的个人经验(总体来说很棒,但是价格并不便宜,我与特定的主板供应商之间的经验也很差,并且QNX对于其他系统我们的不在意态度比它们最常见的尺寸大),对于PIC和MSP430而言太大了。

在以下方面,您将从RTOS中受益:

  • 线程管理/调度
  • 线程间通讯+同步
  • 具有stdin / stdout / stderr或串行端口或以太网支持或文件系统的系统上的I / O(除串行端口外,大多数情况下不是MSP430或PIC)

对于PIC或MSP430的外设:对于串行端口,我将使用环形缓冲区+中断...每个系统我只写一次,然后重用;其他外围设备我不认为您会从RTOS那里获得很多支持,因为它们是如此特定于供应商的。

如果您需要精确到微秒级的时序,则RTOS可能无济于事-RTOS的时序受限制,但由于上下文切换延迟,通常在调度中确实存在时序抖动...在PXA270上运行的QNX具有抖动通常在几十微秒内,最大值为100-200us,所以我不会将它用于必须运行于大约100Hz以上或需要定时比大约500us更精确的东西。对于这种情况,您可能必须实现自己的中断处理。有些RTOS可以很好地解决这个问题,而另一些RTOS则使它痛苦不堪:您的时间安排和他们的时间安排可能无法很好地共存。

如果时序/调度不太复杂,则使用设计良好的状态机可能会更好。如果您还没有的话,我强烈建议您阅读C / C ++中的实用状态图。在我工作的某些项目中,我们已经使用了这种方法,与传统的状态机相比,它在管理复杂性方面具有一些真正的优势。。。。这确实是您需要RTOS的唯一原因。


我在一家刚起步的公司工作,那里经验最丰富的嵌入式系统人员刚刚大学毕业(即,我本人和与我合作大约2年的其他人)。在我的工作周中,我花费了大量时间自学有关行业实践的知识。正如我一直在阅读的那样,除最低成本的系统外,我已获得除RTOS之外的所有改进。
Kortuk

用于PIC和MSP430之类的东西的RTOS系统似乎资源很低,它们可以帮助从非常复杂的系统中创建确定性系统,同时也大大简化了我们保持模块分离的管理。我是一个由两个人组成的团队的成员,该团队有效地构建了现场数据收集和路由系统。现在,我看了RTOS,我发现它非常适合我们的设计。
2009年

抱歉,使用三个帖子位,您的回答非常有帮助,我正在寻找一种资源很少的解决方案,但是该信息非常有用,感谢您的帮助。
2009年

不用担心评论数(恕我直言,StackExchange框架缺少的一件事是支持讨论... Q / A格式涵盖了大多数内容,但不包括某些内容)...听起来您对什么内容都有很好的处理能力您正在寻找。我没有看过Steve提到的FreeRTOS,但是如果将它移植到低端微控制器上,也许它将完成您需要的调度管理。
杰森S

它似乎可以通过堆栈保存每个线程的状态(类似于50个push / pull语句),并且可以处理定时中断。我的系统通常使用端口中断进行线程切换,但是该任务看起来可行。我希望此站点类型以更好的格式处理讨论。
Kortuk

26

您尝试过FreeRTOS吗?它是免费的(受T&C约束),并且已移植到MSP430和多种PIC版本中。

与其他一些相比,它很小,但这也使它易于学习,尤其是如果您以前没有使用过RTOS。

提供(非免费)商业许可证以及IEC 61508 / SIL 3版本。


谢谢您,我将在一周内进行调查,我将保留其他问题的答案,但是您将为您提供很大的帮助!
Kortuk

12

我刚刚发现有关NuttX RTOS的信息,它甚至可以在8052(8位)系统上工作。它没有很多端口,但是看起来很有趣。POSIX可能是加分项,因为如果您升级到功能更强大的处理器并且想要运行实时linux或QNX,则它可能会使您的某些代码更具可移植性。

我自己没有商业RTOS的任何经验,但是多年来我一直使用自制的RTOS!它们非常擅长帮助您将代码开发分散到许多程序员之间,因为它们本质上可以各自获得一个“任务”或“线程”以各自工作。您仍然必须进行协调,并且必须有人监督整个项目,以确保每个任务都能按时完成。

我还建议您在使用RTOS时研究速率单调分析或RMA。这将帮助您确保关键任务能够按时完成。

我还将研究Miro Samek的QP-nano事件驱动的编程框架,该框架可以与RTOS一起使用,也可以不带RTOS,并且仍然为您提供实时功能。有了它,您就可以将设计分为分层状态机,而不是传统任务。杰森·S(Jason S)在其帖子中提到了米罗的书。优秀的读物!


9

我发现许多机器上有用的一件事是一个简单的堆栈切换器。我实际上尚未为PIC编写一个,但是我希望,如果两个/所有线程总共使用31个或更少的堆栈级别,则该方法在PIC18上会很好用。在8051上,主要例程是:

_taskswitch:
  Xch A,SP
  xch a,_altSP
  Xch A,SP
  退回

在PIC上,我忘记了堆栈指针的名称,但是例程类似于:

_taskswitch:
  movlb _altSP >> 8
  movf _altSP,w,b
  movff _STKPTR,altSP 
  movwf _STKPTR,c
  返回

在程序开始时,调用task2()例程,该例程会用备用堆栈的地址加载altSP(对于PIC18Fxx,16可能会很好地工作)并运行task2循环。这个惯例绝不能返回,否则事情将死于痛苦的死亡。相反,只要它希望对主要任务产生控制权,就应该调用_taskswitch。然后,只要主要任务要屈服于次要任务,就应调用_taskswitch。通常,会有一些可爱的小例程,例如:

void delay_t1(无符号短值)
{
  做
    taskswitch();
  while((无符号短] [millisecond_clock-val)> 0xFF00);  
}

注意,任务切换器没有任何“等待条件”的手段;它所支持的只是一次旋转等待。另一方面,任务切换是如此之快,以至于当另一个任务正在等待计时器到期时尝试taskswitch()会切换到另一个任务,检查计时器,并且比典型的任务切换器切换得更快将确定它不需要任务切换。

请注意,协作式多任务处理有一些局限性,但是在可以快速重建暂时受干扰的不变式的情况下,它避免了使用大量锁定和其他与互斥相关的代码的需求。

(编辑):关于自动变量的一些警告,例如:

  1. 如果从两个线程中都调用了使用任务切换的例程,则通常有必要编译该例程的两个副本(可能是#两次包含相同的源文件,并使用不同的#define语句)。任何给定的源文件要么只包含一个线程的代码,要么包含将被编译两次的代码(每个线程一次),因此我可以使用“ #define delay(x)delay_t1(x)”之类的宏,或者#define delay(x)delay_tx(x)“,具体取决于我使用的线程。
  2. 我相信无法“看到”正在调用的函数的PIC编译器将假定该函数可能会破坏所有CPU寄存器,从而避免了将任何寄存器保存在任务切换例程中的问题[与抢占式多任务处理]。任何考虑为其他任何CPU使用类似任务切换器的人都需要了解所使用的寄存器约定。假定存在足够的堆栈空间,在任务切换之前先将寄存器压入寄存器,然后在其后弹出寄存器是处理事务的一种简便方法。

协作式多任务处理无法使人们完全摆脱锁定等问题,但确实确实可以大大简化事情。例如,在具有压缩垃圾收集器的抢占式RTOS中,必须允许固定对象。当使用协作切换器时,如果代码假定GC对象可能在调用taskswitch()的任何时间移动,则不必这样做。一个不必担心固定对象的压缩收集器比一个收集器要简单得多。


1
很棒的答案。我认为获得一些资源链接来接近我自己的RTOS会很有趣。我在这里的工作重点实际上是从已经完成确保实时性的工作的供应商那里获得高质量的RTOS,但这对我自己来说可能是一个有趣的业余爱好者项目。
2011年

1
很酷,从没想过要切换SP就可以了...
NickHalden 2011年

1
@JGord:我已经在8x51和TI DSP上完成了微小的任务切换器。如上所示,8051专为完成两项任务而设计。DSP 1与4一起使用,有点复杂。但是,我只是有个疯狂的主意:一个人只需使用三个任务切换器就可以处理四个任务。每次前两个任务之一想要进行任务切换时,都应调用TaskSwitch1和TaskSwitch2。当后两个任务之一要进行任务切换时,应调用Taskswitch1和Taskswitch3。假定代码从stack0开始,并且每个任务切换器都设置有其相应的堆栈号。
supercat

@JGord:嗯...那不太行;它似乎产生三路循环,而忽略了第三个切换台。好吧,做实验,我想您可能会找到一个好的公式。
supercat

7

我在MSP430上使用过Salvo。这对处理器资源的影响很小,并且只要您遵守实施规则,就非常易于使用和可靠。这是一个协作操作系统,需要在任务功能的外部功能调用级别执行任务切换。此约束使OS可以在非常小的内存设备中工作,而无需使用大量的堆栈空间来维护任务上下文。

在AVR32上,我正在使用FreeRTOS。到目前为止,它还是非常可靠的,但是FreeRTOS发行的版本与Atmel框架提供的版本之间存在一些配置/版本差异。但是,它具有免费的优点!


5

12月版的《日常实用电子产品》包含PIC实时操作系统系列的第3部分(在PIC n'Mix栏中),并详细介绍了使用MPLAB和PICKit 2设置FreeRTOS的过程。前两篇文章( (尚未见)似乎讨论了各种RTOS的优点,并决定使用FreeRTOS。一旦本文设置了开发环境,他们便开始设计二进制数字时钟。似乎至少还有一部分涉及该主题。

我不确定美国的EPE的可用性如何,但似乎确实有一家美国商店与其网站链接,并且可能有电子版。


4

PIC的CCS编译器带有一个简单的RTOS。我还没有尝试过,但是如果您有此编译器,将很容易尝试。


1
我实际上是第一次尝试。它不是真正意义上的RTOS。它绝不是抢先的。它需要定期使用yield命令,以便RTOS可以决定下一步运行谁,如果有其他程序需要接管,则必须有意识地将它们连续放置。
Kortuk 2010年

2
我认为它仍称为RTOS。听起来好像它具有协作调度程序,而不是完全抢占式调度程序。
杰伊·阿特金森

是的,从技术上讲,它仍然是RTOS,但是我拥有它,并且仍然没有什么价值。我知道这是个人的事情,但对我而言,它必须先行成为有价值的东西。我仍然+1,因为这是一个很好的答案,而且很有价值。
Kortuk 2010年

3

谢谢!看起来大多数人都没有得到这个问题,但这仍然很有趣。
Kortuk 2010年

我在SO问题上发布了一个邀请用户来E&R寻求帮助的问题!
Kortuk

我认为我们“了解”了SO的问题,它提出的问题有所不同,但与此问题相关。至于您对认证的评论;这取决于很多事情。看着这里的答案,我喜欢DoxaLogos的关于QP-nano的答案。我的经验使我比线程和隐式上下文切换更喜欢事件驱动的代码。
2010年1

2

您还没有对您的应用程序说太多。是否使用RTOS在很大程度上取决于您在PIC中需要执行的操作。除非您要执行几种不同的异步操作(这些操作需要严格的时间限制,或者要运行多个线程),否则RTOS可能会显得过大。

有多种方法可以根据最重要的时间在微控制器上组织时间:

  1. 恒定帧率:对于运行伺服控制器的PIC,例如,该控制器必须以1000Hz运行。如果PID算法执行时间少于1毫秒,则您可以使用毫秒的剩余时间执行其他任务,例如检查CAN总线,读取传感器等。

  2. 所有中断:PIC中发生的所有事件均由中断触发。可以根据事件的重要性确定中断的优先级。

  3. 将其循环粘贴,并尽一切可能快速地进行操作。您可能会发现这提供了合适的时间范围。


我了解其他方法,但想扩展到RTOS。我将运行多个任务并拥有一个硬实时系统,但是我愿意在没有硬实时需求的情况下开始。感谢您抽出宝贵的时间来回答问题,但是我想学习一个RTOS,以便可以在需求很高的情况下使用它。
Kortuk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.