(源自:http://www.j2medev.com/windowsmobile/ShowArticle.asp?ArticleID=5102)
(一)Windows CE概述
这篇文章的目的并不是介绍Windows Embedded CE开发的方方面面,只是用一个初涉嵌入式领域的软件开发者的视角来介绍Windows CE开发中最常用的概念和知识,解决大家会在实际开发中碰到的一些小问题,让大家了解嵌入式开发与应用程序开发,到底有哪些不同。
Windows CE概述
从6.0版本开始,Windows CE的名字改为Windows Embedded CE,当然这也是为了结合Windows Embedded品牌作出的改变。CE经过了十年的风风雨雨之后,终于在CE 6.0这个版本上再次浴火重生了。CE 6.0经历了CE历史上第二次内核重写,使CE操作系统更加符合当今嵌入式开发的方向。
CE 6.0在内核方面的改变主要是为了适应嵌入式设备硬件发展的要求,在进程数量方面,从过去最多运行32个进程,改变为最多运行3万2千个进程,内存方面从每个进程最多拥有32M虚拟内存空间改为最多拥有2G虚拟内存空间。在OS布局方面,将关键的驱动程序、文件系统和图形界面管理器(GWES)移到了内核中,这样可以更好解决因为CPU在内核态和用户态间切换而造成的性能损失。
当然,从以上的改变,我们可以看到CE 6.0较之前版本更加“重量级”了。操作系统领域关于“微内核”的争论已经持续了很多年,CE的改变也许会为某个学派的观点提供支持。但我们必须指出的是,正因为目前的嵌入式设备硬件已经可以支持比较“重量级”的操作系统了,所以CE 6.0才会做出如此改变。
CE针对开发者的另一个转变开始自CE 5.0,将开发环境Platform Builder整合到Visual Studio中,这种做法无疑减轻了微软维护两套IDE的负担,从另外一个方面来看,CE的开发者也可以享受到更好的开发体验了。
嵌入式开发流程
也许很多初涉嵌入式开发领域的程序员会被一系列的新名词搞得头昏脑胀,在这里,我希望能够将嵌入式开发的流程展现给大家。
嵌入式开发主要分为三个比较大的部分:
l 驱动程序开发
这部分开发是从硬件设计开始的,硬件工程师会设计PCB板,为我们提供标准开发板(SDB,standard development board)。当我们拿到开发板之后的第一件事情就是编写boot-loader,让开发板启动起来,一般是通过JTGA将boot-loader烧录到开发板中的。我们可以将boot-loader看作PC中的BIOS,负责硬件设备的初始化工作,并且将操作系统运行起来。在此之后,我们需要根据开发板上的硬件开发各种驱动程序,比如串口、USB、鼠标、视频输入等。最后将这些驱动程序和boot-loader打包,称为一个板级支持包(BSP)。BSP是和开发板的具体硬件紧密相关的。
所以从事这方面开发的工程师往往具有比较强的硬件知识水平。
l 平台定制
我们可以将Windows CE想象为一盒积木,根据不同的应用场景和设备要求,我们要对这盒积木进行定制,堆积出不同形状的城堡、动物和生活用品。这个过程称为“平台定制”,定制产生的平台往往和具体的硬件设备相关,直接将平台下载到硬件设备上就可以运行了。整个开发过程,需要选择不同的组件来搭配出最适合当前硬件的软件平台。所以要对Windows CE的组件,也就是Catalog Item,有相当程度的了解。
l 应用程序开发
嵌入式设备上的应用程序开发与传统应用程序开发类似,只是要借助于硬件模拟器或者实际设备对程序进行调试。最常见的嵌入式设备应用程序开发,就是Windows Mobile的移动应用开发。平台定制工程师会在硬件出厂之前先提供平台相关的SDK,SDK中会包括模拟器。应用开发者可以首先使用模拟器对程序进行开发和调试。等实际硬件出来之后,再将程序转移到实际硬件中。因为Windows CE采用了很多措施,这种“转移”几乎是无缝的,所以我们并没有使用“移植”这个词。
嵌入式领域的应用开发其实是普通软件工程师就可以进行的。
下图是对嵌入式开发整个流程的图示:
Windows CE开发流程图
在下一节中,我们会借助实际的硬件开发板,来逐步介绍嵌入式开发环境的搭建、平台的部署和调试、应用程序的部署和调试等话题。
(二)CE开发环境
下面就要让今天的主角闪亮登场了——Digi CC 9P开发板。为了感谢Digi提供的开发板,还是给他们做个广告吧:这是一家以WiFi相关产品为主营业务的公司,也生产ARM架构的CPU,所以做开发板也是他们公司份内的事情了。总的感觉还不错,大家如果有兴趣可以访问www.digiembedded.com,了解更多关于Digi开发板的情况。
下图就是Digi开发板的实拍照片,感谢我的ET900,效果还不错:
Digi CC 9P 开发板
从图上我们可以看到,这块开发板上并没有附带LCD屏,所以我们需要通过VGA输出连接一台显示器,图中上方蓝色的接口为VGA输出;左侧的接口从上到下,分别是:DC电源,RJ45以太网接口,RS232串口;右侧还连着我那久经考验的鼠标:)
因为设备环境变量、启动eboot等命令都需要通过串口发给开发板,所以我们需要通过串口线将连接开发板与PC串口相连。因为我的笔记本没有串口,所以我使用了一个USB到串口的转换器,工作一切正常。
当我们将平台编译完成后,Image文件(NK.bin)是需要通过网线下载到开发板的RAM中的,采用网线的优势是速度比较快。关于网线的连接,有两种选择:使用直连线,将PC与开发板的以太网口直接相连,这也是成本最低的一种方式;另外一种方式,是使用带DHCP功能的路由器,将PC和开发板的网线连接到路由器上。在实际开发中,我选择的是后一种方法,原因是路由器比直连网线好找……
在硬件连接完成后,我们要讨论的就是开发环境的安装了,整个过程可以需要几个小时的时间,不过这个依赖于具体的机器。
在Digi CC 9P开发包中包括了Visual Studio 2005和Platform Builder 6.0的180天验证版。在安装PB的过程中,需要输入KEY。这个KEY可以通过在微软网站上注册获得,注册地址如下:http://www.microsoft.com/windows/embedded/eval/getregistration.mspx
我们在安装完Visual Studio 2005之后,应该首先安装VS 2005 SP1,然后再安装PB 6.0。毕竟PB是作为一个插件出现在VS 2005中的。接下来还需要安装PB 6.0 SP1,可以在微软网站上下载,下载地址为:
在安装完VS 2005和PB 6.0之后,我们还应该安装Digi的资源光盘。
我们首先应该安装的是Digi 9P的BSP,BSP中包含的是与开发板相关的boot-loader 和驱动程序。也就是说,前边我们说过的“驱动程序开发”部分,Digi已经帮我们做好了。我们所需要关注的就是“平台定制”与“应用开发”。当然,如果需要自定义boot-loader,还可以选装boot-loader的源代码,以及GNU X编译环境。在boot-loader开发方面,并没有一个统一的开发环境,硬件厂商往往根据自己的需求而选择不同的开发工具来进行开发,比如ARM的SDT等开发环境。Digi使用的则是GNU X,可能是为了兼容 Embedded Linux的方便吧?
完成软件和硬件的安装之后,我们就可以进行CE的平台定制开发了。怎么样?看起来也不是很难哈。
(三)设置Boot-loader
在Digi CC 9P开发板中已经预置了Boot-loader和一个CE 6.0的系统,所以,我们直接启动开发板,就可以运行一个CE 6.0的操作系统。不过,我们的最终目的是要开发一个自己的CE 6.0平台,所以我们需要对Boot-loader中的一些系统变量进行设置。
Boot-loader相当于PC中的BIOS,当硬件被reset之后,首先执行的就是boot-loader。Boot-loader首先对硬件进行初始化,然后引导操作系统运行。Boot-loader是嵌入式开发中相当重要的程序,因为它与硬件设备密切相关,所以Boot-loader的开发是由硬件厂商完成,它也是BSP的一部分。这也决定了不同的硬件厂商对Boot-loader有不同的实现,我们这里以Digi为例,涉及到对boot-loader的设置仅对Digi的开发板有效。如果使用了其他厂商的开发板,请参考相关的说明文档。
Digi开发板支持从串口输出一个命令行来对Boot-loader的行为进行控制,以及设置一些环境变量。所以我们需要通过“超级终端”,来进行设置。
将开发板的串口与开发机器的串口相连,如果没有串口则需要一个USB到串口的转换器。需要主意的是,在Vista中没有“超级终端”,我们可以从XP上将hypertrm.exe和hypertrm.dll拷贝到Vista中。
创建一个新建连接后,输入连接名称,然后选择COM口。
然后设置串口的波特率为38400,数据位8,无奇偶校验,停止位1,数据流控制None。最后点击确定,我们就进入了超级终端的主界面。
确认开发板的电源、与PC串口等连接正确,打开开发板的电源。Boot-loader会从超级终端中输出命令行。如果我们不进行干预,Boot-loader会启动Flash Rom中的CE 6.0系统。我们为了设置环境变量,所以要中断启动过程,在命令行提示“Hit any key to stop autoboot”时,我们按任意键,就会出现一个命令行提示符。
我们在命令行里输入:
setenv ipaddr 192.168.0.150
setenv netmark 255.255.255.0
setenv serverip 192.168.0.198
saveenv
第一句是设置开发板的IP地址,第二句是设置开发板的子网掩码,第三句是告诉开发板,开发PC的IP地址。如果不知道开发PC的IP地址,可以在命令行里输入ipconfig获得。因为我们将开发PC和开发板用带DHCP的路由器连接,所以,路由器会自动为开发PC设置一个IP地址。最后要调用saveenv,讲系统设置写入到Flash中。
为了让开发板重新启动,在命令行中输入reset。当超级终端中再次显示“Hit any key to stop autoboot”提示时,我们不要按任何键,让开发板内置的CE操作系统启动。
CE 6.0操作系统运行之后,显示器将会显示如下的画面:
为了确定开发板与PC的网络连接是否正确,我们在PC的IE中输入“http://192.168.0.150”,也就是开发板的IP地址。IE浏览器将会访问开发板中的Web Server。如果出现下面的画面,则说明网络连接正确。
当开发板设置完成之后,接下来,我们就可以进行自己的开发工作了。
(四)跑个应用程序先
因为我们的开发板上已经预置了Windows CE 6.0的系统,所以我们可以先创建一个.NET CF的应用程序,来看一下如何将.NET CF程序部署到Digi开发板上。
第一步,首先在Visual Studio 2005中创建一个新的工程。这一步和开发普通的Windows Mobile应用程序基本一样,不同的是,要选择“Windows CE 5.0”的平台。Digi开发板的操作系统是CE 6.0,但是这里我们选择CE 5.0也不会影响部署的正确性。
在开发Windows Mobile的过程中,我们一般是通过USB接口连接PC的ActiveSync。但是目前我们的Digi开发板还没办法使用USB连接ActiveSync。所以我们要修改一下调试工具连接的方式。
在Tools菜单中选择Options菜单项,打开Device Tools节点,然后选择Devices。在Windows CE 5.0平台下,只有Windows CE 5.0 Deivce,我们点击Properties按钮。
接下来会出现的CE Deivce属性,Transport里默认选择就是TCP Connect Transport,因为ActiveSync其实也是模拟出网卡来的。点击Transport后边的Configure按钮。
在TCP/IP Transport页面里,我们就需要进行设置了。选择使用指定IP地址:192.168.0.150,这个地址就是开发板的IP地址。
在完成设备IP地址的设定后,我们就可以编译并部署应用程序了。首先选择Windows CE 5.0 Device作为部署设备,点击后边的“连接设备”按钮。如果连接成功,我们可以点击Debug按钮开始调试。
如果设备连接成功,就会显示如下的对话框。我们就可以开始调试程序了。
最后是应用程序在开发板上的运行情况。这个Demo是为了MVP Open Day 2007准备的。在我辛苦写文章的同时,这些“腐败份子”们都在三亚花天酒地。写这篇Blog,也是希望有关部门注意一下这群“腐败份子”。
(五)构建CE平台
接下来的一节会有非常多的图,因为我们要在Visual Studio 2005里创建一个CE 6.0的平台(Platform)了。创建CE平台的方法和创建普通工程的方法类似。在完成了Platform Builder之后,我们打开Visual Studio 2005后,选择File-New-Project菜单:
在New Project对话框中,选择Platform Builder for CE 6.0,这个项目不安装PB 6.0是没有的,项目模板里只有OS Design一项。选择这一项,为要创建的平台命名为“Digi9POS”,工程的位置选择默认即可。点击OK之后,我们会看到下面的欢迎界面:
点击Next,进入下面的界面:
在这个界面中,我们需要选择该平台所用的BSP(板级支持包),一般来说,一个平台只会针对一个硬件平台,而BSP与硬件平台是一一对应的关系。在这里我们选择“ConnectCore 9P”这个BSP,支持的CPU类型是ARMV4I。
点击Next:
接下来选择的是设备类型,有很多默认设备类型的模板,比如:PDA Device、Phone Device等。这些设计模板已经根据不同的设备类型进行了预先的定制,加入了适当的组件。如果想完全从头设计一个平台,可以选择“Custom Device”,在这里我们选择“ConnectCore 9P Device”,可见Digi为我们提供的不仅仅只有BSP,还有平台设计模板。点击Next:
接下来选择的是:是否支持显示设备,如果选择ConnectCore 9P,则可以通过VGA输出获取图形界面的显示,如果选择ConnectCore 9P Headless,则不会有VGA输出,我们只能靠板子上的LED获取信息了。Headless设备对于某些工作场合还是非常适用的。
到这里,我们就可以点击Finish按钮,完成平台定制向导了。如果此时结束向导,则平台会按照默认值进行定制。但是为了让大家了解,平台定制的过程中会包括哪些组件,我们会将这个向导一直走完。需要提醒的是,在向导中选择的组件,我们同样可以在IDE中进行选择。继续Next:
接下来选择的是.NET Compact Framework,很重要的组件。在CE 6.0之前,PB中内置的是.NET CF 1.0 SP2,而到了CE 6.0的时代,我们终于可以看到.NET CF 2.0了。不过想看到.NET CF 3.5,恐怕还需要点时间。保持默认值,继续Next:
下面是关于网络设置的选择,我们添加了对局域网LAN的支持,还有FTP Server、Telnet Server和Web Server。其中FTP Server会引发一个安全警告,不过我们需要这个组件来下载编译好的Image文件。保持默认,继续Next:
下面是关于Debug工具、显示支持和USB Host支持的。这里我们要选择“USB Host Support”(图中红色部分),这个选项允许我们的设备称为USB Host,可以访问一些通过USB接口连接的外部设备,比如鼠标、U盘等。Next……
接下来是文件系统,设备支持FAT文件系统,注册表是基于RAM的。Next……
浏览器软件,IE 6.0,Next……
接下来是Shell,会有命令行窗口,使用标准的Shell,会包括软键盘(SIP),我们在这里选择了两个尺寸的键盘。Next……
Remote Tools 的支持文件,Next……
接下来是应用程序支持,支持Visual Studio 2005调试器的选项必须被选择,下面部分是Digi提供的应用程序Demo,用来控制GPIO、I2C等硬件接口,Test_SPI不是默认选择的,在这里我们将这个应用选择上。Next……
设置内存尺寸,因为我们的开发板是64M内存,所以在这里别无选择,Next……怎么还没完啊?
硬件驱动程序,保持原状就好了……Next
呼,看到这个界面,说明我们完成了整个创建向导。赶紧点击Finish……
因为我们选择了FTP Server组件,所以会有一个安全警告出来,点击Acknowledge按钮。接下来,我们就可以看到熟悉的IDE开发环境了。默认的IDE布局与原有Platform Builder类似,工程文件列表、类列表和Catalog Item列表都放置在IDE左侧,但是我们也可以通过拖拽的方式来修改IDE布局。
下图是Solution Explorer的截图,这就是定制平台工程中所包括的所有文件。
(六)平台定制
Windows CE是一个组件化的操作系统,我们可以根据不同的环境设置不同的组件来组合成有针对性的平台,而一个功能往往需要多个组件才能够实现。Catalog就是实现某个功能的组件集合,每个Catalog Item会包含一个或多个组件,而Catalog Item则需要实现某种功能。当我们的平台需要这个功能是,就将相对应的Catalog Item选入平台中即可。
在完成了平台创建的向导之后,我们就进入了PB的IDE界面。Catalog Items视图与Solution Explorer处于同一区域,两者间可以*进行切换。
在Catalog Items视图中,我们可以看到CE中包含的Catalog大概可以分为下面几类:BSP(板级支持包); Core OS(操作系统中包含的组件);Device Drivers(驱动程序类);Platform Manager(平台管理器)和Third Party(第三方提供的组件)。其中实现功能的组件大都包含在Core OS中。
我们如果要为平台增加游戏,则选择“Core OS” – “CEBASE” – “Application – End User”- “Games”下的游戏:Freecell和Solitaire两个游戏。
除了能够为平台增加Catalog外,我们还可以增加自己的文件和注册表信息。
将视图切换回Solution Explorer,我们可以看到平台中包含的所有文件。其中,选择“Parameter Files”中的“ConnectCore 9P”,其中会包含 project.reg文件,双击点开该文件,我们就可以增加一些注册表信息。这些注册表信息,将会出现在目标设备的注册表中。
除此之外,在C:/WINCE600的PLATFORM - CC9P – Parameter Files下,我们还可以看到platform.reg文件。Platform.reg文件是针对所有运行于CC9P开发板上的平台,而project.reg只是针对目前的开发平台。
如果想在平台中加入自己的文件,则需要使用bib文件了。如果想引入一些批处理操作,则要使用dat文件了。我们通常使用project.bib和project.dat文件。
Bib文件的标准格式为三个部分: 目标文件名,源文件路径和名称,Memory Type。目标文件名指的是在目标设备上的文件名,如果没有指定路径,则默认出现在/Windows目录下。第二部分是源文件路径和名称,指的是文件在PC上的路径;最后指定的是Memory Type,如果是想让文件被编译到NK.bin中,则要指定为NK。三个部分之间使用空格隔开即可。同时bib文件支持宏。我们可以通过指定不同的环境变量,来为NK.bin中加入不同的文件。
指定环境变量的方法如下:在Solution Explorer中右键点击DigiOS,在菜单中选择Properties。在属性对话框中,选择Environment,然后,我们就可以添加自己的环境变量了。
环境变量有两个值:1或者<空>。在这里我们创建一个名为“IMG_NETCF_CSAPP”的环境变量。如果该变量为1,则bib文件,会包含hello_mvp.exe文件到NK.bin中。
如果我们还想执行一些其他操作的话,就必须借助于dat文件了。这里的dat文件和PC平台上的一样,也是批处理文件。比如,我们可以讲一个快捷方式文件(.lnk)从/Windows目录下拷贝到/Windows/Startup目录下。这样,在操作系统启动时,就会执行lnk文件相对应的可执行文件了。
好了,进行到这里,我们平台定制的工作就可以告一段落了。我们学习了如何向平台中添加Catalog Items、文件和注册表项,还可以执行批处理操作。接下来,我们就可以对定制好的平台进行编译和调试了。