I’m trying to toggle a GPIO with gpiod on Apalis imx6 + Ixora carrier board but no luck. I think my code is correct and it builds, so I suspect that it’s a hardware access issue. (gpiod_ctxless_find_line is also throwing an error). I’ve tried toggling LED4_GREEN (gpiochip1, line 14), LED5_GREEN (gpiochip2, line 1), and GPIO 1 (gpiochip2, line 4) with no luck.
Code:
// GPIO Test
// try to flash LED4_GREEN, which is pin 188 of MXM3 connector = gpiochip1, line 14
// try to flash LED5_GREEN, which is pin 152 of MXM3 connector = gpiochip2, line 1
int line_value = 0;
char bank[32];
snprintf(bank, sizeof(bank), "gpiochip2");
unsigned int line = 1;
// if (gpiod_ctxless_find_line("SODIMM_188", bank, sizeof(bank), &line) <= 0){
// perror("Error finding GPIO\n");
// return -1;
// }
while(true){
line_value = !line_value;
gpiod_ctxless_set_value(bank,line,line_value,false,"main",NULL,NULL);
sleep(1);
}
and my Dockerfile. (Do I need to manually edit the Dockerfile somewhere?)
# ARGUMENTS --------------------------------------------------------------------
##
# SDK container version
##
ARG SDK_BASE_VERSION=3
##
# Base container version
##
ARG BASE_VERSION=3
##
# Board architecture
# arm or arm64
##
ARG IMAGE_ARCH=
##
# Board GPU vendor prefix
##
ARG GPU=
##
# Directory of the application inside container
##
ARG APP_ROOT=
# BUILD ------------------------------------------------------------------------
# TODO: cross compile x86 to arm
# We will use emulation here
##
# Build Step
##
FROM --platform=linux/${IMAGE_ARCH} \
torizon/qt6-wayland${GPU}:${SDK_BASE_VERSION} AS Build
ARG IMAGE_ARCH
ARG GPU
ARG APP_ROOT
# for vivante GPU we need some "special" sauce
RUN apt-get -q -y update && \
if [ "${GPU}" = "-vivante" ] || [ "${GPU}" = "-imx8" ]; then \
apt-get -q -y install \
imx-gpu-viv-wayland-dev \
; else \
apt-get -q -y install \
libgl1 \
libgles-dev \
; fi \
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# __deps__
RUN apt-get -q -y update && \
apt-get -q -y install \
build-essential \
cmake \
qt6-base-private-dev \
qt6-base-dev \
qt6-wayland \
qt6-wayland-dev \
qt6-declarative-dev \
qt6-declarative-private-dev \
qml6-module-qtqml \
qml6-module-qtqml-workerscript \
qml6-module-qtcore \
qml6-module-qtquick \
qml6-module-qtquick-window \
qml6-module-qtquick-controls \
qml6-module-qtquick-layouts \
qml6-module-qtquick-templates \
libqt6opengl6-dev \
# ADD YOUR PACKAGES HERE
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
# __torizon_packages_dev_start__
libgpiod-dev:armhf \
# __torizon_packages_dev_end__
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# __deps__
COPY . ${APP_ROOT}
WORKDIR ${APP_ROOT}
RUN if [ "$IMAGE_ARCH" = "arm64" ] ; then \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -Bbuild-${IMAGE_ARCH} ; \
elif [ "$IMAGE_ARCH" = "arm" ] ; then \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc -Bbuild-${IMAGE_ARCH} ; \
fi
RUN cmake --build build-${IMAGE_ARCH}
# BUILD ------------------------------------------------------------------------
# DEPLOY -----------------------------------------------------------------------
##
# Deploy Step
##
FROM --platform=linux/${IMAGE_ARCH} \
torizon/qt6-wayland${GPU}:${BASE_VERSION} AS Deploy
ARG IMAGE_ARCH
ARG GPU
ARG APP_ROOT
# SSH for remote debug
EXPOSE 2231
ARG SSHUSERNAME=torizon
# Make sure we don't get notifications we can't answer during building.
ENV DEBIAN_FRONTEND="noninteractive"
# for vivante GPU we need some "special" sauce
RUN apt-get -q -y update && \
if [ "${GPU}" = "-vivante" ] || [ "${GPU}" = "-imx8" ]; then \
apt-get -q -y install \
imx-gpu-viv-wayland-dev \
; else \
apt-get -q -y install \
libgl1 \
libgles-dev \
; fi \
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
# your regular RUN statements here
# Install required packages
RUN apt-get -q -y update && \
apt-get -q -y install \
file \
curl \
qt6-base-private-dev \
qt6-base-dev \
qt6-wayland \
qt6-wayland-dev \
qt6-declarative-dev \
qt6-declarative-private-dev \
qml6-module-qtqml \
qml6-module-qtqml-workerscript \
qml6-module-qtcore \
qml6-module-qtquick \
qml6-module-qtquick-window \
qml6-module-qtquick-controls \
qml6-module-qtquick-layouts \
qml6-module-qtquick-templates \
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
# __torizon_packages_prod_start__
libgpiod2:armhf \
# __torizon_packages_prod_end__
# DO NOT REMOVE THIS LABEL: this is used for VS Code automation
&& \
apt-get clean && apt-get autoremove && \
rm -rf /var/lib/apt/lists/*
USER torizon
# Copy the application compiled in the build step to the $APP_ROOT directory
# path inside the container, where $APP_ROOT is the torizon_app_root
# configuration defined in settings.json.
COPY --from=Build ${APP_ROOT}/build-${IMAGE_ARCH}/bin ${APP_ROOT}
# "cd" (enter) into the APP_ROOT directory
WORKDIR ${APP_ROOT}
# Command executed in runtime when the container starts
CMD ["./AutoFilteringFixture2"]
# DEPLOY -----------------------------------------------------------------------
I’m not getting any build errors, and gpiod_ctxless_set_value is returning 0 (so it thinks it succeeds.) But gpios aren’t actually changing when I debug the code I posted. (LED’s aren’t flashing, and I couldn’t see GPIO1 changing on a scope.)
It would seem that gpiod_ctxless_find_line is also returning 0 when I uncomment that block, so it thinks the SODIMM/MXM3 label doesn’t exist.
A little bit, I’ve had to edit device tree overlays in the past.
I was assuming that this was the device tree in use. Maybe you can give me some guidance… how would I confirm which device tree is actually in use on the module?
It seems to me from this device tree that the LED4 and LED5 GPIOs should be connected to the LEDs. The only overlays I see in /proc/device-tree/chosen/overlays are for hdmi and spi.
Okay good call, it has defaulted to “Toradex Apalis iMX6Q/D Module on Apalis Evaluation Board.” Is there an easy way to swap in a complete device tree, like the one for the Ixora board? I think this doc says I can just scp the new device tree into /home/boot… is that correct?
Also, I wasn’t clear when I said “GPIO1”. I was referring to GPIO 1 on the Ixora carrier board, which is MXM Pin 1 (GPIO2_IO04 in the Apalis datasheet). According to the datasheet this pin should default to GPIO… so that doesn’t explain why that isn’t working. I confirmed again with a scope for MXM Pins 1, 3, and 15 (GPIO2_IO4, GPIO2_IO5, GPIO1IO2). These are GPIO1, GPIO2, and GPIO7 on the carrier board. I’m still not seeing them toggle on a scope when I swap in the bank and line in my code and debug.
I’m certain I’ll need to edit device trees/device tree overlays, but for the moment I just need 7 GPIOs and a couple UARTs.
Yes, the document you listed is the correct resource for changing the device tree for the OS. With Torizon OS, you would be compiling the device tree and still using TorizonCore Builder dt apply command.
I believe the best way to change the device tree is going to be with TorizonCore Builder. Either the standalone tool or via the IDE extension. This will also allow you to build in device tree overlays once setup.
If doing the TorizonCore Builder, you would be customizing the tcbuild.yaml file, such as:
I followed this article and think I’ve built the new image correctly, but I ran into an issue trying to deploy it onto the board via ssh. I have the easy installer running on the SoM and run:
torizoncore-builder deploy --remote-host 192.168.11.1 --remote-username torizon --remote-password torizon --reboot
Pulling OSTree with ref base (checksum 38fad791849b202e09628d45c2781616bdf5f2f34562310f3baed46625b5ac36) from local archive repository...
Starting http server to serve OSTree.
OSTree server listening on "localhost:33351".
An unexpected Exception occurred. Please provide the following stack trace to
the Toradex TorizonCore support team:
Traceback (most recent call last):
File "/builder/torizoncore-builder", line 221, in <module>
mainargs.func(mainargs)
File "/builder/tcbuilder/cli/deploy.py", line 101, in do_deploy
do_deploy_ostree_remote(args)
File "/builder/tcbuilder/cli/deploy.py", line 92, in do_deploy_ostree_remote
dbe.deploy_ostree_remote(args.remote_host, args.remote_username,
File "/builder/tcbuilder/backend/deploy.py", line 294, in deploy_ostree_remote
client.connect(hostname=resolved_remote_host,
File "/usr/lib/python3/dist-packages/paramiko/client.py", line 368, in connect
raise NoValidConnectionsError(errors)
paramiko.ssh_exception.NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 192.168.11.1
I can see from the easy installer that the network info is:
Ethernet - 192.168.1.2/24
USB RNDIS - 192.168.11.1/24
What am I doing wrong? Do I need to change the port somehow? I get “resolve hostname failed” I run the command with 192.168.11.1:24
The 192.168.11.1 IP address is a static IP address for the Toradex Easy Installer. Once you install your image from the easy installer a new IP address is assigned. You’ll want to use that one with username torizon and your new password that it will force you to create. ( shell into device after Toradex Easy Installer image).
With the module connected to the your network, you can use arp-scan to find the IP address of the module. This is typically what I do when I need to know the IP address and don’t already have it.
As a follow up. Because of how the leds node is defined in imx6q-apalis-ixora-v1.2.dts You’ll find the leds available under /sys/class/leds/ and without preforming the pin multiplexing (until needed) you’ll be able to change the LED color via echo 1 > LED_4_GREEN/brightness such as:
@eric.tx It looks like this ultimately got me to the solution! I had to install the image via usb, I couldn’t get deploying via ssh to work. Also, I missed that fact that bank indexing is off by one between the “ALT” names in Apalis imx6 datasheet and the libgpiod library interface…