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

简介:

by LiAnLab.org / 宋宝华

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

[cpp]  view plain copy
  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 plain copy
  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 plain copy
  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 ,如需转载请自行联系原作者


相关文章
|
17天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
49 1
|
17天前
|
Java Android开发
Android反编译查看源码
Android反编译查看源码
22 0
|
3月前
|
数据采集 小程序 数据可视化
智慧校园电子班牌管理系统源码 Java Android原生
家长通过家长小程序端随时了解孩子在校的情况,实时接收学生的出勤情况,学生到校、离校时间。随时了解学生在校的表现、学生成绩排名,及时与教师沟通,关注孩子的健康成长。
30 0
智慧校园电子班牌管理系统源码 Java Android原生
|
3月前
|
算法 Java 定位技术
分享104个益智休闲安卓游戏源码,总有一款适合你
分享104个益智休闲安卓游戏源码,总有一款适合你
144 1
|
14天前
|
Android开发 开发者
Android开发之OpenGL的画笔工具GL10
这篇文章简述了OpenGL通过GL10进行三维图形绘制,强调颜色取值范围为0.0到1.0,背景和画笔颜色设置方法;介绍了三维坐标系及与之相关的旋转、平移和缩放操作;最后探讨了坐标矩阵变换,包括设置绘图区域、调整镜头参数和改变观测方位。示例代码展示了如何使用这些方法创建简单的三维立方体。
12 1
Android开发之OpenGL的画笔工具GL10
|
1月前
|
定位技术 API 数据库
基于Android的在线移动电子导航系统的研究与实现(论文+源码)_kaic
基于Android的在线移动电子导航系统的研究与实现(论文+源码)_kaic
|
1月前
|
搜索推荐 测试技术 定位技术
基于Android的自助导游系统的设计与实现(论文+源码)_kaic
基于Android的自助导游系统的设计与实现(论文+源码)_kaic
|
1月前
|
Java 关系型数据库 应用服务中间件
基于Android的人事管理系统设计与实现(论文+源码)_kaic
基于Android的人事管理系统设计与实现(论文+源码)_kaic
|
1月前
|
设计模式 测试技术 数据库
基于Android的食堂点餐APP的设计与实现(论文+源码)_kaic
基于Android的食堂点餐APP的设计与实现(论文+源码)_kaic
|
2月前
|
小程序 JavaScript Java
android电子班牌人脸识别系统源码
智慧校园云平台全套源码包含:电子班牌管理系统、成绩管理系统、考勤人脸刷卡管理系统、综合素养评价系统、请假管理系统、电子班牌发布系统、校务管理系统、小程序移动端、教师后台管理系统、SaaS运营云平台。
34 1