2. RT-Linux#
本章配套视频介绍:
《23-在鲁班猫上使用实时RT-Linux》
https://www.bilibili.com/video/BV1Js4y1B7jd/
RT-Linux是一个基于Linux内核的实时操作系统,它结合了Linux操作系统的通用性和实时性能,为开发者提供了一个统一的平台来开发实时应用程序。
RT-Linux的核心是Linux内核的一个实时扩展,它为实时任务提供了必要的调度机制和时间管理。 通过采用抢占式调度策略,高优先级的实时任务可以打断低优先级的任务,确保实时任务能够及时响应。 RT-Linux对任务的调度和中断处理进行了改进,使得任务能够按照预定的时间要求执行。
RT-Linux适用于对时间要求敏感的应用领域,例如工业自动化、机器人控制、航空航天系统等。 它可以提供精确的任务调度和快速的响应时间,以确保系统能够在实时任务的要求下正常运行。
与传统的Linux内核相比,RT-Linux在实时性能方面有所提升,但它并不是一个硬实时系统,无法保证任务的执行时间绝对精确。 对于对时间要求极高的应用,可能需要采用更专门的实时操作系统。
RT-Linux兼容Linux操作系统的通用性,可以利用Linux生态系统中的各种工具和库进行开发。 开发者可以使用广泛的开发工具和资源来构建实时应用程序,从而提高开发效率。
备注
鲁班猫的内核也支持RT-Linux,使用PREEMPT_RT补丁对内核进行修改。
2.1. 鲁班猫RT-Linux安装方法#
2.1.1. 在线更新内核#
先更新软件包数据库
1sudo apt update
卸载旧的内核:因为旧的内核不兼容RT-Linux,所以要把他卸载
1#卸载旧内核
2sudo apt remove linux-headers-6.1.99-rk3576 linux-image-6.1.99-rk3576
获取RT-Linux内核
1#在线安装新内核
2sudo apt install linux-headers-6.1.99-rt36-rk3576 linux-image-6.1.99-rt36-rk3576
重启生效内核
1reboot
2.2. 鲁班猫RT-Linux测试#
2.2.1. cyclictest#
Cyclictest是一个用于测试Linux系统实时性能的工具,它能够测量系统的响应时间和时钟精度。Cyclictest通过创建周期性的负载来评估系统在实时任务处理方面的能力。
注意
该测试为带载测试,负载很大,ssh登录的话,可能会无法进入控制台和显示信息,所以推荐使用串口root登录,下面的命令都是依照串口root登录来写的
1#apt更新软件包
2apt update
3
4#安装工具
5apt install -y python git
6
7#下载cyclictest的源码
8git clone https://github.com/jlelli/rt-tests.git
9
10#进入源码目录
11cd rt-tests
12
13#编译源码(如果有报错,应该是依赖没弄好,根据缺失的依赖安装即可)
14make -j4
15
16#如果是桌面镜像需额外执行以下命令,lite镜像则不用
17sysctl -w kernel.sched_rt_runtime_us=-1
18
19#负载测试(该方法需要在rt-tests目录下面执行)
20./cyclictest -t 4 -p 99 -n -m -d 0 & ./hackbench -l -1 -g 15 -f 25 -P &
21
22#空载测试(该方法需要在rt-tests目录下面执行)
23./cyclictest -t 4 -p 99 -n -m -d 0
24
25#安装到/usr/bin中(该选项可选)
26make install
27
28#负载测试(该选项可选,可在其他目录下执行)
29cyclictest -t 4 -p 99 -n -m -d 0 & hackbench -l -1 -g 15 -f 25 -P &
30
31#空载测试(该选项可选,可在其他目录下执行)
32cyclictest -t 4 -p 99 -n -m -d 0
hackbench -l -1 -g 15 -f 25 -P 是用来制作负载的
-l -1: 表示hackbench将以无限循环方式运行,不会自动退出。
-g 15: 设置每个进程组(group)的进程数量为15。每个进程组将会生成一组进程进行通信。
-f 25: 设置每个进程组之间的父子关系的数量为25。这决定了进程组之间的通信方式。
-P: 使用多个CPU核心来运行测试,以模拟多核系统的情况。
cyclictest -t 4 -p 99 -n -m -d 0
-t 4: 指定使用4个线程进行测试。每个线程将创建一个周期性负载。
-p 99: 设置线程的优先级为99,这是最高的实时优先级。使用最高优先级可以更好地测试系统的实时性能。
-n: 在测试期间禁止休眠。这将防止系统进入休眠状态,以保持系统处于活跃状态。
-m: 运行测试前锁定内存。这将防止测试期间的内存分页错误,并提供更一致的测试结果。
-d 0: 禁用延迟输出。这将阻止输出每个线程的详细延迟数据,只显示测试的总体统计信息
2.3. 鲁班猫RT-Linux内核源码#
仓库地址为:https://github.com/LubanCat/kernel/tree/lbc-develop-6.1-rt36
rk3576对应的分支为:lbc-develop-6.1-rt36
如果需要自行编译RT内核,可在SDK根目录执行以下命令:
1#删除旧内核源码
2rm -rf kernel-6.1/
3rm -rf kernel
4
5#拉取新内核源码,只拉取最新一次提交,指定lbc-develop-6.1-rt36分支
6git clone --depth=1 -b lbc-develop-6.1-rt36 https://github.com/LubanCat/kernel.git
7
8#重命名
9mv kernel kernel-6.1
10
11#编译内核deb包
12./build.sh kerneldeb
编译出来的linux-headers-6.1.99-rt36-rk3576和linux-image-6.1.99-rt36-rk3576内核deb包传到板卡进行更新即可,或者也可通过编译完整镜像,然后更新系统镜像的方式进行更新。
2.4. 提高实时策略#
2.4.1. 使用不带桌面的系统#
不带桌面的系统实时性能比带桌面的系统要好,因此要求实时性能高建议使用lite版本镜像,如果需要运行图形界面,可自行编写Qt程序等。
2.4.2. 绑定核心#
2.4.2.1. CPU核心隔离#
通过uEnv.txt传递参数可很方便对uboot启动变量进行修改,在uEnv.txt的cmdline环境变量中添加isolcpus参数即可对CPU核心进行隔离。
以隔离CPU的2、3核为例,修改/boot/uEnv/uEnv.txt如下:
1cmdline="earlyprintk console=ttyFIQ0 console=tty1 consoleblank=0 loglevel=7 rootwait rw rootfstype=ext4 isolcpus=2,3"
只需在cmdline中添加isolcpus=2,3,添加完成后重启板卡,执行以下命令查看2、3核是否被隔离:
1#查看指定进程pid绑定到哪些CPU核心上
2taskset -cp 1
3
4#信息输出如下
5pid 1's current affinity list: 0,1,4-7
从输出信息可见,pid 1进程没有运行在2、3核,也即成功对CPU核心进行隔离。
2.4.2.2. 程序绑定核心#
对CPU核心进行隔离后,可将程序绑定到隔离的CPU核心上运行,以简单的helloworld程序进行测试,helloworld.c程序内容如下:
1#include <stdio.h>
2#include <unistd.h>
3
4int main()
5{
6 int i=0;
7 printf("hello, world! This is a C program.\n");
8 for(;;){
9 printf("output i=%d\n",i);
10 sleep(1);
11 i++;
12 }
13
14 return 0;
15}
编译并绑定到CPU核心2上运行:
1#编译
2gcc helloworld.c -o helloworld
3
4#绑定到核心2上并后台运行
5taskset -c 2 ./helloworld &
6
7#查看helloworld的pid
8pgrep helloworld
9
10#查看helloworld运行在哪个核心
11taskset -cp $(pgrep helloworld)
12
13#杀死helloworld
14kill $(pgrep helloworld)
2.4.2.3. 中断绑定核心#
对于重要的中断可以在系统启动之后将中断绑定到其他核心,例如eth0中断绑定到CPU核心2上。
1#查看eth0中断号
2cat /proc/interrupts | grep eth0
3#信息输出如下
455: 0 0 0 0 0 0 0 0 GICv2 325 Level eth0
556: 0 0 0 0 0 0 0 0 GICv2 330 Level eth0
6
7#查看55中断运行的核心
8cat /proc/irq/55/smp_affinity_list
9
10#将55中断绑定到CPU核心2
11echo 2 > /proc/irq/55/smp_affinity_list