曙海教育集团论坛Linux专区Linux驱动开发 → 嵌入式Linux操纵系统的驱动步伐开发要点2008-11-28


  共有6970人关注过本帖树形打印

主题:嵌入式Linux操纵系统的驱动步伐开发要点2008-11-28

美女呀,离线,留言给我吧!
wangxinxin
  1楼 个性首页 | 博客 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:青蜂侠 帖子:1393 积分:14038 威望:0 精华:0 注册:2010-11-12 11:08:23
嵌入式Linux操纵系统的驱动步伐开发要点2008-11-28  发帖心情 Post By:2010-11-24 10:39:34

嵌入式Linux操纵系统的驱动步伐开发要点  在操纵系统">Linux操纵系统下有3类主要的设备文件类型:块设备、字符设备和网络设备。这种分类方法可以将控制输入/输出设备的驱动步伐与其他操纵系统软件分离开来。

  字符设备与块设备的主要区别是:在对字符设备发出读/写哀求时,实际的硬件I/O一般紧接着发生。块设备则否则,它利用一块系统内存作为缓冲区,若用户进程对设备的哀求能满意用户的要求,就返回哀求的数据;否则,就调用哀求函数来进行实际的I/O操纵。块设备主要是针对磁盘等慢速设备设计的,以免耗费过多的CPU时间用来等待。网络设备可以通过BSD套接口访问数据。

  每个设备文件都有其文件属性(c/b),体现是字符设备还是块设备。另外每个文件都有2个设备号,第一个是主设备号,标识驱动步伐;第二个是从设备号,标识使用同一个设备驱动步伐的、差别的硬件设备。设备文件的主设备号必须与设备驱动步伐在登记时申请的主设备号一致,否则用户进程将无法访问驱动步伐。

  系统调用时操纵系统内核与应用步伐之间的接口,设备驱动步伐是操纵系统内核与机器硬件之间的接口。设备驱动步伐是内核的一部分,它完成以下功能:

对设备初始化和释放 把数据从内核传送到硬件和从硬件读取数据 读取应用步伐传送给设备文件的数据和回送应用步伐哀求的数据 检测和处理设备出现的错误

  MTD(Memory Technology Device)设备是闪存芯片、小型闪存卡、记忆棒之类的设备,它们在嵌入式设备中的使用正在不绝增加。MTD驱动步伐是在Linux下专门为嵌入式环境开发的新的一类驱动步伐。相对于通例块设备驱动步伐,使用MTD驱动步伐的优点在于他们能更好的支持、管理给予闪存设备,有基于扇区的擦除和读/写操纵的更好的接口。

  驱动步伐结构

  Linux的设备驱动步伐可以分为3个主要组成部分:

  1. 自动配置和初始化子步伐,负责监测所要驱动的硬件设备是否存在和能否正常工作。如果该设备正常,则对这个设备及其相关的设备驱动步伐需要的软件状态进行初始化。这部分驱动步伐仅在初始化时被调用一次。

  2. 服务于I/O哀求的子步伐,又称为驱动步伐的上半部分。调用这部分步伐是由于系统调用的结果。这部分步伐在执行时,系统仍认为是与进行调用的进程属于同一个进程,只是由用户态酿成了核心态,具有进行此系统调用的用户步伐的运行环境,因而可以在其中调用sleep()等与进行运行环境有关的函数。

  3. 中断服务子步伐,又称为驱动步伐的下半部分。在Linux系统中,并不是直接从中断向量表中调用设备驱动步伐的中断服务子步伐,而是由Linux系统来接收硬件中断,再由系统调用中断服务子步伐。中断可以在任何一个进程运行时孕育发生,因而在中断服务步伐被调用时,不克不及依赖于任何进程的状态,也就不克不及调用任何与进程运行环境有关的函数。因为设备驱动步伐一般支持同一类型的若干设备,所以一般在系统调用中断服务子步伐时,都带有一个或多个参数,以唯一标识哀求服务的设备。

  在系统内部,I/O设备的存/取通过一组固定的入口点来进行,这组入口点是由每个设备的驱动步伐提供的。详细到Linux系统,设备驱动步伐所提供的这组入口点由一个文件操纵结构来向系统进行说明。file_operation结构定义于linux/fs.h文件中。

struct file_operation{
int (*lseek)(struct inode *inode, struct file *filp, off_t off, int pos);
int (*read)(struct inode *inode, struct file *filp, char *buf, int count);
int (*write)(struct inode *inode, struct file *filp, const char *buf, int count);
int (*readdir)(struct inode *inode, struct file *filp, struct dirent *dirent, int count);
int (*select)(struct inode *inode, struct file *filp, int sel_type, select_table *wait);
int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned int arg);
int (*mmap)(void);
int (*open)(struct inode *inode, struct file *filp);
int (*release)(struct inode *inode, struct file *filp);
int (*fasync)(struct inode *inode, struct file *filp);
};

  file_operation结构中的成员几乎全部是函数指针,所以实质上就是函数跳转表。每个进程对设备的操纵都会根据major、minor设备号,转换成对file_operation结构的访问。

常用的操纵包括以下几种:

lseek, 移动文件指针的位置,只能用于可以随机存取的设备。 read, 进行读操纵,参数buf为存放读取结果的缓冲区,count为所要读取的数据长度。返回值为负体现读取操纵发生错误;否则,返回实际读取的字节数。对于字符型,要求读取的字节数和返回的实际读取字节数都必须是inode-i_blksize的倍数。 write, 进行写操纵,与read类似 readdir, 取得下一个目录入口点,只有与文件系统相关的设备步伐才使用。 select, 进行选择操纵。如果驱动步伐没有提供select入口,select操纵会认为设备已经准备好进行任何I/O操纵。 ioctl, 进行读、写以外的其他操纵,参数cmd为自定义的命令 mmap, 用于把设备的内容映射到地址空间,一般只有块设备驱动步伐使用 open, 打开设备准备进行I/O操纵。返回0体现打开乐成,返回负数体现失败。如果驱动步伐没有提供open入口,则只要/dev/driver文件存在就认为打开乐成。 release, 即close操纵。

  在用户自己的驱动步伐中,首先要根据驱动步伐的功能,完成file_operation结构中函数实现。不需要的函数接口可以直接在file_operation结构中初始化为NULL。file_operation变量会在驱动步伐初始化时注册到系统内部。当操纵系统对设备操纵时,会调用驱动步伐注册的file_operation结构中的函数指针。

  Linux对中断的处理

  在Linux系统里,对中断的处理是属于系统核心部分,因而如果设别与系统之间以中断方式进行数据交换,就必须把该设备的驱动步伐作为系统核心的一部分。设备驱动步伐通过调用request_irq函数来申请中断,通过free_irq来释放中断。它们被定义为:

#include
int request_irq(unsigned int irq,
void (*handler)(int irq, void dev_id, struct pt_regs *regs),
unsigned long flags,
const char *device,
void *dev_id);
void free_irq(unsigned int irq, void *dev_id);

  参数irq体现所要申请的硬件中断号;handler为向系统登记的中断处理子步伐,中断孕育发生时由系统来调用,调用时所 带参数irq为中断号;dev_id为申请时告诉系统的设备标识;regs为中断发生时的寄存器内容;device为设备名,将会出现在/proc/interrupts文件里;flag是申请时的选项,它决定中断处理步伐的一些特性,其中最重要的是中断处理步伐是快速处理步伐还是慢速处理步伐。快速处理步伐运行时,所有中断都被屏蔽,而慢速处理步伐运行时,除了正在处理的中断外,其他中断都没有被屏蔽。在Linux系统中,中断可以被差别的中断处理步伐共享。

  作为系统核心的一部分,设备驱动步伐在申请和释放内存时不是调用malloc和free,而代之以调用kmalloc和kfree,它们被定义为:

#include
void *kmalloc(unsigned int len, int priority);
void kfree(void *obj);

  参数len为希望申请的字节数;obj为要释放的内存指针;priority为分配内存操纵的优先级,即在没有足够空闲内存时如何操纵,一般用GFP_KERNEL。


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部

返回版面帖子列表

嵌入式Linux操纵系统的驱动步伐开发要点2008-11-28








签名