QNX 4.25设备驱动程序的编写
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
QNX 4.25 设备驱动程序的编写 摘要介绍实时操作系统 425 下编写设备驱动程序的大体框架、底层细 节以及诸多注意点。 针对使用较为普遍的设备作为较为详细的描述。 关键词驱动程序实时操作系统引言是一个多任务、多用户、分布式、 可嵌入式符合标准的微内核的主流实时操作系统,广泛用于实时性能、开 发灵活性、网络灵活性要求较高的场合,如电信系统、医疗仪器、航空航 天、工业自动化、交通运输、机、信息家电等。 是一个适合软件硬件定制的实时操作系统。 如果你曾经试图在传统的或平台下开发设备驱动程序,那么,下开发 驱动程序一定会让你受宠若惊。 由于的微内核结构,下的系统进程和用户所写的进程没有什么不同, 甚至没有私有的隐藏起来的以至用户不能使用的界面。 正是这种结构给带来了无与伦比的可扩展性,使得在下写驱动程序如 同写其它程序一般方便。 设备驱动程序能够获取普通程序所能获得的任务服务。 在中增加一个新的驱动程序不会影响操作系统其它程序的任何部分, 环境所需的唯一改变是实现地启动新的驱动程序。 当然,我们会遇到形形色色的硬件设备,某些驱动程序可能将以特殊
方式控制设备的存在和配置。 本文只想集中讨论下如何进入、控制设备级的通用硬件,对所有驱动 程序来讲这是一个共性问题。 其中,将对使用较多的设备作较为详细的叙述。 以下是硬件驱动程序的编写。 1 探测硬件首先,需要判断设备是否存在,然后查询该设备的配置例 如,设备基地址、中断号等。 对于某类设备,一般会有一大相应的标准机制来判断其配置。 每块设备的基地址、中断号等是编程必须的资源,例如,常用的及硬 件设备。 对于设备,一般由板上手工跳线设定,不言自明;对于常用的设备, 这些资源会由系统自动分配,特别是添减设备,可能会发生变化。 因此,在驱动程序中能够动态查找这些资源显得比较重要。 对于诸如、、定时卡、板卡这类设备,对照硬件手册编写一些简单的 驱动程序并不困难。 如果有下驱动程序的源码,移值应该更容易一些。 为了实现对总线设备的控制和管理,必须访问设备的配置空间。 配置空间是一容量为 256 字节并具特定纪录结构的地址空间。 该地址空间的结构如图 1 所示。 425 中对应的结构体定义。 范文先生网收集整理每个设备具有唯一的厂商标识和设备标识,这些 信息由硬件手册提供或系统启动时可以看到。
下面一段代码展示了于一个给定的设备如何调用相关的函数、侦测设 备的存在以及系统分配的资源。 其中,标识用来支持和区分具有同样厂商标识和设备标识的几块同样 的设备。 从 0 开始,如果指定为 1,将标识第二块同型号的设备。 本例中,___、_值是研华的-1713 采集卡,可以根据所使用的硬件填 以合适的值。 以根据所使用的硬件填以合适的值。 ___01713 根据具体设备提供对应的厂商标识及设备标识#___013{,;总 线号仅有一条及设备功能号;_;基地址;中断号_=0 标识为零标识第一块此 种型号设备_______,___,_,&,&!=_{"";_;}侦测设备中断_____ ,,___,_, 1, &!=_{""; _;}侦测设备基地址_____,,___,_[2], 1, *&! =_{""; _;}_=__;"",_;""",;_;}注意各种设备的__[],可能不尽相同,需要查看具体的 硬件手册决定。 2 进入硬件一旦获得了系统分配给某个硬件设备的资源信息,就可以 同这个设备进行通信了。 至于如何做取决于需要访问的硬件资源。 21 资源一个进程试图进行操作,必须具有正确的权限等级。 你必须是超及用户,在编译的时候加上适当参数 1,以确何该进程拥 有访问口的权限。 若忽视这一点,该运行进程将获得一个口的权限。 若忽视这一点,该运行进行将获得一个信号,表示一个非法的内存引
用,并结束进程运行。 现在就可以利用、、,,,0 等函数,对基地址加上寄存器偏移量处 的进行操作了。 例如+_,0;此外,对于一些设备,其口是固定、众所皆知的,例如, 一块兼容的设备,并无上述所谓基地址。 通过 030、034、035,可以直接进入这些的控制器。 例如 034,011;035,035&~080;22 存储映射资源某些设备,可以通过 一般的内存操作进入寄存器,这就需要获得内存基地址。 为了能够获进入此类设备的寄存器,需要将其映射到驱动程序虚拟地 址空间。 下的技术资料描述了如何创建一个共享内存对象,然后将这个内存对 象的一段内存映射到卡中,以便能够进入这个设备。 接着上面的代码可以利用*_;__{判断内存基地址;*_;=_"",_,0777;创 建一个共享内存对象==-1{"_";_;}_=0,4096,_|_,_,,__&~0;将内存基地址映 射_==*"";_;}_=_+__&0;;}""",__;__"",_;现在可以使用指针_来进入设备寄 存器了。 例如_[_]=00; 23 中断资源超级用户可以调用__将一个中断处理程序绑 定到一个设备上。 中断处理程序作为一个远程调用,在进程空间运行。 该函数最后一个参数设置数据段。 寄存器为一个特别的内核栈,这不同于数据段。 因此,需要在中断处理程序及其调用的函数中关断栈检查。
大部分系统库中的函数在编译的时候都关断了栈检查,然而,对于需 要使用大量内存的函数可能并非如此。 后者即是那些在中断处理程序中不可调用的函数,如 、。 通过具体函数在线资源的→项进行判断该函数是否可以调用。 如果函数中包括任何自动变量,强烈建议将中断函数放在自身文件中, 然后利用参数-选项编译之。 这样能够告知编译器,使得!=。 任何被中断处理程序修改的变量需要指定为关键字。 中断处理程序的返回值必须为 0;或某个有效的代码号,以此来触发 一个代码从而发送一则消息。 下面总结一个中断处理程序编写时的注意点 ①只能和自己的硬件对 话如,清除设备的中断状态位,千万不要对 8259 中断控制器编程!②使 中断处理程序尽可能的短小。 如果有很多的工作需要做,必须触发一个代理,并且它唤醒一个进程 完成这些工作,以保证其它进程及低优先级的中断正常运行,提高系统的 实时响应能力。 ③中断处理程序不能调用含有内核调用的例程。 ④中断处理程序必须是一个远程调用函数。 ⑤中断处理程序必须在自己的模块中。 ⑥无论程序中其它模块是如何编译的, 包含中断处理程序的模块必须 是利用-和-选项编译。