Linux 2.6的“实时性”有多强?

29

我正在考虑将我的产品从一个RTOS移植到嵌入式Linux。我没有很多实时要求,而且我所需要的一些实时要求大约是10毫秒左右。

请问有人能够指引我查阅一份关于目前版本的Linux到底有多实时的参考资料吗?

除了实时性方面,从商用RTOS迁移到Linux还需要注意哪些问题呢?

4个回答

37

您可以从实时Linux 维基FAQ中获取大部分答案。

2.6 Linux内核的实时能力是什么?

传统上,Linux内核只允许在特定情况下一个进程抢占另一个进程:

  • 当CPU运行用户模式代码
  • 当内核代码从系统调用或中断返回到用户空间
  • 当内核代码在mutex上阻塞或明确将控制权让给另一个进程时

如果内核代码正在执行,而某个事件需要高优先级的线程开始执行,则直到内核代码明确放弃控制权之前,高优先级线程无法抢占正在运行的内核代码。在最坏的情况下,延迟可能会达到几百毫秒甚至更长。

Linux 2.6配置选项CONFIG_PREEMPT_VOLUNTARY引入对长延迟的最常见原因的检查,以便内核可以自愿地放弃对等待执行的更高优先级任务的控制权。这可能有所帮助,但虽然它减少了长延迟的发生次数(从几百毫秒到可能达到几秒钟或更长时间),但并没有消除它们。不过与下文所讨论的CONFIG_PREEMPT不同,CONFIG_PREEMPT_VOLUNTARY对系统的整体吞吐量影响较小。(一如既往地,在吞吐量——系统的总体效率——和延迟之间存在经典的权衡。在当今的高速CPU系统中,通常可以通过降低吞吐量来换取更低的延迟,但不需要最小延迟保证的服务器级系统可能会选择使用CONFIG_PREEMPT_VOLUNTARY,或者坚持传统的非抢占式内核设计。)

2.6 Linux kernel有一个额外的配置选项,CONFIG_PREEMPT,使所有未受自旋锁保护区域和中断处理程序保护的内核代码能够被更高优先级的内核线程进行非自愿抢占。使用此选项,最坏情况下的延迟降至(大约)几毫秒,尽管一些设备驱动程序可能具有比这更糟糕的引入延迟的中断处理程序。如果实时Linux应用程序需要比几毫秒更小的延迟,则强烈建议使用CONFIG_PREEMPT_RT补丁。

他们还在常见问题解答中列出了“Gotcha”列表。

编写实时应用程序时需要注意哪些重要事项?

在初始启动阶段时注意以下几点:

  • 从main()中尽快调用mlockall()。
  • 在应用程序启动时创建所有线程,并触摸每个线程的整个堆栈的每个页面。永远不要在RT展示时间期间动态启动线程,这会破坏RT行为。
  • 永远不要使用已知会生成页面错误的系统调用,例如fopen()。 (打开文件会执行mmap()系统调用,这将生成页面错误)。
  • 如果您使用“编译时全局变量”和/或“编译时全局数组”,则请使用mlockall()来防止访问它们时出现页面错误。

更多信息:HOWTO: Build an RT-application

他们还有一个大的出版物页面,您可能想要查看。


6

你有没有看过Xenomai?它可以让你在Linux上运行“硬实时”进程,同时仍然允许你访问常规的Linux API以满足所有非实时需求。


2

1

答案可能是“足够好”。

如果你正在运行一个嵌入式系统,你可能控制着盒子上的所有或大多数软件。

股票Linux 2.6有几个适用于低延迟任务的特性-主要包括:

  • 调度策略
  • 内存锁定

假设您使用的是单核机器,如果只有一个任务将其调度策略设置为SCHED_FIFO或SCHED_RR(如果只有一个任务则无关紧要),并使用mlockall()锁定了所有内存,那么它将在准备好运行时立即得到调度。

然后,你只需要担心的是内核中不可抢占部分花费的时间超过了你可以接受的延迟时间-除非发生一些糟糕的事情,例如极端的内存压力或者你的驱动程序有问题,这在嵌入式系统中是不太可能发生的。

我觉得“试一试看”是一个很好的答案,但在你的情况下可能相当复杂(可能涉及编写设备驱动程序等)。

查看sched_setscheduler文档获取一些有用的信息。


2
似乎你不知道什么是实时。 - piotr
2
@piotr,你能解释一下为什么吗?在我看来这似乎是一个有效的答案。 - Dani van der Meer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接