什么是PRU-ICSS?
BeagleboneBlack所使用的ti芯片(XAM3359AZCZ revision 2)包含了一个主处理器和许多其他的模块,如下图:
尽管ARM Cortex-A8内核的性能十分强大,但是Linux的本质决定了对于高速外部硬件的控制可能会不太容易实现。而TI的这款芯片添加了两个额外的CPU(称为PRU-ICSS或PRUSSv2,即可编程实时单元和工业用通信子系统,以后简称PRU),从而使这个问题得到了改善。这意味着这两个CPU可以分别运行不同的软件,以便减轻底层协议在硬件接口和处理上的工作量。
这款芯片就好像具有Arduino类似功能的处理器,只不过其额外的两个CPU工作频率要高出许多,达到200MHz,也就是说在许多情况下可以不再需要外部逻辑器件、CPLD或者FPGA。
通常来说,针对一个以上的处理器进行编程是一件麻烦事,而且处理器之间还需要有通信协议。而TI的这款芯片则极大的简化了这种麻烦,原因有两点,一是用于PRU的代码可以从主处理器下载,二是为了方便处理器之间通信,芯片集成了共享存储器。
PRU的作用体现在哪儿?
对于低速通信来说,传统的I2C或者常用的协议就已经足够应付了,因此PRU在这些地方并没有用武之地。而对于高速通信PRU可能会非常受欢迎,这是因为PRU能够消除由于Linux环境切换所造成的中断,从而连续对硬件提供服务,也不会对ARM主处理器造成负担。这里有一些常见的并且可行例子;
• 连接到高速ADC(例如模拟信号捕捉)
• CCD 或者CMOS摄像机
• LED或者LCD显示器
• 生成模拟视频信号(视频编码器)
• 自定义PWM或者其他自定义协议或非标准协议
• 带反馈的电机控制
据我所知,PRU甚至能够用某个外部时钟来作为并行数据的时钟。
如何使用PRU?
当前来说使用PRU即不简单也不算困难。主要的难度在于在网上找到完整的实例。这里提供的内容就是从网上收集而来的。
主要步骤如下:
1. 在BB-Black上使能PRU系统
2. 将PRU汇编程序安装到BBB上(当前用于PRU的代码是都是用汇编写的,还没有人开发出这对PRU的C编译器)
3. 编写代码。PRU应用程序分为两部分,而且相互之间能够通过存储器寻址来进行通信,即
(a) 汇编代码,编译为.bin机器指令文件,以便在PRU上运行
(b) C语言代码,运行于主处理器上,也就是Linux系统上。这些代码负责将汇编代码下载到RPU
4. 配置Linux设置树,启用所有引脚用于输入输出
5. 运行程序
PRU使用什么样的汇编代码?
还好寄存器数量很给力(都是32位),而且指令都是正交的,另外用于操作的位和字节参考都相当令人满意,所以相对而言,比起某些常见的汇编语言,例如针对PIC或其他8位处理器的汇编来说,PRU使用的汇编代码算是比较容易上手的了。汇编命令数量并不多,目前为止我只使用了大约45条命令中的一小部分,结果还不错。(通常本人不愿意为了某个不太好用的处理器花太多时间学习汇编 – 但RPU完全不同,其指令集貌似很好用的样子)
PRU是否物有所值?
我觉得答案是肯定的,应为有了PRU就能够在高速状态下控制硬件(比如50MHz)。每条指令在PRU上只需要5纳秒的执行时间(200MHz频率,每条指令占用一个周期),并且不存在由于Linux内核造成的不规则延迟。
难点在哪儿?
难点主要在于和设备树相关的东西。希望在未来能够有所变化或者变得更简单。在一个典型的微控制器上,输入输出的设定是用特定的寄存器完成的,这些寄存器存在于某个设备的某一部分存储映射中。据我所知,当前运行在BB-Black上的软件不允许用户通过传统的C代码对这些硬件寄存器进行直接的修改操作。当前采用的方法叫做“设备树”。它是一个文本文件,并且被压缩成为二进制文件,在系统启动时需要对其进行读操作。该文件高速系统哪些是用于输入输出的引脚。设备树的修改也适用于使能RPU系统。
有人曾经通过设备树关闭了BB-Black上默认闪烁的LED灯。设备树文件位于BB-Black的/boot目录下,是一个二进制文件,其内容自然无法看懂(如下图),通常文件名为.dtb或者.dtbo。