分岔分层机制

              app  

————————————–

               

      (装备与运用权层一致的相互作用)                |      

   |                        |                      |分层      

   –分岔–                   |   

(五金器具相干) (纯软件)

分岔:分岔五金器具相干和纯软件。

分层:五金器具相干和纯软件使杰出招收。,装备一致的使联系;每床都专注于本人的事情。

1。看居于首位地实例。

 gpio_keys_init 在进入方式有或起作用中招收平台驱动力排列。

 static int __init gpio_keys_init(void)    {        

  return platform_driver_register(&gpio_keys_device_driver);//招收居于首位地平台驱动力排列体;    

}

进入gpio_keys_device_driver:    

  struct platform_driver gpio_keys_device_driver = {      

    .probe      = gpio_keys_probe,      

    .remove     = __devexit_p(gpio_keys_remove),      

    .driver     = {              

            .name   = “gpio-keys”,      

    }    

  };

对GPIO-KEYSY探头效能的议论:       

  input = input_allocate_device();//分派居于首位地input_dev排列 

2. 通行证PrimFieldRover表示有或起作用,绍介另居于首位地观念。 机器脚踏车驱动力陶冶(BUS)     

  (1)机器脚踏车亦一种排列。,它收录:DRV链表,DEV链表,.match有或起作用     

  (2)固定排列(五金器具相干):通行证device_add有或起作用把device放入bus机器脚踏车的DEV链表;后来地从bus的DRV链表中取出每居于首位地driver排列体,运用机器脚踏车

婚配有或起作用确定DRV其中的那可以支撑物DEV。,若支撑物则使调动driver排列体的probe有或起作用(probe是比较地不乱的法典);     

  (3)驱动力器排列:通行证driver_register有或起作用把driver排列体放入bus机器脚踏车的DRV链表;后来地从bus机器脚踏车的DEV链表中取出每居于首位地dev,通行证.match函

逐个地比较地DEV其中的那支撑物DRV。,若支撑物则使调动driver排列体的probe有或起作用(probe是比较地不乱的法典);

在上文中3点,这仅仅Buth-DrvdEV陶冶的一种机制。;probe有或起作用外面可以蜡纸油印机总而言之或许招收居于首位地使具有特征固定或许招收input_dev排列体,这完整停止你。

定;这仅仅一种机制。,对单方都是命令的的。,它可以放在稍微位置。;当朕修正五金器具时,,仅修正五金器具固定,驱动力嫁妆同意不乱。;    

    三。任务:

  运用分层的思惟来使安定驱动力次。,首要分为两嫁妆。,LeDyDV与五金器具操纵和对立不乱的DeldRDV关于;LeDyDV首要本着良心的频率分布。,设置,平台招收

备用排列(平台式固定),因此次的任务是点亮一盏LED灯。,条件你把持另居于首位地LED灯,只必要修正此驱动力次那就够了创造必要的效能;DeliDRV首要本着良心的

分派,设置,招收居于首位地平台驱动力次排列(PrimthyDrviver),它首要本着良心的招收居于首位地使具有特征固定驱动力次。,从平台固定获取资源人

法典:

/*———————————————-*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

分派/设置/招收居于首位地平台固定平台

该排列贮藏了最重要的固定资源人。,通行证婚配后,驱动力次可以成为五金器具资源。

static struct resource led_resource[] = {

表示摄取地址,条件要更改五金器具表示,只需在在这里修正那就够了。

  [0] = {          

      .start = 0x56000050,            

      .end   = 0x56000050 + 8 – 1,//完毕地址           

      .flags = IORESOURCE_MEM,他们代表什么资源?       

 },

  哪居于首位地大头针?,条件你想使变酸LED灯,你只必要修正上面的数字。  

  [1] = {           

       .start = 4,           

       .end   = 4,           

       .flags = IORESOURCE_IRQ,周转资源人的暂停。。固定驱动力次将理性指定而尚未上任的获取相配的资源人。。       

 }

};

static void led_release(struct device DEV)

}

static struct platform_device led_dev = {    

  .name    = “myled”,因此名字必然要和国文同上。,固定name,通行证因此婚配平台驱动力次    

  .id     = -1,    

  .num_resources  = ARRAY_SIZE(led_resource),    

  .resource   = led_resource,    

  .dev    = {               

  .release = led_release,条件无装备因此有或起作用,转嫁模块时会交谈背面的。        

      },

};

static int led_dev_init(void){

//platform_device_register→platform_device_add→device_add即把固定放入平台机器脚踏车里的固定在链表中

瞄准LSMOD 后,驱动力器的探测效能被使调动。。   

 platform_device_register(&led_dev);

    return 0;

}

static void led_dev_exit(void){

/*    

 *    rmmod  LeDyDV模块继,使调动此有或起作用,而此有或起作用会从bus机器脚踏车的DEV链表中找出此固定,后来地    

 *    本婚配有或起作用停止和查找相配的DRV。,后来地使调动待在家里的停止有或起作用(DRV排列)来做若干。    

 *     清算任务  

 */

    platform_device_unregister(&led_dev);

}

module_init(led_dev_init);

module_exit(led_dev_exit);

MODULE_LICENSE(“GPL”);

—————————————————-

分派/设置/招收平台驱动力次平台

#include

#include  

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static int major;

static struct class *cls;

static volatile unsigned long *gpio_con;

static volatile unsigned long *gpio_dat;

static int pin;

static int led_open(struct inode *inode, struct file 贴壁纸)

划拨的款项为输出     

  *gpio_con &= ~(0x3<<(pin*2));

  *gpio_dat &= (0x1<<(pin*2));

   return 0;

}

static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t * 工艺学校)

    int val;

   copy_from_user(&val, buf, 伯爵)

条件(瓦尔) == 1){

      //照亮       

    *gpio_dat &= ~(1<

   }

   else{

    //灭灯

    *gpio_dat |= (1<

       }

 return 0;

}

static struct file_operations led_fops = {

  .owner = THIS_MODULE,    

  .open = led_open,    

  .write = led_write,

};

static int led_probe(struct platform_device PDEV)

  struct resource *res;  /*理性platform_device的资源停止ioremap*/    

  Re= PrimFixGETYA资源(PDEV), IORESOURCE_MEM, 0);*获取资源。

      gpio_con = ioremap(res->start, res->end – res->start + 1);    

  gpio_dat = gpio_con + 1;

      Re= PrimFixGETYA资源(PDEV), IORESOURCE_IRQ, 0);*获取资源。    

  pin = res->start;

招收使具有特征固定驱动力次

   printk(“led_porbe, found led\n”);

   major = register_chrdev(0, “myled”, &led_fops);

   cls = class_create(THIS_MODULE,”myled”);    

 class_device_create(cls, NULL, MKDEV(major,0), NULL, LED

     return 0;

}

static int led_remove(struct platform_device PDEV)

转嫁使具有特征固定驱动力次    printk(“led_remove, found led\n”);

   /*iounmap*/

    class_device_destroy(cls, MKDEV(major,0));    

  class_destroy(cls);    

      unregister_chrdev(major, “myled”);    

      iounmap(gpio_con);    

      return 0;

}

struct platform_driver led_drv = {    

    .probe      = led_probe,    

    .remove     = led_remove,    

    .driver     = {        

            .name   = “myled”,      

    }

};

static int led_drv_init(void){

驱动力次排列:通行证driver_register有或起作用把driver排列体放入bus机器脚踏车的DRV链表;后来地从bus机器脚踏车的DEV链表中取出每居于首位地dev,通行证.match函逐个地比较地DEV其中的那支撑物DRV。,若支撑物则使调动driver排列体的probe有或起作用(probe是比较地不乱的法典);*/  

 platform_driver_register(&led_drv);

   return  0;

}

static void led_drv_exit(void){

   platform_driver_unregister(&led_drv);

}

module_init(led_drv_init);

module_exit(led_drv_exit);

MODULE_LICENSE(“GPL”);

/*—————————————————–*/

Makefile:

KERN_DIR = /home/arm/linux-2.6.22.6

all:

  make -C $(KERN_DIR) M=`pwd` modules

clean:

  make -C $(KERN_DIR) M=`pwd` modules clean

  rm -rf Module.symvers

obj-m  += led_dev.o

obj-m  +=

条件你先瞄准LedioDV,DEV将被添加到机器脚踏车的固定列表中。,后来地找到相配的DRV。,因此时候未看见。,瞄准Ledi-DRV后,,将DRV添加到机器脚踏车驱动力次中。

在链表中,后来地会在DEV链表中找一遍有无婚配的dev(为了就相当于再找了一遍,就为了。,条件看见,DRV的探测效能也将被使调动。。因而,不

管是在DEV链表中找固定仍然在DRV链表中找驱动力,由于找到它。,在DRV中使调动探测有或起作用。,因此固定和驱动力次可以在不一样的工夫瞄准。,也可以按次瞄准。,通行证试

化验还标示,先装仍然先装,它们都是婚配有或起作用,在一切两个都是DRV继使调动DRV。。

 因而说,漠视它其中的那先装入?,平地婚配。,DRV排列的探头效能单位数被使调动。。其中的那率先转嫁LeDyDV或LeDyDRV?,一切的居于首位地

转嫁后,DRV排列的LeDelDead有或起作用盟员被使调动。。

化验法典:

#include

#include

#include

#include

/* my_led on    * my_led off    */

int 主(int) argc, char **argv) {    

  int fd;    

  int val = 1;  

   fd = open(“/dev/led”, O_RDWR);      

      条件(FD) < 0)      

          PrtTf(不克不及 open!\n”);

         if (argc != 2){      

          运用 :\n”);      

          Prtf(%s) \n”,argv[0]);

          return 0;    

      }

     if(strcmp(argv[1], on == 0)      

      val = 1;    

  else     

        val = 0;

  读到(FD), &val, 4);        

   return 0;  

}

当输出MyPeLED时 on  尤伊;

当输出MyPeLED时 off  关灯;

次法典的转折点剖析:

  (1)在LeDyDeViSin有或起作用中。:招收平台机器脚踏车固定,platform_device_register->platform_device_add->device_add把led-dev固定放入平台机器脚踏车的固定链表外面去;

      platform_device_register(&led_dev);

  (2)动态 struct platform_device led_dev中:

    朕朕必要留意的是:  .name  =  “my_led”  因此名字必然要和国文同上。,固定name,通行证因此婚配平台驱动力次

             .num_resources  = ARRAY_SIZE(led_resource),  五金器具资源号  

                              .resource   = led_resource,    /*五金器具资源*/

  (3)界说五金器具资源

static struct resource led_resource[] = {

表示摄取地址,条件要更改五金器具表示,只需在在这里修正那就够了。

  [0] = {          

      .start = 0x56000050,            

      .end   = 0x56000050 + 8 – 1,//完毕地址           

      .flags = IORESOURCE_MEM,他们代表什么资源?       

 },

  哪居于首位地大头针?,条件你想使变酸LED灯,你只必要修正上面的数字。  

  [1] = {           

       .start = 4,           

       .end   = 4,           

       .flags = IORESOURCE_IRQ,周转资源人的暂停。。固定驱动力次将理性指定而尚未上任的获取相配的资源人。。       

 }

};

————————————————————————————————————————

  (1)LeDyA使发声效能。:

      朕朕必要留意的是:运用PrimFixGETX资源有或起作用获取资源,先决条件是平台型固定。 此资源必不可少的事物做。;

             IORMAP假定的地址计划

             pin = res->strat 引脚得到转折点值,这是哪个用纽扣扣紧?,在这里是4。;先决条件是在LeDyDeV中界说了PIN。;

Leave a Comment

电子邮件地址不会被公开。 必填项已用*标注