raspi-config nonint do_i2c 1 hangt "voor altijd"

Tijdens de ontwikkeling van PiCockpiten ik heb geprobeerd om de gebruiker I2C uit te laten schakelen via de webinterface, ik ben tegen crashes en problemen aangelopen.

Ik gebruik raspi-config in niet-interactieve modus (ik heb hier al eerder over geschreven) om I2C van de PiCockpit client te besturen.

Tijdens het debuggen van het probleem merkte ik op dat - als iets bezig was om de I2C bus te benaderen, het commando (raspi-config) zou bevriezen.

Onderzoekend met ps aux, zag ik dat een ander commando gestart was, maar niet klaar was om uitgevoerd te worden:

dtparam i2c_arm=off

Dit is een gecompileerde binary, geen script. Maar het heeft een verbose mode.

dit handmatig uitvoeren, in verbose mode, terwijl iets anders de I2C bus zou benaderen:

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

DTOVERLAY[debug]: platform 'bcm2711' gebruikt

DTOVERLAY[debug]: overlappende kaart geladen

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]: bestand '/tmp/.dtoverlays/base.dtb' laden

DTOVERLAY[debug]: override i2c_arm gevonden

DTOVERLAY[debug]: opheffen i2c_arm: string doel 'status'

DTOVERLAY[debug]: 166 bytes geschreven naar '/tmp/.dtoverlays/69_dtparam.dtbo'

DTOVERLAY[debug]: schreef 179 bytes naar '/sys/kernel/config/device-tree/overlays/69_dtparam/dtbo'

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

zou hangen voor het laatste commando (geel gemarkeerd).

Zodra de andere applicatie de I2C bus had vrijgegeven, zou dtparam zijn werk afmaken en de laatste regel tonen.

Hoe kan je te weten komen welke toepassingen toegang hebben tot de i2c bus?

Gemakkelijk, met Isof:

sudo lsof /dev/i2c-1

lsof: WAARSCHUWING: kan niet stat() fuse.gvfsd-fuse bestandssysteem /run/user/1000/gvfs
       De output informatie kan onvolledig zijn.
COMMANDO PID GEBRUIKER FD TYPE APPARAAT GROOTTE/UIT KNOOPPUNT NAAM
python3 24772 root 13u CHR 89,1 0t0 285423 /dev/i2c-1

afbeelding

in mijn geval, afhankelijk van de activiteit van de twee apps (CO2 en BME688), kan het bestand ook twee keer geopend zijn:

afbeelding

Mijn aanbeveling is, daar er geen workaround lijkt te zijn voor dtparam hanging (en dus raspi-config hanging) wanneer I2C wordt benaderd / geopend, om eerst de toestand van de bestandsdescriptors te controleren, en de gebruiker een foutmelding te tonen indien dit het geval is (dat ze eerst de applicaties zullen moeten uitschakelen om dit te laten werken).

NB: voor Python's SMBus, kunt u eenvoudig gebruik maken van bus.close() (als je je SMBus instance bus hebt genoemd)