zoukankan      html  css  js  c++  java
  • 在Android源码树中添加userspace I2C读写工具(i2c-util)

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

    http://blog.csdn.net/21cnbao/article/details/7919055

    分类: Android系统架构

    by @宋宝华Barry

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

    [cpp] view plaincopy
     
    1. #include <stdio.h>  
    2. #include <linux/types.h>  
    3. #include <fcntl.h>  
    4. #include <unistd.h>  
    5. #include <stdlib.h>  
    6. #include <sys/types.h>  
    7. #include <sys/ioctl.h>  
    8. #include <errno.h>  
    9. #include <assert.h>  
    10. #include <string.h>  
    11. #include <linux/i2c.h>  
    12.   
    13. /* This is the structure as used in the I2C_RDWR ioctl call */  
    14. struct i2c_rdwr_ioctl_data {  
    15.         struct i2c_msg __user *msgs;    /* pointers to i2c_msgs */  
    16.         __u32 nmsgs;                    /* number of i2c_msgs */  
    17. };  
    18.   
    19. int i2c_read_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)  
    20. {  
    21.     struct i2c_rdwr_ioctl_data work_queue;  
    22.     unsigned char w_val = reg_address;  
    23.     int ret;  
    24.   
    25.     int fd = open(dev, O_RDWR);  
    26.     if (!fd) {  
    27.         printf("Error on opening the device file ");  
    28.         return 0;  
    29.     }  
    30.   
    31.     work_queue.nmsgs = 2;  
    32.     work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct  
    33.             i2c_msg));  
    34.     if (!work_queue.msgs) {  
    35.         printf("Memory alloc error ");  
    36.         close(fd);  
    37.         return 0;  
    38.     }  
    39.   
    40.     ioctl(fd, I2C_TIMEOUT, 2);  
    41.     ioctl(fd, I2C_RETRIES, 1);  
    42.   
    43.     (work_queue.msgs[0]).len = 1;  
    44.     (work_queue.msgs[0]).addr = slave_address;  
    45.     (work_queue.msgs[0]).buf = &w_val;  
    46.   
    47.     (work_queue.msgs[1]).len = len;  
    48.     (work_queue.msgs[1]).flags = I2C_M_RD;  
    49.     (work_queue.msgs[1]).addr = slave_address;  
    50.     (work_queue.msgs[1]).buf = buf;  
    51.   
    52.     ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);  
    53.     if (ret < 0) {  
    54.         printf("Error during I2C_RDWR ioctl with error code: %d ", ret);  
    55.         close(fd);  
    56.         free(work_queue.msgs);  
    57.         return 0;  
    58.     } else {  
    59.         printf("read salve:%02x reg:%02x ", slave_address, reg_address);  
    60.         close(fd);  
    61.         free(work_queue.msgs);  
    62.         return len;  
    63.     }  
    64. }  
    65.   
    66. int i2c_write_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)  
    67. {  
    68.     struct i2c_rdwr_ioctl_data work_queue;  
    69.     unsigned char w_val = reg_address;  
    70.     unsigned char w_buf[len+1];  
    71.     int ret;  
    72.   
    73.     w_buf[0] = reg_address;  
    74.   
    75.     int fd = open(dev, O_RDWR);  
    76.     if (!fd) {  
    77.         printf("Error on opening the device file ");  
    78.         return 0;  
    79.     }  
    80.   
    81.     work_queue.nmsgs = 1;  
    82.     work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct  
    83.             i2c_msg));  
    84.     if (!work_queue.msgs) {  
    85.         printf("Memory alloc error ");  
    86.         close(fd);  
    87.         return 0;  
    88.     }  
    89.   
    90.     ioctl(fd, I2C_TIMEOUT, 2);  
    91.     ioctl(fd, I2C_RETRIES, 1);  
    92.   
    93.     (work_queue.msgs[0]).len = 1 + len;  
    94.     (work_queue.msgs[0]).addr = slave_address;  
    95.     (work_queue.msgs[0]).buf = w_buf;  
    96.   
    97.     memcpy(w_buf + 1, buf, len);  
    98.   
    99.     ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);  
    100.     if (ret < 0) {  
    101.         printf("Error during I2C_RDWR ioctl with error code: %d ", ret);  
    102.         close(fd);  
    103.         free(work_queue.msgs);  
    104.         return 0;  
    105.     } else {  
    106.         printf("write salve:%02x reg:%02x ", slave_address, reg_address);  
    107.         close(fd);  
    108.         free(work_queue.msgs);  
    109.         return len;  
    110.     }  
    111. }  
    112.   
    113. int main(int argc, char **argv)  
    114. {  
    115.     unsigned int fd;  
    116.     unsigned int slave_address, reg_address;  
    117.     unsigned r_w;  
    118.     unsigned w_val;  
    119.     unsigned char rw_val;  
    120.   
    121.     if (argc < 5) {  
    122.         printf("Usage: %s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val] ", argv[0]);  
    123.         return 0;  
    124.     }  
    125.   
    126.     fd = open(argv[1], O_RDWR);  
    127.   
    128.     if (!fd) {  
    129.         printf("Error on opening the device file %s ", argv[1]);  
    130.         return 0;  
    131.     }  
    132.   
    133.     sscanf(argv[2], "%x", &slave_address);  
    134.     sscanf(argv[3], "%x", ®_address);  
    135.     sscanf(argv[4], "%d", &r_w);  
    136.   
    137.     if (r_w == 0) {  
    138.         i2c_read_reg(argv[1], &rw_val, slave_address, reg_address, 1);  
    139.         printf("Read %s-%x reg %x, read value:%x ", argv[1], slave_address, reg_address, rw_val);  
    140.     } else {  
    141.         if (argc < 6) {  
    142.             printf("Usage: %s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val] ", argv[0]);  
    143.             return 0;  
    144.         }  
    145.         sscanf(argv[5], "%d", &w_val);  
    146.         if ((w_val & ~0xff) != 0)  
    147.             printf("Error on written value %s ", argv[5]);  
    148.   
    149.         rw_val = (unsigned char)w_val;  
    150.         i2c_write_reg(argv[1], &rw_val, slave_address, reg_address, 1);  
    151.     }  
    152.   
    153.     return 0;  
    154. }  
    在android/external/新建i2c-util目录,上述源代码存入android/external/i2c-util/i2c-util.c,编写对应的Android.mk:
    [plain] view plaincopy
     
    1. LOCAL_PATH := $(call my-dir)  
    2. include $(CLEAR_VARS)  
    3.   
    4. LOCAL_MODULE_TAGS := optional  
    5.   
    6. LOCAL_MODULE := i2c-util  
    7.   
    8. LOCAL_SRC_FILES +=   
    9.     i2c-util.c   
    10.   
    11. include $(BUILD_EXECUTABLE)  
    编译Android后,上述工具会位于/system/bin目录。在电路板上使用它:
    [plain] view plaincopy
     
    1. / #  i2c-rw /dev/i2c-2 0x38 0x1 0    
    2. read salve:38 reg:01 value:12    
    3. / #     
    4. / #  i2c-rw /dev/i2c-2 0x38 0x2 0    
    5. read salve:38 reg:02 value:81   
  • 相关阅读:
    大家一起写mvc(二)
    大家一起写mvc(一)
    jquery读取XML 生成页面文件
    jquery点击区域显示或隐藏DIV,点击非该DIV的地方隐藏该DIV
    struts2 iterator排序
    解决JS传参中文乱码
    关于解决 请求被中止:无法建立SSL / TLS安全通道
    查看sqlserver被锁的表以及如何解锁
    查询sqlserver数据库视图、存储过程等包含特定的字符串
    C#中查询字符串中是否包含指定字符/串,使用IndexOf还是Contains?
  • 原文地址:https://www.cnblogs.com/tao560532/p/4348620.html
Copyright © 2011-2022 走看看