BB-black开发板[Linux arm-v8]

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

2020-11-14  本文已影响0人  applecai

一,前言

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    ................
上一篇下一篇

猜你喜欢

热点阅读