一、认识BBG中的PRU
1 PRUSS(Programmable Real-time Unit Sub-System ),即可编程实时单元子系统,它是在AM335x等芯片上自带的,独立于ARM CPU运行的子系统。其时钟频率为200MHz,可以直接控制特定的IO口,可以达到非常高的实时性要求。一般两种情况需要用到它:一是linux系统的实时性不满足要求的时候;二是芯片的功能模块不够用的时候(比如你想要10个UART,但芯片上只有6个,那你可以用它再创造4个)。芯片内部的结构如下图所示
PRU的功能框图如下图所示,它包括两个PRU单元,除了可以实时控制引脚,系统还为其分配了分配8K的数据单元以及12K共享内存单元。另外,该模块还可以一个串口模块,一个eCAP0实时捕获模块,以及一个IEP(Industrial Ethernet Peripheral)接口,可以运行EtherCat,EtherNer等网络接口等。
2 BBG上的扩展接口
在BBG上,引出的PRU引脚如下图所示,一共引出了25个接口,其实还引出了UART接口,只是现在还没有开源的、可运行的源码,只是在TI官方的SDK中有说明,但针对的是linux3.2和linux3.12内核,而不是常用的linux3.8内核。
二、操作BBG中的PRU
在官方的镜像文件中,默认是没有开启PRU单元的,所以需要手动将其启动并加载。具体的使用方法,主要步骤如下:
1. 在BB-Black上使能PRU系统
2. 将PRU汇编程序安装到BBB上(当前用于PRU的代码是都是用汇编写的,还没有人开发出这对PRU的C编译器)
3. 编写代码。PRU应用程序分为两部分,而且相互之间能够通过存储器寻址来进行通信,即
(a) 汇编代码,编译为.bin机器指令文件,以便在PRU上运行
(b) C语言代码,运行于主处理器上,也就是Linux系统上。这些代码负责将汇编代码下载到RPU
4. 配置Linux设置树,启用所有引脚用于输入输出
5. 运行程序
1修改主设备树,启动PRUSS模块
cd /boot
cp am335x-boneblack.dtb
am335x-boneblack.dtb_orig
dtc -I dtb -O dts am335x-boneblack.dtb
> am335x-boneblack.dts_orig
vi am335x-boneblack.dts_orig
Search for pruss@4a300000 and then it changes “diabled" to "okay" as followiing
status = "disabled";
to
status = "okay";
dtc -I dts -O dtb
am335x-boneblack.dts_orig > am335x-boneblack.dtb
reboot
2 编译PRU控制包
git clone
git://github.com/beagleboard/am335x_pru_package.git
cd am335x_pru_package
export CROSS_COMPILE=
cd pru_sw/app_loader/interface
make
cd ../../../pru_sw/utils/pasm_source
source ./linuxbuild
cd ../../../
cp pru_sw/app_loader/lib/* /usr/lib
cp pru_sw/app_loader/include/*
/usr/include
cp pru_sw/utils/pasm /usr/bin
3 开启设备树(BB-BONE-PRU-03-00A0.dts)
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
/* identification */
part-number = "BB-BONE-PRU";
version = "00A0";
exclusive-use =
"P8.12";
fragment[@0:56500] {
target = <&am33xx_pinmux>;
__overlay__ {
mygpio: pinmux_mygpio{
pinctrl-single,pins = <
0x30 0x06
>;
};
};
};
fragment[@1:145105] {
target = <&ocp>;
__overlay__ {
test_helper: helper {
compatible = "bone-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&mygpio>;
status = "okay";
};
};
};
fragment@2{
target = <&pruss>;
__overlay__ {
status = "okay";
};
};
};
1)编译生成dtbo文件
dtc -O dtb -@ BB-BONE-PRU-03-00A0.dts >
BB-BONE-PRU-03-00A0.dtbo
2)将生成文件复制到/lib/fireware目录下
cp BB-BONE-PRU-03-00A0.dtbo /lib/fireware
3)加载设备树
echo BB-BONE-PRU-03 >
/sys/devices/bone_capemgr.*/slots
4 编写汇编语言
.origin 0
.entrypoint START
#define PRU0_ARM_INTERRUPT 19
#define CONST_PRUCFG C4
START:
LBCO r0, CONST_PRUCFG, 4, 4
CLR r0, r0, 4
SBCO r0, CONST_PRUCFG, 4, 4
MOV r1, 10
LOOP1:
SET r30.t14 //set P8.12
MOV r0,100000000
DELAY1:
SUB r0, r0, 1
QBNE DELAY1, r0, 0
CLR r30.t14
MOV r0, 100000000
DELAY2:
SUB r0, r0, 1
QBNE DELAY2, r0, 0
SUB r1, r1, 1
QBNE LOOP1, r1, 0
MOV r31.b0, PRU0_ARM_INTERRUPT+16
HALT
编译,生成bin文件
pasm -b prucode
5 编写控制程序
1 )控制程序
#include
#include
#include
#define PRU_NUM 0
int main (void)
{
unsigned int ret;
tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
prussdrv_init ();
if (prussdrv_open(PRU_EVTOUT_0))
{
printf("prussdrv_open open failedn");
return (-1);
}
prussdrv_pruintc_init(&pruss_intc_initdata);
prussdrv_exec_program (PRU_NUM, "./prucode.bin");
prussdrv_pru_wait_event (PRU_EVTOUT_0);
prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
prussdrv_pru_disable (PRU_NUM);
prussdrv_exit ();
return(0);
}
2) 编译程序
gcc mytest.c -lpthread -lprussdrv -o mytest
3)运行程序
./mytest
4 )效果
参考链接
1 BBB - Working with the PRU-ICSS/PRUSSv2
关注微信公众号【口袋物联】,微信号为koudaiwulian,更多物联网知识等着你
BeagleBone Green开发板试用帖汇总
|