基于i2c-dev.c与i2c client交互的应用程序

linux kernel version:4.4.38

hardware platform: exynos4412-tiny4412

基于i2c-dev.c写应用程序,在用户空间与i2c设备交互  

  1 #include <stdio.h>  
2 #include<stdlib.h>
3
#include<string.h> 4 #include <errno.h> 5 #include <unistd.h> 6 #include <sys/ioctl.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 #include <fcntl.h> 10 #include <linux/i2c.h> 11 #include <linux/i2c-dev.h> 12 13 // my_i2c_app [adapter number] [client addr] [r] [register addr] 14 // my_i2c_app [adapter number] [client addr] [w] [register addr] [register value]
  //eg: ./my_i2c_app 0x3 0x4c w 0x8 0x4
  //eg: ./my_i2c_app 0x3 0x4c r 0x8
15 #define I2C_ADAPTER_FORMAT "/dev/i2c-%d" 16 #define I2C_WRIRE 0 17 #define I2C_READ 1 18 19 struct i2c_rdwr_ioctl_data work_queue; 20 unsigned char adapter_addr = 0; 21 unsigned char client_addr = 0; 22 unsigned char register_addr = 0; 23 unsigned char flags = 0; 24 unsigned char register_value = 0; 25 //解析参数,这里图省事,定义了全局变量 26 int analyse_parse(int argc, char *argv[]){ 27 28 if(argc < 5){ 29 return -1; 30 } 31 32 adapter_addr = strtoul(argv[1], NULL, 16); 33 client_addr = strtoul(argv[2], NULL, 16); 34 register_addr = strtoul(argv[4], NULL, 16); 35 36 if(argv[3][0] == 'w'){ 37 flags = I2C_WRIRE; 38 register_value = strtoul(argv[5], NULL, 16); 39 } 40 else { 41 flags = I2C_READ; 42 } 43 44 printf("i2c client adapter [0x%02x]\n", adapter_addr); 45 printf("i2c client address [0x%02x]\n", client_addr); 46 printf("i2c register address [0x%02x]\n", register_addr); 47 printf("i2c register value [0x%02x]\n", register_value); 48 printf("i2c flags [0x%02x]\n", flags); 49 return 0; 50 } 51 52 int create_ioctl_data(void) 53 { 54   //malloc 两个i2c_msg,因为写只需要一个i2c_msg就ok,但是读需要两个 55 work_queue.nmsgs = 2; 56 work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg)); 57 work_queue.msgs[0].buf = (unsigned char *)malloc(8 * sizeof(unsigned char)); 58 work_queue.msgs[1].buf = (unsigned char *)malloc(8 * sizeof(unsigned char)); 59 60 if(work_queue.msgs == NULL || work_queue.msgs[0].buf == NULL || work_queue.msgs[1].buf == NULL){ 61 return -1; 62 } 63 64 if(flags == I2C_WRIRE){ 65 //write 66 work_queue.nmsgs = 1; 67 (work_queue.msgs[0]).flags = I2C_WRIRE;//write 68 (work_queue.msgs[0]).addr = client_addr; 69 (work_queue.msgs[0]).len = 2; 70 (work_queue.msgs[0]).buf[0] = register_addr;//因为上面buf已经分配过了 71 (work_queue.msgs[0]).buf[1] = register_value;//因为上面buf已经分配过了 72 } 73 else { 74 //read 75 work_queue.nmsgs = 2; 76 (work_queue.msgs[0]).flags = I2C_WRIRE;//write 77 (work_queue.msgs[0]).addr = client_addr; 78 (work_queue.msgs[0]).len = 1; 79 (work_queue.msgs[0]).buf[0] = register_addr;//因为上面buf已经分配过了 80 81 (work_queue.msgs[1]).flags = I2C_READ;//read 82 (work_queue.msgs[1]).addr = client_addr; 83 (work_queue.msgs[1]).len = 1; 84 (work_queue.msgs[1]).buf[0] = 0; //memset 85 } 86 return 0; 87 } 88 89 void free_memory(void) 90 { 91 free(work_queue.msgs[0].buf); 92 free(work_queue.msgs[1].buf); 93 free(work_queue.msgs); 94 return ; 95 } 96 97 int main(int argc, char *argv[]) 98 { 99 int ret; 100 int fd; 101 int i; 102 unsigned char file_name[32]; 103 104 ret = analyse_parse(argc, argv); 105 if(ret < 0){ 106 printf("param error!!!"); 107 return -1; 108 } 109 110 ret = create_ioctl_data(); 111 if(ret < 0){ 112 printf("create_ioctl_data error!!!"); 113 return -1; 114 } 115 116 memset(file_name, 0, sizeof(file_name)); 117 snprintf(file_name, sizeof(file_name), I2C_ADAPTER_FORMAT, adapter_addr); 118 119 fd = open(file_name, O_RDWR); 120 if(fd < 0){ 121 perror("open"); 122 return -1; 123 } 124 125 //set i2c client address 126 ret = ioctl(fd, I2C_SLAVE, client_addr); 127 if(ret < 0){ 128 perror("ioctl"); 129 return -1; 130 } 131   //经测试,写的时候用write系统调用ok,读的时候read不行
    //read系统调用不能repeat start
132 ret = ioctl(fd, I2C_RDWR, (unsigned long)&work_queue); 133 printf("%s %d ret=%d\n", __FUNCTION__, __LINE__, ret); 134 if(flags == I2C_WRIRE){ 135 //write 136 printf("i2c client addr [0x%02x] reg_address [0x%02x] data [0x%02x]\n", client_addr, register_addr, work_queue.msgs[0].buf[1]); 137 } 138 else { 139 //read 140 printf("i2c client addr [0x%02x] reg_address [0x%02x] data [0x%02x]\n", client_addr, register_addr, work_queue.msgs[1].buf[0]); 141 } 142 143 close(fd); 144 free_memory(); 145 return ret; 146 147 }

 

posted @ 2021-05-12 16:46  王东力  阅读(155)  评论(0)    收藏  举报