android系统中alarm驱动框架分析

来源:互联网 发布:网络水军 编辑:程序博客网 时间:2024/06/05 09:20

专题一alarm

第一课、

1、 功能:一般用作闹钟

2、 工作流程:

App->获取系统服务(alarm service->返回特定类型的对象(Alarm Manager->

启动闹钟->定时时间到后通过广播通知app(也可以通过activityservice通知)->广播接收器(broadcast receiver->进行处理

二、分析Alarm Manager

进入下面网站:

http://www.android-doc.com/  -》点击API文档-android.app-classes-Alarm Manager

-public methods

 

Schedule an alarm起到一个一次性的定时器

voidset(int type, long triggerAtMillis, PendingIntent operation)

Schedule a repeatingalarm启动一个重复性的定时器

Void setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

 

参数:

1type可以取值为:One of ELAPSED_REALTIME,ELAPSED_REALTIME_WAKEUP,RTC, orRTC_WAKEUP一般使用RTC_WAKEUP,表示即使android即使处于休眠状态,一旦定时器超时也会触发事件/

2triggerAtMillis为超时时间,单位是ms

3operation:当定时器超时后执行什么事件,一般为发烧广播/4intervalMillis:为重复闹钟俩次响铃的时间间隔

 

三、开始编写app

最后过滤打印信息:adb logcat -s alarm

 

第二课

整体框架:

1、进入AlarmManager.java (frameworks\base\core\java\android\app)开始分析

分析过程(从启动函数开始分析):

///////////////AlarmManager////////////////////////////////////////////////////

public void set()  390

-private void setImpl()

-mService.set();

/////////////////进入AlarmManagerService.java////////////////////////////////////////

-》此后会调用AlarmManagerService.java780set函数 

进入AlarmManagerService

-void setImpl()

-setImplLocked()

-rescheduleKernelAlarmsLocked();

-setLocked()

////////////开始进入jni///////////////////////////////////////////////路径如下

com_android_server_AlarmManagerService.cpp(frameworks\base\services\core\jni)

/////////////////////////////////////////////////////////////////////////////////////////////

 -set()   其函数定义:private native voidset();

-void android_server_AlarmManagerService_set()

-impl->set(type, &ts); //分析此函数,先分析impl对象

-class AlarmImpl{ }

-virtual int set(int type, struct timespec *ts) = 0;  //因为是虚函数,所以set AlarmImpl的继承类实现

-class AlarmImplAlarmDriver : public AlarmImpl{}

-int AlarmImplAlarmDriver::set(int type, struct timespec *ts)

-ioctl(fds[0], ANDROID_ALARM_SET(type), ts);此函数中的fds[0]指的是下面open函数获取的fd,在source insight中收索open函数即可找到

static jlonginit_alarm_driver()

{

    int fd = open("/dev/alarm",O_RDWR);

    if (fd < 0) {

        ALOGV("opening alarm driverfailed: %s", strerror(errno));

        return 0;

    }

    AlarmImpl *ret = newAlarmImplAlarmDriver(fd);

    return reinterpret_cast<jlong>(ret);

}

/////////////////开始进入alarm驱动层(alarm-dev.c//////////////////////////////////////

-static long alarm_ioctl()

-case ANDROID_ALARM_SET_RTC: //开始设置

-alarm_set_rtc(new_rtc_time); //进入分析

-rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);  //进入此函数

//////////////////进入rtc驱动///////////////////////////////////////////////////////////

rtc->ops->set_time(rtc->dev.parent,tm); //开始操作rtc驱动

2分析alarm启动

2.1分析private void setImplLocked函数

Alarm即闹钟

Batch:闹钟容器

一个系统种一定有多个batch,每个batch中可以有多个闹钟

 

3查询闹钟是否超时过程:

当系统中的硬件闹钟响起时,就会与batch中的alarm进行比较,如果有合适的,就会激活batch中的alarm,最终调用alalrm的操作函数

 

///////////////进入AlarmManagerService.java/////////////////////////

-private class AlarmThread extends Thread1673行)

-waitForAlarm(mNativeData); //会调用jni中的waitForAlarm函数,发生阻塞,直到有闹钟超时函数返回

///////////////////进入jniandroid_server_AlarmManagerService.cpp //////////////

-static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*,jobject, jlong nativeData)

-result = impl->waitForAlarm();

-int AlarmImplAlarmDriver::waitForAlarm()

-ioctl(fds[0], ANDROID_ALARM_WAIT); 调用alarm-dev.c驱动中的ioctl函数

////////////////进入内核驱动alarm_dev.c//////////////////////////////////////////

-static long alarm_ioctl(struct file *file, unsigned int cmd, unsignedlong arg)

-case ANDROID_ALARM_WAIT: 

-rv = alarm_pending;  //获取alarm_pending的值,这个值其实就是alarmmask

-return rv;

 

 

 

第二课:内核驱动分析

1alalrm_dev.c分析

-static int __init alarm_dev_init(void)  //入口函数

-misc_register(&alarm_device); //注册为混扎设备驱动

-static struct miscdevice alarm_device = {

-.fops = &alarm_fops,  //操作函数集

-static const struct file_operations alarm_fops = {

       .owner = THIS_MODULE,

       .unlocked_ioctl = alarm_ioctl,   //ioctl为给用户提供的接口函数

       .open = alarm_open,

       .release = alarm_release,

};

-alarm_ioctl,   //ioctl为给用户提供的接口函数

-case ANDROID_ALARM_SET_RTC: //开始设置一个新的闹钟

-alarm_set_rtc(new_rtc_time); //进入分析

-rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); //进入此函数 设置闹钟相应时间

-rtc->ops->set_time(rtc->dev.parent, tm); //开始操作rtc驱动,在rtc-s3c.cstruct rtc_class_ops s3c_rtcops中的set_time函数

/////////开始进入rtc-s3c.c static const struct rtc_class_opss3c_rtcops = {}///////////

-.set_time= s3c_rtc_settime,   //设置设置alalrm时间

 

 

2rtc-s3c.c分析

-static int __inits3c_rtc_init(void) //入口函数

-platform_driver_register(&s3c_rtc_driver); //注册平台设备驱动

-static struct platform_drivers3c_rtc_driver = {

       .probe          =s3c_rtc_probe, //主要分析probe函数

       .remove       =__devexit_p(s3c_rtc_remove),

       .suspend      =s3c_rtc_suspend,

       .resume       =s3c_rtc_resume,

       .id_table=s3c_rtc_driver_ids,

       .driver          ={

              .name   = "s3c-rtc",

              .owner  = THIS_MODULE,

       },

};

-s3c_rtc_probe, //主要分析probe函数

-s3c_rtc_enable(pdev, 1);rtc硬件初始化

-s3c_rtc_gettime(NULL, &rtc_tm);获取当前时间

-rtc = rtc_device_register("s3c",&pdev->dev, &s3c_rtcops, THIS_MODULE); 注册rtc设备,注意一下注册的操作函数集s3c_rtcops,

-static conststruct rtc_class_ops s3c_rtcops = {

       .read_time   = s3c_rtc_gettime,

       .set_time     =s3c_rtc_settime,  //设置时间

       .read_alarm = s3c_rtc_getalarm,

       .set_alarm   = s3c_rtc_setalarm,

       .alarm_irq_enable = s3c_rtc_setaie,

};

-.set_time= s3c_rtc_settime,   //设置设置alalrm时间

 

0 0