文章目录

  • 一、前言
  • 二、系列文章
  • 三、准备工作
    • 3.1 挑选I2C引脚
    • 3.2 测试设备:QMI8658C
  • 四、编写设备树节点
    • 4.1 查找MUX
    • 4.2 修改i2c1引脚配置
      • 4.2.1 修改前
      • 4.2.2 修改后
  • 五、编译、烧录dt.img
    • 5.1 烧录后效果
  • 六、编写test程序
    • 6.1 创建文件
    • 6.2 源码:Android.mk
    • 6.3 源码:i2c-slaver.c
    • 6.4 编译test程序
  • 七、测试
    • 7.1 部署 i2c-slaver
    • 7.2 运行 i2c-slaver

一、前言

本文是系列文章的第3篇,介绍如何利用内核中现有的i2c bus驱动,在最少的代码量上,做到对slaver设备的控制。基于现有的i2c bus驱动,我们可直接在应用层编写slaver设备的控制代码!如此,大大降低了设备驱动的开发难度。当然,工资还是得照样领!

本文开发板基于Amlogic T972平台, Android 9.0

二、系列文章

第1篇 :不写一行代码(一):实现安卓基于GPIO的LED设备驱动

第2篇 :不写一行代码(二):实现安卓基于PWM的LED设备驱动

第3篇:不写一行代码(三):实现安卓基于i2c bus的Slaver设备驱动

三、准备工作

3.1 挑选I2C引脚

从芯片datasheet,结合开发板可用插座脚,如下所示,可挑选GPIOZ_1(SDA)、GPIOZ_2(SCL)作为实验对象

图一:Amlogic T972 Datasheet

图二:开发板J31引出的两排引脚

3.2 测试设备:QMI8658C

找了半天,没有更简单的i2c模块(例如基于I2C接口的热传感器,寄存器会很简单),只有一个六轴陀螺仪模块,所以就将就用吧!

  • VCC 3.3V – 红线
  • GND – 黑线
  • SCL2 – 黄线,连接GPIOZ_2(排针J31的PIN9)
  • SDA2 – 绿线 ,连接GPIOZ_1(排针J31的PIN8)
  • 白色和蓝色未使用

四、编写设备树节点

4.1 查找MUX

默认情况下,GPIOZ_1和GPIOZ_2是普通的GPIO引脚,无法作为I2C引脚来使用,所以我们需要修改这两个引脚的MUX配置,这些配置都是原厂已经写好的,我们只需找出来,然后填入到i2c1的控制器配置中即可。

//文件:common\arch\arm\boot\dts\amlogic\mesontl1.dtsii2c1_z_pins:i2c1_z {mux {groups = "i2c1_sda_z","i2c1_sck_z";function = "i2c1";bias-pull-up;drive-strength = <3>;};};/** i2c sleep mode1: set the gpio the input* in this scene, pull up power is off*/i2c1_z_pins_slp_input:i2c1_z_slp_input {mux {groups = "GPIOZ_1", "GPIOZ_2";function = "gpio_periphs";input-enable;bias-disable;};};

4.2 修改i2c1引脚配置

4.2.1 修改前

&i2c1 {status = "okay";clock-frequency = <300000>;pinctrl-names = "default", "sleep";pinctrl-0 = <&i2c1_h_pins>; //未修改前,i2c1模块MUX连接的PIN脚不是GPIOZ_1和GPIOZ_2pinctrl-1 = <&i2c1_h_pins_slp_input>;//未修改前,i2c1模块MUX连接的PIN脚不是GPIOZ_1和GPIOZ_2// …… 略 ……
//添加测试所用设备的DTS节点描述i2c_tof_geo@6a {compatible = "test_i2c, i2c";reg = <0x6a>;status = "okay";};
};

4.2.2 修改后

&i2c1 {status = "okay";clock-frequency = <300000>;pinctrl-names = "default", "sleep";pinctrl-0 = <&i2c1_z_pins>; //选用GPIOZ_1和GPIOZ_2的PIN脚配置,GPIOZ_1和GPIOZ_2将连通i2c1控制器模块pinctrl-1 = <&i2c1_z_pins_slp_input>;// …… 略 ……
//添加测试所用设备的DTS节点描述,测试设备的slaver address=0x6Ai2c_tof_geo@6a {compatible = "test_i2c, i2c";reg = <0x6a>;status = "okay";};
};

五、编译、烧录dt.img

参考系列文章第一篇(第四节):不写一行代码(一):实现安卓基于GPIO的LED设备驱动

5.1 烧录后效果

(1)烧录后,通过sys-fs系统,切换到如下目录,可以看到设备1-006a,也就是i2c-1的第1个设备,地址为0x6A
x301:/sys # cd bus/i2c/devices/i2c-1/
x301:/sys/bus/i2c/devices/i2c-1 # ls
1-006a delete_device device i2c-dev name new_device of_node power subsystem uevent(2) 继续进入1-006a设备的目录下,查看其设备树节点名称,可以看到:i2c_tof_geo
x301:/sys/bus/i2c/devices/i2c-1 # cd 1-006a/
x301:/sys/bus/i2c/devices/i2c-1/1-006a # ls
modalias name of_node power subsystem uevent
x301:/sys/bus/i2c/devices/i2c-1/1-006a # cat of_node/name
i2c_tof_geo
x301:/sys/bus/i2c/devices/i2c-1/1-006a #

图示:

六、编写test程序

6.1 创建文件

如下在AOSP代码的development目录下:

(1)创建目录,姑且就叫 i2c-slaver

(2)创建 Android.mk 和 i2c-slaver.c 文件

szhou@bc04:~/T972/android_x301/source/t962x3-t972-android9.0/development$ tree i2c-slaver/
i2c-slaver/
├── Android.mk
└── i2c-slaver.c0 directories, 2 files
szhou@bc04:~/T972/android_x301/source/t962x3-t972-android9.0/development$

6.2 源码:Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := i2c-slaverLOCAL_SRC_FILES := i2c-slaver.cinclude $(BUILD_EXECUTABLE)

6.3 源码:i2c-slaver.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/string.h>static int i2c_trans(int fd, __u8 rw, __u8 cmd, __u32 size, union i2c_smbus_data *data)
{struct i2c_smbus_ioctl_data args;args.read_write = rw;//0:I2C_SMBUS_WRITE, 1:I2C_SMBUS_READargs.command = cmd;args.size = size;args.data = data;return ioctl(fd,I2C_SMBUS,&args);
}static int i2c_write(int fd, __u8 cmd, __u8 value){union i2c_smbus_data data;data.byte = value;return i2c_trans(fd,I2C_SMBUS_WRITE,cmd, I2C_SMBUS_BYTE_DATA, &data);}static int  i2c_read(int fd, __u8 cmd, __u32 size, union i2c_smbus_data *data){__u32 i=0;if (i2c_trans(fd,I2C_SMBUS_READ,cmd, size, data)){printf("i2c_trans failed\n");return -1;}else{printf("\n");for(i=0; i<size; i++){printf("data[%d]=0x%02X \t", i, data->block[i]);}printf("\n");return 0;}}int main()
{int fd;union i2c_smbus_data data;//打开i2c-1总线控制器fd = open("/dev/i2c-1", O_RDWR);if (fd == -1){printf("zs, open i2c failed. \n");goto fail;}//访问Slaver地址为0x6A的设备if (ioctl(fd, I2C_SLAVE, 0x6A) < 0){printf("zs, open i2c I2C_SLAVE failed. \n");goto fail;}//发送CMD初始化测试用的i2c-slaver设备,是一个陀螺仪,各位请换成自己的i2c设备i2c_write(fd, 0x06, 0xB0);usleep(300000);i2c_write(fd, 0x02, 0x60);i2c_write(fd, 0x03, 0x24);i2c_write(fd, 0x08, 0x83);//读取陀螺仪的X、Y、Z轴的原始数据,各2bytes,一共6byteswhile(i2c_read(fd, 0x35, 6, &data) != -1){usleep(3*1000*1000); //每3秒读取一次} fail:close(fd);  return 0;
}

6.4 编译test程序

  • 注意:使用局部编译前,一般需要对整个源码做一次完整编译!
  • 生成位置:Install: out/target/product/x301/system/bin/i2c-slaver

编译步骤:

(1) source build/envsetup.sh
(2) lunch your-board
(3) make i2c-slaver

编译打印

root@d185403d1e6f:/home/builder/android_x301/source/t962x3-t972-android9.0# make i2c-slaver
// …… 略 ……
[100% 6/6] Install: out/target/product/x301/system/bin/i2c-slaver#### build completed successfully (01:48 (mm:ss)) ####root@d185403d1e6f:/home/builder/android_x301/source/t962x3-t972-android9.0#

七、测试

7.1 部署 i2c-slaver

(1)ADB 推送i2c-slaver到板子上
Z:\T972\android_x301\source\t962x3-t972-android9.0\out\target\product\x301\system\bin>adb push i2c-slaver /data/
i2c-slaver: 1 file pushed, 0 skipped. 0.9 MB/s (16016 bytes in 0.016s)(2)添加可执行权限
Z:\T972\android_x301\source\t962x3-t972-android9.0\out\target\product\x301\system\bin>adb shell chmod 777 /data/i2c-slaver

图示如下:

7.2 运行 i2c-slaver

因为打印默认是输出到串口的,所以运行部分,我们在串口上执行,当然,你也可以通过adb执行,之后dmesg查看打印

130|:/data # ./i2c-slaver                                                      //  ……  略 ……
data[0]=0x20    data[1]=0xD4    data[2]=0xF5    data[3]=0x4A    data[4]=0xF4    data[5]=0xBF
[17541.246189@2]- [dhd-wlan0] wl_run_escan : LEGACY_SCAN sync ID: 176, bssidx: 0
data[0]=0x20    data[1]=0xCE    data[2]=0xF5    data[3]=0x4D    data[4]=0xF4    data[5]=0xB9
//  ……  略 ……data[0]=0x20    data[1]=0xF7    data[2]=0xF1    data[3]=0x99    data[4]=0xF9    data[5]=0x6E
^C
130|:/data #

运行效果的图示如下,通过晃动陀螺仪模块,可以看到它的值会大幅变动,如果静置的话,则值能基本保持不变或变化很小

图示如下:

不写一行代码(三):实现安卓基于i2c bus的Slaver设备驱动相关推荐

  1. 不写一行代码(一):实现安卓基于GPIO的LED设备驱动

    文章目录 系列文章 一.前言 二.准备工作 2.1 内核版本 2.2 内核文档:bindings->leds 2.3 文档解析: leds-gpio.txt 三.编写DTS 3.1 查原理图,挑 ...

  2. MATLABSTM32CubeMX联合开发系列——不用手写一行代码就能实现CAN通讯

    MATLAB&STM32CubeMX联合开发系列--不用手写一行代码就能实现CAN通讯 从第一次搭建好MATLAB和STM32CubeMX的联合开发环境有一段时间了,之前已经发布了两个实例分享 ...

  3. 【效率】微软开源最强Python自动化神器!不用写一行代码!

    相信玩过爬虫的朋友都知道selenium,一个自动化测试的神器工具.写个Python自动化脚本解放双手基本上是常规的操作了,爬虫爬不了的,就用自动化测试凑一凑. 虽然selenium有完备的文档,但也 ...

  4. 快速实现免费的个人免签收款功能(不写一行代码)

    最近一直在研究使用冰狐智能辅助的"自动构建"功能在不编程的情况如何实现各种好玩的东东,由于自己利用业余时间开发的小工具需要用到收款功能,于是自然想到用"自动构建" ...

  5. 不写一行代码,也能解释XML,因为是JAVA

    不写一行代码,也能解释XML,因为是JAVA. 整个过程就三个步骤 1.XML转换成XSD 2.XSD生成JAVA Class 3.调用unmarshal实现转换结果 具体实例: 1.假设有一个XML ...

  6. win7滑动关机代码bat_写一行代码实现滑动关机电脑

    ياخشىمۇ سىلەر؟بۈگۈن بىز بىر قۇر كود يىزىپلا كومپىيوتىرنى سىيرىپ ئۆچۈرۈش(滑动关机) نى ئۈگۈنىمىز ! نەتىجە: ...

  7. 不写一行代码,也能玩转Kaggle竞赛?

    整理 | Jane 出品 | AI科技大本营(ID:rgznai100) [导读]AI科技大本营会给大家分享一些 Kaggle 上的资源,如 Kaggle 开放的数据集,也会分享一些好的竞赛方案或有意 ...

  8. 飞鸽传书每写一行代码都会有新的成就

    喜欢的人,日子过得非常开心,飞鸽传书每写一行代码都会有新的成就,尤其当自己的作品被广泛应用的时候,那种自豪感油然而起. 不喜欢的人,飞鸽传书x坐在电脑前极端无聊,被进度压得喘不过气来,天天为找bug改 ...

  9. 不写一行代码就能玩转 Kaggle 竞赛?

    整理 | Jane 出品 | AI科技大本营(ID:rgznai100) 今天,我们要给大家介绍的这个工具特别推荐给以往只能仰望别人的,缺乏竞赛技能和经验的朋友,你不需要写一行代码就可以参与 Kagg ...

  10. 太赞了,使用应用魔方 AppCube,我没有写一行代码就开发出了一款投票微信小程序

    低代码开发近些年非常火热,所谓低代码开发就是无需写太多的代码甚至有些简单应用不用写代码就能构建出一款应用,低代码开发平台非常多,其中我比较熟悉的就是华为的应用魔方 AppCube,本文就带着大家用应用 ...

最新文章

  1. 最小费用最大流 ---- 2017icpc青岛现场赛 K Our Journey of Xian Ends (拆点控制原图点度 + 中间必经过的点设置成源点 + 起点设成汇点)
  2. 12款优秀的 JavaScript 日历和时间选择控件
  3. jsr 269 api_研究Java 9 Money and Currency API(JSR 354)
  4. dot2谜团png_一个类加载的谜团解决了
  5. 以python程序调用的系统_python 系统调用的实例详解
  6. java 获取视频信息_Java获取视频参数信息
  7. Python面向对象模型概述
  8. 谈谈MySQL的WriteSet并行复制
  9. 概率论与数理统计习题集及答案
  10. html点击下载图片
  11. 八.声明圆锥体类,实现Area和vloume接口计算表面积和体积,按体积大小进行比较...
  12. ItemCF的Python实现
  13. Android 智能语音相关知识-PCM设备
  14. 安吉县人力资源和社会保障局数据中心容灾备份项目
  15. 前长江基金董事长王含冰被开除党籍和公职 涉嫌职务犯罪
  16. 怎么用几何画板制作图形平移和旋转
  17. 把执行结果转成json对象报错_关于JSON转换成对象 报错LinkedHashMap不能直接转成对象...
  18. 做一个Java程序员,数学一定要好吗?
  19. 集成wangEditor富文本编辑器
  20. Vue路由的动态添加和缓存

热门文章

  1. Linux命令:ls -l(ll)结果解析
  2. C# web 分页控件
  3. doom3灯光编辑器和FX编辑器
  4. 微信小程序对商户而言到底有什么用?
  5. 机械键盘cherry常见轴科普 --By Cheng
  6. react 跳转外部链接
  7. 极智资讯 | 一文看尽今年的云栖大会 有哪些好玩的
  8. php验证qq,正则表达式验证qq号码是否输入正确
  9. debian安装vim提示Package vim is not available, but is referred to by another package的解决方案
  10. 学习Java第一天笔记