“实时”如何是Linux 2.6?

时间:2021-12-03 03:55:17

I am looking at moving my product from an RTOS to embedded Linux. I don't have many real-time requirements, and the few RT requirements I have are on the order of 10s of milliseconds.

我正在考虑将我的产品从RTOS迁移到嵌入式Linux。我没有很多实时要求,我所拥有的少数RT要求大约为10毫秒。

Can someone point me to a reference that will tell me how Real-Time the current version of Linux is?

有人能指出我的参考资料,告诉我当前版本的Linux是如何实时的吗?

Are there any other gotchas from moving to a commercial RTOS to Linux?

从商用RTOS迁移到Linux还有其他问题吗?

4 个解决方案

#1


35  

You can get most of your answers from the Real Time Linux wiki and FAQ

您可以从Real Time Linux wiki和FAQ获得大部分答案

What are real-time capabilities of the stock 2.6 linux kernel?

什么是股票2.6 linux内核的实时功能?

Traditionally, the Linux kernel will only allow one process to preempt another only under certain circumstances:

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

  • When the CPU is running user-mode code
  • 当CPU运行用户模式代码时
  • When kernel code returns from a system call or an interrupt back to user space
  • 当内核代码从系统调用或中断返回到用户空间时
  • When kernel code code blocks on a mutex, or explicitly yields control to another process
  • 当内核代码代码在互斥锁上阻塞时,或者明确地将控制权交给另一个进程

If kernel code is executing when some event takes place that requires a high priority thread to start executing, the high priority thread can not preempt the running kernel code, until the kernel code explicitly yields control. In the worst case, the latency could potentially be hundreds milliseconds or more.

如果在发生需要高优先级线程开始执行的某个事件时执行内核代码,则高优先级线程不能抢占正在运行的内核代码,直到内核代码明确地产生控制。在最坏的情况下,延迟可能是几百毫秒或更长。

The Linux 2.6 configuration option CONFIG_PREEMPT_VOLUNTARY introduces checks to the most common causes of long latencies, so that the kernel can voluntarily yield control to a higher priority task waiting to execute. This can be helpful, but while it reduces the occurences of long latencies (hundreds of milliseconds to potentially seconds or more), it does not eliminate them. However unlike CONFIG_PREEMPT (discussed below), CONFIG_PREEMPT_VOLUNTARY has a much lower impact on the overall throughput of the system. (As always, there is a classical tradeoff between throughput --- the overall efficiency of the system --- and latency. With the faster CPU's of modern-day systems, it often makes sense to trade off throughput for lower latencies, but server class systems that do not need minimum latency guarantees may very well chose to use either CONFIG_PREEMPT_VOLUNTARY, or to stick with the traditional non-preemptible kernel design.)

Linux 2.6配置选项CONFIG_PREEMPT_VOLUNTARY引入了对长延迟的最常见原因的检查,以便内核可以自动控制等待执行的更高优先级的任务。这可能会有所帮助,但是虽然它可以减少长延迟(几百毫秒到几秒或更长)的出现,但它并没有消除它们。但是,与CONFIG_PREEMPT(下面讨论)不同,CONFIG_PREEMPT_VOLUNTARY对系统的整体吞吐量的影响要小得多。 (与往常一样,吞吐量 - 系统的整体效率 - 和延迟之间存在经典的权衡。现代系统的CPU速度更快,因此在较低的延迟时间内折衷吞吐量通常是有意义的,但服务器不需要最小延迟保证的类系统可能选择使用CONFIG_PREEMPT_VOLUNTARY,或者坚持使用传统的不可抢占的内核设计。)

The 2.6 Linux kernel has an additional configuration option, CONFIG_PREEMPT, which causes all kernel code outside of spinlock-protected regions and interrupt handlers to be eligible for non-voluntary preemption by higher priority kernel threads. With this option, worst case latency drops to (around) single digit milliseconds, although some device drivers can have interrupt handlers that will introduce latency much worse than that. If a real-time Linux application requires latencies smaller than single-digit milliseconds, use of the CONFIG_PREEMPT_RT patch is highly recommended.

2.6 Linux内核有一个额外的配置选项CONFIG_PREEMPT,它使得自旋锁保护区域和中断处理程序之外的所有内核代码都有资格获得更高优先级内核线程的非自愿抢占。使用此选项,最坏情况延迟降至(大约)单位数毫秒,尽管某些设备驱动程序可能具有中断处理程序,这将导致比此更糟糕的延迟。如果实时Linux应用程序要求延迟小于一位数毫秒,强烈建议使用CONFIG_PREEMPT_RT补丁。

They also have a list of "Gotcha's" as you called them in the FAQ.

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

What are important things to keep in mind while writing realtime applications?

在编写实时应用程序时要记住哪些重要事项?

Taking care of the following during the initial startup phase:

在初始启动阶段注意以下事项:

  • Call mlockall() as soon as possible from main().
  • 尽快从main()调用mlockall()。
  • Create all threads at startup time of the application, and touch each page of the entire stack of each thread. Never start threads dynamically during RT show time, this will ruin RT behavior.
  • 在应用程序启动时创建所有线程,并触摸每个线程的整个堆栈的每个页面。永远不要在RT显示时间内动态启动线程,否则会破坏RT行为。
  • Never use system calls that are known to generate page faults, such as fopen(). (Opening of files does the mmap() system call, which generates a page-fault).
  • 切勿使用已知会产生页面错误的系统调用,例如fopen()。 (打开文件会执行mmap()系统调用,从而生成页面错误)。
  • If you use 'compile time global variables' and/or 'compile time global arrays', then use mlockall() to prevent page faults when accessing them.
  • 如果使用'compile time global variables'和/或'compile time global arrays',那么在访问它们时使用mlockall()来防止页面错误。

more information: HOWTO: Build an RT-application

更多信息:HOWTO:构建RT应用程序

They also have a large publications page you might want to checkout.

他们还有一个您可能想要结帐的大型出版物页面。

#2


5  

Have you had a look at Xenomai? It will let you run "hard real time" processes above Linux, while still allowing you to access the regular Linux APIs for all the non-real-time needs.

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

#3


2  

There are two fundamentally different approaches to achieve real-time capabilities with Linux.

有两种根本不同的方法可以实现Linux的实时功能。

1) Patch the existing kernel with things like the rt-preempt patches. This will eventually lead to a fully preemptive kernel

1)使用rt-preempt补丁之类的东西修补现有内核。这最终将导致完全抢先的内核

2) Dual kernel approach (like xenomai, RTLinux, RTAI,...)

2)双核方法(如xenomai,RTLinux,RTAI,......)

There are lots of gotchas moving from a RTOS to Linux.

从RTOS到Linux都有很多问题。

Maybe you don't really need real-time?

也许你真的不需要实时?

I'm talking about real-time Linux in my training: http://www.reliableembeddedsystems.com/embedded-systems_7.html

我正在谈论培训中的实时Linux:http://www.reliableembeddedsystems.com/embedded-systems_7.html

#4


1  

The answer is probably "good enough".

答案可能“足够好”。

If you're running an embedded system, you probably have control of all or most of the software on the box.

如果您正在运行嵌入式系统,则可能已经控制了所有或大部分软件。

Stock Linux 2.6 has several features suitable for low-latency tasks - chiefly these are:

Stock Linux 2.6有几个适用于低延迟任务的功能 - 主要是:

  • Scheduling policies
  • 调度策略
  • Memory locking
  • 内存锁定

Assuming you're using a single-core machine, if you have just one task which has set its scheduling policy to SCHED_FIFO or SCHED_RR (it doesn't matter which if you have just one task), AND locked all its memory in with mlockall(), then it WILL get scheduled as soon as it is ready to run.

假设您正在使用单核机器,如果您只有一个任务将其调度策略设置为SCHED_FIFO或SCHED_RR(如果您只有一个任务则无关紧要),并使用mlockall锁定其所有内存(),然后它会在准备好运行后立即安排。

Then the only thing you'd have to worry about was some non-preemptable part of the kernel taking longer than your acceptable latency to complete - which is unlikely to happen in an embedded system unless something bad happens, such as extreme memory pressure, or your drivers are dodgy.

那么你唯一需要担心的是内核的一些非抢占部分需要的时间超过你可接受的延迟时间 - 这在嵌入式系统中不太可能发生,除非发生了一些不好的事情,例如极端的内存压力,或者你的司机很狡猾。

I guess "try it and see" is a good answer, but that's probably rather complicated in your case (and might involve writing device drivers etc).

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

Look at the doc for sched_setscheduler for some good info.

查看sched_setscheduler的doc以获取一些好的信息。

#1


35  

You can get most of your answers from the Real Time Linux wiki and FAQ

您可以从Real Time Linux wiki和FAQ获得大部分答案

What are real-time capabilities of the stock 2.6 linux kernel?

什么是股票2.6 linux内核的实时功能?

Traditionally, the Linux kernel will only allow one process to preempt another only under certain circumstances:

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

  • When the CPU is running user-mode code
  • 当CPU运行用户模式代码时
  • When kernel code returns from a system call or an interrupt back to user space
  • 当内核代码从系统调用或中断返回到用户空间时
  • When kernel code code blocks on a mutex, or explicitly yields control to another process
  • 当内核代码代码在互斥锁上阻塞时,或者明确地将控制权交给另一个进程

If kernel code is executing when some event takes place that requires a high priority thread to start executing, the high priority thread can not preempt the running kernel code, until the kernel code explicitly yields control. In the worst case, the latency could potentially be hundreds milliseconds or more.

如果在发生需要高优先级线程开始执行的某个事件时执行内核代码,则高优先级线程不能抢占正在运行的内核代码,直到内核代码明确地产生控制。在最坏的情况下,延迟可能是几百毫秒或更长。

The Linux 2.6 configuration option CONFIG_PREEMPT_VOLUNTARY introduces checks to the most common causes of long latencies, so that the kernel can voluntarily yield control to a higher priority task waiting to execute. This can be helpful, but while it reduces the occurences of long latencies (hundreds of milliseconds to potentially seconds or more), it does not eliminate them. However unlike CONFIG_PREEMPT (discussed below), CONFIG_PREEMPT_VOLUNTARY has a much lower impact on the overall throughput of the system. (As always, there is a classical tradeoff between throughput --- the overall efficiency of the system --- and latency. With the faster CPU's of modern-day systems, it often makes sense to trade off throughput for lower latencies, but server class systems that do not need minimum latency guarantees may very well chose to use either CONFIG_PREEMPT_VOLUNTARY, or to stick with the traditional non-preemptible kernel design.)

Linux 2.6配置选项CONFIG_PREEMPT_VOLUNTARY引入了对长延迟的最常见原因的检查,以便内核可以自动控制等待执行的更高优先级的任务。这可能会有所帮助,但是虽然它可以减少长延迟(几百毫秒到几秒或更长)的出现,但它并没有消除它们。但是,与CONFIG_PREEMPT(下面讨论)不同,CONFIG_PREEMPT_VOLUNTARY对系统的整体吞吐量的影响要小得多。 (与往常一样,吞吐量 - 系统的整体效率 - 和延迟之间存在经典的权衡。现代系统的CPU速度更快,因此在较低的延迟时间内折衷吞吐量通常是有意义的,但服务器不需要最小延迟保证的类系统可能选择使用CONFIG_PREEMPT_VOLUNTARY,或者坚持使用传统的不可抢占的内核设计。)

The 2.6 Linux kernel has an additional configuration option, CONFIG_PREEMPT, which causes all kernel code outside of spinlock-protected regions and interrupt handlers to be eligible for non-voluntary preemption by higher priority kernel threads. With this option, worst case latency drops to (around) single digit milliseconds, although some device drivers can have interrupt handlers that will introduce latency much worse than that. If a real-time Linux application requires latencies smaller than single-digit milliseconds, use of the CONFIG_PREEMPT_RT patch is highly recommended.

2.6 Linux内核有一个额外的配置选项CONFIG_PREEMPT,它使得自旋锁保护区域和中断处理程序之外的所有内核代码都有资格获得更高优先级内核线程的非自愿抢占。使用此选项,最坏情况延迟降至(大约)单位数毫秒,尽管某些设备驱动程序可能具有中断处理程序,这将导致比此更糟糕的延迟。如果实时Linux应用程序要求延迟小于一位数毫秒,强烈建议使用CONFIG_PREEMPT_RT补丁。

They also have a list of "Gotcha's" as you called them in the FAQ.

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

What are important things to keep in mind while writing realtime applications?

在编写实时应用程序时要记住哪些重要事项?

Taking care of the following during the initial startup phase:

在初始启动阶段注意以下事项:

  • Call mlockall() as soon as possible from main().
  • 尽快从main()调用mlockall()。
  • Create all threads at startup time of the application, and touch each page of the entire stack of each thread. Never start threads dynamically during RT show time, this will ruin RT behavior.
  • 在应用程序启动时创建所有线程,并触摸每个线程的整个堆栈的每个页面。永远不要在RT显示时间内动态启动线程,否则会破坏RT行为。
  • Never use system calls that are known to generate page faults, such as fopen(). (Opening of files does the mmap() system call, which generates a page-fault).
  • 切勿使用已知会产生页面错误的系统调用,例如fopen()。 (打开文件会执行mmap()系统调用,从而生成页面错误)。
  • If you use 'compile time global variables' and/or 'compile time global arrays', then use mlockall() to prevent page faults when accessing them.
  • 如果使用'compile time global variables'和/或'compile time global arrays',那么在访问它们时使用mlockall()来防止页面错误。

more information: HOWTO: Build an RT-application

更多信息:HOWTO:构建RT应用程序

They also have a large publications page you might want to checkout.

他们还有一个您可能想要结帐的大型出版物页面。

#2


5  

Have you had a look at Xenomai? It will let you run "hard real time" processes above Linux, while still allowing you to access the regular Linux APIs for all the non-real-time needs.

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

#3


2  

There are two fundamentally different approaches to achieve real-time capabilities with Linux.

有两种根本不同的方法可以实现Linux的实时功能。

1) Patch the existing kernel with things like the rt-preempt patches. This will eventually lead to a fully preemptive kernel

1)使用rt-preempt补丁之类的东西修补现有内核。这最终将导致完全抢先的内核

2) Dual kernel approach (like xenomai, RTLinux, RTAI,...)

2)双核方法(如xenomai,RTLinux,RTAI,......)

There are lots of gotchas moving from a RTOS to Linux.

从RTOS到Linux都有很多问题。

Maybe you don't really need real-time?

也许你真的不需要实时?

I'm talking about real-time Linux in my training: http://www.reliableembeddedsystems.com/embedded-systems_7.html

我正在谈论培训中的实时Linux:http://www.reliableembeddedsystems.com/embedded-systems_7.html

#4


1  

The answer is probably "good enough".

答案可能“足够好”。

If you're running an embedded system, you probably have control of all or most of the software on the box.

如果您正在运行嵌入式系统,则可能已经控制了所有或大部分软件。

Stock Linux 2.6 has several features suitable for low-latency tasks - chiefly these are:

Stock Linux 2.6有几个适用于低延迟任务的功能 - 主要是:

  • Scheduling policies
  • 调度策略
  • Memory locking
  • 内存锁定

Assuming you're using a single-core machine, if you have just one task which has set its scheduling policy to SCHED_FIFO or SCHED_RR (it doesn't matter which if you have just one task), AND locked all its memory in with mlockall(), then it WILL get scheduled as soon as it is ready to run.

假设您正在使用单核机器,如果您只有一个任务将其调度策略设置为SCHED_FIFO或SCHED_RR(如果您只有一个任务则无关紧要),并使用mlockall锁定其所有内存(),然后它会在准备好运行后立即安排。

Then the only thing you'd have to worry about was some non-preemptable part of the kernel taking longer than your acceptable latency to complete - which is unlikely to happen in an embedded system unless something bad happens, such as extreme memory pressure, or your drivers are dodgy.

那么你唯一需要担心的是内核的一些非抢占部分需要的时间超过你可接受的延迟时间 - 这在嵌入式系统中不太可能发生,除非发生了一些不好的事情,例如极端的内存压力,或者你的司机很狡猾。

I guess "try it and see" is a good answer, but that's probably rather complicated in your case (and might involve writing device drivers etc).

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

Look at the doc for sched_setscheduler for some good info.

查看sched_setscheduler的doc以获取一些好的信息。