DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2209|回复: 0
打印 上一主题 下一主题

[待整理] TI:PRU处理器开发详解

[复制链接]
跳转到指定楼层
楼主
发表于 2015-4-27 23:47:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
摘要
          TI OMAPL13x, C674x, AM180x,OMAP-L137,C6747,AM170x等芯片上(本文统一以OMAP-L138代称)有一个PRUSS(Programmable Real time Unit Subsystem),可独立编程实现一些实时性要求高的个性化需求,实现产品的差异化。本文介绍PRU处理器架构,开发,调试方法。
         
        PRUSS简介
          在系统架构上,PRUSS是连接在OMAPL138内部总线SCR上的一个模块,与系统中其它主模块如ARM,DSP一样,可以访问芯片上的其它外设,工作在PLL0_SYSCLK2时钟域,即ARM/DSP 频率的一半。
         

       
       
        图1 PRUSS框图

         

          PRUSS包括两个PRU,通过自己的SCR与子系统的中断控制器、指令内存、数据内存、以及系统SCR相连。PRU不是一个加速器,它是32-bit Load/Store RISC架构小端处理器,每个PRU有32个通用寄存器R0~R31,4K byte指令RAM,512 byte数据RAM,指令RAM是独立的,互相之间不能访问,但数据RAM可以通过映射地址互相访问;专用的30个输入引脚和32个输出引脚(注:OMAPL137系列没有PRU外部引脚)。PRU没有Cache、指令流水线、及乘法指令。
         
        1 PRU内存映射
          1.1 指令空间
          每个PRU独立的指令空间为0x00000000~0x00000FFF。指令空间由外部主处理ARM/DSP初始化,程序指针PC是32bit字地址,不是字节地址,如PC=2,代表指令地址0x08。
           
       
        表1 PRU指令空间映射表

         
        1.2 数据空间
          每个PRU独立的512byte数据RAM空间为0x0000~0x01FF,因为数据RAM连接在PRU子系统的SCR上,所以子系统中的其它主模块也可以访问到这块空间,这段内存空间在另一个PRU 上的映射地址为0x2000~0x21FF。
         
        位于数据空间的还有共用的中断控制器寄存器;PRU控制/状态寄存器,有各自的地址空间。
         

       
       
        表2 PRUSS本地数据空间内存映射表

         

          1.3 全局地址空间映射
          PRU局部地址空间在系统全局地址空间映射端口为0x01C30000,如表3所示,PRU可以通过表2的局部地址,也可以通过表3的全局地址访问PRUSS的数据空间,通过全局地址空间访问要经过系统SCR2,比通过局部地址空间访问要慢。PRUSS外部主模块如ARM,DSP等可通过全局地址空间访问PRU资源。
       
         
       

        表3 PRUSS全局空间内存映射表

         

          2控制/状态寄存器
          PRU0的控制/状态寄存器地址位于0x00007000~0x000077FF,PRU1的控制/状态寄存器地址位于0x00007800~0x00007FFF,寄存器列表如表4所示,各寄存器的详细说明请参阅[1] 。
           
       
        表4 PRU控制/状态寄存器表

         

          2.1 CONTROL控制寄存器
          外部主模块ARM/DSP通过控制寄存器可以控制PRU的运行状态。
       
       
        表5 PRU控制寄存器说明表

         

          2.2 STATUS状态寄存器
          状态寄存即PRU 的程序指针寄存器,与程序的真正运行状态有一个周期的延时。
         
        2.3 WAKEUP唤醒使能寄存器
          在程序执行SLP指令进入睡眠状态之前,使能WAKEUP寄存器相应的位,当输入状态寄存器R31相应的位置1时,即WAKEUP&R31!=0时,唤醒PRU。
         
        2.4 CYCLECNT周期计数器
          当CONTROL[ENABLE]=1和CONTROL[COUNTENABLE]=1时,CYCLECNT以PRU时钟周期计数。当CONTROL[ENABLE]=0或CONTROL[COUNTENABLE]=0时,计数停止。当重新使能时,恢复继续计数。
         
        2.5 STALLCNT取指停止计数器
          当CONTROL[ENABLE]=1和CONTROL[COUNTENABLE]=1,且由于某种原因PRU不能取指令时,STALLCNT开始以PRU时钟周期计数。其值总是小于,或等于CYCLECNT的值。
         
        2.6 常量表
          PRU提供32个常量地址表C0~C31,INTCTER0-INTCTER31是常量表的调试接口,当PRU停止时,外部主模块读取INTCTERn即得到常量表Cn的值。通过指令LBCO或SBCO从常量表指向的地址与寄存器之间以簇发方式传递数据。指令格式举例如下:
         
        LBCO   R2, C2, 5, 8 //从C2+5 的地址读取8 字节到R2, R3。
         
        SBCO   R2, C2, 5, 8 //将R2, R3 的数据写到C2+5 开始的地址。
           
       
       
        表6 PRU常量表

         

          在性能上与指令LBBO和SBBO没有区别,利用常量表可以节省通用寄存器的使用。
        0~23号常量表提供的入口地址是固定的,24~31号常量表的域可通过寄存器编程设置:

           
  •                 C24[11:8]通过CONTABBLKIDX0[3:0]设置;          
  •                 C25[11:8]通过CONTABBLKIDX0[19:16]设置;        
  •                 C28[23:8]通过CONTABPROPTR0[15:0]设置;        
  •                 C29[23:8]通过CONTABPROPTR0[31:16]设置;        
  •                 C30[23:8]通过CONTABPROPTR1[15:0]设置;        
  •                 C31[23:8]通过CONTABPROPTR1[31:16]设置。
           
         
          2.7 INTGPR0~31调试通用寄存器
          INTGPR0~31与通用寄存器R0~R31对应,为外部主模块提供一个调试窗口。当PRU停止时,ARM/DSP读/写INTGPR0~31直接读/写寄存器R0~R31。
         
        3 PRU模块接口
          3.1 PRU事件/状态寄存器R31
          R31是一个特殊的寄存器,读与写操作时的功能是不一样的。
         
        写R31寄存器时,写事件号0~31到R31_PRU_VEC[4:0],同时设置R31_PRU_VEC_VALID,将产生中断输出事件到中断控制器的32~63号系统事件。两个PRU输出的中断事件相“或”输出到同一个中断号。
           
       

        表7 写R31寄存器

           
          读R31寄存器时,R31[29:0]反映PRU的输入管脚PRU_R30[29:0]的状态。R31[31:30]是映射到中断控制器的INTR_IN[0]和INTR_IN[1]的状态。
       
       
        表8 读R31寄存器

         

          3.2 通用输出寄存器R30
          每个PRU有32个独立的输出管脚PRU0_R31[31:0]和PRU1_R31[31:0],写到寄存器R30[31:0]的值直接输出到PRUn_R31[31:0]管脚。
         
        4 PRU中断控制器
          PRU中断控制器支持64个系统事件,10个中断通道,10个主机中断。
           
       
        图2 PRU中断控制器框图

           
          系统事件0~31为32个外部事件如表9所示,可以通过系统配置寄存器CFGCHIP3的第3位PRUEVTSEL在两组事件中进行选择,PRUSSEVTSEL=0时选择第一列的32个外部系统事件,PRUSSEVTSEL=1时选择第二列的32个外部系统事件;系统事件32~63由写R31产生。
       
         
       

       
        表9 PRUSS系统中断事件

           
          10个通道可以由任意64个系统事件映射,可以多个系统事件映射到一个通道,但不要将一个系统事件映射到多个通道。
           
          10个主机中断与10个通道之间可以任意映射,可以多个通道映射到一个主机中断,但不要将一个通道映射到多个主机中断,推荐按x号通道映射到x号主机中断方式映射。
         
        主机中断0输出到R31.b30,主机中断1输出到R31.b31。主机中断2~9接输出PRUSS到ARM 和DSP的中断控制器的系统事件PRUSS_EVTOUT0~7。PRU不支持中断向量表,产生的0,1 主机中断可用来唤醒PRU,或为PRU软件提供状态查询。
         
        PRU中断控制器寄存器说明请参考文献[2] 。
         
        5 PRU编程
          5.1 汇编工具PASM
          PRU只支持汇编编程,可用任意的文本编辑器编写源代码。PASM是PRU的命令行汇编器,其语法为:
          pasm[-bcmldz] [-Dname=value] [-Cname] InFile [OutFileBaseName]
         
        参数含义如表10所示:
       
       
       

       
        表10 PASM命令表

         

          PASM将汇编代码转换成一整块可执行的二进制数据用于加载,代码从指令内存的首地址开始排放,编译时没有链接过程,没有内存映射,所以没有段,从而也没有段指示符。输出格式可以为纯二进制文件,C语言形式的数组,Hex格式文件。
         
        5.2 PRU指令集
          指令按功能分为四类:数据搬移指令,算术运算指令,逻辑操作指令,程序流控指令。指令的语法规则参考[3]。
         
       
        表11 PRU指令集

         

          除了访问外部内存的指令,其它所有PRU 指令都是单周期指令。指令中寄存器名加上后缀表示寄存器中的位、字节、半字,这种灵活的寄存器访问方式可以将数据包,结构体分解成小的数据单位处理。
       
       
        表12 寄存器位域表示方式

           
          举例说明这种寄存器访问方式:
           
       

       

         
        5.3 汇编操作符
          PASM支持4类汇编操作符:Hash命令,指示语句,标签,注释。
         
        5.3.1 Hash命令
          控制汇编器的预处理,包括#include,#define,#undef,#ifdef,#ifndef,#else, #endif,#error,与C语言的预处理命令用法类似。
         
        5.3.2 指示符
          指示符以“.”开头,单独占一行,不一定要放在一行的开头,后面可以跟注释语句。
       
       
        表13 PASM汇编指示符

          5.3.3 标签
          在源代码中加入标签名+“:”,用来标示源代码的地址,当被指令引用时,直接替换成标签所在的源代码地址。标签命名不能以数字开头,可以单独为一行,也可以与指令,注释在同一行。
           
         
          5.3.4 注释
          以“//”开始,以行结束符结束,可以出现在代码的任何位置。
         
        6 PRU开发包
          TI提供的PRU开发包里[4],提供了大量的实例源码,目录结构如图3所示。
       
       
        图3 PRU开发包目录结构

         
        bin目录下是Linux与Window版本的PASM工具;docs目录下的readme文件列出了TI wiki上的PRU帮助说明链接;example目录下为各种例程源码,每个例程包括CCSV3.3的DSP工程,和以“.p 和.hp”结尾的PRU代码;host目录下是两个单独的PRU代码下载例程,以文件形式的和以数组形式的。
         
        7 PRU代码下载与运行
          先通过PSC使能PRU模块时钟,PRU空间才可以被访问。
         
        PASM编译后PRU代码通过ARM/DSP从全局地址空间加载到PRU 的指令空间后,ARM/DSP通过全局空间地址将PRUCONTROL寄存器的CONTERENABLE和ENABLE置1,PRU即开始从0地址开始运行。在运行过程中ARM/DSP可以通过CONTROL控制PRU的暂停,运行,复位,及复位后的运行地址等;暂停时可以通过PRU的调试寄存器观察PRU 的寄存器状态,也可以通过调试寄存器修改PRU寄存器的值。
         
        8 PRU调试
          目前在CCSV5里可以用仿真器连接PRU 查看寄存器,内存。但是没有图形界面的PRU调试工具,不能在代码中加入断点这样的方式调试。可以通过以下几种方法进行间接调试。
         
        8.1 加入“打印”信息
          在PRU代码中增加调试代码,根据程序运行状态在内存里写入相应的值,暂停PRU后,通过查看内存值来获取程序的运行状态,也可以在DSP/ARM的代码里加入调试代码检测内存值的变化。
         
        8.2 触发中断
          在PRU代码中通过写R31寄存器给DSP/ARM发送中断,这种方法减轻DSP/ARM的负荷,尤其在DSP/ARM软件与PRU软件一起调试时更为有效。
         
        8.3 通过输出寄存器R30输出状态
          在代码中写R30 设置相应PRU 输出管脚的状态,用示波器或万用表观察管脚状态以获知程序运行状态。
         
        8.4 加入空循环反复调试
          在代码中加入while(1),通过查看PRU的程序指针是否停在空循环处,可以知道程序运行流程是否正确,查看PRU 的寄存器和内存判断运行结果是否正确。在PASM编译产生的列表文件里有代码的对应的程序指针值。
         
        参考文献:
          1.http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit#PRU_C
        ontrol_Register_.280x0000.29
        2.http://processors.wiki.ti.com/index.php/PRU_Interrupt_Controller
        3.http://processors.wiki.ti.com/index.php/PRU_Assembly_Instructions
        4.http://www.ti.com/tool/sprc940
        5.http://processors.wiki.ti.com/index.php/PASM_Syntax_Highlighting
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-12-26 10:23 , 耗时 0.098555 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表