看linux平台的驱动程序,一切都从那对欢喜冤家开始。
且看代码:
323 module_init(lis3lv02d_i2c_init);
324 module_exit(lis3lv02d_i2c_exit);
了解与不了解linux设备驱动模型的弟兄们都知道,这两行的意思,就不多说了。
根据前面代码的指示前去阅读lis3lv02d_i2c_init函数。
306 static int __init lis3lv02d_i2c_init(void)
307 {
308 return i2c_add_driver(&lis3lv02d_i2c_driver);
309 }
这个函数看起来似乎没什么内容,只是一句简单的i2c_add_driver调用。调用的是什么东东呢?
&lis3lv02d_i2c_driver,跟谭浩强大哥学过几天c的兄弟都知道,这是一个指针变量,
指向的东西可能是康庄大道也可能是万丈深渊,不去看,永远不知道下一步到底是什么。
如诗所云,劝君更进一杯酒,西出阳关无故人!
将要开始的征程,对于初学的我们而言,全都是未知的x。
对于大神之辈,这连小儿科都不算……
方才说到i2c_add_driver()调用的参数是&lis3lv02d_i2c_driver,我们来看看它的定义和赋值
且看代码:
295 static struct i2c_driver lis3lv02d_i2c_driver = {
296 .driver = {
297 .name = "lis3lv02d",
298 },
299 .id_table = lis3lv02d_i2c_id,
300 .probe = lis3lv02d_i2c_probe,
301 .remove = lis3lv02d_i2c_remove,
302 .suspend = lis3lv02d_i2c_suspend,
303 .resume = lis3lv02d_i2c_resume,
304 };
光看这么一堆东东,如果刚开始学习的兄弟,可能会一头雾水,这都在“闹啥捏”。
所以,必须把这个结构体变量的母体(定义)列出来给大家瞅瞅。
定义在文件kernel/incluce/linux/i2c.h中:
99 /**
100 * struct i2c_driver - represent an I2C device driver
101 * @class: What kind of i2c device we instantiate (for detect)
102 * @attach_adapter: Callback for bus addition (for legacy drivers)
103 * @detach_adapter: Callback for bus removal (for legacy drivers)
104 * @probe: Callback for device binding
105 * @remove: Callback for device unbinding
106 * @shutdown: Callback for device shutdown
107 * @suspend: Callback for device suspend
108 * @resume: Callback for device resume
109 * @command: Callback for bus-wide signaling (optional)
110 * @driver: Device driver model driver
111 * @id_table: List of I2C devices supported by this driver
112 * @detect: Callback for device detection
113 * @address_data: The I2C addresses to probe, ignore or force (for detect)
114 * @clients: List of detected clients we created (for i2c-core use only)
115 *
116 * The driver.owner field should be set to the module owner of this driver.
117 * The driver.name field should be set to the name of this driver.
118 *
119 * For automatic device detection, both @detect and @address_data must
120 * be defined. @class should also be set, otherwise only devices forced
121 * with module parameters will be created. The detect function must
122 * fill at least the name field of the i2c_board_info structure it is
123 * handed upon successful detection, and possibly also the flags field.
124 *
125 * If @detect is missing, the driver will still work fine for enumerated
126 * devices. Detected devices simply won't be supported. This is expected
127 * for the many I2C/SMBus devices which can't be detected reliably, and
128 * the ones which can always be enumerated in practice.
129 *
130 * The i2c_client structure which is handed to the @detect callback is
131 * not a real i2c_client. It is initialized just enough so that you can
132 * call i2c_smbus_read_byte_data and friends on it. Don't do anything
133 * else with it. In particular, calling dev_dbg and friends on it is
134 * not allowed.
135 */
136 struct i2c_driver {
137 unsigned int class;
138
139 /* Notifies the driver that a new bus has appeared or is about to be
140 * removed. You should avoid using this if you can, it will probably
141 * be removed in a near future.
142 */
143 int (*attach_adapter)(struct i2c_adapter *);
144 int (*detach_adapter)(struct i2c_adapter *);
145
146 /* Standard driver model interfaces */
147 int (*probe)(struct i2c_client *, const struct i2c_device_id *);
148 int (*remove)(struct i2c_client *);
149
150 /* driver model interfaces that don't relate to enumeration */
151 void (*shutdown)(struct i2c_client *);
152 int (*suspend)(struct i2c_client *, pm_message_t mesg);
153 int (*resume)(struct i2c_client *);
154
155 /* a ioctl like command that can be used to perform specific functions
156 * with the device.
157 */
158 int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
159
160 struct device_driver driver;
161 const struct i2c_device_id *id_table;
162
163 /* Device detection callback for automatic device creation */
164 int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *);
165 const struct i2c_client_address_data *address_data;
166 struct list_head clients;
167 };
168 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
这个结构体,相比它在USB子系统里的各位兄弟姐妹而言,可谓小巧玲珑,聊聊数十行而已,
可别小看了这么简单一个结构体,i2c子系统中的设备端驱动,全靠他来实现与i2c core
进行交互,实现通信功能,可谓小而强大!人不可貌相,结构体不能行量,就是这个道理。
看完了这个结构体,我们来看看这个结构体变量被添加到了哪里。
来找找i2c_add_driver()这个函数的定义。
也在kernel/incluce/linux/i2c.h中:
429 static inline int i2c_add_driver(struct i2c_driver *driver)
430 {
431 return i2c_register_driver(THIS_MODULE, driver);
432 }
且看代码:
323 module_init(lis3lv02d_i2c_init);
324 module_exit(lis3lv02d_i2c_exit);
了解与不了解linux设备驱动模型的弟兄们都知道,这两行的意思,就不多说了。
根据前面代码的指示前去阅读lis3lv02d_i2c_init函数。
306 static int __init lis3lv02d_i2c_init(void)
307 {
308 return i2c_add_driver(&lis3lv02d_i2c_driver);
309 }
这个函数看起来似乎没什么内容,只是一句简单的i2c_add_driver调用。调用的是什么东东呢?
&lis3lv02d_i2c_driver,跟谭浩强大哥学过几天c的兄弟都知道,这是一个指针变量,
指向的东西可能是康庄大道也可能是万丈深渊,不去看,永远不知道下一步到底是什么。
如诗所云,劝君更进一杯酒,西出阳关无故人!
将要开始的征程,对于初学的我们而言,全都是未知的x。
对于大神之辈,这连小儿科都不算……
方才说到i2c_add_driver()调用的参数是&lis3lv02d_i2c_driver,我们来看看它的定义和赋值
且看代码:
295 static struct i2c_driver lis3lv02d_i2c_driver = {
296 .driver = {
297 .name = "lis3lv02d",
298 },
299 .id_table = lis3lv02d_i2c_id,
300 .probe = lis3lv02d_i2c_probe,
301 .remove = lis3lv02d_i2c_remove,
302 .suspend = lis3lv02d_i2c_suspend,
303 .resume = lis3lv02d_i2c_resume,
304 };
光看这么一堆东东,如果刚开始学习的兄弟,可能会一头雾水,这都在“闹啥捏”。
所以,必须把这个结构体变量的母体(定义)列出来给大家瞅瞅。
定义在文件kernel/incluce/linux/i2c.h中:
99 /**
100 * struct i2c_driver - represent an I2C device driver
101 * @class: What kind of i2c device we instantiate (for detect)
102 * @attach_adapter: Callback for bus addition (for legacy drivers)
103 * @detach_adapter: Callback for bus removal (for legacy drivers)
104 * @probe: Callback for device binding
105 * @remove: Callback for device unbinding
106 * @shutdown: Callback for device shutdown
107 * @suspend: Callback for device suspend
108 * @resume: Callback for device resume
109 * @command: Callback for bus-wide signaling (optional)
110 * @driver: Device driver model driver
111 * @id_table: List of I2C devices supported by this driver
112 * @detect: Callback for device detection
113 * @address_data: The I2C addresses to probe, ignore or force (for detect)
114 * @clients: List of detected clients we created (for i2c-core use only)
115 *
116 * The driver.owner field should be set to the module owner of this driver.
117 * The driver.name field should be set to the name of this driver.
118 *
119 * For automatic device detection, both @detect and @address_data must
120 * be defined. @class should also be set, otherwise only devices forced
121 * with module parameters will be created. The detect function must
122 * fill at least the name field of the i2c_board_info structure it is
123 * handed upon successful detection, and possibly also the flags field.
124 *
125 * If @detect is missing, the driver will still work fine for enumerated
126 * devices. Detected devices simply won't be supported. This is expected
127 * for the many I2C/SMBus devices which can't be detected reliably, and
128 * the ones which can always be enumerated in practice.
129 *
130 * The i2c_client structure which is handed to the @detect callback is
131 * not a real i2c_client. It is initialized just enough so that you can
132 * call i2c_smbus_read_byte_data and friends on it. Don't do anything
133 * else with it. In particular, calling dev_dbg and friends on it is
134 * not allowed.
135 */
136 struct i2c_driver {
137 unsigned int class;
138
139 /* Notifies the driver that a new bus has appeared or is about to be
140 * removed. You should avoid using this if you can, it will probably
141 * be removed in a near future.
142 */
143 int (*attach_adapter)(struct i2c_adapter *);
144 int (*detach_adapter)(struct i2c_adapter *);
145
146 /* Standard driver model interfaces */
147 int (*probe)(struct i2c_client *, const struct i2c_device_id *);
148 int (*remove)(struct i2c_client *);
149
150 /* driver model interfaces that don't relate to enumeration */
151 void (*shutdown)(struct i2c_client *);
152 int (*suspend)(struct i2c_client *, pm_message_t mesg);
153 int (*resume)(struct i2c_client *);
154
155 /* a ioctl like command that can be used to perform specific functions
156 * with the device.
157 */
158 int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
159
160 struct device_driver driver;
161 const struct i2c_device_id *id_table;
162
163 /* Device detection callback for automatic device creation */
164 int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *);
165 const struct i2c_client_address_data *address_data;
166 struct list_head clients;
167 };
168 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
这个结构体,相比它在USB子系统里的各位兄弟姐妹而言,可谓小巧玲珑,聊聊数十行而已,
可别小看了这么简单一个结构体,i2c子系统中的设备端驱动,全靠他来实现与i2c core
进行交互,实现通信功能,可谓小而强大!人不可貌相,结构体不能行量,就是这个道理。
看完了这个结构体,我们来看看这个结构体变量被添加到了哪里。
来找找i2c_add_driver()这个函数的定义。
也在kernel/incluce/linux/i2c.h中:
429 static inline int i2c_add_driver(struct i2c_driver *driver)
430 {
431 return i2c_register_driver(THIS_MODULE, driver);
432 }
本文深入剖析了Linux平台下I2C子系统的设备驱动模型,从初始化到具体函数调用,详细介绍了lis3lv02d_i2c_driver的结构与功能,并探讨了i2c_add_driver的工作原理。
2950

被折叠的 条评论
为什么被折叠?



