libiio on BBB?

What would it take to get libiio:

Into the BBB kernels? I think this would be amazing.

I believe the ADC already uses a libiio “driver”. Assuming it is the same thing I’m thinking of. But for instance when you load the ADC device tree file, it in turn loaded the iio:device0 object for the ADC.

Like demonstrated on my blog post here:

With that said, I do not purport to know very much about it. Just that it exists.

libiio (along with additional stuff in the kernel that doesn't appear to be in 4.1.x-ti) provides for fast ADC access, rather than getting at it through sysfs.

Not sure I understand what you’re getting at, but I’ve read that iio has at least two methods of access. Slow( sysfs ), and fast( mmap()). I’m not sure that the “fast” method driver exists for our board here in the context of the ADC’s but certainly the slow sysfs method does. As for the rest of the things mentioned on that landing page you pasted a link to . . . it seems that he steps are very straight forward to get working, and indeed laid out on that exact page.

What are you wanting to do with iio ? The idea of the library does intrigue me too. But I’m, not exactly sure I have the time to learn yet-another-abstraction-layer . . .

Rick, also for what it’s worth. Getting it compiled and working on a system does seem very straight forward and is shown step by step on that landing page you linked to.

Yeah wow, I already said that, hah ! Too much going on . . .

There's a good slide presentation on why mmap() isn't so great, and they talk about the changes they made to the underlying driver and the ioctl() calls they added. libiio wraps those ioctl calls.

It's not what I envision a proper user-space API should look like, but it's much closer. I'm hoping I can write one on top of it, perhaps expanding iio. But when I refer to libiio, I'm also including the necessary updates to the iio driver system.

I do not see where it says mmap() is not so great. I do see where they imply that mmap() is slower than mmap() + DMA. Which does, can, or otherwise makes sense. The block copy idea is also pretty cool, but not unique to iio.

Here is my take on that set of slides:

  1. It is already written.
  2. It is very probably well thought out.
  3. It is yet another abstraction layer - Pluses, and minus.
  4. It is possibly supported. Good if so, bad if not.
  5. built into or can be built into the kernel if supported.
  6. Does use interrupts apparently, so will incur some kind of penalty.

Do I think it would be a cool / good thing to have in the kernel( optionally ) ? No doubt - Yes. But would I use it ? I’m still not convinced. But of course I see most, many or potentially all abstraction layers as initially bad. Bad in that it is something else to learn / understand. Bad that you get a lot of extra stuff typically built in that you do not need. Which leads to bloat, and potential performance issues. Also bad that sometimes it’s more convenient to just use such an abstraction layer, than fully understand it, which can lead to many, many frustrating problems to solve. Very few abstraction layers convince me otherwise, but I would guess that iio would be one to do so. If not, well it is an interesting idea in of it’s self to merit a second look, or four. In fact, I already had thought iio was worth revisiting later, after learning about it a few days ago - While exploring the BBB’s ADC’s.

I should probably make it clearer as to what I mean by “bad” in the context of learning. I love to learn, I think learning is a very good thing. What I really meant is that something like this is something else you have to know, before using it. Which is not always convenient of efficient. Sometimes, it can be though . . .

This must be a fundamentally different philosophy. I come from OS X (and earlier) development, where abstractions are the key to app development. Even libiio isn't nearly abstract enough for my tastes. It still exposes (or requires) knowledge about sysfs and the connected devices. The ADC code I've written on the BBB can't be used on any other computer (the sysfs paths aren't consistent, for starters). A good abstraction would support very high-speed I/O on a wide variety of devices without having to know specifics, like sample size or padding, or configuration steps. It could provide safe callback mechanisms for asynchronous use, too. Even with libiio, you'd still have to build that stuff. I certainly don't want to.

What I envision is something like ALSA, but for ADC (and GPIO). IIO may not be the way to get there, but it seems to have a lot of support already. It probably needs significant additional enhancement to do what I want, but I'd at least like to try using it first.

This must be a fundamentally different philosophy.

Indeed. I believe in a minimalist approach where possible.

But at some point, I believe this could be considered “splitting hairs” on my behalf. As I do use Linux, and POSIX API calls, etc. But all those are standardized and very well documented. In the end, I get tired of wasting my time with projects, or libraries that go no where. Also, investing my time into learning such libraries, or projects, only to find that they’re fundamentally broken, or really do not serve my needs. Tends to upset me. I do not write software to aggravate myself. I write software to achieve an end goal, and because I enjoy it.

It also does not help that I am somewhat of a code snob. Meaning: It really bothers me when code is not well written, or readable. Well formed, simple, and easily readable code is how I prefer things. Short, concise . . . all that. Which is why when I hear people like Linus saying that a function should do one thing well, and only one thing, and should be less than 3-4 pages long . . . I tend to laugh to myself. Because if I’m doing one thing well, and that one well done thing takes 3-4 pages of code. . . Well let me just say that I’d have to find something else to do. Because I’m not very good at writing code. At least that is how I feel. Anyway, this all play a part in using a 3rd party library. In order to get to know a library well, you have to sift through the code line by line. When 90-95% of the code I’ve seen out there, I can not stand to read through. Do you know what ? I don’t have to like it, or even use it. Which is where I wind up most of the time when looking at such libraries.

Anyway, I do not expect you, or anyone else to agree with me. Which is fine.

There is also another aspect to all of this. I like to solve complicated problems. Using the third library can solve complex problems. But the problems I’m usually interested in, is the problem that library has solved. I often wonder how I could solve the same problem, only better. This is not to say I go out there reinventing all the software out there. But it is me realizing that I can do the same things, a lot of the interesting problems already do. The truly interesting problems, to me, I tend to jump into for months on end. Or at least a couple weeks :slight_smile:

Hi Rick,

the linux kernel supports IIO (industrial input output) for quite some
time and the BBB ADC has a IIO driver. You will have to enable the ADC
pins in the device tree.

I just started using the libiio on the BBB to read all 8 ADC channels. I
initially tried it with the latest 4.2.x-bone linux kernel, but ran into
issues enabling buffer continuous mode, so reverted back to 4.1.5-ti-r10
(ubuntu 15.10). Didn't investigate further what makes it different, will
do whenever have the opportunity.

I'm also investigating the low sample rates I'm getting...when creating
the buffer the library complains: "WARNING: High-speed mode not
enabled". The full source code is available and the documentation has
reasonable quality, so it's just a matter of putting some time and
effort improving it.

Just for reference, here's the list of loaded modules after enabling the
ADC through the device tree:

~$ lsmod
Module Size Used by
ti_am335x_adc 5984 0
kfifo_buf 3524 1 ti_am335x_adc
industrialio 52301 2 ti_am335x_adc,kfifo_buf
omap_rng 5254 0
rng_core 8737 1 omap_rng
ti_am335x_tsc 6048 0
ti_am335x_tscadc 6199 2 ti_am335x_adc,ti_am335x_tsc
uio_pdrv_genirq 3745 0
uio 10395 1 uio_pdrv_genirq
tilcdc 32944 0

~$ uname -r

~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu Wily Werewolf (development branch)
Release: 15.10
Codename: wily


Hi Nuno,

Yeah, Rick and I both know about libiio. We’ve actually been talking back and forth by direct email yesterday. I’ve been attempting to find more information on how the sample etc are stored in the buffer. I have been successful reading the buffer one sample at a time however. But the data in the buffer is not how is explained in what little information I could find. Which says something like 16bits data per channel, and optional 64bit time stamp. Where the data values I’m seeing out of the buffer are 32bit values, with 16bit data, and 3 bit id tag.

I could not figure out if fast mode was enabled or not, until now. But where can I find more information on that ? I would like to test it if possible. I really like the whole idea of iio, but it seems maintainers have been coming and going. So finding good information on it is not easy, and what can be found may, or may not apply to the current state of iio . . .

$ uname -r

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 7.8 (wheezy)
Release: 7.8
Codename: wheezy

$ lsmod |grep industrialio
industrialio 41756 2 ti_am335x_adc,kfifo_buf

The first time I’ve noticed kfifo_buf was last night and was curious . . .

I just built libiio, and tested iio_readdev iio:device0, and the sample rate is terrible. Just above 1ksps. Just for perspective, this 4-5 times slower than using sysfs with one-shot mode. Continuous mode through sysfs, I’ve gotten up to around 15ksps.

Using mmap() on /dev/mem/ . . . well lets just say it can keep up with using the PRU’s with the ADC’s in many cases . But not all.