raspi-config nonint do_i2c 1 hangs "forever"

Mientras se desarrolla PiCockpity tratando de permitir al usuario desactivar el I2C desde la interfaz web, me he encontrado con caídas y problemas.

Estoy usando raspi-config en modo no interactivo (ya he escrito sobre esto) para controlar el I2C desde el cliente PiCockpit.

Mientras depuraba el problema, noté que - si algo estaba ocupado accediendo al bus I2C, el comando (raspi-config) se congelaba.

Investigando con ps aux, me di cuenta de que otro comando se había iniciado pero no terminó de ejecutarse:

dtparam i2c_arm=off

Se trata de un binario compilado, sin script. Pero tiene un modo verboso.

ejecutando esto manualmente, en modo verbose, mientras otra cosa estaría accediendo al bus I2C:

17:32:55 root@Avalon:/home/pi # dtparam -v i2c_arm=off

DTOVERLAY[debug]: utilizando la plataforma 'bcm2711'

DTOVERLAY[debug]: mapa de superposición cargado

run_cmd: which dtoverlay-pre >/dev/null 2>&1 && dtoverlay-pre

run_cmd: dtc -I fs -O dtb -o '/tmp/.dtoverlays/base.dtb' /proc/device-tree 1>/dev/null 2>&1

DTOVERLAY[debug]: cargando archivo '/tmp/.dtoverlays/base.dtb'

DTOVERLAY[debug]: encontrado override i2c_arm

DTOVERLAY[debug]: override i2c_arm: string target 'status'

DTOVERLAY[debug]: escribió 166 bytes en '/tmp/.dtoverlays/69_dtparam.dtbo'

DTOVERLAY[debug]: escribió 179 bytes en '/sys/kernel/config/device-tree/overlays/69_dtparam/dtbo'

run_cmd: which dtoverlay-post >/dev/null 2>&1 && dtoverlay-post

colgaría antes de el último comando (resaltado en amarillo).

Una vez que la otra aplicación haya liberado el bus I2C, dtparam terminará su trabajo y mostrará la última línea.

¿Cómo se puede saber qué aplicaciones acceden al bus i2c?

Fácilmente, con lsof:

sudo lsof /dev/i2c-1

lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
       La información de salida puede ser incompleta.
COMANDO PID USUARIO FD TIPO DISPOSITIVO TAMAÑO/OFF NOMBRE NODO
python3 24772 root 13u CHR 89,1 0t0 285423 /dev/i2c-1

imagen

en mi caso dependiendo de la actividad de las dos aplicaciones (CO2 y BME688), el archivo podría estar abierto dos veces también:

imagen

Mi recomendación es, ya que no parece haber una solución para que dtparam se cuelgue (y por lo tanto raspi-config se cuelgue) cuando se está accediendo / abriendo I2C, comprobar primero el estado de los descriptores de archivo, y mostrar al usuario un mensaje de error si este es el caso (que tendrán que desactivar las aplicaciones primero para que esto funcione).

NB: para el SMBus de Python, puede utilizar simplemente bus.close() (si llamó a su bus de instancia SMBus)