zoukankan      html  css  js  c++  java
  • 嵌入式Linux驱动学习之路(十七)驱动程序分层分离概念-平台设备驱动

     平台设备驱动:

      包含BUS(总线)、DEVICE、DRIVER。

      DEVICE:硬件相关的代码

      DRIVER:比较稳定的代码  

      BUS有一个driver链表和device链表。

        ①把device放入bus的device链表中

        ②从bus的drv链表中取出每一个drv,用bus的match函数判断drv能否支持dev。

        ③如果可以执行,则调用probe函数。

      driver和device类似。

    device驱动程序代码:

    /**
    * file name: led_dev.c
    */
    #include <linux/platform_device.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> /* 分配注册一个平台device结构体 */ static struct resource led_resources[] = { [0] = { .start= 0x56000050, .end= 0x56000050 + 8 - 1, .flags= IORESOURCE_MEM, }, [1] = { .start= 5, //第4个引脚 .end= 5, .flags= IORESOURCE_IRQ, }, }; void led_release(struct device * dev) { } static struct platform_device led_dev = { .name= "myled", .id= -1, .resource= led_resources, .num_resources= ARRAY_SIZE(led_resources), .dev = {.release = led_release,}, }; static int led_dev_init(void) { platform_device_register(&led_dev); return 0; } static void led_dev_exit(void) { platform_device_unregister(&led_dev); return ; } module_init(led_dev_init); module_exit(led_dev_exit); MODULE_LICENSE("GPL");

    driver驱动程序代码:

    /**
       * file name:led_driver.c
       */
    #include <linux/platform_device.h>
    #include <asm/mach/arch.h>
    #include <asm/mach/map.h>
    #include <linux/sched.h>
    #include <linux/signal.h>
    #include <linux/spinlock.h>
    #include <linux/errno.h>
    #include <linux/random.h>
    #include <linux/poll.h>
    #include <linux/init.h>
    #include <linux/slab.h>
    #include <linux/module.h>
    #include <linux/wait.h>
    #include <linux/mutex.h>
    #include <linux/io.h>
    #include <linux/fs.h>
    
    static int major;
    
    struct class *led_class;
    struct class_device *led_class_dev;
    static volatile unsigned long *gpio_con;
    static volatile unsigned long *gpio_dat;
    static int pin;
    
    static int led_open(struct inode *inode, struct file *file)
    {
        *gpio_con &= ~(0x3<<(pin*2));
        *gpio_con |= 0x1<<(pin*2);
        return 0;
    }
    
    ssize_t led_write(struct file *file, const char  *buff, size_t len, loff_t *pos )
    {
        int val;
        copy_from_user(&val, buff, 1);
        val &= 0x1;
        *gpio_dat &= ~(1<<pin);
        *gpio_dat |= (val<<pin);
    
        return 0; 
    }
    
    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;
    
        printk("led drv probe
    ");
        
        res = platform_get_resource(pdev,IORESOURCE_MEM,0);
        gpio_con = ioremap(res->start,res->end-res->start + 1);
        gpio_dat = gpio_con + 1;
        
        res = platform_get_resource(pdev,IORESOURCE_IRQ,0);
        pin = res->start;
        
        major = register_chrdev(0,"myled", &led_fops );
        led_class = class_create(THIS_MODULE,"myled");
        led_class_dev = class_device_create(led_class,NULL,MKDEV(major,0),NULL,"led%d",pin);
        
        return 0;
    }
    
    
    static int led_remove(struct platform_device *pdev)
    {
        iounmap(gpio_con);
        class_device_unregister(led_class_dev);
        class_destroy(led_class);
        unregister_chrdev( major,"myled");
        printk("led remove
    ");
        return 0;
    }
    
    struct platform_driver led_drv = {
        .driver={
            .owner=THIS_MODULE,
            .name = "myled",
        },
        .probe = led_probe,
        .remove= led_remove,
    };
    
    static int led_drv_init(void)
    {
        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");

    sd

  • 相关阅读:
    VMware12中CentOS7网络设置
    技术牛人
    PHP程序员如何突破成长瓶颈(php开发三到四年)
    php多线程
    go git 安装配置与使用 (windows 7 64bit)
    php内核和瓦力上线部署
    VM虚拟机下安装Centos7.0图文教程
    php结合redis实现高并发下的抢购、秒杀功能
    php foreach循环中unset后续的键值问题
    excle导入
  • 原文地址:https://www.cnblogs.com/ynxf/p/6014699.html
Copyright © 2011-2022 走看看