Android中的闹钟与RTC

来自个人维基
跳转至: 导航搜索

这里以MSM8916为例,大概介绍一下 Android中 RTC的实现模式。

我们知道,RTC的主要功能就是保证系统睡眠、甚至掉电的情况下,时钟的准确性,同时提供定时唤醒系统、甚至定时开机的功能。

先来看一下 android中的闹钟。

android的闹钟分为以下三种类型:RTC , RTC_WAKEUP 和 RTC_POWEROFF_WAKEUP,其他的实质都是这三者中的一种:

  • RTC
只在机器唤醒时计时,进入睡眠后就暂停
  • RTC_WAKEUP
具备唤醒机器特性,即闹钟时间到后,即使机器处于睡眠状态,也会把机器唤醒以执行任务
  • RTC_POWEROFF_WAKEUP
除了具备 RTC_WAKEUP的特性外,还具备自动开机功能,即闹钟时间超时后,如果机器处于关机状态,就会把机器自动开机来执行任务


App设置一个闹钟时:

alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+120000, chkPenIntent);

将调用 AlarmManagerService.set ==> AlarmManagerService.setImplLocked ==> AlarmManagerService.rescheduleKernelAlarmsLocked ==> AlarmManagerService.setLocked

  • 从 rescheduleKernelAlarmsLocked可以发现 AlarmManagerService并不是直接将 App设置的alarm传下去,而是在这里进行了预处理,只把最先触发的 alarm分类传到了 jni中

进入jni:

static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
{
    struct timespec ts;
    ts.tv_sec = seconds;
    ts.tv_nsec = nanoseconds;

	int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts);
	if (result < 0)
	{
        ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
    }
}

fd在 jni init中被初始化:

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

接下来,看一下 /dev/alarm这个驱动