PRU驱动分析

1、PRU-ICSS硬件分析

PRU-ICSS全称:Programmable Real-Time Unit Subsystem and Industrial Communication Subsystem

翻译:可编程实时单元子系统和工业通信子系统

具体这个全称的含义,到后面再进行分析,下面先对PRU进行分析。

image-20200904150155451

以上是PRU-ICSS的资源概览image-20200904160326245

以上是PRU-ICSS2的外部引脚接口。

image-20200904162145200

以上是PRU-ICSS的内存地址。

2、PRU-ICSS功能

image-20200905111110461

PRU要实现的功能主要取决于开发的Firmware。该固件可自己开发,也可以通过从SDK上拷贝TI提供的固件,

TI官方的说法:

Basic firmware examples showing simple functionality

3、如何使用PRU

使用PRU的关键点:

  • 加载固件到PRU

  • 控制PRU的执行,例如:启动、停止等

  • 管理PRU的资源,内存、中断对应表等

  • 提供通信方法

    以上由pruss, pru_rproc,rpmsg_pru Linux 驱动完成。

    image-20200905150942476

以上四个板块表示了加载PRU固件的必备程序,通过pru_rproc module加载Linux文件系统中的/lib/firmware/am335x-pru0-fw固件,并对PRU所需要的资源进行配置,最终完成PRU正常的运行工作。

在工作过程中PRU需要与arm core进行通信,其中两者进行通信的机制是通过在DDR中申请两块内存,分别是PRU to ARM和PRU form ARM。然后当有新的信息时,通过mailboxes进行提示两个核。在arm core当中有rpmsg_pru驱动在用户空间创建一个字符设备,通过读写字符设备实现与PRU的接收与发送信息。在PRU当中,使用RPMsg库进行通信,直接调用 pru_rpmsg_receive 和 pru_rpmsg_send即可实现与ARM CORE的通信。 详情见下图:

image-20200905152516108

以上是PRU的通用的用法,具体到PRU可以实现的功能的话,需要根据PRU的固件来决定。

以上了解了PRU的基本用法,下面对其驱动进行研究。

4、PRU相关驱动研究

根据之前TI给出的框架情况,可以看到remoteproc driver是比较基础的一个驱动,这个层面的驱动主要是与驱动设备模型相关的东西,其中有remoteproc_core.c、remoteproc_debugfs.c等,这里暂不做分析。

这里重点分析pruss和pru_rproc相关的驱动。根据何工之前的关于PRU驱动分析可知,共用到了以下驱动:

device compatible driver
pruss ti,am5728-pruss pruss.c
pruss_intc ti,am5728-pruss-intc pruss_intc.c
pru2_0 ti,am5728-pru pru_rproc.c
pru2_1 ti,am5728-pru pru_rproc.c
pruss2_mdio ti,davinci_mdio davinci_mdio.c

这里针对每个驱动所对应的硬件设备进行分析。

4.1、pruss.c

4.4.1、PRU寄存器地址及功能

        pruss2: pruss@4b280000 {
   
            compatible = "ti,am5728-pruss";
            ti,hwmods = "pruss2";
            reg = <0x4b280000 0x2000>,//Data 8 KiB RAM0
                  <0x4b282000 0x2000>,//Data 8 KiB RAM1
                  <0x4b290000 0x8000>,//Data 32 KiB RAM2 (shared)
                  <0x4b2a6000 0x2000>,//CFG
                  <0x4b2ae000 0x31c>,//IEP
                  <0x4b2b2000 0x58>;//eCAP0+0x2000
            reg-names = "dram0", "dram1", "shrdram2", "cfg",
                    "iep", "mii_rt";
            #address-cells = <1>;
            #size-cells = <1>;
            ranges;
            status = "disabled";
...
        }

在设备树中以上是pru设备的节点,在其下有多个子节点,可以判定该节点是PRU整体模块。对该的属性进行分析,属性主要包括较多的寄存器,对这些寄存器进行分析。

由以上注释可知,前三项是关于PRU RAM的地址信息,这在PRU-ICSS概览图中可以看到,具体这些RAM如何被使用,需要的驱动中具体查看,这里通过设备树传入了该设备的地址信息。

再向下,是关于CFG的地址信息,以下是该地址范围内的寄存器地址,下面不具体分析每一个寄存器每一位的具体作用,仅简单分析该地址范围内的寄存器的大体上的功能。

image-20200907152506076

此类寄存器

1、配置电源

2、配置IO口

3、时钟管理

4、中断状态、中断使能、中断禁止

5、地址偏移使能

6、优先级设置

7、引脚配置

image-20200907155346484

image-20200907155358197

IEP全称:Industrial Ethernet Peripheral 工业以太网外围模块

这些IEP模块有工业以太网定时器,可产生16个比较事件,和一个数字IO。

4.4.2、PRUSS结构体

pruss.c主要就是对这些寄存器进行操作,以完成pru的驱动。

/**
 * struct pruss - PRUSS parent structure
 * @node: list node of this object
 * @dev: pruss device pointer
 * @mem_regions: data for each of the PRUSS memory regions
 * @mem_in_use: to indicate if memory resource is in use
 * @data: pointer to store PRUSS instance private data
 * @host_mask: indicate which HOST IRQs are enabled
 * @pru_running: flag to indicate if PRU is running
 * @pru_in_use: flag to indicate if PRU is used
 * @lock: mutex to serialize access to resources
 * @cfg_lock: mutex to serialize access to CFG
 * @in_standby: flag for storing standby status
 */
struct pruss {
   
	struct list_head node;
	struct device *dev;
	struct pruss_mem_region mem_regions[PRUSS_MEM_MAX];
	struct pruss_mem_region *mem_in_use[PRUSS_MEM_MAX
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔通天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值