PRU C Project - from device tree to program execution

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.

I couldn’t install am335x-pru-package and ti-pru-cgt-installer from terminal, it gave the following errors when I tried,
root@arm:/home/ubuntu# apt-get install am335x-pru-package ti-pru-cgt-installer
Reading package lists… Done
Building dependency tree
Reading state information… Done
E: Unable to locate package am335x-pru-package
E: Unable to locate package ti-pru-cgt-installer

I am using ubuntu 14.04 on BBB with following kernel
Linux arm 3.8.13-bone64 #1 SMP Fri Aug 22 00:19:37 UTC 2014 armv7l armv7l armv7l GNU/Linux

I have installed am335x-pru-package manually with following steps

cd pru_sw/app_loader/interface/
gcc -I. -Wall -I…/include -c -fPIC -O3 -mtune=cortex-a8 -march=armv7-a -shared -o prussdrv.o prussdrv.c
gcc -shared -o libprussdrv.so prussdrv.o

Copy the driver and headers to system folders

sudo cp libprussdrv.so /usr/lib/
sudo cp …/include/*.h /usr/include/

Now build the assember

cd …/…/utils/pasm_source
./linuxbuild

Copy the assembler to system

sudo cp …/pasm /usr/bin/

Installed ti-cgt-pru-installer with following steps

root@arm:/home/ubuntu# wget --no-check-certificate http://software-dl.ti.com/codegen/esd/cgt_public_sw/PRU/2.1.0/ti_cgt_pru_2.1.0_armlinuxa8hf_busybox_installer.sh

root@arm:/home/ubuntu# chmod 766 ti_cgt_pru_2.1.0_armlinuxa8hf_busybox_installer.sh

root@arm:/home/ubuntu# ./ti_cgt_pru_2.1.0_armlinuxa8hf_busybox_installer.sh

Sorry, i haven't yet started pushing these to ubuntu. The ppa on
repos.rcn-ee.net is now live for ubuntu (trusty/14.04) so you'll start
seeing these packages showing up.. (for ubuntu, i'm not planning on
doing non-lts's)

Regards,

Sorry, I didn’t get your point, are the packages available for ubuntu 14.04? The version on my bbb is ubuntu trusty 14.04, I guess it is lts version. Still I get the same error ‘Unable to locate package’ for both the packages am335x-pru-package and ti-pru-cgt-installer.

Well:

sudo apt-get update ; sudo apt-get install am335x-pru-package

Should work right "now", give me another 10minutes for the other package..

Regards,

and:

sudo apt-get update ; sudo apt-get install ti-pru-cgt-installer

should work now too..

Regards,

yeah, its working now :slight_smile:

Hey Peter,

thank you for your guide.

Im a bit stuk with my own projekt. I wrote and succesfully debugged some code for reading from an ADC with CCS and a JTAG probe. I also checked the shared ram mecanism for the host/PRU communication by manipulating it via Memory Browser. It works well from the PRU side. I also wired some LED’ s for debugging for when I’m trying out with the Linux (Ubuntu).
So as I can see i have done all the steps you mentioned below. But when I load the PRU-Programm with "prussdrv_exec_program (PRU_NUM, “./text.bin”); " nothing is happening with the PRU. First line in the the program should switch the Debug LED’s from previus state.
The right pinmuxxing can be seen when applying the devicetree overlay - one LED lights up as experienced with CCS and JTAG manipulating the control module.

So I wonder wy my PRU doesnt seem to run the program. Do you know any way to look inside the PRU from linux?

with kind regards
Philipp

Um, and what about the data.bin file?
I see you only use the text.bin file.

I don't know of a way to debug the PRU.
I'd start with a very simple C program.
You can start with setting the interrupt telling the loader the program is halting.
Next, enable the OCP, then go into a tight loop toggling a pin.

    // 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;

That should let you know the PRU is loaded and running and it is able to access pins.

If all your variables are in the .bss segment (uninitialized variables) then you only need to load the text.bin file.

Okay, now i followed your Instructions with a clean new flashed Ubuntu 14.04 kernel 3.8.13 - aaand it works. :slight_smile:
I also can toggle some LED’ s.

But I stumbelt over some difrences toward your guide with Debian regarding the device tree stuff.

Create overlay file /lib/kernel/myoverlay-00A0.dts using contents below.

No /lib/kernel here, but cp the .dtbo to /lib/firmware did the job.

#sudo nano /etc/default/capemgr
CAPE=myoverlay
Edit /etc/modules and append text
#sudo nano /etc/modules
uio_pruss

Has no effekt in my setup and seems not te be needet.
I had to
echo myoverlay > SLOTS=/sys/devices/bone_capemgr.*/slots
to get the PRU drv and the Pinmux working. But first there is to kill the HDMI cape by adding “optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN” on

sudo nano /boot/uEnv.txt

Any idear where this diffrence comes from? Is the capemanagement that diffrent from Debian? I thought they were close relatives?!

In this context is also to mention that it seems important to use kernel 3.8 and not 3.14. With the newest Ubuntu immage I missed “/sys/devices/bone_capemgr.*/

I will use this as a starting point and port my “problem” program step by step. I will soon maybe find out what my mistake was.

As a contribution for your work and for the help of others I atached my source from the LED Example.

with kind regards
Philipp

PRU_C_example_blinkLED.zip (5.98 KB)

There hardware support for debugging the CPU in the AM335x, and a few programs that have support for debugging. Nothing as fancy as gdb, but it can be helpful. I mostly use the pru_debug setup from Machinekit, which basically allows viewing register contents while single-stepping and pausing (but no breakpoints).

The programs I know about are listed here:

http://blog.machinekit.io/2013/06/beagle-bone-pru-links.html

...the list is a bit dated, if anyone knows of other tools (or a better list), let me know.

Okay, now i followed your Instructions with a clean new flashed Ubuntu 14.04 kernel 3.8.13 - aaand it works. :slight_smile:
I also can toggle some LED’ s.

Well, if you were using a 3.14.x kernel, that would explain it. There is no capemgr in 3.14.x

Any idear where this diffrence comes from? Is the capemanagement that diffrent from Debian? I thought they were close relatives?!

Ubuntu is based on Debian. Debian uses SYSV init daemon where Ubuntu uses upstart. Starting with Jessie, it looks like Debian will be moving to systemd, and I’ve heard “talk” that Canonical is considering moving to systemd as well. Also, packages are somewhat different. Where Debian sticks with the “tried and true” approach, Ubuntu has a much more “bleeding-edge” package list. So, with Ubuntu you get newer packages, but sometimes at the cost of reliability. This is not to say that packages in Ubuntu are unstable / unreliable, they’re just not tested as rigorously as is done in Debian.

As to where your problem is coming from ? No idea, not enough information given. I’m guessing you were not using a 3.8.x kernel with Debian.

everything went fine, except I get “prussdrv_open open failed” when I run the pru_loader

Hi Pete,

What kernel are you on?
uname -a

The loader will fail if the kernel module is not loaded or the device tree does not enable the PRU device.

I also have a typo in my notes that the overlay should go in /lib/kernel
It should go in /lib/firmware

Sorry for the confusion.
It should go in /lib/firmware

Linux beaglebone 3.8.13-bone68 #1 SMP Sat Nov 22 02:12:03 UTC 2014 armv7l GNU/Linux
No problem, I really appreciate your posting this. I would love to see more examples using it. I need to program a specific timing sequence for a TI led

If your need a timer, each PRU has a ECAP module that can work as a PWM.
You can use the ECAP module's timer to set a flag each time period for timing loops.
I set a timer period of 1/100th second and the PRU runs a tight loop running a stepper motor.
After each step, it waits for the timer to reset, clears the overflow flag and does the next step.
That way the main loop has a fixed delay of 1/100th second per step.