raspi-config nonint do_i2c 1 blocca "per sempre"

Mentre si sviluppa PiCockpite cercando di permettere all'utente di disattivare l'I2C dall'interfaccia web, mi sono imbattuto in crash e problemi.

Sto usando raspi-config in modalità non interattiva (ne ho già scritto) per controllare I2C dal client PiCockpit.

Durante il debug del problema, ho notato che - se qualcosa era occupato ad accedere al bus I2C, il comando (raspi-config) si bloccava.

Indagando con ps aux, ho notato che un altro comando era stato avviato ma non ha finito di essere eseguito:

dtparam i2c_arm=off

Questo è un binario compilato, senza script. Ma ha una modalità verbosa.

eseguendo questo manualmente, in modalità verbose, mentre qualcos'altro accede al bus I2C:

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

DTOVERLAY[debug]: usare la piattaforma 'bcm2711'.

DTOVERLAY[debug]: mappa di sovrapposizione caricata

run_cmd: quale 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]: caricamento del file '/tmp/.dtoverlays/base.dtb

DTOVERLAY[debug]: trovato override i2c_arm

DTOVERLAY[debug]: override i2c_arm: obiettivo stringa 'status'

DTOVERLAY[debug]: ha scritto 166 byte in '/tmp/.dtoverlays/69_dtparam.dtbo

DTOVERLAY[debug]: ha scritto 179 byte in '/sys/kernel/config/device-tree/overlays/69_dtparam/dtbo

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

sarebbe appeso prima di l'ultimo comando (evidenziato in giallo).

Una volta che l'altra applicazione ha rilasciato il bus I2C, dtparam finisce il suo lavoro e mostra l'ultima linea.

Come potete scoprire quali applicazioni stanno accedendo al bus i2c?

Facilmente, con lsof:

sudo lsof /dev/i2c-1

lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
       Le informazioni in uscita possono essere incomplete.
COMANDO PID UTENTE FD TIPO DISPOSITIVO DIMENSIONE/OFF NOME DEL NODO
python3 24772 root 13u CHR 89,1 0t0 285423 /dev/i2c-1

immagine

nel mio caso, a seconda dell'attività delle due applicazioni (CO2 e BME688), il file potrebbe essere aperto anche due volte:

immagine

La mia raccomandazione è, dal momento che non sembra esserci un workaround per dtparam sospeso (e quindi raspi-config sospeso) quando si accede a I2C / aperto, di controllare lo stato dei descrittori di file prima, e mostrare all'utente un messaggio di errore se questo è il caso (che avranno bisogno di disabilitare le applicazioni prima per questo lavoro).

NB: per l'SMBus di Python, si può semplicemente usare bus.close() (se avete chiamato il vostro bus di istanza SMBus)