字符设备驱动

一、字符设备注册

内核在内部使用类型  struct cdev  的结构来代表字符设备. 

在内核调用你的设备操作前, 你需要编写分配并注册一个或几个这样的结构. 为此, 

你的代码应当包含<linux/cdev.h>, 这个结构和它的关联帮助函数定义在这里.

有 2 种方法来分配和初始化一个这些结构.

1.定义cdev结构并申请内存,然后将其与操作函数指针相关联

struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &my_fops;

2.如果你想将 cdev 结构嵌入一个你自己的设备特定的结构 ,在这种情况下, 你应当初始化你已经分配的结构, 使用:

void cdev_init(struct cdev *cdev, struct file_operations *fops);

一旦 cdev 结构建立, 最后的步骤是把它告诉内核, 调用:

int cdev_add(struct cdev *dev, dev_t num, unsigned int count);

这里, dev 是 cdev 结构, num 是这个设备响应的第一个设备号, count 是应当关联到设备的设备号的数目. 

常常 count 是 1, 但是有多个设备号对应于一个特定的设备的情形.

例如, 设想 SCSI 磁带驱动, 它允许用户空间来选择操作模式(例如密度), 通过安排多个次编号给每一个物理设备。

调用可能失败. 它返回一个负的错误码 。这时需要做错误处理,为从系统去除一个字符设备, 调用:

void cdev_del(struct cdev *dev);

通常我们使用一个   set_cdev 函数来完成 cdev 的初始化和注册,eg:

static void scull_setup_cdev(struct scull_dev *dev, int index)
{
int err, devno = MKDEV(scull_major, scull_minor + index);
cdev_init(&dev->cdev, &scull_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &scull_fops;
err = cdev_add (&dev->cdev, devno, 1);
/* Fail gracefully if need be */
if (err)
printk(KERN_NOTICE "Error %d adding scull%d", err, index);
} 

二、设备号申请和注销

int register_chrdev_region(dev_t first, unsigned int count, char *name)
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name)
void unregister_chrdev_region(dev_t first, unsigned int count);

允许驱动分配和释放设备编号的范围的函数. 

register_chrdev_region 应当用在事先知道需要的主编号时; 

对于动态分配, 使用 alloc_chrdev_region 代替.










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值