Package: avrdude
Severity: normal
Tags: upstream

Dear maintainer,

The packaged avrdude does not work reliably out of the box for linuxgpio 
bit-banging on current Raspberry Pi OS / Debian-based Raspberry Pi systems with 
recent kernels.

This is a real regression for existing Raspberry Pi setups that use avrdude 
directly from the GPIO header to program AVR/ATmega devices.

Problem
=======

On current Raspberry Pi OS kernels, the old global sysfs GPIO numbering is no 
longer stable. Raspberry Pi GPIO controllers are no longer forced to start at 
global GPIO base 0. On some systems the GPIO base is 512 or another non-zero 
value.

As a result, old linuxgpio/sysfs setups using BCM GPIO numbers such as:

  reset = 1;
  sck   = 12;
  sdo   = 24;
  sdi   = 23;

may fail because linuxgpio tries to use /sys/class/gpio/export with these 
numbers directly.

A typical failure with the packaged avrdude/linuxgpio path is:

  avrdude OS error: cannot export GPIO 1, already exported/busy?: Invalid 
argument
  avrdude error: unable to open programmer linuxgpio on port unknown

Trying to work around this by using sysfs global GPIO numbers such as base + 
BCM GPIO is also problematic. For example, if the GPIO base is 512, the mapping 
becomes:

  BCM GPIO1  -> 513
  BCM GPIO12 -> 524
  BCM GPIO24 -> 536
  BCM GPIO23 -> 535

But some avrdude builds reject such GPIO numbers in avrdude.conf with an error 
like:

  pin must be in the range 0-400

So the old sysfs workaround is blocked by an artificial compile-time pin limit 
as well.

Expected behavior
=================

On current Raspberry Pi OS / Debian systems, avrdude -c linuxgpio should work 
using the modern Linux GPIO character device ABI via libgpiod, not the 
deprecated sysfs GPIO interface.

The package should be built with working libgpiod support for linuxgpio.

The package should also ship or document a usable linuxgpio configuration for 
Raspberry Pi systems, for example:

  default_linuxgpio = "gpiochip0";

  programmer
    id         = "linuxgpio";
    desc       = "Use Linux GPIO via libgpiod";
    type       = "linuxgpio";
    prog_modes = PM_ISP;
    reset      = 1;
    sck        = 12;
    sdo        = 24;
    sdi        = 23;
  ;

With this configuration, avrdude should use:

  /dev/gpiochip0 line 1
  /dev/gpiochip0 line 12
  /dev/gpiochip0 line 24
  /dev/gpiochip0 line 23

instead of relying on unstable sysfs global GPIO numbers.

Actual behavior
===============

The packaged avrdude/linuxgpio setup is not usable reliably on current 
Raspberry Pi OS systems. Depending on the exact package build and 
configuration, one of these happens:

  - linuxgpio is missing from the usable programmer configuration;
  - linuxgpio still uses the deprecated sysfs GPIO path;
  - GPIO export fails with "Invalid argument";
  - using base+GPIO sysfs numbers is rejected by the avrdude pin limit;
  - the user has to rebuild avrdude manually with libgpiod support.

Local working fix
=================

I rebuilt avrdude manually on Debian Trixie arm64 with libgpiod development 
files installed and linuxgpio enabled.

The resulting binary links against libgpiod:

  libgpiod.so.3 => /lib/aarch64-linux-gnu/libgpiod.so.3

At runtime it prints:

  using libgpiod for linuxgpio

With this /etc/avrdude.conf configuration:

  default_linuxgpio = "gpiochip0";

  programmer
    id         = "linuxgpio";
    desc       = "Use Linux GPIO via libgpiod";
    type       = "linuxgpio";
    prog_modes = PM_ISP;
    reset      = 1;
    sck        = 12;
    sdo        = 24;
    sdi        = 23;
  ;

This command works correctly without specifying -P or -C:

  avrdude -p m1280 -c linuxgpio -U 
flash:w:/home/pi/NetBeansProjects/SAS/dist/uart_9bit_converter.ino.mega.hex -U 
lock:w:0x3C:m

The important part is that linuxgpio now uses libgpiod and /dev/gpiochip0, 
while the pin numbers remain normal BCM GPIO line numbers.

Suggested fix
=============

Please change the Debian/Raspberry Pi OS avrdude package so that:

  1. avrdude is built with working libgpiod support for linuxgpio;
  2. linuxgpio is usable out of the box or clearly documented;
  3. the default documentation explains use of -P gpiochip0 or 
default_linuxgpio = "gpiochip0";
  4. the avrdude.conf linuxgpio example uses normal GPIO line numbers, not 
deprecated sysfs global GPIO numbers;
  5. if sysfs linuxgpio remains supported, the artificial PIN_MAX / "0-400" 
limit should be increased enough to allow systems where GPIO base is 512 or 
higher.

The preferred fix is libgpiod support. Increasing the pin-number limit only 
helps legacy sysfs users and does not solve the underlying problem with 
unstable global GPIO numbering.

Why this matters
================

A common Raspberry Pi use case is programming AVR/ATmega devices directly 
through the 40-pin GPIO header using avrdude linuxgpio. This worked for years 
on older Raspberry Pi OS releases. On current Raspberry Pi OS systems, the old 
sysfs GPIO numbering model is no longer reliable, so the packaged avrdude 
should follow the current Linux GPIO model and use libgpiod.

This is not just a documentation issue. For embedded installations, a normal 
OS/kernel/package upgrade can break the ability to reprogram attached 
microcontrollers in the field.

References
==========

There are public reports of the same class of problem:

  - avrdude linuxgpio failing on Raspberry Pi with "cannot export GPIO ... 
Invalid argument":
    https://github.com/avrdudes/avrdude/issues/1748

  - Raspberry Pi forum discussion about avrdude linuxgpio/linuxspi and sysfs 
GPIO behavior:
    https://forums.raspberrypi.com/viewtopic.php?t=365362

Please build the package with libgpiod-enabled linuxgpio support and provide a 
working configuration path for current Raspberry Pi OS systems.

Regards,
Sergey

Reply via email to