μArt

The high quality, versatile, and reliable USB-UART converter for both professionals and enthusiasts

Limited items in stock

View Purchasing Options
Oct 18, 2018

Project update 15 of 21

GPIO Interfacing

Hiya!

One of the more common questions I get is about making use of the GPIOs in the μArt. I then answer something along the lines of "once you have a kernel recent enough with the new driver, you can just use the standard sysfs GPIO interface like you do with any other single-board computer". But did you know that there are other possibilities beside the sysfs interface? More importantly, did you know that the sysfs interface that everybody talks about and is most commonly used is officially deprecated and strongly discouraged? And besides, what if you don’t have a recent kernel with the μArt project’s mainline contributions, how can you use GPIOs then? What if you are using Windows, not Linux? This update is all about GPIOs, and we’ll cover all your options.

Overview

One thing I want to point out first is that everything in this article only pertains to the GPIO functions of the μArt. If you need just serial conversion, for UART’ing, then things should just work automagically for you in any application just as you’d expect, and the information here is superfluous to you.

Now, onto the matter. No matter if using Windows or Linux (with whatever kernal version), you can always make use of the GPIOs in the μArt. Depending on your OS environment however, your possibilities will vary. Sometimes you’ll have multiple options, and sometimes you’ll be forced to use a specific solution. The reason I normally point to the sysfs on Linux is because it is something that most people are already familiar with, and it is also the interface that you’ll find the most resources / materials about on the internet. This does not mean, though, that it is always the best option for you. In this update we’ll discuss all options. Still, we won’t go into details too much, as teaching the programming APIs of various libraries, for example, would go way beyond the scope of this writeup.

First, let me list all your options briefly:

You need one of the above options if you either need to control a GPIO line from your host computer, or if you want to read the status of a GPIO line on your host computer. However, if all you need is visual feedback (like an LED) about the state of a data line, you do not need any OS or driver support. Just connect it to the GPI pin on the μArt and observe the GPI (right-most) light. It will turn on if GPI goes low.

Hardware preparations

None needed with the μArt.

Normally, you’d need to reconfigure the EEPROM of the UART IC before it becomes technically possible to use some of the GPIO interfaces. The μArt, however, ships with these necessary pre-programming steps already done, so that you don’t have to mess with its EEPROM configuration just to use its GPIO pins.

libftdi

The libftdi project (website) is an open-source and cross-platform library for communicating with FTDI ICs. The most prominent advantage of using it for GPIO access is that it works equally on all platforms, Windows, Linux, and MacOS X. It is a programming libarry, which means you need to do at least some basic software development to use it. Being a library written in C, you can use it naturally from C or C++, but bindings for other languages (such as for python here, docs) also exist.

Another advantage of libftdi is that you’ll be able to use all GPIO modes of the hardware, including modes that allow implementing real-time protocols and modes where UART pins are re-purposed to GPIOs. Only libftdi and the D2XX APIs can do these.

Using libftdi also has its disadvantages. One is that installation and setup for your project can be a PITA, as you’ll have to tell your OS not to load its native drivers for your device, otherwise libftdi (more specifically libusb that libftdi uses) won’t be able to access it. This is done differently on every OS. On Linux, for example, you need to disable the appropriate kernel module (ftdi_sio). And on Windows probably the easiest way is to use the GUI tools that you get when you install the libusb library, which will ensure the device will bind to libusb instead of the Windows driver. Of course, these measures will disable loading the drivers for other ICs of the same type, too, so you can easily find yourself in a mysterious situation where you cannot use any hardware with a similar IC by FTDI unless you re-enable the native drivers of your OS.

Another (but closely related) problem with having to disable the native OS drivers for libftdi is that you lose your ability to use virtual COM ports. This means your device will no longer appear as a serial COM port on your computer. You can still use the device for serial or UART communication, but you will have to use the libftdi library for that too. This is a big deal. It means if you want to use libftdi (or D2XX) for GPIO, and these two are your only options on Windows and MacOS, you cannot use any standard programs that use COM ports to access the UART interface. In practice, this means if you want both GPIO and serial communication at the same time on these platforms, you will have to implement your own software for both functions. For this reason, GPIO on Linux is a lot easier and cooler, at least with a recent kernel, as the sysfs or libgpiod interfaces do not have this limitation.

If you think libftdi is still the right option for you, take a moment to read about D2XX too before making your final decision, because - at least as far as functionality is concerned - it provides a real alternative for libftdi.

D2XX

This is basically FTDI’s proprietary alternative to libftdi. By that I mean it shares most of its technical advantages and disadvantages, so you should read the section about libftdi first before continuing here. D2XX is made available on the manufacturer’s homepage for download. Example projects and documentation are similarly provided by FTDI itself.

Just like libftdi, you can use the D2XX API under all OS’es. Just like with libftdi, you can use D2XX to access all GPIO modes of your device. D2XX and libftdi also share many of their disadvantages. For one, they do not use the native drivers of any OS, so there are additional installation steps involved. You also cannot use COM ports for serial communication with either D2XX or libftdi, so you won’t be able to use standard programs for the serial interface, and you’ll have to implement that yourself using the corresponding library.

Despite all their similarities, D2XX and libftdi also differ slightly in some aspects. D2XX is a proprietary solution and not open-source, and you cannot recompile it from sources. Being that it comes straight from FTDI, you might enjoy technical support from the manufacturer if you opt for D2XX. Installation and setup for D2XX can be easier than for libftdi, as FTDI provides utilities which make it unnecessary to fiddle with device-driver bindings manually. On Windows for example, you get a separate driver that you can just install using its executable and you are ready to roll. On Mac OS X, a separate "D2xxHelper" utility is provided to automate the configuration process.

In the end, you would use D2XX in the same scenarios where you would use libftdi, and you’d choose between them depending on how important setup experience, openness, and official support are, or which one’s documentation you like better. If you program in some other language than C/C++, the availability of language bindings can also be a factor.

sysfs

Starting with kernel version 4.20, a GPIO driver is available in Linux (contributed by the μArt project itself) that allows you to control GPIOs while at the same time using standard programs to communicate over the serial interface.

What follows is a short tutorial on the sysfs interface. Since it is a standard subsystem of the kernel, much of the following description is not specific to the μArt, but I will add product-specific remarks where applicable.

As many of you will know, sysfs is the pseudo filesystem on Linux that resides under /sys, and it contains not data from a storage medium, but special files and directories that either expose data from the kernel, or make tunable parameters from the kernel available to the user. With sysfs, changing system parameters becomes as easy as writing files, for example with the standard input redirection operator > in your shell. Moreover, Linux contains a whole kernel subsystem specifically for controlling GPIOs, so that all GPIO hardware with a driver is exposed and can be accessed over the same interface. You guessed it, over sysfs. An advantage of this interface is that unlike with libftdi or D2XX, no programming knowledge is required, as you can also use the GPIO pins from your bash (or other shell) using it. Actually, managing GPIOs over sysfs is the most well known and most common method on the internet currently, even though it is officially deprecated (and was always discouraged) and will be removed from Linux in the future. Still, due its popularity, I am inclined to discuss it.

Each GPIO line (a data signal that you want to read or write) belongs to a "gpiochip". Physically, a gpiochip will be a peripheral in the SoC or a separate IC either on the mainboard or connected to it that offers control of hardware pins (a line) as GPIOs. Whenever you want to control a line, the steps necessary will be:

  1. Figure out the gpiochip's number
  2. Request the GPIO line for user control
  3. Set direction of the line (input or output)
  4. Read or write the line's value

Some more detail is probably warranted:

1. Figure out the gpiochip’s number

The easiest way to figure out the gpiochip’s number with plug-and-play devices like the μArt is to take a look at the contents of the /sys/class/gpio directory before and after attaching the μArt. For example, if after plugging in the device a new directory gpiochipN (N being a number) appears, then the number you need is N. Note this number is dynamic and will be different on every system, and will often change even on the same machine. As an exercise, you can then also figure out how many GPIO lines this chip controls by inspecting the contents of the file /sys/class/gpio/gpiochipN/ngpio, but you don’t need this for later steps.

2. Request the GPIO line for user control

As the next step, you have to request that the kernel give you control of a GPIO line. This is because it is also possible for other applications, and even kernel drivers, to make use of a GPIO line, and the request / release mechanism makes sure there is always only one entity controlling a line at any given time. If you find you cannot request a line, the reason is most likely that something else has already claimed it. Another common reason for not being able to request a line is that the hardware is not configured to the correct state, so the line is unavailable at the moment even though nothing has claimed it yet. This is the case for lines 1 and 2 in the μArt, which could be GPIOs as far as the chip is concerned, but they are configured to drive the TX and RX LEDs in hardware, so you cannot request them.

Each line on a gpiochip will be numbered. Most often it is just the number of the GPIO pin in the schematic of your hardware. Unfortunately, there is no automatic way to find out what number your desired pin has, and you will have to consult either the schematic or rely on the manufacturer’s documentation. In the case of the μArt, I will tell you that GPO is number 0 and GPI is number 3.

Now, knowing both the number of the gpiochip and the number of the GPIO pin, you construct the line’s global name as seen by the kernel, by mathematically adding these numbers together. So if your gpiohip had the number 420 and you want to control the GPI pin on the μArt (which is pin 3, remember?), then you know GPI’s name to be 423.

Once you know the line’s number, you request it by simply writing that number to the file /sys/class/gpio/export. In a Linux shell, for the μArt’s GPI, you’d do:

 echo 423 > /sys/class/gpio/export

3. Set direction and value

Things now become easy. After the previous step, a new directory named gpioX (with X being the requested line number) appeared. This folder contains files that you can write to to control the direction and value of the GPIO pin.

Shell examples follow. Note that on the μArt, GPI must always be an input and GPO must always be set to be an output. The examples assume a gpiochip number of 420.

Read GPI (first set direction, then read):

 echo in > /sys/class/gpio/gpio423/direction     
 cat /sys/class/gpio/gpio423/value     

Set GPO to high (sets both direction and value):

echo high > /sys/class/gpio/gpio420/direction

Set GPO to low (sets both direction and value):

echo low > /sys/class/gpio/gpio420/direction

libgpiod

The sysfs interface was the first kernel interface to expose GPIO lines, and over many years it turned out to have quite a number of design deficiencies. People wanted the ability to atomically control multiple lines at the same time, and there were also problems related to event handling and polling, topped off with some line ownership issues. To address these (and some more) problems, a new character-device-based interface was introduced in Linux 4.8, which, for simplicity reasons I will call the "libgpiod interface" (even though libgpiod is actually just the name of the corresponding user-space helper code). Since its introduction, libgpiod is the recommended and best way to control GPIOs under Linux, and the old sysfs interface will be eventually removed completely, possibly in 2020 as current plans go. As Linus Walleij, the current maintainer of the GPIO subsystem put it, "I just want the sysfs to die".

Similarly to sysfs, libgpiod is now a standard kernel interface, and, used with the μArt it too allows you to set and get GPIO pins at the same time while using standard serial communication programs.

As I already said, I call the new interface "libgpiod" too, even though officially it is only the name of the corresponding helper project. However, you can easily use this new interface from your own C code without any library at all using nothing more than your standard open(), read(), write(), poll() and ioctl() calls (if you know what these are). In the same repository, python and C++ bindings are also available. One of the great plusses of the libgpiod user-space code though is that it also provides command-line utilities to manage GPIO lines without any programming knowledge required, so you can manage GPIOs from a shell, or from scripting / programming languages without any bindings or having to call native code.

Unfortunately, resources on libgpiod are a bit scarce, but this PDF provides a nice overview, including simple examples of the new programming API for C and usage of the command-line tools. These command-line utilities are now becoming the standard tools for dealing with GPIOs from a shell or from scripts, though they are too new to be already included by standard on major distributions. For Arch Linux, for example, you’ll only find them in the AUR. On Debian you’ll need the "gpiod" package, which, as of today is not yet available in stable (Debian 9), while Ubuntu will have the same package but only starting with 18.04 (Bionic). Nevertheless, while it is pretty obvious these tools are very new, there is a way to install them on major distributions even without having to resort to compiling from source. Note, the interface and the tools might be new, but they use the same drivers and driver model as sysfs. This means any driver that already worked with sysfs will also work with libgpiod. All you need to do is ensure you have at least kernel version 4.8 (or 4.20 for the μArt).

So, assuming you have installed the gpiod command-line tools, how do you use them? It is really simple, let me give you some examples.

First, lets’s see what GPIO controllers are attached to my computer.

 $ gpiodetect     
 gpiochip420 [ftdi-cbus] (4 lines)

What you see is I have one GPIO controller attached to my laptop, it is called "gpiochip420", claimed by the ftdi-cbus driver, and it has 4 lines in total.

Let’s see if we can get more detailed information.

 $ gpioinfo     
 gpiochip420 - 4 lines:     
 	line   0:      "CBUS0"       unused   input  active-high     
 	line   1:      "CBUS1"       unused   input  active-high     
 	line   2:      "CBUS2"       unused   input  active-high     
 	line   3:      "CBUS3"       unused   input  active-high

Again, we see the same info as before, but we also see each GPIO line listed separately, with names, their current direction, and whether they are currently in use by something or not.

Remember what I wrote earlier - that line 0 of the μArt is GPO, GPI is number 3, and lines 1 and 2 are reserved and cannot be used by the user.

Lets’s change line 0’s (GPO) value to logic high.

 $ gpioset gpiochip420 0=1

Or to low.

 $ gpioset gpiochip420 0=0

We could also try reading the GPI pin of the μArt.

 $ gpioget gpiochip420 3     
 1


What you might notice is that we didn’t have to request lines like we did using sysfs. Well, this is not 100% correct. Technically we did request them, or to be more exact, the gpioset and gpioget tools requested them, but since these tools have already finished running, the lines have been released. This is one of the (many) advantages of the libgpiod interface - an application only owns GPIO lines while it is running, and hence crashed or terminated processes cannot erroneously keep occupying lines they can’t possibly use anymore. This is confirmed when we run gpioinfo again. Even though we’ve messed with both lines 0 and 3, they show up as unused.

 $ gpioinfo     
 gpiochip420 - 4 lines:     
 	line   0:      "CBUS0"       unused   input  active-high     
 	line   1:      "CBUS1"       unused   input  active-high     
 	line   2:      "CBUS2"       unused   input  active-high     
 	line   3:      "CBUS3"       unused   input  active-high

Another difference in comparison to the sysfs interface is that we don’t need to calculate system-global line numbers anymore. For example, the GPI line is simply referred to as "line 3 of gpiochip420" instead of "line 423 on the machine".

Summary

Wow… looong update. But now you know how to use the μArt’s GPIOs using four different ways, under any operating system, when to use which, and which has what advantages. Still, even though I talked about a lot of stuff, some of this information is only scratching the surface. But I’m sure you can figure out the rest ;). Until next time, cheers!


Sign up to receive future updates for μArt.

Subscribe to the Crowd Supply newsletter, highlighting the latest creators and projects