现在的位置: 首页 > 综合 > 正文

wince bsp study

2013年09月06日 ⁄ 综合 ⁄ 共 6930字 ⁄ 字号 评论关闭

驱动模型:

1.      
.LIB
库文件,与操作系统内核链接,随操作系统启动一起加载,关闭一起关闭。效率高,但是缺乏灵活性和扩展性。

2.      
延迟加载,但是仍在系统的内核空间中。实现了驱动的动态加载,但是容易导致系统不稳定。

3.      
wince
采用用户态下的DLL文件形式存在。

 

 

Wince驱动宿主

1.      
device.exe
设备管理器,负责加载和管理绝大多数的设备驱动:网卡、电池、声卡、串口、NLEDUSB设备驱动、PCMCIA驱动等。

2.      
GWES.dll
某驱动仅被GWES进程使用。如鼠标、键盘、显卡和触摸屏等驱动。

3.      
FileSys.dll
负责管理wince中的对象存储和文件系统。如FAT文件系统驱动、CDFS文件系统驱动等。

 

单体驱动程序

直接与硬件交互,暴露DDI: Device Driver Interface给操作系统。应用于对效率要求较高的场合或者较简单的硬件设备驱动。

 

分层驱动程序

2层:上面一层,模型设备驱动(Model
Device Driver
MDD);下面一层,平台相关驱动(Platform
Dependence Driver
PDD)。MDD包含某一类型驱动的通用代码,通常Platform
Builder
会自带,无需修改。PDD包含特定硬件或平台专用的代码,供MDD调用。当移植示例驱动时,只需对PDD层代码进行修改。

另外,MDDPDD之间还需要一个接口协议。故在分层驱动中,有2类接口:操作系统和MDD之间的DDIMDDPDD之间的DDSIDevice
Driver Service provider Interface
)。

 

MDD

ü        
包含某一类驱动所通用的代码,对于同一类型驱动,代码可重用。通常无需改动

ü        
调用PDD层访问硬件设备

ü        
PDD层代码链接,定义PDD层必须实现的DDSI函数,并在代码中使用

ü        
对于操作系统,实现DDI函数,供操作系统和驱动程序交互

ü        
进行中断处理,中断处理线程IST通常位于这一层

ü        
编译后生成的Lib库可与不同的PDD库进行链接

 

PDD

ü        
包含与特定硬件相关的代码,对不同的硬件或标准,有不同的实现

ü        
只能与某一类MDD协同工作

ü        
实现MDD所需的DDSI函数

 

与平台无关的驱动sample位于:%WINCEROOT%/PUBLIC/COMMON/OAK/DRIVERS

与平台相关的位于:%WINCEROOT%/PLATFORM/<BSP Name> /SRC/DRIVERS

 

 

设备管理器

²       
为大量DLL形式的驱动程序提供宿主进程,也就是把驱动程序的DLL文件加载到Device.exe进程的地址空间内。

²       
在系统启动和新设备连接时负责加载和初始化驱动程序;在设备不使用时卸载。

²       
对驱动程序进行统一管理,并可在特殊驱动事件发生时对其他应用程序发出通知。

²       
实现并暴露设备管理相关的API函数,供其他应用程序调用,进而对设备进行访问和控制。

²       
提供电源管理的接口。

²       
负责对I/O资源进行管理。

²       
Device.exe会调用其他DLL来共同完成设备管理的功能。如:Devmgr.dll会进行大部分的设备管理工作,BusEnum.dll会完成驱动加载和总线枚举的工作等。

 

wince中,设备的初始化可分成2个阶段:device.exe本身的初始化,外设的枚举和加载。

 

Device.exe本身的初始化

1.        
wince
冷启动后,操作系统内核NK首先运行,然后NK根据注册表HKLM/init下的内容陆续启动一些其他进程,device.exe就是在此时被启动。

2.        
device.exe启动后,进行一系列自身的初始化工作:先初始化本身的一些数据结构,再初始化I/O资源管理器和电源管理器。

3.        
device.exe
根据注册表的设置,加载BusEnum.dll,让BusEnum.dll负责加载和初始化所有的内置外设。

至此,控制权交给busenum.dlldevice.exe本身的初始化结束。

 

外设的枚举和加载

Busenum.dll的源代码:%WiNCEROOT%/PUBLIC/COMMON/OAK/DRIVERS/BUSENUM

1.        
当设备自身的初始化结束后,device.exe会在注册表HKLM/Drivers下读取RootKey的值,该值保存总线枚举器的位置,一般为“Drivers/BuiltIn”。

2.        
根据RootKey的值,device.exe加载总线枚举器。如HKLM/Drivers/BuiltIn

设备管理器直接调用ActivateDeviceEx函数来加载busenum.dll,然后调用后者的导出函数Init()

枚举过程会遍历HKLM/Drivers/BuiltIn下所有子键。ActivateDeviceEx函数根据里面注册表的信息,把对应的驱动DLL加载到device.exe的地址空间内,然后在注册表HKLM/Drivers/Actice键下增加一个子键,来记录已经加载的驱动程序。最后调用设备的Init函数。如果设备时即插即用设备,则还有负责发送即插即用的通知。

3.        
busenum.dll
init函数会遍历HKLM/Drivers/BuiltIn下的所有子键。每个子键都对应着一个预先配置的驱动程序信息。busenum.dll读取这些信息,然后加载驱动程序。加载方式调用ActivateDeviceEx函数来完成的。

如果碰到总线驱动程序,会引起递归,该总线驱动要负责枚举查在该总线上的所有设备,并加载对应的驱动程序。

此外,应用程序也可显式的调用ActivateDeviceEx函数来加载一个驱动程序。

 

设备文件的名称(Device File Names

Applications can access peripheral devices through file system functions, such as
CreateFile. The file I/O operations are redirected to the stream interface.

The following table shows descriptions and examples for the three device namespaces.

Namespace description

Example

Three letter prefix, followed by a number between 0 and 9, followed by a colon.

"LPT2:"

$bus mount point, followed by the bus name, bus number, device number, and function number.

"/$bus/PCMCIA_0_0_0"

$device mount point, followed by a three letter prefix representing the device, followed by a number.

"/$device/COM7"

 

 

应用程序的通知

HANDLE RequestDeviceNotifications(
  const GUID* devclass,
  HANDLE hMsgQ,
  BOOL fAll
);
BOOL StopDeviceNotifications(
  HANDLE h
);

 

 

资源的管理

注册表HKLM/Drivers/Resources/IRQIO项记录了资源的状态。

当总线驱动程序希望申请一定的资源时,可以通过ResourceRequest()ResourceRequestEx()函数来申请,后者可申请独占的资源。可通过ResourceRelease()释放。

 

 

中断处理

Wince下的中断处理分为2个阶段:处于内核模式的中断服务例程ISR(Routine)和处于用户模式的中断服务线程IST(Thread)

ISRIRQ(Interrupt
ReQuest)
1对多的关系。ISR负责把IRQ转化程逻辑中断并返回给内核;IST则负责中断的逻辑处理。

  1. If the kernel's exception-trapping code receives a hardware interrupt, and then the kernel detects an exception, the kernel handles the hardware
    interrupt.

    Otherwise, go to the next step.

  2. The kernel's interrupt support handler notifies the ISR to disable the specific interrupt until the required handling completes.

    All other interrupts remain enabled.

  3. The exception handler calls the ISR to determine how to handle the interrupt.

Note:

Details might vary depending on the CPU architecture.

  1. The kernel receives the return value from the ISR, which lets the kernel know what to do about the interrupt.

    The following table shows the possible responses from the kernel.

Response

Description

SYSINTR_NOP

The kernel does nothing.

SYSINTR_RESCHED

The kernel reschedules the IST. The interrupt was for the OS timer tick thread.

SYSINTR_XXX, logical interrupt value for that specific interrupt source.

The kernel triggers the interrupt sources ISR so the IST wakes up and does its work. Then, the IST creates an event and waits on it.

  1. When the IST wakes up, the IST does whatever work it needs to do to handle the interrupt.

    This could mean moving data into a buffer or interpreting the data in some meaningful way.

  2. As needed, the IST calls various I/O routines to access the hardware to do its work.
  3. When the IST finishes its work, it notifies the kernel by calling
    InterruptDone.
  4. The kernel calls the OAL function
    OEMInterruptDone to complete all handling for the interrupt.

    The OAL notifies the hardware to re-enable the interrupt.

 

 

 

导致ISR延迟(从发生中断到ISR首次执行之间的时间)的因素包括:

Ø        
中断被关闭的时间

Ø        
总线指令锁定处理器的时间(检查中断并锁定)

Ø        
内核ISR的执行时间+导向ISR的时间

 

导致IST延迟(从中断发生到执行IST中第一行代码之间的时间)的因素包括:

Ø        
ISR延迟时间

Ø        
ISR执行时间

Ø        
OS执行系统调用的时间

Ø        
调度IST的时间

 

 

访问物理内存

Wince提供了相对简单的物理内存呢访问方式。

物理内存结构体PHYSICAL_ADDRESS(定义在ceddkh中,用64位来代表物理地址,对大多数32位的cpu,只需吧HighPart设置为0即可)。

VirtualAlloc()负责在虚拟内存空间内保留一段虚拟内存,而VirtualCopy()负责吧一段物理内存和虚拟内存绑定。因此,最终对物理内存的访问还是通过虚拟地址进行的。

CEDDK还提供MmMapIoSpace()函数来把一段物理内存直接映射到虚拟内存。用该函数申请的内存要有那个MmUnmapIoSpace()释放。函数的源代码:%WINCEROOT%/PUBLIC/COMMON/OAK/DRIVERS/CEDDK/DDK_MAP

此外,wince还提供了AllocPhysMem()FreePhysMen()函数,用来申请和释放一段连续的物理内存。函数可保证申请的物理内存是连续的,这对DMA设备尤为重要。

 

 

DMA处理

Using CEDDK.dll functions

Using kernel functions

CEDDK.dll provides these functions for obtaining a buffer for DMA transfers:

HalAllocateCommonBuffer

HalFreeCommonBuffer

HalTranslateSystemAddress

The kernel provides these functions for obtaining a buffer for DMA transfers:

AllocPhysMem

FreePhysMem

CEDDK.dll functions can handle bus and hardware platform-specific address translations.

You must handle hardware platform-specific address translations. You can call
HalTranslateSystemAddress to translate the address.

CEDDK.dll functions are useful for common buffer DMA.

The kernel functions may be useful for scatter/gather DMA.

CEDDK.dll functions use a default memory alignment of 64 KB.

The kernel functions allow you to change the default memory alignment.

 

 

电源管理

 

 

 

CEDDK

CEDDK.dll exposes functions typically used by drivers for handling bus address translations, allocating and mapping device memory, setting up direct memory access (DMA) buffers, performing I/O, and so on. You can
implement CEDDK.dll to support any bus on your hardware platform.

While you are completing your OAL, implement CEDDK.dll. To implement CEDDK.dll, you can use the default files or you can create your own
to support your hardware platform. Many platforms only implement a unique Ddk_bus.c file and link to the other libraries built from the public tree.

The following table shows the location of the CEDDK.dll source code in the %_WINCEROOT%/Public/Common/OAK/Drivers/CEDDK directory.

Library

Location

Address mapping abstraction 
地址映射

DDK_MAP

Bus abstraction 
总线访问

DDK_BUS

DMA abstraction 
DMA
操作

DDK_DMA

I/O abstraction 
I/O
操作

DDK_IO

Power management abstraction 
电源管理

DDK_POWER

Time-based abstraction 

DDK_TIME

 

 

Registry Helper

The registry helper functions and structures allow you to read resource configurations from the registry

re

【上篇】
【下篇】

抱歉!评论已关闭.