platform平台总线---led实验实例

来源:互联网 发布:天刀萝莉少女捏脸数据 编辑:程序博客网 时间:2024/05/17 20:32
/***************************************************@ name :obsession@ date   :March 16.2016@mailbox:1162732624@qq.com****************************************************/#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>/*1.分配一个struct resource*//*struct resource {      resource_size_t start;      //资源的起始值      resource_size_t end;        //资源的结束值      const char *name;      unsigned long flags;        //资源的类型,如IORESOURCE_IO,IORESOURCE_IRQ,    IORESOURCE_MEM,IORESOURCE_DMA      struct resource *parent, *sibling, *child;  }; *//*2.填充resource硬件信息*/static struct resource led_resource[] = {    [0] = {//操作那个寄存器        .start = 0xE020_0280,        .end   = 0xE020_0280 + 8 - 1,        .flags = IORESOURCE_MEM,    },    [1] = {    //引脚位        .start = 1,        .end   = 1,        .flags = IORESOURCE_IRQ,    }};static void led_release(struct device * dev){}/*3.分配自己的私有硬件信息*//*struct platform_device {      const char  * name;        //判断platform_device和platform_driver成员里的name,如果二者的name字    段相同则匹配,如果匹配则调用platform_driver的probe函数。    int     id;      struct device   dev;      u32     num_resources;      // 资源总数     struct resource * resource; // 资源        struct platform_device_id   *id_entry;  };  */static struct platform_device led_dev = {    .name         = "myled",    .id       = -1,    .num_resources    = ARRAY_SIZE(led_resource),    .resource     = led_resource,    .dev = {     .release = led_release, },};static int led_dev_init(void){/*注册设备平台驱动 int platform_device_register(struct platform_device *pdev) {      device_initialize(&pdev->dev);      return platform_device_add(pdev);  } */platform_device_register(&led_dev);return 0;}static void led_dev_exit(void){/*注销设备平台驱动void platform_device_unregister(struct platform_device *pdev)  {      platform_device_del(pdev);      platform_device_put(pdev);  }  */platform_device_unregister(&led_dev);}module_init(led_dev_init);module_exit(led_dev_exit);MODULE_LICENSE("GPL");

/*******************************************************@工程名字:平台设备驱动软件部分@姓          名:obsession@日          期:2016.03.14*******************************************************/#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 int major;static struct class *cls;static volatile unsigned long *gpio_con;static volatile unsigned long *gpio_dat;static int pin;/*1.定义GPIO管脚的硬件数据结构*//*2.初始化LED灯对应的GPIO管脚信息*/static int led_open(struct inode *inode,struct file *file){//配置GPIO为输出口*gpio_con &= ~(0x3 << (pin*2)); *gpio_con |= (0x1 << (pin*2));return 0;}static ssize_t led_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){// 点灯*gpio_dat &= ~(1<<pin);}else{// 灭灯*gpio_dat |= (1<<pin);}return 0;}static struct file_operations led_fops = {.owner  = THIS_MODULE,.open    = led_open,.write    = led_write,};/*当硬件和软件匹配成功以后,调用probe函数并且此函数的形参指向匹配成功的硬件信息;*/static int led_probe(struct device *pdev){struct resource *res;/* 根据platform_device的资源进行ioremap */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;/* 注册字符设备驱动程序 */printk("led_probe, 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"); /* /dev/led */return 0;}static int led_remove(struct device *pdev){/* 卸载字符设备驱动程序 *//* iounmap */printk("led_remove, remove led\n");class_device_destroy(cls, MKDEV(major, 0));class_destroy(cls);unregister_chrdev(major, "myled");iounmap(gpio_con);return 0;}/*分配struct_driver来描述软件信息struct device_driver {      const char      *name;      struct bus_type     *bus;      struct module       *owner;        int (*probe) (struct device *dev);      int (*remove) (struct device *dev);  //当删除硬件或软件信息时,调用此函数做清理工作};  */struct platform_driver led_drv = {.probe= led_probe,.remove= led_remove,.driver= {.name= "myled",}};static int led_drv_init(void){/*平台驱动的注册使用platform_driver_register函数注册节点int platform_driver_register(struct platform_driver *drv)  {      drv->driver.bus = &platform_bus_type;      if (drv->probe)          drv->driver.probe = platform_drv_probe;      if (drv->remove)          drv->driver.remove = platform_drv_remove;      if (drv->shutdown)          drv->driver.shutdown = platform_drv_shutdown;      if (drv->suspend)          drv->driver.suspend = platform_drv_suspend;      if (drv->resume)          drv->driver.resume = platform_drv_resume;      return driver_register(&drv->driver);  }  */platform_driver_register(&led_drv);return 0;}static void led_drv_exit(void){/*注销平台驱动void platform_driver_unregister(struct platform_driver *drv)  {      driver_unregister(&drv->driver);  }  */platform_driver_unregister(&led_drv) ;}module_init(led_drv_init);module_exit(led_drv_exit);MODULE_LICENSE("GPL");

1 0
原创粉丝点击