Deleting Device Tree Overlays

I am trying to use both the A/D and the high-speed PRU direct I/O. I have the A/D working using Adafruit_BBIO.ADC and separately, I can write directly using the PRU based on the TI examples and using a Device Tree Overlay, but have not been successful using them concurrently yet. By using cat /sys/devices/bone_capemgr.9/slots, I found that the commands in python of

import Adafruit_BBBIO.ADC as ADC

setup()
loaded the cape-bone-iio-00A0.dtbo overlay

as

/lib/firmware> cat $SLOTS
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
9: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-bone-iio

I then attempted to remove the overlay by

/lib/firmware> sudo sh -c “echo -9 > $SLOTS”
/lib/firmware> cat $SLOTS

but the terminal then freezes and never comes back. In another terminal window, using ps aux | grep cat
I can see the process, but a kill -9 will not get rid of it. In the other terminal window, I also attempted the
cat $SLOTS, and it froze up, as well. The only way of getting it back is rebooting the system. In addition
the Adafruit_BBBIO.ADC does not have cleanup function. This behaviour does not seem correct to me.
I also tried removing the overlay that set up the PRU output pins, and that did seem to work correctly.

Any ideas? Thanks.
Bit Pusher

Device tree overlays are generally a hack to try and convert the
inherently static device tree mechanism into a sort of poor mans
hot-plug infrastructure. The loading of overlays works mostly OK, but
unloading an overlay is a very good way to make your system totally
unstable and/or cause kernel panics.

To unload a device tree overlay cleanly, you have to reboot.

:frowning:

if you actually run “echo -9 > $SLOTS” as the root user do you still have this issue?

I did a >sudo su - and then >echo -7 > /sys/devices/bone_capemgr.9/slots (as Adafruit_BBIO.ADC had loaded into slot 7). The command appeared to work, but it also dropped me back to my regular user status so something went wrong. When, as a regular user, I >cat $SLOTS, it locked up the terminal the same as before. By the way, my kernel is
Linux ubuntu-armhf 3.8.13-bone28

As far as I know trying to remove a device tree overlay while the BBB is running the OS will always cause a crash.

In order to remove device tree overlays, pass the appropriate parameters to the kernel via uEnv.txt / uboot

Such as : optargs=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN

Except of course use the device tree overlay name you’re trying to unload.

However I get the sense you really do not care about this specifically and would possibly like to tweak a device tree overlay file ( make changes etc ) remove and then reload the modified version. Unfortunately I do not think this is possible without a reboot.

Like I said...the only way to remove a device tree overlay is to reboot,
you can only *ADD* overlays w/o making the system unstable (at best).

It sucks^H^H^H is sub-optimal, but that's how it is. The fact that
loading an overlay works pretty well is pretty convenient, and downright
amazing, when you consider what the underlying device tree was intended
to support. It sure beats rebooting *AND* having to edit your board.dto
file! :slight_smile:

Charles, where do you get your information from ? Not trying to be rude or condescending, or anything of that nature. I only ask because I have actual hands experience with this “feature” and have often wondered if there could be a potential work around( through code ).

My experience is mostly from beating my head against the wall trying to
get this working, along with crawling through some of the device tree
"back-story", technical details, and kernel code.

Basically, device tree is intended to be a *STATIC* definition of the
machine hardware available to the kernel at boot. Pretty much *ALL*
device tree does is store a bunch of values that can be retrieved via an
identifier (think INI file and you're not too far off). The overlay
stuff is all pretty much BeagleBone specific.

Loading an overlay works fairly well because it is very similar in
concept and process to the kernel initialization...various kernel module
code gets run and other kernel modules may or may not already be present
or fully loaded. If your driver code can't deal with this, it's going
to be buggy in general use, regardless of whether or not you're trying
to load overlays. In a sense, loading a device tree overlay is very
much like simply extending system initialization for what could be a
_long_ time while a bunch of other code runs. :slight_smile:

Unloading an overlay, however, is a minefield of potential problems,
particularly since most of the ARM drivers weren't written with hot-plug
in mind. I'm not even sure most of the drivers can be unloaded at the
kernel level (hmm...I should go off and try to rmmod some of them).

Anyway, true hotplug is a big-fat-hairy-can-of-worms, and pretty much
_none_ of the ARM ecosystem has been written with hot-plug in mind
(except for the bits that carry over from other systems, like USB and
PCI). It's not really surprising it crashes, it's just kind of
annoying. :slight_smile:

As for a work-around, I believe the saying goes:

"There is no problem in computer science which cannot be solved by one
more level of indirection."

In all honesty, there really should be no hotplug anyhow. At not for this sort of thing. The device should be powered down when wiring new circuitry to it anyhow right ?

Correct me if I am wrong, but it appears that you simply want to use ADC and PRU pins whose pins DO NOT physically overlap on the board? The cape-bone-iio device tree only grabs the ADC0-ADC7 pins plus analog power and ground, so it should not interfere with the PRU pins.

What issue are you getting when you try to load the PRU overlay after loading the ADC overlay?

Note: The adafruit library has a cleanup function in code, but it is commented out due to the lockup on load that you are describing.

Zach

If I load my device tree overlay to use the high-speed GPIO pins first, and then try to read the ADC using Adafruit_BBIO, it kicks me out of python:

~/pru> sudo python
Python 2.7.5+ (default, Sep 19 2013, 14:17:30)
[GCC 4.8.1] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

import Adafruit_BBIO.ADC as ADC
ADC.setup()
ADC.read(“P9_40”)
~/pru>

notice no value returned and no python prompt. I suspect this indicates a problem.
I then rebooted (reset switch), waited until the network started working again (it takes 5 minutes each time for the network to work, something needs to timeout)
and then did the same, but this time did not load the device overlay to change one pru gpio to a high-speed output and got as expected

~/pru> sudo python
Python 2.7.5+ (default, Sep 19 2013, 14:17:30)
[GCC 4.8.1] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

import Adafruit_BBIO.ADC as ADC
ADC.setup()
ADC.read(“P9_40”)
0.8072222471237183

I should mention that when I load both overlays, with my overlay first, >cat $SLOTS shows them both there, just the ADC overlay load does not
work correctly. If I run the ADC.setup() first, and then run
~/pru>>sudo sh -c “echo BB-BONE-PRU > $SLOTS” to load my overlay, then

/lib/firmware> cat $SLOTS
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
7: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-bone-iio
9: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-PRU
/lib/firmware>

and both overlays are shown but the high
speed pin does not work.
Loading just my overlay only, works as expected as far as I can tell (i.e. the led turns on and off).
I’m guessing things are not quite as expected.
Also, could someone point me to the file in kernel source that loads overlays?
Thanks.
Bit Pusher

If I load my device tree overlay to use the high-speed GPIO pins first, and then try to read the ADC using Adafruit_BBIO, it kicks me out of python:

~/pru> sudo python
Python 2.7.5+ (default, Sep 19 2013, 14:17:30)
[GCC 4.8.1] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

import Adafruit_BBIO.ADC as ADC
ADC.setup()
ADC.read(“P9_40”)
~/pru>

notice no value returned and no python prompt. I suspect this indicates a problem.
I then rebooted (reset switch), waited until the network started working again (it takes 5 minutes each time for the network to work, something needs to timeout)
and then did the same, but this time did not load the device overlay to change one pru gpio to a high-speed output and got as expected

~/pru> sudo python
Python 2.7.5+ (default, Sep 19 2013, 14:17:30)
[GCC 4.8.1] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

import Adafruit_BBIO.ADC as ADC
ADC.setup()
ADC.read(“P9_40”)
0.8072222471237183

I should mention that when I load both overlays, with my overlay first, >cat $SLOTS shows them both there, just the ADC overlay load does not
work correctly. If I run the ADC.setup() first, and then run
~/pru>>sudo sh -c “echo BB-BONE-PRU > $SLOTS” to load my overlay, then

/lib/firmware> cat $SLOTS
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
7: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-bone-iio
9: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-PRU
/lib/firmware>

and both overlays are shown but the high
speed pin does not work.
Loading just my overlay only, works as expected as far as I can tell (i.e. the led turns on and off).
I’m guessing things are not quite as expected.
Also, could someone point me to the file in kernel source that loads overlays?

GIT is your friend and you can use it to find what you want in the kernel. Simply use “git grep capemgr” and it will show you all the files that reference the cape manager, which is what loads and removes overlays. You will notice that there are several patches that attempt to fix crashes related to capemgr.
Regards,
John

Could you post or send me your overlay? I can load it on one of my BBBs and take a look for you.

Zach

Thanks John, appreciated.
Bit Pusher

Zach, that would be very good of you; I got if from searching on the net and it is barely changed (if at all) from what I found (but I didn’t record who I copied it from so I apologize for not giving credit). The *.dts is below. I might mention that if I load my overlay only, then using >cat $PINS, I can see the expected pin change to 6. If I setup the AD first in python, I do not see any changes in the $PINS, and if I then try to load my overlay and check the pins, they are still the same as just after boot.
Bit Pusher

/lib/firmware> cat BB-BONE-PRU-00A0.dts
/*

  • pru dts file BB-BONE-PRU-00A0.dts
    */
    /dts-v1/;
    /plugin/;

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

/* identification */
part-number = “BB-BONE-PRU”;
version = “00A0”;

exclusive-use =
“P8.12”;

fragment@0 {
target = <&am33xx_pinmux>;
overlay {
mygpio: pinmux_mygpio{
pinctrl-single,pins = <
0x30 0x06

;
};
};
};

fragment@1 {
target = <&ocp>;
overlay {
test_helper: helper {
compatible = “bone-pinmux-helper”;
pinctrl-names = “default”;
pinctrl-0 = <&mygpio>;
status = “okay”;
};
};
};

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

Odd, dmesg has no errors, but there is definitely a conflict between the two.

Someone can correct me if I am wrong as this is a guess based on the behavior of the system (I’ll have to look it up later) but loading a device tree will dynamically map a bunch of hardware register to the file system in certain locations based on the fragment used. Since the dts file you posted specified &ocp as the target, it placed it into /sys/devices/ocp.*/[Name].

In this case [Name] is the name that you specified is the one inside of that overlay keyword. That would be “helper”.

I know for sure that the Adafruit Library looks for /sys/devices/ocp./helper. to read from and control the ADC registers, so if your overlay is overwriting those values, it will lead to problems. I am not sure why it would affect your pru code without seeing how you are trying to access the IOs.

Anyway, try changing the line:

test_helper: helper {

to something more unique such as:

pru_iomap {

Recompile, then try loading as before.

Though if you are not using the ocp mapping to write to the IO, you could probably drop the section. Some of the sample dts files in /lib/firmware/BB-BONE-PRU-01.dts do not even map the ocp.

Also, you may want to add “pru0” to your exclusive use list so another cape doesn’t try to use it at the same time.

After those changes:

`
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
root@beaglebone:~# echo BB-BONE-PRU > $SLOTS
root@beaglebone:~# cat $SLOTS
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-PRU
root@beaglebone:~# python
Python 2.7.3 (default, May 29 2013, 21:25:00)
[GCC 4.7.3 20130205 (prerelease)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

import Adafruit_BBIO.ADC as ADC
ADC.setup()
ADC.read(“P9_40”)
0.86722224950790405
`

Let me know how it goes,
Zachary Thorson

Zach, your help is very appreciated; I will give it a try shortly after looking after commitments and get back to you soon. Thanks.
Bit Pusher

Zach, your suggestions worked. I changed fragment@1 to:

fragment@1 {
target = <&ocp>;
overlay {
test_pru_iomap: pru_iomap {
compatible = “bone-pinmux-helper”;
pinctrl-names = “default”;
pinctrl-0 = <&mygpio>;
status = “okay”;
};
};
recompiled, and then when I loaded the overlay, and later did ADC.setup(), I was still able to
control the output pins with the ADC simultaneously working using pru0 commands

SET r30.t14

and

CLR r30.t14

I also added pru0 to:

exclusive-use =
“P8.12”, “pru0”;
as you suggested. Finally, your explanations about which files are being affected when overlays are loaded

was very illuminating. I have spent time googling to try and understand what is going on with device trees, and
read articles such as http://www.devicetree.org/Device_Tree_Usage, but your few lines of explanation have been
more useful than anything I have found to date. If there is an article or site you would recommend to read, I would
be very interested. Also, if you happen to know where the source code for Adafruit_BBIO.ADC can be found,
I would be interested in trying to follow it through. Once again, thank you for your
help; with my limited knowledge re device trees, this is not something I would have
been able to solve on my own.
Bit Pusher

This should be the repo you’re looking for, though if not check the rest of them there. HTH

I’m glad to hear it’s working!

Jeremy posted the correct link for the source code. It is written in C with support for calls through Python.

As far as useful Devicetree links, the Usage one you posted is useful, though since they write it to be very generic, it can be hard to follow.

A few with a more limited focus (to overlays, specifically the BBB):
Basic Overview of Capes: https://github.com/jadonk/validation-scripts/blob/master/test-capemgr/README.md (Ignore the parts about unloading, it is not functioning)
Excellent More detailed Overview Here: http://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree?view=all
Very well written overlay, good example: https://github.com/modmaker/BeBoPr/wiki/Device-Tree-Overlay-and-devices

If you learn better by learning why and how rather than just how look here for an explanation on why they came about and some good explanations:
https://docs.google.com/document/d/17P54kZkZO_-JtTjrFuVz-Cp_RMMg7GB_8W9JK9sLKfA/pub

Zach