i2c驱动程序是否需要像其他字符设备驱动程序一样执行?

我是Linux设备驱动程序的noob,所以请耐心等待。 我试图实现一个i2c驱动程序(客户端)。 这是我可以insmod.probe被调用(因为设备树条目),并在.probe我可以读/写设备。 大。

不过,我需要能够从用户空间启动读取/写入驱动程序。 为了做到这一点,一个i2c驱动程序应该像任何其他字符设备驱动程序的形状? 意思是有一个file_operations结构,所以用户空间可以openclosereadwriteioctls

我在问,因为在我见过的所有i2c客户端例子中,没有人实现我提到的这些东西。 我想知道他们如何发起呼叫从用户空间没有file_operations结构设置。 也许这是如此明显,没有人提到它,我不知道…我想知道是不是因为i2c被称为平台设备驱动程序,它不需要这个? 如果有人可以证实,将帮助我第二次猜测自己。

如果你明白我在问什么,请忽略其余部分。 如果你对我的问题感到困惑,这里是我所问的更具体的解释:

我现在所拥有的:

 static int device_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct device_data *data; /* Check the functionality of the i2c-adapter for smbus byte read/write */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { printk(KERN_ALERT "%s %d: device required i2c functionality is not supported\n", __func__, __LINE__); return -ENODEV; } /* Allocate memory to hold the device data * Using devm_kzalloc so do not have to worry about kfree */ data = devm_kzalloc(dev, sizeof(struct device_data), GFP_KERNEL); if (dev == NULL) { printk(KERN_ALERT "%s %d: no memory\n", __func__, __LINE__); return -ENOMEM; } /* Record the pointer to current client */ data->device_i2c_client = client; /* Set the client's data field to point to device-specific data struct */ i2c_set_clientdata(client, data); /* Add the device-specific data struct to our collection of device client devices */ device_data_tbl[id->driver_data] = data; /* Do a read, test the access */ device_read(); return 0; } static int device_remove(struct i2c_client *client) { return 0; } int device_read(uint8_t device_device_id, uint16_t const dev_reg_addr, uint8_t *const read_val) { /* some read access */ } static struct i2c_device_id device_idtable[] = { { "si5342", 0 }, { }, }; MODULE_DEVICE_TABLE(i2c, device_idtable); static struct i2c_driver device_driver = { .driver = { .name = device_DRIVER_NAME, .owner = THIS_MODULE }, .id_table = device_idtable, .probe = device_probe, .remove = device_remove, }; static int __init device_driver_init(void) { return i2c_add_driver(&device_driver); } module_init(device_driver_init); static void __exit device_driver_exit(void) { return i2c_del_driver(&device_driver); } module_exit(device_driver_exit); 

想知道是否需要添加以下元素

 static struct file_operations oxdrv_fops = { .owner = THIS_MODULE, .release = device_release, .open = device_open, .unlocked_ioctl = device_ioctl }; /* Associated function definitions: device_open, device_ioctl, etc */ alloc_chrdev_region(); cdev_init(); 

Solutions Collecting From Web of "i2c驱动程序是否需要像其他字符设备驱动程序一样执行?"

我想我现在可以更好地理解设备驱动模型了@Alexandre Belloni的评论,并阅读了这套幻灯片: http ://free-electrons.com/doc/training/linux-kernel/linux-kernel-slides.pdf。 相关的幻灯片从第221页到第236页。

有三种类型的设备驱动程序:

  1. 字符
  2. 网络

但是,作为字符设备驱动程序的子类存在特定的“框架”,它们实现了相同类型设备的驱动程序的公共部分。

例如,用于硬件监控的主板上的温度传感器将在hwmon框架下注册( https://www.kernel.org/doc/Documentation/hwmon/hwmon-kernel-api.txt )。 您将实现i2c probereadwrite功能,而不是将其整形为具有file_operations struct的字符设备,您只需将其注册为hwmon设备: hwmon_device_register_with_groups() 。 为了暴露给用户空间,你需要使用你想要的暴露的读/写命令列表(例如:从通道1读取温度,写入限制临时寄存器)来建立你的/sys/class/hwmon/hwmon*目录。

在构建内核时,请在make menuconfig中选择您的设备,以便使用内核构建它。 这样,一旦启动内核,设备将出现在/sys/class/hwmon/hwmon* ,然后用户空间可以通过sysfs接口open并从设备read 。 看一个很好的例子: http : //lxr.free-electrons.com/source/drivers/hwmon/tmp421.c 。 或者hwmon目录中的任何设备。

所以这就是我的困惑所在。 正如@Alexandre Belloni指出的那样,这些设备是在一个框架下注册的,所以显式字符设备驱动程序代码是不必要的。 对我来说,情况并非如此,我不认为我正在做的设备(时钟PLL)有一个合适的框架。 因此,我需要去一般的路线和实现作为一个字符设备。 这也将允许我作为一个模块加载/卸载,而不是在内核启动时自动加载。

请随时纠正我所犯的任何错误。 我希望这对于编写i2c客户端的任何人都很有帮助。