linux内核驱动模块编写ioctlWord文件下载.docx
《linux内核驱动模块编写ioctlWord文件下载.docx》由会员分享,可在线阅读,更多相关《linux内核驱动模块编写ioctlWord文件下载.docx(18页珍藏版)》请在冰豆网上搜索。
.open=hello_mod_open,
.read=hello_mod_read,
.write=hello_mod_write,
.ioctl=hello_mod_ioctl,
.release=hello_mod_release,
};
这个结构体变量定义好之后我们在模块初始化函数中就可以通过register_chrdev()或者填充cdev结构来关联所有的操作到我们的模块函数了。
和设备交互的数据我们总称为“数据”,但是大致可划分为两种
“功能数据”:
我们要输入设备处理的和设备处理完之后输出的数据。
“控制数据”:
我们用来控制设备特性功能的命令和参数。
open,read,write,release等函数是对一个驱动模块的使用,就是我们对“设备的功能”的使用。
但是一个设备有可能有很多功能,那么我们要怎么控制设备让设备完成指定的功能呢?
据个例子来说:
假如我们有一个翻译机(姑且说机吧,也可能是器)实体设备,主要功能是输入中文,然后可以输出各种语言对应的翻译结果,那这个机的功能就是翻译,我们真正用来处理的数据是我们输入的中文,我们要得到的“设备功能”就是翻译后的输出内容,而各种语言则是我们的选择控制了,我们可设定这个设备翻译成何种语言。
这就要求我们要向设备发送命令,设定目标语言。
请注意我们要发送的是两个“控制数据”,命令和参数。
命令:
一个设备可能有很多种行为,我们的命令就是代表我们要让设备执行何种行为。
“复位”,“设定目标语言”,“获得当前目标语言”等
参数:
对于某一个命令,可能需要参数可能不需要参数。
比如:
“复位”命令就不需要参数。
“设定目标语言”则需要传入目标语言的类型。
“获取目标语言”则需要传入一个能够接收目标语言类型的参数。
自己画了一个设备“数据流”图,希望能加深理解。
对于我们自己的设备我们就要自己定义设备命令了,如果你要想搞清命令的格式,请参考其他资料关于ioctl的参数的介绍。
这里不打算介绍这个,只介绍ioctl实际功能。
定义自己的IO控制命令需要用到宏。
这里直接写出我的定义而不是介绍宏的实现
#defineHELLO_MAGIC
12
#defineHELLO_IOCTL_RESETLANG
_IO(HELLO_MAGIC,0)
//设置复位,这个命令不带参数
#defineHELLO_IOCTL_GETLANG
_IOR(HELLO_MAGIC,1,int)
//获取当前设备的语言类型参数,参数是int型
#defineHELLO_IOCTL_SETLANG
_IOW(HELLO_MAGIC,2,int)
//设置设备的语言类型,参数是int型
多的不说了,下面贴上完整代码,懒人没写注释。
。
不好意思。
hello_mod.c
[cpp]viewplaincopyprint?
/*
*
=====================================================================================
Filename:
hello.c
Description:
hello_mod
Version:
1.0
Created:
01/28/2011
05:
07:
55
PM
Revision:
none
Compiler:
gcc
Author:
Tishion
(shion),
***************
Company:
LIM
*/
#include
<
linux/module.h>
linux/init.h>
linux/kernel.h>
linux/uaccess.h>
linux/semaphore.h>
linux/cdev.h>
linux/device.h>
linux/ioctl.h>
linux/slab.h>
linux/errno.h>
linux/string.h>
"
hello_mod_ioctl.h"
#define
MAJOR_NUM
250
MINOR_NUM
0
IN_BUF_LEN
256
OUT_BUF_LEN
512
MODULE_AUTHOR("
Tishion"
);
MODULE_DESCRIPTION("
Hello_mod
driver
by
tishion"
static
struct
class
hello_class;
cdev
hello_cdev;
dev_t
devnum
=
0;
char
modname
hello_mod"
;
devicename
hello"
classname
hello_class"
int
open_count
semaphore
sem;
spinlock_t
spin
SPIN_LOCK_UNLOCKED;
inbuffer
NULL;
outbuffer
lang_t
langtype;
hello_mod_open(struct
inode
*,
file
*);
hello_mod_release(struct
ssize_t
hello_mod_read(struct
size_t,
loff_t
hello_mod_write(struct
const
hello_mod_ioctl(struct
unsigned
int,
long);
file_operations
hello_mod_fops
{
.owner
THIS_MODULE,
.open
hello_mod_open,
.read
hello_mod_read,
.write
hello_mod_write,
.ioctl
hello_mod_ioctl,
.release
hello_mod_release,
*inode,
*pfile)
printk("
+hello_mod_open()!
/n"
spin_lock(&
spin);
if(open_count)
spin_unlock(&
return
-EBUSY;
}
open_count++;
-hello_mod_open()!
+hello_mod_release()!
open_count--;
-hello_mod_release()!
*pfile,
*user_buf,
size_t
len,
*off)
+hello_mod_read()!
if(down_interruptible(&
sem))
-ERESTARTSYS;
memset(outbuffer,
0,
OUT_BUF_LEN);
+switch()/n"
switch(langtype)
case
english:
>
in
case:
english/n"
sprintf(outbuffer,
Hello!
%s."
inbuffer);
break;
chinese:
chinese/n"
你好!
pinyin:
pinyin/n"
ni
hao!
default:
default/n"
-switch()/n"
if(copy_to_user(user_buf,
outbuffer,
len))
up(&
sem);
-EFAULT;
-hello_mod_read()!
+hello_mod_write()!
if(len
IN_BUF_LEN)
Out
of
input
buffer/n"
if(copy_from_user(inbuffer,
user_buf,
-hello_mod_write()!
cmd,
long
arg)
err
+hello_mod_ioctl()!
switch(cmd)
HELLO_IOCTL_RESETLANG:
HELLO_IOCTL_RESETLANG/n"
langtype
english;
HELLO_IOCTL_GETLANG:
HELLO_IOCTL_GETLANG/n"
copy_to_user((int
*)arg,
&
langtype,
sizeof(int));
HELLO_IOCTL_SETLANG:
HELLO_IOCTL_SETLANG/n"
copy_from_user(&
langtype,(int
ENOTSUPP;
-hello_mod_ioctl()!
err;
__init
hello_mod_init(void)
result;
+hello_mod_init()!
MKDEV(MAJOR_NUM,
MINOR_NUM);
result
register_chrdev_region(devnum,
1,
modname);
if(result
0)
:
can'
t
get
major
number!
cdev_init(&
hello_cdev,
hello_mod_fops);
hello_cdev.owner
THIS_MODULE;
hello_cdev.ops
hello_mod_fops;
cdev_add(&
devnum,
1);
if(result)
Failed
at
cdev_add()"
hello_class
class_create(THIS_MODULE,
classname);
if(IS_ERR(hello_class))
class_create().Please
exec
[mknod]
before
operate
the
device/n"
else
device_create(hello_class,
NULL,
devnum,NULL,
devicename);
(char
*)kmalloc(IN_BUF_LEN,
GFP_KERNEL);
*)kmalloc(OUT_BUF_LEN,
init_MUTEX(&
-hello_mod_init()!
void
__exit
hello_mod_exit(void)
+hello_mod_exit!
kfree(inbuffer);
kfree(outbuffer);
cdev_del(&
hello_cdev);
device_destroy(hello_class,
devnum);
class_destroy(hello_class);
unregister_chrdev_region(devnum,
-hello_mod_exit!
module_init(hello_mod_init);
module_exit(hello_mod_exit);
MODULE_LICENSE("
GPL"
hello_mod_iotcl.h
hello_mod_ioctl.h
define
cmd
supported
Created