Linux I2C read eeprom 从应用层看系统

转载地址:http://www.zhimengzhe.com/bianchengjiaocheng/qitabiancheng/302708.html

Linux 操作I2C从设备有两种不同的方法。本篇文章将会介绍通过系统总线来操作I2C设备的流程。

在应用层操作I2C,使用ioctl来传参。
ret = ioctl(fd, I2C_RDWR, (unsigned long)&erom_data);
这是设备接口控制函数ioctl,

fd是打开设备节点的文件描述符 fd = open("/dev/i2c-0",O_RDWR);I2C_RDWR 是命令控制符,这是定义在 linux/i2c-dev.h 中的宏。就是告诉驱动我们要它干什么。
?
code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<code class = " hljs cs" > #define I2C_RETRIES    0x0701  /* number of times a device address should be polled when not acknowledging */
#define I2C_TIMEOUT 0x0702  /* set timeout in units of 10 ms */
 
/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
  * are NOT supported! (due to code brokenness)
  */
#define I2C_SLAVE   0x0703  /* Use this slave address */
#define I2C_SLAVE_FORCE 0x0706  /* Use this slave address, even if it
                    is already in use by a driver! */
#define I2C_TENBIT  0x0704  /* 0 for 7 bit addrs, != 0 for 10 bit */
 
#define I2C_FUNCS   0x0705  /* Get the adapter functionality mask */
 
#define I2C_RDWR    0x0707  /* Combined R/W transfer (one STOP only) */
 
#define I2C_PEC     0x0708  /* != 0 to use PEC with SMBus */
#define I2C_SMBUS   0x0720  /* SMBus transfer */</code>
?
code
1
2
<code>透过这些命令控制符,可向定义在 /linux/i2c-dev.c 的i2cdev_ioctl()函数传递cmd。下面的fops 就是定义在i2c-dev.c 的钩子函数,在应用程序空间调用ioctl,内核就会找到i2cdev_ioctl(),并且调用。然后根据传入的不同的命令控制符,来调用不同函数来实现不同的功能。
</code>
?
code
1
2
3
4
5
6
7
8
9
10
<code class = " hljs avrasm" >
     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,
};</code>

比如,我们现在传入的 I2C_RDWR ,意思就是读写,ioctl就会继续调用
i2cdev_ioctl_rdrw(client, arg);

这个函数就会透过i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);对I2C从设备进行操作。

下面介绍重头戏 erom_data

定义如下

?
code
1
<code class = " hljs cs" >   struct  i2c_rdwr_ioctl_data     erom_data;</code>

我们看看 i2c_rdwr_ioctl_data 是什么内容

?
code
1
2
3
4
<code class = " hljs cs" > struct i2c_rdwr_ioctl_data {
     struct i2c_msg __user   *msgs;    /* pointers to i2c_msgs */
     __u32   nmsgs;                    /* number of i2c_msgs */
};</code>

msgs 从命名上就可以看出 这就是我们和终端设备通讯 的消息,
nmsgs 也可以看出,这是消息的数量。

我们看看 i2c_msg 是什么内容

?
code
1
2
3
4
5
6
7
8
9
10
11
12
13
<code class = " hljs cs" > struct i2c_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          */
};</code>

这些成员就不用解释了吧,上面的注释都写得很清楚了。
flags需要解释下(我认为)如果在设置的时候不赋值,或者设置为0,应该是向从设备写入数据。赋值为I2C_M_RD 则为向从设备读取数据。

总结 ioctl(fd, I2C_RDWR, (unsigned long)&erom_data);

这一行代码,就实现了以下内容

-明确我们操作的设备是什么,这个由fd确定。
- 告诉驱动我们让它实现什么功能,这个由I2C_RDWR确定,还可以填入另外的值,可以参照上面宏设置。
- 和从设备通讯的 msgs。(个人认为,这个msgs 可能是发送给master,即I2C控制器的消息,这里面包含了 slave address 、flags等设置,这些都是告诉master 怎么和 终端设备通讯)。
- 我们可以从*buf 读出或者写入数据

以上解释了ioctl内核操作的流程.下面介绍我们该如何填充 i2c_rdwr_ioctl_data erom_data; 以上就是Linux I2C read eeprom 从应用层看系统的全文介绍,希望对您学习和使用程序编程有所帮助.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值