raspi-config nonint do_i2c 1 hangs "forever" (pour toujours)

Tout en développant PiCockpitet en essayant de permettre à l'utilisateur de désactiver l'I2C à partir de l'interface web, j'ai rencontré des problèmes et des pannes.

J'utilise raspi-config en mode non interactif (j'ai déjà écrit à ce sujet) pour contrôler I2C depuis le client PiCockpit.

En déboguant le problème, j'ai remarqué que - si quelque chose était occupé à accéder au bus I2C, la commande (raspi-config) se figeait.

En enquêtant avec ps aux, j'ai remarqué qu'une autre commande avait été lancée mais n'avait pas fini de s'exécuter :

dtparam i2c_arm=off

C'est un binaire compilé, pas de script. Mais il a un mode verbeux.

en exécutant ceci manuellement, en mode verbeux, pendant que quelque chose d'autre accéderait au bus I2C :

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

DTOVERLAY[debug] : utilisation de la plate-forme 'bcm2711'.

DTOVERLAY [debug] : carte de recouvrement chargée

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] : chargement du fichier '/tmp/.dtoverlays/base.dtb'.

DTOVERLAY [debug] : trouvé override i2c_arm

DTOVERLAY[debug] : override i2c_arm : string target 'status' (chaîne de caractères)

DTOVERLAY[debug] : a écrit 166 octets dans '/tmp/.dtoverlays/69_dtparam.dtbo'.

DTOVERLAY[debug] : a écrit 179 octets dans '/sys/kernel/config/device-tree/overlays/69_dtparam/dtbo'.

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

s'accrocherait avant la dernière commande (surlignée en jaune).

Une fois que l'autre application a libéré le bus I2C, dtparam termine son travail et affiche la dernière ligne.

Comment pouvez-vous savoir quelles applications accèdent au bus i2c ?

Facilement, avec lsof :

sudo lsof /dev/i2c-1

lsof : WARNING : can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
       Les informations de sortie peuvent être incomplètes.
COMMANDE PID UTILISATEUR FD TYPE DISPOSITIF TAILLE/OFF NOM DU NOEUD
python3 24772 root 13u CHR 89,1 0t0 285423 /dev/i2c-1

image

dans mon cas, selon l'activité des deux applications (CO2 et BME688), le fichier pourrait être ouvert deux fois également :

image

Ma recommandation est, puisqu'il ne semble pas y avoir de solution de contournement pour le blocage de dtparam (et donc de raspi-config) lorsque I2C est accédé / ouvert, de vérifier l'état des descripteurs de fichiers d'abord, et de montrer à l'utilisateur un message d'erreur si c'est le cas (qu'ils devront d'abord désactiver les applications pour que cela fonctionne).

NB : pour le SMBus de Python, vous pouvez simplement utiliser bus.close() (si vous avez appelé votre bus d'instance SMBus)