微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Linux驱动总结3

Linux驱动总结3

时间:12-01 来源:互联网 点击:
学习了驱动程序的设计,感觉在学习驱动的同时学习linux内核,也是很不错的过程哦,做了几个实验,该做一些总结,只有不停的作总结才能印象深刻。

我的平台是虚拟机,fedora14,内核版本为2.6.38.1.其中较之前的版本存在较大的差别,具体的实现已经在上一次总结中给出了。今天主要总结的是ioctl和堵塞读写函数的实现。

一、ioctl函数的实现

首先说明在2.6.36以后ioctl函数已经不再存在了,而是用unlocked_ioctl和compat_ioctl两个函数实现以前版本的ioctl函数。同时在参数方面也发生了一定程度的改变,去除了原来ioctl中的struct inode参数,同时改变了返回值。

但是驱动设计过程中存在的问题变化并不是很大,同样在应用程序设计中我们还是采用ioctl实现访问,而并不是unlocked_ioctl函数,因此我们还可以称之为ioctl函数的实现。

ioctl函数的实现主要是用来实现具体的硬件控制,采用相应的命令控制硬件的具体操作,这样就能使得硬件的操作不再是单调的读写操作。使得硬件的使用更加的方便。

ioctl函数实现主要包括两个部分,首先是命令的定义,然后才是ioctl函数的实现,命令的定义是采用一定的规则。

ioctl的命令主要用于应用程序通过该命令操作具体的硬件设备,实现具体的操作,在驱动中主要是对命令进行解析,通过switch-case语句实现不同命令的控制,进而实现不同的硬件操作。

ioctl函数的命令定义方法:

int (*unlocked_ioctl)(struct file*filp,unsigned int cmd,unsigned long arg)

虽然其中没有指针的参数,但是通常采用arg传递指针参数。cmd是一个命令。每一个命令由一个整形数据构成(32bits),将一个命令分成四部分,每一部分实现具体的配置,设备类型(幻数)8bits,方向2bits,序号8bits,数据大小13/14bits。命令的实现实质上就是通过简单的移位操作,将各个部分组合起来而已。

一个命令的分布的大概情况如下:

|---方向位(31-30)|----数据长度(29-16)----------------|---------设备类型(15-8)------|----------序号(7-0)----------|

|----------------------------------------------------------------------------------------------------------------------------------------|

其中方向位主要是表示对设备的操作,比如读设备,写设备等操作以及读写设备等都具有一定的方向,2个bits只有4种方向。

数据长度表示每一次操作(读、写)数据的大小,一般而已每一个命令对应的数据大小都是一个固定的值,不会经常改变,14bits说明可以选择的数据长度最大为16k。

设备类型类似于主设备号(由于8bits,刚好组成一个字节,因此经常采用字符作为幻数,表示某一类设备的命令),用来区别不同的命令类型,也就是特定的设备类型对应特定的设备。序号主要是这一类命令中的具体某一个,类似于次设备号(256个命令),也就是一个设备支持的命令多达256个。

同时在内核中也存在具体的宏用来定义命令以及解析命令。

但是大部分的宏都只是定义具体的方向,其他的都需要设计者定义。

主要的宏如下:

#include

_IO(type,nr) 表示定义一个没有方向的命令,

_IOR(type,nr,size) 表示定义一个类型为type,序号为nr,数据大小为size的读命令

_IOW(type,nr,size) 表示定义一个类型为type,序号为nr,数据大小为size的写命令

_IOWR(type,nr,size) 表示定义一个类型为type,序号为nr,数据大小为size的写读命令

通常的type可采用某一个字母或者数字作为设备命令类型。

是实际运用中通常采用如下的方法定义一个具体的命令:

//头文件

#include

/*定义一系列的命令*/

/*幻数,主要用于表示类型*/

#define MAGIC_NUM k

/*打印命令*/

#define MEMDEV_PRINTF _IO(MAGIC_NUM,1)

/*从设备读一个int数据*/

#define MEMDEV_READ _IOR(MAGIC_NUM,2,int)

/*往设备写一个int数据*/

#define MEMDEV_WRITE _IOW(MAGIC_NUM,3,int)

/*最大的序列号*/

#define MEM_MAX_CMD 3

还有对命令进行解析的宏,用来确定具体命令的四个部分(方向,大小,类型,序号)具体如下所示:

/*确定命令的方向*/

_IOC_DIR(nr)

/*确定命令的类型*/

_IOC_TYPE(nr)

/*确定命令的序号*/

_IOC_NR(nr)

/*确定命令的大小*/

_IOC_SIZE(nr)

上面的几个宏可以用来命令,实现命令正确性的检查。

ioctl的实现过程主要包括如下的过程:

1、命令的检测

2、指针参数的检测

3、命令的控制switch-case语句

1、命令的检测主要包括类型的检查,数据大小,序号的检测,通过结合

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top