linux简单的字符设备驱动程序

要求:掌握添加设备驱动程序的方法内容:采用模块方法,添加一个新的设备驱动程序。要求添加字符设备的驱动。

编写一个应用程序,测试添加的驱动程序。

linxu系统中,在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:

对设备初始化和释放.

把数据从内核传送到硬件和从硬件读取数据.

读取应用程序传送给设备文件的数据和回送应用程序请求的数据.

检测和处理设备出现的错误.

设备分为两种:字符设备和块设备,这里就以简单的字符设备为例。

在设备驱动程序中有一个非常重要的结构file_operations,该结构的每个域都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。

struct file_operations {

int(*seek) (struct inode * ,structfile *, off_t ,int);int (*read) (struct inode * ,structfile *, char ,int);int (*write) (struct inode * ,structfile *, off_t ,int);

……

}

编写设备驱动程序的主要工作是编写子函数,并填充file_operations的各个域。

例如:

Structfile_operations my_fops={

.read=my_read,

.write=my_write,

.open=my_open,

.release=my_release

}

然后再定义函数my_read,my_write,my_open,my_release相应的函数体。

例如:

staticssize_t my_open(struct inode *inode,struct file *file){

staticint counter=0;

if(Device_Open)

return-EBUSY;

Device_Open++;

/*写入设备的信息*/

sprintf(msg,"the device hasbeen called %d times\n",counter++);

msg_ptr=msg;

return0;

}

同时对于可卸载的内核模块(LKM),至少还有两个基本的模块:

my_init用于注册设备,获得设备的主设备号

调用register_chrdev(0,“sky_driver(设备名)”,&my_fops);

my_exit用于注销设备

调用unregister_chrdev(my_major,“sky_driver(设备名)”);

然后在程序尾再调用这两个函数

Module_init(my_init);

Module_exit(my_exit)

MODULE_LICENSE(“GPL”);

不过如果使用特殊函数名

init_module 和cleanup_module,

就不用在程序最后加上上面那三行代码了。

废话少说,以下是实验过程:

首先编写驱动程序。

将后面附上的3个源程序放在一个文件夹中后(也可直接打包下载),开始进行实验:1.编译驱动程序。

在控制台下进入文件所在目录,输入命令make。如图:

看到了吗?提示错误。原来需要用超级用户权限。

没有错误提示,说明make成功,进入文件夹下可以看到多了一些.k,.ko之类的文件。这就是编译好的模块。

2. 装载模块。

同样,必须要是root下才能进行。装载前,我们可以先看看系统中的模块:lsmod

装载,输入命令: insmod devDrv.ko

完成后,再看看系统中的模块,发现多了一个模块“devDrv”,表示我们成功加载了!

可以用命令查看系统日志信息:dmesg

看到如下信息:

这正是在我们的驱动程序中注册函数输出的内容哦!

3.分配次设备号。每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们.设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序.。

分配前,我们必须要知道主设备号(其实在上一步中我们从dmesg中已经看到主设备好为250): cat /proc/devices

可见到这一行:250 myDevice,是了,主设备号为250.

现在我们分配从设备号:mknod /dev/myDevice c 250 0

实际上就是在虚拟文件夹/dev/中加一个设备(在系统看来是文件)myDevice ,注意,这个是设备名,在测试文件中真是要利用这个设备名打开设备。最后的0表示从设备号。可以随便分配(只要不冲突)。

此后便可以在/dev/目录下看到新建的设备myDevice了:ls /dev/

一切成功的话,就可以测试我们的驱动程序啦!

4.测试驱动程序。

首先要编译测试程序:gcc drvTest.c -o sb

得到sb可执行程序,再执行 :./sb

测试程序首先列出所有的设备名,让我们选中一个,当然输入myDevice啦:

正确读出之前存放在设备中的字符串!然后提示让我们输入一个字符串,随便啦:

最后是不是正确保存、读出了呢?of course !而且还告诉我们调用了几次这个设备呢!

5.删除设备、模块。首先删除设备。就像删除普通文件一样:rm /dev/myDevice

删除后,看看/dev/目录下是佛已经木有myDevice 啦?:ls /dev/

接着删除模块:rmmod devDrv.

看看模块列表中是否已经没有devDrv模块了?:lsmod

每个人在他的人生发轫之初,总有一段时光,

linux简单的字符设备驱动程序

相关文章:

你感兴趣的文章:

标签云: