/sys/bus/i2c/devices下的内容与i2c_board_info结构

本文介绍Linux系统中I2C设备的注册过程及如何通过/sys/bus/i2c/devices目录查看已注册的I2C设备。具体展示了i2c_board_info结构体的使用,并解释了如何根据该结构体中的I2C地址来命名设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在目录/sys/bus/i2c/devices下能发现系统中的I2C设备,如下:

 

  1. # ls  
  2. 0-0034  
  3. 0-0030  
  4. 0-0011  
  5. 0-0058  

 

这些设备就是系统中存在的设备。

这些设备是怎么来的?

在你对应的machine配置里会执行“i2c_register_board_info”一个函数,它会将一个i2c_board_info的结构体注册进系统,

这个i2c_board_info的结构体里就描述了板载的所有I2C设备信息,如下例:

 

  1. static struct i2c_board_info littleton_i2c_board_info[] = {  
  2. #if defined(CONFIG_PXA3xx_MICCO) || defined(CONFIG_PXA3xx_MICCO_MODULE)  
  3.     {  
  4.         .type   = "micco",  
  5.         .addr       = 0x34,  
  6.         .platform_data  = &micco_data,  
  7.         .irq        = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO18)),  
  8.     },  
  9. #endif  
  10. #if defined(CONFIG_GPIO_MAX7320) || defined(CONFIG_GPIO_MAX7320_MODULE)  
  11.     {  
  12.         .type   = "max7320",  
  13.         .addr       = 0x50,  
  14.         .platform_data  = &exp0_pdata,  
  15.     },  
  16. #endif  
  17. #if defined(CONFIG_GPIO_MAX7321) || defined(CONFIG_GPIO_MAX7321_MODULE)  
  18.     {  
  19.         /* on 8385 WLAN Board */  
  20.         .type   = "max7321",  
  21.         .addr       = 0x60,  
  22.         .platform_data  = &exp1_pdata[BOARD_8385_WLAN],  
  23.     },  
  24.     {  
  25.         /* on UMTS Board */  
  26.         .type   = "max7321",  
  27.         .addr       = 0x61,  
  28.         .platform_data  = &exp1_pdata[BOARD_UMTS],  
  29.     },  
  30.     {  
  31.         /* on Siemens Baseband Radio Interposer Board */  
  32.         .type   = "max7321",  
  33.         .addr       = 0x62,  
  34.         .platform_data  = &exp1_pdata[BOARD_SIEMENS_BASEBAND],  
  35.     },  
  36.     {  
  37.         /* on 8688 WLAN/Camera Board */  
  38.         .type   = "max7321",  
  39.         .addr       = 0x63,  
  40.         .platform_data  = &exp1_pdata[BOARD_8688_WLAN_CAMERA],  
  41.     },  
  42.     {  
  43.         /* on Camera Board */  
  44.         .type   = "max7321",  
  45.         .addr       = 0x64,  
  46.         .platform_data  = &exp1_pdata[BOARD_CAMERA],  
  47.     },  
  48.     {  
  49.         /* on 8686 WLAN/Camera Board */  
  50.         .type   = "max7321",  
  51.         .addr       = 0x66,  
  52.         .platform_data  = &exp1_pdata[BOARD_8386_WLAN_CAMERA],  
  53.     },  
  54.     {  
  55.         /* on 8385 WLAN/Camera Board */  
  56.         .type   = "max7321",  
  57.         .addr       = 0x6c,  
  58.         .platform_data  = &exp1_pdata[BOARD_8385_WLAN_CAMERA],  
  59.     },  
  60.     {  
  61.         /* on 8688 WLAN Board */  
  62.         .type   = "max7321",  
  63.         .addr       = 0x6d,  
  64.         .platform_data  = &exp1_pdata[BOARD_8688_WLAN],  
  65.         .irq        = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO77)),  
  66.     },  
  67. #endif  
  68. #if defined(CONFIG_PXA_CAMERA)  
  69.     {  
  70.         .type   = "sensor_ov7673",  
  71.         .addr       = 0x21,  
  72.         .platform_data  = &ov7673_sensor_data,  
  73.     },  
  74.     {     
  75.         .type   = "sensor_ov5623",  
  76.         .addr       = 0x30,  
  77.         .platform_data  = &ov5623_sensor_data,  
  78.     },  
  79. #endif  
  80. };  

 

可以发现,在目录/sys/bus/i2c/devices下的设备就是这个i2c_board_info结构体里所描述的I2C设备,

而/sys/bus/i2c/devices下的设备名字就是根据i2c_board_info结构体中定义的I2C Address来命名的。

所以添加一个I2C设备时,除了需要编写这个I2C设备的驱动之外,还需要在machine里面加入I2C设备的i2c_board_info内容。

<think>我们正在处理一个关于I2C通信中i2c_master_send函数返回-6错误的问题。错误代码-6在Linux内核中通常对应EAGAIN,表示资源暂时不可用。然而,在I2C上下文中,-6更可能对应ENXIO(在errno.h中,ENXIO定义为6,即“Nosuchdeviceoraddress”)。因此,我们需要确认这个错误代码的确切含义。根据Linux内核源代码,I2C核心返回的错误代码中,-ENXIO(即-6)通常表示从设备没有响应,或者设备地址不被识别。可能的原因:1.I2C从设备地址不正确:设备可能被配置为不同的地址,或者硬件连接错误导致地址不匹配。2.硬件连接问题:SDA或SCL线连接不良,或者上拉电阻不合适,导致通信失败。3.设备未就绪:设备可能未上电、处于复位状态或未初始化完成。4.总线忙:总线可能被其他设备占用或处于不可用状态。5.驱动程序问题:I2C适配器驱动程序可能存在问题,或者适配器未正确配置。解决方案:1.检查设备地址:使用i2cdetect工具扫描I2C总线,确认设备地址是否正确响应。2.检查硬件连接:确保SDA和SCL线连接正确,上拉电阻符合要求(通常4.7kΩ)。3.确认设备状态:确保设备已上电,复位引脚已正确释放,并满足设备启动时间要求。4.检查总线状态:确认没有其他进程占用总线,总线没有被意外锁定。5.调试驱动程序:检查I2C适配器驱动是否正常工作,必要时增加调试打印。代码示例(调试用):在驱动代码中,可以在发送函数前后添加打印,观察执行流程:```cdev_dbg(&client->dev,"Attemptingtosenddata\n");ret=i2c_master_send(client,buf,len);dev_dbg(&client->dev,"i2c_master_sendreturned%d\n",ret);```如果问题仍然存在,可能需要使用逻辑分析仪或示波器检查I2C总线上的信号。相关问题:1.如何用i2cdetect工具诊断I2C设备?2.I2C通信中常见的错误代码有哪些?3.如何调试Linux内核中的I2C驱动程序?4.硬件上如何正确连接I2C总线的上拉电阻?5.I2C设备地址冲突如何解决?</think>### I2C_Master_Send 返回 -6 错误分析解决 **错误代码含义**: 在 Linux I2C 子系统,`i2c_master_send()` 返回 `-6` 对应内核错误码 `ENXIO`(定义于 `<linux/errno.h>`),表示 **设备地址无响应** 或 **目标设备不存在**。 --- ### 常见原因解决方案 #### 1. **设备地址错误** - **现象**:I2C 从设备地址配置错误 - **检查方法**: ```bash # 扫描 I2C 总线(示例:总线0) i2cdetect -y 0 ``` 输出示例: ``` 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- -- ``` `--` 表示无响应地址,`UU` 表示地址被占用,`23` 表示检测到的设备地址 - **修复**: 在驱动代码中修正设备地址: ```c // 错误示例:0x50 (无响应) struct i2c_client *client = i2c_new_client_device(adapter, &(struct i2c_board_info){ .addr = 0x23, // 修正为检测到的地址 }); ``` #### 2. **硬件连接问题** - **检查点**: - SDA/SCL 线路短路、断路或接触不良 - 设备未上电(测量 VCC/GND 电压) - 上拉电阻缺失(标准要求:3.3V 总线需 4.7kΩ 上拉) - **调试工具**: 用示波器/逻辑分析仪捕获总线波形,确认: - START 信号后是否有 ACK ![](https://i.imgur.com/ACK_waveform.png) *图:正常波形(左)无ACK响应(右)[^1]* #### 3. **总线冲突或设备忙** - **原因**: - 其他进程占用 I2C 总线 - 设备处于复位/低功耗状态 - **解决方案**: ```c // 重试机制(示例) int retry = 3; while (retry--) { ret = i2c_master_send(client, buf, len); if (ret != -ENXIO) break; // 成功则退出 msleep(10); // 等待10ms重试 } ``` #### 4. **驱动适配器问题** - **检查步骤**: 1. 确认 I2C 控制器驱动已加载: ```bash lsmod | grep i2c_ ``` 2. 检查控制器是否注册: ```bash cat /sys/bus/i2c/devices/i2c-*/name ``` 3. 在设备树中验证控制器使能状态: ```dts &i2c1 { status = "okay"; // 必须为"okay" your_device@23 { ... }; }; ``` --- ### 调试代码示例 在内核驱动添加调试信息: ```c dev_info(&client->dev, "Trying address 0x%02x\n", client->addr); ret = i2c_master_send(client, buf, len); if (ret == -ENXIO) { dev_err(&client->dev, "ENXIO: Check address/power/wiring\n"); // 触发总线状态检查 i2c_check_bus_status(adapter); } ``` --- ### 典型修复案例 某 I2C 温度传感器驱动返回 `-6`: 1. 用 `i2cdetect` 发现实际地址为 `0x48`(非驱动中 `0x50`) 2. 示波器显示 SDA 线电压不稳,增加 4.7kΩ 上拉电阻 3. 修改设备树: ```dts sensor: tmp112@48 { compatible = "ti,tmp112"; reg = <0x48>; // 修正地址 vcc-supply = <&vdd>; // 添加电源节点 }; ``` 修复后传输成功[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值