您的位置:首页 > 其它

字符设备驱动程序的设计

2016-01-22 17:27 190 查看
【字符设备驱动程序的组成】

字符设备驱动程序包含5个部分:头文件、file_operation结构体变量、接口函数、加载函数以及卸载函数。

头文件的部分包含进数据结构以及内核函数要用到的头文件。file_operation结构体变量部分定义file_operation结构体的变量,该结构体声明了驱动程序所有的接口函数。接口函数部分包含字符驱动设备驱动程序与内核应用程序交互的read()函数、write()函数、open()函数、ioctl()函数、relase()函数。加载函数用于加载驱动程序至内核,卸载函数用于从内核卸载驱动程序。

【file_operation结构体变量】

用户进程利用系统调用在对设备文件进行诸如read()、write()等操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取file_operation结构体变量相应的函数指针,接着把控制权交给该函数。一个字符设备驱动设备即是file_operation结构体的一个变量。、,字符设备驱动程序中应该首先定义该结构体的变量,定义该结构体的方法如下:

static struct file_operation XXX_fops={

owner: THIS_MODULE,

write: XXX_write,

read: XXX_read;

ioctl: XXX_ioctl;

open:
XXXX_open,

release: XXX_release,

};

以上定义了名为XXX_ops的file_operation结构体变量,的部分成员并对其中用XXX_write、XXX_read、XXX_ioctl、XXXX_open、XXX_release进行初始化。XXX_write、XXX_read、XXX_ioctl、XXXX_open、XXX_release函数分别对应XXX_ops的一个接口函数,他们构成了字符驱动程序的主体。

PS:XXX可以随意指定,一般用设备文件名。

【字符设备驱动的加载函数和卸载函数】

加载函数调用驱动注册函数实现驱动程序在内核中的注册,同时还有可能对设备进行初始化,在驱动程序加载时被调用:卸载函数调用解除注册函数实现驱动程序在内核中的解除注册,在驱动程序卸载时被调用。示例代码如下:

/*加载函数的示例代码*/

static int _init XXX_init(void)

{

/*the codefor registing driver*/

return 0;

}

static void _exit XXX_exit(void)

{

/*thecode for canseling to regist driver*/

}

/*指定加载函数和卸载函数*/

module_init(XXX_init);

module_exit(XXX_exit);

【字符设备驱动程序的接口函数】

read()函数

read()函数从设备端口读取数据,并将这些数据从内核空间复制到用户空间,其示例代码如下:

staticssize_t
XXX_read(struct file *filp,char*buffer,size_t count,loff_t
*ppos)

{

//从设备读取数据

//从内核空间复制到用户空间

//返回读取的字节数

};

write()函数

write()函数从用户空间接收数据,将这些数据复制到内核空间,然后进一步写到设备端口,其示例代码如下:

staticssize_t XXX_write( struct file *filp,const char *buffer,size_t count)

{

//从用户空间复制数据到内核空间

//写数据到设备

//返回写入的字节数

};

ioctl()函数

iotcl()函数实现不能由read()和write()实现的设备功能,其示例代码如下:

staticint XXX_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsignedlong arg)

{

switch(cmd){

case 1:

//命令为1时的处理代码

Break;

case 2:

//命令为2时的处理代码

Break;

case 3:

//错误命令的处理代码

Break;

}

return 0;

}

open()函数

open()函数使用MOD_INC_USE_COUNT宏增加打开驱动程序打开的次数,以防止还有设备打开时卸载驱动程序,如果没有在加载函数中进行设备的初始化,而且是第一次打开设备,则需要进行设备的初始化,其示例代码如下:

staticint XXX_open(struct inode *inode,struct file *file)

{

MOD_INC_USE_COUNT;

//如果是初次打开该设备,则对设备进行初始化

//驱动使用计数器加1

return0;

};

release()函数

release()函数使用MOD_DEC_USE_COUNT宏减少驱动程序打开的次数,以防止还有设备打开时卸载驱动程序。其示例代码如下:

staticint XXX_release(struct inode *inode,struct file *filp)

{

MOD_DEC_USE_COUNT;

//如果设备不再使用,则关闭设备

//驱动使用计数器减1

return 0;

}

MOD_DEC_USE_COUNT和MOD_INC_USE_COUNT必须成对出现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: