tp 双击唤醒 最终方案 实现流程

 折腾许久,终于调试出一个比较满意的版本,采用的许多方法跟上一篇不一样,在这里重新整理。

 注册和上报键值这里就不在累赘了,本篇博客主要要解决以下bug:
 1.系统进入睡眠状态后,如何通过tp唤醒系统。
 2.如何解决快速双击时唤醒系统,长按时不唤醒系统。

要唤醒进入睡眠状态的系统,首先要了解以下函数接口:
在了解函数接口前,讲一下suspend和resume,
Suspend:kernel会依次调用你注册驱动里的suspend函数,将各种外设都进入节电模式。最后CPU进入power down 模式。
Resume:当用RTC或者GPIO中的一个将cpu从power down 模式唤醒。依次也会调用各个驱动里的resume函数将外设唤醒,
进入正常工作状态。
这些函数核心功能体现在它为底层的设备驱动提供用于上报wakeup event的接口。

首先要定义一个可以在睡眠状态下唤醒cpu的gpio,用enable_irq_wake(irq);和disable_irq_wake(ts->irq);
disable_irq_wake(ts->irq);//禁止中断唤醒功能
enable_irq_wake(ts->irq);//使能中断唤醒功能
在进入suspend时,会将irq mask写入到cpu。也就是告诉cpu哪些irq可以将其从睡眠中唤醒。

device_init_wakeup(&client->dev, 1);
用来设置一个驱动可以被唤醒,函数中的can_wakeup为1时,表明一个设备可以被唤醒,    在设备初始化的时候调用。
//设置dev的can_wakeup标志,若是enable==1,同时调用device_wakeup_enable使能wakeup功能;
int device_init_wakeup(struct device *dev, bool enable)
{
...
    if (enable) {
        device_set_wakeup_capable(dev, true);//设置设备能不能被唤醒
        ret = device_wakeup_enable(dev);//设置设备使不使用唤醒
    } 
...
}
// 设备模型中的所有设备都有两个标志来控制唤醒事件(可使得设备或系统退出低功耗状态)
static inline void device_set_wakeup_capable(struct device *dev, bool capable)
{
    dev->power.can_wakeup = capable;
}
static inline int device_set_wakeup_enable(struct device *dev, bool enable)
{
    dev->power.should_wakeup = enable;
    return 0;
}
can_wakeup为1时表明一个设备可以被唤醒,设备驱动为了支持Linux中的电源管理,有责任调用device_init_wakeup()来初始化can_wakeup。
而should_wakeup则是在设备的电源状态发生变化时被device_may_wakeup()用来测试,测试它该不该变化。

pm_stay_awake(&ts->client->dev);
中断中,pm_stay_awake可以使的设备不立即进入休眠,这个响应是非常快的。
当设备有wakeup event正在处理时,需要调用该接口通知电源管理系统。
那处理完成后呢?driver要调用pm_relax通知电源管理系统。pm_relax释放这个“锁”,让系统可以重新休眠。
pm_relax和pm_stay_awake成对出现,用于在event处理结束后通知电源管理系统。

以下提供一个例子:
//想要具备唤醒系统的功能,就要从中断上下功夫,如下:
#include <xxx.h>
...
#include <linux/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值