您的位置:首页 > 移动开发 > Android开发

android alarm driver &framework 关键流程

2016-07-01 10:53 731 查看
android alarm driver如下:

alarm-dev.c@\kernel\drivers\staging\android

static int __init alarm_dev_init(void)
{
int err;
int i;

err = misc_register(&alarm_device);
if (err)
return err;

alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
ALARM_REALTIME, devalarm_alarmhandler);
hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
CLOCK_REALTIME, HRTIMER_MODE_ABS);
alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
ALARM_BOOTTIME, devalarm_alarmhandler);
hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);

for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
alarms[i].type = i;
if (!is_wakeup(i))
alarms[i].u.hrt.function = devalarm_hrthandler;
}

wakeup_source_init(&alarm_wake_lock, "alarm");
return 0;
}


driver init主要做了三件事,

1. 注册android alarm 设备:alarm_device。

2. 向linux alarm子系统注册alarm处理函数devalarm_alarmhandler,如果是允许唤醒系统的alarm,还会注册devalarm_hrthandler。当系统linux alarm到期时, 会回调这两个handler处理。

3. 初始化alarm 的wakeup source。

再细看handler里的处理:

static void devalarm_triggered(struct devalarm *alarm)
{
unsigned long flags;
uint32_t alarm_type_mask = 1U << alarm->type;

alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type);
spin_lock_irqsave(&alarm_slock, flags);
if (alarm_enabled & alarm_type_mask) {
__pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */
alarm_enabled &= ~alarm_type_mask;
alarm_pending |= alarm_type_mask;
wake_up(&alarm_wait_queue);
}
spin_unlock_irqrestore(&alarm_slock, flags);
}


主要做了一个动作是唤醒alarm的等待队列alarm_wait_queue, 后面分析再看如何与这里对接 。

先看上层AlarmManagerService初始化的函数,

主要有两步, 一是call native init, 二是启动thread一直等alarm消息:

public AlarmManagerService(Context context) {
mContext = context;
mDescriptor = init();
....
if (mDescriptor != -1) {
mWaitThread.start();
} else {
Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler.");
}
}


其中AlarmManagerService是由System_server init时new出来:

initAndLoop()@SystemServer.java

Slog.i(TAG, "Alarm Manager");
alarm = new AlarmManagerService(context);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);


init对应初始化,完成alarm设备打开:

com_android_server_AlarmManagerService.cpp@ \frameworks\base\services\jni

static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj)
{
return open("/dev/alarm", O_RDWR);
}


mwaitThread start后,一直循环block等待alarm driver消息, :

public void run()
{
ArrayList<Alarm> triggerList = new ArrayList<Alarm>();

while (true)
{
int result = waitForAlarm(mDescriptor);


native实现 :

static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)
{
int result = 0;

do
{
result = ioctl(fd, ANDROID_ALARM_WAIT);
} while (result < 0 && errno == EINTR);

if (result < 0)
{
ALOGE("Unable to wait on alarm: %s\n", strerror(errno));
return 0;
}

return result;
}


ioctl对应driver逻辑:

static long alarm_do_ioctl(struct file *file, unsigned int cmd,
struct timespec *ts)
{
...
case ANDROID_ALARM_WAIT:
rv = alarm_wait();
break;


alarm_wait实现 如下, 此处会一直wait等待wake up alarm_wait_queue状态 , 就接上了最开始提到的向linux alarm子系统注册的alarm handler来wakeup的地方. 从而完成了具体alarm到期事件 向framework的通知 。

static int alarm_wait(void)
{
unsigned long flags;
int rv = 0;

spin_lock_irqsave(&alarm_slock, flags);
alarm_dbg(IO, "alarm wait\n");
if (!alarm_pending && wait_pending) {
__pm_relax(&alarm_wake_lock);
wait_pending = 0;
}
spin_unlock_irqrestore(&alarm_slock, flags);

rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
if (rv)
return rv;

spin_lock_irqsave(&alarm_slock, flags);
rv = alarm_pending;
wait_pending = 1;
alarm_pending = 0;
spin_unlock_irqrestore(&alarm_slock, flags);

return rv;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息