树莓派提高实时性的几种方式(使用python测试)

前言

本文基于python3.5+, 树莓派型号为3b+

1. 关于树莓派的实时性

2. 几种思路与实现

2.1 提高优先级

提高优先级可以通过wiringpi库提供的piHiPri(pri)方法实现
其中,pri为int类型,取值范围为[0,99], 根据python中的实际测试,0为默认值,1优先级最高,99最小(此处貌似和资料不一致,但是实际测试是这样),使用方法为在执行前调用piHiPri()方法,具体代码如下:

import wiringpi
wiringpi.piHiPri(pri)

2.2 绑定CPU

绑定cpu需要两个操作:

  • 在系统中屏蔽掉一个或多个cpu
  • 代码中绑定cpu

屏蔽cpu的实现方法:
/boot/cmdline.txt 中末尾添加isolcpus=x
其中x为屏蔽的核心 X=3时为树莓派中的最后一个cpu(树莓派3b为例,cpu编号为0-3)
此处注意,添加的isolcpus=x不能起新行,需要写在原行的末尾,如:


dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=3a7978f6-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait isolcpus=3

添加后重启系统,使用htop命令查看cpu占用(没有可以用apt-get install htop安装),如下图:

htop命令下的cpu占用情况

此时系统自身调度不会再占用最后一个cpu(此处显示序号为4,因为是从1开始的,在系统中实际编号为3)

绑定cpu的方式:
python中,可以使用affinity库来绑定制定cpu(没有可以用pip install affinity 安装),affinity库一共提供了两个方法:

  • affinity.get_process_affinity_mask(pid)
  • affinity.set_process_affinity_mask(dwMask)

第一个方法传入pid,返回dwMask值,dwMask为CPU序号掩码,1(0001)代表只运行在CPU1,2(0010)代表只运行在CPU2,3(0011)代表可以运行在CPU1和CPU2,以此类推。
第二个方法传入dwMask, 返回0为成功,-1为失败.该方法需要root用户权限.
参考代码如下:

def run():
    while True:
        pass

p = multiprocessing.Process(target=run)
p.start()
pid = p.pid
print(affinity.get_process_affinity_mask(pid))
affinity.set_process_affinity_mask(pid, 15L)
print(affinity.get_process_affinity_mask(pid))

2.3 实时linux系统移植

出于通用性的考虑,本文只讨论linux系统的patch

2.3.1 RT-linux

Linux是典型的分时应用系统,对于实时性要求很高的应用,必须对内核本身动手术。而RTLinux则采取了一种比较聪明也比较折中的办法:他们实现一个最底层的精简的调度器,用于调度实时线程,原来的内核本身则成为实时调度器的一个优先级最低的任务。这样,当有实时任务时,普通内核已经建立于其上的普通进程被强制中断,实时线程被强制执行;只有当若有实时线程都让出cpu之后,普通内核才被运行,再由普通内核去调度执行普通的应用程序

移植方法:
(1)首先下载树莓派linux源代码:
git clone https://github.com/raspberrypi/linux.git

注意,由于该repo比较大,而git其实不支持断点续传(git init + git fetch + git checkout的方式实测并不能续传,每次断链再次fetch都是从头开始),所以建议只clone一个分支,且令depth为1,下载成功后再下载历史记录(如果需要),则命令改为:
git clone --depth=1 --single-branch --branch rpi-4.14.y git https://github.com/raspberrypi/linux.git

本文选用4.14,目前最新的树莓派内核版本为为4.14

(2)下载patch文件:
https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/4.14/

patch压缩包,在本地解压出.patch文件,并移动到clone好的linux/文件夹下即可

(3)给linux内核打patch
进入clone好的linux文件夹,执行命令
cat *.patch | patch -p1

(4)下载编译
git clone https://github.com/raspberrypi/tools ~/tools

(5)配置PATH变量,注意32bit和64bit系统存在差异(如果是其他版本的树莓派则不是arm-bcm2708,1代为):
32位系统:

echo PATH=\$PATH:~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin >> ~/.bashrc
source ~/.bashrc

64位系统:

echo PATH=\$PATH:~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin >> ~/.bashrc
source ~/.bashrc
sudo apt-get install libc6:i386
sudo apt-get install lib32stdc++6
sudo apt-get install lib32z1

如果文件夹或路径不同注意自己改名,zsh同理
另外一些文章提到了另外一些依赖,如果可能也尽量安装(并不知道有何种影响,一般的报错可以先行google查询):

sudo apt-get install bc
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install zlib1g:i386
sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5

(6)配置交叉编译设置
进入linux目录,修改Makefile文件
vim Makefile
找到如下语句
ARCH ?= arm,修改为 :
CROSS_COMPILE ?= /home/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
同样路径注意修改

(7)检查依赖
运行make menuconfig查看是否有报错,根据报错信息安装依赖或自行google

(8)进行编译

KERNEL=kernel7 
make bcm2709_defconfig
make zImage modules dtbs

如需多核加速编译可以加–j8参数等

(9)部署到内存卡
插入sd卡和读卡器(格式化,分区等参考fdisk等命令)
注意此sd卡已有rasbian系统
挂载:

mkdir mnt 
mkdir mnt/fat32 
mkdir mnt/ext4 
sudo mount /dev/sdb1 mnt/fat32 
sudo mount /dev/sdb2 mnt/ext4

安装:
sudo make INSTALL_MOD_PATH=mnt/ext4 modules_install

备份与拷贝内核:

sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img 
sudo cp arch/arm/boot/zImage mnt/fat32/$KERNEL.img 
sudo cp arch/arm/boot/dts/*.dtb mnt/fat32/ 
sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/ 
sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/ 
sudo umount mnt/fat32 
sudo umount mnt/ext4

(10)启动树莓派,检查是否安装成功
运行uname -a查看是否有RT字段

2.3.2 PREEMPT_RT

2.4 利用中断

2.5 连接外设(实时钟发生器)

2.6 超频

3. 测试

影响延迟的变量包括:

  • cpu是否满载(或其他cpu是否满载)
  • 是否使用python(考虑到解释器的延迟)

3.1 提高优先级

3.2 绑定cpu

3.3 实时操作系统移植

3.4 利用中断

4. 总结

后记

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容