By 高焕堂 2011/09/09
[ IT史上最完整、最经典的软件框架开发技术宝典 (上百篇经典文章&eBooks) ]
[Go Back]
天字第一号框架模式与Android/Linux 驱动开发
3. Linux驱动框架:诞生轮胎
3.1 撰写file的子类别,并诞生其对象(即轮胎)
编写驱动模块的程序代码:adder_module.c档案。
<引入标头档>
在撰写驱动程序时,必须先# include 一些标头档(Head File):
#include <linux/module.h>
#include <linux/fcntl.h>
#include <linux/semaphore.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
<定义子类别:add_file>
兹定义如下:
struct add_file {
int data[2];
struct file* common;
struct semaphore sem;
};
由于C程序代码并没有类别机制,所以运用指标来指向父类别的对象,如指令:
struct file* common;
这个common指标就是用来指向父类别(即file类别)的对象,它是在驱动模块初始化时由 Linux自动诞生的。
<诞生add_file的物件>
struct add_file adder;
这拿 add_file子类别来诞生一个对象,名称为:adder。这个对象是以静态(static)方式宣告的,会在驱动模块加载时刻(loading time)诞生出来。
3.2 撰写子类别的函数,来实作(implement)接口
<撰写add_file的函数>
int add_open(struct inode *inode, struct file *filp){
filp->private_data = &adder;
adder.common = filp;
return 0;
}
ssize_t add_access(int access_dir, struct file *filp, char __user *buf, size_t count){
int *data = filp->private_data->data;
ssize_t retval = 0;
if(down_interruptible(&device->sem)) return -ERESTARTSYS;
if(access_dir == 0) {
int sum = data[0] + data[1];
if(count != sizeof(int)) goto out;
retval = copy_to_user(buf, &sum, sizeof(int));
}
else {
if(count != sizeof(int) * 2) goto out;
retval = copy_from_user(data, buf, count);
}
if(retval) {
retval = -EFAULT;
goto out;
}
out:
up(&adder.sem);
return retval;
}
int add_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){
return add_access(0, filp, buf, count);
}
int add_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){
return add_access(1, filp, (char __user *)buf, count);
}
int add_release(struct inode *inode, struct file *filp){
return 0;
}
这些都是为了来实作file_operations接口里的抽象函数。
<诞生file_operations的物件:fop物件>
struct file_operations fop={
.owner = THIS_MODULE,
.open = add_open,
.read = add_read,
.write = add_write,
.release = add_release,
};
这个file_operations类别只定义了函数,而没有定义数据项(data item),这相当于C++的纯粹抽象类别(pure abstract class),也相当于Java的接口(Interface)定义。这个对象也是以静态(static)方式宣告的,会在驱动模块加载时刻(loading time)诞生出来。就在fop对象诞生时刻,让fop接口的函数连结add_file子类别的函数,就体现了:add_file子类别实作(implement)了file抽象类别的抽象函数(定义于file父类别的file_opeartions接口里)。[歡迎光臨 高煥堂 網頁:http://www.cnblogs.com/myEIT/ ]
刚才说过了,在OO概念里,接口就相当于纯粹抽象类别,所以上图6里的小圆圈(就是接口的符号),也能以类别图形来表示,如下图:

图8、由add_file子类别实作file_operations接口
现在已经定义及诞生了轮胎(即adder对象)。但是还不能用,因为还有装配到汽车、没有连结到引擎。于是,我们需要将轮胎装配到汽车上。此时,可以运用GoF的Factory Method设计模式。
[Go Back]