设为首页 加入收藏

TOP

1.Linux电源管理-休眠与唤醒(一)
2019-09-01 23:09:39 】 浏览:127
Tags:1.Linux 电源 管理 休眠 唤醒

1.休眠方式

 在内核中,休眠方式有很多种,可以通过下面命令查看

# cat /sys/power/state
          //来得到内核支持哪几种休眠方式. 

 

常用的休眠方式有freeze,standby, mem, disk

  • freeze:   冻结I/O设备,将它们置于低功耗状态,使处理器进入空闲状态,唤醒最快,耗电比其它standby, mem, disk方式高
  • standby:除了冻结I/O设备外,还会暂停系统,唤醒较快,耗电比其它 mem, disk方式高
  • mem:      将运行状态数据存到内存,并关闭外设,进入等待模式,唤醒较慢,耗电比disk方式高
  • disk:       将运行状态数据存到硬盘,然后关机,唤醒最慢

示例:

 # echo standby > /sys/power/state
                   // 命令系统进入standby休眠.

 

2.唤醒方式

当我们休眠时,如果想唤醒,则需要添加中断唤醒源,使得在休眠时,这些中断是设为开启的,当有中断来,则会退出唤醒,常见的中断源有按键,USB等.

 

3.以按键驱动为例(基于内核3.10.14)

在内核中,有个input按键子系统"gpio-keys"(位于driver/input/keyboard/gpio.keys.c),该平台驱动platform_driver已经在内核中写好了(后面会简单分析)

我们只需要在内核启动时,注册"gpio-keys"平台设备platform_device,即可实现一个按键驱动.

 

3.1首先使板卡支持input按键子系统(基于mips君正X1000的板卡)

查看Makefile,找到driver/input/keyboard/gpio.keys.c需要CONFIG_KEYBOARD_GPIO

方式1-修改对应板卡的defconfig文件,添加宏:

CONFIG_INPUT=y                             //支持input子系统(加载driver/input文件)
CONFIG_INPUT_KEYBOARD=y              //支持input->keyboards(加载driver/input/keyboard文件)
CONFIG_KEYBOARD_GPIO=y                   //支持input->keyboards->gpio按键(加载gpio.keys.c)

方式2-进入make menuconfig

-> Device Drivers                                                                                                   
   -> Input device support        
     ->  [*]Keyboards   
             [*]  GPIO Buttons

 

3.2修改好后,接下来写my_button.c文件,来注册platform_device

#include <linux/platform_device.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>

struct gpio_keys_button __attribute__((weak)) board_buttons[] = {
         {
                  .gpio                 = GPIO_PB(31),    //按键引脚
                  .code   = KEY_POWER,                    //用来定义按键产生事件时,要上传什么按键值
                  .desc                 = "power key",    //描述信息,不填的话会默认设置为"gpio-keys"
                  .wakeup           =1,                   //设置为唤醒源
                  . debounce_interval =10,                //设置按键防抖动时间,也可以不设置
                  .type                = EV_KEY,
                  .active_low     = 1,                   //低电平有效
         },
};

static struct gpio_keys_platform_data  board_button_data = {
         .buttons  = board_buttons,
         .nbuttons         = ARRAY_SIZE(board_buttons),
};

struct platform_device  my_button_device = {
         .name               = "gpio-keys",
         .id             = -1,
         .num_resources      = 0,          
         .dev          = {
                .platform_data      = &board_button_data,
         }
};

static int __init button_base_init(void)
{
         platform_device_register(&my_button_device);
         return 0;
}

arch_initcall(button_base_init);     

上面的arch_initcall()表示:

会将button_base_init函数放在内核链接脚本.initcall3.init段中,然后在内核启动时,会去读链接脚本,然后找到button_base_init()函数,并执行它.

通常,在内核中,platform 设备的初始化(注册)用arch_initcall()调用

而驱动的注册则用module_init()调用,因为module_init()在arch_initcall()之后才调用

因为在init.h中定义:

#define pure_initcall(fn)                  __define_initcall(fn, 0)

#define core_initcall(fn)                  __define_initcall(fn, 1)

#define core_initcall_sync(fn)                __define_initcall(fn, 1s)

#define postcore_initcall(fn)          __define_initcall(fn, 2)

#define postcore_initcall_sync(fn)        __define_initcall(fn, 2s)

#define arch_initcall(fn)         __define_initcall(fn, 3)            // arch_initcall()优先级为3,比module_init()先执行

#define arch_initcall_sync(fn)                 __define_initcall(fn, 3s)

#define subsys_initcall(fn)              __define_initcall(fn, 4)

#define subsys_initcall_sync(fn)    __define_initcall(fn, 4s)

#define fs_initcall(fn)                       __define_initcall(fn, 5)

#define fs_initcall_sync(fn)             __define_initcall(fn, 5s)

#define rootfs_initcall(fn)               __define_initcall(fn, rootfs)

#define d
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Linux分页机制之分页机制的实现详.. 下一篇Linux内存描述之概述--Linux内存..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目