长文分享丨TI AM5718的PRU开发详解

跟風遠走 提交于 2020-04-07 17:33:08

PRUSS简介
TI AM5 718 系列 OK571 8开发板 有两个PRU-ICSS(ProgrammableReal-Time Unit Subsystem and Industrial CommunicationSubsystem),可以独立编程实现一些实时性要求高的个性化需求,实现产品的差异化。

本文介绍PRU处理器架构,开发,调试方法。在系统架构上,PRUSS是连接L3_MAIN内部总线上的一个模块,与系统中其它主模块如ARM,DSP一样,可以访问芯片上的其它外设。

长文分享丨TI AM5718的PRU开发详解

PRUSS包括两个PRU,通过自己的32-bitinterconnect总线与子系统的中断控制器、指令内存、数据内存、共享内存、外设模块相连。

PRU不是一个加速器,它是32-bitLoad/Store RISC架构小端处理器,每个PRU有32个通用寄存器R0~R31,12Kbyte指令RAM,8Kbyte数据RAM和32byte共享RAM。指令RAM是独立的,互相之间不能访问,但数据RAM可以通过映射地址互相访问;专用的21个输入引脚和21个输出引脚。

设备中的pru-icss1和pru-icss2集成功能:

•PD_L4PER power domain instantiation
• two master ports (PRU0and PRU1 core initiators) on the device L3_MAIN interconnect
•Non-wakeup capable - smart Standby protocol with the device PRCM
•Software assertion of a standby request "MStandby" (formaster port clock disable) with local (PRUICSS) monitoring of thePRCM "MWait" acknowledge.
• one slave(configuration) port on the L3_MAIN interconnect for device hosts(MPU, DSP1, etc.) to
access various memories and registers ofPRU-ICSS
• Non-wakeup capable - smart Idle protocol with thedevice PRCM
• 10 output interrupt events from local interruptcontroller - PRUSS_INTC:

– 2events to each PRU core (events 0 and 1)
– 8 events mapped tothe device IRQ_CROSSBAR which further remaps them to deviceinterrupt
controllers (events 2 through 9)
– 2 eventsmapped to the device DMA_CROSSBAR, that remaps them to device DMAcontrollers
(events 8 and 9)
• 32 external interrupts aremapped via the device IRQ_CROSSBAR to the local PRUSS_INTC
• Alocal software gating of clocks to several modules within PRUsubsystem (local clock management
protocol), as follows:
–PRUSS_IEP
– PRUSS_eCAP_0
– PRUSS_UART0
–PRUSS_INTC
– PRUSS_PRU0
– PRUSS_PRU1
• 3 inputclocks obtained from device PRCM:
– a PRU-ICSS top levelgatable interface clock
– a PRUSS IEP functional clock
–a PRUSS UART0
• No memory/register retention is supported
•One hardware non-retention (level sensitive) reset

长文分享丨TI AM5718的PRU开发详解

长文分享丨TI AM5718的PRU开发详解

PART 01 ▼ PRU内存映射
1.1 指令空间
每个PRU独立的指令空间为0x00000000~0x00002FFF。指令空间由外部主处理ARM/DSP初始化,程序指针PC是32bit字地址,不是字节地址,如PC=2,代表指令地址0x08。

长文分享丨TI AM5718的PRU开发详解

▲PRU指令空间映射表

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

长文分享丨TI AM5718的PRU开发详解

长文分享丨TI AM5718的PRU开发详解

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

1.3 全局地址空间映射
PRU_ICSS1局部地址在系统全局地址空间基地址(L3_MAINbase address)为0x4B2A0000,PRU_ICSS2局部地址在系统全局地址空间基地址(L3_MAINbase address)为0x4B28E000。表3表示PRU_ICSS局部地址空间的偏移量(OffsetAddress)。

长文分享丨TI AM5718的PRU开发详解

▲PRUSS全局空间内存映射表

PRU可以通过表2的局部地址,也可以通过全局地址访问PRUSS的数据空间,通过全局地址空间访问要经过系统L3_MAINdevice,比通过局部地址空间访问要慢。

PRUSS外部主模块如ARM,DSP等可通过系统全局地址空间映射端口+全局地址空间访问(表3的OffsetAddress + L3_MAIN base address)PRU资源。详情参考《AM571xTechnical Reference Manual》中30.4.4.2PRU-ICSS Global Memory Map章节内容。

PART 02 ▼ 控制/状态寄存器
PRU0的控制/状态寄存器地址位于0x00020000~0x0002_3FFF,PRU1的控制/状态寄存器地址位于0x0002_4000~0x0002_5FFF,寄存器列表如表4所示,各寄存器的详细说明请参阅[1]。

长文分享丨TI AM5718的PRU开发详解

长文分享丨TI AM5718的PRU开发详解

长文分享丨TI AM5718的PRU开发详解

▲PRU控制/状态寄存器表

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

长文分享丨TI AM5718的PRU开发详解

▲表5 PRU控制寄存器说明表

2.2 PRU_STATUS状态寄存器
状态寄存即PRU的程序指针寄存器,与程序的真正运行状态有一个周期的延时。

2.3 PRU_WAKEUP_EN唤醒使能寄存器
在程序执行SLP指令进入睡眠状态之前,使能WAKEUP寄存器相应的位,当输入状态寄存器R31相应的位置1时,即WAKEUP&R31!=0时,唤醒PRU。

2.4 PRU_CYCLE周期计数器
当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 PRUSS_DBG_GPREG 0~31调试通用寄存器
PRUSS_DBG_GPREG0~31与通用寄存器R0~R31对应,为外部主模块提供一个调试窗口。当PRU停止时,ARM/DSP读/写INTGPR0~31直接读/写寄存器R0~R31。

PART 03 ▼ PRU通用寄存器
3.1 PRU事件/状态寄存器R31
R31是一个特殊的寄存器,读与写操作时的功能是不一样的。写R31寄存器时,写一个0到15之间的通道号到R31_PRU_VEC[3:0],同时设置R31_PRU_VEC_VALID,将产生相应的中断输出事件到中断控制器的系统事件。两个PRU输出的断事件相“或”输出到同一个中断控制器系统事件。

长文分享丨TI AM5718的PRU开发详解

长文分享丨TI AM5718的PRU开发详解

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

长文分享丨TI AM5718的PRU开发详解

3.2 通用输出寄存器R30
每个PRU有32个独立的输出管脚PRU0_R31[31:0]和PRU1_R31[31:0],写到寄存器R30[31:0]的值直接输出到PRUn_R31[31:0]管脚。

PART 04▼PRU中断控制器
PRU中断控制器支持64个系统事件,10个中断通道,10个主机中断。

长文分享丨TI AM5718的PRU开发详解

▲图2 PRU中断控制器框图

PRU-ICSS1_INTC/PRUSS2_INTC的中断0~31对应着PRU-ICSS集成模块产生的事件。系统事件16~31由写R31产生。

长文分享丨TI AM5718的PRU开发详解

PRU_ICSS系统事件32~55(中断输入),可以通过系统配置寄存器PRUSS_MII_RT[0]选择标准的或者MII_RT系统事件,PRUSSEVTSEL=0时选择PRU-ICSS专用IRQ_CROSSBAR输出的事件作为中断源,PRUSSEVTSEL=1时选择MII_RT模块产生的事件作为中断源。如下图所示:

长文分享丨TI AM5718的PRU开发详解

10个通道可以由任意64个系统事件映射,可以多个系统事件映射到一个通道,但不要将一个系统事件映射到多个通道。

设置PRUSS_INTC_CMR实现通道和64个系统事件的映射,PRUSS_INTC_CMRi(i为0~15)寄存器用于实现i4到i4+k号系统事件映射到相应的通道。通过寄存器相应位设置的通道号映射到相应的系统事件。

10个主机中断与10个通道之间可以任意映射,可以多个通道映射到一个主机中断,但不要将一个通道映射到多个主机中断,推荐按x号通道映射到x号主机中断方式映射。

PRUSS_INTC_HMR寄存器主机中断和通道的映射。PRUSS_INTC_HMRi(i为0~3)寄存器用于实现0-9号通道映射到0-9号主机中断。通过寄存器相应位设置主机中断号,将住中断号与通道号建立映射。

主机中断0输出到R31.b30,主机中断1输出到R31.b31。主机中断2~9接输出PRUSS到ARM和DSP的中断控制器的系统事件PRUSS_EVTOUT0~7。PRU不支持中断向量表,产生的0,1主机中断可用来唤醒PRU,或为PRU软件提供状态查询。PRU中断控制器寄存器说明请参考文献[2]。

看点05▼PRU代码包
飞凌嵌入式 AM571x 系列 OK5718开发板 用户资料中提供了大量的实例源码,目录结构如图3所示。

长文分享丨TI AM5718的PRU开发详解

关于例程的编译和测试,详见《OK5718-C软件手册》7.4Ti 官方例程编译及测试和7.5飞凌例程编译及测试。

PART06▼PRU软件调试
6.1 调试工具
调试工具我们使用TI官方推出的仿真器XDS100V2 ,XDS100V2是一款USBJTAG仿真器。

6.2 硬件连接
步骤一:

将XDS100V2仿真器相关引脚通过飞凌调试转接板与 0K5718-C开发板 的JTAG

接口使用排线进行连接。连接方式如下:

长文分享丨TI AM5718的PRU开发详解

步骤二:

使用USB数据连接线连接XDS100V2到PC机USB接口。

6.3 软件调试
本实例使用飞凌pru测试程序PRU_LED0做仿真调试,将项目导入到ccs后,右击PRU_LED0,选择Properties。

长文分享丨TI AM5718的PRU开发详解

选择使用仿真器和编译器版本,设置完成后点击ok。

长文分享丨TI AM5718的PRU开发详解

右击PRU_LED0,选择DebugConfigurations。

长文分享丨TI AM5718的PRU开发详解

选择PRU_LED0,去掉相应的勾选之后如下图。点击Apply,最后点Debug。

长文分享丨TI AM5718的PRU开发详解

点击run菜单,选择debug。

长文分享丨TI AM5718的PRU开发详解

以下方式也可以进入debug。

长文分享丨TI AM5718的PRU开发详解

如果编译通过的话,会是这个样子。

长文分享丨TI AM5718的PRU开发详解

进入仿真后光标会停在主函数开始处。

长文分享丨TI AM5718的PRU开发详解

长文分享丨TI AM5718的PRU开发详解

下面对上图的按钮做一下说明

按钮1,运行按钮,全速运行。如果为灰色,说明一直在执行代码,也可能是死循环,点暂停键看看。

按钮2,暂停运行。

按钮3,退出仿真。

按钮4,单步运行,遇到子函数进入子函数。

按钮5,单步运行,遇到函数会当成语句,直接一步过,不进入函数内部。

按钮6,单步运行,如果程序在子函数中运行,点击此按钮,跳出子函数。

按钮7,汇编单步,遇到子函数,进入子函数。

按钮8,汇编单步运行,遇到函数会当成语句,直接一步过,不进入函数内部。

在软件调试过程中,进行如下操作可以查看变量,寄存器值。

点击view菜单,选择Expressions项。

长文分享丨TI AM5718的PRU开发详解

出现以下界面

长文分享丨TI AM5718的PRU开发详解

▼ 选中要观察的变量名,右击选中AddWatch Expression 项。

长文分享丨TI AM5718的PRU开发详解

点击ok。

长文分享丨TI AM5718的PRU开发详解

Expressions 窗口中加入变量gpio的值。

长文分享丨TI AM5718的PRU开发详解

点击Addnew expression 输入R30,在Expressions窗口中显示R30值。

长文分享丨TI AM5718的PRU开发详解

当进入调试界面后,当要程序运行到某一行时,右击某一行,点击runto line 。则运行到此行,右击57行。

长文分享丨TI AM5718的PRU开发详解

运行到57行gpio值发生变化,转化为16进制为0xffffffff。

长文分享丨TI AM5718的PRU开发详解

右击60行,选择runto line,R30值发生变化。

长文分享丨TI AM5718的PRU开发详解

原文链接:https://www.forlinx.com/article_view_274.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!