Surefire PRU - Setup.

Hi All,

Thanks for all the previous help, I am happy to report that I have a script that will download, install , configure a beaglebone for working pru support. It does this at the most basic level. One blinking LED.

Here is how to get a surefire setup if you are just learning about the PRU and want to know you have a working base system. Once you have a working base you can build your knowledge from there and understand which pieces do what.

  1. Get this image : https://debian.beagleboard.org/images/bone-debian-8.4-lxqt-4gb-armhf-2016-05-13-4gb.img.xz
    install it on SD card / flash it to emmc. It is the release I used.

  2. Login into your beaglebone black and run:
    git clone https://github.com/Neil-Jubinville/pru

  3. Then cd pru followed by ./prep_pru.sh and that will kickoff the automatic setup.

You can view the script details here: https://github.com/Neil-Jubinville/pru/blob/master/prep_pru.sh

In a nutshell - it upgrades the kernel to a know working version, rebuilds device tree overlays, disables cape universal, enables PRU support, loads the uio_pruss module, downloads examples and sets one of them to run at start up. It will reboot your beaglebone so make your you are watching it start so you can see it blink.

To see it work, ultimately you will need an LED hooked up to P9.27 to ground (and an inline resister likely).

Thx,

Neil

Many thanks for the script. The blinking-led notes for UIO now point to it:
https://github.com/dinuxbg/pru-gcc-examples/tree/master/blinking-led#uio-host-driver
Regards,
Dimitar

I did notice a few error messages using the OP’s disk image + script…
While the script ran, I saw these errors scroll by – is this something I should ignore?

I think the solution here would be to include an "apt-get" in the prep script
     before this point to install the correct linux-headers-x.x.xxxx package, based
     on whatever new kernel was found during the upgrade process.

     In my case, after the reboot, I noticed the active kernel was the new one
     the prep script downloaded (4.4.27), as reported by 'uname -r'..
     so this seemed to be the appropriate command to install those headers:

  apt-get install linux-headers-`uname -r`

     I'll see if I can work that into the prep_pru.sh script, and supply a patch.
     I imagine I'll have to replace the `uname -r` with the downloaded linux image value,
     as at that time the script is running, 'uname -r' will report the wrong kernel version.

     I should probably re-do the imaging procedure, and re-run the prep script
     from scratch with the change applied, as I'm not sure the prep_pru.sh script
     is designed to handle being run more than once (at least, not in its current
     incarnation, as it appears to append to .bashrc and /etc/rc.local without checking
     if the mods are already there..)

     Will try to follow up with what I find..

Hmm, so after the new kernel headers were installed, I verified
    there's now a 'build' link in the modules directory for that kernel version
    that wasn't there before:

# ls -la /lib/modules/4.4.*/build
lrwxrwxrwx 1 root root 36 Oct 26 2016 /lib/modules/4.4.27-ti-r62/build -> /usr/src/linux-headers-4.4.27-ti-r62 <--
lrwxrwxrwx 1 root root 35 May 5 2016 /lib/modules/4.4.9-ti-r25/build -> /usr/src/linux-headers-4.4.9-ti-r25

    ..which is good, because I know building device drivers need that link
    to exist.

    So I then retried making the project the prep_pru.sh command failed to build,
    but still getting these weird errors:

root@beaglebone:~# export DTB=~/dtb-rebuilder/src/arm
root@beaglebone:~# cd /root/dtb-rebuilder/
root@beaglebone:~/dtb-rebuilder# make clean
  CLEAN src/arm
root@beaglebone:~/dtb-rebuilder# make
  DTC src/arm/am437x-gp-evm.dtb
FATAL ERROR: Unrecognized check name "unit_address_vs_reg" <--
Makefile:136: recipe for target 'src/arm/am437x-gp-evm.dtb' failed <--
make[1]: *** [src/arm/am437x-gp-evm.dtb] Error 1
Makefile:84: recipe for target 'all_arm' failed
make: *** [all_arm] Error 2

    Does anyone know the solution for that?

sudo apt update
sudo apt install device-tree-compiler --reinstall

Which will install "mainline" dtc 1.4.4, no more of our dtc 1.4.1 +
patches.. It's all mainline dtc now!! :wink:

Regards,

Google searches weren't helping me solve that one, so I dug into
    the Makefile a bit.

    Short answer seems to be to change this line in the Makefile:

-DTC_FLAGS += -Wno-unit_address_vs_reg
+#DTC_FLAGS += -Wno-unit_address_vs_reg

    ..when I did that, it breezed through the build without errors.

    Will move onward to try to get an error free result.

DIGRESSION

Thanks Robert, so I take it you might be saying that this command:

apt install device-tree-compiler --reinstall

…could maybe replace all the following code in the OP’s “prep_pru.sh” script:

root@beaglebone:~/dtb-rebuilder# make
  DTC src/arm/am437x-gp-evm.dtb
FATAL ERROR: Unrecognized check name "unit_address_vs_reg" <--
Makefile:136: recipe for target 'src/arm/am437x-gp-evm.dtb' failed <--
make[1]: *** [src/arm/am437x-gp-evm.dtb] Error 1
Makefile:84: recipe for target 'all_arm' failed
make: *** [all_arm] Error 2

    Does anyone know the solution for that?

    Google searches weren't helping me solve that one, so I dug into
    the Makefile a bit.

    Short answer seems to be to change this line in the Makefile:

-DTC_FLAGS += -Wno-unit_address_vs_reg
+#DTC_FLAGS += -Wno-unit_address_vs_reg

    ..when I did that, it breezed through the build without errors.

    Will move onward to try to get an error free result.

DIGRESSION

    Regarding figuring out how to solve the above, it was obvious 'make'
    wasn't showing the commands being used to build the targets, so I wanted
    to see what was going on when it failed.

    The Makefile comments indicate there's some kind of convention to keeping
    the noise of the build down, using two Makefile variables 'quiet' and 'Q'.

    I found I could get make to show the commands being executed by changing
    this section of the Makefile:

ifeq ($(KBUILD_VERBOSE),1)
   quiet =
   Q =
else
- quiet=quiet_
- Q = @
+ quiet=
+ Q =
endif

This is just equivalent to 'make V=1'

Actually this is now fixed with U-Boot overlays. (I just added the pru
options a week or two back)

http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays

and i've now just pushed the pru options:

http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_PRU_Options

No rebuilding, just /boot/uEnv.txt editing..

From /boot/uEnv.txt

###PRUSS OPTIONS
###pru_rproc (4.4.x-ti kernel)
uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-4-TI-00A0.dtbo
###pru_uio (mainline kernel)
#uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo

pru_rproc is enabled by default, just comment the first and un-comment
the second and reboot..

Regards,

OK, things went pretty smoothly after that; I now have
a blinking LED via PRU control. W00t!

A DISK IMAGE WITH EVERYTHING APPLIED

Well device tree overlay source files are not C, or assembly either.
Although, you can use C syntax highlighting in your text editor of choice
to make your life easier. I tend to view overlay source files more as
something like xml, or some form of a markup language. Understanding the
source files though just takes time, and knowledge of how pin-muxing, and
several hardware aspect on this platform works.

How, I learned how the source files work, was to take one of the Universal
IO overlay source files, and deleted everything in it except the main
structure, and a single pin. At this point, you see all the different modes
a pin can function as, and things become a bit clearer. It also helps to
understand the hardware that you're trying to configure. Some of the
simpler overlay source files such as for RTC, or 1-wire. Studying these
should help one understand some things too. Such as how to load a driver
from an overlay file, or how to configure an I2C device bus address from an
overlay file. In the end it just takes time.

So a lot of text there to "Wade" through so I'll try to answer the
questions you have in order. Without the "Sea of text" :wink:

I think Universal IO, which includes the shell script config-pin is a
really cool tool for getting started. Especially, when all you want to do
is get down to writing code for the hardware. However, at the same time I
strongly feel that it is not a permanent solution for configuring the
hardware, especially for a production system. For many reasons, partly
because there can be some glitches, and partly because now we have uboot
overlays, that one can load through the second stage bootloader. Which also
means, for a production system you can have your pins, and hardware
configured exactly how it needs to be. Prior to Linux being up and running.
If you script config-pin, this has to be done after Linux is running.

And . . actually, I think that was your only questions. I would like to add
some things however. Let's take this:
/* P8_07 (ZCZ ball R7 ) */
P8_07_default_pin: pinmux_P8_07_default_pin {
pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */

This is just part of configuring a pin. Obviously for P8_07. So for pins
that can be operating in GPIO mode. This will be the first entry in any of
the universal io overlay files. The first line after the comment is pretty
much just a "#define", or a "prototype" definition of the pin in question.
Kind of like prototyping a function in C. The second line after the comment
is the actual pin information. 0x090 being the pin, which is a kernel pin
identifier I think. The second number 0x37 is the mux, and pullup mode( put
simply ). You can read the TRM and get a much better explanation of the mux
/ pullup mode register.

Anyway, check this out.
https://github.com/beagleboard/bb.org-overlays/blob/master/include/dt-bindings/board/am335x-bbw-bbb-base.h#L17

The point here, if you #include Robert's header file, you can use all the
BONE_Px_xx #defines in place of the actual "kernel pin value". Which can(
does for me ) remove a lot of tedious work trying to memorize, or digging
through documentation just to get a pin to work the way you want.
Additionally, there is another header file, which #define mux, and other
register modes. These two headers alone can take a lot of learning pressure
off your shoulders. Then if like me, you do know C very well ( I'm assuming
you do ), you can read through these source header files, along with the
TRM, or whatever documentation that makes the most sense to you. Suddenly,
that light at the end of the tunnel starts to appear. Pullup modes, you
simply OR together ( FOO | BAR )

And yeah, I guess there was another question in there. Yes, any dt file
starting with "univ "including "univ" or "universal" will be a universal IO
related overlay. Some originally written by Charles S( Mug cooler :wink: ). or
Robert Nelson.

Anyway, right now I am kind of busy with work related code. Bu maybe,
sometime soon I can make a working device tree overlay, with an explanation
of the file for one pin. Put it on my blog page, and link back to it. The
problem with that, is it often takes more work to create a post, than it
does to actually just write the code, and *maybe* explain it, if needed.

So a lot of text there to “Wade” through so I’ll try to answer the questions you have in order. Without the “Sea of text” :wink:

No walls of text; OK, will try to keep it shorter.

I think Universal IO, which includes the shell script config-pin is a really cool tool for getting started. Especially, when all you want to do is get down to writing code for the hardware. However, at the same time I strongly feel that it is not a permanent solution for configuring the hardware, especially for a production system. For many reasons, partly because there can be some glitches, and partly because now we have uboot overlays, that one can load through the second stage bootloader. Which also means, for a production system you can have your pins, and hardware configured exactly how it needs to be. Prior to Linux being up and running. If you script config-pin, this has to be done after Linux is running.

Definitely going to consider those concerns, and keep an eye out for them in my setup.

In my case I envisioned config-pin in /etc/rc.local to run once, and be able to run it in real time so field personnel can change/experiment. For instance to make a change for a pin to have a pull-up instead of without one.

I read dev tree files can only be loaded on boot (?), IIRC the binary is loaded ahead of the kernel in ram by the boot loader, so I think dev cycle for dev tree files is harder for the field person, as a recompile + reboot is needed each time. It’s hard enough getting field people to just edit config files.

I’d also like to avoid field people seeing two ways of doing things. During support calls, one could compete with the other in unpredictable ways… better to provide only one way to do something.

Let’s take this:
/* P8_07 (ZCZ ball R7 ) */
P8_07_default_pin: pinmux_P8_07_default_pin {

pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */

This is just part of configuring a pin. Obviously for P8_07. So for pins that can be operating in GPIO mode. This will be the first entry in any of the universal io overlay files. The first line after the comment is pretty much just a “#define”, or a “prototype” definition of the pin in question. Kind of like prototyping a function in C. The second line after the comment is the actual pin information. 0x090 being the pin, which is a kernel pin identifier I think. The second number 0x37 is the mux, and pullup mode( put simply ). You can read the TRM and get a much better explanation of the mux / pullup mode register.

I see – I’ll do some reading to try to figure out what actually parses this info on boot, as I like to understand what tool/driver is looking at the file I’m configuring, in case I need to RTSL to figure out what’s wrong when errors occur. If it’s a built in kernel driver (cape driver maybe?)

I did read petazzoni’s “Device Tree For Dummies” last night to try to determine the big picture, but it really lost me somewhere in the middle. Just too much… stuff… I didn’t want to know or track down. It assumes a knowledge of the modern kernel terminology that I just don’t have.

Anyway, check this out. https://github.com/beagleboard/bb.org-overlays/blob/master/include/dt-bindings/board/am335x-bbw-bbb-base.h#L17 The point here, if you #include Robert’s header file, you can use all the BONE_Px_xx #defines in place of the actual “kernel pin value”.

I see, so I take it these two lines would be equivalent, the lower one my construction:

pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive /
pinctrl-single,pins = <BONE_P8_07 0x37>; }; /
Mode 7, Pull-Up, RxActive */

…yes, symbols would be better than hex.

Which can( does for me ) remove a lot of tedious work trying to memorize, or digging through documentation just to get a pin to work the way you want. Additionally, there is another header file, which #define mux, and other register modes. These two headers alone can take a lot of learning pressure off your shoulders. Then if like me, you do know C very well ( I’m assuming you do ), you can read through these source header files, along with the TRM, or whatever documentation that makes the most sense to you. Suddenly, that light at the end of the tunnel starts to appear. Pullup modes, you simply OR together ( FOO | BAR )

Yes, it’d be much easier on the eyes if 0x37 could be a few macros OR’ed together instead. Would those values be found in, just guessing: bb.org-overlays/include/dt-bindings/pinctrl/omap.h at master · beagleboard/bb.org-overlays · GitHub ? (Same project, different file)

I wouldn’t mind magic numbers if the reference table was in the same document (ascii art preferred to a link, as links go stale).

For fun, I tried to determine what 0x37 means. You referred to the “TRM”, which I take to mean the Sitara Tech Ref Manual (rev c)… that ~2300 page monster! :wink: Spent a bit of time in there, but was unable to figure out which table was relevant.

At first I thought maybe Table 1-236 “PINCTRLn Register Field Descriptions” and Table 1-237 “PINCTRLn Register Pin Multiplexing”, but the bits didn’t match up. I searched for “mux mode” but that only appeared in the HD video section, and searching for “RxActive” (from the .dts file’s comment) without any match at all.

I googled around and found this spreadsheet which references the AM335x Datasheet, but the link is dead. I found a working link, but was unable to find the table. The speadsheet seems to show some info, so from that I determined 0x37 means “an output with a pullup”, which matches the comment. The spreadsheet doesn’t say what the lower 3 mode bits are for though. Seems like they weren’t sure, as it was left blank.

Anyway, right now I am kind of busy with work related code. Bu maybe, sometime soon I can make a working device tree overlay, with an explanation of the file for one pin. Put it on my blog page, and link back to it. The problem with that, is it often takes more work to create a post, than it does to actually just write the code, and maybe explain it, if needed.

Sounds good – If you do, I do think comments and inline comment ascii-art tables would help folks. I spent an hour or two floundering around, still not 100% sure what I found.

I do see one of the TI datasheets referred to a windows utility to calculate the pin mux values… seems that should really be an html/javascript so it can run platform independent, and can be referenced with a link or included locally as an html/js pair. But mainly I don’t have a windows box handy ATM.

Oh, OK, I think “the TRM” must refer to this one instead (I think), while bigger (4300 pages), it’s a bit easier on my eyes, as it seems to have info more relevant to a software person than this other one I was looking at which seems more hardware somehow. I’m still a bit new to this all.

The latter was the first link google returned when searching for “beaglebone technical reference manual”… they call it the ‘system technical reference manual’, but seems to be a different thing.

The former also has a good description of the on-chip hardware peripherals (PWM, UART, etc).

No, prior to uboot overlays, overlays were loaded from the initrd, at best. Also we need to understand that the board file(also an overlay of sorts - but required )is seperate from all this discussion.

I do not understand why you would have “field people” playing around with hardware overlays though. Once your hardware is finalized, it should never change. Which is one small reason why I personally find Universal IO unnecessary for my own purposes.

The problem I’ve seen with explanations, and documentation on device tree, is that no one explains it really well. Additionally, as a new player into device tree overlays. Its not clear where to get information from. See, you need to understand the pin-ctrl subsystem, gpio subsystem . . . list goes one, and on . . .A lot of this information has to be found from the Linux kernel source documentation.HOWEVER, you do not necessarily need to memorize all of this. We ( programmers ) just need a reference that does not goes on, and on for days about silly details we do not need to know to get our jobs done. Nothing like this exists.

Anyway, in order to learn, you need to “do”.

System reference manual SRM, Technical reference manual TRM.

I decided not to copy what was in the TRM into the SRM. That is why the SRM is specific to the BBB. And the TRM gets updated failry often by TI.

Gerald

Greg,

You know what. If I were you, I would get a Beaglebone black or green, and make learning about it your favorite hobby. This way, you could experiment with various things, until you’re happy with what you end up using.

If memory is serving me correctly yes, you’re using a blue. Yes, yes, but the hardware is largely the same, and most if not all the software will be exactly the same.

So yes, buy a beaglebone, take it home, and start experimenting. Then I would probably not worry about HAVING to have hardware connected up with it. There is a lot you can do by experimenting with software only. How, and where to explore the GPIO subsystem. Which will then lead to being able to tell if you’ve configured your overlay file at boot correctly. etc, etc.