gpio控制led灯闪烁 gpio按键控制灯亮
资料下载
由于无法通过浏览器直接访问,需要使用Git工具进行下载:git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git登录后复制
您可以观看百问网的驱动大全视频,以获取更多相关信息。
GPIO 驱动分析与使用参考资料:
Linux 5.x 内核 Documentation\devicetree\bindings\input\gpio-keys.txtdrivers\input\keyboard\gpio_keys.cLinux 4.x 内核 Documentation\devicetree\bindings\input\gpio-keys.txtdrivers\input\keyboard\gpio_keys.c
设备树示例:IMX6ULL:Linux-4.9.88/arch/arm/boot/dts/100ask _imx6ull-14x14.dtsSTM32MP157:Linux-5.4/arch/arm/boot/dts/stm32mp15xx-100ask.dtsiQEMU:linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull_qemu.dts驱动程序框架
设备树示例
2.1 设备树讲解属性:
必备:兼容 = "gpio-keys";任选:autorepeat:表示自动重复,点击按钮不静止,驱动会自动重复上报节点值对于每一个GPIO按钮,都是一个子节点,有这些属性:gpios:使用哪个GPIOinterrupts:对应的中断linux,code:对应的节点值注意:gpios和interrupts至少要保留一个,不能都避免debounce-interval:去除左边的间隔,单位:ms,默认是5ms
2.2 100ASK_IMX6ULLgpio-keys { Compatible = quot;gpio-keysquot;; pinctrl-names = quot;defaultquot;; user1 { label = quot;User1 Buttonquot;; gpios = ; gpio-key,唤醒; linux,code = lt;key_1gt;; }; user2 { label = quot;User2 Buttonquot;; gpios = ; GPIO键,唤醒;linux,代码= lt;key_2gt;; };};登录后复制
2.3 100ASK_STM32MP157joystick {compatible = quot;gpio-keysquot;;#size-cells =;button-0 {label = quot;usr_button0quot;;linux,code = lt;key_agt;;interrupt-parent =;interrupts =;};button-1 {label = quot;usr_button1quot;;linux,code = lt;key_entergt;;int
errupt-parent = ;中断= ; };};登录后复制
2.4 QEMUgpio-keys@0 { Compatible = quot;gpio-keysquot;; pinctrl-names = quot;defaultquot;; pinctrl-0 = ; status = quot;okayquot;; Key0 { label = quot;Key 0quot;; gpios = ; linux,code = lt;key_1gt;; };};gpio-keys@1 { Compatible = quot;gpio-keysquot;; pinctrl-names = quot;defaultquot;; pinctrl-0 = ; status = quot;okayquot;; Key0 { label = quot;Key 1quot;; gpios = ; linux,code = lt;key_2gt;; };};登录后复制gpio_keys.c驱动程序分析
3.1 套路
根据设备树获取硬件信息:哪个GPIO、针对什么按键分配/设置/注册input_dev结构体request_irq:在中断处理函数中确定按键值、上报按键值有两个IRQ函数gpio_keys_gpio_isr:设备树中的用gpios来描述占用的引脚gpio_keys_irq_isr:设备树中的用中断来描述占用的引脚
3.2 gpio_keys_gpio_isr分析
理想情况是:按下、转动动作,各产生一次中断,也只产生一次中断。但是对于机械开关,它的金属弹片会反复关机。GPIO电平会反复变化,最后才稳定。一般是几十毫秒才会稳定。如果不处理连接的话,用户只操作一次,会发生多次,驱动程序可能会报出多个数据。
怎么处理拐点?
在中断程序中,可以循环几十亳秒,找到浓度稳定后再上报使用计时器显然第一种方法太同步,违背“中断要加速处理”的原则,你的系统会很卡。
怎么使用计时器?看下图: /@6再次5432-3/
核心存在:在GPIO中并不记录暂停时间,而是修改计时器超时时间,10ms之后处理。如果10ms内又发生了GPIO,那么认为是差不多,接下来修改超时时间为10ms。只有10ms之内再无GPIO发生,那么重置的函数才会被调用。在函数中上报按钮值。
3.3 gpio_keys_irq_isr分析
有一个变量key_pressed,用于表示当前按键状态:初始值为false,表示按键没有被按下。
发生中断上报“按下的值”:input_event(input, EV_KEY, button-gt;code, 1); input_sync(input);如果不延迟(!bdata-gt;release_delay)立即上报“动作的值”:input_event(input, EV_KEY, button-gt;code, 0); input_sync(input);如果延迟(bdata-gt;release_delay)启动定时器,超过几十秒再上报“读取的值”所以,使用gpio_keys_irq_isr时,一次中断就会导致上报2个事件:单击、读取故障:无法准确判断一个按钮确实已经被读取了QEMU上机实验
IMX6ULL、STM32MP157的出厂系统都已经配置的GPIO按钮。可以执行以下命令确认设备节点:cat /proc/bus/input/devices登录后复制
然后执行hexdump /dev/input/event?(?表示某个数值),并且操作按键来观察输出信息。
也可以在QEMU上做实验:原理图如下:
4.1工具链
在Ubuntu中执行:export ARCH=armexport CROSS_COMPILE=arm-linux-gnueabihf-export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin登录后复制
4.2配置内核
QEMU的内核里已经配置了GPIO 按键的设备树,只需要编译出gpio_keys驱动程序即可。
配置内核:执行make menuconfig-gt;设备驱动程序-gt;输入设备支持-gt;通用输入层-gt;键盘lt;mgt;GPIO按钮登录后复制
4.3编译驱动book@100ask:~/100ask_imx6ull-qemu$ cd linux-4.9.88book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88成功$ make module登录后复制
的话,可以得到:drivers/input/keyboard/gpio_keys.ko登录后复制
复制到如下目录:$ cp drivers/input/keyboard/gpio_keys.ko ~/nfs_rootfs/登录后复制
4.4启动QEMU
在Ubuntu中执行:$ cd ubuntu-18.04_imx6ul_qemu_system$ ./qemu-imx6ull-gui.sh登录后复制
4.5挂载NFS、实验
在QEMU中执行:$ mount -t nfs -o nolock,vers=3 10.0.2.2:/home/book/nfs_rootfs /mnt$ insmod /mnt/gpio_keys.ko$ cat /proc/bus/input/devices // 确认设备节点$ hexdump /dev/input/event3登录后复制
在QEMU的GUI界面操作:
以上就是DRV_05_GPIO驱动分析及使用的内容详细,更多请关注乐哥常识网其他相关文章!