0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

中断唤醒系统demo

麦辣鸡腿堡 来源:嵌入式Linux系统开发 作者:嵌入式Linux系统开 2023-07-30 16:06 次阅读

博主写的 demo

博主下面给的是简化版,并且自测OK,分享给大家,以后如果需要可以copy xxx.c

#include < linux/module.h >
#include < linux/i2c.h >
#include < linux/interrupt.h >
#include < linux/delay.h >
#include < linux/uaccess.h >
#include < linux/pm.h >
#include < linux/slab.h >
#include < linux/sysctl.h >
#include < linux/proc_fs.h >
#include < linux/delay.h >
#include < linux/platform_device.h >
#include < linux/input.h >
#include < linux/gpio_keys.h >
#include < linux/workqueue.h >
#include < linux/gpio.h >
#include < linux/of.h >
#include < linux/of_platform.h >
#include < linux/of_gpio.h >
#include < linux/of_irq.h >
#include < linux/spinlock.h >
#include < linux/cdev.h >

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 = < 1 >;
  #size-cells = < 1 >;
  compatible = "atkalpha-key";
  key-gpio = < &gpio1 18 GPIO_ACTIVE_LOW >; /* KEY0 */
  interrupt-parent = < &gpio1 >;
  interrupts = < 18 IRQ_TYPE_EDGE_BOTH >; /* 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()函数。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5046

    文章

    18837

    浏览量

    299067
  • Linux
    +关注

    关注

    87

    文章

    11131

    浏览量

    208011
  • 系统
    +关注

    关注

    1

    文章

    1004

    浏览量

    21234
收藏 人收藏

    评论

    相关推荐

    stm32u535Rb LPTIM无法中断唤醒怎么解决?

    求助 stm32u535RbLPTIM1无法中断唤醒(ll库非hal) 请问下有没有相关demo例程,这个问题已经困扰我几天了,多谢
    发表于 03-08 08:18

    操作FreeRTOS时,执行__WFI()导致系统滴答中断无法唤醒设备怎么解决?

    1、在操作FreeRTOS时,本想着是在空闲钩子中执行__WFI()以降低设备功耗,等系统滴答中断自动唤醒设备继续执行,运行中发现执行__WFI()之后设备无法唤醒,分析应该是__WF
    发表于 04-24 08:29

    如何使用can rx中断唤醒系统的休眠模式?

    你好,我使用CY8C5868 LTI-LP039。我想实现睡眠模式(LPM)。是否有可能使用CAN RX中断唤醒系统
    发表于 10-10 08:52

    GD32进入深度睡眠后通过外部中断唤醒发现系统时钟变慢的原因

    一、问题1、进入深度睡眠后,通过外部中断唤醒,发现系统时钟变慢。2、进入休眠模式,通过任何中断唤醒系统
    发表于 01-26 07:43

    使用TimeR在中断服务之前唤醒系统执行主程序

    应用程序:使用TimeR来唤醒系统,在中断服务之前,首先执行主程序。 BSP 版本: M051系列 BSP CMSIS v3.01.002 硬件: Nutiny-EVB-M051_V3.0 在正常
    发表于 08-23 06:57

    LPC900系列单片机完全掉电模式下的外部中断唤醒

    LPC900系列单片机完全掉电模式下的外部中断唤醒
    发表于 01-08 14:27 15次下载

    如何利用利用TimerA及中断实现RTC

    D13x Demo - 利用Timer_A及中断实现RTC,观察LED灯的闪烁频率 // 描述:利用Timer_A及中断实现RTC;通过 P1 异或 来取反 P1.5; // 系统
    发表于 11-26 14:59 1582次阅读
    如何利用利用TimerA及<b class='flag-5'>中断</b>实现RTC

    GD32低功耗:深度睡眠唤醒系统时钟变慢问题

    一、问题1、进入深度睡眠后,通过外部中断唤醒,发现系统时钟变慢。2、进入休眠模式,通过任何中断唤醒系统
    发表于 12-02 15:06 21次下载
    GD32低功耗:深度睡眠<b class='flag-5'>唤醒</b><b class='flag-5'>系统</b>时钟变慢问题

    STM32 HAL库初始化MPU6050低功耗 中断唤醒

    @[TOC]STM32初始化MPU6050低功耗 中断唤醒STM32初始化MPU6050低功耗 中断唤醒代码如下: 已亲自测试(2021.2.4) (以下代码 采样率是20Hz)低功耗
    发表于 12-06 13:36 20次下载
    STM32 HAL库初始化MPU6050低功耗 <b class='flag-5'>中断</b><b class='flag-5'>唤醒</b>

    HS26Fxx-C_Demo_Code-中断函数、中断子函数的定义与使用

    HS26Fxx-C_Demo_Code-中断函数、中断子函数的定义与使用功能:定时器TC0中断程序参考void __interrupt[0x08] Interrupt(void)//无
    发表于 12-27 19:25 9次下载
    HS26Fxx-C_<b class='flag-5'>Demo</b>_Code-<b class='flag-5'>中断</b>函数、<b class='flag-5'>中断</b>子函数的定义与使用

    STM32外部中断、串口唤醒低功耗

    外部中断或RTC唤醒待机模式-(standby):待机模式的功耗为2uA,TAMPER引脚不关断,通过WKUP引脚唤醒在项目中综合选择了停止模式,在该模式下使用两种唤醒方式:WKUP引
    发表于 12-31 19:05 29次下载
    STM32外部<b class='flag-5'>中断</b>、串口<b class='flag-5'>唤醒</b>低功耗

    STM32 低功耗睡眠模式(SLEEP)中断(INTERRUPT)唤醒实现及优化

    STM32 低功耗睡眠模式(SLEEP)中断(INTERRUPT)唤醒实现及优化1. 介绍STM32具有多种低功耗模式,当前以STM32L4系列的低功耗模式最为丰富,此处基于STM32L476
    发表于 12-31 19:09 38次下载
    STM32 低功耗睡眠模式(SLEEP)<b class='flag-5'>中断</b>(INTERRUPT)<b class='flag-5'>唤醒</b>实现及优化

    按键如何唤醒系统官方demo

    系统运行时如果某外设很少用需要让它运行时休眠、系统休眠时要保证哪些外设可以唤醒系统。 博主今天要讨论的,就是一个按键如何唤醒
    的头像 发表于 07-30 15:43 696次阅读
    按键如何<b class='flag-5'>唤醒</b><b class='flag-5'>系统</b>官方<b class='flag-5'>demo</b>

    什么是LInux 操作系统中断

    LInux 操作系统中断 什么是系统中断 这个没啥可说的,大家都知道; CPU 在执行任务途中接收到中断请求,需要保存现场后去处理
    的头像 发表于 11-10 11:29 500次阅读
    什么是LInux 操作<b class='flag-5'>系统</b><b class='flag-5'>中断</b>

    LInux 操作系统中断介绍

    LInux 操作系统中断 什么是系统中断 这个没啥可说的,大家都知道; CPU 在执行任务途中接收到中断请求,需要保存现场后去处理
    的头像 发表于 11-13 11:36 765次阅读
    LInux 操作<b class='flag-5'>系统</b><b class='flag-5'>中断</b>介绍