PHP能否在Linux系统中读写字符设备(如树莓派OS的/dev/i2c-1)?
问题解答
PHP完全具备读写Linux字符设备的能力,你遇到的问题并非PHP本身的限制,而是I2C设备的操作逻辑错误。以下是具体分析和修正方案:
你的代码核心问题
- 地址计算逻辑错误:
($address | 0x01) << 8 & $registry完全误解了I2C设备地址与寄存器地址的交互方式,这种位运算无法正确指向目标寄存器。 - 错误使用
fseek:字符设备(如/dev/i2c-1)是流式设备,不支持文件偏移量机制,fseek对这类设备无效。
正确的I2C设备读写流程
Linux下用户空间操作I2C设备的标准流程是:
- 打开I2C总线设备文件
- 通过
ioctl设置目标从设备地址 - 写入要访问的寄存器地址
- 读取对应长度的数据
修正后的代码示例
<?php $i2cBus = '/dev/i2c-1'; $deviceAddr = 0x62; $targetReg = 0x00; $readLen = 1; // 打开I2C设备 $fd = fopen($i2cBus, 'r+b'); if (!$fd) { die("无法打开I2C总线设备"); } // 设置I2C从设备地址(I2C_SLAVE常量对应值为0x0703) if (!ioctl($fd, 0x0703, $deviceAddr)) { die("设置I2C从设备地址失败"); } // 写入要读取的寄存器地址(打包为单字节二进制) fwrite($fd, pack('C', $targetReg)); // 读取寄存器内容 $data = fread($fd, $readLen); if ($data === false) { die("读取寄存器失败"); } // 转换为可读格式输出 $value = ord($data); echo "寄存器0x00的值(十进制):$value\n"; echo "寄存器0x00的值(十六进制):" . dechex($value) . "\n"; fclose($fd); ?>
额外验证步骤
- 先通过命令行工具确认硬件正常:
i2cdetect -y 1 # 检查0x62地址是否有设备 i2cget -y 1 0x62 0x00 # 直接读取寄存器值,验证硬件可访问 - 确保PHP的
ioctl函数可用:该函数属于PHP的posix扩展,树莓派默认PHP环境通常已集成,若缺失可通过apt install php-posix安装。
内容的提问来源于stack exchange,提问作者FedeKrum
相关产品推荐
相关产品推荐

