Some history, I decided to use the Beaglebone Black Industrial (BBBI) for a new project due to the outstanding temperature specifications. For the project I needed an ADC, i2c, and plenty of gpio inputs and outputs which the BBBI had. I’d been using the Raspberry PI but had failures due to temperature. So time will tell if the BBBI industrial can stand up to the heat.
After purchasing the BBBI, which came with Kernel 6.18.16-bone23, I started getting the foundational basic code written mapping the gpio. That’s when I noticed that some of the GPIO was internally pulled up and some was internally pull down or floating. That’s when the fun started. I spent many hours learning libgpiod starting with version 1 and then porting to version 2. That’s another topic for discussion. libgpiod has functions built in to set the internal gpio mux to pull up or pull down. I needed all of the gpio inputs to pull up for ease of just ground the pins in the field wiring. Reading the pin = high, switch open, reading the pin = low, switch closed.
I worked with libgpiod for a while and it failed to change the pin mux settings. I could read the input pins and write to the output pins. But no luck changing the mux values.
I then tried writing a device tree overlay for pin P8_11 and while it loaded, the overlay failed to change the pin mux register value to 0x37. After these failures and some hints from Daniel I decided to compile a custom kernel just so I could internally pull up four pins. P8_11, P8_12, P8_15 and P8_18. A bit of a challenge I guess, considering I could just use external 10K ohm pull up resistors.
I’m going to try to list the steps to document this effort. Please comment to clarify.
The first step was to download the kernel git clone -b 6.18.16-bone23 https://github.com/RobertCNelson/linux-stable-rcn-ee --depth=100
Then I installed the cross compiler for the BBBI arm system and some other utilities
sudo apt-get update
sudo apt install build-essential crossbuild-essential-armhf
sudo apt install bison flex lzop u-boot-tools libncurses5-dev bc device-tree-compiler libssl-dev
I might be missing a few things here
The next few steps to compile the kernel
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make omap2pluslplc_defconfig, i modified this to enable the heartbeat LED=y
make menuconfig, nothing to change here. probably can skip this step
make
The compile took a few minutes and the zImage was created in
linux-stable-rcn-ee/arch/arm/boot
It also looks like the modules and the device tree overlays compiled also.
After the first compile with no custom modifications, linux-stable-rcn-ee/arch/arm/boot/zImage was moved to the BBBI in /boot to make sure the image would load. The old kernel, /boot/vmlinuz-6.18.16-bone23 was moved to a safe location and the new zImage was renamed to vmlinuz-6.18.16-bone23. Modules and device tree overlay files were left as is with no changes. In the future I am going to learn about placing the module and device tree files in the correct spot with the kernel naming convention matching the uEnv.txt variables. I need help in this area.
The system booted just fine with no errors.
Now for the modifications,
With a little research I was able to find the spot in the kernel just before user space where processes took over.
This entry point location is in init/main.c located here just before rest_init();
#ifdef CONFIG_SOC_AM33XX
bgpioSetPinMux();
#endif
/* Do the rest non-__init'ed, we're now alive */
rest_init();```
I placed the above code at the top of main.c. I suppose a separate file would have been better but I spent enough time on this and I need to move on to other priorities. Then I repeated the compile process and successfully changed the pins to pull up. Did I break something? we will see
For future builds I would like to better understand the naming convention of the kernel and how uboot finds the kernel. Also to better understand the module naming and location and the device tree naming and location, all these things have to be named exactly correct and be placed in the correct locations or they don’t work. I my case here I just compiled the same kernel, renamed the kernel with the same name and used the old modules and old device tree files already there.
Are you going to push changes to personal propper? To my mind it’s fair clear what should be done, that is set the pull on gpio pins in the device tree. Now of course it would only apply to gpio pins, so pins with other functionality in the device tree could have other pulls. E.g. Really want there to be a consistent way of doing this in the root kernel.
This change is kind of a hack work around to the kernel. I was hoping that a proper permanent fix to the user space libgpiod gpio mux functions would be officially completed. If Robert could provide some guidance here I would be willing to take a look.
I still don’t have a clear understanding of why the pin mux settings were disabled from user space and/or the device tree overlays. Or maybe there is just a bug that needs fixing, Don’t know.
This kernel hack pin mux config shown above is static on boot, so like some applications, easy dynamic run time changes are needed by the user.
If you can’t get a device-tree or libgpiod to set the exact value you require,
you’ve stumbled on a bug. Device-tree and libgpiod exists to avoid
having to poke around in the kernel directly!
[ 7.632713] systemd[1]: systemd-hibernate-clear.service - Clear Stale Hibernate Storage Info was skipped because of an unmet condition check (ConditionPathExists=/sys/firmware/efi/efivars/HibernateLocation-8cf2644b-4b0b-428f-9387-6d876050dc67).
[ 21.962549] remoteproc remoteproc0: Direct firmware load for am335x-pm-firmware.elf failed with error -2
[ 21.972340] remoteproc remoteproc0: request_firmware failed: -2
[ 32.565748] faux_driver regulatory: Direct firmware load for regulatory.db failed with error -2
[ 52.467904] rtw88_8821cu 1-1:1.0: Firmware version 24.11.0, H2C version 12
[ 52.678670] usbcore: registered new interface driver rtw88_8821cu