Android alarm driver source code analysis (alarm. c)

Source: Internet
Author: User

 

Preface:

Android has added many drivers based on Linux kernel. The alarm driver is the simplest one. The entire file contains more than 500 lines. As the beginning of a series of articles driving code analysis, I tried to carefully analyze almost all of the function code of this driver, hoping to use this as a good start for reviewing the android driver source code.

Android adds an alarm driver, which is implemented in the kernel_root/driver/RTC/alarm. c file. Android wants to provide an incremental clock (monotonic), which should be based on hardware so that android applications can still run or wake up the device when the device enters the sleep state, to save power.

 

1. Overview

1.1 Implementation Mechanism

Android alarm runs in hard interrupt based on the hardware clock. However, he does not implement the hardware RTC driver. It is implemented based on the Linux high-precision clock hrtimer.

The Linux high-precision clock is implemented in the kernel_root/kernel/hrtimer. c file.

For the analysis of this Part (high precision clock hrtimer), see the following two blog posts:

Http://blog.csdn.net/walkingman321/article/details/6133171

Http://blog.csdn.net/walkingman321/article/details/6151172

 

1.2 Implementation Method

Alarm. C registers a platform device in Linux kernel (an RTC device is finally registered and saved in the variable static struct rtc_device * alarm_rtc_dev;). The device node is/dev/alarm.

The user space program opens the node through fopen and obtains the control handle, and then sends a request to the driver through ioctrl.

The following file directly uses this driver:

Android_root/system/CORE/toolbox/alarm. c

Android_root/frameworks/base/serices/JNI/com_android_server_alarmmanagerservice.cpp

Android_root/system/CORE/toolbox/date. c

Android_root/frameworks/base/cmds/runtime/main_runtime.cpp

Android_root/frameworks/base/libs/utils/systemclock. cpp

Android_root/system/CORE/toolbox/uptime. c

 

1.3 DEMO code using the alarm driver

If you need to directly operate this driver, you can refer to the usage method in the above file.

The following example is taken from systemclock. cpp:

# If have_android_ OS
FD = open ("/dev/alarm", o_rdwr );
If (FD <0 ){
Logw ("unable to open alarm DRIVER: % s \ n", strerror (errno ));
Return-1;
}
TS. TV _sec = TV. TV _sec;
TS. TV _nsec = TV. TV _usec * 1000;
Res = IOCTL (FD, android_alarm_set_rtc, & TS );
If (RES <0 ){
Logw ("unable to set RTC to % ld: % s \ n", TV. TV _sec, strerror (errno ));
Ret =-1;
}
Close (FD );
# Else
If (settimeofday (& TV, null )! = 0 ){
Logw ("unable to set clock to % d. % d: % s \ n ",
(INT) TV. TV _sec, (INT) TV. TV _usec, strerror (errno ));
Ret =-1;
}
# Endif

 

2. driver code analysis

2.1 list of main functions

Alarm_start_hrtimer tool function. Other alarm-driven functions use this function to create an hrtimer timer for alarm of the corresponding type (android_alarm_type.

The ioctl function of the alarm_ioctl alarm driver. The upper-Layer Code sends an operation request to the driver through this interface.

Alarm_open

Alarm_release

Alarm_timer_triggered

Alarm_triggered_func

Alarm_suspend

Alarm_resume

Rtc_alarm_add_device

Rtc_alarm_remove_device

The post-initialization function of the alarm_late_init Driver runs after alarm_init (see the remarks in this section ).

Alarm_init driver initialization Function

Exit function driven by alarm_exit

 

Note:For more information about the Linux driver startup sequence (alarm_init and alarm_late_init), see the following blog:

Http://blog.csdn.net/cstk502/article/details/6579231

 

2.2 alarm_start_hrtimer Function

The code and comments are as follows:

Static void alarm_start_hrtimer (Enum android_alarm_type alarm_type)
{
Struct timespec hr_alarm_time;
If (! (Alarm_enabled & (1u <alarm_type) // determine the enabled type based on the alarm_enabled mask.
Return;
Hr_alarm_time = alarm_time [alarm_type]; // save timespec of this type to a local variable
If (alarm_type = android_alarm_elapsed_realtime_wakeup |
Alarm_type = android_alarm_elapsed_realtime)
Set_normalized_timespec (& hr_alarm_time, // set the time format
Hr_alarm_time. TV _sec + elapsed_rtc_delta. TV _sec,
Hr_alarm_time. TV _nsec + elapsed_rtc_delta. TV _nsec );

// Record the log. The current version has disable this macro, so no logs will appear.
Android_alarm_dprintf (android_alarm_print_flow,
"Alarm start hrtimer % d at % lD. % 09ld \ n ",
Alarm_type, hr_alarm_time. TV _sec, hr_alarm_time. TV _nsec );

// Add an hrtimer for alarm_timer [alarm_type]. If alarm_timer [alarm_type] already has an hrtimer, delete it and then add a new one. See the implementation of the hrtimer_start_range_ns function in hrtimer. C.
Hrtimer_start (& alarm_timer [alarm_type],
Timespec_to_ktime (hr_alarm_time), hrtimer_mode_abs );
}

 

Conclusion: This function eventually creates an hrtimer for the alarm_type type in the array alarm_timer [alarm_type.

 

2.3 alarm_init Function

 

To be continued.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.