首页 > 解决方案 > Linux:写入 i2c/SMBus

问题描述

我在使用Intel Apollo Lake处理器的 Linux 系统上遇到 i2c/SMBus 问题。我正在尝试读取/写入 EEPROM,但我遇到了一些问题。我的 EEPROM 位于地址 0x56,我可以用我的逻辑分析仪观察总线。

当我尝试通过i2ctools ( i2cget) 从设备读取数据时,系统会按预期运行。例如,当我尝试通过执行写入命令时,就会出现我的问题i2cseti2cset以错误结束(写入失败)。因为我能够以电子方式观看总线,所以我也可以说所有线路都保持高电平并且总线没有被触及。我能够激活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 地址空间周围是否有锁,我的对手是谁?”

我是整个驱动程序和内核世界的新手,所以请善待,我很可能犯了初学者的错误。我会很感激我可以解决我的问题的提示和技巧。

标签: linuxdriveri2ceepromsmbus

解决方案


看来我找到了问题的原因。在此论坛帖子中描述了英特尔更改了 SMBus 控制器的配置位。

好的,我知道发生了什么。

从 8 系列/C220 芯片组开始,英特尔在寄存器 HOSTC 中为 SMBus 控制器引入了一个新的配置位(PCI D31:F3 地址偏移 40h):

位 4 SPD 写禁止 - R/WO。0 = SPD 写使能。1 = SPD 写禁用。禁止写入 SMBus 地址 50h - 57h。

配置中这种记录不全的更改解释了这些问题。

一个挑战是,要应用和启用对 SPD 写入位的更改,系统需要重新启动。不幸的是,在重新启动 BIOS 时,会将 Bit 更改回默认值。唯一的解决方案似乎是在 BIOS 中进行调整。

对我来说,这个问题已经解决了。我只是想分享这些信息,以防有人遇到同样的问题。


推荐阅读