首页 > 代码库 > 教你一招如何开发平台无关的内核驱动

教你一招如何开发平台无关的内核驱动

       相信搞过内核驱动开发的人员都面临过这样的问题:为了让上层代码尽可能的不改变,需要底层驱动对上层提供的接口在各种形态上都要保持不变,但是底层的逻辑实现又不可避免的有差异,甚至有些时候在同一款产品形态上都会有很大差异,那么我们此时该如何设计驱动架构,使代码看起来既好看又易于维护呢?接下来我们来具体分析一下。

       举一个例子,现在有两种规格的定时器,内部实现逻辑不一样,要操作的寄存器也有差别,那么我现在有三种产品形态,一种形态上使用feature1,一种形态上使用feature2,另一种形态上这两种feature都会使用,那么此时还需要对上层提供的接口一致,接下来我们该如何做呢?

       1、实现feature1的接口:

               void timer_feature1_enable(u32 timer_id){........}

               void timer_feature1_disable(u32 timer_id){........}

                /*此处略去其他接口......................*/

        2、实现feature2的接口:

void timer_feature2_enable(u32 timer_id){........}

               void timer_feature2_disable(u32 timer_id){........}

         3、对上层提供的接口:

                void timer_enable(u32 timer_id){........}

                void timer_disable(u32 timer_id){........}

         对上层的这两个接口里边该如何实现呢?

         首先我们先来设一个控制回调函数的ops结构体:

                struct timer_ops{

                           void (*enable)(u32 timer_id);

                           void (*disable)(u32 timer_id);

                           ..............

                 };

                struct timer_ctrl{

struct *timer_ops[8];/*假设有8个定时器*/

                  };

               struct timer_ops feature1_ops ={

                       .enable = timer_feature1_enable,

                       .disable = timer_feature1_disable

                };

               struct timer_ops feature2_ops ={

                       .enable = timer_feature2_enable,

                       .disable = timer_feature2_disable

                };

  /*如果此产品形态上只使用feature1*/

#ifdef TIMER_FEATURE1

                static struct_ctrl common_ctrl = {

                     timer_ops[0] = &feature1_ops,

                     timer_ops[1] = &feature1_ops,

                      .......

               };

#endif


/*如果此产品形态上只使用feature2*/

#ifdef TIMER_FEATURE2

                static struct_ctrl common_ctrl = {

                     timer_ops[0] = &feature2_ops,

                     timer_ops[1] = &feature2_ops,

                      .......

               };

#endif


/*如果此产品形态上同时使用feature1和feature2,比如前4个使用feature1,后四个使用feature2*/

#ifdef TIMER_FEATURE1_AND_FEATURE2

                

static struct_ctrl common_ctrl = {

                              timer_ops[0] = &feature1_ops,

                              timer_ops[1] = &feature1_ops,

                               ...................


                               timer_ops[4] = &feature2_ops,

                               timer_ops[5] = &feature2_ops,

                                ....... 

}

#endif


控制结构体设置好之后,我们就可以在对上层接口里尽情调用了

void timer_enable(u32 timer_id)

{

                common_ctrl.timer_ops[timer_id]->enable(timer_id);

}

void timer_disable(u32 timer_id)

{

                common_ctrl.timer_ops[timer_id]->disable(timer_id);

}


这样设计驱动架构之后,无论后续又有多少个新特性,我们可以随心所欲进行添加,可扩展性极强,而且还特别易于维护。

其他任何有差异性的IP均可采用此思想进行平台无关的开发。