LinuxCon Experience

As part of our internship, we were strongly  encouraged to participate in a conference of interest for us, being offered a $500 travel allowance for it. As soon as I heard about this opportunity, I knew that I want to attend LinuxCon Europe, which took place in Dublin, Ireland, at the beginning of October 2015.

It was the first time I participated in such an important conference and the fact that I had to give a short talk together with the other Outreachy Linux Kernel interns made it even more overwhelming, but at the same time it felt like a great achievement.

Together with a large group of Romanians from my university and not only, we landed in Dublin on Sunday, October 4th, a day before the start of the conference. No need to say that Dublin is well known for its amazing Guinness beer, so we started our journey by verifying this in a local pub and  listening stories from friends who previously attended Linux conferences.

As I previously mentioned, together with Julia Lawall the other kernel interns, two of whom are also Romanians, colleagues of mine at University POLITEHNICA of Bucharest, we had a presentation scheduled, but only on the third day of the conference, so we had a lot of time to get rid of emotions and get to know the people we collaborated with during our internships.

This LinuxCon was special, since there were actually two other important conferences taking place at the same time in Dublin, Embedded Linux Conference and CloudOpen. This was a great opportunity, offering a huge diversity of talks, covering many topics.

The conference started with Jim Zemlin (Linux Foundation) opening remarks, where he highlighted some important facts from Linux world, remembering us that exactly 24 years ago, Linus Torvalds released the first Linux kernel and a few days ago it also was the 30th anniversary of Free Software Foundation. After this, the hardest part started: choosing which talks to attend, many taking place at the same time. Since it would be too much describing each talk I attended, I will just mention a few of them, adding that all were very interesting and I wish that I could’ve been in many places at the same time.

One of the first talks I attended was Read the F* Manual?  Write a Better F* Manual, by Rich Bowen from Red Hat. Rich is an amazing speaker, with over 20 years of Open Source documentation experience and I really enjoyed the talk. It was funny, but at the same time there were a lot of serious lessons about how to interact with the community and how a good documentation plays an important role in the development process.

IMG_20151005_122047

Another talk I attended on the first day of the conference was Introducing the Industrial IIO subsystem – the home of sensor drivers, held by Daniel Băluță, my mentor during the OPW internship, a person from whom I learned a lot and who really guided my first steps in the kernel world. As the name suggests, the talk was about IIO, the subsystem on which I focused during my internship. Daniel presented the steps for writing a sensor driver, features of the IIO subsystem and also some new things regarding IIO. I found the talk very useful for an IIO newbie, but also for someone who already has some experience and needs more detailed information.

IMG_20151005_145952

At the end of the first day I attended a great keynote, Kernel Developer Panel, where some of the greatest kernel figures answered questions from the conference attendees.

IMG_20151005_171711

On the second day of the conference, a talk that I was looking forward to was Using seccomp to Limit the Kernel Attack Surface, by Michael Kerrisk, the author of many Linux man-pages and of “The Linux Programming Interface”, the book that made me love operating systems and system programming. I really enjoyed learning more about seccomp and it really got my interest.

Another moment I couldn’t have missed at LinuxCon was Fireside Chat, between Linus and Dirk Hohndel. It was a funny, light talk, with Linus less acid than I expected. They discussed about kernel security, containers, next projects, etc. Being asked about Linux future, Linus said something I really liked and I think it really summarizes the greatness of Linux community: “Linux did everything I expected it to do in the first six months, everything that came after was about other people solving new and interesting problems. Linux is all these crazy people doing crazy things I never imagined. It’s going to be interesting to see what others will do with it in the next 25 years.”

IMG_20151006_171722

The last day of the conference was the day we held our talk, so there was a lot of nervousness involved. The biggest challenge was to summarize our experience in just 5 minutes, but being sure that we don’t let anything out. Even if I knew the other girls projects, I was very curious to find out about their challenges and their accomplishments. It was awesome that Daniel and Julia were there all the time, supporting us, and even Greg KH attended our presentation and we had the chance to meet him in person.

IMG_20151007_142721

At the end of the last day, there were the closing remarks. These were held in the large auditorium of the CCD, Dublin and a trivia game and a ROCK-PAPER-SCISSORS-SPOCK-LIZARD game took place. It was very funny and a guy from our group even won a box of chocolates.

Summarizing, LinuxCon Dublin was a great experience, with lots of amazing talks, where I met many people I admire for a long time and of course with lots of Guinness, Jim Zemlin being so nice to teach us all how to properly drink it: https://youtu.be/7kxaJQCxAko.

 

 

 

My work lately

Remember the post introducing my new toys, ISL29035 light sensor and DLN-2 adapter? After I got familiar with the hardware and the isl29018 driver, I started working a little on the code.

One of the obvious problems is this driver uses some non-standard sysfs attributes, such as range, range_available, adc_resolution, adc_resolution_available.

In order to fix this I did a set of patches which introduces IIO_CHAN_INFO_RANGE and then refactors isl29018 driver code in order to use standard attributes. Besides this, it also renames lux_scale to calibscale and lux_uscale to ucalibscale to avoid any confusion since these parameters are used for hardware applied calibration.

The purpose of these patches is to change the isl29018 driver to use
standard IIO attributes in order to be moved out of staging.

Besides this, I also worked on a patchset moving iio userspace applications (iio_event_monitor, generic_buffer, lsiio) out of staging. This kind of applications should stay in tools/ directory (for our case in tools/iio/). As part of this patchset, I also worked on iio_utils.h file which had a lot of inline functions, containing a lot of code and that isn’t nice at all. To fix this, I did a patch introducing iio_utils.c and moved all the implementation here.

I’m now waiting for Jonathan to review my patches and hopefully then I can continue with my plan of getting isl29018 driver out of staging.

IIO triggered buffers

As I’ve said in the introductory article about IIO, a subject worth talking about are triggered buffers.

So first let’s see how triggers are used in the IIO Subsystem. A specific trigger can be associated to an IIO device by registering it and set it in iio_device->trig. Also there is the possibility to use a generic trigger for different IIO devices and in this case it should be declared as a separate module.

Let’s have a look at the API the kernel exposes for IIO triggers. To allocate a trigger we should do something like this:

struct iio_trigger *trig = iio_allocate_trigger("foo");

An important field of this structure is .ops. This is a struct iio_trigger_ops and represents the operations structure for an iio_trigger. The key elements to fill here are .owner (usually THIS_MODULE) and .set_triggered_state, function used to switch on/off the trigger on demand. Having all these set, we can then register the trigger using iio_trigger_register.

Currently triggers are only used in IIO  to fill software buffers. Any device supporting INDIO_BUFFER_TRIGGERED has the consumer interface automatically created.

iio_dev structure has a field name .pollfunc, which represents the function triggered at each conversion. Its purpose is to retrieve data from the device and feed them into the buffer. So buffers and triggers are very connected in the IIO Subsystem.

There are two kind of buffers in IIO:

A set of IIO helper functions to set up triggered buffers can be found in drivers/iio/industrialio-triggered-buffer.c. An important function here is iio_triggered_buffer_setup, which will allocate the buffer and the pollfunc, as well as register the buffer with the IIO core.

An example of driver which uses triggered buffers is kxcj-1013. The code that actually does the settings is:

ret = iio_triggered_buffer_setup(indio_dev,
                                 iio_pollfunc_store_time,
                                 kxcjk1013_trigger_handler,
                                 NULL);

To see how the kxcjk1013_trigger_handler is implemented you can have a look here.

A next post about IIO events will come soon and remember, for additional information:

Hardware is here!

As discussed with my mentors, an important part of my project implies changing the driver for Intersil ISL29018 digital ambient light and proximity sensor to use proper IIO ABI and adapt the code to follow the kernel coding style.

Since the driver also has support for ISL29023 and ISL29035 (with some small differences between them), we got the ISL29035 sensor. A few days ago I received all the hardware I need and now I’m ready to start working on it.

Since the device only has an I2C interface, I needed an adapter to easily connect it to my laptop. For that we got DLN-2, an USB-I2C/SPI/GPIO Interface Adapter from Diolan.

The next step was putting them all together and start getting familiar with the driver.

These been said, armed with lots of determination, documentation and a detailed datasheet (hopefully :D), I’m looking forward to getting this driver out of staging!

What is IIO?

Probably everybody knows about I/O Subsystem, but what is Industrial I/O Subsystem?

IIO is a kernel subsystem for analog to digital or digital to analog converters and related hardware. It has been developed since 2009 by Jonathan Cameron and linux-iio community. Examples of devices that fall in this category are: gyroscopes, accelerometers, light sensors, magnetometers, etc.

IIO is organized on two levels, devices and channels:

  • device is the top level of the hierarchy and it represents the acquisition chip. A device is described by the structures iio_info and iio_dev.
  • channel represents a single acquisition source of the device. A channel is described by the iio_chan_spec structure.

IIO communicates with user space via sysfs and a character device. We will have a look at how users can read information from devices.

Lets have a 3-axis accelerometer, mma8452 for example. After compiling and loading the module, if we look under /sys/bus/iio/devices/iio:device0/ we should have the following entries:


roberta@bazinga:~$ ls -l /sys/bus/iio/devices/iio:device0/
(...)
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_sampling_frequency
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_scale
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_x_calibbias
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_x_raw
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_y_calibbias
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_y_raw
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_z_calibbias
-rw-r--r-- 1 root root 4096 ian 21 17:01 in_accel_z_raw
(...) 

The channel definition which gives this entry looks something like this:


#define MMA8452_CHANNEL(axis, idx) { \
    .type = IIO_ACCEL, \
    .modified = 1, \
    .channel2 = IIO_MOD_##axis, \
    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
        BIT(IIO_CHAN_INFO_CALIBBIAS), \
    .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
        BIT(IIO_CHAN_INFO_SCALE), \
    .scan_index = idx, \
    .scan_type = { \
        .sign = 's', \
        .realbits = 12, \
        .storagebits = 16, \
        .shift = 4, \
        .endianness = IIO_BE, \
    }, \
}
static const struct iio_chan_spec mma8452_channels[] = {
    MMA8452_CHANNEL(X, 0),
    MMA8452_CHANNEL(Y, 1),
    MMA8452_CHANNEL(Z, 2),
    IIO_CHAN_SOFT_TIMESTAMP(3),
};

So what are all these fields from  iio_chan_spec structure and what are their roles?

  • .type specifies the type of measurement that the channel is making. In our case (accelerometer), this is set to IIO_ACCEL, but it can have different values, such as: IIO_LIGHT, IIO_VOLTAGE, etc.
  • .modifier specifies if a modifier applies to this channel and in that case modifier is set in .channel2 (IIO_MOD_X, IIO_MOD_Y, IIO_MOD_Z for axial-sensors about the xyz axis)
  • .scan_index and .scan_type fields are used to identify elements from a buffer, when using buffer triggers, but we will discuss more about this in a future post.
  • .info_mask_separate and .info_mask_shared_by_type indicate what information is to be exported that is specific to this channel, respectively that is shared by all channels of the same type. In the example above IIO_CHAN_INFO_RAW, IIO_CHAN_INFO_CALIBBIAS, IIO_CHAN_INFO_SCALE, IIO_CHAN_INFO_SAMP_FREQ were used, but there are also others that can be used according to the driver specifications.

So what is the connection between the entries from /sys/bus/iio/devices/iio:device0/ stated before and these masks?

For instance, reading in_accel_scale calls the read_raw hook with the mask set to IIO_CHAN_INFO_SCALE. Reading in_accel_x_raw calls the read_raw hook with the mask set to IIO_CHAN_INFO_RAW (which is actually 0 since the data should be unscaled) and the channel argument set to the structure corresponding to channel X. More information about all these can be found in documentation.

Next posts will provide a brief overview of IIO triggered buffers (used to limit the amount of reads done by an application) and IIO events (used to receive a notification from the kernel when some event related to IIO happens).

A very nice description of IIO can be found in this presentation.

Additional information:

First round of accepted patches

I started the work at my project by doing some cleanup and small fixes. The patches I sent were accepted and are part of the first round of new IIO drivers, features and cleanups for the 3.20 cycle.

Thanks to some of these patches some Kconfig entries gain annotation with the resulting module name. Other fixes were removing pointless ‘out of memory’ message and unnecessary braces, fix char unsigned order in ad8366, increase the sleep time in ad9523 to make it predictable since that operation isn’t timing critical. Besides all that, there were some patches doing trivial space before comma fixups and white space cleanups.

All these patches are now part of Industrial Input/Output Subsytem tree.

Hello, Linux Kernel World!

Hi everyone! I’m Roberta, a 4th year Computer Science student at University Politehnica of Bucharest, Romania and a big open-source and Linux enthusiast. These two passions made me focus on the Linux kernel internships offered by OPW and here I am today, a part of this great program!

The project that I’ll be working on in the next 3 months is IIO staging drivers cleanup and I will be mentored by Daniel Băluță and Octavian Purdilă. So, what’s the aim of this blog? Well, I hope it will be a kind of a diary, where I’ll post not only the evolution of my project, but also useful information and tips about Industrial I/O subsystem.

I’ve always wanted to contribute to an important open-source project in a way that matters and Linux kernel seems to be the right choice. I see this internship as an amazing opportunity and I’m sure I’ll enjoy it. Stay tuned!

Many thanks to ROSEdu community for initiating, supporting and developing education based on Open Source values in Romania!