Linux字符设备驱动

/*Linux字符设备驱动源代码scdd.c*/

#include <linux/init.h>   /*模块头文件*/

#include <linux/module.h>

#include <linux/types.h>  /*dev_t头文件*/

#include <linux/kdev_t.h> /*MAJOR和MINOR宏头文件*/

#include <linux/fs.h>     /*register_chrdev_region等函数

                                                 file_operations结构体*/

#include <linux/cdev.h>   /*struct cdev结构体*/

#include <asm/uaccess.h>  /*copy_to_user函数*/

 

#define DEVICE_NAME "scdd"  /*定义设备名*/

#define DEVICE_MAJOR 250

 

struct cdev my_cdev;

 

int scdd_open(struct inode *inode,structfile *filp)

{

       return0;

}

int scdd_close(struct inode *inode,structfile *filp)

{

       return0;

}

ssize_t scdd_read(struct file *filp,char__user *buff,size_t size,loff_t *offp)

{

       intleft;

       chardata=1;

      

       for(left=size;left>0;left--)

       {

              /*拷贝数据到用户空间*/

              copy_to_user(buff,&data,1);

              buff++;

       }

       returnsize;

}

ssize_t scdd_write(struct file *filp,char__user *buff,size_t size,loff_t *offp)

{

       return0;

}

/*file_operations结构体*/

struct file_operations scdd_fops={

       .owner=THIS_MODULE,

       .read=scdd_read,

       .write=scdd_write,

       .open=scdd_open,

       .release=scdd_close,

};

static int __init scdd_init(void)

{     /*模块初始化函数*/

       intsmajor;

       smajor=DEVICE_MAJOR;

       dev_tdev_n=MKDEV(smajor,0);

       /*申请设备号*/

       if(!register_chrdev_region(dev_n,1,DEVICE_NAME))

       {     /*静态申请*/

              printk("registersuccess\n");

       }else

       {

              gotoregister_error;

       }

       /*else

       {     /*动态申请*/

              /*alloc_chrdev_region(&dev_n,0,1,DEVICE_NAME);

              smajor=MAJOR(dev_n);

       }*/

      

       /*初始化cdev结构体*/

       cdev_init(&my_cdev,&scdd_fops);

       my_cdev.owner=THIS_MODULE;

       my_cdev.ops=&scdd_fops;

      

       /*注册字符设备*/

       cdev_add(&my_cdev,dev_n,1);

       return0;

      

register_error:

       unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);

       return0;

}

static void __exit scdd_exit(void)

{     /*模块卸载函数*/

       cdev_del(&my_cdev);

       unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);

}

 

module_init(scdd_init);

module_exit(scdd_exit);

MODULE_LICENSE("Dual BSD/GPL");


这个程序只是简单演示字符注册的一个完整过程,并不带有复杂的操作,调用read时向用户空间写全1

相关推荐