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

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

分类: Android系统架构2012-08-29 10:41 3659人阅读 评论(2) 收藏 举报

by @宋宝华Barry

通过/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. /* This is the structure as used in the I2C_RDWR ioctl call */
  13. struct i2c_rdwr_ioctl_data {
  14. struct i2c_msg __user *msgs;    /* pointers to i2c_msgs */
  15. __u32 nmsgs;                    /* number of i2c_msgs */
  16. };
  17. int i2c_read_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)
  18. {
  19. struct i2c_rdwr_ioctl_data work_queue;
  20. unsigned char w_val = reg_address;
  21. int ret;
  22. int fd = open(dev, O_RDWR);
  23. if (!fd) {
  24. printf("Error on opening the device file\n");
  25. return 0;
  26. }
  27. work_queue.nmsgs = 2;
  28. work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct
  29. i2c_msg));
  30. if (!work_queue.msgs) {
  31. printf("Memory alloc error\n");
  32. close(fd);
  33. return 0;
  34. }
  35. ioctl(fd, I2C_TIMEOUT, 2);
  36. ioctl(fd, I2C_RETRIES, 1);
  37. (work_queue.msgs[0]).len = 1;
  38. (work_queue.msgs[0]).addr = slave_address;
  39. (work_queue.msgs[0]).buf = &w_val;
  40. (work_queue.msgs[1]).len = len;
  41. (work_queue.msgs[1]).flags = I2C_M_RD;
  42. (work_queue.msgs[1]).addr = slave_address;
  43. (work_queue.msgs[1]).buf = buf;
  44. ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);
  45. if (ret < 0) {
  46. printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
  47. close(fd);
  48. free(work_queue.msgs);
  49. return 0;
  50. } else {
  51. printf("read salve:%02x reg:%02x\n", slave_address, reg_address);
  52. close(fd);
  53. free(work_queue.msgs);
  54. return len;
  55. }
  56. }
  57. int i2c_write_reg(char *dev, unsigned char *buf, unsigned slave_address, unsigned reg_address, int len)
  58. {
  59. struct i2c_rdwr_ioctl_data work_queue;
  60. unsigned char w_val = reg_address;
  61. unsigned char w_buf[len+1];
  62. int ret;
  63. w_buf[0] = reg_address;
  64. int fd = open(dev, O_RDWR);
  65. if (!fd) {
  66. printf("Error on opening the device file\n");
  67. return 0;
  68. }
  69. work_queue.nmsgs = 1;
  70. work_queue.msgs = (struct i2c_msg*)malloc(work_queue.nmsgs *sizeof(struct
  71. i2c_msg));
  72. if (!work_queue.msgs) {
  73. printf("Memory alloc error\n");
  74. close(fd);
  75. return 0;
  76. }
  77. ioctl(fd, I2C_TIMEOUT, 2);
  78. ioctl(fd, I2C_RETRIES, 1);
  79. (work_queue.msgs[0]).len = 1 + len;
  80. (work_queue.msgs[0]).addr = slave_address;
  81. (work_queue.msgs[0]).buf = w_buf;
  82. memcpy(w_buf + 1, buf, len);
  83. ret = ioctl(fd, I2C_RDWR, (unsigned long) &work_queue);
  84. if (ret < 0) {
  85. printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
  86. close(fd);
  87. free(work_queue.msgs);
  88. return 0;
  89. } else {
  90. printf("write salve:%02x reg:%02x\n", slave_address, reg_address);
  91. close(fd);
  92. free(work_queue.msgs);
  93. return len;
  94. }
  95. }
  96. int main(int argc, char **argv)
  97. {
  98. unsigned int fd;
  99. unsigned int slave_address, reg_address;
  100. unsigned r_w;
  101. unsigned w_val;
  102. unsigned char rw_val;
  103. if (argc < 5) {
  104. printf("Usage:\n%s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val]\n", argv[0]);
  105. return 0;
  106. }
  107. fd = open(argv[1], O_RDWR);
  108. if (!fd) {
  109. printf("Error on opening the device file %s\n", argv[1]);
  110. return 0;
  111. }
  112. sscanf(argv[2], "%x", &slave_address);
  113. sscanf(argv[3], "%x", ®_address);
  114. sscanf(argv[4], "%d", &r_w);
  115. if (r_w == 0) {
  116. i2c_read_reg(argv[1], &rw_val, slave_address, reg_address, 1);
  117. printf("Read %s-%x reg %x, read value:%x\n", argv[1], slave_address, reg_address, rw_val);
  118. } else {
  119. if (argc < 6) {
  120. printf("Usage:\n%s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val]\n", argv[0]);
  121. return 0;
  122. }
  123. sscanf(argv[5], "%d", &w_val);
  124. if ((w_val & ~0xff) != 0)
  125. printf("Error on written value %s\n", argv[5]);
  126. rw_val = (unsigned char)w_val;
  127. i2c_write_reg(argv[1], &rw_val, slave_address, reg_address, 1);
  128. }
  129. return 0;
  130. }

在android/external/新建i2c-util目录,上述源代码存入android/external/i2c-util/i2c-util.c,编写对应的Android.mk:

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE_TAGS := optional
  4. LOCAL_MODULE := i2c-util
  5. LOCAL_SRC_FILES += \
  6. i2c-util.c \
  7. include $(BUILD_EXECUTABLE)

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

  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

在Android源码树中添加userspace I2C读写工具(i2c-util)的更多相关文章

  1. 【转】--在Android源码树中添加userspace I2C读写工具(i2c-util)

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

  2. Android源码中添加C可执行程序

    在Android源码中添加C/CPP可执行程序一般保存在external目录中 下面是每个文件的内容 ①add.c #include "add.h" int add (int a, ...

  3. Android源码中添加APP

    参考罗升阳<Android系统源代码情景分析> 在Android源码中,我们通常把实验性质的Android APP放在packages/experimental目录下.对于一个简单的应用程 ...

  4. 在Android 源码中添加系统服务

    Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等.下面描述一下添加一个系统服务的具体步骤. 1.定义自定义系统服务接口 撰 ...

  5. Eclipse与Android源码中ProGuard工具的使用

    由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...

  6. Eclipse与Android源码中ProGuard工具的使用(代码混淆)

    由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...

  7. Android源码中编译出指定jar包

    今天想把android源码/vendor/letv/frameworks/base/java下的源码编译成 framework-letv.jar供乐乐语音客户端使用,编译完后,发现jar包文件虽然生成 ...

  8. Android源码中的FLAG为何使用16进制

    1.在阅读源码的时候经常发现有一些标志属性使用一些位操作来判断是否具有该标志,增加标志或者去除标志. 比如View.java中的 /** * This view does not want keyst ...

  9. 关于android源码中的APP编译时引用隐藏的API出现的问题

    今天在编译android源码中的计算器APP时发现,竟然无法使用系统隐藏的API,比如android.os.ServiceManager中的API,引用这个类时提示错误,记忆中在android源码中的 ...

随机推荐

  1. perl debug

    1. 进入debug模式 # perl -d ./perl_debugger.pl it prompts, DB<1>   2. 查看从第10行开始的代码. 查看函数get_pattern ...

  2. 模拟一个带背景的 TPanel

    https://www.cnblogs.com/del/archive/2008/09/01/1281345.html

  3. Android:ImageView控件

    ImageView 是用于在界面上展示图片的一个控件,通过它可以让我们的程序界面变得更加 丰富多彩.学习这个控件需要提前准备好一些图片,由于目前 drawable 文件夹下已经有一张 ic_launc ...

  4. java try-with-resource语句使用

    定义 JDK7之后,Java多了个新的语法:try-with-resources语句, 可以理解为是一个声明一个或多个资源的 try语句(用分号隔开), 一个资源作为一个对象,并且这个资源必须要在执行 ...

  5. lua去掉字符串中的UTF-8的BOM三个字节

    废话不多说,还是先说点吧,项目中lua读取的text文件如果有BOM,客户端解析就会报错,所以我看了看,任务编辑器swGameTaskEditor 在写入文件的时候,也不知道为什么有的文件就是UTF- ...

  6. 服务 AIDL 定向tag IPC Parcelable 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. Windows下Phalcon的安装以及phpstorm识别phalcon语法及提示

    1.由于Phalcon是C语言写的一个扩展,所以需要安装这个扩展php_phalcon.dll,下载地址https://github.com/phalcon/cphalcon/releases, 然后 ...

  8. 〖Android〗arm-linux-androideabi-gdb报 libpython2.6.so.1.0: cannot open shared object file错误的解决方法

    执行: prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-gdb out/target/p ...

  9. virtualbox centos安装增强工具和Centos与VirtualBox共享文件夹设置

    VirtualBox 大家都习惯性把它简称为 Vbox ,比 VM 的体积小.开源.速 度快.不过在使用 VirtualBox  在虚拟机中安装 CentOS 之后,不能直接运行安装好 Virtual ...

  10. 利用jsPDF有效减轻报表型应用服务器的IO负载

    1.利用jsPDF在客户端浏览器上生成pdf文档 使用这种方法可以有效减轻服务器的压力,但是对于国际化,此库任然存在的问题:该库不支持unicode,生成中文文档会乱码,官方也有描述这个问题,详情请参 ...