raspi-config nonint do_i2c 1 pendura "para sempre".

Ao desenvolver PiCockpite tentando permitir que o usuário desligue o I2C da interface web, encontrei colisões e problemas.

Eu estou usando raspi-config em modo não-interactivo (já escrevi sobre isto antes) para controlar a I2C do cliente PiCockpit.

Enquanto depurava o problema, eu notei que - se algo estivesse ocupado acessando o bus I2C, o comando (raspi-config) iria congelar.

Investigando com ps aux, notei que outro comando tinha sido iniciado mas não tinha terminado de executar:

dtparam i2c_arm=off

Este é um binário compilado, sem roteiro. Mas tem um modo verboso.

rodando isto manualmente, em modo verboso, enquanto outra coisa estaria acessando o barramento I2C:

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

DTOVERLAY[debug]: usando a plataforma 'bcm2711'.

DTOVERLAY[debug]: mapa de sobreposição carregado

run_cmd: qual 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]: carregando o arquivo '/tmp/.dtoverlays/base.dtb'.

DTOVERLAY[debug]: encontrado sobreposição i2c_arm

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

DTOVERLAY[debug]: escreveu 166 bytes para '/tmp/.dtoverlays/69_dtparam.dtbo'.

DTOVERLAY[debug]: escreveu 179 bytes para '/sys/kernel/config/device-tree/overlays/69_dtparam/dtbo'.

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

seria enforcado antes de o último comando (destacado em amarelo).

Uma vez que a outra aplicação tivesse lançado o autocarro I2C, a dtparam terminaria o seu trabalho e mostraria a última linha.

Como você pode descobrir quais aplicações estão acessando o ônibus i2c?

Facilmente, com o Isof:

sudo lsof /dev/i2c-1

Isof: ATENÇÃO: não pode stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
       As informações de saída podem estar incompletas.
COMANDO PID USUÁRIO TIPO FD TAMANHO DO DISPOSITIVO/NOME DO NÓ DESLIGADO
python3 24772 raiz 13u CHR 89,1 0t0 285423 /dev/i2c-1

imagem

no meu caso, dependendo da atividade dos dois aplicativos (CO2 e BME688), o arquivo poderia ser aberto duas vezes também:

imagem

Minha recomendação é, já que não parece haver uma alternativa para o dtparam pendurado (e portanto raspi-config pendurado) quando o I2C está sendo acessado / aberto, verificar o estado dos descritores de arquivo primeiro, e mostrar ao usuário uma mensagem de erro se este for o caso (que ele precisará desativar as aplicações primeiro para que isto funcione).

NB: para os SMBus Python's, você pode simplesmente usar bus.close() (se você chamou seu ônibus de exemplo SMBus)