在Android源码树中添加userspace I2C读写工具(i2c-util)-阿里云开发者社区

开发者社区> 技术小胖子> 正文

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

简介:
+关注继续查看

by LiAnLab.org / 宋宝华

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

  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\n");  
  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\n");  
  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\n", ret);  
  55.         close(fd);  
  56.         free(work_queue.msgs);  
  57.         return 0;  
  58.     } else {  
  59.         printf("read salve:%02x reg:%02x\n", 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\n");  
  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\n");  
  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\n", ret);  
  102.         close(fd);  
  103.         free(work_queue.msgs);  
  104.         return 0;  
  105.     } else {  
  106.         printf("write salve:%02x reg:%02x\n", 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:\n%s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val]\n", 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\n", 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\n", argv[1], slave_address, reg_address, rw_val);  
  140.     } else {  
  141.         if (argc < 6) {  
  142.             printf("Usage:\n%s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val]\n", 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\n", 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    

 本文转自 21cnbao 51CTO博客,原文链接:http://blog.51cto.com/21cnbao/976137,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android开发8——利用pull解析器读写XML文件
  一、基本介绍 对XML解析有SAX和DOM等多种方式,Android中极力推荐xmlpull方式解析xml。xmlpull不仅可用在Android上同样也适用于javase,但在javase环境中需自己获取xmlpull所依赖的类库,kxml2-2.3.0.jar,xmlpull_1_1_3_4c.jar。   jar包下载网址http://www.xmlpull.org/ht
1120 0
继克仔修改了我的RssReader后,添加了的用mail发送文章的功能!
修改后的源代码下载:http://files.cnblogs.com/aowind/RssReader2.rar主要添加了一个mail.vb的窗体:源代码如下: Imports System.web.mailPublic Class mailClass mail    Inherits System.Windows.Forms.Form#Region " Windows 窗体设计器生成的代码 "    Public Sub New()Sub New()        MyBase.New()        '该调用是 Windows 窗体设计器所必需的。
480 0
WPF 为资源字典 添加事件响应的后台类
原文:WPF 为资源字典 添加事件响应的后台类 前言,有许多同学在写WPF程序时在资源字典里加入了其它控件,但又想写事件来控制这个控件,但是资源字典没有CS文件,不像窗体XAML还有一个后台的CS文件,怎么办呢? 在工作时也遇到了这个问题,现在把它分享出来 比如说我们现在要写一个TabControl控件,在TabItem中有一个关闭按钮或其它按钮,这个按钮要能响应某个事件。
1085 0
【最佳实践】OSS开源工具ossutil-上传性能调优
经常碰到内部同学或者外部客户问ossutil关于并发上传性能的问题。本文简单描述下ossutil并发上传原理并举例说明。 用户可从这里获取ossutil。 官网:https://help.aliyun.com/document_detail/50452.html代码:https://github.com/aliyun/ossutil 参数 --recursive 上传文件到oss时,如果file_url为目录,则必须指定--recursive选项,否则无需指定--recursive选项。
5651 0
Android Jxl读写Excel
Jxl 包下载 Android Studio 依赖 compile 'net.sourceforge.jexcelapi:jxl:2.6.12' 本测试在Exlipse中, 由于Jxl的跨平台性。
1732 0
Android开发5——文件读写
一、基本概念 在Android应用中保存文件,保存的位置有两处 ①手机自带的存储空间,较小(如200M),适合保存一些小文件,Android中保存位置在data/data/应用包名/files目录 ②外存储设备如SD卡,较大,适合保存大文件如视频,Android中保存位置在mnt/sdcard目录,androd1.5,android1.6保存在sdcard目录 保存的位置通过and
1236 0
21119
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载