You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核6.6.37-v8+下I2C驱动初始化指针类型不兼容错误排查

I2C驱动编译报错:函数签名不匹配问题

我在编写I2C设备驱动时陷入僵局,连续几天谷歌搜索都没解决问题。为了定位错误,我把代码简化到了最小程度:

#include <linux/i2c.h>
#include <linux/module.h>

static int my_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    pr_info("Probe function called\n");
    // Add your probe implementation here
    return 0; // Return 0 on success
}

static int my_i2c_remove(struct i2c_client *client)
{
    pr_info("Remove function called\n");
    // Add your remove implementation here
    return 0; // Return 0 on success
}

static const struct i2c_device_id my_id_table[] = {
    { "my_i2c_device", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, my_id_table);

static struct i2c_driver my_i2c_driver = {
    .driver = {
        .name = "my_i2c_driver",
        .owner = THIS_MODULE,
    },
    .probe = my_i2c_probe,
    .remove = my_i2c_remove,
    .id_table = my_id_table,
};

static int __init my_init(void)
{
    return i2c_add_driver(&my_i2c_driver);
}

static void __exit my_exit(void)
{
    i2c_del_driver(&my_i2c_driver);
}

module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Sample I2C Driver");

编译错误信息

编译时持续出现以下错误:

sudo make 
make -C /lib/modules/6.6.37-v8+/build M=/home/pi/ForestBox/driver modules
make[1]: Entering directory '/home/pi/linux-4251c6ff2aa870ca9782abc0ecdf60eac3ba22ab'
  CC [M]  /home/pi/ForestBox/driver/RTC_PCF_Driver.o
/home/pi/ForestBox/driver/RTC_PCF_Driver.c:29:14: error: initialization of ‘int (*)(struct i2c_client *)’ from incompatible pointer type ‘int (*)(struct i2c_client *, const struct i2c_device_id *)’ [-Werror=incompatible-pointer-types]
   29 |     .probe = my_i2c_probe,
      |              ^~~~~~~~~~~~
/home/pi/ForestBox/driver/RTC_PCF_Driver.c:29:14: note: (near initialization for ‘my_i2c_driver.probe’)
/home/pi/ForestBox/driver/RTC_PCF_Driver.c:30:15: error: initialization of ‘void (*)(struct i2c_client *)’ from incompatible pointer type ‘int (*)(struct i2c_client *)’ [-Werror=incompatible-pointer-types]
   30 |     .remove = my_i2c_remove,
      |               ^~~~~~~~~~~~~
/home/pi/ForestBox/driver/RTC_PCF_Driver.c:30:15: note: (near initialization for ‘my_i2c_driver.remove’)
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:243: /home/pi/ForestBox/driver/RTC_PCF_Driver.o] Error 1
make[2]: *** [/home/pi/linux-4251c6ff2aa870ca9782abc0ecdf60eac3ba22ab/Makefile:1921: /home/pi/ForestBox/driver] Error 2
make[1]: *** [Makefile:234: __sub-make] Error 2
make[1]: Leaving directory '/home/pi/linux-4251c6ff2aa870ca9782abc0ecdf60eac3ba22ab'
make: *** [Makefile:5: all] Error 2

环境信息

  • 内核版本:
$ uname -r
6.6.37-v8+
  • GCC版本:
$ gcc --version
gcc (Debian 12.2.0-14) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我知道错误是函数签名不匹配,但我觉得自己的签名是正确的。在另一台同设备的全新系统测试,还是一样的错误。怀疑是版本问题,但不知道怎么验证。


问题根源

你的内核版本是6.6.37,属于较新的Linux内核,I2C驱动的probe和remove函数签名已经发生了变化:

  1. probe函数:旧版本内核支持带const struct i2c_device_id *id参数的签名,但新内核已经废弃该形式,要求probe只接收struct i2c_client *client一个参数。
  2. remove函数:旧版本返回int,新内核要求返回void,不再需要返回值。

修改后的代码

#include <linux/i2c.h>
#include <linux/module.h>

static int my_i2c_probe(struct i2c_client *client)
{
    pr_info("Probe function called\n");
    // Add your probe implementation here
    return 0; // Return 0 on success
}

static void my_i2c_remove(struct i2c_client *client)
{
    pr_info("Remove function called\n");
    // Add your remove implementation here
}

static const struct i2c_device_id my_id_table[] = {
    { "my_i2c_device", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, my_id_table);

static struct i2c_driver my_i2c_driver = {
    .driver = {
        .name = "my_i2c_driver",
        .owner = THIS_MODULE,
    },
    .probe = my_i2c_probe,
    .remove = my_i2c_remove,
    .id_table = my_id_table,
};

static int __init my_init(void)
{
    return i2c_add_driver(&my_i2c_driver);
}

static void __exit my_exit(void)
{
    i2c_del_driver(&my_i2c_driver);
}

module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Sample I2C Driver");

验证版本兼容性的方法

你可以直接查看当前内核的i2c.h头文件,确认struct i2c_driver的定义:

cat /usr/src/linux-headers-$(uname -r)/include/linux/i2c.h | grep -A 10 "struct i2c_driver"

在6.6版本的内核中,i2c_driver的probe和remove定义如下:

struct i2c_driver {
    ...
    int (*probe)(struct i2c_client *client);
    void (*remove)(struct i2c_client *client);
    ...
};

内容的提问来源于stack exchange,提问作者Mykola Grodskyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:54:54