中断唤醒系统demo

博主写的 demo
博主下面给的是简化版,并且自测ok,分享给大家,以后如果需要可以copy xxx.c
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int gpionum = 0;static int irqnum = 0;static irqreturn_t my_handler(int irq, void *dev_id){ printk(%srn,__function__); return irq_handled;}static int gpio_keys_probe(struct platform_device *pdev){ int ret = 0; struct device_node *node = null;; /* 设备节点*/ node = of_find_compatible_node(null,null,atkalpha-key); if (node == null){ printk(%s:atkalpha-key node not find!rn,__function__); return -einval; } /* 提取 gpio */ gpionum = of_get_named_gpio(node,key-gpio, 0); if (gpionum < 0) { printk(of_get_named_gpio can't get keyrn); } /* 初始化 key 所使用的 io,并且设置成中断模式 */ gpio_request(gpionum, key-gpio); gpio_direction_input(gpionum); irqnum = gpio_to_irq(gpionum); ret = request_irq(irqnum,my_handler, irqf_trigger_falling|irqf_trigger_rising, my-key, null); if(ret < 0){ printk(irq %d request failed!rn, irqnum); return -efault; } return 0;}static const struct of_device_id gpio_keys_of_match[] = { { .compatible = atkalpha-key, }, { },};module_device_table(of, gpio_keys_of_match);static int gpio_keys_remove(struct platform_device *pdev){ return 0;}static int gpio_keys_suspend(struct device *dev){ printk(%srn,__function__); enable_irq_wake(irqnum); return 0;}static int gpio_keys_resume(struct device *dev){ printk(%srn,__function__); disable_irq_wake(irqnum); return 0;}static simple_dev_pm_ops(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume);static struct platform_driver gpio_keys_device_driver = { .probe = gpio_keys_probe, .remove = gpio_keys_remove, .driver = { .name = my-key, .pm = &gpio_keys_pm_ops, .of_match_table = of_match_ptr(gpio_keys_of_match), }};static int __init gpio_keys_init(void){ return platform_driver_register(&gpio_keys_device_driver);}static void __exit gpio_keys_exit(void){ platform_driver_unregister(&gpio_keys_device_driver);}module_init(gpio_keys_init);module_exit(gpio_keys_exit);module_license(gpl);module_author(jason);module_description(keyboard driver for gpios);module_alias(platform:gpio-keys);xxx.dts
key { #address-cells = ; #size-cells = ; compatible = atkalpha-key; key-gpio = ; /* key0 */ interrupt-parent = ; interrupts = ; /* falling rising */ gpio-key,wakeup; status = okay;};最后再总结一下:中断唤醒系统和普通的驱动区别在于,多了两个函数:suspend 和 resume,在suspend 函数中,调用 enable_irq_wake,表示该中断号在系统休眠时也是 enable 状态,可以触发中断。在 resume 函数中,调用 disable_irq_wake ,恢复原始的中断触发路径。
然后使用 simple_dev_pm_ops 宏将 suspend 和 resume 函数注册到 gpio_keys_pm_ops 操作集,最终由 platform 注册到系统中。这样完成后,系统休眠过程中就会调用到设备注册的 suspend,系统唤醒过程中就会调用设备注册的 resume 函数。
note:该 demo 只用来唤醒系统,如果你的中断是在 i2c 等设备驱动中,唤醒系统后要立刻在中断处理函数中进行 i2c 通信,写法不太一样,但是框架相同。
另外,该驱动的中断处理函数中没做什么东西,因此唤醒后执行完中断处理函数后又会睡过去。如果你想要该中断唤醒系统后让系统一直处于唤醒状态,请在中断处理函数中使用 __pm_stay_awake() 和__pm_relax()函数。

基于STM32的TL431小电流输出电路
高低温湿热试验箱使用时的注意事项都有哪些
华为荣耀Magic发布,主打智慧生活!
移动5G开通网络伴随什么的到来
MAX9918, MAX9919, MAX9920 -20V
中断唤醒系统demo
上海集成电路综合性产业基地启动仪式举行
嵌入式系统常规电源设计
内存频率是什么_内存频率高有什么好处
自制CPU(一)单周期
人工智能数据点来创建并训练统计模型分析
英特尔称14nm Bay Trail比A7性能好功耗低
在疫情中大显身手的AI发展路在何方
东芝推出小型SO6封装的光电耦合器
胜负已分?Micro LED和OLED谁才是胜者?
远程抄表-LoRa水电气无线抄表解决方案
基于电动汽车快速充电技术研究及发展趋势
基于一种宽带数字接收机的信道化设计
交易所自动搬砖交易软件开发量化策略交易软件
神奇的创世之城VR虚拟土地