调用i2c_new_client_device()后关联I2C设备的probe()函数未触发的问题排查
可能的故障原因及排查方案
1. i2c_new_client_device调用失败,设备未成功创建
这是最容易忽略的核心问题——如果设备根本没被创建出来,自然不会触发probe。你需要先验证设备创建是否成功:
- 在模块A的代码中添加返回值检查:
i2c_client = i2c_new_client_device(client->adapter, &board_info[0]); if (IS_ERR(i2c_client)) { pr_err("Failed to create Device B client: %ld\n", PTR_ERR(i2c_client)); return PTR_ERR(i2c_client); } pr_info("Successfully created Device B client at adapter %d, addr 0x%02x\n", client->adapter->nr, client->addr); - 查看内核日志,常见失败原因包括:
- 目标I2C适配器未初始化或不存在
- 0x70地址已被同一适配器上的其他设备占用
- 模块权限不足,无法操作I2C总线
2. probe_new与传统ID匹配机制不兼容
部分内核版本中,probe_new是为设备树/ACPI驱动的设备设计的,而通过i2c_board_info创建的传统设备(无固件节点)会优先调用标准probe函数(带const struct i2c_device_id *id参数)。
你可以尝试修改模块B的驱动,替换为标准probe:
static int device_B_probe(struct i2c_client *client, const struct i2c_device_id *id) { pr_info("Probe called for device: %s\n", id->name); return 0; } static struct i2c_driver device_B_driver = { .driver = { .name = "device_B_name", .of_match_table = device_B_of_match, }, .probe = device_B_probe, // 替换为标准probe函数 .id_table = device_B_id, };
3. 驱动与设备的匹配未生效
虽然你的代码逻辑上匹配条件正确,但可以通过sysfs验证实际匹配状态:
- 查看I2C设备是否存在:
ls /sys/bus/i2c/devices/,检查是否有对应适配器下的X-0070(X为适配器编号)节点 - 查看驱动是否加载:
ls /sys/bus/i2c/drivers/,确认device_B_name驱动目录存在 - 检查设备与驱动的绑定状态:
cat /sys/bus/i2c/devices/X-0070/driver,如果输出为空,说明匹配失败 - 临时排查手段:将驱动的
.driver.name改为"device_B"(与设备name一致),让内核尝试通过名称匹配
4. 内核配置缺失必要功能
确保你的内核配置中开启了以下选项:
CONFIG_I2C=y或=m(I2C核心功能)- 对应硬件平台的I2C适配器驱动(比如
CONFIG_I2C_GPIO、CONFIG_I2C_S3C2410等) - 若使用设备树,需开启
CONFIG_OF=y
5. 驱动加载顺序异常
如果模块A先创建设备、模块B后加载,理论上内核会在驱动注册时自动遍历现有设备触发probe,但如果出现异常:
- 尝试先加载模块B,再加载模块A,观察probe是否触发
- 在模块B的代码中添加
pr_info("Device B driver loaded successfully\n"),确认驱动确实被加载
内容的提问来源于stack exchange,提问作者Ulrich Sørensen
相关产品推荐
相关产品推荐

