可以在自己家做外卖的网站,做抛物线的网站,网站设计师简介,如何在工商网站做预先核名嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理③ 第十八章 Linux系统对中断的处理 ③18.5 编写使用中断的按键驱动程序 ③18.5.1 编程思路18.5.1.1 设备树相关18.5.1.2 驱动代码相关 18.5.2 先编写驱动程序18.5.2.1 从设备树获得 GPIO18.5.2.2 从 GPIO获得中断号18.5… 嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理③ 第十八章 Linux系统对中断的处理 ③18.5 编写使用中断的按键驱动程序 ③18.5.1 编程思路18.5.1.1 设备树相关18.5.1.2 驱动代码相关 18.5.2 先编写驱动程序18.5.2.1 从设备树获得 GPIO18.5.2.2 从 GPIO获得中断号18.5.2.3 申请中断18.5.2.4 中断函数 18.6 IMX6ULL设备树修改及上机实验18.6.1 查看原理图确定按键引脚18.6.2 修改设备树18.6.3 上机实验 第十八章 Linux系统对中断的处理 ③ 18.5 编写使用中断的按键驱动程序 ③
写在前面的话对于 GPIO按键我们并不需要去写驱动程序使用内核自带的驱动程序drivers/input/keyboard/gpio_keys.c就可以然后你需要做的只是修改设备树指定引脚及键值。 但是我还是要教你怎么从头写按键驱动特别是如何使用中断。因为中断是引入其他基础知识的前提后面要讲的这些内容都离不开中断休眠-唤醒、POLL机制、异步通知、定时器、中断的线程化处理。 这些基础知识是更复杂的驱动程序的基础要素以后的复杂驱动也就是对硬件操作的封装彼此不同但是用到的基础编程知识是一样的。
18.5.1 编程思路
18.5.1.1 设备树相关
查看原理图确定按键使用的引脚再在设备树中添加节点在节点里指定中断信息。 例子
gpio_keys_xxxxxx { compatible xxxxxx,gpio_key; gpios gpio5 1 GPIO_ACTIVE_HIGH gpio4 14 GPIO_ACTIVE_HIGH; pinctrl-names default; pinctrl-0 key1_pinctrl key2_pinctrl;
}; 18.5.1.2 驱动代码相关
首先要获得中断号参考上面《18.4.3 在代码中获得中断》 然后编写中断处理函数 最后 request_irq。
18.5.2 先编写驱动程序
参考内核源码 drivers/input/keyboard/gpio_keys.c 使用 GIT命令载后源码 gpio_key_drv.c位于这个目录下 01_all_series_quickstart\ 05_嵌入式 Linux驱动开发基础知识\source\ 06_gpio_irq\ 01_simple\
18.5.2.1 从设备树获得 GPIO
count of_gpio_count(node);
for (i 0; i count; i) gpio_keys_xxxxxx[i].gpio of_get_gpio_flags(node, i, flag); 18.5.2.2 从 GPIO获得中断号
gpio_keys_xxxxxx[i].irq gpio_to_irq(gpio_keys_xxxxxx[i].gpio); 18.5.2.3 申请中断
err request_irq(gpio_keys_xxxxxx[i].irq, gpio_key_isr, \
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, xxxxxx_gpio_key, gpio_keys_xxxxxx[i]); 18.5.2.4 中断函数
static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{ struct gpio_key *gpio_key dev_id; int val; val gpiod_get_value(gpio_key-gpiod); }
printk(key %d %d\n, gpio_key-gpio, val); return IRQ_HANDLED; 18.6 IMX6ULL设备树修改及上机实验
本实验的内核版本
https://e.coding.net/weidongshan/imx-linux4.9.88 commit 6020a20c1277c6b511e5673eecd8523e376031c8 18.6.1 查看原理图确定按键引脚 18.6.2 修改设备树
对于一个引脚要用作中断时 a. 要通过 PinCtrl把它设置为 GPIO功能 b. 表明自身是哪一个 GPIO模块里的哪一个引脚 运行 NXP提供的图形化设备树配置工具“i.MX Pins Tool v6”点击左侧选中 GPIO5_IO01、GPIO4_IO14如下图所示
按上图右侧去修改设备树 arch/arm/boot/dts/xxxxxx_imx6ull-14x14.dts修改结果放 GIT中。
使用 GIT命令载后源码“修改后 xxxxxx_imx6ull-14x14.dts” 位于这个目录下(使用之前要改名为 “xxxxxx_imx6ull-14x14.dts”并上传到内核的 arch/arm/boot/dts目录)
01_all_series_quickstart\
05_嵌入式 Linux驱动开发基础知识\source\
06_gpio_irq\ 01_simple\ device_tree\ 主要内容摘录如下 GPIO5_IO01的 pinctrl定义
iomuxc_snvs { pinctrl-names default_snvs; pinctrl-0 pinctrl_hog_2; imx6ul-evk { key1_xxxxxx: key1_xxxxxx{ /*! Function assigned for the core: Cortex-A7[ca7] */ fsl,pins MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x000110A0 ; };
GPIO4_IO14的 pinctrl定义
iomuxc { pinctrl-names default; pinctrl-0 pinctrl_hog_1; imx6ul-evk { key2_xxxxxx: key2_xxxxxx{ /*! Function assigned for the core: Cortex-A7[ca7] */ fsl,pins MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x000010B0 ; };
定义这 2个按键的节点 gpio_keys_xxxxxx { compatible xxxxxx,gpio_key; gpios gpio5 1 GPIO_ACTIVE_HIGH gpio4 14 GPIO_ACTIVE_LOW; pinctrl-names default; pinctrl-0 key1_xxxxxx key2_xxxxxx; }; 把原来的 GPIO按键节点禁止掉
gpio-keys { compatible gpio-keys; pinctrl-names default; status disabled; // 这句是新加的 18.6.3 上机实验
实验步骤如下
编译设备树把 xxxxxx_imx6ull-14x14.dtb放到板子的/boot目录重启开发板。编译驱动程序安装驱动程序操作按键。 大概命令列出如下
// 1. 在电脑上设置工具链
export ARCHarm
export CROSS_COMPILEarm-linux-gnueabihf-
export PATH$PATH:/home/book/xxxxxx_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
// 2. 进入内核目录后执行
make dtbs // 生成 arch/arm/boot/dts/xxxxxx_imx6ull-14x14.dtb请把它放到板子的/boot目录
// 3. 编译驱动: 先进入驱动程序目录执行 make即可把生成的 gpio_key_drv.ko放到开发板上
// 4. 重启开发板后在板子上执行
echo 7 4 1 7 /proc/sys/kernel/printk insmod gpio_key_drv.ko
// 5. 按下、松开按键可以看到输出信息 [ 48.396584] key 110 0
[ 48.569403] key 110 1
[ 49.321805] key 129 0
[ 49.498734] key 129 1 参考资料 中断处理不能嵌套
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?ide58aa3d2d0cc genirq: add threaded interrupt handler support https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id3aa551c9b4c40018f0e261a178e3d25478dc04a9 Linux RT(2)硬实时 Linux(RT-Preempt Patch)的中断线程化 https://www.veryarm.com/110619.html Linux中断管理 (1)Linux中断管理机制 https://www.cnblogs.com/arnoldlu/p/8659981.html
Breakpoint 1, gpio_keys_gpio_isr (irq200, dev_id0x863e6930) at drivers/input/keyboard/gpio_keys.c:393
393 {
(gdb) bt
#0 gpio_keys_gpio_isr (irq200, dev_id0x863e6930) at drivers/input/keyboard/gpio_keys.c:393
#1 0x80270528 in __handle_irq_event_percpu (desc0x8616e300, flags0x86517edc) at kernel/irq/handle.c:145
#2 0x802705cc in handle_irq_event_percpu (desc0x8616e300) at kernel/irq/handle.c:185
#3 0x80270640 in handle_irq_event (desc0x8616e300) at kernel/irq/handle.c:202
#4 0x802738e8 in handle_level_irq (desc0x8616e300) at kernel/irq/chip.c:518
#5 0x8026f7f8 in generic_handle_irq_desc (descoptimized out) at ./include/linux/irqdesc.h:150
#6 generic_handle_irq (irqoptimized out) at kernel/irq/irqdesc.c:590
#7 0x805005e0 in mxc_gpio_irq_handler (port0xc8, irq_stat2252237104) at drivers/gpio/gpio-mxc.c:274
#8 0x805006fc in mx3_gpio_irq_handler (descoptimized out) at drivers/gpio/gpio-mxc.c:291
#9 0x8026f7f8 in generic_handle_irq_desc (descoptimized out) at ./include/linux/irqdesc.h:150
#10 generic_handle_irq (irqoptimized out) at kernel/irq/irqdesc.c:590
#11 0x8026fd0c in __handle_domain_irq (domain0x86006000, hwirq32, lookuptrue, regs0x86517fb0) at kernel/irq/irqdesc.c:627
#12 0x80201484 in handle_domain_irq (regsoptimized out, hwirqoptimized out, domainoptimized out) at ./include/linux/irqdesc.h:168
#13 gic_handle_irq (regs0xc8) at drivers/irqchip/irq-gic.c:364
#14 0x8020b704 in __irq_usr () at arch/arm/kernel/entry-armv.S:464