當前位置:歷史故事大全網 - 故事大全 - 什么是linux 平台驱动开发

什么是linux 平台驱动开发

在学习之前一直对驱动开发非常的陌生,感觉有点神秘。不知道驱动开发和普通的程序开发到底有什么不同;它的基本框架又考虑的;他的开发环境有什么特殊的 地方;以及怎么写编写一个简单的字符设备驱动前编译加载,下面我就针对这些问题一个一个的介绍。

一、驱动的基本框架

1. 那么什么是驱动程序,它有什么用呢:

l驱动是硬件设备与应用程序之间的一个中间软件层

l它使得现在某个特定的硬件能够能够 响应一个定义了良好的内部编程接口,同时完全了设备的工作细节

l 用户通过一组与具体设备无关的标准化的调用来完成相应的操作

l 驱动程序的任务就是把这些标准化的系统调用映射到具体设备上,以实现实际硬件的特定操作上

驱动程序是内核的一部分,可以使用中断、DMA等操作

l 驱动程序在用户态和内核态之间传送数据

2. Linux驱动的基本框架

3. Linux下设备驱动程序的一般可以分为以下三类

1) 字符设备

a) 所有能够象字节流一样访问的设备都通过字符设备来实现< /p>

b)其中被映射为文件系统中的节点,通常在/dev/目录下面

c)一般要包含open read write close等系统调用的实现

2) 块设备

d) 通常是指磁盘、内存、Flash 等可以承载文件系统的存储设备。

e) 块设备也是通过文件系统来的 访问,与字符设备的区别是:内核管理数据的方式不同

f) 它允许象字符设备以字节流的方式访问,也可以一次传递任意多个字节。< /p>

3) 网络接口设备

g) 通常指的是硬件设备,但有时也可能是软件设备(如回环环回接口),它们由内核中网络子系统组成 驱动,负责发送和接收数据包。

h)它们的数据传送往往不是面向流的,因此很难将它们映射到一个文件系统的节点上。

二 、怎么构建一个驱动的开发环境

因为驱动是要编译进内核的,在启动内核时就会驱动这个硬件设备;或者编译生成一个.o文件,当应用程序需要时再动态加载 进内核空间运行。因此编译任何一个驱动程序都要链接到内核的源码树。所以搭建环境的第一步当然是搭建内核源码树

1. 怎么建内核源码树

a)首先看你的系统有没有树,在你的/lib/modules目录下有内核信息,比如我当前的系统里有两个版本:< /p>

#ls /lib/modules

2.6.15-rc7 2.6.21-1.3194.fc7

查看其源码:

## ll /lib/modules/2.6.15-rc7/build

lrwxrwxrwx 1 root root 27 2008-04-28 19:19 /lib/modules/2.6.15-rc7/build -> / root/xkli/linux-2.6.15-rc7

发现build是一个链接文件,其对应的目录就是源码树的目录。但现在这里目标目录已经是无效的了。

所以得自己重新下载

b)下载并编译源码树

有很多网站上可以下载,但官方网址是:

http://www .kernel.org/pub/linux/kernel/v2.6/

下载后当然就是解压编译了

# tar –xzvf linux-2.6.16.54.tar.gz

#cd linux-2.6.16.54

## make menuconfig(配置内核各选项,如果没有配置就无法下一步编译,这里不要改任何东西)

#make

...

如果编译没有错误。那么恭喜你。

你的开发环境已经搭建好了

三、了解驱动的基本知识

1. 设备号

1) 什么是设备号呢?我们进系统根据现有的设备来讲解就讲清楚了:

#ls -l /dev/

< p>crwxrwxrwx 1 root root 1, 3 2009-05-11 16:36 null

crw-------- 1 root root 4, 0 2009-05-11 16:35 systty

crw-rw-rw- 1 root tty 5, 0 2009-05-11 16:36 tty

crw-rw---- 1 root tty 4, 0 2009-05- 11 16:35 tty0

在日期前面的两个数字(如第一列就是1,3)就是表示的设备号,第一个是主设备号,第二个是从设备号

2) 设备号有什么用呢?

l 传统上,主编号标识设备连续的驱动。 例如, /dev/null 和 /dev/zero 都由驱动 1 来管理,而虚拟控制台和串口终端都由驱动 4 管理

l次编号被内核用来决定引用哪个设备。 依赖你的驱动是如何编写自己的区别

3) 设备号结构类型以及申请方式

l 在内核中,dev_t 类型(在中定义)用于持有设备 编号,对于2.6.0内核,dev_t是32位的数量,12位设置主编号,20位设置次编号。

l能够获得一个dev_t的主次编号或者编号方式:

主要(dev_t dev); //主要

MINOR(dev_t dev);//次要

l但是如果你有主次编号,需要将其转换为一个dev_t,使用:MKDEV(int Major ,int小);

4)如何在程序中分配和释放设备号

在建立一个字符驱动时需要做的第一件事是获取一个或多个设备 编号来使用。 可以达到此功能的函数有两个:

l一个是你自己事先知道设备号的

register_chrdev_region,在中声明:

int register_chrdev_region( dev_t first, unsigned int count, char *name);

first 是你要分配的起始设备编号。 第一个的次编号部分通常是 0,count 是你请求的连续设备编号的总数。 name 是应该连接到这个编号范围的设备的名子; 它会出现在 /proc/devices 和 sysfs 中。

l 第二个是动态分配设备编号

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count , char *name);

使用这个函数,dev只是一个输出的参数,它在函数成功完成时保存你的分配范围的第一个数字。 fisetminor 应当是请求的第一个使用的次编号; 它通常是 0。count 和 name 参数类似于给 request_chrdev_region 的一样。

5) 设备编号的释放

使用

无论您采用哪种方式分配的设备号。

使用之后肯定是要释放的,其方式如下:

void unregister_chrdev_region(dev_t first, unsigned int count);

6)

2. 驱动程序的两个最重要的数据结构

1) file_operation

倒如Character设备scull的一般定义如下:

struct file_operations scull_fops = {

struct file_operations scull_fops = {

p>

.owner = THIS_MODULE,

.llseek = scull_llseek,

.read = scull_read,

.write = scull_write,

.ioctl = scull_ioctl,

.open = scull_open,

.release = scull_release,

};

file_operation也 所谓的设备驱动程序接口定义在,是一个函数指针的集合。 每个打开文件(内部用一个 file 结构来代表)与其自身的函数集合相关连(通过包含一个名为 f_op 的成员,它指向一个 file_operations 结构)。 这些操作大部分负责实现系统调用,因此,命名为 open、read 等等

2) File

定义位于include/fs.h

struct file结构与驱动相关的成员

l mode_t f_mode文件的读写器权限

l loff_t f_pos当前读写器位置

l unsigned int_f_flag文件标志 ,主要进行阻塞/非阻塞型操作时检查

l struct file_operation * f_op文件操作的结构指针

l void * private_data驱动程序一般将其指向已经分配的数据< /p>

l struct dentry* f_dentry 文件对应的目录项结构

3. 字符设备注册

1) 内核在内部使用类型 struct cdev 的结构来代表字符设备。 在内核调用您的设备操作之前,必须编写分配并注册一个或几个这些结构。 有两种方法来分配和初始化这些结构。

如果你想在运行时获得一个独立的cdev结构,可以这样使用:

struct cdev *my_cdev = cdev_alloc ();

my_cdev->ops = &my_fops;

l 如果想将 cdev 结构嵌入一个你自己的设备特定的结构; 你应该使用初始化你已经分配的结构,:

void cdev_init(struct cdev *cdev, struct file_operations *fops);

2) 一旦cdev结构建立,最后的步骤是 把它告诉内核,调用:

int cdev_a

dd(struct cdev *dev, dev_t num, unsigned int count);

说明:dev 是 cdev 结构, num 是这个设备响应的第一个设备号, count 是应该关联到设备的设备号 的数量。 通常计数为 1,但是有多个设备号对应于一个特定的设备的情况。

3) 为从系统去除一个字符设备,调用:

void cdev_del(struct cdev *dev);

4. 打开和发布

  • 上一篇:華研外語英語6級聽力1000題MP3
  • 下一篇:建設工程項目質量管理論文5000字左右
  • copyright 2024歷史故事大全網