Linux I2C(五) I2C字符设备的注册和使用

本文介绍了i2c-tools的使用,包括i2cdetect、i2cset等工具的功能及用法。阐述了i2c-dev注册,涵盖注册代码流程、cdev_device_add函数等内容。还说明了在用户空间读写I2C设备的方法,如open、read/write、ioctl的实现及main函数相关参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,i2c-tools的使用

Android-i2ctools 下载:

https://github.com/skyxiaoyan1/android-i2ctool

编译会生成五个工具:i2cdetect、i2cset、i2cget、i2cdump、i2ctransfer,拷贝到开发板中就可以使用。

i2cdetect:用于扫描 i2c 总线上的设备,并显示地址

i2cset:设置i2c设备某个寄存器的值 

i2cget:读取i2c设备某个寄存器的值 

i2cdump:读取某个i2c设备所有寄存器的值 

i2ctransfer:一次性读写多个字节

Android toybox源码中也有一些i2c tools,但是缺少i2ctransfer工具:

external/toybox/toys/other/i2ctools.c

(1)i2cdetect

用i2cdetect检测有几组i2c总线在系统上,输入:./i2cdetect -l

Usage: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]

       i2cdetect -F I2CBUS

       i2cdetect -l

  I2CBUS is an integer or an I2C bus name

  If provided, FIRST and LAST limit the probing range.

  y:关闭交互式,不会显示警告信息

  a:扫描总线上所有设备

  q:使用SMBus的"quick write"命令进行检测,不建议使用

  r:使用SMBus的"receive byte"命令进行检测,不建议使用

  i2cbus:指定查询某个总线编号

  first、last:扫描的地址范围

lynkco:/ # i2cdetect -l
i2c-3   i2c             Geni-I2C                                I2C Adapter
i2c-1   i2c             Geni-I2C                                I2C Adapter
i2c-4   i2c             Geni-I2C                                I2C Adapter
i2c-2   i2c             Geni-I2C                                I2C Adapter

用i2cdetect检测挂载在i2c总线上器件,输入 ./i2cdetect -r -y 1(检测i2c-1上的挂载情况)

lynkco:/sys/devices/platform/soc/a94000.i2c/i2c-1/1-0052 # i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

两个设备,设备地址0x52和设备地址0x64。

(2)i2cdump

用i2cdump查看器件所有寄存器的值,以总线1上0x52 这个器件为例,输入 i2cdump -f -y 2 0x52

lynkco:/sys/devices/platform/soc/a94000.i2c/i2c-1/1-0052 # i2cdump -f -y 1 0x52
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 09 14 07 08 18 60 22 00 b8 20 20 0e 89 55 40 08    ?????`".?  ??U@?
10: 00 00 10 00 00 81 00 00 02 0d ea 0d d5 00 00 00    ..?..?..?????...
20: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    4...............
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: a0 07 d0 00 00 00 08 00 00 00 00 00 00 00 00 00    ???...?.........
70: 00 00 00 00 41 00 00 00 00 00 00 00 00 00 00 00    ....A...........
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX

(3)i2cget

用i2cget 看单个寄存器地址, 以总线1上0x52 0x01这个寄存器为例 i2cget -f -y 1 0x52 0x01

lynkco:/ # i2cget -f -y 1 0x52 0x01
0x14

Usage: i2cget [-f] [-y] [-a] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]

  I2CBUS is an integer or an I2C bus name

  ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)

  MODE is one of:

    b (read byte data, default)

    w (read word data)

    c (write byte/read byte)

    Append p for SMBus PEC

    

    f:强制访问

    y:关闭交互模式,不会提示警告信息

    i2cbus:总线编号

    chip-address:i2c设备地址

    data-address:i2c寄存器地址

    mode:指定读取的大小,b字节,w字,s是SMBus块,i是i2c块

(4)i2cset

i2cset:向i2c设备某个寄存器写入值

Usage: i2cset [-f] [-y] [-m MASK] [-r] [-a] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]

  I2CBUS is an integer or an I2C bus name

  ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)

  MODE is one of:

    c (byte, no value)

    b (byte data, default)

    w (word data)

    i (I2C block data)

    s (SMBus block data)

    Append p for SMBus PEC

    

    f:强制访问

    y:指令执行自动yes,否则会提示确认执行Continue? [Y/n] Y,不加参数y会有很多执行提示,可以帮助判断

    r:写入后立即回读寄存器的值,并将结果与写入的值进行比较

    i2cbus:总线编号

    chip-address:i2c设备地址

    data-address:i2c寄存器地址

    value 要写入的值

    mode:指定读取的大小,b字节,w字,s是SMBus块,i是i2c块

设置i2c-1上0x20器件的0x77寄存器值为0x3f

./i2cset -f -y 1 0x20 0x77 0x3f

2,i2c-dev注册

i2c-dev.c文件完全可以被看作是一个i2c设备驱动,不过,它实现的i2c_client是虚拟的,临时的,主要是为了便于从用户空间操作i2c外设。

i2c-dev.c针对每个i2c适配器生成一个主设备号为89的设备文件,实现了i2c_driver的成员函数以及文件操作接口,因此i2c-dev.c的主体是"i2c_driver成员函数 + 字符设备驱动"。

2.1 i2c-dev注册代码流程

static int __init i2c_dev_init(void)
{
    int res;

    printk(KERN_INFO "i2c /dev entries driver\n");

    res = register_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS, "i2c"); //注册设备编号,起始主设备号89, 起始次设备号为0
    if (res)
        goto out;

    i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); //创建i2c-dev的class,为在linux文件系统中创建字符设备做准备
    if (IS_ERR(i2c_dev_class)) {
        res = PTR_ERR(i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值