第25卷第9期 国外电子测量技术 Vo1.25,No.9 Sep.,2006 2006年9月 Foreign Electronic Measurement Technology 基于Windows CE.NET实现蓝牙 通讯模块的几种方法 白 炜 刘月松 白万民 (西安工业大学计算机系 西安710032) 摘要:蓝牙通讯技术在嵌入式产品中的应用具有极为广阔的前景,微软公司的Windows CE. NET已经成为了主流的嵌入式操作系统之一。论文给出了在Visual Studio 2005中利用托管码并 分别采用P/Invoke技术、微软蓝牙嵌入式工具包、OpenNETCF类库和利用本机码来开发Windows CE.NET操作系统下蓝牙通讯模块的几种方法,并在其中对P/Invoke技术、托管码开发、本机码开 发等几个关键技术进行了阐述。最后给出了利用托管码和本机码开发蓝牙通讯模块这几种方法的 优劣比较和分析。其内容对于在Windows mobile平台下开发蓝牙设备间的通讯具有一定实用 价值。 关键词:蓝牙Windows mobile P/Invoke托管码本机码 Several methods on developing bluetooth communication module based on Windows CE.NET Bai Wei Liu Yuesong Bai Wanmin (Department of Computer,Xi'an Technological University,Xi'an 710032,China) Abstract:The application of bluetooth communication technology in embedded system has a huge vision,Microsoft Corporation's Windows CE.NET has already become one of the mainstream em— bedded operating systems.The article introduces several methods on developing bluetooth commu— nication module of Windows CE.NET operating system on the basement of Visual Studio 2005 u— sing managed code methods of P/Invoke technology,Microsoft bluetooth embedded tools,Open— NETCF class libraries and using native code.The article expatiates on the key technologies of P/In— voke,managed code method,native code method and gives the capability comparison and the analy— sis to these methods on developing bluetooth communication module using managed code and native code in the end.its content has the certainly practical value tO the people who want to program communication of the bluetooth equipment in windows mobile platform. Keywords:bluetooth,windows mobile,P/Invoke,managed code,native code 0引 言 自1998年,世界九大电子产业巨头共同发起蓝 牙特殊利益集团SIG后,在短短不到十年之内,蓝 讯“最后10m”的问题,从而替代了各种移动信息电 子设备之间的电缆。因此,蓝牙技术在移动计算领 域的应用将十分广阔,它的应用开发也就有很大的 实际意义。 微软公司从1996年起开发了嵌入式操作系统 Windows CE 1.0开始,凭借着其在PC市场上的成 功经验和Windows CE类似于PC机上操作系统的 牙技术已经被应用到如信息家电、电子商务、汽车、 航空、医疗、交通等多个领域。在移动计算方面,蓝 牙技术采用了一种极为经济的形式解决了无线通 作者简介:白 炜(1980-),男,硕士研究生,研究方向为嵌入式系统。 导师简介:白万民,教授,研究方向为嵌入式系统、计算机应用。 维普资讯 http://www.cqvip.com
国外电子测量技术 第25卷 友好熟悉的界面逐渐扩大着自己在嵌入式操作系 统市场的份额。Windows mobile平台是微软公司 针对嵌入式环境下开发的一套嵌入式操作系统,其 主要是指Windows CE.NET,Windows CE.NET 的最新版本为Windows CE 5.0,其中包括3个版 本:以数据为中心的掌上电脑Pocket PC;以语音为 中心的智能手机Smart Phone以娱乐为中心的便 携式媒体中心Portable Media Centers。而在这3 个版本中都可能涉及到蓝牙应用的开发。 在Windows CE.NET的开发上,目前采用微 软公司2005年年底推出的Visual Studio 2005是最 理想的选择。用Visual Studio 2005可以进行利用 C#,或VB.NET等语言开发基于.NET Compact Framework 2.0或1.0的托管码WinCE程序,也可 以利用C++语言来开发基于MFC,ATL或 Win32API的本机码WinCE程序。 因为在微软最新的.NET Compact Framework 2.0的类库中还未包含针对蓝牙通讯模块的类库, 而且目前关于在Windows CE中开发蓝牙通讯模块 应用程序的介绍还很少,同时开发蓝牙通讯技术的 应用需要十分广泛,所以本文将就此进行一些讨论。 l基于托管码开发蓝牙通讯模块 基于托管码的开发就是使用一套运行时环境 (run-time environment)的应用程序接口来开发。 一般情况下,托管码应用程序的开发会比较简单和 快速,并且可跨软件平台和处理器来运行,所以开 发出的托管码也能重新使用并有较高的可移植性。 另外,内存管理、资源管理、资源收集、安全性管理 等琐碎工作都由运行时环境来处理。应用程序开 发工程师不必费心处理。托管应用程序在目标机 器上运行,是通过目标机器端的实时编译器来实时 把托管码编译成目标机器码后在目标机器上执行。 由于在.NET平台下,采用CLR(公共语言运 行时)可以用不同的语言来调用.NET Compact Framework来开发相同功能的应用程序,所以本文 托管码部分仅采用C#语言为例来介绍蓝牙通讯模 块开发。 1.1利用P/Invllie方法编写蓝牙通讯模块 蓝牙通讯模块是一个涉及到驱动硬件的应用 程序开发,而.NET Compact Framework并不是一 个对Win32API进行了完整封装的类库。所以在基 于托管码开发蓝牙通讯模块中必须利用到托管代 码如何与非托管代码交互技术。P/Invoke全称为 Platform Invoke,是.NET开发平台下允许托管代 码调用DI I 库的本地代码函数的服务,类似于JA— VA中的GNI的概念。图1说明了P/Invoke方法 的工作原理。首先用相应语言的编译器将托管的 源代码编译成Assembly的形式,其中包括元数据 和中问语言代码。而此时P/Invoke的声明会以元 数据的形式存在于Assembly中,当Assembly被 CLR调用的时候,CLR会根据元数据的声明在对 应的DLL函数中查找DLI 的实现。如果找到,就 将其加载到内存中,并定位此DI I 函数的入口点。 将托管的参数人栈,并将函数的入口点指向对应的 native dll,从而完成了托管代码调用非托管代码 的DLL。 托管码 图1 P/Invoke方法的工作原理图 利用P/Invoke方法编写蓝牙通讯模块,Dlllm— port属性非常有用。下面的代码将用例子说明此 通用方案,例中托管程序将调用MessageBox(位于 User32.1ib中): #using<mscorlib.dll> using namespace System::Runtime::InteropSer— vices; namespace SysWin32 { [Dlllmport(”user32.dll”.EntryPoint一”Mes— sageBox”,CharSet—Unicode)] int MessageBox(void*hWnd.wchar_t*lpText. wchar_t*lpCaption,unsigned int uType); 维普资讯 http://www.cqvip.com
2006年第9期 白炜,等:基于Windows CE.NET实现蓝牙通讯模块的几种方法 29 } int main() { SysWin32::MessageBox(0,L”Hello world!”,I ” Greetings”,O); } 注意包含DllImport的代码行。此代码行根据 参数值通知编译器,使之声明位于User32.dll中的 函数,并将签名中出现的所有字符串(如参数或返 回值)视为Unicode字符串。如果缺少EntryPoint 参数,则默认值为函数名。另外,由于CharSet参数 指定Unicode,因此公共语言运行库将首先查找称 为MessageBoxW的函数。如果运行库未找到此函 数,它将根据调用约定查找MessageBox以及相应 的修饰名。 当调用用户定义的DLL中所包含的函数时,有 必要将extern”C”添加在DLL函数声明之前,如 下所示:extern”C”SAMPLEDLL—API int fnSam- pleDLL(void); 在调用非本机码时,需要注意的是要将非结构 化参数由托管封送处理为本机码形式。可以利用 CharSet参数值的作用,将参数中字符串(string* 类型)都自动转换为wchar—t 。同样,所有Int32 参数类型转换为非托管int,UInt32参数类型转换 为非托管unsigned int,而Int16参数类型转换为了 short int。char 用于Ein]参数的为String (Char— Set—Ansi),用于EouQ参数或返回值的为Text:: StringBuilder 。wchar—t 用于[in]参数为 String (CharSet—Unicode),用于Eout]参数或返 回值的为Text::StringBuilder 。需要注意的是函 数指针必须具有 st&all调用约定,这是因为这是 DllImport支持的唯一类型。对于数组来说数组(如 wchar_t E1),CharSet参数仅应用于函数参数的根 类型。因此,无论CharSet的值是什么,String ~ geE]都将被封送处理为wchar_t*[]。除简单类型 外,运行库还提供了一种机制,可以将简单结构由 托管上下文封送处理为非托管上下文。简单结构 不包含任何内部数据成员指针、结构化类型的成员 或其他元素。 在做一个关于蓝牙通讯程序前,还需要一些关 于蓝牙的基础知识。一个蓝牙模块程序需要包含 开启蓝牙,配对,连接,建立串行通道,然后开启通 讯过程,还需要在应用程序中设置串行端口。因为 蓝牙技术有安全方面的设置,所以需要对蓝牙设备 进行配对。蓝牙的工作状态总共有3种,分别为开 启、关闭、可发现。并且所有的通讯设备都必须有 一个对应的DeviceID,蓝牙也不例外,蓝牙的Devi— ceID是一串以“:”分隔的l6进制的数字。有了上 述知识,就可以在托管码中利用P/Invoke方法开始 编写蓝牙通讯模块了。 对应的每一步需要调用的基本函数如下: ・获取本地设备的ID EDllImport(”Btdrt.dll”,SetLastError=true)] public static extern int BthReadLocalAddr(byte E] PBa); ・获取远程设备的ID EDllImport(”ws2.dll”.EntryPoint一”WSALook— upServiceBegin”,SetLastError=true)] public static extern int CeL∞kupServiceBegin (byteE]pQuerySet,LookupFlags dwFlags,ref int lphLookup); ・监听服务 EDllImport(”ws2.dll”,EntryPoint=”WSASetSer— vice”,SetI astError=true)] public static extern int CeSetService (byteE]pQuerySet,RNRSERVICE—REGISTER, LookupFlags dwFlags); ・连接 EDlllmport(”mscoree”,EntryPoint=”@339”)] public static extern int connect(int S,byte[] name,int namelen); ・蓝牙的安全设置 获取配对码请求: EDlllmport(”Btdrt.dll”.SetLastError=true)] public static extern int BthGetPINRequest(byte[- ̄ pba); 设置配对码: EDlllmport(”btdrt.dll”.SetLastError=true)] public static extern int BthSetPIN(byte[]pba,int cPinLength,byte[-]ppin); 创建ACL连接: EDlllmport(”Btdrt.dll”,SetLastError=true)] public static extern int BthCreateACLConnection (byteE]pbt,ref ushort phandle); 然后是配对码验证: EDlllmport(”Btdrt.dll”.SetLastError=true) ̄ 维普资讯 http://www.cqvip.com
30 国外电子测量技术 第25卷 public static extern int BthAuthenticate(byte[] pbt); 然后一定要关闭连接: [Dlllmport(”Btdrt.dll”,SetLastError=true)] public static extern int BthCloseConnection(ushort handle); ・设置蓝牙无线电状态 [Dlllmport(”BthUtil.dll”,SetLastError=true)] public static extern int BthSetMode(RadioMode dwMode); 在建立好蓝牙设备的连接后,就可以进行两个 蓝牙设备之间的通讯了。由于可以将蓝牙通信当 作一个虚拟的串行通信来处理,所以在建立通讯的 过程中可以采用类似于串口之间的通讯方式。而 关于串口通讯这方面资料很多,本文就不具体详 述了。 1.2 利用微软蓝牙嵌入式工具包编写蓝牙通讯 模块 微软蓝牙嵌入式工具包是微软公司新推出来 基于.NET Compact Framework 2.0的一款专门用 来快速开发蓝牙应用程序的工具包,直接在.NET 平台下直接调用其中类库。可以快速,简单的开发 一般的蓝牙应用程序。不过该工具包只能在win— dows CE 5.0下使用。利用工具包可以完成:启动 一个蓝牙服务,寻找周边蓝牙设备,连接已存在的 蓝牙设备或者服务。工具包可以在微软网站下载。 利用此工具做两个蓝牙设备间进行简单文本 传输的程序部分代码如下: Server端: Guid serviceGuid—new Guid(”{8 1 5 5 3B2B-FF0B- 4415—86C9—22B799058B81}”); ServerHandle sh—btscore.CreateService(ser— viceGuid); NetworkStream ns=sh.AcceptConnection(); Sting dataToSend=’’Hello”; Byte r]dataBuffer—System.Text.ASCIIEncod— ing.ASCII.GetBytes(dataToSend); ns.Write(dataBuffer,0,dataBuffer.Length); ns.Flush(); ns.Close(); Client端: PairedDevices=btsCore.GetPairedDevices(); Foreach(BluetoothDevice device in pairedDevices) {pairedDevicesListBox.Item.Add(device.device— Name);} Guid serviceGuid—new Guid(”{01550D2【)_FF0D- 4415—86C9—22B799O58B81}”); If(pairedDevicesListBox.SelectedIndex ̄一0) {BluetoothDevice deviceToConnect 一(BluetoothDevice)pairedDevices I pairedDevic— esListBox.Selected]; NetworkStream ns—btsCore.Connect(deviceTo— Connect,serviceGuid); byte[-]buffer=new byte[2000]; ns.Read(buffer,0,50); char[]bufferAsChars—System.Text.ASCII.Get— Chars(buffer); System.String s—System.Text.Encoding.ASCII. GetString(buffer,0,buffer.1ength); Message.Show(s); ns.Close();} 1.3利用OpenNETCF编写蓝牙通讯模块 OpenNETCF是一个可以有效提高Windows Mobile开发效率的第三方开源类库。是一帮win— dows Mobile爱好者共同编写的,里面提供了很多 在.NET Compact Framework 2.0中未能包含的类 库。有两种方式可以来使用它:一种是可以将其当 作一个组件安装在Visual Studio2005中;另一种是 可以将其原代码编辑拿来使用。在OpenNETCF 开源类库中就包括有蓝牙方面的,所以也可以利用 OpenNETCF来编写蓝牙通讯模块。对应类库可在 Ⅵ九^rw.opennetcf.corn网站下载。在类库中,可以利 用命名空间OpenNETCF.IO.Ports下的Blue— toothSerialPort来建立蓝牙连接,利用命名空间 OpenNETCF.IO.Serial中内容进行蓝牙程序的 通讯。 2基于本机码开发蓝牙通讯模块 本机码应用程序是使用一套特定软件平台的 应用程序开发接口来开发,并且被编译成一个特定 处理器的目的码或机器码。一般情况下,本机码提 供较高的效能和最小的资源要求,但是被编译好的 本机码或是可执行文件却只能在此软件平台或特 定处理器上运行。此外,本机码应用程序常需要应 用开发者自行处理类似内存管理、资源管理、安全 性管理等。在Visual Studio 2005中已经可以利用 维普资讯 http://www.cqvip.com
2006年第9期 白炜,等:基于Windows CE.NET实现蓝牙通讯模块的几种方法 31 C++语言来开发基于MFC,ATL或Win32API的 有开发针对蓝牙通讯模块的类库,所以利用P/In— 本机码WinCE程序。这就提供了类似于用eMbed— voke方法编写蓝牙通讯模块是在托管码下开发蓝 ded Visual C++来开发windows mobile设备的方 牙通讯模块比较常见的选择。而微软蓝牙嵌入式 法。而本文在利用P/Invoke方法编写蓝牙通讯模 工具包和OpenNETCF类库编写蓝牙通讯模块方 块时介绍的就是调用本机码开发蓝牙应用程序,方 法比较类似,其都是类库对底层API的类封装,所 法类似,所以此处就不再进行具体的分析了。 以开发起来较为简单和快速,更适合于一般要求的 3结束语 蓝牙通讯模块的开发。 蓝牙设备在嵌入式环境下的应用有着十分广 本文讨论了在Visual Studio 2005里分别利用 阔的前景,目前还有很多工作尚需研究。解决如何 托管码和本机码来开发Windows mobile设备蓝牙 在windows mobile平台下开发更好更高效的蓝牙 通讯模块的几种方法。文中介绍的蓝牙通讯模块 应用程序能够推动蓝牙技术在嵌入式产品上的更 各种开发方法都有各自的优点和缺点,如果用户开 好利用。这一方面的开发将具有极强的实用性,将 发的蓝牙通讯设备需要较高的效能和最小的资源 成为以后研究工作的重点。 要求,一定是采用本机码的方法来开发是最好的。 因为采用本机码开发的程序是直接被编译成机器 参考文献 码来执行的,从而可以获得更高的性能。但是采用 [1]Andy Wigley,Stephen Wheelwright.Microsoft.NET 本机码来开发程序的最大缺点就是开发难度大,开 Compact Framework技术内幕[M].北京:清华大学出 发周期长,所以并不适用于一般要求的用户。而在 版社. 对效能和资源要求并不是很高的产品中采用文中 [2]李静,奉继辉,王婷,等.蓝牙应用开发指南[M].北京: 所述的托管码中的几种方法来开发蓝牙通讯模块 科学出版社. 则是更好的选择,用托管码开发的程序会比较的简 [3]傅曦,齐宇.嵌入式系统Windows CE开发技巧与实例 单和快速,同时又由于其并不直接生成最终的机器 [M].北京:化学工业出版社. [4]周毓林,宁杨,陆贵强,等.Windows CE.net内核定制 代码,而是生成了中间代码来执行,所以用托管码 及应用开发[M].北京:电子工业出版社. 开发的程序可以跨平台和处理器来运行,但是这是 [5]NET平台下第三方开源类库[OL].http: www. 以牺牲一定的访问速度为代价的。在基于托管码 opennetcf.org/ 开发蓝牙通讯设备中本文共介绍了3种方法,因为 [6]微软MSDN[OL].http://msdn1.microsoft.com/en- 到.NET FRAMEWORK 2.0的时候微软公司都没 us/default.aspx 术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术术米 (上接第18页) 参考文献 [4]周旭.电子设备防干扰原理与技术[M].北京:国防工 业出版社,2005. [1]Mark I.Montrose.Printed Circuit Board Design Tech— [5]杨克俊.电磁兼容原理与设计技术[M].北京:人民邮 niques for EMC oCmpliance[Z].IEEE PRESS Editorial 电出版社,2005. oBard,1996. [6]周开基.电磁兼容性原理[M].哈尔滨:哈尔滨工程大 L 2]Norman J L,et.a1.Electromagnetic Compatibility 学出版社,2005. Handbook[Z].New York:Van Nostrand Reinhold [7]陈穷,译.电磁兼容设计手册[M].北京:航空工业 oCmpany,1987. 部,1988. [3]区健昌.EMI滤波器和开关电源防护设计[J].安全与 [8]林国荣.电磁干扰及控制[M].北京:电子工业出 电磁兼容,2002(3). 版,2003.
因篇幅问题不能全部显示,请点此查看更多更全内容