首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

在Android源码树中平添userspace I2C读写工具(i2c-util)

2012-09-07 
在Android源码树中添加userspace I2C读写工具(i2c-util)by @宋宝华Barry通过/dev/i2c-n节点,用户可以在use

在Android源码树中添加userspace I2C读写工具(i2c-util)

by @宋宝华Barry

通过/dev/i2c-n节点,用户可以在userspace直接访问板上的i2c外设寄存器,主要是透过I2C_RDWR这个IO控制命令将i2c_msg数组传递给kernel去执行。下面的代码可以完成这个功能:

  • #include <stdio.h>  #include <linux/types.h>  
  • #include <fcntl.h>  #include <unistd.h>  
  • #include <stdlib.h>  #include <sys/types.h>  
  • #include <sys/ioctl.h>  #include <errno.h>  
  • #include <assert.h>  #include <string.h>  
  • #include <linux/i2c.h>    
  • /* This is the structure as used in the I2C_RDWR ioctl call */  struct i2c_rdwr_ioctl_data {  
  •         struct i2c_msg __user *msgs;    /* pointers to i2c_msgs */          __u32 nmsgs;                    /* number of i2c_msgs */  
  • };    
  • int i2c_read_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)  {  
  •     struct i2c_rdwr_ioctl_data work_queue;      unsigned char w_val = reg_address;  
  •     int ret;    
  •     int fd = open(dev, O_RDWR);      if (!fd) {  
  •         printf("Error on opening the device file\n");          return 0;  
  •     }    
  •     work_queue.nmsgs = 2;      work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct  
  •             i2c_msg));      if (!work_queue.msgs) {  
  •         printf("Memory alloc error\n");          close(fd);  
  •         return 0;      }  
  •       ioctl(fd, I2C_TIMEOUT, 2);  
  •     ioctl(fd, I2C_RETRIES, 1);    
  •     (work_queue.msgs[0]).len = 1;      (work_queue.msgs[0]).addr = slave_address;  
  •     (work_queue.msgs[0]).buf = &w_val;    
  •     (work_queue.msgs[1]).len = len;      (work_queue.msgs[1]).flags = I2C_M_RD;  
  •     (work_queue.msgs[1]).addr = slave_address;      (work_queue.msgs[1]).buf = buf;  
  •       ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);  
  •     if (ret < 0) {          printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);  
  •         close(fd);          free(work_queue.msgs);  
  •         return 0;      } else {  
  •         printf("read salve:%02x reg:%02x\n", slave_address, reg_address);          close(fd);  
  •         free(work_queue.msgs);          return len;  
  •     }  }  
  •   int i2c_write_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)  
  • {      struct i2c_rdwr_ioctl_data work_queue;  
  •     unsigned char w_val = reg_address;      unsigned char w_buf[len+1];  
  •     int ret;    
  •     w_buf[0] = reg_address;    
  •     int fd = open(dev, O_RDWR);      if (!fd) {  
  •         printf("Error on opening the device file\n");          return 0;  
  •     }    
  •     work_queue.nmsgs = 1;      work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct  
  •             i2c_msg));      if (!work_queue.msgs) {  
  •         printf("Memory alloc error\n");          close(fd);  
  •         return 0;      }  
  •       ioctl(fd, I2C_TIMEOUT, 2);  
  •     ioctl(fd, I2C_RETRIES, 1);    
  •     (work_queue.msgs[0]).len = 1 + len;      (work_queue.msgs[0]).addr = slave_address;  
  •     (work_queue.msgs[0]).buf = w_buf;    
  •     memcpy(w_buf + 1, buf, len);    
  •     ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);      if (ret < 0) {  
  •         printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);          close(fd);  
  •         free(work_queue.msgs);          return 0;  
  •     } else {          printf("write salve:%02x reg:%02x\n", slave_address, reg_address);  
  •         close(fd);          free(work_queue.msgs);  
  •         return len;      }  
  • }    
  • int main(int argc, char **argv)  {  
  •     unsigned int fd;      unsigned int slave_address, reg_address;  
  •     unsigned r_w;      unsigned w_val;  
  •     unsigned char rw_val;    
  •     if (argc < 5) {          printf("Usage:\n%s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val]\n", argv[0]);  
  •         return 0;      }  
  •       fd = open(argv[1], O_RDWR);  
  •       if (!fd) {  
  •         printf("Error on opening the device file %s\n", argv[1]);          return 0;  
  •     }    
  •     sscanf(argv[2], "%x", &slave_address);      sscanf(argv[3], "%x", ?_address);  
  •     sscanf(argv[4], "%d", &r_w);    
  •     if (r_w == 0) {          i2c_read_reg(argv[1], &rw_val, slave_address, reg_address, 1);  
  •         printf("Read %s-%x reg %x, read value:%x\n", argv[1], slave_address, reg_address, rw_val);      } else {  
  •         if (argc < 6) {              printf("Usage:\n%s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val]\n", argv[0]);  
  •             return 0;          }  
  •         sscanf(argv[5], "%d", &w_val);          if ((w_val & ~0xff) != 0)  
  •             printf("Error on written value %s\n", argv[5]);    
  •         rw_val = (unsigned char)w_val;          i2c_write_reg(argv[1], &rw_val, slave_address, reg_address, 1);  
  •     }    
  •     return 0;  }  在android/external/新建i2c-util目录,上述源代码存入android/external/i2c-util/i2c-util.c,编写对应的Android.mk:[plain] view plaincopy
    1. LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  
    2.   LOCAL_MODULE_TAGS := optional  
    3.   LOCAL_MODULE := i2c-util  
    4.   LOCAL_SRC_FILES += \  
    5.     i2c-util.c \    
    6. include $(BUILD_EXECUTABLE)  
    编译Android后,上述工具会位于/system/bin目录。在电路板上使用它:[plain] view plaincopy
    1. / #  i2c-rw /dev/i2c-2 0x38 0x1 0    read salve:38 reg:01 value:12    
    2. / #     / #  i2c-rw /dev/i2c-2 0x38 0x2 0    
    3. read salve:38 reg:02 value:81   

  • 热点排行