查看: 6381|回复: 0

BeagleBone Black——PRU的使用

[复制链接]
  • TA的每日心情
    开心
    2014-7-12 10:10
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2015-9-15 20:49:20 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 yu1019594136_3004577 于 2015-9-27 22:36 编辑

    一、为什么需要PRU?
           相信大家喜欢操作系统,或者说喜欢使用linux的一个原因肯定包括:系统内包含丰富的设备驱动程序;还有很多好用的方便的软件包;以及系统支持很多编程语言以及脚本语言,C,C++,shell,Python等等;还有以及一些丰富的库,比如Qt,OpenCV......上述的众多优点使得我们在面对一个多任务操作的,需要外接多个设备却又想避开协议源码的,想要让人机交互体验更棒的任务时,我们会毫不犹豫的选择操作系统。
           通常,能够在限定时间内完成给定任务或者能够及时响应外部中断任务的系统我们称为实时操作系统。这类系统不允许任何一个critical mission被错过,一旦错过将会产生不同严重程度的后果,
           遗憾的是在BBB上使用的linux系统就不是实时操作系统,那么这会有什么影响或者限制呢?
           大家通常在/sys目录下操作一些设备文件,比如我们的GPIO口,对这些设备文件write一个1,对应的GPIO口将会变成高电平,write一个0,对应的GPIO口将会变成低电平,那么假如我们写一个C程序或者一个脚本文件,不断地对一个IO口进行翻转,中间不加任何延时,也没有其他代码,这个速度会有多快呢?产生的方波频率有多高呢?我的测试结果是这个频率大概在2-3KHz之间,,应该比STM32能产生的最高方波频率要低很多吧,,,
            其中大部分原因在于linux系统或者说linux内核不是一个实时系统,内核中对于进程的调度不分优先级,原本应该及时的翻转IO口,然而内核却让执行其他任务的进程时间片先执行完,才会回到我们的IO翻转任务,因此还可以发现我们的波形可能极为不稳定,并且最高也就几KHz.
            第二个例子是我在项目开发中遇到的问题,其中有一个数据采集的任务,模拟信号由一片外接的AD芯片转换为数字信号,数字信号通过芯片的SPI接口传到BBB上,这就产生了AD芯片和BBB之间的SPI通信,然而linux系统下SPI通信不像我们写逻辑程序那样,在系统环境下一次SPI通信从我们的应用程序,再到linux内核中产生SPI请求,而这些请求又被中断控制器按队列管理,在这儿也就是说我们的SPI通信再次被“搁置”,最后的效果就是数据采集的频率连100Hz(测试情况说明:当时整个程序也不小,多线程的。)都满足不了,并且通信过程中伴随着大量的数据丢失。而这块AD芯片的采样速率其实可以达到几十KHz的,但是由于受通信速度的限制,采样速率的优势完全没有发挥出来,当然这个速度也没有满足项目需求!
            对于上述问题,大家也许可以想到各种各样的解决方案:1、或许可以移植其他的嵌入式实时系统到BBB上,比如QNX Neutrino;2、或者咱们不玩系统了,用StarterWare玩裸机吧;3、或者给linux增加一个Cobalt核;4、或者在BBB之外再外接一个STM32,AVR,再不行就51,让他们来完成实时任务,最后由BBB完成“高级”任务。对此我只想说,如果大家不嫌移植系统麻烦,不嫌手里钱多,不嫌外接单片机浪费时间精力,可以!
            在解决问题的时候,我想没人会拒绝省时省力的方案吧,此刻PRU闪亮登场!!!

    二、什么是PRU?
            PRU = The Programmable Real‐Time Unit,在BBB的AM335X处理器中包含了2个32位的PRU,每一个PRU的运行频率是200MHz(即每一条汇编指令执行时间是5ns),这个速度堪比DSP了吧,另外每个PRU有8KB的instrction RAM和
    8KB的Data RAM,以及两个PRU之间有一块共享的12KB内存,每个PRU可以控制P8/P9上的部分IO口,可以触发一些中断,另外,BBB板子上面的512MB内存芯片是被PRU和CPU(或者称为host device)共享的,这给数据的传递带来大大的便利!总结为一句:PRU相当于一块内置于CPU中的200MHz的单片机。大致的框图如下:
    PRU_ICSS_block_diag.png


           为了让本帖读者更生动详细的了解PRU是个神马东东,下面粗略描述一下PRU和CPU(下文用host device代替CPU如何协同工作。
    QQ截图20150915223558.png


            由上图可知,1、在使用PRU之前,同样我们先要处理好资源外设的问题,必须先使能相应的引脚等;
               2、host device和PRU之间相当于是协作关系,前者运行C程序,也就是我们想在linux系统中干的事,而我们想让PRU干的事则写在PRU的汇编源码中,可谓泾渭分明;
               3、要运行一个C程序很简单,我们编写C源码,然后用C编译器编译后得到可执行文件,然后一条命令./xxx即可让我们的C程序在linux系统中跑起来。而要让PRU运行我们的PRU代码则稍微麻烦一点,同样先编写好PRU源码(我用的是汇编代码,其实也可以写PRU的C源码再用CCS编译即可),再用一个pasm汇编器将其编译成可以被PRU执行的可执行程序,这个可执行文件再由我们前面的C代码下载到PRU的RAM中运行即可。
              举个例子,我们先写一个PRU程序,这个程序用于不断的翻转IO口,编译后将其可执行文件存放于某个目录,然后再写一个C程序,这个程序仅仅做一件事,将那个目录下的PRU可执行文件下载到PRU的instruction RAM中。然后我们./xx运行刚刚写的C程序,那么接下来PRU可执行文件被下载到PRU的RAM中并开始运行,此时即使你强行退出这个C程序,你会发现IO口仍然在翻转,因此host device和PRU之间不仅仅是代码中泾渭分明的关系,同时两种代码在运行时还是井水不犯河水的关系!
             4、host device和PRU之间当然也需要通信的啦。这个两者可以通过共享的内存块来完成,或者是发送和接受中断来实现。
           关于PRU的参考资料:
           1、首推TI的官方资料WIKI,其中包含有关的硬件信息,软件信息,以及一些开发工具和示例。
             http://processors.wiki.ti.com/index.php/PRU-ICSS
             2、elinux.org提供的一些资料。
             http://elinux.org/Ti_AM33XX_PRUSSv2
             3、自行百度以下文档
             The PRU Debugger User Guide
             The PRU Linux Application Loader API Guide

    三、如何使用PRU?
           在阅读下文时,请确保你已经阅读第二部分的参考资料文档。
           最简单最容易入手的莫过于点亮一个LED灯了,因此,下文将展示如何使用PRU来控制一个LED灯。

          

    最近找工作真的很忙,后续一定会更新.........





    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-16 17:49 , Processed in 0.117057 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.