PRU 开发详解

PRUSS 简介99【中国自动化网社区】6859d5【http://sns.ca800.com】669ecf0

    在系统架构上,PRUSS 是连接在OMAPL138 内部总线SCR 上的一个模块,与系统中其它主模块如ARM,DSP 一样,可以访问芯片上的其它外设,工作在PLL0_SYSCLK2 时钟域,即ARM/DSP 频率的一半。99【中国自动化网社区】6859d5【http://sns.ca800.com】669ecf0

229945【中国自动化网社区】be3ab7【http://sns.ca800.com】aee

 229945【中国自动化网社区】be3ab7【http://sns.ca800.com】aee

    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、指令流水线、及乘法指令。229945【中国自动化网社区】be3ab7【http://sns.ca800.com】aee

    1 PRU 内存映射2d【中国自动化网社区】ef65e4【http://sns.ca800.com】1b48

    1.1 指令空间2d【中国自动化网社区】ef65e4【http://sns.ca800.com】1b48

    每个PRU 独立的指令空间为0x00000000~0x00000FFF。指令空间由外部主处理ARM/DSP 初始化,程序指针PC 是32bit 字地址,不是字节地址,如PC=2,代表指令地址0x08。2d【中国自动化网社区】ef65e4【http://sns.ca800.com】1b48

2d【中国自动化网社区】ef65e4【http://sns.ca800.com】1b48

    1.2 数据空间0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    每个PRU 独立的512byte 数据RAM 空间为0x0000~0x01FF,因为数据RAM连接在PRU 子系统的SCR 上,所以子系统中的其它主模块也可以访问到这块空间,这段内存空间在另一个PRU 上的映射地址为0x2000~0x21FF。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    位于数据空间的还有共用的中断控制器寄存器;PRU 控制/状态寄存器,有各自的地址空间。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    1.3 全局地址空间映射0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PRU 局部地址空间在系统全局地址空间映射端口为0x01C30000,如表3 所示,PRU 可以通过表2 的局部地址,也可以通过表3 的全局地址访问PRUSS 的数据空间,通过全局地址空间访问要经过系统SCR2,比通过局部地址空间访问要慢。PRUSS 外部主模块如ARM,DSP 等可通过全局地址空间访问PRU 资源。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    控制/状态寄存器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PRU0 的控制/状态寄存器地址位于0x00007000~0x000077FF,PRU1 的控制/状态寄存器地址位于0x00007800~0x00007FFF,寄存器列表如表4 所示,各寄存器的详细说明请参阅 [1] 。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.1 CONTROL控制寄存器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    外部主模块ARM/DSP 通过控制寄存器可以控制PRU 的运行状态。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.2 STATUS状态寄存器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    状态寄存即PRU 的程序指针寄存器,与程序的真正运行状态有一个周期的延时。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.3 WAKEUP唤醒使能寄存器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在程序执行SLP 指令进入睡眠状态之前,使能WAKEUP 寄存器相应的位,当输入状态寄存器R31 相应的位置1 时,即WAKEUP&R31  != 0 时,唤醒PRU。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.4 CYCLECNT周期计数器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    当CONTROL[ENABLE]=1 和CONTROL[COUNTENABLE]=1 时,CYCLECNT以PRU 时钟周期计数。当CONTROL[ENABLE]=0 或CONTROL[COUNTENABLE]=0 时,计数停止。当重新使能时,恢复继续计数。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.5 STALLCNT取指停止计数器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    当CONTROL[ENABLE]=1 和CONTROL[COUNTENABLE]=1,且由于某种原因PRU 不能取指令时,STALLCNT 开始以PRU 时钟周期计数。其值总是小于,或等于CYCLECNT 的值。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.6 常量表0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PRU 提供32 个常量地址表C0~C31,  INTCTER0-INTCTER31 是常量表的调试接口,当PRU 停止时,外部主模块读取INTCTERn即得到常量表Cn 的值。通过指令LBCO 或SBCO 从常量表指向的地址与寄存器之间以簇发方式传递数据。指令格式举例如下:0df【中国自动化网社区】28598a【http://sns.ca800.com】181

LBCO     R2, C2, 5, 8 //从C2+5 的地址读取8 字节到R2, R3。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

SBCO     R2, C2, 5, 8 //将R2, R3 的数据写到C2+5 开始的地址。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在性能上与指令LBBO 和SBBO 没有区别,利用常量表可以节省通用寄存器的使用。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    0~23 号常量表提供的入口地址是固定的,24~31 号常量表的域可通过寄存器编程设置:0df【中国自动化网社区】28598a【http://sns.ca800.com】181

  •          C24[11:8]通过CONTABBLKIDX0[3:0]设置;0df【中国自动化网社区】28598a【http://sns.ca800.com】181
  •          C25[11:8]通过CONTABBLKIDX0[19:16]设置;0df【中国自动化网社区】28598a【http://sns.ca800.com】181
  •          C28[23:8]通过CONTABPROPTR0[15:0]设置;0df【中国自动化网社区】28598a【http://sns.ca800.com】181
  •          C29[23:8]通过CONTABPROPTR0[31:16]设置;0df【中国自动化网社区】28598a【http://sns.ca800.com】181
  •          C30[23:8]通过  CONTABPROPTR1[15:0]设置;0df【中国自动化网社区】28598a【http://sns.ca800.com】181
  •          C31 [23:8] 通过CONTABPROPTR1 [31:16] 设置。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    2.7 INTGPR0~31 调试通用寄存器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    INTGPR0~31 与通用寄存器R0~R31 对应,为外部主模块提供一个调试窗口。当PRU 停止时,ARM/DSP 读/写INTGPR0~31 直接读/写寄存器R0~R31。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    3 PRU模块接口0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    3.1 PRU事件/状态寄存器R31 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    R31 是一个特殊的寄存器,读与写操作时的功能是不一样的。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    写R31 寄存器时,写事件号0~31 到R31_PRU_VEC[4:0],同时设置R31_PRU_VEC_VALID,将产生中断输出事件到中断控制器的32~63 号系统事件。两个PRU 输出的中断事件相“或”输出到同一个中断号。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    读R31 寄存器时,R31[29:0]反映PRU 的输入管脚PRU_R30[29:0]的状态。R31[31:30]是映射到中断控制器的INTR_IN[0]和INTR_IN[1]的状态。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    3.2 通用输出寄存器R300df【中国自动化网社区】28598a【http://sns.ca800.com】181

    每个PRU 有32 个独立的输出管脚PRU0_R31[31:0]和PRU1_R31[31:0],写到寄存器R30[31:0]的值直接输出到PRUn_R31[31:0]管脚。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    4 PRU中断控制器0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PRU 中断控制器支持64 个系统事件,10 个中断通道,10 个主机中断。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    系统事件0~31 为32 个外部事件如表9 所示,可以通过系统配置寄存器CFGCHIP3 的第3 位PRUEVTSEL 在两组事件中进行选择,PRUSSEVTSEL=0时选择第一列的32 个外部系统事件,PRUSSEVTSEL=1 时选择第二列的32 个外部系统事件;系统事件32~63 由写R31 产生。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    10 个通道可以由任意64 个系统事件映射,可以多个系统事件映射到一个通道,但不要将一个系统事件映射到多个通道。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    10 个主机中断与10 个通道之间可以任意映射,可以多个通道映射到一个主机中断,但不要将一个通道映射到多个主机中断,推荐按x 号通道映射到x 号主机中断方式映射。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    主机中断0 输出到R31.b30,主机中断1 输出到R31.b31。主机中断2~9 接输出PRUSS 到ARM 和DSP 的中断控制器的系统事件PRUSS_EVTOUT0~7。PRU 不支持中断向量表,产生的0,1 主机中断可用来唤醒PRU,或为PRU 软件提供状态查询。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PRU 中断控制器寄存器说明请参考文献 [2] 。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5 PRU编程0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.1 汇编工具PASM0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PRU 只支持汇编编程,可用任意的文本编辑器编写源代码。PASM 是PRU 的命令行汇编器,其语法为:0df【中国自动化网社区】28598a【http://sns.ca800.com】181

pasm [-bcmldz] [-Dname=value] [-Cname] InFile [OutFileBaseName] 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    参数含义如表10 所示:0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PASM 将汇编代码转换成一整块可执行的二进制数据用于加载,代码从指令内存的首地址开始排放,编译时没有链接过程,没有内存映射,所以没有段,从而也没有段指示符。输出格式可以为纯二进制文件,C 语言形式的数组,Hex 格式文件。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.2 PRU指令集0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    指令按功能分为四类:数据搬移指令,算术运算指令,逻辑操作指令,程序流控指令。指令的语法规则参考[3]。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    除了访问外部内存的指令,其它所有PRU 指令都是单周期指令。指令中寄存器名加上后缀表示寄存器中的位、字节、半字,这种灵活的寄存器访问方式可以将数据包,结构体分解成小的数据单位处理。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    举例说明这种寄存器访问方式:0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181


0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.3 汇编操作符0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    PASM 支持4 类汇编操作符:Hash 命令,指示语句,标签,注释。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.3.1 Hash命令0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    控制汇编器的预处理,包括#include,#define,#undef,#ifdef,#ifndef,#else, #endif,#error,与C 语言的预处理命令用法类似。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.3.2 指示符0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    指示符以“.”开头,单独占一行,不一定要放在一行的开头,后面可以跟注释语句。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.3.3 标签0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在源代码中加入标签名+“:”,用来标示源代码的地址,当被指令引用时,直接替换成标签所在的源代码地址。标签命名不能以数字开头,可以单独为一行,也可以与指令,注释在同一行。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    5.3.4 注释0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    以“//”开始,以行结束符结束,可以出现在代码的任何位置。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    6 PRU开发包0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    TI 提供的PRU 开发包里 [4] ,提供了大量的实例源码,目录结构如图3 所示。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    bin目录下是Linux 与Window 版本的PASM 工具;docs 目录下的readme 文件列出了TI wiki 上的PRU 帮助说明链接;example 目录下为各种例程源码,每个例程包括CCSV3.3 的DSP 工程,和以“.p 和.hp”结尾的PRU 代码;host 目录下是两个单独的PRU 代码下载例程,以文件形式的和以数组形式的。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    7 PRU代码下载与运行0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    先通过PSC 使能PRU 模块时钟,PRU 空间才可以被访问。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

PASM 编译后PRU 代码通过ARM/DSP 从全局地址空间加载到PRU 的指令空间后,ARM/DSP 通过全局空间地址将PRUCONTROL 寄存器的CONTERENABLE  和ENABLE置1,PRU 即开始从0 地址开始运行。在运行过程中ARM/DSP 可以通过CONTROL 控制PRU 的暂停,运行,复位,及复位后的运行地址等;暂停时可以通过PRU 的调试寄存器观察PRU 的寄存器状态,也可以通过调试寄存器修改PRU 寄存器的值。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    8 PRU调试0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    目前在CCSV5 里可以用仿真器连接PRU 查看寄存器,内存。但是没有图形界面的PRU 调试工具,不能在代码中加入断点这样的方式调试。可以通过以下几种方法进行间接调试。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    8.1 加入“打印”信息0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在PRU 代码中增加调试代码,根据程序运行状态在内存里写入相应的值,暂停PRU 后,通过查看内存值来获取程序的运行状态,也可以在DSP/ARM 的代码里加入调试代码检测内存值的变化。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    8.2 触发中断0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在PRU 代码中通过写R31 寄存器给DSP/ARM 发送中断,这种方法减轻DSP/ARM 的负荷,尤其在DSP/ARM 软件与PRU 软件一起调试时更为有效。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    8.3 通过输出寄存器R30输出状态0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在代码中写R30 设置相应PRU 输出管脚的状态,用示波器或万用表观察管脚状态以获知程序运行状态。0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    8.4 加入空循环反复调试0df【中国自动化网社区】28598a【http://sns.ca800.com】181

    在代码中加入while(1),通过查看PRU 的程序指针是否停在空循环处,可以知道程序运行流程是否正确,查看PRU 的寄存器和内存判断运行结果是否正确。在PASM 编译产生的列表文件里有代码的对应的程序指针值。(作者:唐超伦)0df【中国自动化网社区】28598a【http://sns.ca800.com】181

参考文献:0df【中国自动化网社区】28598a【http://sns.ca800.com】181

1.http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit#PRU_C0df【中国自动化网社区】28598a【http://sns.ca800.com】181

ontrol_Register_.280x0000.29 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

2.http://processors.wiki.ti.com/index.php/PRU_Interrupt_Controller 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

3.http://processors.wiki.ti.com/index.php/PRU_Assembly_Instructions 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

4.http://www.ti.com/tool/sprc940 0df【中国自动化网社区】28598a【http://sns.ca800.com】181

5.http://processors.wiki.ti.com/index.php/PASM_Syntax_Highlighting 0df【中国

猜你喜欢

转载自blog.csdn.net/boyemachao/article/details/89552086
今日推荐