linux - Linux:写入 i2c/SMBus
问题描述
我在使用Intel Apollo Lake处理器的 Linux 系统上遇到 i2c/SMBus 问题。我正在尝试读取/写入 EEPROM,但我遇到了一些问题。我的 EEPROM 位于地址 0x56,我可以用我的逻辑分析仪观察总线。
当我尝试通过i2ctools ( i2cget
) 从设备读取数据时,系统会按预期运行。例如,当我尝试通过执行写入命令时,就会出现我的问题i2cset
。i2cset
以错误结束(写入失败)。因为我能够以电子方式观看总线,所以我也可以说所有线路都保持高电平并且总线没有被触及。我能够激活dev_dbg()
i2c 驱动程序i2c_i801中的功能,并且当我执行时,i2cset
我能够找到(dmesg)调试消息:
[ 765.095591] [2753] i2c_i801:i801_check_post:433: i801_smbus 0000:00:1f.1: No response
使用smbus2库运行我的最小 I²C Python 代码时,我收到以下错误消息和上述调试消息:
from smbus2 import SMBus
bus = SMBus(0)
b = bus.read_byte_data(86,10) #<- This is performed
b = bus.write_byte_data(86,10,12) #<- This is not performed
bus.close()
错误:write_byte_data ioctl(self.fd,I2C_SMBUS,味精)
OSERROR: [Errno 6] No such device or adress
对我来说,一个重要提示是我无法在地址空间形式 0x50 到 0x57 中执行写命令。我的猜测是某些驱动程序锁定了地址空间以防止将命令写入该“危险”区域。
我的问题是:“有人知道这种行为吗?是否有解决方案,以便我可以在地址 0x56 处写入我的 EEPROM?或者从 0x50 到 0x57 的 i2c 地址空间周围是否有锁,我的对手是谁?”
我是整个驱动程序和内核世界的新手,所以请善待,我很可能犯了初学者的错误。我会很感激我可以解决我的问题的提示和技巧。
解决方案
看来我找到了问题的原因。在此论坛帖子中描述了英特尔更改了 SMBus 控制器的配置位。
好的,我知道发生了什么。
从 8 系列/C220 芯片组开始,英特尔在寄存器 HOSTC 中为 SMBus 控制器引入了一个新的配置位(PCI D31:F3 地址偏移 40h):
位 4 SPD 写禁止 - R/WO。0 = SPD 写使能。1 = SPD 写禁用。禁止写入 SMBus 地址 50h - 57h。
配置中这种记录不全的更改解释了这些问题。
一个挑战是,要应用和启用对 SPD 写入位的更改,系统需要重新启动。不幸的是,在重新启动 BIOS 时,会将 Bit 更改回默认值。唯一的解决方案似乎是在 BIOS 中进行调整。
对我来说,这个问题已经解决了。我只是想分享这些信息,以防有人遇到同样的问题。
推荐阅读
- javascript - 我怎么知道我需要哪个modernizr 部件?
- ruby-on-rails - 对于长别名,Rails 复合组计数失败。我怎样才能解决这个问题?
- teradata - 使用递归查询聚合周期
- javascript - 通过单击 contentEditable="false" 子节点来关注 contentEditable="true" 父节点
- react-native - React Native 动画在 iPhone X 上滞后
- python - 如何在python中填写插入语句的列名
- javascript - 放置在非活动手风琴容器中时,Dojo 小部件未正确呈现
- php - 当我在 PHP 的同一页面上显示结果时,如何显示用户在文本字段中键入的内容?
- python - Pandas 预处理:使用 2 个其他文件标记时间序列数据
- javascript - 为languages.js 运行getElementById 外部箭头函数