zoukankan      html  css  js  c++  java
  • 仿照linux dpm机制,实现自己的dpm【转】

    转自:http://blog.csdn.net/lixiaojie1012/article/details/23788713

    前边我们讨论分析了linux 内核的dpm实现,分析的目的在于学以致用;在好多实时操作系统中,并没有dpm这个框架,所以我们可以仿照linux的dpm框架,来实现我们自己的dpm,可以运用到需要dpm的系统中。

     知识点:链表,回调函数,函数指针,互斥锁,锁中断

    为便于描述,本文使用伪代码,仅个别地方具体实现;

    1、首先,我们需要定义两个结构体类型,一个用于控制,一个用于各个模块注册;

          (1)控制结构体

                   struct my_dpm{

                           list_head    dpm_list;

                           list_head    prepare_list;

                           list_head   early_list;

                           list_head    suspend_list;

                           list_head    late_list;

                           spinlock_t      lock_mutx;

                   }dpm_ctrl;

             (2)各模块注册dpm使用的结构体

                   struct dpm_device{

                            char *device_name;

                             list_head     entry;

                             void *data;

                             int  (*prepare)(struct dpm_device *dev);

                             int  (*suspend_early)(struct dpm_device *dev);

                             int (*suspend)(struct dpm_device *dev);

                             int (*suspend_late)(struct dpm_device *dev);

                            int  (*resume_early)(struct dpm_device *dev);

                             int  (*resume)(struct dpm_device *dev);

                             int  (*resume_late)(struct dpm_device *dev);

                             int  (*complete)(struct dpm_device *dev);

                   };

    2、OK,结构体我们已经定义完了,那么我们接下来需要初始化一下控制结构体的变量

                    int  my_dpm_init(void){

                           初始化五个链表;

                           初始化spin_lock锁;

                           return OK;

                    }

    3、到此,我们自己的dpm已初始化完成,各个模块想要注册dpm,就差一个注册接口了,下面我们来实现注册接口

                  int dpm_register(struct dpm_device *device

                      获取互斥锁;

                      初始化设备结构体中的entry;

                      加入到dpm_list链表中;

                     释放互斥锁;

                     return OK;

               }

     4、这样,用户就可以调用dpm_register来注册dpm了;但是注册完后,得需要提供接口来供低功耗流程来调用啊,莫急,我们这就来实现供低功耗调用的接口,    dpm_suspend和dpm_resume

           (1)dpm_suspend:主要回调各个模块注册的保存信息的回调函数,包括prepare、suspend_early、suspend、suspend_late

                     int dpm_suspend(void){

                          if(prepare())

                                   return -1;

                          if(suspend_early())

                                    return -1;

                          if(suspend())

                                   return -1;

                          if(suspend_late())

                                    return -1;

                           return 0;

                        }

             (2)dpm_resume:主要用在唤醒阶段,按照优先级回调各个模块注册的恢复信息的回调函数,包括resume_early、resume、resume_late、complete

                     int dpm_resume(void)

                    {

                           if(resume_early())

                                   return -1;

                          if(resume())

                                    return -1;

                          if(resume_late())

                                   return -1;

                          if(complete())

                                    return -1;

                           return 0;

                    }

    5、大家可以看到,上面两个接口中分别调用了4个函数,供8个函数,分别用在suspend阶段和resume阶段,接下来我们简单实现一下其中一个函数prepare

            int prepare(void)

           {

                  获取互斥锁;

                  遍历dpm_list链表,检查每个结点是否注册prepare回调函数,如果注册,则执行回调函数:ret=dev->prepare(dev),如果成功,则移入prepare_list,否则,执行恢复操作;

                  释放互斥锁;

            }

            其他的suspend_early()、suspend()、suspend_late()、resume()、resume_early()、resume_late()、complete()等具体函数实现基本大致相同,只不过所操作的链表不同罢了。

    好了,我们的dpm框架实现完成了,简单吧,我们尝试注册一个吧:

    int my_prepare(struct dpm_device *dev){}

    int my_suspend dpm_device *dev){}

    int my_resumet dpm_device *dev){}

    int my_completedpm_device *dev){}

                   struct dpm_device test_device={

                         .device_name = "my_test_device";

                         .prepare = my_prepare;

                         .suspend = mysuspend;

                        .resume = my_resume;

                       .omplete = my_complete;

    };

    在合适的地方调用dpm_register(&test_device)即可,需要注意的是,dpm回调函数注册一定要配对:prepare--complete       suspend--resume        suspend_late--resume_early                suspend_late--resume_early

  • 相关阅读:
    bootstrap表格
    Bootstrap的学习
    cssText文本格式化
    for循环坐标生成《逢五向上转》
    for循环坐标生成《逢十往下一行》
    for
    bootstrap学习笔记细化(表格)
    bootstrap学习笔记细化(按钮)
    bootstrap学习笔记细化(表单)
    bootstrap学习笔记细化(标题)
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/5333668.html
Copyright © 2011-2022 走看看