首页 > 代码库 > 字符设备驱动程序

字符设备驱动程序

在内核中,dev_t类型用来保存设备编号——包括主设备号和次设备号。
内核内部使用struct cdev结构来表示字符设备。

根据设备编号获取主设备号和次设备号

MAJOR(dev_t dev);			//获取主设备号
MINOR(dev_t dev);			//获取次设备号

根据主设备号和次设备号得到设备编号

MKDEV(int major, int minor);

分配和释放设备编号

int register_chrdev_region(dev_t from, unsigned count, const char *name);
/*
 *	在主设备号确定的情况下使用
 *from:		要分配的设备编号范围的起始值,主要是有一个确定的主设备号,次设备号一般为0。
 *count:	所请求的连续设备编号的个数(次设备号的个数)
 *name:		将出现在/proc/devices和sysfs中
 */
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
/*
 *	动态分配主设备号
 *dev:		输出参数,将动态分配好的首个设备号返回。
 *baseminor:	第一个次设备号的编号,一般为0。
 */
void unregister_chrdev_region(dev_t from, unsigned count);

inode数据结构中有类型为dev_t的i_rdev字段,当inode指向的是设备文件时,它描述的是设备编号。
从inode数据结构中获得主设备号和次设备号

unsigned int iminor(struct inode* inode);
unsigned int imajor(struct inode* inode);

字符设备的注册

struct cdev *cdev_alloc(void);		                    //函数原型
struct cdev *my_cdev = cdev_alloc();
my_cdev->owner = THIS_MODULE;

void cdev_init(struct cdev *cdev, struct file_operation * fops);	//函数原型
my_cdev->ops = &my_fops;  或者: cdev_init(my_cdev, &my_fops);

int cdev_add(struct cdev* cdev, dev_t num, unsigned int count);		//函数原型
/*
 *count:	是应该和该设备关联的设备编号的数量,常取1.
 */
cdev_add(my_cdev, devno, 1);

void cdev_del(struct cdev *dev);		              //函数原型
cdev_del(my_cdev);

早期的接口
注册字符设备驱动程序的接口

int register_chardev(unsigned int major, const char *name, struct file_operation *fops);	//函数原型
/*
 *major:	设备的主设备号。
 *name:		驱动程序的名称,出现在/proc/devices中
 */
实现方法:
{
  __register_chrdev(major, 0, 256, name, fops);{		//major, baseminor, count, name, fops
    __register_chrdev_region(major, baseminor, count, name);{
      //注册设备编号,若传入的major为0,则自动分配
    }
    cdev = cdev_alloc();
    cdev->owner = fops->owner;
    cdev->ops = fops;
    cdev_add(cdev, MKDEV(cd->major, baseminor), count);
  }
}

移除设备驱动程序的接口

int unregister_chrdev(unsigned int major, const char *name);		//函数原型
实现方法:
{
  __unregister_chrdev(major, 0, 256, name);{
    __unregister_chrdev_region(major, baseminor, count);{
      //释放前面分配设备编号时申请的空间。
    }
    cdev_del(cd->cdev);
  }
}

  

字符设备驱动程序