linux i2c驱动例子,Linux I2C驱动--用户态驱动简单示例

1. Linux内核支持I2C通用设备驱动(用户态驱动:由应用层实现对硬件的控制可以称之为用户态驱动),实现文件位于drivers/i2c/i2c-dev.c,设备文件为/dev/i2c-0

20180908003157247742.png

2. I2C通用设备驱动以字符设备注册进内核的

static const struct file_operations i2cdev_fops ={

.owner=THIS_MODULE,

.llseek=no_llseek,

.read=i2cdev_read,

.write=i2cdev_write,

.unlocked_ioctl=i2cdev_ioctl,

.open=i2cdev_open,

.release=i2cdev_release,

};

res= register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);

3. 对设备文件进行读写时,可以调用read、write或者ioctl等方法,他们都是通过调用函数i2c_transfer来实现的

int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, intnum)

{intret;/*REVISIT the fault reporting model here is weak:

*

* - When we get an error after receiving N bytes from a slave,

* there is no way to report "N".

*

* - When we get a NAK after transmitting N bytes to a slave,

* there is no way to report "N" ... or to let the master

* continue executing the rest of this combined message, if

* that‘s the appropriate response.

*

* - When for example "num" is two and we successfully complete

* the first message but get an error part way through the

* second, it‘s unclear whether that should be reported as

* one (discarding status on the second message) or errno

* (discarding status on the first one).*/

if (adap->algo->master_xfer) {

#ifdef DEBUGfor (ret = 0; ret < num; ret++) {

dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x,"

"len=%d%s\n", ret, (msgs[ret].flags &I2C_M_RD)? ‘R‘ : ‘W‘, msgs[ret].addr, msgs[ret].len,

(msgs[ret].flags& I2C_M_RECV_LEN) ? "+" : "");

}#endif

if (in_atomic() ||irqs_disabled()) {

ret= mutex_trylock(&adap->bus_lock);if (!ret)/*I2C activity is ongoing.*/

return -EAGAIN;

}else{

mutex_lock_nested(&adap->bus_lock, adap->level);

}

ret= adap->algo->master_xfer(adap,msgs,num);

mutex_unlock(&adap->bus_lock);returnret;

}else{

dev_dbg(&adap->dev, "I2C level transfers not supported\n");return -EOPNOTSUPP;

}

}

4. i2c_transfer通过代码可以看出,i2c_transfer 通过调用相应的 adapter 的 master_xfer方法实现的,而 master_xfer 主要是根据 struct i2c_msg 类型的msgs来进行处理的。

structi2c_msg {

__u16 addr;/*slave address*/__u16 flags;#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */

#define I2C_M_RD 0x0001 /* read data, from slave to master */

#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */

#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */

#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */

#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */

#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */__u16 len;/*msg length*/__u8*buf; /*pointer to msg data*/};

5. I2C用户态驱动简单示例

原文:https://www.cnblogs.com/wulei0630/p/9607606.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值