linux设备驱动意义,深入浅出Linux设备驱动编程--结构化设备驱动程序

结构化设备驱动程序

在1~9节关于设备驱动的例子中,我们没有考虑设备驱动程序的结构组织问题。实际上,Linux设备驱动的开发者习惯于一套约定俗成的数据结构组织方法和程序框架。

设备结构体

Linux设备驱动程序的编写者喜欢把与某设备相关的所有内容定义为一个设备结构体,其中包括设备驱动涉及的硬件资源、全局软件资源、控制(自旋锁、互斥锁、等待队列、定时器等),在涉及设备的操作时,仅仅操作这个结构体就可以了。

对于“globalvar”设备,这个结构体就是:

struct globalvar_dev

{

int global_var = 0;

struct semaphore sem;

wait_queue_head_t outq;

int flag = 0;

};

open()和release()

一般来说,较规范的open( )通常需要完成下列工作:

1. 检查设备相关错误,如设备尚未准备好等;

2. 如果是第一次打开,则初始化硬件设备;

3. 识别次设备号,如果有必要则更新读写操作的当前位置指针f_ops;

4. 分配和填写要放在file->private_data里的数据结构;

5. 使用计数增1。

release( )的作用正好与open( )相反,通常要完成下列工作:

1. 使用计数减1;

2. 释放在file->private_data中分配的内存;

3. 如果使用计算为0,则关闭设备。

我们使用LDD2中scull_u的例子:

int scull_u_open(struct inode *inode, struct file *filp)

{

Scull_Dev *dev = &scull_u_device; /* device information */

int num = NUM(inode->i_rdev);

if (!filp->private_data && num > 0)

return -ENODEV; /* not devfs: allow 1 device only */

spin_lock(&scull_u_lock);

if (scull_u_count &&

(scull_u_owner != current->uid) &&  /* allow user */

(scull_u_owner != current->euid) && /* allow whoever did su */

!capable(CAP_DAC_OVERRIDE)) { /* still allow root */

spin_unlock(&scull_u_lock);

return -EBUSY;   /* -EPERM would confuse the user */

}

if (scull_u_count == 0)

scull_u_owner = current->uid; /* grab it */

scull_u_count++;

spin_unlock(&scull_u_lock);

/* then, everything else is copied from the bare scull device */

if ( (filp->f_flags & O_ACCMODE) == O_WRONLY)

scull_trim(dev);

if (!filp->private_data)

filp->private_data = dev;

MOD_INC_USE_COUNT;

return 0;          /* success */

}

int scull_u_release(struct inode *inode, struct file *filp)

{

scull_u_count--; /* nothing else */

MOD_DEC_USE_COUNT;

return 0;

}

上面所述为一般意义上的设计规范,应该说是option(可选的)而非强制的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值