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
en mi caso dependiendo de la actividad de las dos aplicaciones (CO2 y BME688), el archivo podría estar abierto dos veces también:
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)