linux2.6设备驱动程序框架

来源:互联网 发布:6g以下的单机游戏知乎 编辑:程序博客网 时间:2024/06/06 00:36

my.c驱动层代码

/*头文件定义*/#include <linux/kernel.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/platform_device.h>#include <linux/of_device.h>#include <asm/io.h>#include <asm/uaccess.h>static  char cbuff[1024];static int my_open(struct inode *inode, struct file *file){   //设备打开时的操作........   MOD_INC_USE_COUNT;  /*在以前2.4版本内核中,该宏负责记录增加或者减少设备模块的使用情况,防止应用程序使用驱动时,模块被意外卸载。在2.6内核版本后,实现自动化管理模块*/   printk("my device open   sucess!/n");    return 0;}static int my_release(struct inode *inode, struct file *file){   //设备关闭时的操作........   MOD_DEC_USE_COUNT;//跟上面MOD_INC_USE_COUNT宏意义一样    return 0;}//read方法完成将数据从内核拷贝到应用程序空间static int my_read(struct file *file,const char *buff,size_t count,loff_t *ppos ){    //file文件指针,buff数据缓冲区,count数据长度,ppos 文件偏移量    //设备写入时的操作......    /*调用内核接口函数    unsigned  long copy_to_user(void *to, const void *from, unsigned long count);   */    copy_to_user(buff,  cbuff , count);    printk("user  read data from driver\n");    return  count;}//write方法完成将数据从应用程序拷贝到内核空间static int my_write(struct file *file,const char *buff,size_t count,loff_t *ppos ){    //设备写入时的操作......     copy_from_user(cbuf,  buff , count);     cbuff[0]++;     printk("user write data to driver \n");    return  count;}/*ioctl方法主要用于对设备进行读写之外的其他控制,比如配置设备,进入或者退出某种操作模式,这些操作无法通过read/write文件操作来完成,*/static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg){    switch (cmd) {        case 1:            printk("----------------------1\n");            break;        case 2:           printk("------------------------2\n");            break;    }    return 0;}//函数结构体struct file_operations my_fops = {    .open = my_open,    .release = my_release,    .read = my_read,    .write = my_write,   .unlocked_ioctl = my_ioctl,    //对文件操作结构体成员定义初始值};//模块初始化int my_major =555 ;int my_minor =0 ;dev_t  dev =0 ;struct class *myclass;static int my_init(void){   /****************设备号初始化***********************************/   int result;  /*字符设备号 静态注册   dev = MKDEV(my_major, minor);//把主次设备号转换成dev_t类型数据      result = register_chrdev_region(dev , 1, "mydevice");    if (result < 0) {        printk("register_chrdev_region error\n");        return ret;    }*//***************************************************************//*字符设备号动态注册  result = alloc_chrdev_region(&dev,0,1,"mydevice");   //dev是输出量,得到主次设备号放入dev中,0表次设备号,连续分配1个,名字叫mydevice   if (result < 0) {        printk("alloc_chrdev_regionerror\n");        return result ;    }    my_major = MAJOR(dev);//得到主设备号    my_minor = MINOR(dev);//得到次设备号*********************************************************/  /*字符设备静态注册  int  error; //dev上面已经得到了该值,my_fops为上面的函数结构体 cdevt_init(&dev,  &my_fops); cdev->owner = THIS_MODULE; //cdev->ops = &my_fops; error = cdev_add(&cdev, dev, 1);*//*********************************************************struct cdev *my_cdev = cdev_alloc();//动态分配内存空间my_cdev->ops = &my_fops;my_cdev->owner = THIS_MODULE;intcdev_add(my_cdev,dev,1);*//*********************************************************/*自动创建设备节点myclass = class_create(THIS_MODULE, "myclass");//创建设备类if(IS_ERR(myclass)){   printk();   return -1;  }device_create(myclass, NULL, dev , NULL, "mydevice%d",1)//创建设备节点为mydevice1,函数后面为格式化打印*/return 0; }static void my_exit(void){//删除设备文件//注销设备   device_distroy(myclass,dev);   class_distroy(myclass);   cdev_del(&cdev);   unregister_chrdev_region(dev, 1);    printk("unregister_chrdev_regionexit\n");    printk("good-bye,kernel!!\n");}

举例说明应用层调用到内核
1、设备节点和设备文件同时存在才能打开

0 0
原创粉丝点击