通过ROS控制真实机械臂(11) --- 通过 PRU-ICSS 访问 GPIO 实现电机正反转

每个PRU都连接着一个OCP主口,它允许访问linux主机设备对应的内存地址。此功能允许PRU控制通用GPIO的输入和输出状态。PRU可访问Linux主机内存,但是访问速度要慢上好几倍,因为内存访问需要路由到外部的PRU-ICSS,在通过PRU-ICSS接口从/OCP从口接收返回结果。

首先测试用 PRU 通过/OCP主口访问 通用 GPIO 口。

设备树覆盖层如下,用示波器连接beaglebone的GND和P9_11,板子开机发现示波器一直显示的是高电平,如下操作将环境变量写入文件,这样就不用每次开机手动加载环境变量了。

对于通用GPIO口,模式和地址如下查询手册即可。对于增强型GPIO口,0x05表示输出模式,0x26表示输入模式。

__overlay__ {

 gpio_pins: pinmux_gpio_pins {         // The GPIO pins
	pinctrl-single,pins = <
	   0x070 0x07  // P9_11 MODE7 | OUTPUT | GPIO pull-down
	   0x074 0x27  // P9_13 MODE7 | INPUT | GPIO pull-down
	>;
 };

 pru_pru_pins: pinmux_pru_pru_pins {   // The PRU pin modes
	pinctrl-single,pins = <
	   0x1a4 0x05  // P9_27 pr1_pru0_pru_r30_5, MODE5 | OUTPUT | PRU
	   0x19c 0x26  // P9_28 pr1_pru0_pru_r31_3, MODE6 | INPUT | PRU
	>;
 };
};

$ vim ./bashrc
    export SLOTS=/sys/devices/bone_capemgr.9/slots
    export PINS=/sys/kernel/debug/pinctrl/44e10800.pinmux/pins
$ sudo sh -c "echo EBB-PRU-Example > $SLOTS"

加载好设备树之后,发现示波器上的高电平变成了低电平,说明设备树加载成功。
使用如下主程序测试motor_direction.cpp:

#include <stdio.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <sys/epoll.h>
#include <iostream>
#include "prussdrv.h"
#include <pruss_intc_mapping.h>

#define DELAY_US 4000 // Max. value = 21474836 us
#define TICKS ((DELAY_US / 5) * 1000)
#define PRU_NUM 0
using namespace std;
int main(void)
{
    if(getuid()!=0){
        printf("必须使用root权限,否则会提示段错误\n");
    }

    tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
    prussdrv_init();
    prussdrv_open(PRU_EVTOUT_0);
    prussdrv_pruintc_init( &pruss_intc_initdata);

    // PRU开始时间
    struct timeval start;
    gettimeofday(&start,NULL);

    prussdrv_exec_program (PRU_NUM, "./motor_direction.bin");
    prussdrv_pru_wait_event (PRU_EVTOUT_0);

    // pru结束时间
    struct timeval end;
    gettimeofday(&end,NULL);

    double diff;
    diff = end.tv_sec -start.tv_sec + (end.tv_usec - start.tv_usec)*0.000001;
    cout<< "EBB PRU程序已完成,历时约 "<< diff << "秒!" << endl;

    // prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
    prussdrv_pru_disable(PRU_NUM);
    prussdrv_exit ();
    return 0;
}

PRU程序如下motor_direction.p:

// 选择gpio0_30和gpio0_31 对应 p9_11(OUT)和p9_13(IN)

.origin 0
.entrypoint ENABLEOCP

#define DELAY_US 4000 // Max. value = 21474836 us
#define TICKS ((DELAY_US / 5) * 1000)
#define PRU0_R31_VEC_VALID 32
#define PRU_EVTOUT_0    3

#define GPIO0 0x44e07000         // GPIO 0 See the AM335x TRM,Table 2.2 Peripheral Map
#define GPIO1 0x4804c000         // GPIO 1
#define GPIO2 0x481ac000         // GPIO 2
#define GPIO3 0x481ae000         // GPIO 3

#define GPIO_CLEARDATA 0x190     // for clearing the GPIO registers, See the TRM section 25.4.1
#define GPIO_DATAOUT   0x194     // for setting the GPIO registers
#define GPIO_DATAIN    0x1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值