在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

本文出自 “宋宝华的博客” 博客,请务必保留此出处http://21cnbao.blog.51cto.com/109393/976137

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索printf
, include
, return
, linux i2c通信
, i2c设备驱动字符设备
, i2c
, argv
unsigned
i2c读写时序图、mlx90614 i2c读写程序、i2c读写、linux下i2c应用层读写、i2c读写程序,以便于您获取更多的相关知识。

时间: 2024-09-05 06:33:14

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

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

由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的理解和认识简要的做个笔记,有异议或者不解的,可以直接留言. 什么是ProGuard工具? ProGuard是android提供的一个免费的工具,它能够移除工程中一些没用的代码,或者使用语义上隐晦的名称来重命名代码中的类.字段和函数等,达到压缩.优化和混淆代码的功能.具体来说,使用ProGuard工具

android源码中的values-sw580的文件夹

问题描述 android源码中的values-sw580的文件夹 在看android联系人的源码时发现有values-sw580这样的文件夹,不知道这样的文件夹是干嘛的?还有这个文件夹的名字是如何来定义的? 解决方案 res/下文件夹的命名是这样的,名称分为两部分{作用}[-{适用条件}*]如:values/values-land/values-sw600dp/values-sw600dp-land/等, LZ看到的values-sw580dp这个文件夹,首先它里面放的是value,其实,它只有

android 源码中使用System.loadLibrary加载第三方库

问题描述 android 源码中使用System.loadLibrary加载第三方库 我在android源码中编译一个apk,使用了几个第三方库文件,下面是Android.mk文件内容: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := debug optional eng LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE

如何学习android源码中的framework,只有java基础

问题描述 如何学习android源码中的framework,只有java基础 求大神指导,如何学习framework?源码里面东西太多,感觉找不到入口 解决方案 从写android应用软件开始,或者上网收集framework的一些讲解资料,网上特别多 解决方案二: 你怎么学习的java就怎么学习Android 解决方案三: 除了努力還是努力加油 解决方案四: 围绕AMS和WMS展开,Android系统核心就这两个,弄懂了这两个服务如何和应用交互的,基本就了解Android系统的运行原理了. 解决

android studio导入-android studio 导入android源码中的项目的问题

问题描述 android studio 导入android源码中的项目的问题 android studio 导入android源码中的项目的问题.android stufio如何导入android源码中的项目可以不出错,或者怎么修改,可以在android studio上正常使用.请手请指教 解决方案 如果你指的是导入Eclipse 的Project :http://ask.android-studio.org/?/explore/sort_type-new__category-19__day-0

android-搜索Android源码中的下拉资源

问题描述 搜索Android源码中的下拉资源 在grepAndroid源码时进行divider_holo_light,获得如下结果: ~/platform_frameworks_base/core/res/res master gg divider_holo_light . ./values/arrays.xml:137: <item>@drawable/list_section_divider_holo_light</item> ./values/arrays.xml:239:

《Android 源码设计模式解析与实战》——第2章,第2.7节Android源码中的单例模式

2.7 Android源码中的单例模式在Android系统中,我们经常会通过Context获取系统级别的服务,如WindowsManagerService.ActivityManagerService等,更常用的是一个LayoutInflater的类,这些服务会在合适的时候以单例的形式注册在系统中,在我们需要的时候就通过Context的getSystemService(String name)获取.我们以LayoutInflater为例来说明,平时我们使用LayoutInflater较为常见的地

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

今天在编译android源码中的计算器APP时发现,竟然无法使用系统隐藏的API,比如android.os.ServiceManager中的API,引用这个类时提示错误,记忆中在android源码中的APP是可以使用隐藏的API的,为什么这个不行? 百思不得其解,最后通过对比mk文件发现,在计算机的mk文件中多了一句:LOCAL_SDK_VERSION := current,顿时发现问题所在 注释掉这句之后,重新mmm编译通过.

Android实现EditText中添加和删除bitmap的方法

本文实例讲述了Android实现EditText中添加和删除bitmap的方法.分享给大家供大家参考,具体如下: SpannableString mSpan1 = new SpannableString("1"); /* * this is add bitmap on edit text */ private void displayBitmapOnText(Bitmap thumbnailBitmap) { if(thumbnailBitmap == null) return; in