27
WINCE 驱驱驱驱驱驱 AEC 驱驱 2005.8.31

WINCE 驱动开发初探

  • Upload
    saman

  • View
    234

  • Download
    0

Embed Size (px)

DESCRIPTION

WINCE 驱动开发初探. AEC 陈辉 2005.8.31. CONTENT. WINCE 驱动程序概述 WINCE 驱动开发流程及相关技术 i.mx21 开发板键盘驱动实例分析 ADC 系统串口键盘 / 鼠标驱动开发方案. WINCE 驱动程序概述. 所有的驱动都是动态链接库。 驱动实现过程中可调用所有标准的 API 函数。 CE 驱动程序模型。 可以分为本机驱动程序和流接口驱动程序 加载方式不同。本机驱动程序一旦系统启动就加载,而流接口驱动则是需要时加载。. WINCE 驱动程序概述. - PowerPoint PPT Presentation

Citation preview

Page 1: WINCE  驱动开发初探

WINCE 驱动开发初探

AEC 陈辉2005.8.31

Page 2: WINCE  驱动开发初探

CONTENT

WINCE 驱动程序概述 WINCE 驱动开发流程及相关技术 i.mx21 开发板键盘驱动实例分析 ADC 系统串口键盘 / 鼠标驱动开发方案

Page 3: WINCE  驱动开发初探

WINCE 驱动程序概述 所有的驱动都是动态链接库。 驱动实现过程中可调用所有标准的 API 函数。 CE 驱动程序模型。 可以分为本机驱动程序和流接口驱动程序 加载方式不同。本机驱动程序一旦系统启动

就加载,而流接口驱动则是需要时加载。

Page 4: WINCE  驱动开发初探

WINCE 驱动程序概述 GWES 加载的有键盘 / 鼠标、触摸屏、显

示器、电源、 LED 等 DEVICE.EXE 加载的驱动有本地驱动 PCM

CIA 控制器、 USB 控制器、 NDIS.DLL , 也有流接口驱动,如声音、串口、并口等

需要时才加载的如 PC 卡的 USB 设备的等

Page 5: WINCE  驱动开发初探

WINCE 驱动程序概述 中断处理分内核模式( ISR )的中断服务

例程和用户模式的中断服务线程( ISP )。前者返回中断号给内核,后者接收中断后进行中断处理。

设备驱动加载后,产生中断 IST ,注册到中断处理器。

调用 InterruptDisable 来删除 IST 与逻辑中断的连接。

Page 6: WINCE  驱动开发初探

WINCE 驱动程序概述 中断处理过程如下1. 中断发生,内核跳至异常处理程序2. 异常处理程序使所有的中断无效,然后调用合适

的中断服务例程准备物理中断。3. 经中断服务例程以中断标识符形式返回逻辑中断。4. 中断处理程序重新启动除当前中断以外的所有中

断,并把信号传递给适当的中断服务线程。

Page 7: WINCE  驱动开发初探

WINCE 驱动程序概述

5. 中断服务线程调用依赖平台的驱动程序来访问硬件和完成逻辑中断的处理。

6. 中断服务程序调用 InterruptDone 函数 .

7. 中断处理程序重新启动当前中断 , 并在 OAL 中调用 OEMInterruptDone 函数。

中断有 256 个优先级,缺省 CE 驱动为 97-152.

Page 8: WINCE  驱动开发初探

WINCE 驱动程序概述

Page 9: WINCE  驱动开发初探

WINCE 驱动程序概述 本机驱动程序按照设计的不同可以分为单

片驱动程序和分层驱动程序。单片驱动是将硬件设备的功能直接传递给操作系统;分层则有模型设备驱动程序( MDD )和依赖平台的设备驱动程序( PDD )两类。

Page 10: WINCE  驱动开发初探

WINCE 驱动程序概述

Page 11: WINCE  驱动开发初探

WINCE 驱动开发流程及相关技术 1 选择使用分层的还是单片的驱动结构。 2 熟悉微软和第三方提供的驱动源代码、开

发环境( PB )中操作、编译和调试的方法。 3. 找一个相近的驱动,拷贝到自己的驱动目

录下,然后进行配置文件的修改以及代码的修改与优化。

4. 编译无错后加入到 OS 中。

Page 12: WINCE  驱动开发初探

WINCE 驱动开发流程及相关技术 5. 在 PB-IDE 中编译 run-time image 来包

含该驱动。 6. 在 PB 中对驱动进行断点调试。在不同模

块以及程序入口设置断点,都运行完毕并且中断服务程序功能正确,完成调试。

7. 使能 CETK 到 OS ,然后进行 CETK 的测试。

Page 13: WINCE  驱动开发初探

i.mx21 开发板键盘驱动实例分析 键盘直接挂到 i.mx21 上 键区 6 乘 6 ,矩阵扫描 关系紧密的三个文件,一个是 keypad.h,

一个是 keypad_map.h ,和 keypad.c ,其中 keypad_map.h 提供了键区的索引与键的对应。 keypad.h 定义了一些全局变量;主驱动程序在 keypad.c

Page 14: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案

问题描述 串口接收到遥控器发送来的码字,每按一次发送两个字节的相同数据。目标是要能够使用串口捕获到中断,并且调用中断服务程序将接收到的数据进行键值转换,在应用软件层定义对应的键值,一旦满足这样的键值,则发生对应的动作,完成遥控特殊键盘 / 鼠标的功能。

Page 15: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 常见驱动可以分为本地驱动和流驱动两种。存储

卡,网络驱动等属于流驱动,需要时加载。键盘、显示器、鼠标等属于本地驱动,需要在系统加载时就被调用。

串口遥控键盘 / 鼠标驱动应该属于输入设备驱动,隶属键盘驱动大类。开发环境是 PB ,可以参考 I.mx21 的 keypad 和 serial 进行修改、编写,编译后进入和系统联系起来调式阶段,调试完成后,使用 PB 的 BSP克隆并添加驱动的方法,将完成的驱动添加到 OS 中。

Page 16: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案

每个驱动一般用三个字母表示,我们可以使用 RMC ( Remote Controller )表示。每个驱动按照模块有以下几个部分:

(1)RMC_Init ------Load (2)RMC_Deinit ------unload (3)RMC_Open -------Createfile (4)RMC_Close ------Closehandle (5)RMC_Read -------readFile (6)RMC_Write ------writeFile (7)RMC_Seek ------SetFilePoint (8)RMC_IOControl -----DeviceControl (9)RMC_PowerDown ------before suspend (10)RMC_PowerUp -----system resumes 我们开发驱动也应该按照这种模块的划分方法,最好在比较接近的驱动的基础上,添加自己的代码完成特殊的功能。

Page 17: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 键盘驱动的流程 (1 )初始化 PFN_KEYBD_DRIVER_INITIALIZE 和标准码转换 PFN_

KEYBD_DRVER_VKEY_TO_UNICODE (2) 中断服务 IST (3) 中断响应,转换扫描到虚拟键值 (4) 使用回调函数传虚拟键值到 PFN_KEYBD_DRIVER_INITIALIZE_

EX或者 keybd_even API 到系统输入 (5)从队列中读出键值事件,转到( 1 )启动的标准码转换线程 (6) 驱动分析键盘事件,由虚拟的键值产生相应的字母,输入系统将虚拟码字和字母送到应用程式中。

Page 18: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 解决方案 1.读 i.mx21 的 serial.c 串口驱动,找到接收到中

断的部分。 2. 对遥控键盘送到串口上的中断进行分析。 3. 在中断服务例程里加入虚拟键值以及自定义键值的映射。

4. 进行 DEBUG 。 5. 加入到 OS 中进行 CETK 测试。

Page 19: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 键盘的中断 每个中断请求对应一个中断服务。一个中断服务程序可以

相应多个中断请求源。当中断有效并且产生一个中断,内核调用为该中断注册的 ISR。一旦结束, ISR返回中断识别符。系统检查返回的中断识别符然后设置对应的事件。一旦事件设置完毕,中断服务线程开始运行。例外处理器是所有中断的基本处理器,中断产生后,微处理器在核中将控制权交给核中的例外处理器。然后意外控制器调用注册给当前中断的 ISR。 ISR将中断翻译成逻辑中断符, SYSINTR作为返回值送给核。核对应地设置了事件,导致排列了一个中断服务线程。该线程在设备管理器中运行。

Page 20: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 如果内核的 exception-trapping 接受到一个硬件中断,内核会检测异

常,内核处理中断,否则到下一步。 核中断支援控制器通知 ISR停止所有的中断,直到控制完成。 例外控制器调用 ISR决定如何处理该中断。(不同 CPU 不用的细

节) 核从 ISR得到返回值,使核直到该如何去处理这个中断。 如果返回 SYSINTR_NOP -------------Kernel does nothing SYSINTR_RESCHED -------Kernel reschedules the IST SYSINTR_XXX ----------Logical interrupt value for that specifi

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

当 IST苏醒, IST 处理该中断。可能是对数据的搬迁或者特殊的解释。

需要的话, IST 调用 I/O 程序来存取硬件操作。 IST 结束工作后,通知 Kernel 完成,使用 InterrputDone 。 核调用 OAL 的 OEMInterruptDone 来结束中断,再次中断使能。

Page 21: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 在原来的基础上修改 (1) 将原来的驱动代码进行复制,并在 WINCE根目录下的 Platform

下找到自己要用的 OS ,如果没有自己的 OS ,可以自己建立。 (2) 在其中的 Driver里或者是公共的 COMMON里的 OAK 下找到驱

动的原始参考代码包。 (3 ) 将包复制并且拷贝到你自己的 OS 下的 Drivers里自己的驱动名称目录下,对 SOURCE 、 DEF 等文件进行修改并且修改源代码。

(4) 修改后进行编译;编译的方法可以在 PB-IDE 中,也可以在 PB-〉 build-〉 open build release directory 进入到 DOS 下,转到驱动的目录下面,输入 sysgen命令;等待几分钟编译通过且没有错误的话,输入 build –c命令。在 IDE里编译的方法,

Page 22: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 常用的一些函数 BOOL KernelIoControl( DWORD dwIoControlCode, LPVOID lpInBuf,

DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned );

dwIoControlCode [in]I/O 控制码,应该可以支持 OAL I/O 控制。 lpInBuf [out]输入 buffer 的指针 nInBufSize [in] lpInBuf 的字节数 lpOutBuf [out]输出缓冲的指针 nOutBufSize [in] lpOutBuf 的最大返回字节数 lpBytesReturned [in] 接收返回数据的字节大小的一个双字型变量的地址 返回 TRUE 为成功, FALSE 为失败。

Page 23: WINCE  驱动开发初探

VOID keybd_event( BYTE bVk, BYTE bScan, DWORD dwFlags, DWORD dwExtraInfo ) 该函数可以模拟键盘输入。 bVk [in] 定义了一个虚拟键码。该码必须在 1-254之间。 bScan [in] 定义了一个硬件扫描码,不常用。 dwFlags [in] 操作标志 dwExtraInfo [in] 对应键击定义 32位附加值。 使用以上的函数就可以将扫描到的码值转换成虚拟按键时的值,这样就可以完成从键盘输入到系统的识别的过程。而且,其中有不少中断,这些中断的服务程序是整个键盘驱动的核心。

ADC 串口键盘 / 鼠标驱动开发方案

Page 24: WINCE  驱动开发初探

BOOL InterruptInitialize( DWORD idInt, // 和 IST联合的中断检验器 HANDLE hEvent, // 中断触发后发生的事件 LPVOID pvData, // 传到 OEMInterruptEnable 的一个数据块的指针 DWORD cbData // 上面数据块的大小 );

该函数初始化硬件中断,该初始化允许设备驱动注册一个事件并且使能中断。返回 BOOL 型 TRUE或 FALSE 。

ADC 串口键盘 / 鼠标驱动开发方案

Page 25: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 HANDLE CreateThread( LPSECURITY_ATTRI

BUTES lpThreadAttributes, //MUST NULL DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, //长指针指向要执行 LPVOID lpParameter, //长指针送一个 32位参数到线程里 DWORD dwCreationFlags, LPDWORD lpThreadId);

该函数创建一个线程来执行访问的地址空间的程序。

Page 26: WINCE  驱动开发初探

ADC 串口键盘 / 鼠标驱动开发方案 驱动的调试信息 ( 1 )调试信息函数 DEBUGMSG ( Condition, Printf_expr) ( 2 ) condition 可以设置全局变量 #define KEY_DEBUG_MSG 0 #define KEY_ERROR_MSG 0 这样就可以使用 DEBUGMSG(KEY_DEBUG_MSG, (TEXT("Testing item

count against maximum %u\r\n"), dwMaxNumberOfItems)); 进行调试了。同样地定义错误消息变量,也是为了调式的需要。设置为 0 时候,这些信息都不会显示。

Page 27: WINCE  驱动开发初探

THANKS!!