美文网首页BB-black开发板[Linux arm-v8]
动手写i2c总线设备驱动--Apple的学习笔记

动手写i2c总线设备驱动--Apple的学习笔记

作者: applecai | 来源:发表于2020-11-14 14:43 被阅读0次

    一,前言

    i2c子系统及eeprom驱动--Apple的学习笔记中其实eeprom内核中已经有了i2c总线驱动,并且也有了i2c总线设备eeprom的驱动,以及i2c虚拟文件驱动,配置加载at24.ko即可实现atmel的eeprom读写。但是我本次的目的是学习写驱动,那么就要假设内核中不存在,自己写,过程中遇到坑才会进步呀,所以呢,就像之前自己写的applepaper基于平台总线的字符设备驱动一样,我再自定义一个基于i2c总线的字符设备驱动AppleEEP。主要是添加框架,功能比较简单就是从0地址可以读取或写入1个字节数据到eeprom。源码工程11已上传我的gitee共享

    二,遇到的问题

    1. ./i2c2 r及./i2c2 w 1读写值不正确。
    调试步骤如下,最终解决问题。
    a,先检查设备添加都正确。设备树添加applecai,AppleEEP,地址0x51。

    /* start add by apple */
    &i2c2 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins>;
    
        status = "okay";
        clock-frequency = <100000>;
    
        apple_eeprom0: apple_eeprom0@51 {
            /*compatible = "atmel,24c02";*/
            compatible ="applecai,AppleEEP";
            reg = <0x51>;
            #address-cells = <1>;
            #size-cells = <1>;
            apple_eeprom0_data: apple_eeprom0_data@0 {
                reg = <0 0x100>;
            };
        };
    };
    /* end add by apple */
    

    驱动及设备添加正确

    # cd /sys/bus/i2c/drivers/
    # ls
    AppleEEP  lp872x    lp87565   palmas    tps65023  tps65218  twl
    dummy     lp873x    menelaus  pcf857x   tps65217  tps65910  twl6040
    # cd AppleEEP/
    # ls
    2-0051  bind    module  uevent  unbind
    # cd 2-0051/
    # ls -al
    total 0
    drwxr-xr-x    3 root     root             0 Jan  1 00:02 .
    drwxr-xr-x    5 root     root             0 Jan  1 00:02 ..
    lrwxrwxrwx    1 root     root             0 Jan  1 00:02 driver -> ../../../../../../../../../bus/i2c/drivers/AppleEEP
    -r--r--r--    1 root     root          4096 Jan  1 00:02 modalias
    -r--r--r--    1 root     root          4096 Jan  1 00:02 name
    lrwxrwxrwx    1 root     root             0 Jan  1 00:02 of_node -> ../../../../../../../../../firmware/devicetree/base/ocp/interconnect@48000000/segment@100000/target-module@9c000/i2c@0/apple_eeprom0@51
    drwxr-xr-x    2 root     root             0 Jan  1 00:02 power
    lrwxrwxrwx    1 root     root             0 Jan  1 00:02 subsystem -> ../../../../../../../../../bus/i2c
    -rw-r--r--    1 root     root          4096 Jan  1 00:02 uevent
    

    b,检查是否调用到了i2c-omap中的transfer函数
    验证正确,已经调用了omap_i2c_xfer_irq

    # mount -t debugfs nodev /sys/kernel/debug
    # cd /sys/kernel/debug/tracing
    # echo 0 > tracing_on
    # echo omap_i2c_xfer_irq > set_ftrace_filter
    # echo function > current_tracer
    # echo func_stack_trace > trace_options
    # echo 1 > tracing_on
    # cd /usr/study/
    # [  182.802641] random: crng init done
    ./i2c2 r
    [  188.039454] addr=81
    [  188.039831] i2c rd failed=-121 reg=000000 len=1
    readdata return:0
    rddata:0x31
    # cd /sys/kernel/debug/tracing
    # echo 0 > tracing_on
    # cat trace | head -30
    # tracer: function
    #
    # entries-in-buffer/entries-written: 2/2   #P:1
    #
    #                              _-----=> irqs-off
    #                             / _----=> need-resched
    #                            | / _---=> hardirq/softirq
    #                            || / _--=> preempt-depth
    #                            ||| /     delay
    #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
    #              | |       |   ||||       |         |
                i2c2-118   [000] ....   188.039470: omap_i2c_xfer_irq <-__i2c_transfer
                i2c2-118   [000] ....   188.039488: <stack trace>
     => __i2c_transfer
     => i2c_transfer
     => AppleEEP_read
     => __vfs_read
     => vfs_read
     => ksys_read
     => sys_read
     => ret_fast_syscall
     => 0xbe97dcd0
    

    c,在i2c-omap.c中添加#define DEBUG来查看更多信息
    i2c-tools是可以正确读写eeprom的,于是通过对比打印信息发现我的flag不正确,期望为0,但是我都是0x8c8b,于是查看代码,原来驱动中我忘记为msg.flag赋值了。

    # ./i2c2 w 1
    [   46.742430] omap_i2c 4819c000.i2c: addr: 0x0051, len: 2, flags: 0x8c8b, stop: 1
    [   46.750363] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0008)
    [   46.755545] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    writeaddress return: 0
    wrdata:0x1
    # ./i2c2 r
    [   53.454942] addr=81
    [   53.455064] omap_i2c 4819c000.i2c: addr: 0x0051, len: 1, flags: 0x8c8b, stop: 0
    [   53.464983] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0008)
    [   53.470072] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    [   53.476292] omap_i2c 4819c000.i2c: addr: 0x0051, len: 1, flags: 0x1, stop: 1
    [   53.483763] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0008)
    [   53.488852] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    readdata return:0
    rddata:0xff
    # i2cget -f -y 2 0x51 0x00
    [  100.837911] omap_i2c 4819c000.i2c: addr: 0x0051, len: 1, flags: 0x0, stop: 0
    [  100.845336] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0010)
    [  100.850575] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    [  100.856807] omap_i2c 4819c000.i2c: addr: 0x0051, len: 1, flags: 0x1, stop: 1
    [  100.864520] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0008)
    [  100.869618] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    0xe4
    # i2cset -f -y 2 0x51 0x00 0xab
    [  125.338737] omap_i2c 4819c000.i2c: addr: 0x0051, len: 2, flags: 0x0, stop: 1
    [  125.346138] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0010)
    [  125.351469] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    

    d,添加msg.flags=0后,一切正常。

    三,测试通过

    AppleEEP驱动已验收,打包资料咯~ 这是最简单的基于i2c总线设备的框架,没有添加同步及阻塞,将来要使用可继续扩展功能添加。

    Welcome to Buildroot
    buildroot login: root
    # cd /usr/study/
    # insmod appleEEP.ko 
    [   16.144140] appleEEP: loading out-of-tree module taints kernel.
    # ./i2c2 w 12
    [   22.622783] omap_i2c 4819c000.i2c: addr: 0x0051, len: 2, flags: 0x0, stop: 1
    [   22.629996] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0010)
    [   22.635385] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    writeaddress return: 0
    wrdata:0xc
    # ./i2c2 r
    [   25.799290] omap_i2c 4819c000.i2c: addr: 0x0051, len: 1, flags: 0x0, stop: 0
    [   25.806686] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0010)
    [   25.811916] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    [   25.817991] omap_i2c 4819c000.i2c: addr: 0x0051, len: 1, flags: 0x1, stop: 1
    [   25.825457] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0008)
    [   25.830544] omap_i2c 4819c000.i2c: IRQ (ISR = 0x0004)
    readdata return:0
    rddata:0xc
    

    在i2c-omap.c中删除#define DEBUG后,验证通过,存档咯~

    Welcome to Buildroot
    buildroot login: root
    # cd /usr/study/
    # insmod appleEEP.ko 
    [   16.024107] appleEEP: loading out-of-tree module taints kernel.
    # ./i2c2 w 15
    writeaddress return: 0
    wrdata:0xf
    # ./i2c2 r
    readdata return:0
    rddata:0xf
    # i2cdump -f -y 2 0x51
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
    00: 0f 12 ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ??..............
    10: 0c ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ?...............
    20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
    

    相关文章

      网友评论

        本文标题:动手写i2c总线设备驱动--Apple的学习笔记

        本文链接:https://www.haomeiwen.com/subject/jpqwbktx.html