博主最近想搞搞运动控制器的底层,已经到了走火入魔的地步。常规意义上来讲,Linux并不算是一个实时操作系统,仅仅能实现软实时,我们可以通过打补丁的方式来实现硬实时,常用的补丁有:RT Preempt、Xenomai等。本文考虑在Ubuntu系统上打RT Preempt实时补丁来提高实时性,通过此文记录整个过程。
“Controlling a laser with Linux is crazy, but everyone in this room is crazy in his own way. So if you want to use Linux to control an industrial welding laser, I have no problem with your using PREEMPT_RT.”—— Linus Torvalds
文章目录
0. 概述
博主测试环境
- VMware Workstation 15.0 Pro
- Ubuntu 16.04 LTS
准备工作
提前安装好编译内核所需要的模块,很多教程提到需要安装libncurses-dev
,博主实践过程中发现源中并没有该包:
我们可以将能安装的完全安装,执行如下两条命令:
sudo apt-get install libncurses*
sudo apt-get install libssl-dev
整体步骤
- step1:确认系统内核版本
- step2:下载相对应的RT补丁,如果没有对应补丁,则下载一个可运行的内核版本和与之相对应的RT补丁
- step3:解压内核tar包和RT补丁包
- step4:打补丁
- step5:配置内核
- step6:编译内核
- step7:安装内核
- step8:更新GRUB启动并重启
- step9:查看内核版本以确定是否成功
- step10:测试实时内核
下面按以上叙述顺序进行记录
1. 查看系统的内核版本
uname -a
Ubuntu 16.04 LTS版本默认为4.15.0内核,默认最低内核版本为4.4.0,也可以降级为3. x但不建议这么搞
2. 下载对应的RT补丁
建议采用国内的源,博主使用的清华的源,发现没有与之对应的RT内核版本,因此博主选用了linux-4.4.206
版本内核以及与之对应的RT补丁patch-4.4.206-rt190
。
注意:内核版本与RT补丁版本必须匹配!!!
v4.x版本内核下载网址: https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x
v4.x版本RT补丁下载网址: https://mirrors.tuna.tsinghua.edu.cn/kernel/projects/rt/4.4/
小技巧:在网页使用组合键Ctrl + F可以让你很快找到你想要的东西。
3. 解压内核、补丁包并打补丁
首先创建一个文件夹,名称无所谓,自定义即可,此处取名kernel
mkdir kernel
cd kernel
将下载好的linux-4.4.206.tar.gz
和patch-4.4.206-rt190.patch.gz
复制到该文件夹中,执行以下命令:
tar -xzvf linux-4.4.206.tar.gz
gunzip patch-4.4.206-rt190.patch.gz
将解压得到的patch-4.4.206-rt190.patch
文件复制到内核解压文件夹linux-4.4.206
中,执行以下命令:
patch -p1 < patch-4.4.206-rt190.patch
至此完成打补丁工作。
4. 配置内核
注意!!!在执行以下命令时,编译模块必须已经安装完毕,否则报错缺少文件!!!
在文件夹linux-4.4.206
下打开终端,执行如下命令:
make menuconfig
出现如图所示界面:
注意:以下过程可能因内核版本不同而不同,需根据实际情况选择,其目的都相同,即选择RT模式和关闭内存溢出。
选中红框内容Processor type and features --->
并按下Enter键:
通过↑、↓键选定Preemption Model (Voluntary Kernel Preemption (Desktop)) --->
并按下Enter键:
通过↑、↓键选定( ) Fully Preemptible Kernel (RT)
并按下Enter键:
主要配置已经做完了,接下来我们要关闭内存溢出检测,两次ESC键回到如下图界面,找到Kernel hacking
选项并按下Enter键:
通过↑、↓键选定Memory Debugging
并按下Enter键:
通过↑、↓键找到[ ] Check for stack overflows
选项确认其处于未选中状态。(该选项默认为取消状态)
四次ESC键回到如下图界面,通过←、→键选中Save
选项保存配置。
保存配置界面如下,Enter< OK >
:
5. 编译内核
在kernel/linux-4.4.206
文件夹下启动终端执行如下命令:
make -j4 # 此处的数字为处理器内核总数
# 使用该参数是为了提高编译速度
# 以下命令如出现此参数,同样是出于提高速度的目的
注意:此处的数字为处理器内核总数,由于博主虚拟机分配的是2个处理器,2内核/处理器,故此处数字为4。
- 关于加速编译可参考博文:https://blog.csdn.net/gonghuihuihui/article/details/79091762
接下来就是风扇狂啸的时刻!!!
过了20多分钟后发现。。。。。。
好吧,是我的锅,重新分配磁盘再来一次~
6. 安装内核
执行如下命令:
sudo make modules_install -j4
sudo make install -j4
7. 更新GRUB并重启
执行如下命令:
sudo update-grub
sudo reboot
重启后长按Shift (虚拟机需要,其他根据实际情况)选择Ubuntu 高级选项
→Ubuntu,Linux 4.4.206-rt190
8. 测试实时内核
同样通过uname -a
命令来查看内核版本:
接下来需要安装测试工具,通常采用开源的RT-tests
来进行测试,执行如下命令:
sudo apt-get install rt-tests
对于RT-tests测试工具集的使用,运行其中的cyclictest:
sudo cyclictest -t 5 -p 80 -n #5个线程,线程优先级80,无限循环
图中运行结果解释:
- T: 0 序号为0的线程
- P: 0 线程优先级为0
- C: 9397 计数器。线程的时间间隔每达到一次,计数器加1
- I: 1000 时间间隔为1000微秒(us)
- Min: 最小延时(us)
- Act: 最近一次的延时(us)
- Avg:平均延时(us)
- Max: 最大延时(us)
对于非RT内核下的测试结果如下:
我们发现两者区别不大,有大佬说在虚拟机中效果一般,受主机限制太大,没有经过实际测试咱也不敢瞎说,实体机测试留坑待填! 经过实际测试发现,在无干扰的情况下最近延迟确实要小一些,但并没有测试有干扰情况下的区别,测试图如下:
- 但实体机测试时出现一个新问题,rt内核版本无法联网,而正常版本可以,不清楚是电脑的问题(Y7000是存在安装完系统无法联网的问题的)还是普遍存在的问题。
- 其他版本系统的RT补丁安装与此类似,本文可做实践参考!
后记
在网上看到有网友说:
不太推荐在Linux下用硬实时,这伙本身就是为高并发而生的, 用了硬实时,严格时序后,本质上把装有Linux的嵌入设备变成了大号单片机,不太划算,而且服务端设备上,更不肯可能用这个,吞吐量会大幅下降, 而且异步无阻塞模式下,哪怕是抢占式任务管理, 也能最大限度发挥硬件性能,小设备应用,非要实时,还不如直接用单片机+裸机程序呢,不用考虑任务调度与管理
其实这位网友说的是有一定道理的,通常情况下实时系统都是在嵌入式设备上跑,是针对那种复杂算法且实时性要求较高的底层控制使用,如果单片机能实现,当然更好,毕竟实际工程要考虑成本嘛!
仅仅在计算机上学习一下实时操作系统,当然还是选择虚拟机,不要问我为什么,当你开不开机的时候你就知道了~
以上仅为博主个人观点,如果有误还请各路大神斧正。
关于RT-PREEMPT的使用,参见wiki.linuxfoundation.org
本文参考:
- https://blog.csdn.net/lsky380/article/details/90769058
- https://ubuntuforums.org/showthread.php?t=2273355
- https://www.linuxidc.com/Linux/2018-05/152270.htm
- https://blog.csdn.net/uanjj/article/details/88830668
- https://blog.csdn.net/dzhongjie/article/details/84869322
- https://rt.wiki.kernel.org/index.php/Main_Page
- https://blog.csdn.net/21cnbao/article/details/8038279
- https://blog.csdn.net/v6543210/article/details/80941906#7.1%20ubuntu%20%E5%AE%89%E8%A3%85%E4%BD%8E%E5%BB%B6%E6%97%B6%E5%86%85%E6%A0%B8