GPIO and #include <gpiod.h>

My setup:
Colibri iMX6 512MB IT v1.1B running on the
Colibri Evaluation Board
TorizonCore upstream 5.6.0

I am struggling to run the gpio-toggle.c sample.

I would be okay if I could skip this step and just get the gpiod.h library into my development container for VSCODE, but maybe I should do it properly…

I can see there are instructions but I am unable to follow.

I have downloaded the torizon-samples configured my development environment by sourcing the following batch file from my /~/tcbworkdir:

wslfetch
sudo apt-get update && sudo apt-get install rsync ssh
sudo apt install openssh-client
docker --version
docker run hello-world
docker run --rm -it --privileged torizon/binfmt
docker run --platform linux/arm/v7 --rm -it arm32v7/debian arch
docker run --platform linux/arm64/v8 --rm -it arm64v8/debian arch
rm tcb-env-setup.sh*
wget https://raw.githubusercontent.com/toradex/tcb-env-setup/master/tcb-env-setup.sh
source ./tcb-env-setup.sh

Then I made a copy of the Dockerfile.armhf file and put it in the tcbworkdir as well.

But I get this error message:

leighjboyd@EMERALENOVO11:~/tcbworkdir$ docker build -f Dockerfile.armhf -t leighjboyd/arm32v7-c-gpiod .
Sending build context to Docker daemon  1.096GB
Step 1/17 : ARG CROSS_TC_IMAGE_ARCH=armhf
Step 2/17 : ARG CROSS_TC_DOCKER_REGISTRY=torizon
Step 3/17 : ARG BASE_NAME=debian
Step 4/17 : ARG IMAGE_ARCH=linux/arm/v7
Step 5/17 : ARG IMAGE_TAG=2-bullseye
Step 6/17 : ARG DOCKER_REGISTRY=torizon
Step 7/17 : FROM $CROSS_TC_DOCKER_REGISTRY/debian-cross-toolchain-$CROSS_TC_IMAGE_ARCH:$IMAGE_TAG AS cross-container
 ---> 4f8af6cdb008
Step 8/17 : ARG GCC_PREFIX=arm-linux-gnueabihf
 ---> Using cache
 ---> 2d848376ad7c
Step 9/17 : ARG CROSS_TC_IMAGE_ARCH
 ---> Using cache
 ---> cc101410d8ef
Step 10/17 : RUN apt-get -y update && apt-get -y upgrade && apt-get install -y --no-install-recommends     libgpiod-dev:$CROSS_TC_IMAGE_ARCH     libgpiod2:$CROSS_TC_IMAGE_ARCH     && apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> 07b31403182e
Step 11/17 : WORKDIR /project
 ---> Using cache
 ---> 291eb787898f
Step 12/17 : COPY . /project
 ---> Using cache
 ---> bb475ee1b291
Step 13/17 : RUN mkdir build && cd build     && $GCC_PREFIX-gcc -o gpio-toggle ../gpio-toggle.c -lgpiod     && $GCC_PREFIX-gcc -o gpio-event ../gpio-event.c -lgpiod
 ---> Running in ffb4a0734e47
arm-linux-gnueabihf-gcc: error: ../gpio-toggle.c: No such file or directory
The command '/bin/sh -c mkdir build && cd build     && $GCC_PREFIX-gcc -o gpio-toggle ../gpio-toggle.c -lgpiod     && $GCC_PREFIX-gcc -o gpio-event ../gpio-event.c -lgpiod' returned a non-zero code: 1

If Im understanidng this right, step 13/17 seems to think gpio-toggle.c should be in a parallel folder from where I run this command. (…/gpio-toggle.c)

If I try this from the location where the Dockerfile.armhf is located :

leighjboyd@EMERALENOVO11:~/torizon-samples/gpio/c$ docker build -f Dockerfile.armhf -t leighjboyd/arm32v7-c-gpiod .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /home/leighjboyd/torizon-samples/gpio/c/Dockerfile.armhf: no such file or directory

So that’s not the right location either…

Should I copy the /gpio/c/gpio-toggle.c folder so that it is in fact located parallel to tcbworkdir?

Also tried running from the torizon-samples folder:

leighjboyd@EMERALENOVO11:~/torizon-samples$ docker build -f Dockerfile.armhf -t leighjboyd/arm32v7-c-gpiod .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /home/leighjboyd/torizon-samples/Dockerfile.armhf: no such file or directory

I am hoping that all this will magically solve my REAL issue which is that

#include <gpiod.h> is not found
image

The last time I experienced a problem like that I went in to docker and installed the library file via the CLI there. but I’m sure that’s not best practice… I am hoping there is a way to use VSCODE to command an apt-get to get the necessary library(ies).

Leigh

Hi @leighjboyd,

Let me see if I got this right: you’re trying to run the gpio-toggle.c sample (torizon-samples/gpio-toggle.c at bullseye · toradex/torizon-samples · GitHub) using VSCode with our extension for Torizon, but in your project you have an include file (gpiod.h) not being found. Is this correct?

Judging by some commands that you ran I assume you installed the extension and did the initial setup following our Developer page (Visual Studio Code Extension for Torizon | Toradex Developer Center).

You should if you haven’t already create a C/C++ project in VSCode as instructed in C/C++ Development and Debugging on TorizonCore Using Visual Studio Code | Toradex Developer Center. Make sure that:

The include error indicates that the SDK container doesn’t have all the necessary development packages to build the project, and you can instruct the container to install a Debian package before compilation:

  • On VSCode, go to the Torizon extension config page and edit devpackages by adding libgpiod-dev:#%platform.debian-arch%# (in your case libgpiod-dev:armhf should also work);

  • Once applied you will be prompted to rebuild the SDK container: click on Rebuild & reload now. The include error should be gone.

The section Add Libraries Available on Debian Feed of the previous page has these exact steps in more detail. I recommend reading through the rest of it as well as the following sections.

Please let me know if that helps and if you need any additional support.

Best regards,
Lucas Akira

So yes, I have added gpio-toggle.c directly to my program actually, (its the first call in main) which I created according to the instructions - i.e. using a remote container, wsl running.

I believe I have set up the visual studio code extension for torizon correctly.

I added the code to the makefile.

Now when I added the libgpiod to the devpackages, and rebuilt the container (took quite some time…)

Now the squiggle indicating that the compiler cannot find the gpiod.h library from VSCODE has disappeared. but now I get:

> Executing task: make <

arm-linux-gnueabihf-gcc -c -o EmeraBlockEnergyBox.o EmeraBlockEnergyBox.c -g -LINUX
Finished compiling all .c and .h files

arm-linux-gnueabihf-gcc -o EmeraBlockEnergyBox EmeraBlockEnergyBox.o -g -LINUX
/usr/lib/gcc-cross/arm-linux-gnueabihf/10/../../../../arm-linux-gnueabihf/bin/ld: EmeraBlockEnergyBox.o: in function `ToggleGPIO':
/workspaces/EmeraBlockEnergyBox/GPIOhandler.c:15: undefined reference to `gpiod_ctxless_find_line'
/usr/lib/gcc-cross/arm-linux-gnueabihf/10/../../../../arm-linux-gnueabihf/bin/ld: /workspaces/EmeraBlockEnergyBox/GPIOhandler.c:34: undefined reference to `gpiod_ctxless_set_value'
collect2: error: ld returned 1 exit status

The strange part is that I can hover over the offending functions and see the tool-tip help:

int gpiod_ctxless_find_line(const char *name, char *chipname, size_t chipname_size, unsigned int *offset)
SPDX-License-Identifier: LGPL-2.1-or-later

I have the following set up…

username:
root

devices:

/dev/spidev3.0
/dev/colibri-i2c
/dev/gpiochip0
/dev/gpiochip1
/dev/gpiochip2
/dev/gpiochip3

extraparams:
cap_add CAP_NET_ADMIN

dockercomposefile docker-compose.yml

build commands:
RUN usermod -a -G gpio,dialout torizon

dev packages:
libgpiod-dev:#%platform.debian-arch%#

extra packages:
iproute2 can-utils python3-can python3-pexpect

and dockerfile:

FROM emerablockenergybox_arm32v7-debian-no-ssh_bullseye_debug_69ac5093-51e4-4f03-8827-ec9f9390dfe3_sdk_image

# This is required to allow regular user inside the container to access docker socket

RUN addgroup docker && groupmod --non-unique --gid 0 docker && adduser torizon docker

Could there also be a problem that I don’t have the right username? You mention I should use torizon, but I need root for CAN bus…

I am rebuilding the container again to see if that helps.

Am I supposed to do something with this:

[13162 ms] Start: Run in container: /bin/sh -c mkdir -p /home/torizon/.vscode-server-insiders/extensions ; mkdir -p /home/torizon/.vscode-server/extensions; ln -s /home/torizon/.torizon-extension /home/torizon/.vscode-server-insiders/extensions/toradex.torizon ; ln -s /home/torizon/.torizon-extension /home/torizon/.vscode-server/extensions/toradex.torizon ; chgrp docker /var/run/docker.sock ; true
chgrp: changing group of '/var/run/docker.sock': Operation not permitted

docker build log:

[75 ms] Start: Resolving Remote
[93 ms] Setting up container for folder or workspace: c:\GitHub3\EmeraBlockEnergyBox
[110 ms] Start: Check Docker is running
[110 ms] Start: Run: docker version --format {{.Server.APIVersion}}
[380 ms] Server API version: 1.41
[380 ms] Start: Run: docker volume ls -q
[758 ms] Start: Run: docker inspect --type container a47e914fd9388405a4838bea69d83ef22faa8d47aef0e8aec214c268a6ce27e7
[1083 ms] Start: Run: docker ps -q -a --filter label=vsch.local.folder=c:\GitHub3\EmeraBlockEnergyBox --filter label=vsch.quality=stable
[1444 ms] Start: Run: C:\Users\LeighBoyd\AppData\Local\Programs\Microsoft VS Code\Code.exe c:\Users\LeighBoyd\.vscode\extensions\ms-vscode-remote.remote-containers-0.234.0\dist\spec-node\devContainersSpecCLI.js up --user-data-folder c:\Users\LeighBoyd\AppData\Roaming\Code\User\globalStorage\ms-vscode-remote.remote-containers\data --container-data-folder .vscode-server/data/Machine --container-system-data-folder /var/vscode-server --workspace-folder c:\GitHub3\EmeraBlockEnergyBox --workspace-mount-consistency cached --id-label vsch.local.folder=c:\GitHub3\EmeraBlockEnergyBox --id-label vsch.quality=stable --log-level debug --log-format json --config c:\GitHub3\EmeraBlockEnergyBox\.devcontainer\devcontainer.json --default-user-env-probe loginInteractiveShell --mount type=volume,source=vscode,target=/vscode,external=true --skip-post-create --update-remote-user-uid-default on --mount-workspace-git-root true
[1640 ms] remote-containers 0.234.0.
[1640 ms] Start: Resolving Remote
[1643 ms] Start: Run: git rev-parse --show-cdup
[1693 ms] Start: Run: docker ps -q -a --filter label=vsch.local.folder=c:\GitHub3\EmeraBlockEnergyBox --filter label=vsch.quality=stable
[121852 ms] Start: Run: docker build -f c:\GitHub3\EmeraBlockEnergyBox\.devcontainer\Dockerfile -t vsc-emerablockenergybox-06d53ccbef969652194c0db32672db33 c:\GitHub3\EmeraBlockEnergyBox\.devcontainer
Sending build context to Docker daemon  6.144kB
Step 1/2 : FROM emerablockenergybox_arm32v7-debian-no-ssh_bullseye_debug_69ac509
3-51e4-4f03-8827-ec9f9390dfe3_sdk_image
 ---> f104a8b1ca8c
Step 2/2 : RUN addgroup docker && groupmod --non-unique --gid 0 docker && adduse
r torizon docker
 ---> Using cache
 ---> c4d5a5cdd37b
Successfully built c4d5a5cdd37b
Successfully tagged vsc-emerablockenergybox-06d53ccbef969652194c0db32672db33:lat
est
SECURITY WARNING: You are building a Docker image from Windows against a non-Win
dows Docker host. All files and directories added to build context will have '-r
wxr-xr-x' permissions. It is recommended to double check and reset permissions f
or sensitive files and directories.

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and l
earn how to fix them
[125171 ms] Start: Run: docker events --format {{json .}} --filter event=start
[125182 ms] Start: Starting container
[125182 ms] Start: Run: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=c:\GitHub3\EmeraBlockEnergyBox,target=/workspaces/EmeraBlockEnergyBox,consistency=cached --mount source=C:\Users\LeighBoyd/.moses,target=/home/torizon/.moses,type=bind --mount source=//var/run/docker.sock,target=/var/run/docker.sock,type=bind --mount source=c:\Users\LeighBoyd\.vscode\extensions\toradex.torizon-1.4.0,target=/home/torizon/.torizon-extension,type=bind --mount type=volume,src=vscode,dst=/vscode -l vsch.local.folder=c:\GitHub3\EmeraBlockEnergyBox -l vsch.quality=stable -e AR=arm-linux-gnueabihf-ar -e AS=arm-linux-gnueabihf-as -e CC=arm-linux-gnueabihf-gcc -e CXX=arm-linux-gnueabihf-g++ -e CPP=arm-linux-gnueabihf-cpp -e LD=arm-linux-gnueabihf-ld -e STRIP=arm-linux-gnueabihf-strip -e CROSS_COMPILE=arm-linux-gnueabihf- --network=host --entrypoint /bin/sh vsc-emerablockenergybox-06d53ccbef969652194c0db32672db33 -c echo Container started
[245597 ms] Error response from daemon: i/o timeout

[245597 ms] Docker events terminated (code: 1, signal: null).
Container started

tried devpackages:
libgpiod-dev:armhf and noticed that I forgot to initialize the development environment for building Toradex containers…

unfortunately, its still not rebuilding the container…

oh wait! yes it is! just took 5 attempts!

It worked with libgpiod-dev:armhf, but not with the environment variable

Hi @leighjboyd ,

The undefined reference errors are caused when you don’t link all the necessary libraries when compiling. To avoid it you can pass the flag -lgpiod in your Makefile to link the gpiod library. The resulting GCC command should be something similar to this:

arm-linux-gnueabihf-gcc -o EmeraBlockEnergyBox EmeraBlockEnergyBox.o -lgpiod -g -LINUX

There shouldn’t be any problems setting up the container user as root. As for this message:

chgrp: changing group of '/var/run/docker.sock': Operation not permitted

It is a known bug in our extension unrelated to your issue that shouldn’t cause any problems. It has been fixed recently, but you can safely ignore it.

Try including the flag I mentioned above and let me know if that solved your issue.

Best regards,
Lucas Akira

that got me a little bit further, thanks… but now I get this error instead:
unable to start debugging. Unexpected GDB output from command “interpreter-exec console @set architecture %{torizon.gdb-arch}”. Undefined item: %{torizon.gdb-arch}"
image

[1] + Done “/usr/bin/gdb-multiarch” --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-so05slv2.rvj" 1>"/tmp/Microsoft-MIEngine-Out-r02kq0hv.ty1"
torizon@docker-desktop:/workspaces/EmeraBlockEnergyBox$

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C++ Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}\\EmeraBlockEnergyBox",
            "args": [
                "-I", "5000",
                "-s", "50",
                "-v"
            ],
            "miDebuggerServerAddress": "",
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}",
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "gdb-multiarch",
            "targetArchitecture": "",
            "preLaunchTask": "${defaultBuildTask}",
            "setupCommands": [

                {
                    "description": "Setting architecture",
                    "text": "set architecture %{torizon.gdb-arch}",
                    "ignoreFailures": false,
                    "externalConsole":false
                }
            ]
        }
    ]
}

tasks.json
{

"version": "2.0.0",
"tasks": [
    {
        "label": "build_debug",
        "command": "make",
        "type": "shell",
        "args": [],
        "problemMatcher": {
            "base": "$gcc"
        },

        "options": {
            "env": {
                "CFLAGS": "-lgpiod -g -LINUX",
                "CXXFLAGS": "-g"
            }
        },

        "group": {
            "kind": "build",
            "isDefault": true
        }
    },

    {
        "label": "build_release",
        "command": "make",
        "type": "shell",
        "args": [],
        "problemMatcher": {
            "base": "$gcc"
        },

        "options": {
            "env": {
                "CFLAGS": " "
            }
        },
        "group": "build"
    },

    {
        "label": "clean",
        "command": "make",
        "type": "shell",
        "args": [
            "clean"
        ],
        "problemMatcher": {
            "base": "$gcc"
        },
        "group": "build"
    },

    {
        "detail": "deploy application to work folder",
        "label": "deploy",
        "command": "make",
        "args": [
            "WORKDIR=${command:torizon.ccpp.getTargetFolder}",
            "install"
        ],
        "type": "shell",
        "group": "none"
    }
],
"options": {
    "env": {
        "TORIZON_PROP_ARG": "ARG SSHUSERNAME=#%application.username%#\n"
    }
}

}

OKAY!
UPDATE: after a few restarts of vscode, it seems to finally build the dev container, compile, link but then crash on this error message

gdbserver: Error disabling address space randomization: Success
Process /EmeraBlockEnergyBox/EmeraBlockEnergyBox created; pid = 9
Listening on port 6502
Remote debugging from host 192.168.1.160, port 61880
/EmeraBlockEnergyBox/EmeraBlockEnergyBox: error while loading shared libraries: libgpiod.so.2: cannot open shared object file: No such file or directory
Child exited with status 127
!

Hi @leighjboyd ,

after a few restarts of vscode, it seems to finally build the dev container, compile, link but then crash on this error message

So you managed to get past the Undefined item: "%{torizon.gdb-arch}" error, is that correct?

I believe the shared library loading error is caused when the container that will run on the device (which is different from the SDK one) doesn’t find the libraries it needs at runtime. To install packages on this container you need to list the necessary packages in extrapackages, as written in C/C++ Development and Debugging on TorizonCore Using Visual Studio Code | Toradex Developer Center. From your previous message I see that you have not included the libgpiod2 package:

extrapackages
iproute2 can-utils python3-can python3-pexpect

Try to include libgpiod2 like so:

extrapackages
iproute2 can-utils python3-can python3-pexpect libgpiod2

See if that works for you.

Best regards,
Lucas Akira

yes, I had to use armhf instead of the environment variable (couldnt figure out where this is getting set, or not)

Now its all compiling and running! You’re a genius!!

Thanks!

I’m glad I was able to help!

Best regards,
Lucas Akira