Using SODIMM_190 as a GPIO on the iMX7 with Torizon

I’m trying to learn how to toggle a GPIO output on an iMX7 using Torizon. Everything seems to work inside the module, but the LED attached to module does not change state. I am using SODIMM pin 190 which I think is gpio5.IO[4] or GPIO 132 on the iMX7. I am using that pin because I am testing the iMX7 on a carrier board which we use with the T20 running WinCE - the LED works with WinCE.

Is this pin perhaps not multiplexed as a GPIO by default for Torizon on the iMX7? If not, is there a simple way to make this pin a GPIO?

I’ve had a quick look at this page Device Tree Overlays on Torizon but the process looks daunting compared with the one line of code I’m used to using on WinCE to set the pin multiplexor.

Greetings @MikeS,

The quickest way to test a GPIO in Linux in general would be to use the sysfs approach as outlined in this document: https://developer.toradex.com/knowledge-base/gpio-(linux)#GPIO_Sysfs

In short SODIMM 190’s default function isn’t a GPIO so you’ll need to export it as one then you should be able to manipulate it’s properties via command line as shown in the documentation.

Do note that while this is one of the simplest ways to manipulate GPIOs, depending on the language you’re developing an application in there may be more optimal options.

Best Regards,
Jeremias

Hi @jeremias.tx, thanks for your reply. I was already using sysfs to test this and I found today that I was able to toggle SODIMM_79 / gpio4.IO[18] / GPIO 114 successfully from inside my container running in Torizon on an iMX7. That means that I am using the right commands to export a GPIO pin and switch it on and off (Seeing one GPIO pin toggle state feels like a big step for me) . But I can’t toggle SODIMM_190 / gpio5.IO[4] / GPIO 132 in the same way. Is there something different about SODIMM_190? The reason I am trying to use SODIMM_190 as a GPIO is that we have been using that pin for many years in our own products based on the T20 and WinCE. I’m trying to use an iMX7 with Torizon in the same board design.

I looked at the output from “cat /sys/kernel/debug/pinctrl/30330000.iomuxc/pinmux-pins” and saw these two lines for GPIO 114 and GPIO 132:

pin 92 (MX7D_PAD_ECSPI1_MISO): 30330000.iomuxc 30230000.gpio:114 (HOG) function iomuxc group gpio2-grp
pin 102 (MX7D_PAD_SD1_CMD): 30b40000.usdhc 30240000.gpio:132 function iomuxc group usdhc1-grp

It looks like GPIO 114 is multiplexed for GPIO while GPIO 132 is multiplexed for usdhc1. Can you tell me how to change the multiplex setting for this pin to GPIO? I’m brand new to Linux and Torizon (Moving from WinCE) so a simple explanation of how to manage the device tree would be helpful.

@MikeS, yes you appear to be correct.

So in Linux pin functions are defined by a pinfunc file in the linux kernel (i.e. arch/arm/boot/dts/imx7d-pinfunc.h).

If you take a look here from line 791 to 795 you’ll see all the possible functions for SODIMM 190. This takes the form of the pin’s ball name followed by the function (i.e. MX7D_PAD_SD1_CMD__SD1_CMD ball name = MX7D_PAD_SD1_CMD, function = SD1_CMD).

These pin functions are then referenced in other device tree files, for imx7 it is this one. If you look at like 606 you’ll see that SODIMM 190 with function SD1_CMD is part of group usdhc1-grp, which matches what you observe.

So in short you’ll need to remove that line thereby removing SODIMM 190 from the group then you’ll need to add SODIMM 190 with the appropriate function suffix (MX7D_PAD_SD1_CMD__GPIO5_IO4) into one of the gpio groups in that same file.

Then you’ll need to compile the device tree with your changes, reference here.

At which point you can then replace the device tree running on your device with the new one. For Torizon, device trees are located at the following location on the file system (base system not in the container): /boot/ostree/torizon-{some checksum}/.

By default on boot Torizon loads and uses devicetree-imx7d-colibri-emmc-eval-v3.dtb so you’ll want to replace this device tree binary with your new one with the same name.

I hope this helps outline the process you’ll need to perform on your end. Feel free to ask me for further clarifications, I covered quite a bit of topics quickly.

@jeremias.tx I’ve learned how to compile the device tree, but if I install the result on my iMX7 then it bricks the module and I need to put it into recovery mode and reimage it. I think the problem may be which set of source files I am using, and which branch I have checked out.

If I use “uname -r” to ask for the version of the TorizonCore kernel running on my iMX7 then it replies with “4.19.50-rt22-yocto-preempt-rt”. I think I need to find the source code for that version of the kernel. Does it matter that I am using the PREEMPT_RT version of the image?

This page https://developer.toradex.com/knowledge-base/build-u-boot-and-linux-kernel-from-source-code seems to suggest that I want to use branch toradex_4.9-2.3.x-imx and configuration colibri_imx7_defconfig from git.toradex.com/linux-toradex.git. I checkout out that branch and used these the following two commands on my build machine, without changing any of the source code:

make colibri_imx7_defconfig
make imx7d-colibri-emmc-eval-v3.dtb

Those commands appeared to work but the resulting dtb file was not identical to the one already installed on my module, and when I swapped in the new version my module would no longer boot.

Your last message contained a link to the branch toradex_4.20.y. If I checkout that branch then there is no colibri_imx7_defconfig. There is a config called imx_v6_v7_defconfig but I get an error if I try “make imx_v6_v7_defconfig”.

I also found this page https://developer.toradex.com/knowledge-base/build-torizoncore which mentions this git repo https://github.com/toradex/toradex-torizon-manifest. Do I need to use that repo when building device trees for Torizon? The file structure there looks very different.

Can you confirm which branch I should be using from git.toradex.com/linux-toradex.git?
Can you also confirm which configuration I should be using with the make command?

@jeremias.tx I tried again today and made a little progress. Today I am using branch toradex_4.1-2.0.x-imx and I found that if I rebuilt imx7d-colibri-emmc-eval-v3.dtb without making any source code changes and installed it on my module then the module would boot and behave normally, even though the new dtb file is a bit smaller than the original one.

However, if I edited imx7-colibri.dtsi to try to reassign the GPIO pin and then rebuilt the dtb file then the the module would not boot after I installed it.

The original line in pinctrl_usdhc1 was:
MX7D_PAD_SD1_CMD__SD1_CMD 0x59

I removed that line and added this one to the first GPIO pin group:
MX7D_PAD_SD1_CMD__GPIO5_IO4 0x59

But the module wouldn’t boot with that line added. I noticed that most of the other pins in that group use 0x14 instead of 0x59 so I tried:
MX7D_PAD_SD1_CMD__GPIO5_IO4 0x14

But that also prevented the module from booting.

Next I tried just removing the line from pinctrl_usdhc1 but I didn’t add it to the GPIO pin group. That also prevented my module from booting. Do I need to disable the whole usdhc1 device in order to be able to re-use its pins?

I notice that MX7D_PAD_SD1_CMD__SD1_CMD is also referenced in pinctrl_usdhc1_100mhz and pinctrl_usdhc1_200mhz, do I need to remove it from those groups too?

Hi @MikeS,

If I use “uname -r” to ask for the
version of the TorizonCore kernel
running on my iMX7 then it replies
with “4.19.50-rt22-yocto-preempt-rt”.
I think I need to find the source code
for that version of the kernel. Does
it matter that I am using the
PREEMPT_RT version of the image?

Yes you’ll want the matching kernel version on your source or as close as you can get to it. PREEMPT_RT is not really important for the sake of device trees.

Your last message contained a link to
the branch toradex_4.20.y. If I
checkout that branch then there is no
colibri_imx7_defconfig. There is a
config called imx_v6_v7_defconfig but
I get an error if I try “make
imx_v6_v7_defconfig”.

Unfortunately the Torizon kernel configuration isn’t part of the linux kernel tree. As it is made during the image build process with yocto.

Though an easy way around this is to get the kernel config from your device itself using zcat /proc/config.gz you can then copy this to your kernel source tree into a file called .config. Then in your kernel source you can run make nconfig and then just save and exit. This will make your kernel source use this as the kernel configuration.

I also found this page
https://developer.toradex.com/knowledge-base/build-torizoncore
which mentions this git repo
https://github.com/toradex/toradex-torizon-manifest.
Do I need to use that repo when
building device trees for Torizon? The
file structure there looks very
different.

This is for building the entire image which would be overkill for a device tree change.

Moving onto the actual device tree changes. Your changes look good and they worked on my board (i.e. removing MX7D_PAD_SD1_CMD__SD1_CMD 0x59 from pinctrl_usdhc1 and adding MX7D_PAD_SD1_CMD__GPIO5_IO4 0x14 to pinctrl_gpio1). With these changes my board booted fine and was able to manipulate GPIO 132 (SODIMM 190) with sysfs.

I think in your case you just need to use a version of the kernel source that is closer to what your device is running.

Best regards,
Jeremias

Sorry @jeremias.tx but I’m still struggling with this. I was able to generate a convincing looking config file from my module using zcat /proc/config.gz and I saved that as .config in my linux-toradex folder. Near the top of that file is the line # Linux/arm 4.19.50 Kernel Configuration

I checked out the toradex_4.19.y branch as that one seems closest to my module. But when I run make nconfig I get this error:

  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/nconf.o
  YACC    scripts/kconfig/zconf.tab.c
/bin/sh: 1: bison: not found
scripts/Makefile.lib:196: recipe for target 'scripts/kconfig/zconf.tab.c' failed
make[1]: *** [scripts/kconfig/zconf.tab.c] Error 127
Makefile:544: recipe for target 'nconfig' failed
make: *** [nconfig] Error 2

If I ignore that error and try make imx7d-colibri-emmc-eval-v3.dtb then I get a similar error.

  YACC    scripts/kconfig/zconf.tab.c
/bin/sh: 1: bison: not found
scripts/Makefile.lib:196: recipe for target 'scripts/kconfig/zconf.tab.c' failed
make[2]: *** [scripts/kconfig/zconf.tab.c] Error 127
Makefile:532: recipe for target 'syncconfig' failed
make[1]: *** [syncconfig] Error 2
Makefile:631: recipe for target 'include/config/auto.conf.cmd' failed
make: *** [include/config/auto.conf.cmd] Error 2

Then I tried checking out the toradex_4.1-2.0.x-imx branch. The command make nconfig then worked, and it displayed a menu. I chose save and then exit. This overwrote my .config file with a new file which resembled the one from my module, but with many edits. But now the command make imx7d-colibri-emmc-eval-v3.dtb fails. I think this branch just doesn’t match my module.

Can you tell me which git repo and which branch I should I should be using for this to match the Torizon kernel I am using?

Hi @MikeS,

Judging by your uname -r output you should be using the toradex_4.19.y-rt branch. I was able to compile the device tree with the same method on this branch.

Though your compile errors look like an incorrect toolchain. Have you set up your toolchain for compiling as described here: https://developer.toradex.com/knowledge-base/build-u-boot-and-linux-kernel-from-source-code#Toolchain

You’ll want to use the gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf toolchain for our kernel.

Hi @jeremias.tx, I made a typo in my previous comment. I am using the toadex_4.19.y-rt branch and not the toadex_4.19.y branch as I said yesterday. I am using Ubuntu as a build machine and I set-up my build environment following the instructions on that page, but I did it a year ago. There is a folder in my system called gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf which matches the version number in your last comment.

This is what I am doing, step by step:

  1. cd linux-toradex

  2. git checkout toradex_4.19.y-rt

  3. export ARCH=arm

  4. export PATH=~/gcc-linaro/bin/:$PATH

  5. export CROSS_COMPILE=arm-linux-gnueabihf-

  6. Generate a config file from my module using zcat /proc/config.gz

  7. Copy that file to ~/linux-toradex/.config

  8. make nconfig

  9. Get this error message:

    YACC scripts/kconfig/zconf.tab.c
    /bin/sh: 1: bison: not found
    scripts/Makefile.lib:196: recipe for target ‘scripts/kconfig/zconf.tab.c’ failed
    make[1]: *** [scripts/kconfig/zconf.tab.c] Error 127
    Makefile:532: recipe for target ‘nconfig’ failed
    make: *** [nconfig] Error 2

Am I missing a step?

@jeremias.tx hold on, I just noticed something. I looked into the error “bison: not found” and learned about the bison and flex packages. I installed those on my build machine and now I can compile the device tree without errors. I haven’t tested it on my module yet but I wanted to let you know not to reply to my last comment while I go ahead and test this.

@jeremias.tx it works! Thanks for your help with this, I think I’ve learned a lot of useful stuff.

@MikeS,

Glad to hear it worked out for you!

I apologize for the cumbersome process, in the future with Torizon we plan to create tooling that will allow minor edits of GPIO and device tree properties without the need to recompile and such.

Best Regards,
Jeremias