【转】--在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\n");
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\n");
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\n", ret);
close(fd);
free(work_queue.msgs);
return 0;
} else {
printf("read salve:%02x reg:%02x\n", 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\n");
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\n");
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\n", ret);
close(fd);
free(work_queue.msgs);
return 0;
} else {
printf("write salve:%02x reg:%02x\n", 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:\n%s /dev/i2c-x start_addr reg_addr rw[0|1] [write_val]\n", argv[0]);
return 0;
} fd = open(argv[1], O_RDWR); if (!fd) {
printf("Error on opening the device file %s\n", 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\n", argv[1], slave_address, reg_address, rw_val);
} else {
if (argc < 6) {
printf("Usage:\n%s /dev/i2c-x start_addr reg_addr r|w[0|1] [write_val]\n", argv[0]);
return 0;
}
sscanf(argv[5], "%d", &w_val);
if ((w_val & ~0xff) != 0)
printf("Error on written value %s\n", 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
【转】--在Android源码树中添加userspace I2C读写工具(i2c-util)的更多相关文章
- 在Android源码树中添加userspace I2C读写工具(i2c-util)
在Android源码树中添加userspace I2C读写工具(i2c-util) http://blog.csdn.net/21cnbao/article/details/7919055 分类: A ...
- Android源码中添加C可执行程序
在Android源码中添加C/CPP可执行程序一般保存在external目录中 下面是每个文件的内容 ①add.c #include "add.h" int add (int a, ...
- Android源码中添加APP
参考罗升阳<Android系统源代码情景分析> 在Android源码中,我们通常把实验性质的Android APP放在packages/experimental目录下.对于一个简单的应用程 ...
- 在Android 源码中添加系统服务
Android系统本身提供了很多系统服务,如WindowManagerService,PowerManagerService等.下面描述一下添加一个系统服务的具体步骤. 1.定义自定义系统服务接口 撰 ...
- Eclipse与Android源码中ProGuard工具的使用
由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...
- Eclipse与Android源码中ProGuard工具的使用(代码混淆)
由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...
- Android源码中编译出指定jar包
今天想把android源码/vendor/letv/frameworks/base/java下的源码编译成 framework-letv.jar供乐乐语音客户端使用,编译完后,发现jar包文件虽然生成 ...
- Android源码中的FLAG为何使用16进制
1.在阅读源码的时候经常发现有一些标志属性使用一些位操作来判断是否具有该标志,增加标志或者去除标志. 比如View.java中的 /** * This view does not want keyst ...
- 关于android源码中的APP编译时引用隐藏的API出现的问题
今天在编译android源码中的计算器APP时发现,竟然无法使用系统隐藏的API,比如android.os.ServiceManager中的API,引用这个类时提示错误,记忆中在android源码中的 ...
随机推荐
- [C++] C/C++ 取整函数ceil(),floor()
使用floor函数.floor(x)返回的是小于或等于x的最大整数.如: floor(10.5) == 10 floor(-10.5) == -11 使用ceil函数.ceil(x)返回 ...
- [游戏学习29] Win32 图像处理1
>_<:bmp格式的简单处理: >_<:变暗RGB同时除以某一值 >_<:出现轮廓的是通道相减 >_<:最后一个是颜色提取 >_ ...
- [JS3] 立即执行JS
<html> <head> <title>立即执行</title> <SCRIPT TYPE="text/JavaScript" ...
- 开启Github之旅
在那个远古时代,我以为可以用GoogleCode干点事,结果啥也没干好.如今,Github已经成为了业界标杆,就连Google.微软.Facebook的开源项目都往Github搬.Github作为全球 ...
- C#——Dictionary<TKey, TValue> 计算向量的余弦值
说明:三角函数的余弦值Cos我想,每个学计算机的理工人都知道,但是真的明白它的用途,我也是刚明白.每个人在初中或者高中的时候,都有这么个疑惑,学三角函数干什么用的?很直白的答案就是考试用的.而且当时的 ...
- struts2学习笔记之一:基本简介
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个Servlet,在MVC设计模式中,Struts2作为控制器来建立模型与视图的数据交互(所有的访问都会被控制器操作控制) ...
- atitit.跨平台gui 概览
atitit.跨平台gui 概览 为什么需要跨平台gui 国际上那些跨平台的GUI程序,除了像Firefox之类的大型项目会重写界面外,中小型的项目基本上都是用GTK+或WxWidgets为多.毕竟要 ...
- paip. dsl 编程语言优点以及 常见的dsl
paip. dsl 编程语言优点以及 常见的dsl 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn. ...
- javaweb学习总结(十八)——JSP属性范围
所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以访问的保存范围. 一.JSP属性范围 JSP中提供了四种属性范围,四种属性范围分别指以下四种: 当前页:一个属性只能在一个页面中取得 ...
- Leetcode 66 Plus One STL
题意让大数加1 我的做法是先让个位+1,再倒置digits,然后进位,最后倒置digits,得到答案. class Solution { public: vector<int> plusO ...