linux下GPIO中断驱动US100传感器--Apple的学习笔记

一,前言

资源就的利用起来。linux下串口raw驱动(US100超声波)--Apple的学习笔记已经用US100玩了串口,US100还可以用GPIO和中断来玩。原理就是triq发送大于10us的高电平,然后echo脚就会回复高电平,高电平的维持时间,就代表了障碍物的距离。我之前用过gpio但是是老的API,所以本次的其中一个目标很清晰,就是用新的gpiod的API,那么头文件从 #include <linux/gpio.h>要改成 #include <linux/gpio/consumer.h>了。另外我对中断其实用的少,正好本次有机会用下,将来再详细了解。过程中觉得延时10us占用cpu而且不准,所以改成pwm来输出10us非常准。这个US100还比较有的玩,将来我还会再玩一次,重新设计驱动,并且将参数都设计到设备树中。工程已经上传我的gitee,见工程14。

二,设备树修改

依然使用上一篇博客的uart引脚,但是mode设置为7,设置为GPIO,然后设备树设置中断为both边缘触发。

ussensor_pins: pinmux_ussensor_pins {
    pinctrl-single,pins = <
            AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT_PULLUP, MUX_MODE7)  //Echo:gpio0.14
            AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_OUTPUT_PULLDOWN, MUX_MODE7)  //Triq :gpio0.15
        >;
    };

ussensor:ussensor0 {
    compatible = "applecai,AppleUS100";
    interrupt-parent = <&gpio0>;
    interrupts = <14 IRQ_TYPE_EDGE_BOTH>;       /* input pin:gpio0.14  raise and falling*/
    echo-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;    /* input pin */
    triq-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;    /* output pin */
    pinctrl-names = "default";
    pinctrl-0 = <&ussensor_pins>;

    status = "okay";
};

三,遇到的问题

  1. insmod产生bt。
    对于不复杂的驱动,我倾向于使用misc。而misc的.name没有添加。导致bt。
  2. us2运行第二次后,产生bt
    原因request_irq后,free_irq的devid参数传的不正确。后来直接用devm_request_irq就不用free了。另外irqflag参数我之前理解为填写边缘触发等,但是看了源码后才知道理解错误,参考其它driver,我这里改成了shared中断。
[   38.242019] us100 device id is 10485820
[   40.143138] genirq: Flags mismatch irq 61. 00000003 (us100-echo-gpio) vs. 00000003 (us100-echo-gpio)
[   40.156380] ------------[ cut here ]------------
[   40.161045] WARNING: CPU: 0 PID: 119 at kernel/irq/manage.c:1737 __free_irq+0xc0/0x330
[   40.168996] Trying to free already-free IRQ 61
[   40.173457] Modules linked in: US100_drv(O) [last unloaded: US100_drv]
[   40.180028] CPU: 0 PID: 119 Comm: us2 Tainted: G           O      5.4.61 #39
[   40.187105] Hardware name: Generic AM33XX (Flattened Device Tree)
[   40.193224] Backtrace: 
[   40.195694] [<c010e59c>] (dump_backtrace) from [<c010e934>] (show_stack+0x20/0x24)
[   40.203300]  r7:00000000 r6:60070093 r5:00000000 r4:c0ebd85c
[   40.208991] [<c010e914>] (show_stack) from [<c0964ec8>] (dump_stack+0xe8/0x120)
[   40.216344] [<c0964de0>] (dump_stack) from [<c0140b84>] (__warn+0xd0/0x108)
[   40.223340]  r10:60070013 r9:c0b255b4 r8:c0e05148 r7:000006c9 r6:00000009 r5:c01a9328
[   40.231203]  r4:c0b2551c r3:00000000
[   40.234797] [<c0140ab4>] (__warn) from [<c0140f7c>] (warn_slowpath_fmt+0x9c/0xc0)
[   40.242315]  r7:00000009 r6:c01a9328 r5:000006c9 r4:c0b2551c
[   40.248002] [<c0140ee4>] (warn_slowpath_fmt) from [<c01a9328>] (__free_irq+0xc0/0x330)
[   40.255956]  r9:0000003d r8:dd03e0d0 r7:dd03e068 r6:00000000 r5:dd03e000 r4:00000000
[   40.263734] [<c01a9268>] (__free_irq) from [<c01a963c>] (free_irq+0x48/0xa8)
[   40.270816]  r10:bf0011c4 r9:c0e9c220 r8:dd25f5d0 r7:dd20e900 r6:00000000 r5:dd03e000
[   40.278678]  r4:00000000
[   40.281235] [<c01a95f4>] (free_irq) from [<bf0000f0>] (AppleUS100_open+0x60/0x94 [US100_drv])
[   40.289798]  r7:dd20e900 r6:c0e9c234 r5:fffffff0 r4:bf0022c0
[   40.295488] [<bf000090>] (AppleUS100_open [US100_drv]) from [<c06564c4>] (misc_open+0x124/0x17c)
[   40.304310]  r5:0000003c r4:bf002000
[   40.307911] [<c06563a0>] (misc_open) from [<c02f57b0>] (chrdev_open+0xe8/0x1bc)
[   40.315255]  r10:00000000 r9:00000000 r8:dd20e900 r7:c0e05148 r6:dd25f5d0 r5:c0a5c750
[   40.323117]  r4:de298880 r3:c06563a0
[   40.326719] [<c02f56c8>] (chrdev_open) from [<c02ebc90>] (do_dentry_open+0x134/0x414)
[   40.334586]  r10:dd20e900 r9:00000000 r8:c02f56c8 r7:dd20e908 r6:dd25f5d0 r5:00000000
[   40.342447]  r4:dd20e900
[   40.344997] [<c02ebb5c>] (do_dentry_open) from [<c02ed7dc>] (vfs_open+0x3c/0x40)
[   40.352428]  r9:00000000 r8:00000000 r7:00000002 r6:00000000 r5:00000000 r4:dd31fe90
[   40.360211] [<c02ed7a0>] (vfs_open) from [<c0301740>] (path_openat+0x2b4/0x13e0)
[   40.367642] [<c030148c>] (path_openat) from [<c0303b9c>] (do_filp_open+0x80/0xec)
[   40.375160]  r10:00000142 r9:dd31e000 r8:00000001 r7:c0e05148 r6:dd31ff50 r5:dd31fe90
[   40.383023]  r4:00000003
[   40.385571] [<c0303b1c>] (do_filp_open) from [<c02edaec>] (do_sys_open+0x168/0x218)
[   40.393263]  r8:fffff000 r7:de113000 r6:ffffff9c r5:c0e05148 r4:00000003
[   40.399997] [<c02ed984>] (do_sys_open) from [<c02edbe4>] (sys_openat+0x1c/0x20)
[   40.407341]  r10:00000142 r9:dd31e000 r8:c01011c4 r7:00000142 r6:00085460 r5:00010134
[   40.415202]  r4:00010c30
[   40.417752] [<c02edbc8>] (sys_openat) from [<c0101000>] (ret_fast_syscall+0x0/0x28)
[   40.425441] Exception stack(0xdd31ffa8 to 0xdd31fff0)
[   40.430518] ffa0:                   00010c30 00010134 ffffff9c 0005e160 00000000 00000000
[   40.438736] ffc0: 00010c30 00010134 00085460 00000142 00000000 00000000 00000000 be9c6d24
[   40.446950] ffe0: 000858b0 be9c6ce0 000104d0 00027a14
[   40.452022] ---[ end trace 16d04ba7b422cf72 ]---
/dev/AppleUS100: Device or resource busy
  1. gpio初始化引脚不正确
    devm_gpiod_get_optional的第3个参数可以在请求引脚的同时设置电平和方向。一开始不知道,写的是0,所以insmod后不正确。
  2. do_gettimeofday函数在内核中没有了。
    用get_ktime获取ns值。
    参考网址:https://blog.csdn.net/rikeyone/article/details/98498526
  3. 中断thread下半部进入不了.
    中断上半部return的参数不对。
  4. 时间采集不准。
    采集时间放入上半部后相对正确。
  5. 采集时间差偏小
    参见如下第七和第八章节的测试。暂时原因未知,猜测为ktime不准。事后网上搜索下了下有用hrtimer是高精度的。将来有机会再了解下原理适用下。

四,第一步驱动加载及probe测试成功

查看设备号

# cd /sys/class/misc/
# ls
AppleUS100       loop-control     vga_arbiter
cpu_dma_latency  ubi_ctrl
# cd AppleUS100/
# ls
dev        power      subsystem  uevent
# cat dev
10:60

查看驱动

# ls -al
total 0
drwxr-xr-x    3 root     root             0 Jan  1 00:03 .
drwxr-xr-x   21 root     root             0 Jan  1 00:03 ..
lrwxrwxrwx    1 root     root             0 Jan  1 00:03 driver -> ../../../bus/platform/drivers/appleUS100
-rw-r--r--    1 root     root          4096 Jan  1 00:03 driver_override
-r--r--r--    1 root     root          4096 Jan  1 00:03 modalias
lrwxrwxrwx    1 root     root             0 Jan  1 00:03 of_node -> ../../../firmware/devicetree/base/ussensor0
drwxr-xr-x    2 root     root             0 Jan  1 00:03 power
lrwxrwxrwx    1 root     root             0 Jan  1 00:03 subsystem -> ../../../bus/platform
-rw-r--r--    1 root     root          4096 Jan  1 00:03 uevent

驱动框架,irq识别正确,APP open和close正常

# insmod US100_drv.ko 
[  101.155869] irq num is 61
[  139.464344] us100 probe!
[  139.469573] appleUS100 ussensor0: GPIO lookup for consumer triq
[  139.475713] appleUS100 ussensor0: using device tree for GPIO lookup
[  139.482121] of_get_named_gpiod_flags: parsed 'triq-gpios' property of node '/ussensor0[0]' - status (0)
[  139.491590] gpio gpiochip0: Persistence not supported for GPIO 15
[  139.497749] no flags found for triq
[  139.501265] miscUS100_dev.cmdpin is 15
[  139.501273] appleUS100 ussensor0: GPIO lookup for consumer echo
[  139.511012] appleUS100 ussensor0: using device tree for GPIO lookup
[  139.517374] of_get_named_gpiod_flags: parsed 'echo-gpios' property of node '/ussensor0[0]' - status (0)
[  139.526854] gpio gpiochip0: Persistence not supported for GPIO 14
[  139.533002] no flags found for echo
[  139.536513] miscUS100_dev.echopin is 14
# ./us2
[  139.539789] us100 device id min is 60
ok
# ./us2
[  141.592831] irq num is 61
ok
^C
# ./us2
[  147.848742] irq num is 61
ok
# cat /proc/interrupts
           CPU0       
 16:       1626      INTC  68 Level     gp_timer
 18:          0      INTC   3 Level     arm-pmu
 19:          8      INTC  12 Level     49000000.edma_ccint
 21:          0      INTC  14 Level     49000000.edma_ccerrint
 28:          0      INTC  96 Level     44e07000.gpio
 29:        313      INTC  72 Level     44e09000.serial
 30:        146      INTC  70 Level     44e0b000.i2c
 42:          0      INTC  98 Level     4804c000.gpio
 43:         37      INTC  64 Level     mmc0
 45:          0      INTC  30 Level     4819c000.i2c
 46:          0      INTC  32 Level     481ac000.gpio
 47:          0      INTC  62 Level     481ae000.gpio
 48:         46      INTC  28 Level     mmc1
 52:       1273      INTC  41 Level     4a100000.ethernet
 53:        763      INTC  42 Level     4a100000.ethernet
 56:          0  44e07000.gpio   6 Edge      48060000.mmc cd
 57:          0      INTC   7 Level     tps65217-irq
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:          0  Rescheduling interrupts
IPI3:          0  Function call interrupts
IPI4:          0  CPU stop interrupts
IPI5:          0  IRQ work interrupts
IPI6:          0  completion interrupts
Err:          0
# rmmod US100_drv.ko 

五,GPIO引脚控制测试通过

在框架中的open添加了GPIOD及申请IRQ的代码,在read函数中添加控制triq引脚电平及延时10us。示波器测试通过,并且echo脚有正确的返回。

# insmod US100_drv1.ko
[  322.604133] irq num is 61
[  384.515868] us100 probe!
[  384.521094] appleUS100 ussensor0: GPIO lookup for consumer triq
[  384.527249] appleUS100 ussensor0: using device tree for GPIO lookup
[  384.533660] of_get_named_gpiod_flags: parsed 'triq-gpios' property of node '/ussensor0[0]' - status (0)
[  384.543162] gpio gpiochip0: Persistence not supported for GPIO 15
[  384.549298] miscUS100_dev.cmdpin is 15
[  384.549307] appleUS100 ussensor0: GPIO lookup for consumer echo
[  384.559046] appleUS100 ussensor0: using device tree for GPIO lookup
[  384.565426] of_get_named_gpiod_flags: parsed 'echo-gpios' property of node '/ussensor0[0]' - status (0)
[  384.574912] gpio gpiochip0: Persistence not supported for GPIO 14
[  384.581043] miscUS100_dev.echopin is 14
# ./us2
[  384.584160] us100 device id min is 60
ok
# ./us2
[  390.780167] irq num is 61
ok
image.png

六,将10us的高电平有io控制改为PWM控制通过

用pwm控制就非常准。


image.png

七,用示波器来验证时间差,时间差偏小。

# ./us2
ok
[  417.304899] last is 417302210883,now is 417302621549,dis:410666
[  417.307555] dis:69
distance is 69

410666ns,但是示波器显示为424us


image.png

八,用ftrace验证时间差

ftrace硬中断上半部会进入2次,时间差为58.201850-58.200688=1162us。ktime记录的时间为ns,一个为58198435298,另外一个为58199583631,差值为1148us。也说明ktime函数偏小。

# insmod US100_drv6.ko 
[   19.069904] US100_drv6: loading out-of-tree module taints kernel.
[   19.078024] us100 probe!
[   19.080617] appleUS100 ussensor0: GPIO lookup for consumer triq
[   19.086760] appleUS100 ussensor0: using device tree for GPIO lookup
[   19.093172] of_get_named_gpiod_flags: parsed 'triq-gpios' property of node '/ussensor0[0]' - status (0)
[   19.102676] gpio gpiochip0: Persistence not supported for GPIO 15
[   19.108812] miscUS100_dev.cmdpin is 15
[   19.108822] appleUS100 ussensor0: GPIO lookup for consumer echo
[   19.118563] appleUS100 ussensor0: using device tree for GPIO lookup
[   19.124945] of_get_named_gpiod_flags: parsed 'echo-gpios' property of node '/ussensor0[0]' - status (0)
[   19.134430] gpio gpiochip0: Persistence not supported for GPIO 14
[   19.140561] miscUS100_dev.echopin is 14
# mount -t debugfs nodev /sys/kernel/debug
# cd /sys/kernel/debug/tracing
# echo 0 > tracing_on
# echo us100_irq_handler > set_ftrace_filter
# echo function > current_tracer 
# echo 1 > tracing_on
# cd /usr/study/
# ./us2
ok
[   19.142810] us100 device id min is 60
[   58.201906] last is 58198435298,now is 58199583631,dis:1148333
distance is 195
# cd /sys/kernel/debug/tracing
# cat trace | head -20
# 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
#              | |       |   ||||       |         |
          <idle>-0     [000] d.h.    58.200688: us100_irq_handler <-__handle_irq_event_percpu
          <idle>-0     [000] d.h.    58.201850: us100_irq_handler <-__handle_irq_event_percpu

九,多进程验证

今天在昨天的基础上将自定义的设备结构体从全局变量,改成了通过指针传递,然后在open函数通过struct miscUS100 *dev = container_of(filp->private_data,struct miscUS100, miscdev);来获取,依然放入工程14,文件名为US100_drv8.c。并且添加了锁,当一个进程打开文件处理后,其它进程不能打开此文件。测试通过。

Welcome to Buildroot
buildroot login: root
# cd /usr/study/
# insmod US100_drv8.ko 
[   13.282705] US100_drv8: loading out-of-tree module taints kernel.
[   13.290724] appleUS100 ussensor0: GPIO lookup for consumer echo
[   13.296902] appleUS100 ussensor0: using device tree for GPIO lookup
[   13.303306] of_get_named_gpiod_flags: parsed 'echo-gpios' property of node '/ussensor0[0]' - status (0)
[   13.312806] gpio gpiochip0: Persistence not supported for GPIO 14
# ./us2
[   13.318939] miscUS100_dev.echopin is 14
[   14.755360] appleUS100 ussensor0: irq num is 61
[   14.772369] appleUS100 ussensor0: last is 14768965835,now is 14770115335,dis:1149500
distance is 195
# ./us2 &
# [   22.226804] appleUS100 ussensor0: irq num is 61
[   22.291166] appleUS100 ussensor0: last is 22288684127,now is 22288873502,dis:189375
distance is 32
./us2
[   23.939970] US100 is busy
/dev/AppleUS100: Device or resource busy
# ./us2
[   25.143762] US100 is busy
/dev/AppleUS100: Device or resource busy
# ./us2
[   27.298167] US100 is busy
/dev/AppleUS100: Device or resource busy
[1]+  Done                       ./us2
# ./us2
[   32.293119] appleUS100 ussensor0: irq num is 61
[   32.358104] appleUS100 ussensor0: last is 32355629628,now is 32355829503,dis:199875
distance is 33
^C
# ./us2
[   36.579675] appleUS100 ussensor0: irq num is 61
[   36.644860] appleUS100 ussensor0: last is 36642381796,now is 36642584587,dis:202791
distance is 34
^C
# ./us2
[   39.601888] appleUS100 ussensor0: irq num is 61
[   39.667097] appleUS100 ussensor0: last is 39664613254,now is 39664820879,dis:207625
distance is 35
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容