Android睡眠喚醒機制–HAL–>Kernel

來源:互聯網
上載者:User

一、Kernel與HAL介面分析

        Kernel與HAL介面是通過/sys/power下面的一系統檔案來實現的,如:/sys/power/state

        Kernel中/sys/power下的檔案實現過程如下:

1. sysfs的屬性檔案

     在kernel/power/main.c中,定義了一組sysfs的屬性檔案: 

static struct attribute * g[] = {&state_attr.attr,#ifdef CONFIG_PM_TRACE&pm_trace_attr.attr,&pm_trace_dev_match_attr.attr,#endif#ifdef CONFIG_PM_SLEEP&pm_async_attr.attr,&wakeup_count_attr.attr,#ifdef CONFIG_PM_DEBUG&pm_test_attr.attr,#endif#ifdef CONFIG_USER_WAKELOCK&wake_lock_attr.attr,&wake_unlock_attr.attr,#endif#endifNULL,};static struct attribute_group attr_group = {.attrs = g,};

      如state_attr定義如下:

power_attr(state);#define power_attr(_name) \static struct kobj_attribute _name##_attr = {\.attr= {\.name = __stringify(_name),\.mode = 0644,\},\.show= _name##_show,\.store= _name##_store,\}即:static struct kobj_attribute state_attr = {\.attr= {\.name = "state",\.mode = 0644,\},\.show= state_show,\.store= state_store,\}

2. 建立sysfs檔案

static int __init pm_init(void){int error = pm_start_workqueue();if (error)return error;hibernate_image_size_init();hibernate_reserved_size_init();power_kobj = kobject_create_and_add("power", NULL);if (!power_kobj)return -ENOMEM;return sysfs_create_group(power_kobj, &attr_group);}

       pm_init函數執行後,會建立/sys/power目錄,且目錄下會建立一系列屬性檔案,其中一個是/sys/power/state檔案。使用者空間該檔案將會導致state_store被調用,該檔案將會導致state_show函數被調用。

 二、HAL程式碼分析

         HAL代碼位於hardware/libhardware_legacy/power/power.c

1. 路徑及寫入字串定義        

const char * const NEW_PATHS[] = {    "/sys/power/wake_lock",    "/sys/power/wake_unlock",    "/sys/power/state"};static const char *off_state = "mem";static const char *on_state = "on";

2. 開啟上面定義的三個檔案

static intopen_file_descriptors(const char * const paths[]){    int i;    for (i=0; i<OUR_FD_COUNT; i++) {        int fd = open(paths[i], O_RDWR);        if (fd < 0) {            fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);            g_error = errno;            return -1;        }        g_fds[i] = fd;    }    g_error = 0;    return 0;}

3. 修改狀態
      使用者態的電源管理系統會調用set_screen_state函數來觸發suspend的流程,該函數實際上就是往/sys/power/state檔案寫入"mem"或"on"命令字串。

intset_screen_state(int on){    QEMU_FALLBACK(set_screen_state(on));    LOGI("*** set_screen_state %d", on);    initialize_fds();    //LOGI("go_to_sleep eventTime=%lld now=%lld g_error=%s\n", eventTime,      //      systemTime(), strerror(g_error));    if (g_error)        goto failure;    char buf[32];    int len;    if(on)        len = snprintf(buf, sizeof(buf), "%s", on_state);    else        len = snprintf(buf, sizeof(buf), "%s", off_state);    buf[sizeof(buf) - 1] = '\0';    len = write(g_fds[REQUEST_STATE], buf, len);    if(len < 0) {    failure:        LOGE("Failed setting last user activity: g_error=%d\n", g_error);    }    return 0;}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.