华清远见系列图书
VxWorks设备驱动开发详解曹桂平 等编著 ISBN 978-7-121-12828-82011年3月出版定价:49.00元16开420 页内 容 提 要Shell是用户与内核进行交互操作的一种接口,是Linux最重要的软件之一。目前最流行的Shell称为bash Shell,bash Shell脚本编程以其简洁、高效而著称,多年来成为Linux程序本书结合作者实际的开发经验,对VxWorks操作系统内部的机制及其各类设备驱动的开发进行了深入的讲解和分析。全书分3篇共11章,第1篇对VxWorks操作系统的主要组件如任务、任务调度、任务间通信、内存管理、中断处理进行了较为细致的分析;其后对很多VxWorks开发者不甚了解的VxWorks内核映像类型以及启动方式和流程进行了详细的说明和解析。第2篇是驱动开发的准备阶段,着重介绍了VxWorks系统下设备驱动的内核层次结构。第3篇作为本书的重点,每章对应一类驱动,结合开发实例,详细而完整地分析了VxWorks下普通字符设备驱动、串口驱动、普通块设备驱动、Flash设备驱动、网络设备驱动以及USB设备驱动的设计和实现。本书面向广大工程技术工作者,既可作为高等院校教师和相关专业学生的教材,又可作为各类培训班的培训教程。前 言VxWorks是较为常用的嵌入式硬实时操作系统,在很多领域都有其应用的身影,然而由于VxWorks操作系统源代码不公开,虽然文档中对各种驱动设计都有说明,但在实际应用中还是会遇到很多问题。本书根据作者工作中的一些驱动经验,结合Wind River提供的一些官方文档和开发环境下的源代码写成,对VxWorks下各种常见设备的驱动都做了比较详细的介绍和分析,可以作为VxWorks下设备驱动设计的指南。另外,对于各种类型的VxWorks启动方式以及映像文件组成进行了较为细致的分析,将澄清VxWorks BSP开发者具有的很多疑问。本书既可作为VxWorks初学者的学习材料,也可作为VxWorks老手的参考资料。本书内容本书分为3篇共11章。第1篇为VxWorks操作系统快速入门篇,共包括3章内容。第1章简单介绍了嵌入式系统,并对VxWorks操作系统的特性进行了简单说明。第2章对VxWorks操作系统的主要组成进行了比较详细的介绍,包括任务、任务调度、任务间通信、内存管理、中断处理。书中内容不是翻译官方的文档,而是结合作者的经验有感而发。第3章对VxWorks内核映像类型以及启动方式进行了详细分析,并对下载方式中使用的bootrom进行了较为深入的分析和介绍,此后对VxWorks操作系统的启动过程进行了梳理。本章将澄清读者对VxWorks启动方面的很多疑问。第2篇为VxWorks设备驱动起步篇,共包括2章内容。第4章讨论了驱动程序的基本功能和结构,对驱动程序中常用的一些策略以及注意事项进行了介绍。第5章介绍了VxWorks设备驱动的内核结构层次,着重对I/O子系统及其维护的三张系统表进行了讨论,并对VxWorks下已有的几个较为常用的驱动以代码示例的方式介绍其使用方法。第3篇为本书的重点,对VxWorks下六大核心设备驱动进行了详细的分析和介绍,六类驱动中每类驱动对应一章内容,故本篇共包括6章内容。第6章开始进入具体设备驱动的设计,本章将从结构层次最简单的普通字符设备驱动开始讲起,以一个SPI接口驱动代码为例,着重讨论了普通字符设备驱动的结构、设计方式和具体实现。第7章对串口驱动设计和实现进行了详细的分析。串口也是字符设备的一种,由于其常用性,VxWorks内核专门提供了TTY中间层来提高串口驱动设计的效率,降低串口驱动设计的复杂度。第8章进入第二大类设备——块设备驱动的设计和实现的分析。我们将从数据结构的知识出发,分析块设备驱动的基本结构,进而讨论其具体实现。VxWorks下块设备驱动工作的方式比较特殊,其使用的阻塞读写方式不同于通用操作系统下的中断读写方式,这与VxWorks特殊的工作环境有关。第9章将对Flash设备驱动进行详细介绍。Flash设备是嵌入式平台上最常见和常用的设备,用以存储操作系统内核映像和用户数据。本章将以VxWorks内核提供的TrueFFS中间层进行展开,分析Flash设备驱动涉及的各个方面。第10章进入第三大类设备——网络设备驱动的设计和实现中。网络设备由于其独特的工作方式,其内核驱动层次不同于其他两类设备(字符设备、块设备),其不属于I/O子系统管理,而是直接工作在内核网络栈的实现下。为了简化网络设备驱动设计的复杂度,VxWorks提供了MUX中间层,在该层次下实现的驱动通常被称为增强型网络驱动。本章同样也是从数据结构的知识出发,以实际项目中使用的网口驱动代码为例,逐步完成对网络设备驱动的设计和实现。第11章分析了USB设备驱动的设计和实现。首先对USB本身进行了详细的介绍,之后对要驱动的对象进行了澄清。一般而言,USB设备驱动指的是对USB主机或者目标机控制器的驱动,这个驱动由于与内核USB栈耦合较紧密,故必须对内核USB栈的实现有很清楚的了解才能成功地完成USB主机控制器的驱动开发。本章首先跟随一个USB类驱动层读数据请求,对请求在内核USB栈中的传递路径进行了跟踪,对路径上调用的关键函数以及使用的数据结构进行了较为详细的分析和介绍,之后以Mass Storage类驱动为例,介绍类驱动的初始化过程,并以UHCI控制器驱动为例,介绍主机控制器驱动的初始化过程,最后总结出了USB主机控制器的驱动结构,给出了驱动中两个中心函数的实现框架。致谢我要感谢我尊敬的慈祥的奶奶,您的勤劳善良将影响我的一生,是您教导我“自成人,方成人”,告诫我要严于律己。同时,我要感谢我的父母,你们鬓角的丝丝白发,早已印入我的心中,成为我奋斗不止的动力。鉴于作者能力有限,不可能对VxWorks下各类驱动中的每一个问题都理解到位,如果发现理解或者分析有误之处,恳请广大读者批评、指正,读者也可通过邮件与作者联系。曹桂平目 录第1篇 VxWorks操作系统快速入门篇 第1章 VxWorks嵌入式操作系统的特点与应用 21.1 嵌入式系统概述 31.1.1 嵌入式系统定义 31.1.2 嵌入式系统组成和特点 31.1.3 嵌入式系统发展趋势 41.1.4 实时操作系统 51.实时操作系统定义 52.实时操作系统的特征 63.实时操作系统的相关概念 61.2 VxWorks操作系统基本特点 71.2.1 操作系统内核结构——微内核和宏内核 71.宏内核 72.微内核 81.2.2 VxWorks内核——高性能的微内核设计 81.2.3 VxWorks开发支持——可裁减的运行软件 81.2.4 VxWorks网络支持——综合的网络工具 91.2.5 VxWorks移植性支持 91.兼容POSIX 1003.1b标准 92.平台的选择 93.方便移植到用户硬件上 91.2.6 VxWorks操作系统选件 101.3 VxWorks操作系统应用范围 101.4 本章小结 11第2章 VxWorks操作系统的基本组件 122.1 VxWorks任务 132.1.1 内核实现基本原理 132.1.2 任务操作函数 152.1.3 深入了解任务栈 192.1.4 任务名长度问题 202.1.5 正确结束任务 212.1.6 任务的钩子函数——黑客机制 232.1.7 任务小结 252.2 VxWorks任务调度算法——基于优先级的抢占式调度 262.3 VxWorks任务间通信策略 292.3.1 信号量 302.3.2 消息队列 312.3.3 管道 322.3.4 网络套接字Socket 322.3.5 任务间通信的特殊机制:信号 332.4 VxWorks内存管理——虚拟地址空间支持 332.5 VxWorks中断处理——多层次的中断转移 382.5.1 VxWorks下中断转移过程详解(基于ARM平台) 402.5.2 中断上下文中为何不可调用可引起睡眠的函数 432.6 本章小结 45第3章 VxWorks操作系统启动过程详解 463.1 VxWorks操作系统启动 473.1.1 VxWorks基本启动方式 473.1.2 VxWorks操作系统内存布局 481.非压缩形式 482.压缩形式 483.1.3 下载型启动方式概述 503.1.4 ROM型启动方式概述 533.2 深入理解bootrom——下载启动方式下的“瑞士军刀” 543.2.1 bootrom的构成 553.2.2 bootrom脚本的创建 563.2.3 脚本运行过程分析 563.2.4 bootrom的重定位 603.2.5 RAM中运行的bootrom代码 621.usrInit函数 622.usrRoot函数 653.bootCmdLoop函数 683.2.6 在bootrom中添加用户代码 683.2.7 其他注意事项及说明 693.3 深入VxWorks启动过程 713.3.1 ROM型映像早期启动流程详解 711.romInit函数 712.romStart函数 793.3.2 下载型映像早期启动流程详解 813.3.3 公共启动流程详解 821.usrInit函数分析 832.usrRoot函数分析 843.启动用户代码 893.4 VxWorks BSP文件组成 903.4.1 源文件 913.4.2 头文件 943.4.3 Makefile文件 973.4.4 扩展文件 1003.4.5 说明文件 1003.5 本章小结 100 第2篇 VxWorks设备驱动起步篇第4章 设备驱动 1024.1 设备驱动的功能 1034.2 设备驱动的结构 1034.3 设备驱动的基本特点 1054.3.1 驱动代码执行环境——任务和中断上下文 1054.3.2 设备基本分类 1054.3.3 驱动代码安全性——参数合法性检查 1064.3.4 驱动基本工作模式——轮询和中断 1064.3.5 驱动与硬件数据的交互方式——DMA和直接复制 1074.3.6 其他注意事项——Volatile关键字 1074.4 本章小结 108第5章 VxWorks下设备驱动的内核结构层次 1095.1 认识VxWorks设备驱动内核基本层次 1101.USB设备驱动内核层次 1102.块设备驱动内核层次 1113.字符设备驱动内核层次 1114.网络设备驱动内核层次 1125.2 VxWorks内核驱动基本结构——内核三张表 1145.2.1 系统设备表 1145.2.2 系统驱动表 1165.2.3 系统文件描述符表 1185.2.4 内核三张表之间的联系 1205.3 VxWorks内核驱动支持——“免费的午餐” 1225.3.1 管道虚拟设备驱动支持 1235.3.2 虚拟内存设备驱动支持 1241.虚拟内存设备创建函数 1242.虚拟内存设备使用实例 1255.3.3 ramDisk设备驱动支持 1275.3.4 网络设备(netDrv)高层次驱动支持 1291.netDrv驱动基本工作原理 1292.网络设备节点的创建 1303.netDrv驱动中关键参数的获取 1315.4 VxWorks文件系统支持 1325.4.1 虚拟根文件系统VRFS 1325.4.2 事务型文件系统HRFS 1325.4.3 MS-DOS兼容型文件系统dosFs 1335.4.4 原始文件系统rawFs 1345.4.5 CD-ROM文件系统cdromFs 1355.4.6 只读文件系统ROMFS 1355.4.7 目标机文件系统TSFS 1365.5 添加驱动到VxWorks内核 1361.将驱动代码编入内核映像 1362.注册驱动和创建设备 1375.6 本章小结 138 第3篇 VxWorks之六大核心设备驱动第6章 VxWorks设备驱动之字符设备驱动详解 1406.1 用户请求到字符设备驱动服务函数的传递 1416.2 实例入门:基于SPI接口的串口扩展芯片VK3224驱动实现 1446.3 认识VxWorks字符设备驱动基本数据结构——DEV_HDR结构 1456.4 注册字符设备驱动和创建字符设备节点 1476.5 编写字符设备驱动底层服务函数 1506.5.1 编写字符设备打开函数 1506.5.2 编写字符设备读写函数 1526.5.3 编写字符设备控制函数 1556.5.4 编写字符设备关闭函数 1576.5.5 设备驱动工作模式的选择 1606.5.6 编写字符设备删除函数 1616.6 删除字符设备节点和卸载字符设备驱动 1636.6.1 删除字符设备节点 1636.6.2 卸载字符设备驱动 1646.7 本章小结 165第7章 VxWorks设备驱动之串口驱动详解 1667.1 认识VxWorks内核TTY中间层——串口驱动的基石 1687.1.1 TTY中间层应具备的功能 1687.1.2 基于TTY的串口驱动实现思想 1697.1.3 TTY中间层与底层串口驱动的关系 1717.2 VxWorks内核TTY中间层初始化详解 1717.2.1 ttyDrv函数 1727.2.2 ttyDevCreate函数 1737.2.3 sysSerialHwInit和sysSerialHwInit2函数 1747.2.4 TTY中间层初始化过程小结及注意事项 1747.3 认识VxWorks下串口驱动基本数据结构——SIO_CHAN结构 1767.3.1 内核SIO_CHAN结构定义 1767.3.2 封装SIO_CHAN结构 1787.4 VxWorks串口驱动文件基本构成 1807.5 VxWorks串口驱动内核接口文件sysSerial.c的实现 1831.sysSerial.c模板文件 1842.模板文件函数功能说明 1883.sysSerial.c文件功能小结 1907.6 编写VxWorks串口驱动底层服务函数 1907.6.1 编写串口驱动初始化函数 1917.6.2 编写串口驱动回调函数——arm926UartCallback- Install 1937.6.3 编写串口驱动控制函数——arm926UartIoctl 1957.6.4 编写串口驱动中断处理函数——arm926UartInt 1977.6.5 编写串口驱动启动发送函数——arm926Uart- TxStartup 2007.6.6 编写串口驱动轮询工作模式支持函数 2021.编写发送函数arm926UartPollOutput 2022.编写接收函数arm926UartPollInput 2037.7 再议VxWorks内核TTY中间层 2057.8 本章小结 208第8章 VxWorks设备驱动之块设备驱动详解 2088.1 认识VxWorks块设备驱动内核基本层次 2108.2 VxWorks块设备驱动基石——内核文件系统支持 2118.2.1 rawFs文件系统详解 2111.rawFs文件系统初始化第一步:rawFsInit函数 2122.rawFs文件系统初始化第二步:rawFsDevInit函数 2123.rawFs文件系统使用示例 2144.CBIO中间层浅析 2168.2.2 dosFs文件系统详解 2201.dosFs初始化基本流程 2212.初始化第一步:dosFsLibInit函数 2223.初始化第二步:dosFsDevCreate函数 2234.dosFs文件系统格式化 2255.dosFs文件系统初始化小结 2268.3 认识VxWorks块设备驱动基本数据结构——BLK_DEV结构 2288.3.1 内核BLK_DEV结构定义 2298.3.2 封装BLK_DEV结构 2328.4 VxWorks块设备驱动基本架构 2338.4.1 块设备驱动工作的特点 2338.4.2 基于CBIO中间层的块设备驱动内核层次 2348.4.3 块设备驱动底层函数组成 2348.5 编写VxWorks块设备驱动底层服务函数 2358.5.1 认识ATA(IDE)硬盘结构 2368.5.2 认识硬盘分区 2378.5.3 认识CBIO分区管理层 2398.5.4 编写块设备驱动初始化函数 2418.5.5 编写块设备驱动读设备函数ataBlkRd 2448.5.6 编写块设备驱动写设备函数ataBlkWrt 2458.5.7 编写块设备驱动设备控制函数ataIoctl 2478.5.8 编写块设备驱动设备状态查询函数ataStatus 2488.5.9 编写块设备驱动设备复位函数ataReset 2488.6 本章小结 249第9章 VxWorks设备驱动之Flash设备驱动详解 2499.1 认识Flash设备 2519.1.1 概述 2519.1.2 Flash设备硬件接口的差别 2529.1.3 Flash设备容量和成本 2529.1.4 Flash设备可靠性和耐用性 2529.1.5 Flash设备易用性 2539.1.6 Flash设备软件支持 2539.2 深入Nand Flash设备 2549.3 深入Nor Flash设备 2569.3.1 Nor Flash存储器特点 2569.3.2 Nor Flash命令集BCS / SCS 2569.3.3 Nor Flash接口访问标准 2579.4 认识Flash设备地址问题——驱动“陷阱” 2589.5 VxWorks下Flash设备驱动内核层次详解——认识TrueFFS中间层 2599.6 VxWorks内核TrueFFS中间层初始化详解 2619.7 创建和使用Flash设备 2649.8 认识VxWorks下Flash设备驱动基本架构 2679.9 编写VxWorks下Flash设备驱动Socket层服务函数 2689.9.1 Socket驱动层文件构成 2689.9.2 Socket驱动层实现示例 2699.9.3 Socket层实现小结 2799.10 编写VxWorks下Flash设备驱动MTD层服务函数 2859.10.1 tffsConfig.c文件——Flash设备驱动初始化入口 2869.10.2 tffsMtd.c文件——Flash设备驱动MTD层服务函数所在地 2899.10.2.1 编写Flash设备识别函数 2899.10.2.2 编写Flash设备读函数 2929.10.2.3 编写Flash设备写函数 2939.10.2.4 编写Flash设备块擦除函数 2969.10.2.5 编写Flash设备地址映射函数 2979.11 本章小结 297第10章 VxWorks设备驱动之网络设备驱动详解 29810.1 VxWorks下网络设备驱动内核基本层次——认识MUX接口层 30010.1.1 网络设备驱动的基本特点 30010.1.2 网络设备驱动内核层次 30110.1.3 认识MUX中间层 30210.2 认识VxWorks网络设备驱动基本数据结构——END_OBJ结构 30410.3 实例介绍:基于TMS320D-M6446平台的EMAC网口驱动 30510.4 定义VxWorks网络设备驱动自定义结构——“信息集中地” 31010.5 VxWorks网络设备驱动加载与启动 31110.5.1 网络设备驱动初始化基本流程 31110.5.2 修改configNet.h文件 31310.5.3 网络设备驱动加载函数armload的实现 31410.5.4 网络设备驱动启动函数armStart的实现 31910.6 VxWorks网络设备驱动数据帧后台处理支持:netJobAdd 32010.7 编写VxWorks网络设备驱动数据帧接收函数 32310.7.1 编写数据帧接收“下半部分”入口函数 32310.7.2 VxWorks内核网络栈对数据帧的封装要求 32410.7.3 网络数据帧处理和上传 33010.7.4 再议网络数据帧的接收 33210.8 编写VxWorks网络设备驱动数据帧发送函数 33310.9 编写VxWorks网络设备控制函数 33710.10 编写VxWorks网络设备驱动查询模式支持函数 3421.armPollSend函数的实现 3432.armPollRcv函数的实现 34410.11 编写VxWorks网络设备停止和卸载函数 3451.armStop函数的实现 3462.armUnload函数的实现 34710.12 认识VxWorks网络设备驱动内核支持函数 34710.13 VxWorks网络设备驱动实现小结 34910.14 认识网络设备IP地址和MAC地址 35010.15 VxWorks网络设备驱动对多网口的支持 35110.15.1 修改底层驱动 35210.15.2 修改configNet.h文件 35310.15.3 修改usrNetInit函数 35410.16 本章小结 355第11章 VxWorks设备驱动之USB设备驱动详解 35511.1 USB详解 35711.1.1 USB的定义 35711.1.2 认识USB描述符及其相互关系 3601.驱动描述符(Device Descriptor) 3602.配置描述符(Configuration Descriptor) 3603.接口描述符(Interface Descriptor) 3614.端点描述符(Endpoint Descriptor) 36211.1.3 USB控制器基本分类 36311.1.4 认识USB硬件接口 36311.2 认识VxWorks下USB设备驱动内核层次和驱动对象 36511.3 示例介绍:UHCI USB主机控制器基本工作原理 36711.3.1 UHCI规范 36711.3.2 UHCI基本工作原理和数据结构 36811.3.3 UHCI控制器驱动原理概述 37111.4 VxWorks下USB设备操作请求内核传递过程详解 37211.4.1 第一层入口函数:usbBulkDevBlkRd 37311.4.2 第二层入口函数:usbBulkCmdExecute 37611.4.3 第三层入口函数:usbdTransfer 38111.4.4 第四层入口函数:urbExecBlock 38311.4.5 第五层入口函数:usbdCoreEntry 38411.4.6 第六层入口函数:fncTransfer 38611.4.7 第七层入口函数:usbHcdIrpSubmit 38811.4.8 第八层入口函数:底层HCD总入口函数 38911.4.9 VxWorks下USB设备操作请求内核传递过程总结 39111.5 VxWorks下USB设备应用层类驱动初始化详解 39211.6 VxWorks下USB控制器驱动初始化详解 39711.7 VxWorks下USB控制器驱动架构 40211.8 编写VxWorks下USB控制器驱动底层服务函数 40311.8.1 编写USB操作请求总入口函数 40311.8.2 编写USB控制器驱动中断处理函数 40411.8.3 编写USB控制器驱动具体服务函数 40811.9 本章小结 408参考文献 409