下载 RTLinux 系统固件 RTLinux 系统固件: ROC-RK3568-PC ROC-RK3566-PC AIO-3568J (有反馈说在使用hdmi测试实时性能,最达延时有超过200us的现象。 为此我们重新优化了内核,修复了使用hdmi出现高延迟现象,并提升实时性能。)
测试实时效果 测试实时性能需要cyclictest,可以使用apt安装。 apt update apt install rt-tests 使用apt安装的版本比较低(v1.0),可以下载源码编译,建议在板子里编译,因为使用交叉编译工具编译出来的cyclictest功能不完整,比如-a选项无法绑定某些CPU,只能绑定某个或者全部CPU #下载rt_tests源码 git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git #安装依赖 sudo apt-get install build-essential libnuma-dev #切换分支: git checkout v1.7 在板子上编译直接make;在其他平台编译时需要指定交叉编译工具路径。如下: make CROSS_COMPILE=/home/dengkx/project/rk356x/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- 然后执行,生成cyclictest。
测试RTLinux的实时效果 拷贝cyclictest到板子上,执行以下命令对20个线程进行实时测试。 #加上-a 实时效果会更好,版本比较低时需要加上-n选项 sudo ./cyclictest -t 20 -p 99 以下的的截图是minimal ubuntu在cpu满压力下测得的结果,T:0 序号为0的线程;P:99 线程优先级为99 ;C: 9397 计数器。线程的时间间隔每达到一次,计数器加1;I: 1000 时间间隔为1000微秒(us) ;Min: 最小延时(us);Act: 最近一次的延时(us);Avg:平均延时(us);Max: 最大延时(us)。
一些使用参数解析: -t:指定运行多少个实时线程 ; 例如运行20个实时线程: -t20 -p:指定运行的实时线程优先级; 例如运行线程的优先级为80: -p80 -a:设置实时线程亲和核心; 例如设置实时线程运行在1到3CPU上: -a 1-3(后面不加参数,则指定全部核心;低版本指定单个核心或者全部核心) -i:线程的基础间隔,默认为1000us -l;线程之间的间隔,默认为500us -m:固定程序到内存,防止程序被调出内存 -q:只在程序结束时打印结果
Cyclictest标准测试 threads选项(-t)用于指定Cyclictest在检测延迟时将使用的测量线程数。通常,在系统上的每个CPU上只运行一个测量线程是一个标准的测试方案。可以使用亲和性选项(-a)指定线程必须在其上执行的cpu。 这些选项对于最小化运行Cyclictest对观察到的系统的影响至关重要。在使用Cyclictest时,确保在任何给定时间只执行一个测量线程是很重要的。如果两个或多个Cyclictest线程的预期执行时间重叠,则Cyclictest的测量将受到其自己的测量线程所造成的延迟的影响。确保在给定的时间只执行一个测量线程的最好方法是在给定的CPU上只执行一个测量线程。 例如,如果要分析三个特定cpu的延迟,则指定应该使用这些cpu(使用-a选项),并指定应该使用三个测量线程(使用-t选项)。在这种情况下,为了最小化Cyclictest的开销,请确保收集度量数据的主Cyclictest线程没有运行在三个隔离的cpu之一上。主线程的关联性可以使用taskset程序设置,如下所述。
在评估一组隔离的cpu上的延迟时,减小cyclictest的影响 在测量cpu子集上的延迟时,确保主Cyclictest线程正在未被评估的cpu上运行。例如,如果一个系统有两个CPU,并且正在评估CPU 0上的延迟,那么主Cyclictest线程应该固定在CPU 1上。Cyclictest的主线程不是实时的,但是如果它在被评估的CPU上执行,它可能会对延迟产生影响,因为会有额外的上下文切换。在启动Cyclictest之后,可以使用taskset命令将主线程限制为在cpu的某个子集上执行。例如,针对CPU1到CPU3的延时测试: #CPU1到CPU3运行实时程序,主线运行在CPU0上(需要板子编译出来的cyclictest,否则三个实时线程只会运行在CPU1上,CPU2和3则没有) taskset -c 0 ./cyclictest -t3 -p99 -a 1-3 taskset程序还可以用于确保系统上运行的其他程序不会影响隔离CPU上的延迟。例如,启动程序top查看线程并固定到CPU 0上,使用下面的命令: taskset --cpu 0 top -H -p PID #top打开之后点击f键,光标移动到 P 选项,空格选中,然后点击 q建退出,便可查看到实时线程在哪些CPU上运行。
在最坏的情境下测试CPU延迟 下面一条的测试代码是RT系统中最坏情况下的背景压力。 time ./cyclictest -t50 -p 80 -i 10000 -n -l 100000000000 -d 86400 -a 3 你还可以制造相应的压力环境来进行测试CPU延时,例如: 使用stress制造四个核心100%CPU负载。 #stress -c 4& #还可以固定到CPU上,如下: taskset -c 0 stress -c 1& taskset -c 1 stress -c 1& taskset -c 2 stress -c 1& taskset -c 3 stress -c 1& 也可以使用ping制造100%CPU负载。 taskset -c 0 /bin/ping -l 100000 -q -s 10 -f localhost & taskset -c 1 /bin/ping -l 100000 -q -s 10 -f localhost & taskset -c 2 /bin/ping -l 100000 -q -s 10 -f localhost & taskset -c 3 /bin/ping -l 100000 -q -s 10 -f localhost & 对于I/O负载可以使用tar来制造。例如下载linux源码git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-stable cd /opt while true; do taskset -c 0 tar cv*** test1.tgz ./linux-stable ; done & while true; do taskset -c 1 tar cv*** test2.tgz ./linux-stable ; done & while true; do taskset -c 2 tar cv*** test3.tgz ./linux-stable ; done & while true; do taskset -c 3 tar cv*** test4.tgz ./linux-stable ; done & 产生网络负载。 # 启动服务器 /usr/bin/netserver # 启动 netperf 连接 /usr/bin/netperf -H <IP_ADDR_OF_SERVER> -t TCP_STREAM -A 16K,16K -l 3600 # 使用浏览器 firefox 根据需求来选择压力环境,然后进行延时测试。
一些使用rtlinux的建议 抑制控制台消息及禁止内存过度使用 #可以使用内核参数quiet启动内核,或者启动之后抑制,如下: echo 1 > /proc/sys/kernel/printk #禁用内存过度使用以避免 Out-of-Memory Killer产生的延迟 echo 2 > /proc/sys/vm/overcommit_memory
不使用桌面或者使用轻量级桌面 为了更好的实时,我们不建议使用带桌面的系统,因为这将为CPU延迟带来很大的挑战。建议使用minimal ubuntu、自己的QT程序等。 特定的核心处理特定的事 实时要求高的事件固定到某个核心上处理,系统及其它实时要求不高的事件集中到一个核心上处理。例如特定的中断,实时程序等事件可以用专门的核心为他们服务。 使用芯片的MCU 对于实时要求更高的事件,建议使用芯片上的MCU功能,以便达到更好的实时控制。 CANFD驱动 目前暂时只有rtlinux使用CANFD驱动,CAN FD是兼容CAN功能的,发送CAN格式就可以。由于rk3568芯片的canfd发送数据格式有问题,所以只使用can功能。 如果你一定要使用canfd功能,你需要保证发送报文的最后五位数据不全为0或1(例如,将最后两位数据固定为01等),便可以正常使用canfd功能。 #在收发端关闭can0设备 ip link set can0 down #在收发端设置仲裁段1M波特率,数据段3M波特率 ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on #打印can0信息 ip -details link show can0 #在收发端打开can0设备 ip link set can0 up #在接收端执行candump,阻塞等待报文 candump can0 #canfd格式,在发送端执行cansend,发送报文 cansend can0 123##112345678 #can格式,在发送端执行cansend,发送报文 cansend can0 123#1122334455667788
原作者:Firefly Wiki
|