Skip to main content
Version: Torizon OS 6.x.y

How to Use GPIO on Torizon OS

Introduction

This article presents the essential steps for using GPIO on Torizon OS devices. It does not describe how to customize Torizon OS for using GPIO pins that require any device tree modification. If you want to change pin functionalities, refer to the Pin Multiplexing - Changing Pin Functionalities in the Linux Device Tree article. If your image is already customized to make the GPIO pin available, the instructions from this article are also valid.

After reading this guide, you will be able to incorporate GPIO into your application. This article covers the following topics:

  • Check the available GPIO pins in your carrier board
  • Test GPIO pins
  • Use GPIO inside containers
  • Build and run sample applications

This article complies with the Typographic Conventions for Toradex Documentation.

Can I use GPIO user space SysFS?

The Kernel Linux has deprecated GPIO user space SysFS. However, the kernel config CONFIG_GPIO_SYSFS is still enabled on Toradex's BSP to support customers using it in their legacy applications. You can check the configuration by running zcat /proc/config.gz | grep CONFIG_GPIO_SYSFS. For GPIO access from userspace, the new char device API, also known as libgpiod, must be used.

For detailed information on using the command-line tools and the C API, refer to GPIO (Linux).

info

Torizon OS supports various non-generic features such as GPIO power management keys, GPIO power off, GPIO LED and others explained in GPIO (Linux).

What is libgpiod?

The libgpiod library provides a straightforward API that encapsulates the complexities of the Operating System, including ioctl calls and data structures for working with GPIO. Additionally, the libgpiod project offers a set of command-line tools for GPIO manipulation from the command line. These tools can be used as replacements for scripts previously based on the deprecated sysfs API. They can be helpful for quickly verifying if the targeted GPIO pins are available to your application.

The new user space API uses the /dev/gpiochip devices through Operating System calls to manage GPIOs:

# ls /dev/gpiochip*
/dev/gpiochip0 /dev/gpiochip2 /dev/gpiochip4 /dev/gpiochip6
/dev/gpiochip1 /dev/gpiochip3 /dev/gpiochip5 /dev/gpiochip7

Each entry on the /dev/gpiochip corresponds to a GPIO bank that the operating system has access to.

Prerequisites

Pin Standardization

On Torizon OS, the GPIO pins are named based on the module's edge connector type. Verdin and Colibri modules use the name SODIMM for GPIO pins, while Apalis modules use MXM3. This naming convention simplifies pin identification and usage, allowing users to refer to pins by name instead of bank and line. Follow the next steps to identify and test GPIO pins.

Find Available GPIO Pins

This section provides a step-by-step guide on how to identify available GPIO pins of a SoM and locate the corresponding connector on both the SoM and the carrier board.

1. Identify SODIMM/MXM3 Pins on Modules

Each SoM offers multiple dedicated GPIO pins. Some of those are reserved for other interfaces. Additionally, several modules' pins can be used as GPIO if their primary function is not in use. To ensure compatibility across modules, prioritize the utilization of dedicated GPIO pins.

Refer to the GPIO section of the SoM's datasheet for information on available GPIO pins. If you are performing a quick evaluation, you can select a GPIO pin directly available on a carrier board connector, as explained in the next section.

The following example shows the GPIO table for the Verdin iMX8M Plus.

Also, ensure that the chosen pin is not reserved for any other interfaces (which is the case for pin 216 in the above example).

Using GPIO pins other than the dedicated requires device trees modification. However, this is not covered in this article. If you need to modify the device tree to use GPIO pins, refer to the Pin Multiplexing - Changing Pin Functionalities in the Linux Device Tree article.

2. Identify GPIO Pins on the Carrier Board

Refer to your carrier boards' datasheet or schematic and identify a SODIMM/MXM3 Pin connected to the GPIO interface and available through a connector on the carrier board.

For instance, you can find valuable information in the Verdin Development Board datasheet. In the IO pin configuration table you will find the GPIO pins, SODIMM pins, and signal names available through the X5 connector:

3. Record the Pin Details

Once you have selected a GPIO pin, write down its SODIMM/MXM3 Pin, and the corresponding connector.

The relevant information for the GPIO_3 pin is listed below:

  • Connector location: X5
  • SODIMM Pin: 210

Hardware Setup to Test a GPIO Pin

In this section, you will learn how to setup the hardware for testing GPIO pins.

1. Locate the GPIO Pin on Your Carrier Board

The carrier board's datasheet or schematic can help you to locate the GPIO pin. Alternatively, you can directly search for the GPIO pin using the labels on your carrier board.

The image below shows the GPIO_3 connector location on the Verdin Development Board.

GPIO Pin Location

2. Prepare your Testbed

To test the GPIO pin, you can utilize either a multimeter or an LED to verify the logic level of the connector. When using an LED, ensure you match the voltage and current of both the LED and the GPIO pin. If necessary, consider using a driver circuit to power the LED correctly.

The Verdin Development Board already provides LEDs with driver circuits for quick evaluation.

LED schematic

Thus, we can directly connect the GPIO pin to the carrier board's LED interface.

Testbed

danger

The TTL level for Colibri and Apalis I/O is 3.3V, while for Verdin is 1.8V. Do not apply 3.3V signals to Verdin I/O.

Test GPIO Pins from a Container

In this section, you will learn how to make the GPIO pin accessible from a Docker container. Then, you will check if the pin works as expected before using it in your application.

1. Run the Toradex Pre-built Container

Toradex provides a pre-built container with libgpiod installed, which enables you to confirm that the GPIO pin is working as expected.

To download the image and build the container for testing, run the following command on the board's terminal:

# docker run --rm -it -v /dev:/dev --device-cgroup-rule='c 254:* rmw' torizonextras/arm64v8-gpiod

2. Ensure Access to the GPIO Pin from the Container

Take note of its bank and line, as they will be needed for testing using libgpiod commands, such as gpioset.

# gpiofind <SODIMM/MXM3_PIN>

For instance, you would get the following output for SODIMM_210 of the Verdin Development Board:

Testbed

It means that our pin is located at bank 0 and line 5.

If you are experiencing difficulties finding a GPIO pin, you can alternatively execute the command provided below and manually search for the pin.

# gpioinfo

3. Toggle the GPIO Pin

Change the logic level of the pin and verify if it works as expected.

# gpioset <bank> <line>=<logic_level>

For example, we could turn the LED on by running the following command.

# gpioset 0 5=1

LED On

Command-line Tools Usage

After launching the container, you can run any libgpiod command inside the container. For detailed information, refer to the section Command Line Tools on GPIO (Linux).

Best Practices for Production

Use SODIMM/MXM3 Pin Names

Although it is acceptable to use bank and line for testing, using the SODIMM/MXM3 Pin names helps you to simplify your code. SODIMM/MXM3 Pin names are also guaranteed to not change during Torizon/BSP upgrades, minimizing impact of OS upgrades on your application.

Specify Accessible Devices within the Container

To test the GPIO pin, we provided container access to all GPIO banks using the --device-cgroup-rule='c 254:* rmw' flag. However, it is recommended to only share the required banks with the container using the --device flag when in production. For example:

# docker run --rm -it --device /dev/gpiochip0 <yourDockerHubUsername>/<DockerHubRepository>

If the container needs to access multiple GPIO banks, you will need to specify the --device argument multiple times, as shown in the following example:

# docker run --rm -it --device /dev/gpiochip0 --device /dev/gpiochip1 --device /dev/gpiochip2 <yourDockerHubUsername>/<DockerHubRepository>

Use GPIO as Non-root User

A best practice for Dockerfile is to run containers as non-root users. This approach ensures that containers only have the necessary permissions. In this case, you will have to add the user to the GPIO group adding the following command to your Dockerfile:

RUN usermod -a -G gpio torizon
Dockerfile example
ARG BASE_NAME=debian
# Image for arm64 architecture
ARG IMAGE_ARCH=linux/arm64/v8
# Image for arm architecture
#ARG IMAGE_ARCH=linux/arm/v7
ARG IMAGE_TAG=3-bookworm
ARG DOCKER_REGISTRY=torizon

FROM --platform=$IMAGE_ARCH $DOCKER_REGISTRY/$BASE_NAME:$IMAGE_TAG

RUN apt-get -y update && apt-get install -y --no-install-recommends \
gpiod \
&& apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*

# Allow the user torizon use GPIOs
RUN usermod -a -G gpio torizon

# Add sample bash scripts for convenience
COPY ./*.sh /usr/local/bin/

# Run the container using the torizon user
USER torizon

CMD [ "bash" ]

C Language Examples

This section illustrates how to use C API from libgpiod. Pre-built containers are not provided, therefore you are encouraged to build your own.

1. Clone the Torizon Samples Repository

First, clone the torizon-samples repository into your development PC:

$ git clone https://github.com/toradex/torizon-samples.git
$ cd torizon-samples/gpio

Then, you will build, deploy and run the application container, as explained in the next sections.

2. Build the Docker Image With the C Samples

In this section, you will compile all the C examples and build a container image that can be easily deployed to the board.

Dockerfile of the sample

Assuming you have cloned the torizon-samples repository as described in the Software Requirements, you can modify and rebuild the image on your development PC.

Select your SoM from the tabs below:

To begin, build the container image.

$ docker build --build-arg CROSS_TC_IMAGE_ARCH=arm64 --build-arg GCC_PREFIX=aarch64-linux-gnu --build-arg IMAGE_ARCH=linux/arm64 -t <yourDockerHubUsername>/arm64v8-c-gpiod .

Upload the generated image to your Docker Hub:

$ docker login
$ docker push <yourDockerHubUsername>/arm64v8-c-gpiod

After that, on the board's terminal, run the following command to pull the image from Docker Hub:

# docker pull <yourDockerHubUsername>/arm64v8-c-gpiod

The following sections will guide you through running C samples using the containers you previously built.

3. How to Toggle a GPIO

Run the gpio-toggle application example, which is available in the previously built and deployed container. Choose your SoM architecture from the tabs below:

This example continuously toggles the GPIO_3 of the Verdin Development Board:

# docker run --rm -it --device /dev/gpiochip0 <yourDockerHubUsername>/arm64v8-c-gpiod
## gpio-toggle SODIMM_210

4. Read GPIO Using Events (Interrupt Driven)

Run the gpio-event application example, which is available in the previously built and deployed container. Choose your SoM architecture from the tabs below:

This example uses GPIO_1 of the Verdin Development Board as input and GPIO_2 as output. It means the application waits for rising edges on GPIO_1 and then toggles the GPIO_2.

# docker run --rm -it --device /dev/gpiochip0 <yourDockerHubUsername>/arm64v8-c-gpiod
## gpio-event SODIMM_206 SODIMM_208

Next Steps

This article presented the first steps for using GPIO on Torizon OS devices. To support your next steps, Toradex provides comprehensive documentation that will enhance your experience of embedded application development. We recommend exploring the following articles:



Send Feedback!