动手写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 ................