I finally got my Beaglebone Black PRU C code project up and going.
It took a lot of googling and posting, but I thought it would be nice to post a 
condensed version of the notes needed to get C code running on the BBB PRU.
This is targeting Debian 3.8 kernel versions.

------------------------------------------------------------------------------
Possible PRU pin mappings + values for device tree building + BBB conflict pins
------------------------------------------------------------------------------
Bit     pr1_pru0_pru_r30_? (out)
0       P9_31, gpio3[14], 0x190 , Mode 6
1       P9-29, gpio3[15], 0x194, Mode 6
2       P9-30, gpio3[16], 0x198,  Mode 6 (HDMI, LCD)
3       P9-28, gpio3[17], 0x19c,  Mode 6
4       P9-42, gpio3[14], 0x1a0,  Mode 6
5       P9-27, gpio3[19], 0x1a4,  Mode 6 (HDMI, LCD)
6       P9-41, gpio3[20], 0x1a8,  Mode 6
7       P9-25, gpio3[21], 0x1ac, Mode 6
8       
9       
10      
11      
12      
13      
14      P8-12, gpio1[12], 0x030, Mode 6
15      P8-11, gpio1[13], 0x034, Mode 6


Bit     pr1_pru0_pru_r31_?  (in)
0       P9-31, gpio3[14], 0x190, Mode 5
1       P9-29, gpio3[15], 0x194, Mode 5
2       P9-30, gpio3[16], 0x198, Mode 5 (HDMI, LCD)
3       P9-28, gpio3[17], 0x19c, Mode 5
4       P9-42, gpio3[14], 0x1a0, Mode 5
5       P9-27, gpio3[19], 0x1a4, Mode 5
6       P9-41, gpio3[20], 0x1a8, Mode 5 
7       P9-25, gpio3[21], 0x1ac, Mode 5 
8       
9       
10      
11      
12      
13      
14      P8-16, gpio1[14], 0x038, Mode 6
15      P8-15, gpio1[15], 0x03c, Mode 6
16      P9-24, gpio0[15], 0x0184, Mode 6 (HDMI, LCD) 
16      P9-41, gpio3[20], 0x164, Mode 5 

Bit     pr1_pru1_pru_r30_? (out)
0       P8-45, gpio2[6], 0x0a0, Mode 5 (HDMI, LCD)
1       P8-46, gpio2[7], 0x0a0, Mode 5 (HDMI, LCD) 
2       P8-43, gpio2[8], 0x0a8, Mode 5 (HDMI, LCD)
3       P8-44, gpio2[9], 0x0ac, Mode 5 (HDMI, LCD)
4       P8-41, gpio2[10], 0x0b0, Mode 5 (HDMI, LCD)
5       P8-42, gpio2[11], 0x0b4, Mode 5 (HDMI, LCD)
6       P8-39, gpio2[12], 0x0b8, Mode 5 (HDMI, LCD)
7       P8-40, gpio2[13], 0x0bc, Mode 5 (HDMI, LCD)
8       P8-27, gpio2[22], 0x0e0, Mode 5 (HDMI, LCD)
9       P8-29, gpio2[23], 0x0e4, Mode 5 (HDMI, LCD)
10      P8-28, gpio2[24], 0x0e8, Mode 5 (HDMI, LCD)
11      
12      P8-21, gpio1[30], 0x080, Mode 5 (HDMI, LCD)
13      P8-20, gpio1[31], 0x084, Mode 5 (HDMI, LCD)
14      
15      
16      

Bit     pr1_pru1_pru_r31_?  (in)
0       P8-45, gpio2[6], 0x0a0, Mode 6 (HDMI, LCD)
1       P8-46, gpio2[7], 0x0a0, Mode 6 (HDMI, LCD)
2       P8-43, gpio2[8], 0x0a8, Mode 6 (HDMI, LCD)
3       P8-44, gpio2[9], 0x0ac, Mode 6 (HDMI, LCD)
4       P8-41, gpio2[10], 0x0b0, Mode 6 (HDMI, LCD)
5       P8-42, gpio2[11], 0x0b4, Mode 6 (HDMI, LCD)
6       P8-39, gpio2[12], 0x0b8, Mode 6 (HDMI, LCD)
7       P8-40, gpio2[13], 0x0bc, Mode 6 (HDMI, LCD)
8       P8-27, gpio2[22], 0x0e0, Mode 6 (HDMI, LCD)
9       P8-29, gpio2[23], 0x0e4, Mode 6 (HDMI, LCD)
10      P8-28, gpio2[24], 0x0e8, Mode 6 (HDMI, LCD)
11      
12      P8-21, gpio1[30], 0x080, Mode 6 (HDMI, LCD)
13      P8-20, gpio1[31], 0x084, Mode 6 (HDMI, LCD)
14      
15      
16      P9-26, gpio1[29], 0x180, Mode 6
------------------------------------------------------------------------------
Beaglebone Black Kernel 3.8 Device Tree Overlay - map GPIO pins directly to PRU 
R30 or R31
Create overlay file /lib/kernel/myoverlay-00A0.dts using contents below.
Compile using device tree compiler (dtc):
#sudo apt-get install device-tree-compiler
#sudo dtc -O dtb -o /lib/firmware/myoverlay-00A0.dtbo -b 0 -@ 
/lib/firmware/myoverlay-00A0.dts
Modify cape manager file in /etc/default/capemgr to load overlay during boot:
#sudo nano /etc/default/capemgr
CAPE=myoverlay
Edit /etc/modules and append text
#sudo nano /etc/modules
uio_pruss
------------------------------------------------------------------------------
/dts-v1/;
/plugin/;

/ {
        compatible = "ti,beaglebone", "ti,beaglebone-black";

        /* identification */
        part-number = "MYOVERLAY";
        version = "00A0";

        /* state the resources this cape uses */
        exclusive-use =
                // PRU resources used
                "pruss",
                "pru0",
                // PRU Input pins
                "P8.16","pr1_pru0_pru_r31_14",  // PIN Name and the PRU port it 
maps to (see table above)
                // PRU Output pins
                "P9.31","pr1_pru0_pru_r30_0";

    // MUX Bit Maps:
    // 0x40 = slow slew (0 = fast slew)
    // 0x20 = input (0 = output)
    // 0x10 = pullup, 0x08 = disabled (0 = pulldown)
    // 0x01 to 0x07 = mode 1 to 7
    fragment@8 {
        target = <&am33xx_pinmux>;
        __overlay__ {

            pruss_pins: pruss_pins {
                pinctrl-single,pins = <
                    0x038 0x36  // P8_16, gpio3[14] mode 6, input pull-up
                    0x190 0x15  // P9_31 gpio1[19] mode 5, output, pull-down
                >;
            };
        };
    };

    fragment@10 {
        target = <&pruss>;
        __overlay__ {
            status = "okay";   // This enables the PRU
            pinctrl-names = "default";
            pinctrl-0     = <&pruss_pins>; // This uses our custom mapping (see 
above definition)

            // This is for documentation only.  You can see the pin mappings by:
            // sudo cat /sys/kernel/debug/gpio
            any_name1 {  // Grouping of pins under this name
                pin-names     = "Input pin description";     // one name per 
pin defined in gpios.  Multiple entries are comma seperated;   
                gpios         = <&gpio4 14 1>; // &gpio? (One based: 1-4 
instead of 0-3) bit(0-31) input(1)/output(0).  Multiple entries seperated by a 
space 
            };            
            any_name2 { 
                pin-names     = "Output pin description";        
                gpios         = <&gpio2 19 0>; 
            };            
        };
    };
};
------------------------------------------------------------------------------
PRU C Code – compile using clpru & hexpru
------------------------------------------------------------------------------
// C library Installed by: apt-get install am335x-pru-package 
ti-pru-cgt-installer
#include <stdint.h> 
// PRU support libraries Installed from home directory with: git clone 
git://git.ti.com/pru-software-support-package/pru-software-support-package.git 
pru_support
#include <pru_cfg.h> 

#define PRU0_ARM_INTERRUPT 19  // Interrupt used to signal to host we have 
halted

volatile register uint32_t __R30;  // Output pins
volatile register uint32_t __R31;  // Input pins

// Mapping Constant table register to variable
volatile pruCfg CT_CFG __attribute__((cregister("CFG", near), peripheral));  // 
PRU CFG register pointer loaded from constants table (see lnk.cmd)

int main(void) {
    // Enable OCP master ports - this enables pinmux pins to R30 & R31 & host 
ram access (all the BBB GPIO ports & such)
    CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;

    // Do work - write your code here

    // Signal the process has completed (this will wake up the loader to tell 
it work is done)
    __R31 = (__R31 & ~0xff) | (PRU0_ARM_INTERRUPT+16);
    return 0;
}
------------------------------------------------------------------------------
lnk.cmd – linker command file defines physical address mappings
------------------------------------------------------------------------------
-cr
-stack 0x100
-heap 0x100

MEMORY
{
      PAGE 0:
        PRUIMEM         : org = 0x00000000 len = 0x00002000  /* 8kB PRU0 
Instruction RAM */

      PAGE 1:
        PRUDMEM         : org = 0x00000000 len = 0x00002000  /* 8kB PRU Data 
RAM 0 */
        SHAREDMEM       : org = 0x00010000 len = 0x00003000  /* 12kB Shared RAM 
*/
        PRU0_CTRL       : org = 0x00022000 len = 0x00000030
        PRU1_CTRL       : org = 0x00024000 len = 0x00000030

        /* Constant Table Memory directives. */

        INTC            : org = 0x00020000 len = 0x00001504     CREGISTER=0
        DMTIMER2        : org = 0x48040000 len = 0x00000100     CREGISTER=1
        I2C1            : org = 0x4802A000 len = 0x00000100     CREGISTER=2
        ECAP            : org = 0x00030000 len = 0x00000100     CREGISTER=3
        CFG             : org = 0x00026000 len = 0x00000100     CREGISTER=4
        MMCHS0          : org = 0x48060000 len = 0x00000100     CREGISTER=5
        MCSPI0          : org = 0x48030000 len = 0x00000100     CREGISTER=6
        UART0           : org = 0x00028000 len = 0x00000100     CREGISTER=7
        MCASP0_DMA      : org = 0x46000000 len = 0x00000100     CREGISTER=8
        GEMAC           : org = 0x4A100000 len = 0x00000100     CREGISTER=9
        RSVD10          : org = 0x48318000 len = 0x00000100     CREGISTER=10
        UART1           : org = 0x48022000 len = 0x00000100     CREGISTER=11
        UART2           : org = 0x48024000 len = 0x00000100     CREGISTER=12
        RSVD13          : org = 0x48310000 len = 0x00000100     CREGISTER=13
        DCAN0           : org = 0x481CC000 len = 0x00000100     CREGISTER=14
        DCAN1           : org = 0x481D0000 len = 0x00000100     CREGISTER=15
        MCSPI1          : org = 0x481A0000 len = 0x00000100     CREGISTER=16
        I2C2            : org = 0x4819C000 len = 0x00000100     CREGISTER=17
        EHRPWM1         : org = 0x48300000 len = 0x00000100     CREGISTER=18
        EHRPWM2         : org = 0x48302000 len = 0x00000100     CREGISTER=19
        EHRPWM3         : org = 0x48304000 len = 0x00000100     CREGISTER=20
        MDIO            : org = 0x00032400 len = 0x00000100     CREGISTER=21
        MBX0            : org = 0x480C8000 len = 0x00000100     CREGISTER=22
        SPINLOCK        : org = 0x480CA000 len = 0x00000100     CREGISTER=23
/*      PRU0_1          : org = 0x00000000 len = 0x00000100     CREGISTER=24
        PRU1_0          : org = 0x00000000 len = 0x00000100     CREGISTER=25 */
        IEP             : org = 0x0002E000 len = 0x0000031C     CREGISTER=26
/*      MII_RT          : org = 0x00032000 len = 0x00000100     CREGISTER=27
        SHARED_RAM      : org = 0x00000000 len = 0x00000100     CREGISTER=28 */
        TPCC            : org = 0x49000000 len = 0x000010A0     CREGISTER=29
        L3OCMC          : org = 0x40000000 len = 0x00010000     CREGISTER=30
        DDR             : org = 0x80000000 len = 0x00000100     CREGISTER=31
}

SECTIONS {
        /* Forces _c_int00 to the start of PRU IRAM. Not necessary when loading
           an ELF file, but useful when loading a binary */
        .text:_c_int00* >  0x0, PAGE 0

        .text           >  PRUIMEM, PAGE 0
        .stack          >  PRUDMEM, PAGE 1
        .bss            >  PRUDMEM, PAGE 1
        .cio            >  PRUDMEM, PAGE 1
        .data           >  PRUDMEM, PAGE 1
        .switch         >  PRUDMEM, PAGE 1
        .sysmem         >  PRUDMEM, PAGE 1
        .cinit          >  PRUDMEM, PAGE 1
        .rodata         >  PRUDMEM, PAGE 1
        .rofardata      >  PRUDMEM, PAGE 1
        .farbss         >  PRUDMEM, PAGE 1
        .fardata        >  PRUDMEM, PAGE 1
        .PRU0_CTRL      >  PRU0_CTRL, PAGE 1
        .resource_table >  PRUDMEM, PAGE 1
}
------------------------------------------------------------------------------
bin.cmd – used by hexpru to generate text.bin and data.bin
------------------------------------------------------------------------------
-b
-image
ROMS {
                PAGE 0:
                text: o = 0x0, l = 0x1000, files={text.bin}
                PAGE 1:
                data: o = 0x0, l = 0x1000, files={data.bin}
}
------------------------------------------------------------------------------
Compile command:
------------------------------------------------------------------------------
clpru -i /usr/share/ti/cgt-pru/lib -i ~/pru_support/include -i . 
--endian=little --define am3359 --define pru0 --silicon_version=3 -o1 source.c 
-z lnk.cmd -o source.out -m source.map
hexpru bin.cmd pru_cblink.out
------------------------------------------------------------------------------
pru_loader.c – host side code to load the text.bin image to pru 0.  Compile 
with: gcc -o pru_loader pru_loader.c -lprussdrv
Run from linux command prompt to deploy text.bin to PRU 0 and run it (text.bin 
must be in the current directory)
------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>

#include <prussdrv.h>
#include <pruss_intc_mapping.h>

#define PRU_NUM         0
#define AM33XX

int main (int argc, char **argv)
{
    unsigned int ret;
    tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;

    /* Initialize the PRU */
    prussdrv_init ();

    /* Open PRU Interrupt */
    ret = prussdrv_open(PRU_EVTOUT_0);
    if (ret) {
        printf("prussdrv_open open failed\n");
        return (ret);
    }

    /* Get the interrupt initialized */
    prussdrv_pruintc_init(&pruss_intc_initdata);

    /* Execute example on PRU */
    prussdrv_exec_program (PRU_NUM, "./text.bin");

    /* Wait until PRU0 has finished execution */
    prussdrv_pru_wait_event (PRU_EVTOUT_0);
    prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);

    /* Disable PRU and close memory mapping*/
    prussdrv_pru_disable (PRU_NUM);
    prussdrv_exit ();

    return(0);
}

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to