RFC: Universal Device Tree

I have made substantial progress on my proposed "universal" device tree
overlay for the BeagleBone. The general idea is to enable all hardware
that is expected to be generally useful, and use the pinmux helper to
allow user-mode control of pin multiplexing (no writing kernel drivers
or editing device tree files required).

Attached is a first revision of such an overlay for the BeagleBone
Black. The eMMC, HDMI, and cape I2C EEPROM pins are left as-is, but all
other P8 and P9 pins are supported. After loading this overlay, all I/O
pins should be in their default reset state (GPIO input, with pull up or
pull down enabled depending on the pin). User code can then interact
with sysfs to configure the hardware as desired.

To change between functions, you echo the desired pinmux function to the
exported pinmux helper file. For example, to change P8 pin 13 to a PWM
output, as root:

  echo pwm > /sys/devices/ocp.*/P8_13_pinmux.*/state

The supported values vary by pin, and you currently need to extract them
from the device tree file (documentation and a github repository are in
progress). In general, all pins support gpio, and most pins support one
or more of uart, pwm, pruin, pruout, spi, i2c, and can. In addition,
all pins support a "default" setting, which maps to the same as gpio
(ie: you can use default or gpio interchangeably).

Changing the GPIO mode is done the same as with any exported pin, you
access the files in /sys/class/gpio. For example, the following will
change P8 pin 13 to a GPIO output driving high, assuming you applied my
kernel patch to enable exporting gpio pins with changeable direction
(see previous e-mail):

  echo high > /sys/class/gpio23/direction

Note that it is quite possible to "shoot yourself in the foot" with
regards to pin multiplexing, but this also allows things like only using
the Tx pin of a UART for serial communications, while using the Rx pin
for a GPIO or other special-purpose function. All without having to
create a custom device tree overlay, which is even more dangerous than
having to echo some values to the pinmux helper file!

Please review and comment, especially with regards to enabling the
hardware drivers. There was a *LOT* of cut-and-paste involved when
generating the overlay, so I won't be surprised if there's not a typo or
two lurking around. Also, I am not familiar enough with the SPI, I2C,
and PWM drivers to know if what I've got (generally extracted from the
device tree overlays shipped with the BeagleBone kernel source) are
suitable for generic use. Suggestions or pointers to good examples
outside the kernel tree would be welcome!

I'm also not completely happy with the naming conventions for the
various device tree nodes. Please comment if you have suggestions for
better names.

bone-universal-00A0.dts (52.5 KB)

Hi Charles,

Sorry if this is an incredibly dense question. But which kernel version is this for?

I have made substantial progress on my proposed "universal" device tree
overlay for the BeagleBone. The general idea is to enable all hardware
that is expected to be generally useful, and use the pinmux helper to
allow user-mode control of pin multiplexing (no writing kernel drivers
or editing device tree files required).

Attached is a first revision of such an overlay for the BeagleBone
Black. The eMMC, HDMI, and cape I2C EEPROM pins are left as-is, but all
other P8 and P9 pins are supported. After loading this overlay, all I/O
pins should be in their default reset state (GPIO input, with pull up or
pull down enabled depending on the pin). User code can then interact
with sysfs to configure the hardware as desired.

To change between functions, you echo the desired pinmux function to the
exported pinmux helper file. For example, to change P8 pin 13 to a PWM
output, as root:

echo pwm > /sys/devices/ocp.*/P8_13_pinmux.*/state

The supported values vary by pin, and you currently need to extract them
from the device tree file (documentation and a github repository are in
progress). In general, all pins support gpio, and most pins support one
or more of uart, pwm, pruin, pruout, spi, i2c, and can. In addition,
all pins support a "default" setting, which maps to the same as gpio
(ie: you can use default or gpio interchangeably).

Changing the GPIO mode is done the same as with any exported pin, you
access the files in /sys/class/gpio. For example, the following will
change P8 pin 13 to a GPIO output driving high, assuming you applied my
kernel patch to enable exporting gpio pins with changeable direction
(see previous e-mail):

echo high > /sys/class/gpio23/direction

Note that it is quite possible to "shoot yourself in the foot" with
regards to pin multiplexing, but this also allows things like only using
the Tx pin of a UART for serial communications, while using the Rx pin
for a GPIO or other special-purpose function. All without having to
create a custom device tree overlay, which is even more dangerous than
having to echo some values to the pinmux helper file!

Please review and comment, especially with regards to enabling the
hardware drivers. There was a *LOT* of cut-and-paste involved when
generating the overlay, so I won't be surprised if there's not a typo or
two lurking around. Also, I am not familiar enough with the SPI, I2C,
and PWM drivers to know if what I've got (generally extracted from the
device tree overlays shipped with the BeagleBone kernel source) are
suitable for generic use. Suggestions or pointers to good examples
outside the kernel tree would be welcome!

I'm also not completely happy with the naming conventions for the
various device tree nodes. Please comment if you have suggestions for
better names.

Hi Charles,

I¹ve been wondering if device three overlay is the best way to solve this
issue and perhaps this is why it has be rejected in mainline. Why not use
Netlink which is used to setup and configure several I/O frameworks in the
kernel such as route tables, iproute2, etc. Compare net-tools to iproute2.
Why not create a IIO driver for BBB and use Netlink to setup and configure
GPIO modes and also for I/O operations. Sysfs is slow and cumbersome and
does not support streaming and events. Netlink is a two way asynchronous
socket interface between user space and kernel space. With Netlink, it is
possible to have GPIO interrupts, streaming ADC samples, etc. Performance
is way better than sysfs. It would be possible to setup channels for SPI,
I2C, ADC, DAC, PWM, etc. The user space interface is a simple socket
interface with a simple protocol API and would support any programming
language. I foresee a device driver that would configure GPIO modes and
general I/O operations such as SPI, I2C, CAN, GPIO, ADC, DAC, etc.

Thoughts?

Regards,
John

I think for most, or at least a lot of cases sysfs is more than enough for basic GPIO stuffs. It could/would even be fine for PWM/ADC in most/some cases.

Then in other cases when sysfs would not be fast enough, chances are pretty good that you want dedicated external hardware “offloading” the main processor ( Beaglebone ) anyhow. This could come in many different forms.

I think Charles is doing something that is useful. But I have also never heard of netlink, which also sounds very interesting and seems like something akin to IPC between user / kernel modes. However, I think both could be useful for different situations.

I think for most, or at least a lot of cases sysfs is more than enough for basic GPIO stuffs. It could/would even be fine for PWM/ADC in most/some cases.

One sample per second, but nothing faster than that.

Then in other cases when sysfs would not be fast enough, chances are pretty good that you want dedicated external hardware “offloading” the main processor ( Beaglebone ) anyhow. This could come in many different forms.

You have a 1GHz processor with very capable I/O; why would you add more hardware when there is a very simple software solution?

I think Charles is doing something that is useful. But I have also never heard of netlink, which also sounds very interesting and seems like something akin to IPC between user / kernel modes. However, I think both could be useful for different situations.

I’m proposing a solution that solves several problems not addressed by Device Tree Overlays. For example, sysfs is simplex and user space apps must poll the sysfs interface for changes on the kernel side. IOCTL has the same problem. I know that Charles is also working with Xenomai and this solution that could possible provide a two way interface to Xenomai drivers. Here is an article that helps explain the benefits of Netlink over IOCTL and by extension sysfs.

http://www.linuxjournal.com/article/7356

Regards,
John

I think for most, or at least a lot of cases sysfs is more than enough for basic GPIO stuffs. It could/would even be fine for PWM/ADC in most/some cases.

Then in other cases when sysfs would not be fast enough, chances are pretty good that you want dedicated external hardware “offloading” the main processor ( Beaglebone ) anyhow. This could come in many different forms.

I think Charles is doing something that is useful. But I have also never heard of netlink, which also sounds very interesting and seems like something akin to IPC between user / kernel modes. However, I think both could be useful for different situations.

One more point, Bonescript and Nodejs could benefit from the asynchronous I/O provided by NetLink. A decent library written on top of libnl could implement Arduino like functionality for all available BBB I/O.

It's for the 3.8 kernel, unless someone's gotten device tree overlays
working with the 3.12 kernels while I wasn't looking. :slight_smile:

It should work with any 3.8 kernel (regular or Xenomai), but if you
don't have the patch to gpio-of-helper to allow exporting GPIO pins with
changeable direction they'll all be stuck as inputs.

Ok, this is what I was thinking was the case, but at the same time I was hoping it was for 3.12.x . . .

Did i read your original post correctly in that you plan on documenting this fully ( eventually ) ?

I'll be the first to admit that device tree overlays are not the best
way to handle dynamic hardware definition. Device tree is fine, but it
is intended to be static. Trying to press device tree into use as a
poor man's hot-plug is IMHO generally a fools errand, and I've said so
here before. Not only will this never get pulled upstream, but there
are issues maintaining the code (see for instance the 3.12 kernel that
doesn't yet have a working cape manager).

That said, device tree overlays is what we have for the moment, and all
I'm trying to do is provide a way for individuals to access the many
various hardware features of the BeagleBone Black without having to
craft their own device trees or write kernel drivers. The limitations
with sysfs you're referring to are valid, but not really related to the
problem I'm trying to solve. I'm not mandating you use sysfs to access
the GPIO pins, for example, I'm just providing a way to setup all the
I/O without having to iterate through exporting each one individually
(which leaves no way to easily control pin multiplexing) or crafting a
device tree of your own. Once enabled and setup, the hardware can be
controlled via the usual methods, sysfs or otherwise. The UARTs get
/dev/ entries, for instance, and I memory map the GPIO registers and
communicate with them directly via the PRU and hard real-time Xenomai tasks.

John,

Without sounding like I am trying to argue too much, there are cases in electronics where you could easily overwhelm a 1Ghz processor.

Imagine one very “simple” use case. A computer controlled switch mode power supply where power switching could happen from 400Khz to 2Mhz changeable on the fly based on readings taken from 1 or more ADCs reading 2msps. I seriously doubt a BBB could handle this alone. Now add in networking, web UI, security, and countless other aspects to the device and . . . yeah it would never happen without external devices.

After quickly the Wikipedia page for Netlink, I do however find it very interesting, and in fact is IPC between user / kernel mode processes. Among other things.

Ok, this is what I was thinking was the case, but at the same time I was
hoping it was for 3.12.x . . .

It should work with little or no modification with 3.12 once the cape
manager gets fixed up. It would probably work if manually appended to
the system device tree instead of compiling it as an overlay. The
pinmux helper and gpio-of-helper needed are both in the mainline kernel,
it's just the cape manager that's not.

Did i read your original post correctly in that you plan on documenting
this fully ( eventually ) ?

Well, I'm not sure about "fully", but there will be a lot more
documentation than what exists now (virtually zero). I'm mostly still
mulling over project names, so I can start a repository on github.

I'm currently leaning towards 'dt-bone-universal', but I'm open to
suggestions.

I intend to at least provide a list of the available devices, a chart
indicating which pins support which modes, and a shell script or other
runnable program that allows configuration of GPIO pins without
consulting a bunch of tables...probably something like:

  setup-gpio P8_15 high # P8 pin 15 is GPIO output driving high
  setup-gpio P8_16 pruin # P8 pin 16 is a dedicated PRU input

...instead of what you currently have to do, which is:

  echo gpio > /sys/devices/ocp.*/P8_15_pinmux.*/state
  echo high > /sys/class/gpio/gpio47/direction

  echo pruin > /sys/devices/ocp.*/P8_16_pinmux.*/state

John,

Without sounding like I am trying to argue too much, there are cases in electronics where you could easily overwhelm a 1Ghz processor.

Imagine one very “simple” use case. A computer controlled switch mode power supply where power switching could happen from 400Khz to 2Mhz changeable on the fly based on readings taken from 1 or more ADCs reading 2msps. I seriously doubt a BBB could handle this alone. Now add in networking, web UI, security, and countless other aspects to the device and . . . yeah it would never happen without external devices.

Agreed, but what I was proposing was to use the full capability of the existing hardware. Using sysfs doesn’t begin to harness the capabilities of the BBB I/O hardware.

Well I am still relatively new to embedded Linux, but I will try to help with ideas as I understand more. I do understand sysfs mostly in concept and C/C++ development aspects too, but . . . yeah limited hands on has me balking

"I’m currently leaning towards ‘dt-bone-universal’, but I’m open to
suggestions."

how about something like bone-gpio-universal ? Maybe even bone-gpio-default? Personally i think adding “dt” to the name is pretty redundant but could be just me.

I was simply trying to point out that you could make sysfs work. Even in some high speed situations. I do not necessarily disagree with you at all however.

Anyway, I think we have hijacked Charles’ post enough.

From: William Hermans <yyrkoon@gmail.com>

I think Charles is doing something that is useful. But I have also
never heard
of netlink, which also sounds very interesting and seems like
something akin
to IPC between user / kernel modes. However, I think both could be
useful for
different situations.

I¹m proposing a solution that solves several problems not addressed by
Device Tree Overlays. For example, sysfs is simplex and user space apps
must
poll the sysfs interface for changes on the kernel side. IOCTL has the
same
problem. I know that Charles is also working with Xenomai and this
solution
that could possible provide a two way interface to Xenomai drivers.
Here is
an article that helps explain the benefits of Netlink over IOCTL and by
extension sysfs.

Kernel Korner - Why and How to Use Netlink Socket | Linux Journal

I'll be the first to admit that device tree overlays are not the best
way to handle dynamic hardware definition. Device tree is fine, but it
is intended to be static. Trying to press device tree into use as a
poor man's hot-plug is IMHO generally a fools errand, and I've said so
here before. Not only will this never get pulled upstream, but there
are issues maintaining the code (see for instance the 3.12 kernel that
doesn't yet have a working cape manager).

That said, device tree overlays is what we have for the moment, and all
I'm trying to do is provide a way for individuals to access the many
various hardware features of the BeagleBone Black without having to
craft their own device trees or write kernel drivers. The limitations
with sysfs you're referring to are valid, but not really related to the
problem I'm trying to solve. I'm not mandating you use sysfs to access
the GPIO pins, for example, I'm just providing a way to setup all the
I/O without having to iterate through exporting each one individually
(which leaves no way to easily control pin multiplexing) or crafting a
device tree of your own. Once enabled and setup, the hardware can be
controlled via the usual methods, sysfs or otherwise. The UARTs get
/dev/ entries, for instance, and I memory map the GPIO registers and
communicate with them directly via the PRU and hard real-time Xenomai
tasks.

Hi Charles,

I understand where you are coming from and I don¹t want to overly
complicate things for you. I only made the proposal because I see several
configuration tools migrating to NetLink. Consider nftables [1] which
replaces iptables, iw [2] replaces iwconfig, iproute2 [3] replaces
net-tools (ifconfig, netstat, route, etc) and many more.

[1] netfilter/iptables project homepage - The netfilter.org "nftables" project
[2] en:users:documentation:iw [Linux Wireless]
[3]
networking:iproute2 [Wiki]

I think what you propose is a good interim solution, but perhaps the
Beagle community should start thinking about how to make I/O use on the
BBB as simple as Arduino. At the moment, it is far too complicated for new
users.

Regards,
John

After sleeping on it, I am now leaning towards:

  beaglebone-universal-io (github project name)
  bone-universal-00A0.dts (device tree file name)

You're right that dt is fairly redundant, and the whole point of this
exercise is to make it possible to access special hardware modes (pwm,
spi, etc) from userspace. It's already possible to do that with gpio,
so including gpio in the name seems limiting.

Comment on PRUSS support:

in the Current (just downloaded June 30):

/* P9_30 (ZCZ ball D12) */

            (...)
            P9_30_pruout_pin: pinmux_P9_30_pruout_pin {
                pinctrl-single,pins = <0x198  0x25>; };     /* Mode 5, Pull-Down, RxActive */
            P9_30_pruin_pin: pinmux_P9_30_pruin_pin {
                pinctrl-single,pins = <0x198  0x26>; };     /* Mode 6, Pull-Down, RxActive */

I think that the pruout pin line should be: <0x198 0x05>; ]; /*Mode 5, Pull-Down, TxActive *