2024年6月6日发(作者:)
第十一章 Android内核驱动——Alarm
11.1 基本原理
Alarm 闹钟是 android 系统中在标准 RTC 驱动上开发的一个新的驱动,提供了一个定时器
用于把设备从睡眠状态唤醒,当然因为它是依赖 RTC 驱动的,所以它同时还可以为系统提
供一个掉电下还能运行的实时时钟。
当系统断电时,主板上的rtc芯片将继续维持系统的时间,这样保证再次开机后系统的时间
不会错误。当系统开始时,内核从 RTC 中读取时间来初始化系统时间,关机时便又将系统
时间写回到 rtc 中,关机阶段将有主板上另外的电池来供应 rtc 计时。Android 中的Alarm
在设备处于睡眠模式时仍保持活跃,它可以设置来唤醒设备。
上图为android系统中alarm和rtc驱动的框架。Alarm依赖于rtc驱动框架,但它不是一个 rtc
驱动,主要还是实现定时闹钟的功能。相关源代码在kernel/drivers/rtc/alarm.c和
drivers/rtc/alarm_dev.c。
其中alarm.c文件实现的是所有alarm设备的通用性操作,它创建了一个设备class,而
alarm_dev.c则创建具体的alarm设备,注册到该设备class中。alarm.c还实现了与interface.c
的接口,即建立了与具体rtc驱动和rtc芯片的联系。alarm_dev.c在alarm.c基础包装了一层,
主要是实现了标准的miscdevice接口,提供给应用层调用。
可以这样概括:alarm.c实现的是机制和框架,alarm_dev.c则是实现符合这个框架的设备驱
动,alarm_dev.c相当于在底层硬件rtc闹钟功能的基础上虚拟了多个软件闹钟。
11.2 关键数据结构
alarm
定义在 include/linux/android_alarm.h 中。
struct alarm {
struct rb_node node;
enum android_alarm_type type;
ktime_t softexpires; //最早的到期时间
ktime_t expires; //绝对到期时间
void (*function)(struct alarm *); //当到期时系统回调该函数
};
这个结构体代表alarm设备,所有的 alarm 设备按照它们过期时间的先后被组织成一
个红黑树,即红黑树的节点,alarm设备通过这个变量插入红黑树。
是类型,android中一共定义了如下 5 种类型,在现在的系统中每种类型只有一个设备。
enum android_alarm_type {
/* return code bit numbers or set alarm arg */
ANDROID_ALARM_RTC_WAKEUP,
ANDROID_ALARM_RTC,
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
ANDROID_ALARM_ELAPSED_REALTIME,
ANDROID_ALARM_SYSTEMTIME,
ANDROID_ALARM_TYPE_COUNT,
/* return code bit numbers */
/* ANDROID_ALARM_TIME_CHANGE = 16 */
};
alarm_queue
struct alarm_queue {
struct rb_root alarms; //红黑树的根
struct rb_node *first; //指向第一个 alarm device,即最早到时的
struct hrtimer timer; //内核定时器,android 利用它来确定 alarm 过期时间
ktime_t delta; //是一个计算 elasped realtime 的修正值
bool stopped;
ktime_t stopped_time;
};
这个结构体用于将前面的 struct alarm 表示的设备组织成红黑树。它是基于内核定时器
来实现 alarm 的到期闹铃的。
11.3 关键代码分析
alarm_dev.c
发布评论