Android睡眠唤醒机制--HAL-->Kernel

一、Kernel与HAL接口分析

        Kernel与HAL接口是通过/sys/power下面的一系统文件来实现的,如:/sys/power/state

        Kernel中/sys/power下的文件实现过程如下:

1. sysfs的属性文件

     在kernel/power/main.c中,定义了一组sysfs的属性文件: 

[cpp]  view plain copy
  1. static struct attribute * g[] = {  
  2.     &state_attr.attr,  
  3. #ifdef CONFIG_PM_TRACE  
  4.     &pm_trace_attr.attr,  
  5.     &pm_trace_dev_match_attr.attr,  
  6. #endif  
  7. #ifdef CONFIG_PM_SLEEP  
  8.     &pm_async_attr.attr,  
  9.     &wakeup_count_attr.attr,  
  10. #ifdef CONFIG_PM_DEBUG  
  11.     &pm_test_attr.attr,  
  12. #endif  
  13. #ifdef CONFIG_USER_WAKELOCK  
  14.     &wake_lock_attr.attr,  
  15.     &wake_unlock_attr.attr,  
  16. #endif  
  17. #endif  
  18.     NULL,  
  19. };  
  20.   
  21. static struct attribute_group attr_group = {  
  22.     .attrs = g,  
  23. };  

      如state_attr定义如下:

[cpp]  view plain copy
  1. power_attr(state);  
  2. #define power_attr(_name) \  
  3. static struct kobj_attribute _name##_attr = {   \  
  4.     .attr   = {             \  
  5.         .name = __stringify(_name), \  
  6.         .mode = 0644,           \  
  7.     },                  \  
  8.     .show   = _name##_show,         \  
  9.     .store  = _name##_store,        \  
  10. }  
  11.   
  12. 即:  
  13. static struct kobj_attribute state_attr = { \  
  14.     .attr   = {             \  
  15.         .name = "state",    \  
  16.         .mode = 0644,           \  
  17.     },                  \  
  18.     .show   = state_show,           \  
  19.     .store  = state_store,      \  
  20. }  


2. 创建sysfs文件

[cpp]  view plain copy
  1. static int __init pm_init(void)  
  2. {  
  3.     int error = pm_start_workqueue();  
  4.     if (error)  
  5.         return error;  
  6.     hibernate_image_size_init();  
  7.     hibernate_reserved_size_init();  
  8.     power_kobj = kobject_create_and_add("power", NULL);  
  9.     if (!power_kobj)  
  10.         return -ENOMEM;  
  11.     return sysfs_create_group(power_kobj, &attr_group);  
  12. }  

       pm_init函数执行后,会创建/sys/power目录,且目录下会建立一系列属性文件,其中一个是/sys/power/state文件。用户空间该文件将会导致state_store被调用,该文件将会导致state_show函数被调用。

 二、HAL代码分析

         HAL代码位于hardware/libhardware_legacy/power/power.c

1. 路径及写入字符串定义        

[cpp]  view plain copy
  1. const char * const NEW_PATHS[] = {  
  2.     "/sys/power/wake_lock",  
  3.     "/sys/power/wake_unlock",  
  4.     "/sys/power/state"  
  5. };  
  6.   
  7. static const char *off_state = "mem";  
  8. static const char *on_state = "on";  

2. 打开上面定义的三个文件

[cpp]  view plain copy
  1. static int  
  2. open_file_descriptors(const char * const paths[])  
  3. {  
  4.     int i;  
  5.     for (i=0; i<OUR_FD_COUNT; i++) {  
  6.         int fd = open(paths[i], O_RDWR);  
  7.         if (fd < 0) {  
  8.             fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);  
  9.             g_error = errno;  
  10.             return -1;  
  11.         }  
  12.         g_fds[i] = fd;  
  13.     }  
  14.   
  15.     g_error = 0;  
  16.     return 0;  
  17. }  


3. 修改状态
      用户态的电源管理系统会调用set_screen_state函数来触发suspend的流程,该函数实际上就是往/sys/power/state文件写入"mem"或"on"命令字符串。

[cpp]  view plain copy
  1. int  
  2. set_screen_state(int on)  
  3. {  
  4.     QEMU_FALLBACK(set_screen_state(on));  
  5.   
  6.     LOGI("*** set_screen_state %d", on);  
  7.   
  8.     initialize_fds();  
  9.   
  10.     //LOGI("go_to_sleep eventTime=%lld now=%lld g_error=%s\n", eventTime,  
  11.       //      systemTime(), strerror(g_error));  
  12.   
  13.     if (g_error)  
  14.         goto failure;  
  15.   
  16.     char buf[32];  
  17.     int len;  
  18.     if(on)  
  19.         len = snprintf(buf, sizeof(buf), "%s", on_state);  
  20.     else  
  21.         len = snprintf(buf, sizeof(buf), "%s", off_state);  
  22.   
  23.     buf[sizeof(buf) - 1] = '\0';  
  24.     len = write(g_fds[REQUEST_STATE], buf, len);  
  25.     if(len < 0) {  
  26.     failure:  
  27.         LOGE("Failed setting last user activity: g_error=%d\n", g_error);  
  28.     }  
  29.     return 0;  
  30. }  
出处:http://blog.csdn.net/myarrow/article/details/8137566
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值