GPIO Access Lost After Flashing balenaOS on Seeed reComputer J4012 Industrial

With the default Seeed image for the reComputer J4012 Industrial, I can easily access and control the GPIO ports on the front of the device. However, after flashing balenaOS, I can no longer control them.

  • I can see both gpiochip0 and gpiochip1 listed.
  • Using gpioinfo, I can inspect the lines, and they are correctly labeled (e.g., PN.01).
  • I’ve followed the guidance provided here: Seeed Jetson GPIO Wiki.

The issue:

When I run gpioset --mode=wait gpiochip0 85=1 under balenaOS, it does not trigger the GPIO. The exact same command works as expected with the Seeed default image on the same hardware.

Is there an additional configuration or driver I need to enable in balenaOS to access these GPIOs properly?

Thank you!

Hi @DiB, seems the JN4012 OS uses a different pinmux for GPIO12, but the Jetpack 6.2 BSP archive was pulled and is no longer offered on the manufacturer’s website as of today. For Jetpack 5.1.2 for example, the only difference between the vanilla Jetpack was a small change for a HDMI pin in tegra234-mb2-bct-scr-p3767-0000.dts, unrelated to GPIOs.

Now, if you would like to use that GPIO as output, you can try use devmem from the container to configure it as output.

gpioinfo shows the label as PN.01 and cat /sys/kernel/debug/pinctrl/2430000.pinmux/pinconf-groups says this is SOC_GPIO39 and it is set as input:

5 (soc_gpio39_pn1): 
        pull=1
        tristate=1
        enable-input=1
        open-drain=1
        io-reset=1
        rcv-sel=1
        io-hv=1
        schmitt=0
        pull-down-strength=0
        pull-up-strength=0
        drive-type=0
        gpio-mode=0
        function=rsvd1

Looking in the Orin Series Technical Reference Manual at page 6393 I see PADCTL_EDP_SOC_GPIO39_0 has offset 0x20 and the pad control registers are called PADCTL_A16 - page 6388. At page 57 of the reference manual I see the base address for PADCTRL_A16: PADCTL_A16 0x02440000, so the register address for this pin is base address + offset -0x02440020.

Going back to the devmem docs I see that for using a pin as GPIO, we need to set Bits 10, 6 and 4 to 0, and then write that value from the container.

The initial value when it is configured as input is:

busybox devmem 0x02440020
0x00000055

and to configure it as output I did:

busybox devmem 0x02440020 w 0x5

pinconf-groups then reports

5 (soc_gpio39_pn1): 
        pull=1
        tristate=0
        enable-input=0

and with gpioset --mode=wait gpiochip0 85=1 I can then see 3.3V between pins 14 and 15 of the 40 pin header.

Thanks for the quick reply @acostach! To clarify, are you saying that I need to use Jetpack 5.1.2 if I want to use the GPIO pins on the J4012 with the Balena image?

@DiB no, it should only be needed to configure the GPIO pins you need with devmem, as per the example above. Does apt-get update && apt-get install busybox && busybox devmem 0x02440020 w 0x5 && gpioset --mode=wait gpiochip0 85=1 trigger the gpio?

Unfortunately, running apt-get update && apt-get install busybox && busybox devmem 0x02440020 w 0x5 && gpioset --mode=wait gpiochip0 85=1 from my container does not seem to trigger the GPIO. GPIO Mode does seem to be set to 1, however:

5 (soc_gpio39_pn1): 
        pull=1
        tristate=0
        enable-input=0
        open-drain=1
        io-reset=1
        rcv-sel=1
        io-hv=1
        schmitt=0
        pull-down-strength=0
        pull-up-strength=0
        drive-type=0
        gpio-mode=1
        function=rsvd1

I verified that I am using the Seeed reComputer J4012 Jetson Orin NX 16GB image from Balena, running balenaOS 6.4.0.

In my docker-compose.yml, I have set up the following options for the service:

  privileged: true
  network_mode: host
  environment:
      - DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
  labels:
    io.balena.features.udev: '1'
    io.balena.features.supervisor-api: '1'
    io.balena.features.dbus: '1'
  devices:
    - /dev/bus/usb:/dev/bus/usb
    - /dev/video11:/dev/video11
    - /dev/video10:/dev/video10
    - /dev/gpiochip0:/dev/gpiochip0
    - /dev/gpiochip1:/dev/gpiochip1

Could it be there’s something missing in the docker-compose.yml? I’ve tried using balenaOS v6.4.0 on the non-industrial carrier board, with the following container and a multimeter connected to pins 14 and 15: jetson-examples/jetson-orin/Dockerfile at master · balena-io-examples/jetson-examples · GitHub

I set up my J4012 developer kit hardware, and verified that yes, this does work on these pins. It, however, is not triggering the GPIO on the “Industrial” version.

There must be some difference in the hardware/pins that I am unaware of. The industrial version seems to allow us to trigger the GPIO pins with gpioset gpiochip0 51=1. However, when I run in the balena container, this command does not trigger the pin. I am testing using the Dockerfile as the image for the container.

I verified with Seeed that the Seeed reComputer J4012 Industrial needs a different device tree overlay than the Seeed reComputer J4012 Developer Kit. Does Balena only have support for the developer kit and not the actual “Industrial” version?

Hi @DiB,

Yes, currently only the standard variant of the J4012 is supported in balena-cloud, but we also offer Custom Device Support if the device you want to use with Balena is not yet in the supported devices list. Let us know here or through our contact form if you would like one of our sales representatives to provide you with more information about CDS.

1 Like

Hi @DiB – I’m on the Customer Success team at Balena. I just reached out to you via email to discuss the Custom Device Support program for supporting the “Industrial” variant of the J4012.

1 Like