• 【 声明:版权所有,欢迎转载,请勿用于商业用途。...    因为linux本身不是rtos系统,所以用linux来完成一些对实时性有要求的工作,这...只是这个patch修改内容较多,不过最主要的部分还是集中在自选锁互斥化、中...

    【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

     

        因为linux本身不是rtos系统,所以用linux来完成一些对实时性有要求的工作,这本身就是很复杂的一项工作。但是,后来开源社区为linux提供了rt-patch,在很大程度上改善了linux的实时性。只是这个patch修改内容较多,不过最主要的部分还是集中在自选锁互斥化、中断线程化和修正优先级翻转的问题上面。

     

    1、常用的rt-patch地址如下所示

    https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/

     

    2、给kernel打上patch,配置rt-linux然后编译

    patch -p1 < *.patch

    如果需要对kernel配置,基本上配置好“Fully Preemptible Kernel”即可

    编译方法和一般的kernel编译是一样的

     

    3、注意事项

    基本上使用rt-patch的时候,需要将kernel中所有的DEBUG信息全部关掉

     

    4、目前使用rt-patch的项目

    商业上目前使用rt-patch的项目据我所知只限于百度的apollo,链接地址如下

    https://github.com/ApolloAuto/apollo-kernel/tree/master/linux

     

    5、风险和优势

    rt-patch最大的风险,就是需要了解目前自身项目团队中是否有人精通kernel,是否可以解决产品压力测试出现的和rt-patch相关的所有问题

    优势就是成本低

     

    6、推荐方案

    多准备开发板进行压力测试,总结测试中发现的各种问题,优先修改上层代码、其次是驱动代码、最后才是内核核心代码

     

    update:

        和wu zhangjin同学沟通,得知打上rt-patch的kernel一直在OSADL正常运行,时间有10年之久。

     

    展开全文
  • RTlinux3.2安装

    2015-12-05 14:54:13
    前言2003 年以后, fmslabs 的 RTLinux Free 版本为 3.2Pre ,和以前的 RTLinux 3.1 比较,不再需要必须从 2.4.4 的内核上安装。 RTLinux 3.2 支持的 Linux 内核为 2.4.19/2.4.20/2.4.21Pre5( 2 ).准备目前计算机...

    ( 1 ).前言

    2003 年以后, fmslabs 的 RTLinux Free 版本为 3.2Pre ,和以前的 RTLinux 3.1 比较,不再需要必须从 2.4.4 的内核上安装。 RTLinux 3.2 支持的 Linux 内核为 2.4.19/2.4.20/2.4.21Pre5

    ( 2 ).准备

    目前计算机上已经存在系统为 Vine Linux 2.5 ,内核为 2.4.18. 硬盘总共大小为 100G, 前 4G 为 dos 主分区,安装 windows 系统,使用 OSLoader 启动,后 96G 为 Extend 分区其中分配如下:

    hda1      FAT32    Window 4G,

    hda5      Ext3      /boot      500M

    hda6      FAT32    Window 40G

    hda7      Ext3      /root       40G

    hda8      Ext3      /home    4G

    其余给 linux swap

    ( 3 ).下载

    首先,从下载 RTLinux 3.2 和 2.4.20 的内核

    2.4.20 内核下载地址

    ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.20.tar.bz2

    RTLinux 3.2 的下载地址

    http://www2.fsmlabs.com/3.2-free.html

    填好注册表格后,即可下载

    ( 4 ).复制,解压缩和建立目录

    以 root 身份登录,建立如下目录

    cd /usr/src

    mkdir rtlinux

    将下载的文件复制到此,此时此目录下内容如下:

    ls /usr/src/rtlinux

    linux-2.4.20.tar.bz2        

    rtlinux-3[1].2-pre2.tar.bz2

    现在解开压缩包

    bunzip2 linux-2.4.20.tar.bz2 | tar –xvf –

    bunzip2 rtlinux-3[1].2-pre2.tar.bz2 | tar –xvf –

    此时目录结构如下

    ls /usr/src/rtlinux

    linux-2.4.20.tar.bz2          rtlinux-3[1].2-pre2.tar.bz2

    linux-2.4.20                      rtlinux-3.2-pre2

    现在建立必要的连接 :

    ll /usr/src

    会发现这样的一个连接

    linux à /usr/src/linux-2.4.18

    删除这个连接

    cd /usr/src

    rm linux

    然后建立一个新的符号连接:

    ln –s /usr/src/rtlinux/linux-2.4.20 linux

    至此,已经将新内核连接到 /usr/src/linux 上了。

    ( 5 ).打补丁,配置内核

    下面给内核打 Realtime 的补丁。注意到

    /usr/src/rtlinux/rtlinux/rtlinux-3.2-pre2 下有一个目录名字叫 patches ,里面内容如下:

    kernel_patch-2.4.19-rtl3.2-pre2     README

    kernel_patch-2.4.20-rtl3.2-pre2

    kernel_patch-2.4.21-pre5-rtl3.2-pre2

    选择其中的 2.4.20 的补丁,运行 patch 命令:

    cd /usr/src/linux

    patch -p1 < /usr/src/rtlinux/rtlinux-3.2-pre2/patches/kernel_patch-2.4.20-rtl3.2-pre2

    此时 realtime 的补丁已经打入新内核中

    然后运行编译配置命令,

    cd /usr/src/linux

    如果在 xwindow 下运行

    make xconfig &

    如果没有安装 xwindows ,运行

    make menuconfig

    出现内核配置对话框,一般用缺省配置就可以,但是注意以下一些点 :

    5.1. 如果目前的 linux 分区为 ext3 分区,内核缺省选项可能是不支持,在 FileSystem 中,选择支持 ext3 文件系统。

    5.2. 如果硬盘中存在 dos 分区,并且这些分区在 /etc/fstab 中指定为启动后自动 mount ,则必须配置支持 dos 分区格式 fat16 和 fat32 ,在 FileSystem 中,选择支持 vfat 文件系统。如果需要,选择支持 ntfs 文件系统

    5.3. 如果网卡特殊,注意配置特殊的网卡驱动程序,本计算机使用了 Realtek 8139 网卡。在 Network device support 中选择 Ethernet(10 or 100 Mbit) 然后选中 Realtek RTL-8139 PCI Fast Ethernet Adaptor support 。

    有些选象有 3 个选象 y,m,n 分别对应

    yes :该模块被直接编译进入内核,内核会因此变大

    modular :该模块可以在内核启动时被装载,这样内核不会变大,但是可以得到相应的功能

    no :不安装

    全部配置完成后,选择存盘并且退出。下面可以开始编译内核了

    make dep clean bzImage

    开始编译,需要若干时间,因机器而异,可能长达数小时。如果编译成功,最后显示

    Boot sector 512 bytes

    Setup is xxxxx bytes.

    System is xxxxx KB

    一般会提示,内核过大,无法复制到一张软盘上。忽略这些提示

    如果编译过程出现错误,必须重新配置内核编译选项

    cd /usr/src/linux

    make xconfig & 或者 make menuconfig

    配置需要若干技巧和经验。具体可以参考相关的文章。

    下面将相应的驱动程序模块,安装到指定位置( /lib/modules/2.4.20-rtl3.2-pre2 ),供新内核启动时装载这些模块。

    make modules modules_install

    最后检查一下编译是否完整,利用下面的命令

    depmod –a

    如果没有错误,即可进入下一步,每次重新 make dep clean bzImage 成功后,都要注意运行 make modules modules_install ,否则,重新启动新内核时,可能发生找不到驱动程序的情况


    目标机:redhat9(内核版本为2.4.20-8),GCC编译器为3.2版本(可用GCC -v来查询版本号;)

    注:如果编译器gcc版本是2.96,那么在多处理器电脑上安装RTLinux则需要修改/usr/src/RTLinux/Linux/Makefile中的代码

    CC = $(CROSS_COMPILE)gcc
    改变编译器为kgcc(gcc 2.91),改变后的代码为:
    CC = kgcc

    实际上,使用gcc2.91,2.95和3.x都没有问题。(由于本人GCC版本为3.2版本,直接使用,并未对其他GCC版本做测试)。


    操作系统要求:实时操作系统为RTLinux3.2;内核版本为Kernel-2.4.23

    安装步骤:

    1.安装LINUX操作系统(如REDHAT9)

    2.RTLINUX实时操作系统安装

    1)将内核源码linux-2.4.23.tar.gz与实时操作系统RTLinux.rar复制到/usr/src目录下;并进行解压(由于RTLinux安装时并没有安装rar解压工具,下载rarlinux-3.5.1.tar.gz,并安装)

    2)安装RTLinux实时补丁

    将RTLINUX加压后文件夹下的rtlinux-3.2-rc1下patchs目录下的kernel_patch-2.4.23-rtl3.2-pre3复制到内核解压的linux-2.4.23目录下,并打包

    cp /usr/src/root/rtlinux-3.2-rc1/patchs/kernel_patch-2.4.23-rtl3.2-pre3  /usr/src/linux-2.4.23

    cd /usr/src/linux-2.4.23

    patch -p1 < ./patchs/kernel_patch-2.4.23-rtl3.2-pre3

    3)建立软连接,并配置编译内核

    ln -s  /usr/src/linux-2.4.23  /usr/src/root/rtlinux-3.2-rc1/linux

    cd   /usr/src/root/rtlinux-3.2-rc1/linux

    cp /boot/config-2.3.20-8 .config

    make menuconfig(注:此步骤尤其重要;最后启动失败;多半因为此处配置错误)

    Loadable module support->

                  [*]Enable loadable module support,RTLinux使用模块功能来加载实时任务,此功能必须存在。

    processer type and features--->

    (****)processor family(空格进行选择,此处选择的是Pentium-4(本身CPU为酷睿双核))

    General Setup--->

    [  ]Advanced Power Management BIOS(此处一定不要选择,机器的APM功能一定要关闭,它会抢夺RTLinux对硬件的控制
    F
    ile System--->

    [ * ]Ext3 journalling file system support

    [ * ]JBD(ext3)debugging support

    make dep

    make bzImage

    make modules

    make modules_install

    make install

    4)将重新安装的内核加入启动选项

    cp arch/i386/boot/bzImage /boot/rtzImage

    gedit /boot/grub/menu.lst(在打开的文件末尾加入如下内容)

    title RTLinux,kernel 2.4.23-rtl3.2-pre3

    root(hd0,0)(此处标注的是内核文件放置的分区即/boot分区,可用df -l 来查询,若/boot为/dev/hdc1,则此处)

    Kernel /rtzImage ro root =/dev/hdc3

    initrd  /initrd-2.4.20-rtl3.2-pre3.img

    5)重新启动 reboot

    6)RTLinux的bug修正(注意此处若不修正bug,在之后的rtlinux内核配置编译则会产生关于“xargs不能大于20k”的error而使得编译无法继续)重启电脑,在启动界面下选择RTLinux进入

    在rpmseek.com下载findutils-4.1.7-9.src.rpm,放于/usr/src下安装
    rpm -ivh findutils-4.1.7-9.src.rpm   //在rpm文件包所在文件夹下会生成redhat文件夹,其中有一些资源文件
    cp /usr/src/redhat/SOURCES/findutils-4.1.20.tar.bz2 /usr/local
    cd /usr/local
    tar xjvf findutils-4.1.7.tar.bz2
    cd findutils-4.1.7
    ./configure

    注释掉xargs.c中的如下两行:gedit xargs/xargs.c

    /*
      if (arg_max > 20 * 1024)
        arg_max = 20 * 1024;
    */

    cd ..

    make

    make install

    cp /usr/bin/xargs /usr/bin/xargsold
    cp /usr/local/bin/xargs /usr/bin

    7)RTLinux配置和编译

    cd /usr/src/root/rtlinux-3.2-rc1

    make clean

    make menuconfig

    POSIX Support options--->

    [ * ]POSIX Signals
    [ * ]POSIX Timers

    编译RTLinux之前需要修改浮点路径,去掉/usr/src/rtlinux/examples/fp/Makefile和usr/src/rtlinux/examples/v1api/fp/Makefile中的第一个-lm

    make dep

    make modules

    make devices

    make install

    7)重启 reboot

    8)测试

    make regression

    成功则显示为:Testing multiple loads of rtl.o…      [OK] 
                  Testing ……
                  ……

    否则回到第3步重新配置内核

    9)RTLinux简单操作

    启动rtlinux:rtlinux  start
    查看rtlinux:rtlinux  status
    关闭rtlinux:rtlinux  stop


    展开全文
  • 特别声明:本系列文章LiAnLab.org著作权所有,转载请注明出处。by @宋宝华Barry  Vanilla kernel的问题 Linux kernel在spinlock、irq上下文方面无法抢占,...RT-Preempt Patch是在Linux社区kernel的基础上,加

    特别声明:本系列文章LiAnLab.org著作权所有,转载请注明出处。by  @宋宝华Barry 

    Vanilla kernel的问题

    Linux kernel在spinlock、irq上下文方面无法抢占,因此高优先级任务被唤醒到得以执行的时间并不能完全确定。同时,Linux kernel本身也不处理优先级反转。RT-Preempt Patch是在Linux社区kernel的基础上,加上相关的补丁,以使得Linux满足硬实时的需求。本文描述了该patch在PC上的实践。我们的测试环境为Ubuntu 10.10,默认情况下使用Ubuntu 10.10自带的kernel:

    barry@barry-VirtualBox:/lib/modules$ uname -a
    2.6.35-32-generic #67-Ubuntu SMP Mon Mar 5 19:35:26 UTC 2012 i686 GNU/Linux
    
    在Ubuntu 10.10,apt-get install rt-tests安装rt测试工具集,运行其中的cyclictest测试工具,默认创建5个SCHED_FIFO策略的realtime线程,优先级76-80,运行周期是1000,1500,2000,2500,3000微秒:

    barry@barry-VirtualBox:~/development/panda/android$ sudo cyclictest -p 80 -t5 -n 
    [sudo] password for barry: 
    policy: fifo: loadavg: 9.22 8.57 6.75 11/374 21385          
    
    T: 0 (20606) P:80 I:1000 C:  18973 Min:     26 Act:   76 Avg:  428 Max:   12637
    T: 1 (20607) P:79 I:1500 C:  12648 Min:     31 Act:   68 Avg:  447 Max:   10320
    T: 2 (20608) P:78 I:2000 C:   9494 Min:     28 Act:  151 Avg:  383 Max:    9481
    T: 3 (20609) P:77 I:2500 C:   7589 Min:     29 Act:  889 Avg:  393 Max:   12670
    T: 4 (20610) P:76 I:3000 C:   6325 Min:     37 Act:  167 Avg:  553 Max:   13673
    

    由此可见在标准Linux内,rt线程投入运行的jitter非常不稳定,最小值在26-37微秒,平均值为68-889微秒,而最大值则分布在9481-13673微秒之间。

    我们还是运行这个测试,但是在运行这个测试的过程中引入更多干扰,如mount /dev/sdb1 ~/development,则结果变为:

    barry@barry-VirtualBox:~$ sudo cyclictest -p 80 -t5 -n 
    policy: fifo: loadavg: 0.14 0.29 0.13 2/308 1908          
    
    T: 0 ( 1874) P:80 I:1000 C:  28521 Min:      0 Act:  440 Avg: 2095 Max:  331482
    T: 1 ( 1875) P:79 I:1500 C:  19014 Min:      2 Act:  988 Avg: 2099 Max:  330503
    T: 2 ( 1876) P:78 I:2000 C:  14261 Min:      7 Act:  534 Avg: 2096 Max:  329989
    T: 3 ( 1877) P:77 I:2500 C:  11409 Min:      4 Act:  554 Avg: 2073 Max:  328490
    T: 4 ( 1878) P:76 I:3000 C:   9507 Min:     12 Act:  100 Avg: 2081 Max:  328991

    mount过程中引入的irq、softirq和spinlock导致最大jitter明显地加大甚至达到了331482us,充分显示出了标准Linux内核中RT线程投入运行时间的不可预期性(硬实时要求意味着可预期)。

    如果我们编译一份kernel,选择的是“Voluntary Kernel Preemption (Desktop)“,这类似于2.4不支持kernel抢占的情况,我们运行同样的case,时间的不确定性大地几乎让我们无法接受:

    barry@barry-VirtualBox:~$ sudo /usr/local/bin/cyclictest -p 80 -t5 -n
    # /dev/cpu_dma_latency set to 0us
    policy: fifo: loadavg: 0.23 0.30 0.15 3/247 5086           
    
    T: 0 ( 5082) P:80 I:1000 C:   5637 Min:     60 Act:15108679 Avg:11195196 Max:15108679
    T: 1 ( 5083) P:80 I:1500 C:   5723 Min:     48 Act:12364955 Avg:6389691 Max:12364955
    T: 2 ( 5084) P:80 I:2000 C:   4821 Min:     32 Act:11119979 Avg:8061814 Max:11661123
    T: 3 ( 5085) P:80 I:2500 C:   3909 Min:     27 Act:11176854 Avg:4563549 Max:11176854
    T: 4 ( 5086) P:80 I:3000 C:   3598 Min:     37 Act:9951432 Avg:8761137 Max:116026155

    RT-Preempt Patch使能

    RT-Preempt Patch对Linux kernel的主要改造包括:

    • Making in-kernel locking-primitives (using spinlocks) preemptible though reimplementation with rtmutexes:
    • Critical sections protected by i.e. spinlock_t and rwlock_t are now preemptible. The creation of non-preemptible sections (in kernel) is still possible with raw_spinlock_t (same APIs like spinlock_t)
    • Implementing priority inheritance for in-kernel spinlocks and semaphores. For more information on priority inversion and priority inheritance please consultIntroduction to Priority Inversion
    • Converting interrupt handlers into preemptible kernel threads: The RT-Preempt patch treats soft interrupt handlers in kernel thread context, which is represented by a task_struct like a common userspace process. However it is also possible to register an IRQ in kernel context.
    • Converting the old Linux timer API into separate infrastructures for high resolution kernel timers plus one for timeouts, leading to userspace POSIX timers with high resolution.

    在本试验中,我们取的带RT-Preempt Patch的kernel tree是git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable- rt.git,使用其v3.4-rt-rebase branch,编译kernel时选中了"Fully Preemptible Kernel"抢占模型:

    ───────────────────────── Preemption Model ─────────────────────────┐

    │ │          ( ) No Forced Preemption (Server)                 
    │ │          ( ) Voluntary Kernel Preemption (Desktop)       
    │ │          ( ) Preemptible Kernel (Low-Latency Desktop)    
    │ │          ( ) Preemptible Kernel (Basic RT)                
    │ │          (X) Fully Preemptible Kernel (RT)      

    另外,kernel中需支持tickless和高精度timer:

    ┌───────────────────Processor type and features ─────────────────────────┐
    │ │                                      [*] Tickless System (Dynamic Ticks)                                                               
    │ │                                      [*] High Resolution Timer Support       
     

    make modules_install、make install、mkintramfs后,我们得到一个可以在Ubuntu中启动的RT kernel。具体编译方法可详见http://www.linuxidc.com/Linux/2012-01/50749.htm,根据该文修改版本号等信息即可,我们运行的命令包括:

    安装模块

    barry@barry-VirtualBox:~/development/linux-2.6$ sudo make modules_install
    ....
      INSTALL /lib/firmware/whiteheat_loader.fw
      INSTALL /lib/firmware/whiteheat.fw
      INSTALL /lib/firmware/keyspan_pda/keyspan_pda.fw
      INSTALL /lib/firmware/keyspan_pda/xircom_pgs.fw
      INSTALL /lib/firmware/cpia2/stv0672_vp4.bin
      INSTALL /lib/firmware/yam/1200.bin
      INSTALL /lib/firmware/yam/9600.bin
      DEPMOD  3.4.11-rt19
    

    安装kernel

    barry@barry-VirtualBox:~/development/linux-2.6$ sudo make install 
    sh /home/barry/development/linux-2.6/arch/x86/boot/install.sh 3.4.11-rt19 arch/x86/boot/bzImage \ 
    System.map "/boot" 

    制作initrd

    barry@barry-VirtualBox:~/development/linux-2.6$ sudo mkinitramfs 3.4.11-rt19 -o /boot/initrd.img-3.4.11-rt19

    修改grub配置

    在grub.conf中增加新的启动entry,仿照现有的menuentry,增加一个新的,把其中的相关版本号都变更为3.4.11-rt19,我们的修改如下:

     menuentry 'Ubuntu, with Linux 3.4.11-rt19' --class ubuntu --class gnu-linux --class gnu --class os {
        recordfail
        insmod part_msdos
        insmod ext2
        set root='(hd0,msdos1)'
        search --no-floppy --fs-uuid --set a0db5cf0-6ce3-404f-9808-88ce18f0177a
        linux    /boot/vmlinuz-3.4.11-rt19 root=UUID=a0db5cf0-6ce3-404f-9808-88ce18f0177a ro   quiet splash
        initrd    /boot/initrd.img-3.4.11-rt19
    }
    开机时选择3.4.11-rt19启动:

    RT-Preempt Patch试用

    运行同样的测试cyclictest benchmark工具,结果迥异:

    barry@barry-VirtualBox:~$ sudo cyclictest -p 80 -t5 -n
    WARNING: Most functions require kernel 2.6
    policy: fifo: loadavg: 0.71 0.42 0.17 1/289 1926          
    
    T: 0 ( 1921) P:80 I:1000 C:   7294 Min:      7 Act:   89 Avg:  197 Max:    3177
    T: 1 ( 1922) P:79 I:1500 C:   4863 Min:     10 Act:   85 Avg:  186 Max:    2681
    T: 2 ( 1923) P:78 I:2000 C:   3647 Min:     15 Act:   93 Avg:  160 Max:    2504
    T: 3 ( 1924) P:77 I:2500 C:   2918 Min:     23 Act:   67 Avg:  171 Max:    2114
    T: 4 ( 1925) P:76 I:3000 C:   2432 Min:     19 Act:  134 Avg:  339 Max:    3129

    我们还是运行这个测试,但是在运行这个测试的过程中引入更多干扰,如mount /dev/sdb1 ~/development,则结果变为:

    barry@barry-VirtualBox:~$ sudo cyclictest -p 80 -t5 -n
    # /dev/cpu_dma_latency set to 0us
    policy: fifo: loadavg: 0.11 0.12 0.13 1/263 2860          
    
    T: 0 ( 2843) P:80 I:1000 C:  28135 Min:      5 Act:  198 Avg:  200 Max:    7387
    T: 1 ( 2844) P:80 I:1500 C:  18756 Min:     22 Act:  169 Avg:  188 Max:    6875
    T: 2 ( 2845) P:80 I:2000 C:  14067 Min:      7 Act:   91 Avg:  149 Max:    7288
    T: 3 ( 2846) P:80 I:2500 C:  11254 Min:     19 Act:  131 Avg:  155 Max:    6287
    T: 4 ( 2847) P:80 I:3000 C:   9378 Min:     25 Act:   58 Avg:  172 Max:    6121
    时间在可预期的范围内,没有出现标准kernel里面jitter达到331482的情况。需要说明的是,这个jitter大到超过了我们的预期,达到了10ms量级,相信是受到了我们的测试都是在Virtualbox虚拟机进行的影响。按照其他文档显示,这个jitter应该在数十us左右。

    我们在这个kernel里面运行ps aux命令,可以看出线程化了的irq:

    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         1  0.8  0.1   2880  1788 ?        Ss   18:39   0:03 init
    root         2  0.0  0.0      0     0 ?        S    18:39   0:00 kthreadd
    ...
    
    root        45  0.0  0.0      0     0 ?        S    18:39   0:00 irq/14-ata_piix
    root        46  0.0  0.0      0     0 ?        S    18:39   0:00 irq/15-ata_piix
    root        50  0.0  0.0      0     0 ?        S    18:39   0:00 irq/19-ehci_hcd
    root        51  0.0  0.0      0     0 ?        S    18:39   0:00 irq/22-ohci_hcd
    root        55  0.0  0.0      0     0 ?        S    18:39   0:00 irq/12-i8042
    root        56  0.0  0.0      0     0 ?        S    18:39   0:00 irq/1-i8042
    root        57  0.0  0.0      0     0 ?        S    18:39   0:00 irq/8-rtc0
    root       863  0.0  0.0      0     0 ?        S    18:39   0:00 irq/19-eth0
    root       864  0.0  0.0      0     0 ?        S    18:39   0:00 irq/16-eth1
    root      1002  0.5  0.0      0     0 ?        S    18:39   0:01 irq/21-snd_inte
    ...

    在其中编写一个RT 线程的应用程序,通常需要如下步骤:

    • Setting a real time scheduling policy and priority.
    • Locking memory so that page faults caused by virtual memory will not undermine deterministic behavior
    • Pre-faulting the stack, so that a future stack fault will not undermine deterministic behavior
    例子test_rt.c,其中的mlockall是为了防止进程的虚拟地址空间对应的物理页面被swap出去,而stack_prefault()则故意提前导致stack往下增长8KB,因此其后的函数调用和局部变量的使用将不再导致栈增长(依赖于page fault和内存申请):

    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <sched.h>
    #include <sys/mman.h>
    #include <string.h>
    
    #define MY_PRIORITY (49) /* we use 49 as the PRREMPT_RT use 50
                                as the priority of kernel tasklets
                                and interrupt handler by default */
    
    #define MAX_SAFE_STACK (8*1024) /* The maximum stack size which is
                                       guaranteed safe to access without
                                       faulting */
    
    #define NSEC_PER_SEC    (1000000000) /* The number of nsecs per sec. */
    
    void stack_prefault(void) {
    
            unsigned char dummy[MAX_SAFE_STACK];
    
            memset(dummy, 0, MAX_SAFE_STACK);
            return;
    }
    
    int main(int argc, char* argv[])
    {
            struct timespec t;
            struct sched_param param;
            int interval = 50000; /* 50us*/
    
            /* Declare ourself as a real time task */
    
            param.sched_priority = MY_PRIORITY;
            if(sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
                    perror("sched_setscheduler failed");
                    exit(-1);
            }
    
            /* Lock memory */
    
            if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
                    perror("mlockall failed");
                    exit(-2);
            }
    
            /* Pre-fault our stack */
    
            stack_prefault();
    
            clock_gettime(CLOCK_MONOTONIC ,&t);
            /* start after one second */
            t.tv_sec++;
    
            while(1) {
                    /* wait until next shot */
                    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
    
                    /* do the stuff */
    
                    /* calculate next shot */
                    t.tv_nsec += interval;
    
                    while (t.tv_nsec >= NSEC_PER_SEC) {
                           t.tv_nsec -= NSEC_PER_SEC;
                            t.tv_sec++;
                    }
       }
    }
    编译之:gcc -o test_rt test_rt.c -lrt。本节就到这里,后续我们会有一系列博文来描述RT-Preempt Patch对kernel的主要改动,以及其工作原理。

    展开全文
  • RT-Preempt Patch是在Linux社区kernel的基础上,加上相关的补丁,以使得Linux满足硬实时的需求。 一、向内核打RT-Linux补丁 1、下载内核补丁包 下载与自己内核相应的补丁包,以下是下载网址:...

    RT-Preempt Patch是在Linux社区kernel的基础上,加上相关的补丁,以使得Linux满足硬实时的需求。

    一、向内核打RT-Linux补丁

    1、下载内核补丁包

    下载与自己内核相应的补丁包,以下是下载网址:https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/

    这里有各种内核版本的补丁包。

    我用的内核版本是4.6.0的,因此找到4.6的目录下找对应的版本

    哎?这里还没有,older里面看看,果然这才是4.6最全的。选择一个下载。

    2、打补丁

    将补丁包解压到源码目录下

    打开终端,输入以下命令打入补丁:

    xzcat ../patch-4.6-rt19.patch.xz | patch -p1

    或者

    patch -p(n) < [补丁包路径]patch_name

    n=0时,从当前目录查找文件(夹)(直接使用补丁文件里指定的路径)

    n=1时,忽略掉第一层目录,从当前目录查找(去掉补丁文件指定路径最左的第一个斜杠及前面的所有内容)

    校验

    编译内核后,上电启动系统,uname -a命令查看 有 RT 字样内核替换成功

    打出补丁

    patch -p1 -R < ../patch_name

    二、编译RT-test进行Linux实时性测试(cortex9,arm7)

    1、下载

    git clone git:// git.kernel.org / pub / scm / utils / rt-tests / rt-tests.git
    
    cd rt-tests
    
    git checkout stable / v1.0

    2、安装库

    直接make会报错

    报错: src/cyclictest/rt_numa.h:29:18: fatal error: numa.h: 没有那个文件或目录

    解决:

    1)安装apt-file 来找到依赖库

    apt-get install apt-file

    apt-file update #更新源

    2)寻找 numa.h

    apt-file install numa.h

    3) 安装相应的库

    apt-get install libnuma-dev

    3、编译arm平台的cyclictest

    直接make的话编译出的二进制文件是x86_64的,在zynq7平台将无法执行。在网上也看别人博客说修改makefile文件中的编译器选项,我修改之后编译的仍然是x86_64的。无奈之下,只得将cyclictest源文件拿出来单独编译。

    4、在yocto下用poky_sdk,autotool编译

    4.1 新建文件夹cyclictest

    4.2 在上面下载的rt-tests中找到以下文件,复制到cyclictest文件夹下。

    4.3 创建空的README文件,这是GNU编码标准所要求的:

    touch README

    4.4 使用autoscan生成一个configure.scan辅助编写configure.ac

    4.5 创建configure.ac文件

    AC_INIT(cyclictest, 2.69)
    AM_INIT_AUTOMAKE
    AC_CONFIG_HEADERS(config.h)
    
    AM_PROG_CC_C_O
    AC_PROG_INSTALL
    
    
    AC_OUTPUT([Makefile])

    2.69 就是从4.4步骤得来的。

    4.6 创建Makefile.am文件

    bin_PROGRAMS = cyclictest
    cyclictest_SOURCES = cyclictest.c error.c rt-utils.c rt-sched.c

    4.7 修改cyclictest.c,rt-utils.c文件

    在头文件声明前增加       #define _GNU_SOURCE   #define __USE_GNU

    因为要使用GNU的编译器,但是在编译的时候却发现一直报错,找不到features.h里面的定义,因此需手动在头文件声明之前加上以上内容。

    5、获取跨工具链环境设置文件

    source /home/jf-yt/poky_sdk/environment-setup-cortexa9hf-neon-poky-linux-gnueabi

    6、创建configure脚本: 使用该autoreconf命令生成configure脚本。

    autoreconf

    autoreconf工具将正在运行的其他自动工具,如护理 aclocal, autoconf和 automake

    注意:

    如果出现错误的 configure.ac,它 autoreconf运行时,指示丢失的文件,使用“-i”选项,从而确保丢失的辅助文件复制到构建主机。

    7、交叉编译项目:此命令使用交叉编译器编译项目。该 CONFIGURE_FLAGS 环境变量为GNU配置的最小参数:

    $ ./configure $ {CONFIGURE_FLAGS}

    8、修改Makefile文件

    在CC = ....加入 -lpthread -lrt,分别链接线程库和rt库。

    9、编译

    make

    10、验证二进制文件,运行该命令将打印可以运行二进制文件的体系结构。此体系结构应与已安装的跨工具链支持的体系结构相同。

     $ file ./cyclictest

    输出如下

    ./cyclictest: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=c5d2416a3e22086474128ba1377e142b542a5353, not stripped

    果然是ARM架构的,基本可以用了。

    展开全文
  • rtlinux 的配置和测试

    2019-03-29 15:25:36
    rtlinux顾名思义,就是realtime linux操作系统。行业内比较有名的实时操作系统有:VxWorks,uC/OS-II,QNX等。我们可以先了解一下实时操作系统的定义。 实时操作系统: 实时操作系统(RTOS)是指当外界事件或数据...

           rtlinux顾名思义,就是realtime linux操作系统。行业内比较有名的实时操作系统有:VxWorks,uC/OS-II,QNX等。我们可以先了解一下实时操作系统的定义。

    实时操作系统:

    实时操作系统(RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系 统作出快速响应,并控制所有实时任务协调一致运行的操作系统。因而,提供及时响应和高可靠性是其主要特点。实时操作系统有硬实时和软实时之分,硬实时要求 在规定的时间内必须完成操作,这是在操作系统设计时保证的;软实时则只要按照任务的优先级,尽可能快地完成操作即可。我们通常使用的操作系统在经过一定改 变之后就可以变成实时操作系统。

          其实linux系统是非实时操作系统,在很多高精度的场合上linux的实时性就尤为重要了,比如在车载linux系统上需要在毫秒级或者更短的时间获取串口的数据。不过可以通过修改,使linux系统变成Rtlinux,linux社区有针对于此修改的patch。

    配置

    RTlinux 的patch  https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/ 然后下载版本一致的patch。

    比如我这里的linux系统是4.14.34

    下载后解压 并打上patch  : patch -p1 < ../patch-4.14.34-rt27.patch

    然后再make menuconfig

    选中Fully Preemptible Kernel(RT)

    编译,即可使用了。

    测试

    使用cyclictest 程序来进行实时性的测试

    使用的cmd:apt-get source rt-tests(ps:apt-get source可以获取源码,若是install既可以直接安装)

    获取源码当然也可以通过github上去获取,总之能够获取使用就行了。

    tar xzvf rt-tests_0.87.orig.tar.gz

    cd rt-tests-0.87/

    然后vim Makefile (修改安装的目录和指定交叉编译工具链)默认是安装到本地的linux系统上的

    make

    会生成 cyclictest 可执行的镜像程序,把它放在开发板。

    测试如下:cmd:    ./cyclictest -p 80 -t5 -n(运行5个线程,线程优先级为80,无线循环)

    运行其中的cyclictest测试工具,默认创建5个SCHED_FIFO策略的realtime线程

    不加rtlinux的patch

     

    加了rtlinux的patch

    以上数字的单位都是微秒,可见加了实时rtlinux  patch的实时性确实提高了

    关于cyclictest 可参考以下网页(友情链接):

    https://blog.csdn.net/kl1125290220/article/details/78560220

    https://blog.csdn.net/longerzone/article/details/16897655

     

    展开全文
  • RTLinux编程总结

    2016-05-11 16:38:17
    主要是RTLinux环境下编程总结,在嵌入版发过,没几个人响应。 做过一个有关RTLinux的项目,时间一长,差不多忘光了,现在尽量把原来做过的东西总结一下,以备后用,同时正在做类似项目的一个借鉴 平台 主机:...
  • 关于RTLinux的安装

    2012-04-04 15:59:36
    RTLinux选用了rtlinux-rtl3.2-pre3安装方法为 一、虚拟机工具条的安装:首先在虚拟机上安装Redhat9并确保安装好vmware工具条,在安装工具条的过程中,若出现what is the location of the gcc?则先选择no,后运行 /...
  • 树莓派Linux内核代码打上RT-Patch并在Ubuntu16.04环境下完成交叉编译。
  • Linux4.1.15 + patch-4.1.15-rt18.patch 补丁,实测实时性差 开发环境 发行环境 该环境用于发行 Linux: 4.1.15 preempt_rt: patch-4.1.15-rt18.patch SOC: i.MX6Q board: 飞凌OK_MX6X_C_V1.3 运行程序: main (最终...
  • RTlinux ubuntu 移植

    2018-11-20 11:03:07
    Vanilla kernel的问题 Linux kernel在spinlock、irq上下文方面无法抢占,因此高优先级任务被唤醒到得以执行的时间并不能完全确定。同时,Linux kernel本身也不处理...RT-Preempt Patch是在Linux社区kernel的基础...
  • 配置RTLinux系统

    2009-08-26 14:41:00
    作者:王姗姗,华清远见嵌入式学院讲师。一、下载释放核心源代码 从Internet站点上下载了内核文件(2.4.28内核)及补丁(RT-Linux 3.2-rc1)... 1、用tar命令释放内核源代码 # cd /usr/src # rm -rf rtlinux #mv rtli
  • 简介RT-Preempt Patch是在Linux社区kernel的基础上,加上相关的补丁,以使得Linux满足硬实时的需求。下面是编译RT linux内核的流程,以内核3.18.59为例。 流程下载代码rt补丁下载 ...
  • http://21cnbao.blog.51cto.com/109393/1011931
  • //在Redhat9上安装RTLinux3.2 >>>> dslab 杨红刚 <br /> //更多文章见:http://dslab.lzu.edu.cn/<br />  使用的文件: rtlinux-3.2-wr.tar.bz2:从风河公司网站免费注册后下载 ...
  • 注:如果编译器gcc版本是2.96,那么在多处理器电脑上安装RTLinux则需要修改/usr/src/RTLinux/Linux/Makefile中的代码 CC = $(CROSS_COMPILE)gcc 改变编译器为kgcc(gcc 2.91),改变后的代码为: CC = k
  • 提供了目前最新的赛灵思zynq的arm-linux内核,可...内核版本为4.14,并提供了相对应的rt-preempt补丁,通过patch命令可让标志的linux软实时变为硬实时,通过实践代码能顺利编译,并完美生成uImage和devicetree.dts。
1 2 3 4 5
收藏数 100
精华内容 40
热门标签