zoukankan      html  css  js  c++  java
  • 平台设备驱动框架

    框架入口源文件: led_drv.c  led_dev.c

    可根据入口源文件,再按着框架到内核走一遍

    内核版本:linux_2.6.22.6 硬件平台:JZ2440

     以下是驱动框架:

    以下是驱动代码 led_dev.c:

    #include <linux/module.h>
    #include <linux/version.h>
    
    #include <linux/init.h>
    
    #include <linux/kernel.h>
    #include <linux/types.h>
    #include <linux/interrupt.h>
    #include <linux/list.h>
    #include <linux/timer.h>
    #include <linux/init.h>
    #include <linux/serial_core.h>
    #include <linux/platform_device.h>
    
    
    
    
    //定义一个资源结构体
    static struct resource led_drv_resource[]=
    {
       [0] = {.start =0x56000050 , .end = 0x56000050 + 8 - 1 , .flags = IORESOURCE_MEM, },
       [1] = {.start = 5, .end  = 5,.flags = IORESOURCE_IRQ,}
    };
    
    
    static void led_platform_release(struct device * dev)
    {}
    
    
    //定义一个 device_platform 结构体
    static struct platform_device led_dev_platform =
    {
      .name = "platform_led",
      .id = -1,
      .num_resources = ARRAY_SIZE(led_drv_resource),
      .resource = led_drv_resource,
      .dev = { .release = led_platform_release,  },
    };
    
    
    static int led_device_init(void)
    {
      platform_device_register(&led_dev_platform);
      return 0;
    }
    
    static void led_device_exit(void)
    {
       platform_device_unregister(&led_dev_platform);
    }
    
    module_init(led_device_init);
    module_exit(led_device_exit);
    MODULE_LICENSE("GPL");

    以下是驱动代码led_drv.c:

    #include <linux/module.h>
    #include <linux/version.h>
    #include <linux/init.h>
    #include <linux/fs.h>
    #include <linux/interrupt.h>
    #include <linux/irq.h>
    #include <linux/sched.h>
    #include <linux/pm.h>
    #include <linux/sysctl.h>
    #include <linux/proc_fs.h>
    #include <linux/delay.h>
    #include <linux/platform_device.h>
    #include <linux/input.h>
    #include <linux/irq.h>
    #include <asm/uaccess.h>
    #include <asm/io.h>
    
    //引脚定义
    static unsigned long *gpfcon;
    static unsigned long *gpfdat;
    static int pin;
    
    //为设备定义一个类
    static struct class *led_platform_class;
    
    //定义主设备号
    static int major;
    static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
    {
        int val;
        copy_from_user(&val, buf, count); 
    
        if (val == 1) *gpfdat &= ~(1<<pin);
        else *gpfdat |= (1<<pin);
        
        return 0;
    }
    
    static int led_drv_open(struct inode *inode, struct file *file)
    {
       //配置寄存器
       *gpfcon &= ~(0x3<<(pin*2));
       *gpfcon |= (0x1<<(pin*2));
        return 0;    
    }
    
    static struct file_operations led_fops =
    {
       .owner = THIS_MODULE,
       .write   = led_drv_write,
       .open   = led_drv_open,
    };
    
    
    static int probe_led(struct platform_device *pfdrv)
    {
        // 引脚初始化
        struct resource *sodrv;
        sodrv = platform_get_resource(pfdrv,IORESOURCE_MEM,0);
        gpfcon = ioremap(sodrv->start,sodrv->end - sodrv->start+1);    
        gpfdat = gpfcon +1;
    
        sodrv =  platform_get_resource(pfdrv,IORESOURCE_IRQ,0);
        pin = sodrv->start;
    
        //注册字符设备 类 节点
        major = register_chrdev(0,"led_devices",&led_fops);                                  //  proc/devices/led_class
        led_platform_class = class_create(THIS_MODULE,"led_class");                          //  sys/class/led_class
        class_device_create(led_platform_class,NULL, MKDEV(major,0), NULL, "led_dev");       //  dev/led_dev
        return 0;
    }
    
    static int  remove_led(struct platform_device *pfdrv)
    {
       iounmap(gpfcon);
       unregister_chrdev(major,"led_platform");
       class_destroy(led_platform_class);
       class_device_destroy(led_platform_class,MKDEV(major,0));
       return 0;
    }
    
    static struct platform_driver led_platform =
    {
       .probe = probe_led,
       .remove = remove_led,
       .driver ={.name = "platform_led",}
    };
    
    
    static int led_drv_init(void)
    {
       platform_driver_register(&led_platform);
       return 0;
    }
    
    
    static void led_drv_exit(void)
    {
       platform_driver_unregister(&led_platform);
    }
    
    
    module_init(led_drv_init);
    module_exit(led_drv_exit);
    MODULE_LICENSE("GPL");

    以下是编译驱动的Makefile:

    KER_DIR=/work/systems/kernel/linux-2/linux-2.6.22.6
    all:
        make -C $(KER_DIR) M=`pwd` modules
    clean:
        make -C $(KER_DIR) M=`pwd` modules clean
        rm -fr modules.order
    
    obj-m += led_dev.o
    obj-m += led_drv.o
  • 相关阅读:
    css选择器
    HTML标签用法
    pyenv python 版本控制
    Django之路
    Day15-Django
    python+selenium实现登录账户
    requests and BeautifulSoup
    清除MAC 可清除空间
    将python源文件打包成exe文件
    swift的一些东西
  • 原文地址:https://www.cnblogs.com/zsy12138/p/10391933.html
Copyright © 2011-2022 走看看