raspi-config nonint do_i2c 1 hangs "forever" 。

在制定 码头试图让用户从web界面关闭I2C,我遇到了崩溃和问题。

我正在使用Raspi-config 在非交互式模式下(我以前写过这个)。 来控制PiCockpit客户端的I2C。

在调试这个问题时,我注意到--如果有东西忙着访问I2C总线,命令(raspi-config)会冻结。

在用ps aux调查时,我注意到另一条命令已经开始,但没有完成执行。

dtparam i2c_arm=off

这是一个编译的二进制文件,没有脚本。但是,它有一个verbose模式。

在其他东西访问I2C总线的时候,手动运行这个程序,采用的是verbose模式。

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

DTOVERLAY[debug]:使用平台'BCM2711'。

DTOVERLAY[debug]:加载叠加地图

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]:加载文件'/tmp/.dtoverlays/base.dtb'

DTOVERLAY[debug]:发现覆盖i2c_arm

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

DTOVERLAY[debug]: 写了166字节到'/tmp/.dtoverlays/69_dtparam.dtbo'。

DTOVERLAY[debug]: 写了179字节到'/sys/kernel/config/device-tree/overlays/69_dtparam/dtbo'

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

会挂 之前 最后一条命令(用黄色突出显示)。

一旦其他应用程序释放了I2C总线,dtparam将完成它的工作并显示最后一行。

你怎样才能发现哪些应用程序正在访问i2c总线?

很容易,用lsof。

sudo lsof /dev/i2c-1

lsof:WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
       输出信息可能不完整。
命令 pid user fd type device size/off node name
python3 24772 root 13u CHR 89,1 0t0 285423 /dev/i2c-1

形象

在我的例子中,取决于两个应用程序(CO2和BME688)的活动,文件也可能被打开两次。

形象

我的建议是,由于在I2C被访问/打开时,似乎没有解决dtparam挂起(以及因此raspi-config挂起)的办法,首先检查文件描述符的状态,如果是这种情况,向用户显示错误信息(他们将需要先禁用应用程序,这样才能发挥作用)。

注意:对于Python的SMBus,你可以简单地使用 bus.close() (如果你把你的SMBus实例总线称为)