wince系统开发实验三
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
w i n c e系统开发实验三 Document number【AA80KGB-AA98YT-AAT8CB-2A6UT-A18GG】
实验三、W i n d o w s C E驱动开发
一、实验目的
1、学会使用WinCE 操作系统开发工具
2、熟悉开发环境
3、了解嵌入式系统驱动开发的基本思想和开发过程
二、实验内容
学习使用Platform Builder 4.2 集成开发环境,建立流驱动程序。
了解WinCE 基本系统体系架构
了解WINDOWS CE系统设备驱动基础知识和方法
学习使用Platform Builder 4.2 集成开发环境,建立流驱动程序
三、预备知识
C 语言基本知识,设备驱动基础知识和方法,WinCE 基本系统体系架构。
四、实验设备及工具
硬件:PC 一台P3 以上(内存不小于384MB,安装完工具硬盘空间不得小于
600M)、ARM9
实验箱(包含NETARM2410-S 实验板、JTAG 仿真器、各种串口线、并口线、网线、光盘等)
一台。
软件:PC 操作系统Win2000 以上、ADS1.2 集成开发环境、Platform Builder 4.2 版本、
Source Insight3.0。
五、实验原理及说明
1、WinCE 驱动程序架构
目前WinCE 拥有两种驱动架构模型,一种是本机设备驱动,另一种是流接口设备驱动。
其中本机设备驱动已经被Microsoft 开发并由系统直接支持,由GWES (图形窗口及事件子系统)统一管理和加载;流驱动则是由WinCE 设备管理器来管理的。
这种组织形式相对于UNIX体系来说是比较复杂的。
本机设备驱动适合于集成到CE 平台的设备。
例如电源驱动,它们已经成为了GWES 的一部分,不表现为单个的DLL 使用。
这些驱动程序通常和系统有着较为紧密的联系,所以通常是和系统一起加载的。
流设备驱动由于具有较好的可移植性和可扩展性,被设备管理器独立出来管理统筹。
在本实验中,将以一个示例的流驱动演示程序来讲述简单驱动的工作。
下面的图3-1 中较为清楚的显示了单片形式存在的驱动和分层方式的驱动在WinCE 中的组织情况。
图3-1 驱动在WinCE 中的组织情况
2、流驱动程序
流驱动程序通过流驱动接口函数和设备管理器进行数据交互,并通过文件的形式来组
织,这一点和Unix 平台是很类似的。
它以动态链接库形式存在,具有同一组接口并调用同
一个函数集的。
流驱动面向的是各种各样的外设,主要的任务是把外设的使用传递给应用程
序来使用。
在WinCE 中设备文件通常是保存在固定的路径\Windows 目录下,通过注册表机制来完成特殊的命名惯例。
虽然流借口驱动程序具有普遍的特性,但是我们仍旧可以使用不同的方法来实现它们。
例如有些内部设备的驱动程序就是使用的流接口。
另外尽管流接口程序通常是由设备管理器程序加载和卸载的,但是有时候应用程序也执行加载和卸载的任务。
应用程序通过文件系统的API 来调用流接口函数,然后由流接口驱动程序调用本机驱动或者通过设备管理器与系统内核外围设备通讯交互,最后直接驱动相关硬件执行动作。
3、流接口驱动程序的一般标准入口
流接口驱动程序通常都具有如下的函数,具有一个统一的操作标准如表3-1 所示:
表3-1 流接口驱动程序的函数
函数名称描述
XXX_Close 驱动程序关闭时候调用
XXX_Open 打开一个设备驱动时调用
XXX_Deinit 设备管理器或者应用程序卸载驱动时调用
XXX_Init 设备管理器初始化设备时调用
XXX_IOControl 上层软件进行IO 控制调用
XXX_PowerDown 系统挂起前调用
XXX_PowerUp 系统重新启动时调用
XXX_Read 打开设备时候进行的读操作
XXX_Write 打开设备时候进行的写操作
XXX_Seek 对设备指针进行操作时调用
XXX_Reinit 设备重复打开时调用
其中XXX 代表驱动文件名,由驱动类型的3 个大写字母缩写而成,规则由系统约定。
详
细规则请参考帮助文档和MSDN 的说明。
了解了这些函数的功用,就可以开始着手建立起来一个最简单的流驱动程序。
它的功能
是向缓冲区中读写字符。
六、实验步骤
1、建立模拟器工程
运行Platform Builder,建立一个基于X86 体系的模拟器。
下面的驱动程序建立都可以
在仿真器中模拟实现。
注意需要在Applications & Services Development 选项中选择Active Temple Library
(ATL), C libraries &Runtimes, Message Queuing(MSMQ), Microsoft Foundation Classes
(MFC), Standard SDK for Windows 这几个选项,这样可以确保将来调试的驱动和调用的应用程序具有足够的库和服务可以享用。
详细的建立过程和方法可以仿照实验二里面的步骤来做,这里不再赘述。
2、创建驱动程序工程
在PB 中新建一个工程,单击菜单中的File 选择建立New Project or File Name…弹出
如下图3-2 的对话框。
图3-2 新建工程
在这里选择Project 标签选择WCE Dynamic-Link Library 即WinCE DLL 并在右侧输入
工程名和存放位置(会默认)。
点击“OK”确认。
图3-3 生成DLL 的类型
在对话框中选择生成DLL 的类型,可以选择An empty project 来创建一个空的dll,也
可以选择A simple Windows CE DLL project, 创建一个简单的WinCE 动态链接库工程,这
个工程只带有简单的DLL 入口函数。
A DLL that exports some symbols 用来生成简单的输
出函数。
点“Finish”完成创建。
如图3-3。
创建完PB 的主界面上会切换到该工程,如图3-4 所示。
图3-4 工程根目录
再次点击File,选择“New Project or File Name…”,在向导对话框中选择Files 标
签,如下图3-5 所示。
如图3-5 选择File
选择建立C++ Source File,同时添加文件名,存储路径并将文件添加到DLL 工程中。
加入“windows.h”,“tchar.h”头文件和动态链接库的入口函数(标准函数)DllEntry
Point( ),建立好一个简单的动态链接库的架子,添加相应的处理。
详见各种说明文档。
3、编写驱动程序的代码
DWORD STR_Init(DWORD dwContext)
{
DWORD dwReturn = 0;
RETAILMSG (1,TEXT(“MYSTRINGS:STR_Init\t\n”));
memset (achBuffer,0,BUFSIZE * sizeof (WCHAR));
dwReturn = 1;
return dwReturn;
}
BOOL STR_Deinit(DWORD hDeviceContext)
{
BOOL bReturn = TRUE;
RETAILMSG(1,(TEXT(MYSTRINGS:STR_Deinit\t\n”)));
return bReturn;
}
DWORD STR_Open (DWORD hDeviceContext,
DWORD AccessCode,
DWORD ShareMode)
{
DWORD dwReturn = 0;
RETAILMSG (1,TEXT(“MYSTRINGS:STR_Open\t\n”)); dwReturn = 1;
return dwReturn;
}
BOOL STR_Close(DWORD hOpenContext)
{
BOOL bReturn = TRUE;
RETAILMSG(1,(TEXT(MYSTRINGS:STR_Close\t\n”))); return dwReturn;
}
BOOL STR_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL bReturn = TRUE;
RETAILMSG(1,(TEXT(MYSTRINGS:STR_IOControl\t\n”))); return bReturn;
}
void STR_PowerDown (DWORD hDeviceContext)
{
RETAILMSG(1,(TEXT(MYSTRINGS:STR_PowerDown\t\n”))); }
void STR_PowerUp(DWORD hDeviceContext)
{
RETAILMSG(1,(TEXT(MYSTRINGS:STR_PowerUp\t\n”))); }
DWORD STR_Read(DWORD hOpenContext,
LPVOID pBuffer,
DWORD Count)
{
DWORD darter = 0;
RETAILMSG (1,TEXT(“MYSTRINGS:STR_Read\t\n”)); DWORD cbBuffer = wcslen ( achBuffer);
dwReturn = min(cbBuffer, Count);
wcsncpy((LPWSTR)pBuffer, achBuffer, dwReturn); return dwReturn;
}
DWORD STR_Seek(DWORD hOpenContext,
Long Amount,
DWORD Type)
{
DWORD dwReturn =0;
RETAILMSG(1,(TEXT(MYSTRINGS:STR_Seek\t\n”)));
Return dwReturn;
}
DWORD STR_Write(DWORD hOpenContext,
LPCVOID pSourcdBytes,
DWORD NumberOfBytes)
{
DWORD dwReturn =0;
RETAILMSG(1,(TEXT(MYSTRINGS:STR_Write\t\n”)));
dwReturn = min(BUFSIZE, NumberOfBytes);
wcsncpy (achBuffer, (LPWSTR) pSourceBytes, dwReturn);
Return dwReturn;
}
确定编写完毕保存。
如果不想编写,也可以直接拷贝光盘中的MyDriver.cpp 文件到工
作目录下。
4、准备配置文件
Def 文件。
复制光盘中的String.Def 文件到工作目录下。
Reg 文件。
复制光盘中的StringReg.reg 文件到工作目录下。
Cec 文件。
复制光盘中的MyDriver.cec 文件到工作目录下。
Makefile 文件和Sources 文件。
复制makefile 和sources 文件到工作目录下。
这些文件是 DLL 工程编译必须具备的配置文件,它们说明了关于驱动如何链接,编译路
径,和系统注册等等重要的工作,在编写新的DLL 时一般都需要进行改动甚至重写。
这里直
接拷贝光盘中的文件来实现。
有兴趣的也可以使用文本查看软件(如Ultra Edit32,WinHEX
等)来打开这些文件,看看文件内部是如何配置的。
拷贝完毕后,在PB 下导入CEC 文件。
将MyDriver.cec 拷贝到PB 当前工程目录下(模拟器目录下),打开File 菜单,选择Manage Catalog Features 弹出一个属性对话框,如图3-6。
图3-6 属性对话框
在右侧按钮中点击Import,选中MyDriver.cec 导入当前工程目录,然后单击“OK”确
认完成。
导入方法和导入平台BSP 的方法是相同的。
可以发现驱动被添加到工程组件窗口中,在组件上点击右键,选择Add to Platform,
完成系统的驱动添加。
5、编译内核
和实验一的编译方法一样,点击来实现编译。
特别注意现在是在使用模拟
器,所以
在编译选项中应该选中“EMULATOR:X86 WIN32”。
编译之前,在Build Option 选项标签中确保“Enable CE Target Control System”,“Enable Kernel Debugger”,“Enable KITL”被选定,这些选项允许内核向PB 传送调试信息。
单击“OK”确定。
如图3-7 所示:
图3-7 编译
6、加载驱动
内核编译完毕后开始在模拟器下加载。
单击Target 下面选择Configue Remote Connection,弹出对话框如图3-8 所示。
图3-8 加载驱动
选择Emulator – 4.20,再点确定,在Target 菜单中选择
Download/Initialize,就
可以看到模拟器开始运行启动,一个模拟的WinCE 系统在窗口中显示出来,绝大多数的操作
都可以使用了。
此时在PB 的Debug 窗口中可以看到系统的启动调试信息。
其中可以很清楚的看到驱动
模块被加载的状态,驱动运行成功
七、思考题
1. 想一下WinCE 中的驱动程序架构和其他系统中的有什么不同?
2.WinCE 中的驱动程序中断处理是如何实现的?。