linux i2c驱动1. i2c-dev interfaceI2C dev-interface通常,i2c设备由某个内核驱动控制。
但是在用户空间,也可以访问某个I2C设备:你需要加载i2c-dev模块。
每个被注册的i2c适配器(控制器)会获得一个数字号,从0开始。
你可以检查/sys/class/i2c-dev,来查看适配器对应哪个数字号。
你也可以通过命令"i2cdetect -l"获取你的当前系统的所有I2c适配器的列表。
i2cdetct是i2c-tool包中的一个工具。
i2c设备文件是字符设备,主设备号是89,次设备号的分配如上所述。
设备文件名通常被规定为"i2c-%d"(i2c-0, i2c-1, ...,i2c-10, ...)i2c设备文件是字符设备,主设备号是89,次设备号的分配如上所述。
设备文件名通常被规定为"i2c-%d"(i2c-0, i2c-1, ...,i2c-10, ...).所有256个次设备号都保留给i2c使用。
C example=========假定你要在你的C应用程序中访问i2c适配器。
第一件事情就是包含头文件"#include<linux/i2c-dev.h>"。
注意,存在两个"i2c-dev.h"文件: 一个属于Linux kernel,用于内核驱动中;一个由i2c-tools发布,用于用户程序。
显然,这里需要使用第二个i2c-dev.h文件。
现在,你需要确定访问哪个适配器。
你需要通过查看/sys/class/i2c-dev/或者运行"i2cdetect -l"确定。
适配器号时常是动态分配的,你无法预先假定某个值。
因为它们甚至会在系统重启后变为不同的值。
下一步,打开设备文件,如下:int file;int adapter_nr = 2; /*probably dynamically determined */char filename[20];snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);file = open(filename, O_RDWR);if (file < 0) {/* ERROR HANDLING; you can check errno to see what went wrong */ exit(1);}当你打开设备后,你必须明确说明你相与哪个设备地址进行通信:int addr = 0x40;if (ioctl(file, I2C_SLAVE, addr) < 0) {/* ERROR HANDLING; you can check errno to see what went wrong */ exit(1);}Well, 你现在准备好与I2C设备通信了。
你现在可以使用SMBus命令集或者无格式I2C(plain I2C)与你的设备进行通信。
如果设备支持SMB协议,则SMBus命令集优先选择。
代码如下:__u8 register = 0x10; /* Device register to access */__s32 res;char buf[10];/* Using SMBus commands */res = i2c_smbus_read_word_data(file, register);if (res < 0) {/* ERROR HANDLING; you can check errno to see what went wrong */ } else {/* res contains the read word */}/* Using I2C Write, equivalent ofi2c_smbus_write_word_data(file, register, 0x6543) */buf[0] = reister;buf[1] = 0x43;buf[2] = 0x65;if (write(file ,buf, 3) != 3) {/* ERROR HANDLING: i2c transaction failed */}/* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */if (read(file, buf, 1) != 1) {/* ERROR HANDLING: i2c transaction failed */} else {/* buf[0] contains the read byte */}注意,仅有I2C和SMBus协议的一部分子集功能可以通过read()和write()的调用完成。
尤其,对于组合型的传输(mixing read and write messages in the same transaction)不被read()/write()支持。
基于这个原因,read()和write()这两个接口几乎不被用户空间程序使用。
IMPORTANT: because of the use of inline functions, you *have* to use '-O" orsome variation when you compile your program!Full interface description==========================IOCTLs定义如下:ioctl(file ,I2C_SLAVE, long addr)Change slave address. The address is passed in the 7 lower bits of the argument (except for 10 bit addresses, passed in the 10 lower bits in this case)ioctl(file, I2C_TENBIT, long select)Selects ten bit addressed if select not equals 0, selects normal 7 bit addresses if select equals 0. Default 0. This request is only valid if theadapter has I2C_FUNC_10BIT_ADDR.ioctl(file, I2C_PEC, long select)Selects SMBus PEC (packet error checking) generation and verification if select not equals 0, disables if select equals 0. Default 0.Used only for SMBus transactions. This request only has an effect if the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just doesn't haveany effect.ioctl(file, I2C_FUNCS, unsigned long *funcs)Gets the adapter functionality and puts it in *funcs.ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)Do combined read/write transaction without stop in between. Only validif theadatpter has I2C_FUNC_I2C. The argument is a pointer to astruct i2c_rdwr_ioctl_data {struct i2c_msg *msgs; /* ptr to array of simple messages */int nmsgs; /* number of messages to exchanges */}msgs[]包含指向data buffer的指针。
此函数调用会根据每个message中的I2C_M_RD flag的设置向buffer写或者读数据。
在每个message里,slave address和是否使用ten-bit-address必须设置。
ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)Not meant to be called directly; instead, use the access functions below.你可以通过使用read(2)和write(2)调用来进行无格式i2c传输。
在访问设备前通过ioctlI2C_SLAVE来设置地址。
你可以使用SMBus级传输(see documentation file smbus-protocol for details),通过如下函数调用:__s32 i2c_smbus_write_quick(int file, __u8 value);__s32 i2c_smbus_read_byte(int file);__s32 i2c_smbus_write_byte(int file, __u8 value);__s32 i2c_smbus_read_byte_data(int file, __u8 command);__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value); __s32 i2c_smbus_read_word_data(int file, __u8 command);__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value); __s32 i2c_smbus_process_call(int file, __u8 comand, __u16 value); __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8*values);__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, __u8 *values);所有上述传输失败时返回-1;你可以读取errno来检查具体错误信息。