struct i2c_driver 从不兼容的指针类型内核设备驱动程序初始化‘int (*)(struct i2c_client *)’

问题描述 投票:0回答:1

我正在尝试为我的 i2с 设备编写驱动程序。但我遇到了一个死胡同的问题,我在Google的帮助下好几天都无法解决。

总的来说,我将代码简化到最少,以了解错误到底在哪里。

#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

这是内核版本

pi@raspberrypi:~/ForestBox/driver $ uname -r
6.6.37-v8+

海湾合作委员会版本

pi@raspberrypi:~/ForestBox/driver $ 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.

我了解错误的含义,并且签名必须匹配。在我看来它们是一样的。

我尝试在另一个新操作系统但相同的设备上执行相同的操作,但遇到了相同的错误

我怀疑版本有错误,但如何检查?

c linux-kernel raspberry-pi linux-device-driver embedded-linux
1个回答
0
投票

您的代码存在多个不同严重程度的问题。我按时间顺序放在下面(从旧的香草内核得到的,到新的)。

  1. 不需要模块的所有者,因为它是通过宏分配的。同时,您可以使用

    module_i2c_driver()
    宏而不是对其进行开放编码(如
    ->init()
    ->exit()
    函数。

  2. 长期以来,内核对

    —>probe()
    有两个功能,其中之一被称为
    ->probe_new()
    ,直到最近Uwe Kleine-König决定完成这项长达10年左右的工作,即将所有用户转换为使用新版本变体,少一个参数。请注意,您仍然可以从表中获取 ID,但在新代码中,它被认为是多余的,因为所有属性都应通过相应的固件接口获取:ACPI、设备树或软件节点。

  3. 他并没有就此停止,而是继续使用相同的方法从

    ->remove()
    函数中删除不必要的返回代码:a)1创建一个新的原型; 2)转换所有用户; 3)重命名回来; 4) 删除临时原型。

  4. 他还没有停止,因为新的即将到来(实际上正在进行)的更改是将 ID 表的

    .driver_data
    成员从
    kernel_ulong_t
    转换为
    const void *
    。我相信这将在几个内核版本内完成。

总结一下,您需要:1)删除

->probe()
中的最后一个参数; 2) 删除 return 语句并转换为
void
您的
->remove()
实现; 3)删除ID表中的
, 0
部分; 4)删除
.owner
分配; 5) 使用
module_i2c_driver()
宏。

© www.soinside.com 2019 - 2024. All rights reserved.