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
#include
#include
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 device_initcall(fn) __define_initcall(fn, 6) //module_init()优先级为6
#define device_initcall_sync(fn) __define_initcall(fn, 6s)
#define late_initcall(fn) __define_initcall(fn, 7)
#define late_initcall_sync(fn)