本帖最后由 tobot 于 2022-1-13 23:00 编辑
继续之前提升树莓派的实时性的话题,在 https://bbs.21ic.com/forum.php?mod=viewthread&tid=3186340#pid12522916 目标中,为了读取DHT11温湿度传感器,需要GPIO接口至少达到28us的响应速度和时间检测,为了区分0、1,我们使用累加循环若干次,对次数进行统计,确认其高电平的持续时间,也在其中分析了,因为树莓派本身MCU的差异,导致代码的一致性并不好,换一款MCU就需要重新根据实际情况调整,而且在非实时的操作系统上,往往会出现突发的任务占用这一时间片,导致计算操作时延可能出错。 之前帖子https://bbs.21ic.com/icview-3191176-1-1.html中,也提到可以使用专核专用的方法来提升实时特性,这里再介绍另外一种方法,通过部署RT工具来实现每次操作尽可能一致,而不受到其它任务进程的干扰。 参考https://github.com/lemariva/RT-Tools-RPi,是一个面向树莓派的RT补丁,据说部署以后,系统的实时特性会得到有效提升。 但如何度量任务的“实时性”呢?用读取传感器尝试过,“感觉”是有改善的,为了量化这一数据,在系统中安装rt-tests测试工具集(包括cyclictest、hackbench、pmqtest、ptsematest、rt-migrate-test、signaltest、sigwaittest等),来对“real time”特性进行评估。 一、安装rt-test工具集 在操作系统中使用apt-get安装工具集: 参考https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/rt-tests文档,工具集中,最重要的测试项为cyclictest(测试延迟)。 cyclictest是一款用于测试任务时延的工具。通过反复执行一个新建任务,计算任务中断和调度所需时间,得到测试结果。如下图所示: cyclictest工具可以逐条输出每次延时测量的结果,也可以一次性输出大量测试结果的统计值。 二、cyclictest工具的使用 根据https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/worstcaselatency 中的介绍,如果测试实时性能,应该在一定负载下进行测试,其参考建议生成负载可以用: 1、用stress产生背景压力 2、用脚本分别对CPU、IO、网络、disk产生压力 为了简化测试,我们直接使用stress-ng来对系统产生压力,新开一个窗口安装stress-ng并运行: 我们知道stress-ng可产生压力的算法模式非常多(据说有30多种不同的压力算法,包括pi, crc16, fft等),这里也不用一一验证,直接使用stress-ng -c 4 --cpu-method all命令让所有模式都生效: 另开一个终端,执行cyclictest测试,如之前所述,我们希望的是得到一致性的比较,无需过于关注每次测试的结果,调整命令参数,使其直接输出histogram统计结果。具体命令为: sudo cyclictest -p 60 - m -c 0 -i 1000 -n -h 200 -q -l 1000000 其中参数: -p 60表示新建进程优先级为60 -m表示锁定内存分配 -c 0使用默认的MONOTONIC 时钟 -i 1000 指定一个循环为1000us -l 1000000总共1000000次循环,也就是说我们会得到1000000个时延测试结果 -n 使用nanosleep -q为在运行时不打印即时信息 -h 200统计0~199us的信息(这也是多次测试得到的一个参考值,超过200us延迟结果数量不多,可以暂不考虑) 执行完成后会得到一张统计表格与一个较为简略的概述 根据这个描述,可以看到有736个测试结果超过我们预期200us的延迟,分别是02286……次测试,因为超出预期延迟的测试数量,比起测试总数的1000000来说,不到1‰,可以直接忽略。 三、升级Kernel 原始系统的raspbian中kernel是5.4.51,可以通过uname -a查看到: 部署补丁需要重新编译kernel,相对比较麻烦,在网站 https://github.com/lemariva/RT-Tools-RPi 中可以下载到已经集成补丁并编译通过的kernel,我们借来使用。 从网站中下载rt-kernel.tgz文件并放入raspbian系统的某个目录中,解压 tar xzvf rt-kernel.tgz 把解压出的文件拷贝文件到各目录,覆盖现有文件 sudo cp *.dtb /boot/ sudo cp overlays/* /boot/overlays sudo cp -r lib / sudo cp boot/kernel7_rt.img /boot/ 因为部署了RT补丁的kernel名字发生了变化,我们可以通过修改启动配置,使其从新kernel中启动: sudo nano /boot/config.txt 在文件中修改(或添加)kernel=kernel7_rt.img 保存重启,再查看系统: 可以看到当前使用的是4.19.59-rt23版本。 版本号比较低,因为毕竟在网站中下载的最新版本也是2年前上传的。 四、测试RT补丁效果 在修改了kernel实现RT效果的操作系统中,重复上述使用cyclictest测试实时性能过程,同时在两个终端中,执行 stress-ng -c 4 --cpu-method all 和 sudo cyclictest -p 60 - m -c 0 -i 1000 -n -h 200 -q -l 1000000 命令,再次得到一组统计数值 五、结论 为了更加直观比较,将两组数值导入excel表,生成图表 横轴是时延测试结果,纵轴是该时延出现的次数。 可以直观看到,相较于kernel版本5.4.51的测量值,部署RT补丁后kernel版本为4.19.59-rt23的测量值更加集中。意味着其“实时性”更好。 六、展望 本次实验直接借用了网上其它人编译的kernel,版本相对较老,但效果还是比较明显的。 在https://github.com/raspberrypi/linux/branches可以看到最新版本是5.16,与之相对应的,在网站https://www.kernel.org/pub/linux/kernel/projects/rt/也可以找到5.16版本的RT补丁。 因此我们可以尝试自己动手编译kernel,测试一下最新版本上部署RT的效果。
|