在此之前

中断里面 休眠唤醒,poll,异步… 等等都是为了读取该驱动的应用不占用那么多cpu资源
相对来说,对原来的驱动的中断函数没有太多调整,而是在驱动其他地方进行改进处理,给应用程序更好调用
并且 休眠唤醒有一个巨大的缺点,如果没有数据就会一直睡下去,app不执行其他事情

休眠流程

当app读取时候,有数据可以读取

app读取时候没有数据,进入休眠

  1. 先创建一个等待队列 waitqueue
  2. 同时app->read,调用了驱动的read, 在驱动的read里,把进程放进等待队列
  3. app读取的时候没有数据,先进入休眠
  4. 当有按键产生,会执行写好的 handle程序
  5. 在handle程序的最后,会唤醒等待队列告诉app :有数据了,可以继续运行了

代码构思

对于该驱动的几种写法

1. 设备树里只指定gpio

在驱动里面从设备树里提取出gpio , 驱动里使用 gpio_to_irq 转为中断
eg:
struct device_node *node = pdev->dev.of_node;//当probe成功后,把platform_device 变成设备树 node节点
gpio_keys_100ask[i].gpio = of_get_gpio_flags(node, i, &flag); //从node节点得到gpio编号
gpio_keys_100ask[i].irq = gpio_to_irq(gpio_keys_100ask[i].gpio); //把gpio变为中断引脚

request_irq(gpio_keys_100ask[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, “100ask_gpio_key”, &gpio_keys_100ask[i]); //注册中断

2. 设备树里有 interrupts

在设备树里有interrupts eg:

xxx_eint {compatible = "mediatek, xxx-eint";                                                                                                     interrupt-parent = <&eintc>;interrupts = <79 IRQ_TYPE_EDGE_FALLING>;//79是gpio号debounce = <79 1000>;status = "okay";
};

在驱动中我们
node = of_find_compatible_node(NULL, NULL, “mediatek, xxx-eint”); //获取中断对应的compatible的节点
of_property_read_u32_array(node, “debounce”, ints, ARRAY_SIZE(ints)); //获取节点中debounce的内容
debounce = ints[1]; //debounce = 1000
gpiopin = ints[0]; //gpio = 79
irqnum = irq_of_parse_and_map(node, 0); //获取节点中关于interrupt中gpio对应的中断号
//(此接口可以根据device tree中描述的中断信息来分析出此节点中interrupts中gpio对应的中断号),获取中断号后,就可调用request_irq来申请中断。

3. 前两种基础上增加环形缓冲区

有时候app还没人工加载,但是已经有中断发生了,后面运行的app只能获取最近一次的数据
这时候我们用一个环形缓冲区,有中断的时候先保存在驱动里,
后面人为加载的app可以一次性把之前的数据都取出来

在之前的基础上面加

static int r=0,w=0; //一个读位置,一个写位置
#define NEXT_POS(x) ((x+1)% BUF_LEN) //让当前位置+1static int is_key_buf_empty(void)  //判断当前是否有新数据,在app读驱动时调用 wait_event_interruptible 使用
{if(r == w)return 0;elsereturn 1;
}static void put_key(int key) // 存入数据
{g_key[w] = key;w = NEXT_POS(w);
}static int get_key(void) //取出数据
{int key =0;key = g_key[r];r = NEXT_POS(r);return key;
}

完整代码

设备树

/** Copyright (C) 2016 Freescale Semiconductor, Inc.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.*//dts-v1/;#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"/ {model = "Freescale i.MX6 ULL 14x14 EVK Board";compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";chosen {stdout-path = &uart1;};memory {reg = <0x80000000 0x20000000>;};reserved-memory {#address-cells = <1>;#size-cells = <1>;ranges;linux,cma {compatible = "shared-dma-pool";reusable;size = <0x14000000>;linux,cma-default;};};backlight {compatible = "pwm-backlight";pwms = <&pwm1 0 1000>;brightness-levels = <0 1 2 3 4 5 6 8 10>;default-brightness-level = <8>;status = "okay";};pxp_v4l2 {compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";status = "okay";};regulators {compatible = "simple-bus";#address-cells = <1>;#size-cells = <0>;reg_can_3v3: regulator@0 {compatible = "regulator-fixed";reg = <0>;regulator-name = "can-3v3";regulator-min-microvolt = <3300000>;regulator-max-microvolt = <3300000>;};reg_usb_ltemodule: regulator@1 {compatible = "regulator-fixed";regulator-name = "ltemodule-pwr";regulator-min-microvolt = <3800000>;regulator-max-microvolt = <3800000>;gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;enable-active-high;regulator-boot-on;};reg_gpio_wifi: regulator@2 {compatible = "regulator-fixed";regulator-name = "wifi-pwr";regulator-min-microvolt = <3300000>;regulator-max-microvolt = <3300000>;gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;regulator-boot-on;};};leds {compatible = "gpio-leds";pinctrl-names = "default";pinctrl-0 = <&pinctrl_leds>;status = "disabled";led0: cpu {label = "cpu";gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;default-state = "on";linux,default-trigger = "heartbeat";};};gpio_keys_100ask {status = "okay";compatible = "100ask,gpio_key";gpios = <&gpio5 1 GPIO_ACTIVE_HIGH&gpio4 14 GPIO_ACTIVE_LOW>;pinctrl-names = "default";pinctrl-0 = <&key1_100ask &key2_100ask>;interrupt-parent = <&gpio1>;interrupts = <74 IRQ_TYPE_EDGE_FALLING>;};gpio_keys_100ask {status = "disabled";compatible = "100ask,gpio_key";gpios = <&gpio5 1 GPIO_ACTIVE_HIGH&gpio4 14 GPIO_ACTIVE_LOW>;pinctrl-names = "default";pinctrl-0 = <&key1_100ask &key2_100ask>;};gpio-keys {compatible = "gpio-keys";pinctrl-names = "default";status = "disabled";user1 {label = "User1 Button";gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;gpio-key,wakeup;linux,code = <KEY_1>;};user2 {label = "User2 Button";gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;gpio-key,wakeup;linux,code = <KEY_2>;};};sound {compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";model = "wm8960-audio";cpu-dai = <&sai2>;audio-codec = <&codec>;asrc-controller = <&asrc>;codec-master;gpr = <&gpr 4 0x100000 0x100000>;hp-det = <3 0>;/*hp-det-gpios = <&gpio5 4 0>;mic-det-gpios = <&gpio5 4 0>;*/audio-routing ="Headphone Jack", "HP_L","Headphone Jack", "HP_R","Ext Spk", "SPK_LP","Ext Spk", "SPK_LN","Ext Spk", "SPK_RP","Ext Spk", "SPK_RN","LINPUT2", "Mic Jack","LINPUT3", "Mic Jack","RINPUT1", "Main MIC","RINPUT2", "Main MIC",  "Mic Jack", "MICB","Main MIC", "MICB","CPU-Playback", "ASRC-Playback","Playback", "CPU-Playback","ASRC-Capture", "CPU-Capture","CPU-Capture", "Capture";status = "okay";};spi4 {compatible = "spi-gpio";pinctrl-names = "default";pinctrl-0 = <&pinctrl_spi4>;pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;status = "okay";gpio-sck = <&gpio5 11 0>;gpio-mosi = <&gpio5 10 0>;cs-gpios = <&gpio5 7 0>;num-chipselects = <1>;#address-cells = <1>;#size-cells = <0>;gpio_spi: gpio_spi@0 {compatible = "fairchild,74hc595";gpio-controller;#gpio-cells = <2>;reg = <0>;registers-number = <1>;registers-default = /bits/ 8 <0x57>;spi-max-frequency = <10000>;};};sii902x_reset: sii902x-reset {compatible = "gpio-reset";reset-gpios = <&gpio_spi 1 GPIO_ACTIVE_LOW>;reset-delay-us = <100000>;#reset-cells = <0>;status = "okay";};};&gpmi{status = "disabled";
};
&cpu0 {arm-supply = <&reg_arm>;soc-supply = <&reg_soc>;
};&clks {assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;assigned-clock-rates = <786432000>;
};&fec1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_enet1>;phy-mode = "rmii";phy-handle = <&ethphy0>;phy-reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;phy-reset-duration = <26>;status = "okay";
};&fec2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_enet2>;phy-mode = "rmii";phy-handle = <&ethphy1>;phy-reset-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>;phy-reset-duration = <26>;status = "okay";mdio {#address-cells = <1>;#size-cells = <0>;ethphy0: ethernet-phy@0 {compatible = "ethernet-phy-ieee802.3-c22";smsc,disable-energy-detect;reg = <0>;};ethphy1: ethernet-phy@1 {compatible = "ethernet-phy-ieee802.3-c22";smsc,disable-energy-detect;reg = <1>;};};
};&flexcan1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_flexcan1>;xceiver-supply = <&reg_can_3v3>;status = "okay";
};
&gpc {fsl,cpu_pupscr_sw2iso = <0x1>;fsl,cpu_pupscr_sw = <0x0>;fsl,cpu_pdnscr_iso2sw = <0x1>;fsl,cpu_pdnscr_iso = <0x1>;fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
};&i2c1 {clock-frequency = <100000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_i2c1>;status = "okay";
};&i2c2 {clock_frequency = <100000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_i2c2>;status = "okay";codec: wm8960@1a {compatible = "wlf,wm8960";reg = <0x1a>;clocks = <&clks IMX6UL_CLK_SAI2>;clock-names = "mclk";wlf,shared-lrclk;};sii902x: sii902x@39 {compatible = "SiI,sii902x";pinctrl-names = "default";reset-names="sii902x";pinctrl-0 = <&pinctrl_sii902x>;resets = <&sii902x_reset>;interrupt-parent = <&gpio1>;interrupts = <18 IRQ_TYPE_EDGE_FALLING>;mode_str ="1280x720M@60";bits-per-pixel = <16>;reg = <0x39>;status = "okay";    };gt9xx@5d {compatible = "goodix,gt9xx";reg = <0x5d>;status = "okay";interrupt-parent = <&gpio1>;interrupts = <5 IRQ_TYPE_EDGE_FALLING>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_tsc_reset &pinctrl_touchscreen_int>;/*pinctrl-1 = <&pinctrl_tsc_irq>;*//*pinctrl-names = "default", "int-output-low", "int-output-high", "int-input";pinctrl-0 = <&ts_int_default>;pinctrl-1 = <&ts_int_output_low>;pinctrl-2 = <&ts_int_output_high>;pinctrl-3 = <&ts_int_input>;*/reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;irq-gpios = <&gpio1 5 IRQ_TYPE_EDGE_FALLING>;irq-flags = <2>;                /*1:rising 2: falling*/touchscreen-max-id = <1>;touchscreen-size-x = <800>;touchscreen-size-y = <480>;touchscreen-max-w = <1024>;touchscreen-max-p = <1024>;/*touchscreen-key-map = <172>, <158>;*/ /*KEY_HOMEPAGE, KEY_BACK*/goodix,type-a-report = <0>;goodix,driver-send-cfg = <0>;goodix,create-wr-node = <1>;goodix,wakeup-with-reset = <0>;goodix,resume-in-workqueue = <0>;goodix,int-sync = <0>;goodix,swap-x2y = <0>;goodix,esd-protect = <0>;goodix,pen-suppress-finger = <0>;goodix,auto-update = <0>;goodix,auto-update-cfg = <0>;goodix,power-off-sleep = <0>;/*7*/goodix,cfg-group0 = [6b 00 04 58 02 05 0d 00 01 0f 28 0f 50 32 03 05 00 00 00 00 00 00 00 00 00 00 00 8a 2a 0c 45 47 0c 08 00 00 00 40 03 2c 00 01 00 00 00 03 64 32 00 00 00 28 64 94 d5 02 07 00 00 04 95 2c 00 8b 34 00 82 3f 00 7d 4c 00 7a 5b 00 7a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 16 14 12 10 0e 0c 0a 08 06 04 02 ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 18 1c 1d 1e 1f 20 21 22 24 13 12 10 0f 0a 08 06 04 02 00 ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 79 01];/*4.3*/goodix,cfg-group1 = [97 E0 01 10 01 05 0D 00 01 0000 05 5A 46 53 11 00 00 11 1114 14 14 22 0A 04 00 00 00 0000 00 53 00 14 00 00 84 00 003C 00 00 64 1E 28 87 27 08 3234 05 0D 20 33 60 11 02 24 0000 64 80 80 14 02 00 00 54 8968 85 6D 82 72 80 76 7D 7B 7B00 00 00 00 00 00 00 F0 50 3CFF FF 07 00 00 00 02 14 14 0304 00 21 64 0A 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0032 20 50 3C 3C 00 00 00 00 000D 06 0C 05 0B 04 0A 03 FF FFFF FF FF FF 00 01 02 03 04 0506 07 08 09 0A 0B 0C 0D FF FFFF FF FF FF FF FF FF FF FF FF00 00 00 00 00 00 00 00 00 0000 00 00 00 3C 00 05 1E 00 022A 1E 19 14 02 00 03 0A 05 0000 00 00 00 00 00 01 FF FF 8622 03 00 00 33 00 0F 00 00 0050 3C 50 00 00 00 00 2A 01];/*5*/goodix,cfg-group2 = [00 20 03 E0 01 05 3C 00 01 0828 0C 50 32 03 05 00 00 00 0000 00 00 17 19 1E 14 8B 2B 0D33 35 0C 08 00 00 00 9A 03 1100 01 00 00 00 00 00 32 00 0000 20 58 94 C5 02 00 00 00 04B0 23 00 93 2B 00 7B 35 00 6941 00 5B 4F 00 5B 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 02 04 06 08 0A 0C 0E 1012 14 16 18 1A FF 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 02 04 06 08 0A 0C 0F10 12 13 16 18 1C 1D 1E 1F 2021 22 24 26 FF FF FF FF 00 0000 FF FF FF FF FF FF FF FF FFFF FF FF FF 48 01];};};&iomuxc {pinctrl-names = "default";pinctrl-0 = <&pinctrl_hog_1>;imx6ul-evk {key2_100ask: key2_100ask {                /*!< Function assigned for the core: Cortex-A7[ca7] */fsl,pins = <MX6UL_PAD_NAND_CE1_B__GPIO4_IO14           0x000010B0>;};pinctrl_hog_1: hoggrp-1 {fsl,pins = <MX6UL_PAD_UART1_RTS_B__GPIO1_IO19   0x17059 /* SD1 CD */MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x17059 /* USB OTG1 ID */// MX6UL_PAD_CSI_DATA07__GPIO4_IO28           0x000010B0MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05        0x000110A0>;};pinctrl_sii902x: hdmigrp {fsl,pins = <MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x59>;};pinctrl_touchscreen_int: lcdif_tsc_int {fsl,pins = <MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x000010B0>;};pinctrl_enet1: enet1grp {fsl,pins = <>;};pinctrl_enet2: enet2grp {fsl,pins = <MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0MX6UL_PAD_GPIO1_IO07__ENET2_MDC     0x1b0b0MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN  0x1b0b0MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER  0x1b0b0MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN  0x1b0b0MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN  0x1b0b0MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER  0x1b0b0MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN  0x1b0b0MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031>;};pinctrl_flexcan1: flexcan1grp{fsl,pins = <MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX         0x000010B0MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX         0x000010B0>;};pinctrl_i2c1: i2c1grp {fsl,pins = <MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0>;};pinctrl_i2c2: i2c2grp {fsl,pins = <MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0>;};pinctrl_ecspi3: ecspi3 {              fsl,pins = <MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI         0x000010B0MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO         0x000010B0MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK       0x000010B0//MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0        0x000010B0MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20        0x000010B0MX6UL_PAD_GPIO1_IO01__GPIO1_IO01           0x000010B0>;};pinctrl_ecspi1: ecspi1 {fsl,pins = <MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK         0x000010B0MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI         0x000010B0MX6UL_PAD_CSI_DATA07__ECSPI1_MISO         0x000010B0MX6UL_PAD_CSI_DATA05__GPIO4_IO26          0x000010B0MX6UL_PAD_CSI_DATA03__GPIO4_IO24          0x000010B0>;};pinctrl_uart3: uart3grp {fsl,pins = <MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1>;};pinctrl_uart1: uart1grp {fsl,pins = <MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1>;};pinctrl_uart6: uart6grp {fsl,pins = <MX6UL_PAD_CSI_MCLK__UART6_DCE_TX      0x1b0b1MX6UL_PAD_CSI_PIXCLK__UART6_DCE_RX    0x1b0b1>;};pinctrl_sai2: sai2grp {fsl,pins = <MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x17088MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x11088MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA    0x11088MX6UL_PAD_JTAG_TMS__SAI2_MCLK       0x17088>;};pinctrl_tsc: tscgrp {fsl,pins = <MX6UL_PAD_GPIO1_IO01__GPIO1_IO01    0xb0MX6UL_PAD_GPIO1_IO02__GPIO1_IO02    0xb0MX6UL_PAD_GPIO1_IO03__GPIO1_IO03    0xb0MX6UL_PAD_GPIO1_IO04__GPIO1_IO04    0xb0>;};pinctrl_usdhc1: usdhc1grp {fsl,pins = <MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x17059MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x10071MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059>;};pinctrl_usdhc1_100mhz: usdhc1grp100mhz {fsl,pins = <MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170b9MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100b9MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9>;};pinctrl_usdhc1_200mhz: usdhc1grp200mhz {fsl,pins = <MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170f9MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f9MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9>;};pinctrl_usdhc2: usdhc2grp {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x10069MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059>;};pinctrl_usdhc2_8bit: usdhc2grp_8bit {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x10069MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059>;};pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x100b9MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x170b9MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9>;};pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {fsl,pins = <MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x100f9MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x170f9MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9>;};pinctrl_lcdif_dat: lcdifdatgrp {fsl,pins = <MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x79MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x79MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x79MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x79MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x79MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x79MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x79MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x79MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x79MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x79MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x79MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x79MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x79MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x79MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x79MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x79MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x79MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x79MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x79MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x79MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x79MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x79MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x79MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x79>;};pinctrl_lcdif_dat_16bits: lcdifdatgrp_16bits {fsl,pins = <MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x79MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x79MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x79MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x79MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x79MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x79MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x79MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x79MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x79MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x79MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x79MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x79MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x79MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x79MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x79MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x79>;};pinctrl_lcdif_ctrl: lcdifctrlgrp {fsl,pins = <MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x79MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79>;};pinctrl_pwm1: pwm1grp {fsl,pins = <MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0>;};pinctrl_lcdif_reset: lcdifresetgrp {fsl,pins = <MX6UL_PAD_LCD_RESET__GPIO3_IO04     0x1b0b0>;};pinctrl_adc1: adc1grp {fsl,pins = <MX6UL_PAD_GPIO1_IO03__GPIO1_IO03          0x000010B1MX6UL_PAD_GPIO1_IO04__GPIO1_IO04          0x000010B1>;};};
};&iomuxc_snvs {pinctrl-names = "default_snvs";pinctrl-0 = <&pinctrl_hog_2>;imx6ul-evk {key1_100ask: key1_100ask {        /*!< Function assigned for the core: Cortex-A7[ca7] */fsl,pins = <MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01        0x000110A0>;};pinctrl_hog_2: hoggrp-2 {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09     0x1b0b0 /* enet1 reset */MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06     0x1b0b0 /* enet2 reset */MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x000110A0 /*key 1*/>;};pinctrl_tsc_reset: tscresetgrp  {        /*!< Function assigned for the core: Cortex-A7[ca7] */fsl,pins = <MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02        0x000110A0>;};pinctrl_spi4: spi4grp {fsl,pins = <MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x70a1MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x80000000>;};pinctrl_leds: ledgrp {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03        0x000110A0>;};pinctrl_485_ctl: uart3_rs485 {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00     0x1b0b0>;};};
};&lcdif {pinctrl-names = "default";pinctrl-0 = <&pinctrl_lcdif_dat&pinctrl_lcdif_ctrl&pinctrl_lcdif_reset>; display = <&display0>;status = "okay";reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 100ask */display0: display {bits-per-pixel = <24>;bus-width = <24>;display-timings {native-mode = <&timing0>;timing0: timing0_1024x768 {clock-frequency = <50000000>;hactive = <1024>;vactive = <600>;hfront-porch = <160>;hback-porch = <140>;hsync-len = <20>;vback-porch = <20>;vfront-porch = <12>;vsync-len = <3>;hsync-active = <0>;vsync-active = <0>;de-active = <1>;pixelclk-active = <0>;};};};
};&pwm1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_pwm1>;status = "okay";
};&pxp {status = "okay";
};
&ecspi3 { pinctrl-names = "default";pinctrl-0 = <&pinctrl_ecspi3>;cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;status = "okay";spidev: icm20608@0{compatible = "invensense,icm20608";interrupt-parent = <&gpio1>;interrupts = <1 1>;spi-max-frequency = <8000000>; reg = <0>; };
};&sai2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_sai2>;assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,<&clks IMX6UL_CLK_SAI2>;assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;assigned-clock-rates = <0>, <12288000>;status = "okay";
};&tsc {pinctrl-names = "default";pinctrl-0 = <&pinctrl_tsc>;xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;measure-delay-time = <0xfffff>;pre-charge-time = <0xffff>;status = "okay";
};&uart1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_uart1>;status = "okay";
};
&uart3 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_uart3&pinctrl_485_ctl>;//pinctrl-0 = <&pinctrl_uart3>;//fsl,rs485-gpio-txen = <&gpio5 0 GPIO_ACTIVE_HIGH>;//rts-gpio = <&gpio5 0 GPIO_ACTIVE_HIGH>;rs485-rts-active-high;//rs485-rts-active-high;rs485-rx-during-tx;rs485-rts-delay = <100 100>;linux,rs485-enabled-at-boot-time;status = "okay";
};&uart6 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_uart6>;status = "okay";
};&usbotg1 {dr_mode = "otg";srp-disable;hnp-disable;adp-disable;status = "okay";
};&usbotg2 {dr_mode = "host";disable-over-current;status = "okay";
};&usbphy1 {tx-d-cal = <0x5>;
};&usbphy2 {tx-d-cal = <0x5>;
};&usdhc1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_usdhc1>;cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;keep-power-in-suspend;enable-sdio-wakeup;bus-width = <4>;status = "okay";
};&usdhc2 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_usdhc2_8bit>;bus-width = <8>;non-removable;status = "okay";
};&wdog1 {status = "okay";
};&adc1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_adc1>;num-channels = <5>;vref-supply = <&reg_can_3v3>;status = "okay";
};&ecspi1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_ecspi1>;fsl,spi-num-chipselects = <2>;cs-gpio = <&gpio4 26 GPIO_ACTIVE_LOW>, <&gpio4 24 GPIO_ACTIVE_LOW>;status = "okay";/*   spidev0: spi@0 {compatible = "rohm,dh2228fv";reg = <0>;spi-max-frequency = <5000000>;};spidev1: spi@1 {compatible = "rohm,dh2228fv";reg = <1>;spi-max-frequency = <5000000>;};*/};

1. 设备树里只指定gpio c驱动

#include <linux/module.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>struct gpio_key{int gpio;struct gpio_desc *gpiod;int flag;int irq;
} ;static struct gpio_key *gpio_keys_100ask;/* 主设备号                                                                 */
static int major = 0;
static struct class *gpio_key_class;static int g_key = 0;static DECLARE_WAIT_QUEUE_HEAD(gpio_key_wait);/* 实现对应的open/read/write等函数,填入file_operations结构体                   */
static ssize_t gpio_key_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{//printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);int err;wait_event_interruptible(gpio_key_wait, g_key);err = copy_to_user(buf, &g_key, 4);g_key = 0;return 4;
}/* 定义自己的file_operations结构体                                              */
static struct file_operations gpio_key_drv = {.owner    = THIS_MODULE,.read    = gpio_key_drv_read,
};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);g_key = (gpio_key->gpio << 8) | val;wake_up_interruptible(&gpio_key_wait);return IRQ_HANDLED;
}/* 1. 从platform_device获得GPIO* 2. gpio=>irq* 3. request_irq*/
static int gpio_key_probe(struct platform_device *pdev)
{int err;struct device_node *node = pdev->dev.of_node;int count;int i;enum of_gpio_flags flag;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);count = of_gpio_count(node);if (!count){printk("%s %s line %d, there isn't any gpio available\n", __FILE__, __FUNCTION__, __LINE__);return -1;}gpio_keys_100ask = kzalloc(sizeof(struct gpio_key) * count, GFP_KERNEL);for (i = 0; i < count; i++){gpio_keys_100ask[i].gpio = of_get_gpio_flags(node, i, &flag);if (gpio_keys_100ask[i].gpio < 0){printk("%s %s line %d, of_get_gpio_flags fail\n", __FILE__, __FUNCTION__, __LINE__);return -1;}gpio_keys_100ask[i].gpiod = gpio_to_desc(gpio_keys_100ask[i].gpio);gpio_keys_100ask[i].flag = flag & OF_GPIO_ACTIVE_LOW;gpio_keys_100ask[i].irq  = gpio_to_irq(gpio_keys_100ask[i].gpio);}for (i = 0; i < count; i++){err = request_irq(gpio_keys_100ask[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "100ask_gpio_key", &gpio_keys_100ask[i]);}/* 注册file_operations     */major = register_chrdev(0, "100ask_gpio_key", &gpio_key_drv);  /* /dev/100ask_gpio_key */gpio_key_class = class_create(THIS_MODULE, "100ask_gpio_key_class");if (IS_ERR(gpio_key_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "100ask_gpio_key");return PTR_ERR(gpio_key_class);}device_create(gpio_key_class, NULL, MKDEV(major, 0), NULL, "100ask_gpio_key"); /* /dev/100ask_gpio_key */return 0;}static int gpio_key_remove(struct platform_device *pdev)
{//int err;struct device_node *node = pdev->dev.of_node;int count;int i;device_destroy(gpio_key_class, MKDEV(major, 0));class_destroy(gpio_key_class);unregister_chrdev(major, "100ask_gpio_key");count = of_gpio_count(node);for (i = 0; i < count; i++){free_irq(gpio_keys_100ask[i].irq, &gpio_keys_100ask[i]);}kfree(gpio_keys_100ask);return 0;
}static const struct of_device_id ask100_keys[] = {{ .compatible = "100ask,gpio_key" },{ },
};/* 1. 定义platform_driver */
static struct platform_driver gpio_keys_driver = {.probe      = gpio_key_probe,.remove     = gpio_key_remove,.driver     = {.name   = "100ask_gpio_key",.of_match_table = ask100_keys,},
};/* 2. 在入口函数注册platform_driver */
static int __init gpio_key_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = platform_driver_register(&gpio_keys_driver); return err;
}/* 3. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数*     卸载platform_driver*/
static void __exit gpio_key_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&gpio_keys_driver);
}/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */module_init(gpio_key_init);
module_exit(gpio_key_exit);MODULE_LICENSE("GPL");

2. 设备树里只指定gpio 再增加环形缓冲区 c驱动

#include <linux/module.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>struct gpio_key{int gpio;struct gpio_desc *gpiod;int flag;int irq;
} ;static struct gpio_key *gpio_keys_100ask;/* 主设备号                                                                 */
static int major = 0;
static struct class *gpio_key_class;#define BUF_LEN 128
static int g_key[BUF_LEN];
static int r=0,w=0;
#define NEXT_POS(x) ((x+1)% BUF_LEN)static int is_key_buf_empty(void)
{if(r == w)return 0;elsereturn 1;
}static void put_key(int key)
{g_key[w] = key;w = NEXT_POS(w);
}static int get_key(void)
{int key =0;key = g_key[r];r = NEXT_POS(r);return key;
}static DECLARE_WAIT_QUEUE_HEAD(gpio_key_wait);/* 实现对应的open/read/write等函数,填入file_operations结构体                   */
static ssize_t gpio_key_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{//printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);int err;printk(KERN_EMERG"111111111\n");wait_event_interruptible(gpio_key_wait, is_key_buf_empty() );int return_val = get_key();printk(KERN_EMERG"the return val is %d\n",return_val);err = copy_to_user(buf, &return_val, 4);return 4;
}/* 定义自己的file_operations结构体                                              */
static struct file_operations gpio_key_drv = {.owner    = THIS_MODULE,.read    = gpio_key_drv_read,
};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(KERN_EMERG"222222222222222\n");printk("key %d %d\n", gpio_key->gpio, val);put_key((gpio_key->gpio << 8) | val);printk(KERN_EMERG"the val is %d\n",(gpio_key->gpio << 8) | val);printk(KERN_EMERG"now r is %d w is %d\n",r,w);wake_up_interruptible(&gpio_key_wait);return IRQ_HANDLED;
}/* 1. 从platform_device获得GPIO* 2. gpio=>irq* 3. request_irq*/
static int gpio_key_probe(struct platform_device *pdev)
{int err;struct device_node *node = pdev->dev.of_node;int count;int i;enum of_gpio_flags flag;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);count = of_gpio_count(node);if (!count){printk("%s %s line %d, there isn't any gpio available\n", __FILE__, __FUNCTION__, __LINE__);return -1;}gpio_keys_100ask = kzalloc(sizeof(struct gpio_key) * count, GFP_KERNEL);for (i = 0; i < count; i++){gpio_keys_100ask[i].gpio = of_get_gpio_flags(node, i, &flag);if (gpio_keys_100ask[i].gpio < 0){printk("%s %s line %d, of_get_gpio_flags fail\n", __FILE__, __FUNCTION__, __LINE__);return -1;}gpio_keys_100ask[i].gpiod = gpio_to_desc(gpio_keys_100ask[i].gpio);gpio_keys_100ask[i].flag = flag & OF_GPIO_ACTIVE_LOW;gpio_keys_100ask[i].irq  = gpio_to_irq(gpio_keys_100ask[i].gpio);}for (i = 0; i < count; i++){err = request_irq(gpio_keys_100ask[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "100ask_gpio_key", &gpio_keys_100ask[i]);}/* 注册file_operations     */major = register_chrdev(0, "100ask_gpio_key", &gpio_key_drv);  /* /dev/100ask_gpio_key */gpio_key_class = class_create(THIS_MODULE, "100ask_gpio_key_class");if (IS_ERR(gpio_key_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "100ask_gpio_key");return PTR_ERR(gpio_key_class);}device_create(gpio_key_class, NULL, MKDEV(major, 0), NULL, "100ask_gpio_key"); /* /dev/100ask_gpio_key */return 0;}static int gpio_key_remove(struct platform_device *pdev)
{//int err;struct device_node *node = pdev->dev.of_node;int count;int i;device_destroy(gpio_key_class, MKDEV(major, 0));class_destroy(gpio_key_class);unregister_chrdev(major, "100ask_gpio_key");count = of_gpio_count(node);for (i = 0; i < count; i++){free_irq(gpio_keys_100ask[i].irq, &gpio_keys_100ask[i]);}kfree(gpio_keys_100ask);return 0;
}static const struct of_device_id ask100_keys[] = {{ .compatible = "100ask,gpio_key" },{ },
};/* 1. 定义platform_driver */
static struct platform_driver gpio_keys_driver = {.probe      = gpio_key_probe,.remove     = gpio_key_remove,.driver     = {.name   = "100ask_gpio_key",.of_match_table = ask100_keys,},
};/* 2. 在入口函数注册platform_driver */
static int __init gpio_key_init(void)
{int err;printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);err = platform_driver_register(&gpio_keys_driver); return err;
}/* 3. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数*     卸载platform_driver*/
static void __exit gpio_key_exit(void)
{printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);platform_driver_unregister(&gpio_keys_driver);
}/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */module_init(gpio_key_init);
module_exit(gpio_key_exit);MODULE_LICENSE("GPL");

app 代码


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>/** ./button_test /dev/100ask_button0**/
int main(int argc, char **argv)
{int fd;int val;/* 1. 判断参数 */if (argc != 2) {printf("Usage: %s <dev>\n", argv[0]);return -1;}/* 2. 打开文件 */fd = open(argv[1], O_RDWR);if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}while (1){/* 3. 读文件 */read(fd, &val, 4);printf("get button : 0x%x\n", val);}close(fd);return 0;
}

中断深入-->休眠唤醒(通用)相关推荐

  1. S5PV210 按键驱动源码、应用程序解析(重点:中断、休眠唤醒、定时器)

    按键驱动是最简单的功能,一旦使用linux来做就需要做很多功课.anyway,逻辑层还是前年不变的.先贴上驱动层代码. /** linux/drivers/char/mini210_buttons.c ...

  2. android休眠唤醒驱动流程分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/11777501 标准linux休眠过程: l        power managemen ...

  3. 2440 休眠唤醒的实现过程(作者:wogoyixikexie@gliet)

    2440 休眠唤醒的实现过程(作者:wogoyixikexie@gliet) //----------------------------------------------------------- ...

  4. android 休眠唤醒驱动流程分析,Android4.0.4休眠唤醒机制分析(基于MSM8260)

    当手机满足一定的条件时,会进入休眠状态.从手机进入休眠到唤醒,主要分为三个阶段: early suspend suspend late resume early suspend执行在休眠前需要完成的一 ...

  5. 一文搞懂ECU休眠唤醒之利器-TJA1145

    前言 首先,小T请教大家几个小小问题,你清楚: 什么是TJA1145吗? 你知道休眠唤醒控制基本逻辑是怎么样的吗? TJA1145又是如何控制ECU进行休眠唤醒的呢? 使用TJA1145时有哪些注意事 ...

  6. S32K14x CAN休眠唤醒的实现方案

    S32K14x系列芯片的唤醒源 通过查阅S32K14X芯片的用户手册可以获取S32K14x芯片的和唤醒源如下图所示: 由上表可知S32K14x系列芯片的CAN模块在普通模式下不支持休眠唤醒功能,在Pr ...

  7. 计划任务唤醒计算机,亲测利用windows 10任务计划实现计算机定时开关机(休眠唤醒)...

    利用任务计划实现计算机定时开关机 休眠唤醒 计算机如果具有定时开关机功能 是一件很吸引人的事情 但是一般的电脑要实现开 关机功能 需要有硬件的支持 所幸的是 在没有硬件支持的情况下 我们可以利用 wi ...

  8. 亲测用win10任务计划实现定时开关机—休眠唤醒

    在没有硬件支持的情况下,利用windows系统自带的任务计划程序和休眠功能,实现计算的定时开关机.解决休眠重启问题.下面以windows 10为例进行介绍. 工具/原料 电脑 Windows 10或以 ...

  9. 单片机反复进入休眠唤醒导致死机问题-辉芒微FMD 62F80X

    单片机反复进入休眠唤醒导致死机问题-辉芒微FMD 62F80X 辉芒微FMD 62F80X芯片出现了按键反复开机关机操作,反复进入休眠退出,会有死机现象,死机后有时会几秒几十后自动唤醒, 有时候发现唤 ...

最新文章

  1. 合法的python变量名import_python 环境变量和import模块导入方法(详解)
  2. 今天开始写技术博客啦
  3. 中如何计算工龄_在Substrate中如何计算交易权重
  4. python改变turtle画笔方向的函数_哪个选项不能改变turtle画笔的运行方向?
  5. 反射 数据类型_C#扫盲篇(一):反射机制情真意切的说
  6. ajax 回调数据 刷新table_Ajax gt;gt;gt; 001
  7. 2021年皓丽新品- 86KD1 86寸纳米智慧黑板(电容屏)-产品说明
  8. 字体转换,woff,ttf,otf,eot,svg
  9. Django下载安装及创建项目
  10. 金三银四,冰河为你整理了这份20万字134页的面试圣经!!
  11. 主控域NTP时间同步(PTP时钟同步服务器)配置方法
  12. Automating Android with Ant
  13. 视频直播的购物平台,网站,app
  14. 小白建设一个网站需要什么资料?完整网站建设流程今天告诉你!
  15. android ota功能,支持 OTA 更新  |  Android 开源项目  |  Android Open Source Project
  16. micro python 语音识别_语音识别
  17. 在 Visual Studio Code 中添加自定义的代码片段
  18. H264/AVC Hypothetical Reference Decoder(HRD)
  19. P6软件设置OBS组织分解结构
  20. CAD梦想画图中“合并命令”

热门文章

  1. RK3588 rtc-hym8563设备开发
  2. HDU 1593题解
  3. 全球及中国高速铁路行业发展状况与十四五运营潜力预测报告2022版
  4. HDU—— 1290 献给杭电五十周年校庆的礼物
  5. 休假管理系统——类图文档
  6. 孢子社群:今日推荐人工智能微信群:中国高端工业智造生态圈
  7. 一个简单的判断三角形形状的C程序
  8. 文件下载输出--零拷贝
  9. [python]:幂集
  10. 178页7万字智慧乡村大数据平台建设项目解决方案2022