https://blog.csdn.net/baidu_34045013/article/details/78886617
实时应用程序在某些触发事件和应用程序对该事件的响应之间有操作截止日期。为了满足这些操作期限,程序员使用实时操作系统(RTOS),在该系统上可以可靠地计算或测量给定应用程序和环境的最大响应时间。典型的RTOS使用优先级。需要CPU的最高优先级任务总是在事件唤醒任务之后的固定时间内获得CPU。在这种RTOS中,任务的延迟只取决于以相同或更高优先级运行的任务;优先级较低的任务可能会被忽略。在非实时操作系统(大多数GNU/Linux发行版运行它们的默认内核)上,由于延迟依赖于系统上运行的每个进程,因此很明显,要确保每次都能满足截止日期要困难得多,而且这种困难会随着系统的复杂性而非线性地扩展。调度中的决定论变得更加难以实现,因为可以在任意数量的时间内关闭抢占。因此,想要运行的高优先级任务可以被禁用抢占的低优先级任务无限期延迟。
所谓实时操作系统(Real-time Opearting System),是指当外接世界或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,调度一切可利用的资源完成实时任务,并控制所有实时任务协调一致运行的操作系统。相比于分时操作系统有着响应及时和可靠性高的优点。
本文将在QEMU环境下,通过给内核打实时补丁的方式,使Linux成为一个实时操作系统,并使用测试程序判断内核的实时性。
对QEMU不熟悉的朋友可以移步我的上一篇博客:http://blog.csdn.net/baidu_34045013/article/details/78882607
实验环境
ubuntu 16.04.2
QEMU-2.11.0
Linux kernel-4.14.7
Real-time patch-4.14.8
安装Cyclictest
为了比较打补丁前后的性能差异,我们选用Real-Time Linux Wiki提供的基准测试用例Cyclictest
https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest
Cyclictest是一个高精度的测试程序,是rt-test下的一个测试工具,也是rt-test下使用最广泛的测试工具,样板主要用来测试使用内核的延迟,从而判断内核的实时性。
从git clone rt-test源码
git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
cd rt-tests
git checkout stable/v1.0
1
2
3
交叉编译rt-test,修改Makefile中的编译器
CC = arm-linux-gnueabi-gcc
AR = arm-linux-gnueabi-ar
1
2
make
1
将编译好的rt-tests放入文件系统
sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop
sudo mkdir tmpfs/rt-tests
sudo cp rt-tests/* -r tmpfs/rt-tests/
sudo umount tmpfs
1
2
3
4
启动QEMU,进入rt-tests目录,使用Cyclictest
./cyclictest -t1 -p 80 -n -i 10000 -l 10000
1
运行结果如下:
结果分析
T:0(783) P:80 I:10000 C:10000 Min:259 Act:4281 Avg:5201 Max: 14962
T: 线程序号为0
P: 线程的优先级为80
C: 计数器,线程的时间间隔每达到一次,计数器加1
I: 时间间隔(单位微秒 us)
Min: 最小时延(us)
Act: 最近一次的时延
Avg: 平均时延
Max: 最大时延
参数分析
-t 线程数
-p 最高优先级线程的优先级
-n 使用clock_nanosleep
-i 基本线程间隔,默认为1000us
-l 循环次数,默认为正无穷
运行另一个测试命令
./cyclictest -t5 -p80 -n -i 10000 -l 1000
接下来我们给kernel打上实时补丁,再运行测试用例测试系统实时性
打实时补丁
Linux Real-time Patch可以在kernel.org找到
这里我们选择下载与内核版本对应的rt patch
wget /patch-4.14.8-rt9.patch.gz
1
解压patch
gunzip patch-4.14.8-rt9.patch.gz
cp patch-4.14.8-rt9.patch linux-4.14.7/
cd linux-4.14.7
1
2
3
打补丁
patch -p1 < patch-4.14.8-rt9.patch
1
如需回退补丁使用以下命令
patch -R -p1 < patch-4.14.8-rt9.patch
1
打补丁成功后,重新编译内核,这里由于内核是跑在QEMU模拟的vexpress-a9单板上,所以需要交叉编译,有关交叉编译的内容也在我的上一篇博客有介绍
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm menuconfig
1
在“Processor type and features”中
选择“Complete Preemption (Real-Time)”、“Thread Softirqs”和“Thread Hardirqs”
在“Device Drivers”中
去掉“Staging Drivers”
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm
1
更新grub
sudo update-grub2
1
测试实时抢占系统
启动QEMU
命令行输入 uname -a
证明当前内核已打上实时补丁
接下来再运行测试用例,来检验实时补丁是否起了作用
./cyclictest -t1 -p 80 -n -i 10000 -l 10000
1
./cyclictest -t5 -p80 -n -i 10000 -l 1000
1
通过以上两个例子的运行,我们发现打了实时补丁的内核的实时性要明显优于非实时内核。
有兴趣的朋友也可以使用latencytop进行比较测试