Android sleep wake-up mechanism-kernel state

Source: Internet
Author: User
Tags linux sleep

I. Introduction

Several low-power States are defined in the Android system: earlysuspend, suspend, and hibernation.
1) earlysuspend: it is a low power consumption State. Some devices can choose to enter a low power consumption state. For example, the LCD can reduce the brightness or disable it;
2) suspend: this means that all peripheral modules and CPUs except power management do not work, and only the memory is Refresh;
3) hibernation means that all memory images are written to the disk, and the system is shut down. After the recovery, the system will be able to return to the status before the shutdown. Is the most thorough low power mode, which writes all memory images to the disk, and then the system shuts down. This file also creates multiple entries in the sysfs File System:/sys/power/disk,/sys/power/resume, And/sys/power/image_size, in this way, you can directly control the system's access to the hibernation status through sysfs. This code is no different from the standard Linux kernel.

In the kernel that has been installed with the android patch, the state_store () function will go to another path and enter request_suspend_state (). The file is located in earlysuspend. c. these functions are added to the Android system. earlysuspend and late resume will be introduced later.

Ii. User Interfaces

The interface provided by the power management kernel layer to the application layer is the sysfs file system. All related interfaces are implemented through sysfs. The android framework is encapsulated based on sysfs and finally provided to Android Java applications in the form of Java classes.

The Android system creates an entry in sysfs:
/Sys/power/State
/Sys/power/wake_lock
/Sys/power/wake_unlock

Echo mem>/sys/power/State or ECHO standby>/sys/power/State: the command system enters the earlysuspend state, drivers registered with early suspend handler will enter their respective earlysuspend statuses in turn.

Echo on>/sys/power/State: the system will exit the early suspend state.

Echo disk>/sys/power/State: the command system enters the hibernation status.

Echo lockname>/sys/power/wake_lock: Lock "lockname"
Echo lockname>/sys/power/wake_unlock: Unlock "lockname"
The above are the commands for respectively locking and unlocking. Once all the wakelock in the system is unlocked, the system will enter the suspend state, it can be seen that in Linux, the previous suspend operation (echo mem>/sys/power/State, etc.) in Android is replaced with the system into early suspend; the wake lock mechanism becomes the only way for the user's command system to enter the suspend state.

 

3. Android sleep (suspend)

1. Related Files
• Kernel/kernel/power/Main. c
• Kernel/kernel/power/earlysuspend. c
• Kernel/kernel/power/wakelock. c

 

2. Features
1) Early suspend
Early suspend is a mechanism introduced by Android, which is highly controversial in the upstream and will not be commented here. This mechanism is used to disable display-related devices, such as LCD backlights, gravity sensors, and touch screens, however, the system may still be running (wake lock is available at this time) for task processing, such as scanning files on the SD card. In embedded devices, backlight is a huge power consumption, so android will add such a mechanism.

2) late resume
Late resume is a mechanism supporting suspend and starts execution after kernel wake-up. It is mainly used to wake up the device that is sleeping during early suspend.

3) Wake lock
Wake_lock plays a core role in the Power Management System of Android. Wake_lock is a lock mechanism. As long as someone holds this lock, the system will not be able to sleep and can be obtained by user State programs and kernels. The lock can be time-out or not time-out. The lock will be automatically unlocked after time-out. If no lock or timeout occurs, the kernel starts the sleep mechanism to sleep.

3. Android suspend
The main. c file is the entrance to the entire framework. You can read and write the Sys File/sys/power/State to change the control system to a low-power state. The user's read/write operations on/sys/power/State call main. state_store () in C. You can write the strings defined in const char * const pm_states [], such as "on", "mem", "standby", and "disk ".

State_store () first checks whether the user writes a "disk" string. If yes, The Hibernate () function command system is called to enter the hibernation state. If it is another string, call request_suspend_state () (if config_earlysuspend is defined) or call enter_state () (if config_earlysuspend is not defined ). The request_suspend_state () function is implemented in earlysuspend. c Based on the standard Linux version of Android. In the standard Linux kernel
When sysfs writes "mem" and "standby", enter_state () is called directly to enter the suspend mode. However, in Android, The request_suspend_state () function is called to enter the early suspend state. The code for the request_suspend_state () function is as follows:

 

Void request_suspend_state (suspend_state_t new_state) {unsigned long irqflags; int old_sleep; # ifdef config_plat_rkif (system_state! = System_running) return; # events (& state_lock, irqflags); old_sleep = State & suspend_requested; If (debug_mask & debug_user_state) {struct timespec ts; struct rtc_time TM; getnstimeofday (& TS); rtc_time_to_tm (TS. TV _sec, & TM); pr_info ("request_suspend_state: % s (% d-> % d) at % LLD" "(% d-% 02d-% 02d % 02d: % 02d: % 02d. % 09lu UTC) \ n ", new_state! = Pm_suspend_on? "Sleep": "Wakeup", requested_suspend_state, new_state, ktime_to_ns (ktime_get (), TM. tm_year + 1900, TM. tm_mon + 1, TM. tm_mday, TM. tm_hour, TM. tm_min, TM. tm_sec, ts. TV _nsec);} If (! Old_sleep & new_state! = Pm_suspend_on) {state | = suspend_requested; // enter early suspend for processing, and execute the terminate (terminate, & terminate) function;} else if (old_sleep & new_state = pm_suspend_on) {State & = ~ Suspend_requested; wake_lock (& main_wake_lock); // enter late resume for processing, and execute the handler (iterator, & late_resume_work);} iterator = new_state; iterator (& state_lock, irqflags );}

4. Early suspend
In the early_suspend () function, first check whether the current request status is suspend to prevent suspend requests from being canceled at this time (because the user process is still running at this time ), to exit, simply quit. If no, this function calls a series of callbacks registered in early_suspend_handlers (registered through register_early_suspend), synchronizes the file system, and then discards main_wake_lock,
The wake lock is a lock without timeout. If the lock is not released, the system will not be able to sleep.

Note: fbearlysuspend. C and consoleearlysuspend. c files support earlysuspend for LCD framebuffer and earlysuspend for console. In fact, these two files use the interfaces provided by earlysuspend. C to register early suspend handler for framebuffer and console, and provide corresponding handler functions.

static void early_suspend(struct work_struct *work){struct early_suspend *pos;unsigned long irqflags;int abort = 0;#ifdef CONFIG_PLAT_RKif (system_state != SYSTEM_RUNNING)return;#endifmutex_lock(&early_suspend_lock);spin_lock_irqsave(&state_lock, irqflags);if (state == SUSPEND_REQUESTED)state |= SUSPENDED;elseabort = 1;spin_unlock_irqrestore(&state_lock, irqflags);if (abort) {if (debug_mask & DEBUG_SUSPEND)pr_info("early_suspend: abort, state %d\n", state);mutex_unlock(&early_suspend_lock);goto abort;}if (debug_mask & DEBUG_SUSPEND)pr_info("early_suspend: call handlers\n");list_for_each_entry(pos, &early_suspend_handlers, link) {if (pos->suspend != NULL) {if (debug_mask & DEBUG_VERBOSE)pr_info("early_suspend: calling %pf\n", pos->suspend);pos->suspend(pos);}}mutex_unlock(&early_suspend_lock);#ifdef CONFIG_SUSPEND_SYNC_WORKQUEUEsuspend_sys_sync_queue();#elseif (debug_mask & DEBUG_SUSPEND)pr_info("early_suspend: sync\n");sys_sync();#endifabort:spin_lock_irqsave(&state_lock, irqflags);if (state == SUSPEND_REQUESTED_AND_SUSPENDED)wake_unlock(&main_wake_lock);spin_unlock_irqrestore(&state_lock, irqflags);}

5. Late resume

After all the wake-up operations are completed, user processes have started to run. Wake-up is usually due to the following reasons:

• Incoming calls
For incoming calls, the modem sends a command to rild to notify windowmanager of incoming call response, in this way, the device that remotely calls powermanagerservice to write "on" to/sys/power/State to execute late resume, such as lighting the screen.

• User buttons

User Key events are sent to windowmanager. windowmanager processes these key events. There are several key events. If the key is not a wake-up key, the system can be awakened) windowmanager will take the initiative to discard the wakelock to make the system sleep again. If the key is the wake-up key, windowmanger will call the interface in powermanagerservice to execute late
Resume.

Late resume will wake up the device that previously called early suspend.

static void late_resume(struct work_struct *work){struct early_suspend *pos;unsigned long irqflags;int abort = 0;#ifdef CONFIG_PLAT_RKif (system_state != SYSTEM_RUNNING)return;#endifmutex_lock(&early_suspend_lock);spin_lock_irqsave(&state_lock, irqflags);if (state == SUSPENDED)state &= ~SUSPENDED;elseabort = 1;spin_unlock_irqrestore(&state_lock, irqflags);if (abort) {if (debug_mask & DEBUG_SUSPEND)pr_info("late_resume: abort, state %d\n", state);goto abort;}if (debug_mask & DEBUG_SUSPEND)pr_info("late_resume: call handlers\n");list_for_each_entry_reverse(pos, &early_suspend_handlers, link) {if (pos->resume != NULL) {if (debug_mask & DEBUG_VERBOSE)pr_info("late_resume: calling %pf\n", pos->resume);pos->resume(pos);}}if (debug_mask & DEBUG_SUSPEND)pr_info("late_resume: done\n");abort:mutex_unlock(&early_suspend_lock);}

6. Wake lock
Wake_lock prevents running systems from entering the suspend or other low-power state.

Another major change to Android is the addition of the wakelock mechanism. Implemented in wakelock. C and userwakelock. C. Wakelock can prevent a system in the active or idle State from entering sleep or other low-power States. The system can enter sleep and other low-power States until all of its wakelock is released.

Let's take a look at how the wake lock mechanism runs and works, and focus on the wakelock. C (wake_lock) file.

1) There are two statuses of wake lock: locking and unlocking. There are two ways of locking:
• The first type is a permanent lock. Such a lock will not be unlocked unless it is displayed, so the use of this lock is very careful.
• The second is the timeout lock, which will lock the system for a period of time. If the time passes, the lock will be automatically released.

2) There are two types of locks:
• Wake_lock_suspend: This lock prevents the system from sleep (suspend ).
• Wake_lock_idle: This lock does not affect the sleep of the system and is used to prevent the system from entering the low-power state when holding the lock. That is, the system enters the low-power state from the Idle State until the wake_lock is released. This low-power state will delay the interruption or disable a group of interruptions.

3) In the wake lock, there will be three places for the system to start suspend () directly, respectively:
• In wake_unlock (), if no other wake lock is found after unlocking, sleep begins.
• After the timer reaches the time, the timer's callback function will check whether there are other wake locks. If not, let the system go to sleep.
• In wake_lock (), after a wake lock is locked, the system checks whether there is a lock again. I think the check here is unnecessary, A better way is to make the lock operation atomic, rather than tedious checks, and such checks may also be missed.

7. Suspend

After wake_lock runs suspend. c's suspend () function will be called. This function first synchronizes the file system and then calls pm_suspend (request_suspend_state). Then pm_suspend () will call enter_state () to enter the Linux sleep process...

static void suspend(struct work_struct *work){int ret;int entry_event_num;struct timespec ts_entry, ts_exit;if (has_wake_lock(WAKE_LOCK_SUSPEND)) {if (debug_mask & DEBUG_SUSPEND)pr_info("suspend: abort suspend\n");return;}entry_event_num = current_event_num;#ifdef CONFIG_SUSPEND_SYNC_WORKQUEUEsuspend_sys_sync_queue();#elsesys_sync();#endifif (debug_mask & DEBUG_SUSPEND)pr_info("suspend: enter suspend\n");getnstimeofday(&ts_entry);ret = pm_suspend(requested_suspend_state);getnstimeofday(&ts_exit);if (debug_mask & DEBUG_EXIT_SUSPEND) {struct rtc_time tm;rtc_time_to_tm(ts_exit.tv_sec, &tm);pr_info("suspend: exit suspend, ret = %d ""(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret,tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec, ts_exit.tv_nsec);}if (ts_exit.tv_sec - ts_entry.tv_sec <= 1) {++suspend_short_count;if (suspend_short_count == SUSPEND_BACKOFF_THRESHOLD) {suspend_backoff();suspend_short_count = 0;}} else {suspend_short_count = 0;}if (current_event_num == entry_event_num) {if (debug_mask & DEBUG_SUSPEND)pr_info("suspend: pm_suspend returned with no event\n");wake_lock_timeout(&unknown_wakeup, HZ / 2);}}

8. Differences between Android and standard Linux sleep

Although pm_suspend () uses enter_state () to enter the standard Linux sleep process, there are still some differences:

When a frozen process is started, Android will first check whether there is a wake lock. If not, the processes will be stopped, because some people may apply for a wake lock during the suspend and freeze processes, in this case, the frozen process will be interrupted.

In suspend_late (), the system will check whether there is a wake lock at the last time. This may be caused by a process that quickly applies for the wake lock and quickly releases the lock. In this case, here an error is returned, and the entire suspend will be abandoned. If pm_suspend () succeeds, you can add "no_console_suspend" to the kernel cmd to view log output in the suspend and resume processes.

 

From: http://bbs.ednchina.com/BLOG_ARTICLE_1784575.HTM

 

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.