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
in mijn geval, afhankelijk van de activiteit van de twee apps (CO2 en BME688), kan het bestand ook twee keer geopend zijn:
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)