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

    通过/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
    ");  
            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
    ");  
            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
    ", ret);  
            close(fd);  
            free(work_queue.msgs);  
            return 0;  
        } else {  
            printf("read salve:%02x reg:%02x
    ", 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
    ");  
            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
    ");  
            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
    ", ret);  
            close(fd);  
            free(work_queue.msgs);  
            return 0;  
        } else {  
            printf("write salve:%02x reg:%02x
    ", 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:
    %s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val]
    ", argv[0]);  
            return 0;  
        }  
      
        fd = open(argv[1], O_RDWR);  
      
        if (!fd) {  
            printf("Error on opening the device file %s
    ", 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
    ", argv[1], slave_address, reg_address, rw_val);  
        } else {  
            if (argc < 6) {  
                printf("Usage:
    %s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val]
    ", argv[0]);  
                return 0;  
            }  
            sscanf(argv[5], "%d", &w_val);  
            if ((w_val & ~0xff) != 0)  
                printf("Error on written value %s
    ", 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:

    LOCAL_PATH := $(call my-dir)  
    include $(CLEAR_VARS)  
      
    LOCAL_MODULE_TAGS := optional  
      
    LOCAL_MODULE := i2c-util  
      
    LOCAL_SRC_FILES +=   
        i2c-util.c   
      
    include $(BUILD_EXECUTABLE)  
    

      

    编译Android后,上述工具会位于/system/bin目录。在电路板上使用它:

    / #  i2c-rw /dev/i2c-2 0x38 0x1 0    
    read salve:38 reg:01 value:12    
    / #     
    / #  i2c-rw /dev/i2c-2 0x38 0x2 0    
    read salve:38 reg:02 value:81    
    

      

  • 相关阅读:
    父子进程 signal 出现 Interrupted system call 问题
    一个测试文章
    《淘宝客户端 for Android》项目实战 html webkit android css3
    Django 中的 ForeignKey ContentType GenericForeignKey 对应的数据库结构
    coreseek 出现段错误和Unigram dictionary load Error 新情况(Gentoo)
    一个 PAM dbus 例子
    漫画统计学 T分数
    解决 paramiko 安装问题 Unable to find vcvarsall.bat
    20141202
    js
  • 原文地址:https://www.cnblogs.com/tao560532/p/4850963.html
Copyright © 2011-2022 走看看