您的位置:首页 > 其它

i2c设备驱动的四种构造方法

2016-09-23 16:33 281 查看
i2c设备驱动属于字符设备驱动,其构造自然是跟字符设备的结构一样了,字符设备:1、 分配字符设备号(主次设备号),设置为0,表示自动分配设备号 

2、构造file_operatios 3、注册设备,register_chrdev(1,2,3),三个参数分别是设备号,名称(不重要,随便起),构造的file_operations。

i2c总线驱动:核心层:提供统一的接口函数。适配器:提供硬件接口,及其硬件i2c接口

i2c的设备驱动模型 i2c_bus_type ,在这个总线上左右挂载分别是i2c_client和i2c_driver的链表,通过各自注册接口进行注册,在i2c_client 和i2c_driver的原型如下

struct i2c_client {
unsigned short flags;
/* div., see below */
unsigned short addr;
/* chip address - NOTE: 7bit */
/* addresses are stored in the
*/
/* _LOWER_ 7 bits
*/
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter;
/* the adapter we sit on */
struct i2c_driver *driver;
/* and our access routines */
struct device dev;
/* the device structure */
int irq;
/* irq issued by device */
struct list_head detected;

};

struct i2c_driver {
unsigned int class;

/* Notifies the driver that a new bus has appeared. You should avoid
* using this, it will be removed in a near future.
*/
int (*attach_adapter)(struct i2c_adapter *) __deprecated;

/* Standard driver model interfaces */
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);

/* driver model interfaces that don't relate to enumeration  */
void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_t mesg);
int (*resume)(struct i2c_client *);

/* Alert callback, for example for the SMBus alert protocol.
* The format and meaning of the data value depends on the protocol.
* For the SMBus alert protocol, there is a single bit of data passed
* as the alert response's low bit ("event flag").
*/
void (*alert)(struct i2c_client *, unsigned int data);

/* a ioctl like command that can be used to perform specific functions
* with the device.
*/
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

struct device_driver driver;
const struct i2c_device_id *id_table;

/* Device detection callback for automatic device creation */
int (*detect)(struct i2c_client *, struct i2c_board_info *);
const unsigned short *address_list;
struct list_head clients;

};

i2c_client 和i2c_driver 两个结构体之间通过name 连接在一起,只有对应的name匹配正确,才能够调用i2c_driver 中的probe函数。例如

实现i2c_dev.c和i2c_drv.c两个文件中实现at24cxx的i2c驱动代码:

一旦这两个文件的at24c8这个名字出现不同,那么这个驱动绝对不会加载成功。

以i2c设备at24c80为例分析i2c代码

1、构造/设置i2c_driver

2、注册i2c_driver

这是实现i2c设备驱动的右边部分,

然后实现根据要求实现i2c_driver中的函数,加入函数出口函数及其部分关键修饰

那么整个i2c_driver就实现了

但是这个实现,编译加载成功后,并没有在设备文件中产生可操作的接口,使用ls /dev/at24c08查看,并没有产生一个设备

这个就需要我们实现左边部分i2c_client\

代码如下

分别为驱动的入口和出口,入口函数at24cxx_dev_init中实现了适配器的分派,大多开发板中的i2c_dev适配器只有i2c-0,所以直接分派适配器即可,

i2c_new_device这是整个程序的核心,只有启动调用它,才会调用函数probe。这个函数的作用主要是强制认为设备存在。所以一旦name匹配,他就

一定能够启动probe函数

和他具有同等功能的还有一个函数:i2c_new_probed_device,区别是,这个函数用于“对于已经识别出来的设备”才会创建,即确定设备是真实存在的。

i2c_put_adapter函数和i2c_get_adapter相对应的函数,它用来释放适配器。

方法二:使用i2c_register_board_info 的板级文件构造i2c设备

方法三:直接在用户空间操作i2c设备。使用open和ioctl函数

方法四:查询所有的adpater
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: