结合ioctl和at24c02的介绍,写了个at24c02的测试程序
测试硬件平台:TQ2440、at24c02
内核版本:linux-2.6.37.1
读写单独分开成两个小程序。源码如下:
写测试程序:
- #include <stdio.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <string.h>
- #include <linux/i2c-dev.h>
- #include <errno.h>
-
- int main(int argc, char *argv[])
- {
- int num, err, i, j;
- int fd, addr;
- char *buff;
-
- printf("please input as:");
- printf("./wat24 [data]\n");
- fflush(stdout);
-
- if(argc < 3){
- printf("arg error\n");
- return -1;
- }
- num = argc - 1;
-
- buff = malloc(num*sizeof(char));
- if(buff < 0){
- printf("alloc failed\n");
- return -1;
- }
-
- buff[0] = atoi(argv[1]);
-
- printf("write data:\n");
- for(i = 1; i < num; i++){
- buff[i] = atoi(argv[i + 1]);
- printf("%d\n",buff[i]);
- }
- printf("from word addr:%d\n",buff[0]);
-
- fd = open("/dev/i2c-0",O_RDWR);
- if(fd < 0){
- printf("device open failed\n");
- return -1;
- }
-
- err = ioctl(fd, I2C_SLAVE_FORCE, 0x50);
- if(err < 0){
- printf("ioctl failed:%d\n",err);
- return -1;
- }
-
- write(fd, buff, num);
-
- close(fd);
- return 0;
- }
at24c02的写操作可以直接调用write()函数实现。
可以直接进行byte write 或者 page write
在进行page write的时候需要计算好页的起始地址。
程序的使用如下:
page write
./wat24 0 1 2 3 4 5 6 7 8
表示从at24c02中word address为0的地址开始写入1~8。
./wat24 1 1 2 3 4 5 6 7 8
表示从at24c02中的word address为1的地址开始写入1~8数据,但是1是page0内的地址,地址非页对齐。
所以最后在page0内的数据是8 1 2 3 4 5 6 7,8被写到page0的首地址处了。
byte write
./wat24 255 1
byte write相对简单。255表示at24c02中的一个地址,1是向此地址中写入的数据。
读测试程序
- #include <stdio.h>
- #include <fcntl.h>
- #include <string.h>
- #include <stdlib.h>
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
-
- struct i2c_rdwr_ioctl_data rdwrdata;
-
- int main(int argc, char *argv[])
- {
- int i, err;
- int fd;
- char wordaddr;
- char *rdbuf1;
- char *rdbuf2;
- int bytenum;
-
- if(argc < 3){
- printf("please input as:");
- printf("./rat24 [read byte addr] [read num of byte]\n");
- return -1;
- }
-
- wordaddr = atoi(argv[1]);
- bytenum = atoi(argv[2]);
- printf("%d\n",bytenum);
-
- rdwrdata.msgs = (struct i2c_msg *)malloc(2*sizeof(struct i2c_msg));
- if(!rdwrdata.msgs){
- printf("rdwrdata.msgs malloc failed!\n");
- return -1;
- }
-
- rdbuf1 = (unsigned char *)malloc(sizeof(char));
- rdbuf2 = (unsigned char *)malloc(bytenum*sizeof(char));
- if((!rdbuf1) || (!rdbuf2)){
- printf("rdbuf malloc failed!\n");
- return -1;
- }
-
- rdwrdata.nmsgs = 2;
-
- (rdwrdata.msgs[0]).addr = 0x50;
- (rdwrdata.msgs[0]).len = 1;
- (rdwrdata.msgs[0]).flags = 0;
- (rdwrdata.msgs[0]).buf = rdbuf1;
- (rdwrdata.msgs[0]).buf[0] = wordaddr;
-
- (rdwrdata.msgs[1]).addr = 0x50;
- (rdwrdata.msgs[1]).len = bytenum;
- (rdwrdata.msgs[1]).flags = I2C_M_RD;
- (rdwrdata.msgs[1]).buf = rdbuf2;
-
- fd = open("/dev/i2c-0",O_RDWR);
- if(fd < 0){
- printf("i2c device open failed!\n");
- return -1;
- }
-
- err = ioctl(fd, I2C_SLAVE_FORCE, 0x50);
- if(err < 0){
- printf("ioctl failed\n");
- return -1;
- }
-
- err = ioctl(fd, I2C_RDWR, &rdwrdata);
- if(err < 0){
- printf("ioctl msgs error, error number:%d\n", err);
- return -1;
- }
-
- printf("read %d byte data from at24c02 word address 0x%02x:\n",bytenum, wordaddr);
- for(i = 0; i < bytenum; i++)
- printf("%d\n", rdbuf2[i]);
-
- close(fd);
- return 0;
- }
at24c02的read总共有三种
1.current read
2.sequential read
3.random read
其中1和2可以直接通过read系统调用实现
3.的话就需要通过ioctl(,I2C_RDWR,)来实现。
上述程序就是实现这个功能的,可以实现at24c02的random read。
random read
./rat24 0 256
表示从at24c02的word address为0的地址开始读取256个字节数据
./rat24 0 8
表示从at24c02的word address为0的地址开始读取8个字节的数据,即读取page0的数据。