嵌入式软件开发导论
同济大学软件学院
2005
7. 设备驱动程序开发
主要内容
概述
流驱动接口
设备驱动程序架构
USB mouse 驱动开发示例
Windows CE 系统服务
什么是设备驱动程序
设备驱动程序是与硬件设备进行通信的系统
程序。一个设备可以是物理设备,也可以是
一个逻辑实体。通常,这些实体需要操作系
统对其进行控制,资源管理。设备驱动程序
就是管理这些物理设备或者虚拟设备,协议
或者系统服务的软件模块。 对于每一个基于
Windows CE的设备,设备驱动程序都是必
不可少。
--译自 MSDN
“一般”驱动程序开发的理解
必须使用汇编语言对端口进行读写
设备驱动程序是操作系统的一部分,难于
开发与调试。
设备驱动程序控制硬件
中断比较难于处理
必须使用汇编语言读写端口
提供 APIs与硬件进行通信
HalGetBusDataHalGetBusData
READ_PORT_UCHARREAD_PORT_UCHAR
WRITE_REGISTER_ULONGWRITE_REGISTER_ULONG
对于逻辑设备驱动程序,采用Win32 APIs
从硬件获取数据
设备驱动程序是操作系统的一
部分,难于开发与调试
对于UNIX或者是 Windows 9x,设备驱动程
序是与操作系统映像连接的,并运行于系
统内核态。
对于windows CE,大多数的设备驱动程序
运行于用户态,简单的来说就是一个DLL
文件。
设备驱动程序控制硬件
大多数的设备驱动程序用来控制硬件。
对于某些硬件,是没有驱动的。
CPUCPU
内存内存
对于虚拟设备驱动程序,没有物理设备。
文件系统驱动程序文件系统驱动程序
RAM diskRAM disk
中断有时难于处理
Windows CE提供逻辑中断 (SYSINTRs)
中断由一个用户态的线程进行处理 (IST)
为什么应当写驱动程序?
当我们设计硬件时,就需要提供这一硬件
的驱动软件。
硬件OEM厂商不提供基于Windows CE的
硬件驱动,但是提供硬件的规格说明。
对于一个现有硬件驱动的功能进行扩展。
驱动分类—整体
Windows CE 整体上将设备驱动分为三种:
内置驱动内置驱动
总线总线
流接口流接口
内置驱动
硬件所必须的驱动程序,这些驱动程序通
常由设计OEM厂商进行设计。
如:键盘,触摸屏,音频设备。
可能不支持一般的驱动接口,也有可能带
有扩展的接口或者完全提供一个用户自定
义的接口。
内置驱动通常需要针对具体的操作系统进
行小幅改动。
总线驱动
管理系统总线如PCI总线等。PCMCIA与
CompactFlash也在其列。
负责处理总线上硬件的询问,以及资源的
分配。
同时也请求设备管理器为总线上的硬件安
装适当驱动程序。
驱动分类 – 详细
Audio DriversAudio Drivers
Battery DriversBattery Drivers
Block DriversBlock Drivers
Bluetooth HCI Transport DriverBluetooth HCI Transport Driver
Direct3D Device Driver InterfaceDirect3D Device Driver Interface
DirectDraw Display DriversDirectDraw Display Drivers
Display DriversDisplay Drivers
DVD-Video RendererDVD-Video Renderer
IEEE 1394 DriversIEEE 1394 Drivers
Keyboard DriversKeyboard Drivers
Notification LED DriversNotification LED Drivers
Parallel Port DriversParallel Port Drivers
PC Card DriversPC Card Drivers
Printer DriversPrinter Drivers
Serial Port DriversSerial Port Drivers
Smart Card DriversSmart Card Drivers
Stream Interface DriversStream Interface Drivers
Touch Screen DriversTouch Screen Drivers
USB DriversUSB Drivers
参见文档:
Driver Development -> Driver Development ->
Driver CategoriesDriver Categories
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
驱动的加载过程
大多数的设备驱动由设备管理器
()进程在系统启动时进行加载。
另一方面,其中一部分内置驱动程序由
进行加载。这些驱动包括显示
器驱动 ()、键盘驱动、鼠标驱动、
触摸屏驱动等。
驱动的加载过程
. 当对设备驱动程序进行安装时
将在注册表的[HKEY_LOCAL_
MACHINE]\Drivers项下检查一个字符串,
其值为 RootKey,传统地,其名字为
BuiltIn 。
. 然后设备管理器在进行初始化时使用注册
信息检查器为它需要安装的各个驱动读取
值为RootKey的键。
驱动的加载过程
驱动的加载过程
. 安装DLL,给每一个驱动创建一个Active 键,
然后调用ActivateDevice 或者
ActivateDeviceEx将DLL注册为系统中的
一个设备驱动程序。
. ActivateDevice在
[HKEY_LOCAL_MACHINE\Drivers\Acti
ve下创建一个新的键值。
驱动的加载过程
驱动加载API
设备驱动程序也能通过应用程序进行手动
的安装,这是ActivateDeviceEx的一个首
选的功能。
安装驱动一个更老的方法是使用
RegisterDevice 与 DeregisterDevice
主要内容
概述
流驱动接口
设备驱动程序架构
USB mouse 驱动开发示例
Windows CE 系统服务
什么是流接口
流接口驱动包括所有提供流接口函数的驱
动程序,不管由这个驱动控制的设备是什
么类型。
典型的流接口驱动程序有:
文件系统驱动文件系统驱动 (iostream, fstream) (iostream, fstream)
COM, LPTCOM, LPT
使用流接口
hSer = CreateFile(TEXT(“COM1:”), GENERIC_READ,
0, NULL, OPEN_EXSITING, 0, NULL);
rc = ReadFile(hSer, &ch, 1, &cBytes, NULL);
TransmitCommChar(hSer, ‘a’);
CloseHandle(hSer);
直接使用Win32文件系统API。
创建一个流驱动程序
. 写一个导出具体流接口的DLL
. 编译设备驱动程序
. 对注册表进行配置
流接口函数
函数名函数名 说明说明
XXX_CloseXXX_Close 关闭以关闭以hOpenContexthOpenContext标识的设备上下文。标识的设备上下文。
XXX_DeinitXXX_Deinit 由设备管理器调用来删除对某一设备的初始化信息。由设备管理器调用来删除对某一设备的初始化信息。
XXX_InitXXX_Init 由设备管理器调用来对某一设备进行初始化。由设备管理器调用来对某一设备进行初始化。
XXX_IOControlXXX_IOControl 向设备发送命令向设备发送命令
XXX_OpenXXX_Open 打开一个设备以进行读、写或者既读又写。当应用调用打开一个设备以进行读、写或者既读又写。当应用调用
CreateFileCreateFile来打开某一个设备文件名时将间接地调用这来打开某一个设备文件名时将间接地调用这
一个函数。一个函数。
XXX_PowerDownXXX_PowerDown 停止向设备供电。只有在软件控制下关机的设备上才可用。停止向设备供电。只有在软件控制下关机的设备上才可用。
XXX_PowerUpXXX_PowerUp 恢复向设备供电恢复向设备供电
XXX_ReadXXX_Read 从设备读取数据从设备读取数据
XXX_SeekXXX_Seek 在设备中移动数据指针在设备中移动数据指针
XXX_WriteXXX_Write 向设备写数据向设备写数据
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
javascript:()
javascript:()
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
mk:@MSITStore:D:\Program Files\Windows CE Platform Builder\\CEPB\help\::/html/
构建设备驱动程序
构建设备驱动程序与构建一个DLL一样简
单。
可以使用Platform Builder与EVC++。只
需创建一个Windows CE DLL项目, 输出
适当 的入口点,然后编写代码。
常犯的一个错误是没有将入口点声明为
extern C,因此 C++编译器就不能处理输
出的函数名。
注册表设置
在 中:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Sample][HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Sample]
"Dll" = "" "Dll" = ""
"Prefix" = "DEM" "Prefix" = "DEM"
"Index" = dword:1 "Index" = dword:1
"Order" = dword:0 "Order" = dword:0
"FriendlyName" = "Demo Driver" "FriendlyName" = "Demo Driver"
"Ioctl" = dword:0 "Ioctl" = dword:0
注册表设置
Order
给所有的驱动设置相对安装顺序。给所有的驱动设置相对安装顺序。Order Order 为为00
的驱动先安装,依次安装的驱动先安装,依次安装OrderOrder为为1,2,…1,2,…的驱的驱
动。动。OderOder可以让开发者保证有相到依赖关系可以让开发者保证有相到依赖关系
的多个驱动以适当的顺序进行安装。的多个驱动以适当的顺序进行安装。
Index
指定在文件系统中的驱动名的数字部分。在默指定在文件系统中的驱动名的数字部分。在默
认情况下,带有前缀认情况下,带有前缀COMCOM的驱动在文件系统的驱动在文件系统
中分配名字为中分配名字为 COM1COM1,,下一个即为下一个即为COM2COM2。。为为
了保证驱动总是安装成了保证驱动总是安装成COM2COM2,,必须提供必须提供
Index = 2Index = 2。。
演示 :
使用emulator编写一个流接口驱动
程序并使用它
驱动是如何工作的
. When CE启动时, 根据注册表中
的设置安装所有的驱动程序。
. 当安装时, 调用
DEM1_Init。
. Application程序调用
CreateFile(“DEM1”…)
驱动是如何工作的(2)
. 处理API调用并切换到
. 调用 的
DEM1_Open。
. CreateFile返回DEM1_Open的retval
设备功能栈
硬件
Windows CE DDK API
设备驱动程序
设备管理器()
应用程序
主要内容
概述
流驱动接口
设备驱动程序架构
USB mouse 驱动开发示例
Windows CE 系统服务
驱动架构
驱动的类型
内置与流安装机制
通常内置驱动程序根据注册键值安装在
GWES进程空间
总线驱动由根据键值进行安装
可安装的流驱动或其它驱动由
根据总线驱动或注册检查器进行安装。
设备管理器
用户级进程继续运行
与内核、注册表交互的单独应用程序,以
及流接口驱动DLL。
提供ActivateDevice 与
DeactivateDevice API。
设备管理器
包括IO资源管理器
安装注册表检查器() ,并由
这一个注册表检查器根据注册表进行驱动
的安装
提供电源通知回调函数
跟踪所有已安装的驱动程序,给设备接口发出跟踪所有已安装的驱动程序,给设备接口发出
拉入或删除的通知拉入或删除的通知
设备管理器
设备驱动程序的安装过程
I/O Resource Manager
(part of )
loadsloads
loadsloads
loadsloads
I/O Resource ManagerI/O Resource Manager
(part of )(part of )
注册表枚举器
注册枚举器是注册枚举器是
根据根据
HKEY_LOCAL_MACHINE\Drivers\RootKeyHKEY_LOCAL_MACHINE\Drivers\RootKey安安
装注册枚举器装注册枚举器
注册枚举器给每一个要安装的驱动程序扫描表项注册枚举器给每一个要安装的驱动程序扫描表项
注册枚举器是可重入的,并支持分级使用注册枚举器是可重入的,并支持分级使用
当注册枚举器卸载时,同时也御载它安装的所有信当注册枚举器卸载时,同时也御载它安装的所有信
息息
注册枚举器根据注册枚举器根据Order,Order,检查紧挨着传给它的键的下检查紧挨着传给它的键的下
一级键值。一级键值。
注册枚举器对每一个找到的子键调用注册枚举器对每一个找到的子键调用
ActivateDeviceExActivateDeviceEx
ActivateDeviceEx
由由提供提供
总线驱动程序当安装设备驱动时调用总线驱动程序当安装设备驱动时调用
ActivateDeviceExActivateDeviceEx
ActivateDeviceExActivateDeviceEx也在也在RAMRAM工作区锁定流接口驱工作区锁定流接口驱
动程序动程序
这可以防止代码页被丢弃这可以防止代码页被丢弃
注册检查器对找到的每一个内置子键调用注册检查器对找到的每一个内置子键调用
ActivateDeviceExActivateDeviceEx
ActivateDeviceExActivateDeviceEx安装驱动并更新注册表安装驱动并更新注册表
接口类
驱动程序的接口有以下特征驱动程序的接口有以下特征
每一个每一个IclassIclass有一个有一个GUIDGUID,,一个名字一个名字
GUIDGUID描述类设备接口描述类设备接口
NameName 描述接口的实例描述接口的实例
COM1:, DSK1: COM1:, DSK1: 等等等等
提供一个驱动接口提供一个驱动接口
在注册表中的在注册表中的IclassIclass子键子键
驱动程序发布接口驱动程序发布接口 – – AdvertiseInterfaceAdvertiseInterface
应用程序访问接口应用程序访问接口 – – RequestDeviceNotificationsRequestDeviceNotifications
每个已有的接口的预定义每个已有的接口的预定义GUIDGUID
A32942B7-920C-486b-B0E6-92A702A99B35 A32942B7-920C-486b-B0E6-92A702A99B35
I/O 资源管理(IORM)
IORM是设备管理器必备的部分
跟踪可用I/O资源 (IRQ与I/O基地址)
OEM为内置设备预分配的资源
当在总线上安装一个客户驱动时,总线驱动
请求资源
ResourceReleaseResourceRelease
ResourceRequestResourceRequest
ResourceCreateListResourceCreateList
当存在冲突时IORM调用
ResourceRequest失败
注册表帮助例程
从注册表中读取资源初始化信息从注册表中读取资源初始化信息
OpenDeviceKeyOpenDeviceKey
DDKReg_GetIsrInfoDDKReg_GetIsrInfo
DDKReg_GetWindowInfoDDKReg_GetWindowInfo
DDKReg_GetPciInfoDDKReg_GetPciInfo
在在COREDLLCOREDLL的的APIAPI
在在<<> and <> and <> > 的函数原型的函数原型
在在public\common\oak\driverspublic\common\oak\drivers中的例子中的例子
wavedev\pdd\es1371\ -> wavedev\pdd\es1371\ ->
GetRegistryConfigGetRegistryConfig
电源管理
电源管理器
灵活的系统级与外设级电源管理灵活的系统级与外设级电源管理
使设备智能化地管理它们的电源使设备智能化地管理它们的电源
在设备与系统或应用之间充当协调者在设备与系统或应用之间充当协调者
使使OEMOEM修改调用修改调用PowerOffSystem()PowerOffSystem()的相关代的相关代
码码
电源管理
系统级电源状态系统级电源状态
设备设备((外设外设))级电源状态级电源状态
打开打开 系统空闲系统空闲
用户空闲用户空闲 挂起挂起
D0 D0 全供电全供电 D3 D3 睡眠睡眠
D1 D1 降级模式降级模式 D4 D4 关闭关闭
D2 D2 备用模式备用模式
电源管理器架构
驱动电源管理器
()
PM
APIs
应用程序
通知消息队列通知消息队列
驱动驱动
APIsAPIs
应用应用APIAPI
物理内存
64 MB64 MB
RAMRAM
32 MB32 MB
FlashFlash
Dbg Serial PortDbg Serial Port
2 G
B
2 G
B
U
ser
U
ser
512 M
B
512 M
B
U
ncached
U
ncached
512 M
B
512 M
B
C
ached
C
ached
64 MB RAM64 MB RAM
32 MB Flash32 MB Flash
64 MB RAM64 MB RAM
32 MB Flash32 MB Flash
物理内存物理内存
内核虚拟地址内核虚拟地址
ReservedReserved
0400000004000000
8200000082000000
8000000080000000
8000000080000000
A0000000A0000000
C0000000C0000000
00
Not UsedNot Used
Slot 0Slot 0
Slot 32Slot 32
64 KB64 KB
32 MB32 MB
64 MB64 MB
2 GB2 GB
3 GB3 GB
4 GB4 GB
Memory mapped filesMemory mapped files
Above 2G-3GAbove 2G-3G
Mapped to physical Mapped to physical
memorymemory
Virtual Virtual
address address
spacespace
Slot 1Slot 1
Slot 32Slot 32
NULL pointers NULL pointers
虚拟地址空间
512M Cached512M Cached
512M Non-Cached512M Non-Cached
0x800000000x80000000
0xA00000000xA0000000
Accessable via Accessable via
MmMapiIoSpaceMmMapiIoSpace
内存管理函数
设备驱动程序是用户态模块
必须将物理内存映射成虚拟内存必须将物理内存映射成虚拟内存
VirtualAlloc, VirtualFree: 预留,释放虚拟
内存
MEM_RESERVEMEM_RESERVE
VirtualCopy: 将一个物理内存区域映射到
一个虚拟内存区域
PAGE_NOCACHEPAGE_NOCACHE
PAGE_PHYSICALPAGE_PHYSICAL
驱动的内存访问与映射
MapPtrToProcess
将一个地址空间的指针映射成另外一个指针将一个地址空间的指针映射成另外一个指针
GetCurrentProcess /
SetProcPermissions
重新找回进程重新找回进程IDID用于用于MapPtrToProcessMapPtrToProcess函数函数
MmMapIoSpace
将一个物理地址空间映射成一个不分页的,由将一个物理地址空间映射成一个不分页的,由
进程决定的地址空间进程决定的地址空间
CEDDK
CE CE 以及后来的版本支持独立于平台的以及后来的版本支持独立于平台的I/OI/O配配
置置
让让OEMOEM以及驱动开发人员使用它们以及驱动开发人员使用它们
总线管理总线管理
内存管理内存管理
I/OI/O管理管理
从从NTDDKNTDDK拿来的拿来的CEDDK APICEDDK API
直到直到以后的版本才有文档以后的版本才有文档
但在大多数但在大多数版中都有版中都有
CEDDK 简介
设备驱动使用设备驱动使用CEDDKCEDDK
正常开发的驱动是跨平正常开发的驱动是跨平
台二进制兼容的台二进制兼容的
跨跨CPUCPU的源代码兼容的源代码兼容
设备管理器设备管理器
设备驱动设备驱动
硬件硬件
CEDDK 内容
部分部分 函示例函示例
总线管理总线管理 HalGetBusDataByOffset()HalGetBusDataByOffset()
HalGetBusData()HalGetBusData()
HalSetBusDataByOffset()HalSetBusDataByOffset()
HalSetBusData()HalSetBusData()
HalTranslateBusAddress()HalTranslateBusAddress()
HalTranslateSystemAddress()HalTranslateSystemAddress()
内存管理内存管理 MmMapIOSpace – MmUnmapIOSpaceMmMapIOSpace – MmUnmapIOSpace
HalAllocateCommonBufferHalAllocateCommonBuffer
I/O I/O 存取存取
XXXX => XXXX =>
UCHAR/USHORT/ULONG UCHAR/USHORT/ULONG
READ_REGISTER_XXXXREAD_REGISTER_XXXX
WRITE_REGISTER_XXXXWRITE_REGISTER_XXXX
READ_PORT_XXXXREAD_PORT_XXXX
WRITE_PORT_XXXXWRITE_PORT_XXXX
中断架构
中断只是异常处理的一部分
在内核代码中被获取在内核代码中被获取
在恢复到用户态之间进行处理在恢复到用户态之间进行处理
但是硬件是独立于操作系统的但是硬件是独立于操作系统的
CE使用二阶段中断服务模式
少量的代码进行中断的记录少量的代码进行中断的记录
调度中断服务程序代码进行处理调度中断服务程序代码进行处理
操作系统提供API来使能IRQ信号,设置中
断的优先级,等等。
与硬件有关的操作在OAL,以及设备驱动代
码中进行。
关于ISR与IST的一些 解释
IST是老的用户模式代码
有完整的有完整的CE .NET APICE .NET API与与CRTCRT库库
CE .NETCE .NET调度程序根据线程的优先级控制调度程序根据线程的优先级控制ISTIST
的执行的执行
运行态绑定到运行态绑定到SYSINTRSYSINTR
从异常处理函数调用ISR
没有操作系统服务没有操作系统服务
堆栈空间大小有限堆栈空间大小有限
可设置为可重入的可设置为可重入的 ( (在在OALOAL进行设置进行设置))
MIPS, SHxMIPS, SHx汇编语言汇编语言
ISR
IRQ IRQ 优先级的设定依赖于不同优先级的设定依赖于不同CPUCPU的系统架构的系统架构
在在x86x86上由上由PICPIC硬件进行设置硬件进行设置
在在MIPSMIPS上用上用OALOAL的的IntrPriority, IntrMask IntrPriority, IntrMask 进行设置进行设置
通过让通过让ISTIST进程推断进程推断ISRISR服务,服务,OALOAL能够增加实时能够增加实时
性。性。
在在CE 中中,,所有的所有的ISRISR代码都是代码都是OALOAL的一部分的一部分
没有特殊的扩展没有特殊的扩展
IRQIRQ绑定到绑定到OEMInitOEMInit的事件的事件IDID
没有支持没有支持PNP, PNP, 共享共享IRQ (PCIIRQ (PCI总线总线))
CE .NET CE .NET 通过通过IRS(IISR)IRS(IISR)链解决了这些限制。链解决了这些限制。
CE .NET 可安装ISR
CE ISR CE ISR 架构的首选扩展架构的首选扩展
DLL DLL 代码代码,,在运行时进行绑定在运行时进行绑定
源代码可以是独立于源代码可以是独立于CPUCPU的的
一般用一般用CC编写编写
有一些限制有一些限制
不能调用不能调用CRT, Windows API, CRT, Windows API, 或其它的或其它的DLLDLL
不可推断的不可推断的ISR,ISR,或或 IST IST发布发布
支持硬件共支持硬件共IRQIRQ共享共享
从同一个从同一个IRQIRQ关联的不同关联的不同SYSINTR IDSYSINTR ID
IIS
R
IIS
R
CE .NET中断处理
内
核
内
核
O
A
L
O
A
L
驱
动
驱
动
硬
件
硬
件
设置事件设置事件
无中断无中断
异常处函数异常处函数
ISRISR
更高优先级的中断更高优先级的中断
PSRPSR
SYSINTR_SYSINTR_IDID
被屏蔽的被屏蔽的IRQIRQ
SYSINTR_xxSYSINTR_xx
SYSINTR_NOPSYSINTR_NOP
ISTIST
IISRIISR11
NKCallIntChain(IRQ)NKCallIntChain(IRQ)
IISRIISRnn
SYSINTR_CHAINSYSINTR_CHAIN
IISRIISR22
中断服务线程
是内置设备的驱动程序的作户态线程
进行实际的中断处理
调用CreateEvent 创建一个与逻辑中断相关
联的事件对象
IST在大多数时间里都是处于空闲状态,以
内核用信号通知事件对象时被唤醒
IST通常运行的优先级高于普通优先级,其
优先级由 CeSetThreadPriority函数设定
中断服务线程
InterruptInitialize
调用调用InterruptInitializeInterruptInitialize将事件与将事件与ISRISR的中断标识的中断标识
符关联起来符关联起来
WaitForSingleObject
用来等待一个用信号通知的事件用来等待一个用信号通知的事件
这一调用通常放在一个循环中,以使和中断处这一调用通常放在一个循环中,以使和中断处
理时,理时,ISTIST可以回到这一个调用等待下一个要处可以回到这一个调用等待下一个要处
理的中断理的中断
InterruptDone
中断数据处理完以后,中断数据处理完以后,ISTIST必须调用必须调用
InterruptDoneInterruptDone函数函数使内核使能与这一个线程相使内核使能与这一个线程相
关的中断关的中断
典型的IST启动
struct ISTData // Declare the Strucure to pass to the ISTstruct ISTData // Declare the Strucure to pass to the IST
{{
HANDLE hThread; // IST Handle HANDLE hThread; // IST Handle
DWORD sysIntr; // Logical ID DWORD sysIntr; // Logical ID
HANDLE hEvent; // handle to the event to wait for interrupt HANDLE hEvent; // handle to the event to wait for interrupt
volatile BOOL abort; // flag to test to exit the IST volatile BOOL abort; // flag to test to exit the IST
};};
ISTData g_KeypadISTData;ISTData g_KeypadISTData;
// Create event to link to IST // Create event to link to IST
= CreateEvent(NULL, FALSE, FALSE, NULL); = CreateEvent(NULL, FALSE, FALSE, NULL);
// Translate IRQ to an logical ID (x86 CEPC)// Translate IRQ to an logical ID (x86 CEPC)
=Mapirq2Sysintr(5); =Mapirq2Sysintr(5);
// start the thread// start the thread
= CreateThread(NULL,0,&KeypadIST, = CreateThread(NULL,0,&KeypadIST,
&g_KeypadISTData, 0, NULL); &g_KeypadISTData, 0, NULL);
典型的IST启动
//Change the threads priority//Change the threads priority
CeSetThreadPriority(,0);CeSetThreadPriority(,0);
//disconnect any previous event from logical ID//disconnect any previous event from logical ID
InterruptDisable();InterruptDisable();
// Connect Logical ID with Event// Connect Logical ID with Event
InterruptInitialize(, (, g_KeypadISTData.
hEvent,NULL,0);hEvent,NULL,0);
设置设置ISTIST的优先级的优先级
与以前的事件断开与以前的事件断开
与与ISRISR关联关联
典型的IST启动
DWORD KeypadIST(void *dat)DWORD KeypadIST(void *dat)
{ {
ISTData* pData= (ISTData*)dat; ISTData* pData= (ISTData*)dat;
// loop until told to stop // loop until told to stop
While(!pData->abort) While(!pData->abort)
{ // wait for the interrupt event... { // wait for the interrupt event...
WaitForSingleObject(pData->hEvent, INFINITE) WaitForSingleObject(pData->hEvent, INFINITE)
if(pData->abort) if(pData->abort)
break; break;
// Handle the interrupt... // Handle the interrupt...
// Let OS know the interrupt processing is done // Let OS know the interrupt processing is done
InterruptDone(pData->sysIntr); InterruptDone(pData->sysIntr);
} }
Return 0; Return 0;
}}
典型的IST结束
// set abort flag to true to let thread know// set abort flag to true to let thread know
// that it should exit// that it should exit
=TRUE; =TRUE;
//disconnect event from logical ID//disconnect event from logical ID
//this internally sets which in turn//this internally sets which in turn
//sets through the kernel//sets through the kernel
InterruptDisable();InterruptDisable();
//wait for thread to exit//wait for thread to exit
WaitForSingleObject(,INFINITE);WaitForSingleObject(,INFINITE);
CloseHandle();CloseHandle();
CloseHandle();CloseHandle();
设置一个会导致IST退出的标志
总线驱动概览
PCMCIA
I82365 (ISA)I82365 (ISA)
TI-1250 (PCI)TI-1250 (PCI)
USB Host
多主控制器多主控制器
OHCI OHCI 与与 UHCI (PCI) UHCI (PCI)
PCMCIA Host
PCMCIAPCMCIA总线驱动有三个主要的线程总线驱动有三个主要的线程
状态改变线程状态改变线程 ( (卡的插入与移除卡的插入与移除) )
中断线程中断线程((处理卡的功能性中断请求处理卡的功能性中断请求) )
回调线程回调线程 ( (通知事件相关的设备卡通知事件相关的设备卡) )
总线驱动支持总线驱动支持Card ServCard Serv消息的一个子集,从回调消息的一个子集,从回调
线程中用回调函数发送线程中用回调函数发送
中断以回调的形式发送到客户端驱动中断以回调的形式发送到客户端驱动
对新插入的卡进行扫描以确定是否对新插入的卡进行扫描以确定是否PnPPnP元组,并与元组,并与
注册表中的相关项进行比较注册表中的相关项进行比较
如果没有发现相匹配的信息,则候选的驱动程序就如果没有发现相匹配的信息,则候选的驱动程序就
运行与卡相关的运行与卡相关的“detect”“detect”例程对卡进行识别例程对卡进行识别
可能显示出一个对话框询问可能显示出一个对话框询问DLLDLL的名字的名字
USB Host
兼容兼容USB 版版
完全支持完全支持OHCIOHCI与与UHCIUHCI
支持所有的传输类型支持所有的传输类型
Isoch, bulk, interrupt, controlIsoch, bulk, interrupt, control
USBDUSBD支持多个支持多个HCHC的复用的复用
总线设备驱动典型地采用总线设备驱动典型地采用LoadDriverLoadDriver进行安装,进行安装,
使用使用USBDUSBD操作与操作与HCHC进行通信进行通信
总线设备驱动能可选地调用总线设备驱动能可选地调用ActivateDeviceEx()ActivateDeviceEx()以以
提供一个流接口给应用程序提供一个流接口给应用程序
检测并识别新装设备检测并识别新装设备
按照注册表中的描述安装驱动按照注册表中的描述安装驱动
可能显示一个对话框询问可能显示一个对话框询问DLLDLL的名字的名字
OEM硬件
单块驱动单块驱动
((显示显示))
GWE 子系统 设备管理器设备管理器
MDDMDD
PDDPDD
MDDMDD
PDDPDD
DDIDDI
DDSIDDSI DDSIDDSI
编程模型
USB USB 总线设备驱动总线设备驱动
USBDUSBD
MDDMDD
PDDPDD
主要内容
概述
流驱动接口
设备驱动程序架构
USB mouse 驱动开发示例
Windows CE 系统服务
USB 驱动传输类型
控制传输
USB USB 打印机打印机, USB, USB数码相机数码相机
同步传输
USB USB 网络电话网络电话
中断传输
鼠标鼠标,,键盘键盘,,游戏控制器游戏控制器
批量传输
USB USB 相机相机
必须的入口点
USBDeviceAttach
当设备挂接时,当设备挂接时,USBUSB驱动模块调用这个函数驱动模块调用这个函数
USBInstallDriver
当一个不明设备挂接到当一个不明设备挂接到USBUSB上时,上时,USBUSB驱动驱动
模块调用这个函数模块调用这个函数
USBUnInstallDriver
总线设备驱动能调用这个函数从总线设备驱动能调用这个函数从USBUSB驱动注消驱动注消
USB鼠标模型
USB鼠标驱动
硬件
应用
演示:
USB鼠标驱动代码
主要内容
概述
流驱动接口
设备驱动程序架构
USB mouse 驱动开发示例
Windows CE 系统服务
系统服务的概念与历史
在Windows CE 以前,没有系统服务
所谓的 “设备驱动”被写成一个工作区
在Windows CE 以后,引入了系统服务
管理器
系统服务注册
系统服务体系架构
CE的系统服务是一个DLL,这个DLL的构
建几乎与流设备驱动一模一样
与流设备驱动一样,Windows CE系统服
务提供同样的10个入点口,从xxx_Init到
xxx_PowerDown
系统服务有三个前缀字符
系统服务IOCTL命令
IOCTL_SERVICE_START
IOCTL_SERVICE_STOP
IOCTL_SERVICE_REFRESH
IOCTL_SERVICE_INSTALL
IOCTL_SERVICE_STATUS
IOCTL_SERVICE_SUPPORTED_OPTIO
NS
系统服务的应用控制
ActivateService
RegisterService
GetServiceHandle
ServiceIoControl
DeregisterService
作业
读的在线帮助,自已实现关于
Windows CE 的系统服务。
应用程序发送I/O控制命令,然后服务例程将
当前时间写到日志文件