UIO and Pruss

I’ve got a slight issue–

On my hardware:

root@localhost:/sys/class/uio# uname -r
3.14.54-ti-rt-r77

root@localhost:/sys/class/uio# lsmod
Module Size Used by
usb_f_ecm 7909 1
g_ether 1802 0
usb_f_rndis 17719 2 g_ether
u_ether 10156 3 usb_f_ecm,g_ether,usb_f_rndis
libcomposite 38699 3 usb_f_ecm,g_ether,usb_f_rndis
uio_pruss 2372 0
omap_serial_rs485 16943 0
root@localhost:/sys/class/uio#

And finally…

root@localhost:/sys/class/uio# ls
root@localhost:/sys/class/uio#

So after installing uio_pruss nothing shows up in the uio directory for it.

Any ideas?

Thanks

I’ve just started learning about uio myself, but my guess is that you’ve loaded the uio_pruss module manually. Yes ? So with a kernel that has cape manager . . .

$ uname -r
4.1.9-bone-rt-r16
$ lsmod |grep pru

$ sudo sh -c “echo ‘pru_enable’ > /sys/devices/platform/bone_capemgr/slots”
$ lsmod |grep pru
uio_pruss 4143 0
uio 8006 2 uio_pruss,uio_pdrv_genirq

So, anyway, the module you’re missing is uio_pdrv_genirq but this minimal generic driver module needs parameters when loaded. That much I know, but what I do not know is how to load that module. Well not exactly. That, and I’m not sure how to dissect the Linux Image I have now to find out . . .

So a bit more information. Here is the device tree overlay i’ve loaded

/dts-v1/;
/plugin/;

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;

/* identification */
part-number = “pruss_enable”;
version = “00A0”;

fragment@0 {
target = <&pruss>;
overlay {
status = “okay”;

};
};

};

So, the target is &pruss. Looking in the am335x-boneblack.dts file there is no mention of &pruss. But this file does have two includes at the top.

#include “am33xx.dtsi”
#include “am335x-bone-common.dtsi”

Searching through am33xx.dtsi for “pruss” turns up this fragment.

pruss: pruss@4a300000 {
compatible = “ti,pruss-v2”;
ti,hwmods = “pruss”;
ti,deassert-hard-reset = “pruss”, “pruss”;
reg = <0x4a300000 0x080000>;
ti,pintc-offset = <0x20000>;
interrupt-parent = <&intc>;
status = “disabled”;
interrupts = <20 21 22 23 24 25 26 27>;
};

So, I believe you have a couple options. First, you can create an overlay like file, and #include it in am335x-boneblack.dts. IN order to do this you will need to copy your current dtbo file, decompile it, edit the file, etc ,etc, then recompile the file. Back up, and move the old am335x-boneblack.dts file out of the way. Replace with your newly compiled file. The second option is pretty much the same thing, but your change the am335x-boneblack.dtbo file directly.

Anyway, there is actually a third option. Get rid of that 3.14.x kernel, and use a 4.x kernel . . . a kernel that can actually use cape manager.

my bad, I missed a necessary point there. Basically you need to change status = “disabled”; to status = “okay”;

Then it is my best guess that everything you need to use uio_pruss will be loaded correctly.

Sadly I’m running into the same missing uio directories now that I’m trying to get my beaglebone code that was stable on the 3.8 kernel and Wheezy image. My old compiled dtbo wouldn’t load with a 4.1 kernel until it was recompiled. Even with it loaded, the following modules don’t load: PRU, eQEP, PWM, and GPIO_buttons. I spent today hacking together workarounds for the latter 3, but the PRU still has me stumped.

Looking closely, the am335x-boneblack.dtb file has changed quite a bit. Once decompiled I have the following entries for the PRUSS:

3.8 kernel (2015-03-01 image):

`

pruss@4a300000 {
compatible = “ti,pruss-v2”;
ti,hwmods = “pruss”;
ti,deassert-hard-reset = “pruss”, “pruss”;
reg = <0x4a300000 0x80000>;
ti,pintc-offset = <0x20000>;
interrupt-parent = <0x1>;
status = “disabled”;
interrupts = <0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>;
linux,phandle = <0x35>;
phandle = <0x35>;
};

`

4.1 kernel (2015-11-12 image)

`

pruss@4a300000 {
compatible = “ti,am3352-pruss”;
ti,hwmods = “pruss”;
reg = <0x4a300000 0x2000 0x4a302000 0x2000 0x4a310000 0x3000 0x4a320000 0x2000 0x4a326000 0x2000>;
reg-names = “dram0”, “dram1”, “shrdram2”, “intc”, “cfg”;
interrupts = <0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>;
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;
linux,phandle = <0xc6>;
phandle = <0xc6>;

pru@4a334000 {
compatible = “ti,am3352-pru-rproc”;
reg = <0x4a334000 0x2000 0x4a322000 0x400 0x4a322400 0x100>;
reg-names = “iram”, “control”, “debug”;
mboxes = <0x28 0x44>;
linux,phandle = <0xc7>;
phandle = <0xc7>;
};

pru@4a338000 {
compatible = “ti,am3352-pru-rproc”;
reg = <0x4a338000 0x2000 0x4a324000 0x400 0x4a324400 0x100>;
reg-names = “iram”, “control”, “debug”;
mboxes = <0x28 0x45>;
linux,phandle = <0xc8>;
phandle = <0xc8>;
};
};

`

The new entry is missing the “status = “disabled”;” line which explains why my old overlay file which simply changed “disabled” to “enabled” didn’t have an effect. Sadly manually adding the line into the 4.1 kernel version of the am335x-boneblack.dts file and recompiling didn’t help. Does anyone know why this entry was changed and better yet how to get the PRUSS module to load again?

Robert Nelson told us that the uio pruss is not working on the kernel ti. If you want to have uio pruss you should use the bb kernel.

https://github.com/RobertCNelson/bb-kernel

It’s because Texas is working on a new pruss driver.

With newer kernels, you need to use the standard Linux remote-proc
interface, rather than the legacy UIO driver.

With newer kernels, you need to use the standard Linux remote-proc
interface, rather than the legacy UIO driver.

Not exactly. Only if you’re using the *TI kernels. The *bone kernels have uio_pruss enabled.

william@beaglebone:~$ uname -r
4.1.12-bone-rt-r16
william@beaglebone:~$ sudo sh -c “echo ‘pru_enable’ > /sys/devices/platform/bone_capemgr/slots”
william@beaglebone:~$ ./ti/lsuio-0.2.0/lsuio
uio7: name=pruss_evt7, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio6: name=pruss_evt6, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio5: name=pruss_evt5, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio4: name=pruss_evt4, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio3: name=pruss_evt3, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio2: name=pruss_evt2, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio1: name=pruss_evt1, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144
uio0: name=pruss_evt0, version=1.0, events=0
map[0]: addr=0x4A300000, size=524288
map[1]: addr=0x9E880000, size=262144

The pru_enable device tree file is pretty simple too:

/dts-v1/;
/plugin/;

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;

/* identification */
part-number = “pruss_enable”;
version = “00A0”;

fragment@0 {
target = <&pruss>;
overlay {
status = “okay”;

};
};

};

Also, yes, everything works fine. I’ve tested various PRU git projects, and they all seem to work fine.

So, not to argue, but my point of view. I have no problem with people using remoteproc, if that’s what they want to do. At the same time, I feel that it should not be “forced down our throats”, because right now, it is not ready for prime time. uio_pruss is a known quantity, lots of people have documented their use of it, and remoteproc is barely documented at all. Passed that, from what I’ve seen so far, only closed source tools can be used with remoteproc, on the beaglebones.

I did see someone post a gcc “port” of one of Jason Reeders guides . . . but no mention of toolchain setup, or anything else.

So until documentation is up to snuff, and we’re not forced to use close source tools. I’ll always consider remoteproc as something not to be used seriously. I’m sure I’m also not alone.

Well, bone is far behind the ti kernel. When I added remote-proc to the bone kernel, the patch was very large. With the ti kernel, most of the patches where already applied. Anyway, I did send Robert the bone patches, but he decided not to apply them.

Regards,
John

Remoteproc/RPMSG is a standard in mainline for interfacing ARM to other processors on the same SOC. On the x15, this will be the only way you can interface to the DSP, M4’s, etc. Other vendors have adopted this solutions as well.

Regards,
John

We’re not talking about the X15 in this post, and personally, I probably won’t be using an X15 for a long, long time. Too much board, for too much money.

OK, so maybe you can explain why you think there is a difference between writing PRU firmware targeting PRUSS vs PRU firmware targeting remoteproc? The only difference is the API. You can build the firmware for each in the same way. The only reference to CCSV6 is the examples TI created for remoteproc. Someone updated those examples to build with GCC. So I don’t understand what you mean by forced to use “close source tools”. Nothing in remoteproc is closed source. All remoteproc does is load the firmware on the PRU and then start the code. virtio_rpmsg_bus handles the communications between ARM and the PRU.

Regards,
John

OK, so show us a real world example of rpmsg.

By real world I mean a real world useful example. Not some BS spit 100 “hello” messages out into dmesg.

Some good ones here:

https://github.com/dinuxbg/pru-gcc-examples

all using binutils/gcc. :wink:

Regards,

How is that a BS example? The example shows an ARM kernel module sending a message to the PRU, which interrupts the PRU, which then copies the message from the PRU rx buffer to the PRU tx buffer, which then executes a callback on the ARM kernel module. You should be able to take that code and make it do anything you need.

Regards,
John

It’s a BS example because it does not illustrate how remoteproc and rpmsg are useful. It also does not illustrate how to access the hardware modules through this technology. Here . . .

Something useful → https://github.com/boxysean/beaglebone-DMX

Something else useful → https://github.com/pgmmpk/beaglebone_pru_adc

Yet another something useful → https://github.com/abhishek-kakkar/BeagleLogic

All these have been in the wild for a long time. They work, and the hardware / software paradigm is well known, and explained many times all over the web.

Show us how to blink USR0, then explain how that works. Or even show us how to use any on die hardware module, or something that can be “plugged in” to demonstrate an immediate result. Without having to hook up external electronics / circuits.

That is why uio_pruss is better than remoteproc. People understand it, or if they do not, they can read about it, and grasp the concept fairly quickly. Because there is a lot of good documentation, and many, many good examples that cover just about any on die hardware module.

Anyway, I think the burden is actually on you, to explain to me, and others why remoteproc / rpmsg is any good and should be used. Since, uio_pruss has been around since 2011 or earlier, and is perfectly functional. With that said, regurgitating sentiments such as “bla blah blah has adopted x.y.z” is going to do you no good. We do not care who as adopted what, and why. We want to know why remoteproc, and rpmsg is worth out time investment. Especially considering we already have a large time investment with uio_pruss.

I actually think remoteproc / rpmsg is usefu for multi core systems. Say a dual core ARM processor where one core is running Linux, and the other is running bare metal for deterministic purpose. I am however still unconvinced how it is useful when you have multiple cores on die that are not all application based processors. Such as the PRUs, or on die M4 / IPU on the X15’s processor. DSP . . . yeah I do not know enough about those to make that call.

. . . And my god, what is this supposed to be ? C ?

https://github.com/dinuxbg/pru-gcc-examples/blob/master/blinking-led/pru/resource_table_0.h#L43-L72