基于Android的Linux内核的电源管理:Early Suspend


1.用户空间的接口

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

power_attr(state);

把这个宏展开后:

  1. staticstruct kobj_attribute state_attr = { \  
  2.   
  3.         .attr ={                                \  
  4.   
  5.                  .name = "state",    \  
  6.   
  7.                  .mode = 0644,                           \  
  8.   
  9.         },                                            \  
  10.   
  11.         .show      =state_show,                           \  
  12.   
  13.         .store       =state_store,                  \  
  14.   
  15. }  

我们再看看main.c的入口:

  1. staticint __init pm_init(void)  
  2.   
  3. {  
  4.   
  5.     ......  
  6.   
  7.         power_kobj =kobject_create_and_add("power", NULL);  
  8.   
  9.         if (!power_kobj)  
  10.   
  11.                  return -ENOMEM;  
  12.   
  13.         return sysfs_create_group(power_kobj,&attr_group);  
  14.   
  15. }  

显然,该函数执行后,会在生成/sys/power目录,该目录下会建立一系列属性文件,其中一个就是/sys/power/state文件。用户空间向该文件的写入将会导致state_store被调用,读取该文件将会导致state_store函数被调用。

现在回到Android的HAL层中,查看一下代码:hardware/libhardware_legacy/power/power.c:

  1.  //定义写入/sys/power/state的命令字符串   
  2.   
  3. staticconst char *off_state = "mem";  
  4.   
  5. staticconst char *on_state = "on";  
  6.   
  7. //打开/sys/power/state等属性文件,保存相应的文件描述符   
  8.   
  9. staticint  
  10.   
  11. open_file_descriptors(constchar * const paths[])  
  12.   
  13. {  
  14.   
  15.     int i;  
  16.   
  17.     for (i=0; i<OUR_FD_COUNT; i++) {  
  18.   
  19.         int fd = open(paths[i], O_RDWR);  
  20.   
  21.         if (fd < 0) {  
  22.   
  23.             fprintf(stderr, "fatal erroropening \"%s\"\n", paths[i]);  
  24.   
  25.             g_error = errno;  
  26.   
  27.             return -1;  
  28.   
  29.         }  
  30.   
  31.         g_fds[i] = fd;  
  32.   
  33.     }  
  34.   
  35.    
  36.   
  37.     g_error = 0;  
  38.   
  39.     return 0;  
  40.   
  41. }  

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

  1. int  
  2.   
  3. set_screen_state(inton)  
  4.   
  5. {  
  6.   
  7.     ......  
  8.   
  9.     initialize_fds();  
  10.   
  11.     ......  
  12.   
  13.     char buf[32];  
  14.   
  15.     int len;  
  16.   
  17.     if(on)  
  18.   
  19.         len = snprintf(buf, sizeof(buf),"%s", on_state);  
  20.   
  21.     else  
  22.   
  23.         len = snprintf(buf, sizeof(buf),"%s", off_state);  
  24.   
  25.    
  26.   
  27.     buf[sizeof(buf) - 1] = '\0';  
  28.   
  29.     len = write(g_fds[REQUEST_STATE], buf,len);  
  30.   
  31.     ......  
  32.   
  33.     return 0;  
  34.   
  35. }  
  • 1
  • 2
  • 3
  • 下一页

相关内容