通过远程控制程序,开发人员可以从宿主机上远程地对目标机的运行状况进行监视和控制。宿主机和目标机之间一旦建立了远程控制连接,开发人员就可以进行下列操作:下载宿主机的文件到目标机、监视目标机处理器的状况和各个线程及进程、监视并且分析目标机内核或者应用程序的处理性能等。
在Platform Builder和Embedded Visual C++中都包含了下列远程工具:
n Remote Call Profiler
图8-1 选定远程工具
|
n Remote Heap Walker
n Remote Kernel Tracker
n Remote Performance Monitor
n Remote Process Viewer
n Remote Registry Editor
n Remote Spy
n Remote System Information
n Remote Zoom-in
这些功具可以通过Platform Builder或者EVC中的Tools下的菜单来选定,如图8-1所示。
每一个远程控制程序在系统中都只能运行一个实例。有一点要特别注意:Remote Call Profiler和Remote Kernel Tracker程序不能同时运行,由于它们都对系统内部调用进行了跟踪,因此如果同时使用会引起采样点缓冲区堆栈的冲突。其他的远程控制程序中可以运行多个窗口。
在Platform Builder 4.0版本之前,Windows CE是不支持Remote Call Profiler程序的,但是支持其他远程控制程序。在Platform Builder 4.0以后,平台对Remote Call Profiler提供了完美的支持。但是,通常对学习Windows CE的开发人员来说都使用Windows CE standard SDK,这个SDK对Remote Call Profiler的支持是很弱的。笔者使用Remote Call Profiler来连接Windows CE standard SDK的时候,经常发生目标机相关EXE文件(ConPmon.exe)未能正常启动的错误。在不断的尝试后发现这个问题的原因在于standard平台功能选择的时候没有加入profiling support选项,因此内核不支持性能评测程序。而大部分嵌入式软件开发人员一般只用EVC而不用Platform Builder,这样就无法在standard SDK上进行profile程序验证,如果使用的特定的SDK不支持profile的话,同样也无法进行性能调整。后面的小节中将通过实验来解释如何使Remote Call Profiler正常运行,并且获得开发人员所需要的、可理解的各种性能监测数据。
表8-1是Platform Builder和Microsoft Embedded Visual C++ 4.0提供的远程工具的各种功能。
表8-1 远程工具的各种功能描述
工 具 | 功 能 |
远程性能评测程序 | 提供了基于图形界面的目标机性能检测和分析功能。通过这个程序,开发人员不但能够获取目标机的运行数据,而且可以将这些数据以非常容易理解的图形化的方式显示出来,这些图形化方式包括了调用树结构、事件追踪显示,调用结点图显示。使用这个程序可以帮助开发人员寻找到系统或者应用程序的瓶颈所在。在linux中也有相关的性能测试程序,开源项目名称为Oprofile,有兴趣的读者可以参考一下 |
远程文件浏览程序 | 显示了目标机文件系统中的各种文件,开发人员还可以通过这个程序将宿主机的文件下载到目标机,其内部原理可以基本认为是像linux那样使用的FTP服务在宿主机和目标机之间进行文件传输 |
远程堆查看程序(Remote Heap Walker) | 显示了目标机上运行的各类进程的堆的使用情况 |
远程内核跟踪程序 | 显示了目标机内核追踪、执行顺序的信息 |
远程性能监视程序 | 对目标机总体性能进行评估 |
远程进程浏览程序 | 对目标机的进程运行状态信息进行监视 |
远程注册表编辑程序 | 显示了目标机的注册表信息,并且提供在宿主机上对其进行修改的功能 |
远程Spy程序(Remote Spy) | 显示了目标机上所打开的各个窗口的信息,以及它们所产生的各种事件 |
远程系统信息获取程序 | 显示了系统的各种设置和属性 |
远程桌面图像获取程序 | 从目标机桌面获取图像 |
8.1 模拟器
正如各自平台功能的不同,Platform Builder下的模拟器用来调试内核、驱动,EVC下的模拟器用来调试应用程序、DLL等。模拟器能够模拟Windows CE操作系统,使用宿主机的硬件环境。在硬件平台还没有成型的前提下,或者程序员开发与硬件无关的软件时,模拟器能起到很大作用。模拟器启动运行简单,不像实际的开发板的操作那样复杂,即使想重新启动模拟器多次,也不会花去很少时间。但是,模拟器运行在用户态下,它毕竟是一个应用程序,因此它的实时性是无法保证的,它只能一定程度上保证程序非实时性功能的正确性。
目前,模拟器只支持x86平台,它只适合调试基于“Emulator:x86”编译的内核。但是可以调试所有基于x86指令集编译的应用程序、动态链接库、静态链接库。“Emulator:x86”在EVC的“WCE Configuration”工具栏中间编译选项中可以找到。
关于模拟器的硬件限制:
n 仅能模拟DEC 2114x网卡驱动来提供网络支持,其他网卡驱动不支持;
n 仅能模拟FLAT显示驱动,其他显示驱动不支持;
n 不支持USB设备;
n 不支持PC卡、硬盘、CF卡;
n 不支持FAT、CDFS、DVD文件格式;
n 不支持IEEE1394设备。
如果模拟器配置使用了64MB字节的内存,建议用以下配置:
n 1GHz CPU;
n 384MB系统内存;
n 500MB可用硬盘空间。
8.1.1 模拟器的架构
从体系结构来看,模拟器是一个桌面环境中的窗口应用程序,它模拟了目标机的各种硬件接口和操作,例如:PCI总线、声卡、显卡等。
大多数操作系统只允许处理器上运行单独的操作系统,模拟器可以突破此限制,通过模拟硬件操作,直接访问宿主机内存和处理器来实现一个处理器上运行多个操作系统。除了Windows CE的模拟器以外,还有其他的很多模拟器例如著名的VMWare、Virtual PC等。和那些通用的模拟器不同,Windows CE的模拟器只能运行特定版本的Windows CE操作系统。
在开发中,程序员可以很方便地使用模拟器来调试内核和应用程序。但是,任何与时间限制有关的应用程序或者实时程序都不建议使用模拟器进行调试。在模拟器中,由于使用软件模拟了硬件的操作,因此其时序和实际的硬件不完全相同,通常模拟器下的程序运行速度只有同类主频处理器的80%。因此微软公司曾经提示,在模拟器上的程序性能与实际环境下的性能不完全相同。
在普通计算机的操作系统中,系统内核将防止系统级的处理程序在Ring 0或者Ring 1层执行,而把用户态的进程放置在Ring 3层运行。但是模拟器上的所有程序都是作为Ring 3层来运行的,即便模拟器中操作系统的系统级程序也一样,因为模拟器本身就是作为宿主机的一个应用程序来运行的。
目前,模拟器只支持x86芯片。
8.1.2 Platform Manager
在宿主机和目标机之间的连接中,需要使用到Platform Manager。下面通过实验来说明其用法。
实验一:配置Platform Manager
Platform Manager管理着宿主机和目标机的连接功能。在主界面中依次选择Target→Configure Remote Connection可以打开图8-2所示对话框:
图8-2 配置Platform Manager(1)
我们以模拟器为例,进行配置。
首先在图8-2所示的Download下拉框中选择Emulator-4.20,在Kernel下拉框中也同样选择。然后单击Download下拉框右侧的Configure按钮,将出现如图8-3所示的对话框。
在图8-3的示的ScreenSize中设置了模拟器的界面像素,对于Platform Builder这样比较消耗内存的程序来说,还是尽量将像素减小,同时用256色(选择8)。
在System选项组的Memory下拉选框中设置模拟器中预留给操作系统的内存,这部分内存只是模拟器从宿主机中分配的内存。一般配置成128MB足够了。
单击“OK”按钮在配置完连接后,在主界面中单击Target,可以看见Conncet命令可用了,这时才能连接宿主机和目标机,下载操作系统。如图8-4所示。
图8-3 配置Platform Manger(2) 图8-4 菜单配置Platform Manager后的Tanget
8.1.3 EVC++中的模拟器
实验二:在EVC++中创建可以使用模拟器调试的应用程序
(1)从主界面的“File”中选择“New Project”命令,进入如图8-5所示的界面。
图8-5 创建新工程(1)
(2)选择MFC项目WCE MFC AppWizard(exe),并且在CPUs中选择Win32 [WCE emulator],然后选择OK。进入如图8-6所示的界面。
(3)单击OK按钮后,根据向导提示继续完成配置,在图8-6所示界面中单击Finish将完成新工程的创建,此时将出现图8-7所示的开发。
图8-6 完成工程创建
图8-7 开发界面
(4)在开发界面中做如下选择:
n 工程选择helloworld
n SDK选择STANDARD SDK
n 版本选择Win32(WCE emulator)Debug
n 模拟器选择STANDARDSDK Emulator
如图8-7所示。
(5)最后先后按下编译快捷方式 和执行命令快捷方式 ,模拟器中将出现如图8-8所示的程序运行界面。
图8-8 编译与执行界面
8.1.4 Platform Builder中的模拟器
Platform Builder中的模拟器和EVC中的大体功能是一样的,但是Platform Builder可以把特定的功能编译到SDK中去,然后EVC再安装这个SDK后,才能使用新的功能。
总而言之,Platform Builder可以对模拟器中的操作系统的特性进行修改,而EVC只能接受对Platform Builder做的改动。
8.2 远程性能评测程序
8.2.1 Platform Builder中的性能评测程序
要使用Remote Call Profiler,必须在程序代码中嵌入profiling钩子,然后将代码的镜像文件下载到目标机中,再启动目标机,连接宿主机上的Platform Builder中的服务。
Remote Call Profiler不仅仅能监测应用程序,同样也可以监测操作系统内核的调用。如果程序使用Platform Builder或者是EVC编写的话,那么可以直接使用两个工具中的下载镜像文件的功能。如果是用其他工具编写的,那么需要把镜像文件复制出来,首先启动Platform Builder或者是EVC,然后启动模拟器服务,再打开远程文件监视程序,将镜像文件通过export file功能传输到目标机上,然后在目标机上启动(双击)该应用程序。这样才能得到监测的数据。
在启动被监测的程序之前,必须将Remote Call Profiler程序连接上目标机。
1.实验
实验三:创建和编译支持Profile功能的内核以及SDK
标准SDK是不支持Profile的,下面介绍如何使用自己的SDK来支持Porfile功能。
首先本章实验一介绍的方法定制一个平台请注意,本实验的目的仅仅是使用Profile功能,而Windows CE是嵌入式操作系统中最消耗内存的,因此为了防止模拟器内存资源的不足,在定制的过程中可以尽量删除不必要的功能。另外,建议读者在内存大于512MB的计算机上进行本实验。
创建完平台之后,先别急着编译,还有选项要设置,选择图8-2所示的Settings选项卡,进入如图8-9所示的对话框。
图8-9 设置选项(1)
选择Build Options对话框,在Enable Profiling前打勾,这表明Windows CE内核将支持监测功能。
最好再记下这个平台的release目录,如图8-10所示,因为release目录下的文件将被复制到模拟器的/release目录下,因此有任何需要在启动时候下载的文件都可以放在这里。
在笔者的计算机上,这个release目录为G:/WINCE420/PUBLIC/Kaola/RelDir/EMULAT~1,EMULAT~1表示EMULATOR_X86Release,类似DOS对操作系统Windows操作系统的长短文件名支持那样。
图8-10 设置选项(2)
单击“OK”按钮后,系统将记录下编译的配置。
然后在主界面依此单击Build->Build Platform菜单,系统就进入平台编译了。
图8-11 选择一个设备
|
实验完毕。
实验四:在Platform Builder下使用Profile功能
在实验三的基础上进行如下操作。
启动模拟器。首先连接Remote Call Profiler工具和模拟器,后下载包含指定的包含Profile调试代码的样例程序到模拟器中。
连接Remote Call Profiler和模拟器。依此单击Tools-> Remote Call Profiler,将弹出图8-11所示的对话框,选择Windows CE.NET Default Platform下的Default Device。
然后选择“OK”。将进入如图8-12所示的界面。
连接完成后,将弹出Collection Control的对话框,如图8-13所示。
Collection Control窗口是在设置连接设备之后弹出的窗口。只能获取嵌入有Profiling钩子的代码的监测信息。
只要在代码中嵌入Profiling钩子,无论是内核级或者是应用级的函数,都能得到它们的性能指标数据。如果要从应用程序获取性能数据,那么应当从Collection Control窗口中启动相应的应用程序。
在此,使用微软公司提供的例子来继续实验,这个示例程序位于Program Files/Common Files/Microsoft Shared/Windows CE Tools/Platman/sdk/wce420/samples/Hello目录下。它是一个很简单的helloworld程序。
图8-12 连接设备
图8-13 Collection Control对话框
在Collection Control对话框中有个Launch按钮,这个按钮可以启动在模拟器上My Computer下的可执行文件。因此,需要把Callcap.exe的可执行文件下载到模拟器中去。Callcap.exe程序可以使用EVC编译,编译的时候要注意编译成Debug版本,使用Release版本的话,后续的检测数据就无法对程序内部的函数名称进行解析。
可使用Remote File viewer来下载文件Callcap.exe。
按上述方法下载完helloword.exe后,单击Collection Control对话框中的Launch按钮,弹击图8-14所示对话框。
然后按“OK”按钮,将进入如图8-15所示的界面。
图8-14 Launch对话框 图8-15 在Collection Control对话框中显示信息
当Callcap.exe运行时候,Collection Control就会不断地收到数据,当把模拟器中的Callcap程序关闭时,Collection Control也会自动停止收集数据。
在Collection Control中还有Pause按钮,它是用来暂停数据采集功能,可以通过resume来恢复。
在结束了数据采集后,Remote Call Profiler将对数据进行分析,然后显示在图形界面上。如图8-16所示。
图8-16 数据分析界面
还可以从图8-16所示菜单的View→New view命令中选择Call Graph等功能,这些功能以图形化的结点方式来显示目标机程序调用的顺序。下面简要说明。
在选择Call Graph后,系统将要求输入可执行程序进行解析的Image文件的路径,如图8-17所示。
图8-17 输入文件路径
正确的给出路径,如果编译使用的版本是release的话,解析将无法完成。
正确完成以上步骤后,将在Remote Call Profiler中将看到Call Graph的信息,如图8-18所示。
图8-18 Call Graph信息
可以看出,进程首先调用WinMain,其执行率为100%,也就是说所有代码都在其下运行,然后调用WndProc,执行效率为90.99%。之后分为两个分支:DoWork和WndProc总共占了87.7%左右的执行时间,也就是说,整个程序运行的时间中,剩余12.3%的时间都由系统内核在占用处理器。
通过图8-19所示的Time Line窗口也可以得到上述结论。
图8-19 Time Line窗口
图8-19中各种颜色定义如下:
红色:0%-20%的时间在执行应用程序的代码。
绿色:超过80%的时间在执行应用程序的代码。
黄色:82%-80%的时间在执行应用程序的代码。
灰色:所有时间都处于内核态或者其他线程的处理中。
可见,整个数据采样时间中的确有很长时间花费在内核态中。
2.如何在程序中控制Profile功能
在程序中先添加#include cecap.h包含头文件。这个头文件位于Sdk/Wce420/Platman/
Include目录中。
可以在代码中再添加StartProfile(ProfileLevel,PROFILE_CURRENTID);重新启动数据监测收集。也可以在代码中添加StopProfile(ProfileLevel,PROFILE_CURRENTID)函数调用来停止数据采集。
在以上的调用中,将ProfileLevel替换为常数。这些可选择的常数以及它们的功能如表8-2所示。
表8-2 StopProfile和Stop Profile函数的常数及其功能
值 | 代 表 含 义 |
PROFILE_GLOBALLEVEL | 对系统中所有的进程和线程都有效 |
PROFILE_PROCESSLEVEL | 对当前活动进程中的所有线程有效 |
PROFILE_THREADLEVEL | 只对当前活动线程有效 |
请注意,如果系统内核在编译前设置了支持Profile功能,那么所有应用程序默认都是被监测的,只有通过StopProfile才能停止监测。
在代码中实现向宿主机的profiling data (.icp)文件中传输函数被执行信号。只要在响应函数中添加MarkProfile(MarkID)函数或者CommentMarkProfile(MarkID,TextString)函数或者CommentMarkAtProfile(TimestampValue,MarkID,TextString)便可在函数被执行时,将信号传送到.icp文件,这些信号可以在Call Trace中被使用到。
(3)Remote Call Profiler API函数集
Remote Call Profiler API函数集能使程序在运行时自动控制Profile功能,以此来控制监测的数据量,读者可以想象,如果对一个庞大的程序系统进行检测,如果不控制数据流量,可能会使目标机的缓存溢出,从而是数据丢失,数据采样就失真了。在程序中可以直接使用以下的函数接口。
它们都在Cecap.h头文件中被申明这个头文件位于Sdk/Wce420/Platman/Include目录中,表8-3所列是该头文件的函数接口和功能描述。
表8-3 Cecap.h头文件的接口描述
接 口 函 数 | 功 能 描 述 |
将特定的profiling级别的start/stop计数器加1 | |
将特定的profiling级别的start/stop计数器减1 | |
将特定的profiling级别的suspend/resume计数器加1 | |
将特定的profiling级别的suspend/resume计数器减1 | |
将profile标记插入宿主机的.icp文件 | |
功能同上,但是在插入标记的同时,还能附加一个字符串 | |
功能同上,但是在插入标记的同时,还能附加一个时间戳 | |
为一个Profile元素命名 |
下面详细分析表8-3所示函数的原型。
int StartProfile(
int nLevel,
DWORD dwID
);
参数解释:
n nLevel
表示函数作用的系统级别范围,dwID参数将根据这个参数确定值,分别如表8-4所示。
表8-4 nLevel的参数值
值 | 功 能 描 述 |
PROFILE_GLOBALLEVEL | 将影响到所有进程和线程的数据监测 |
PROFILE_PROCESSLEVEL | 将影响到dwId参数指定的进程下的所有线程 |
PROFILE_THREADLEVEL | 将影响到dwId参数指定的线程 |
n dwID
这个参数指定了本函数作用的范围。对于影响全局或者当前进程的情况下,本参数只要设置成PROFILE_CURRENTID即可。如果是将影响到dwId参数指定的进程或者线程,那么将本参数设置成它们的ID。
返回值:
表8-5列出了返回值和它们的含义。
表8-5 StopProfile函数返回值
值 | 描 述 |
PROFILE_OK | 本函数调用是成功的 |
PROFILE_ERROR_NOT_YET_IMPLEMENTED | 函数调用不成功。在各个级别上,数据监测都没有被内核支持 |
PROFILE_ERROR_MODE_NEVER | 在调用本函数启动Profile时发现,数据监测功能被设置成never |
PROFILE_ERROR_LEVEL_NO_EXIST | 被指定的作用级别不存在 |
PROFILE_ERROR_ID_NO_EXIST | dwId指定的对象不存在 |
这个函数将减少start/stop计数器的值,当这个值减少到0时,数据监测就停止。
int StopProfile(
int nLevel,
DWORD dwID
);
参数解释:
n nLevel
指函数作用的系统级别范围,dwID参数将根据这个参数确定值,参数值如表8-6所列。
表8-6 nlevel参数值
值 | 功 能 描 述 |
PROFILE_GLOBALLEVEL | 将影响到所有进程和线程的数据监测 |
PROFILE_PROCESSLEVEL | 将影响到dwId参数指定的进程下的所有线程 |
PROFILE_THREADLEVEL | 将影响到dwId参数指定的线程 |
n dwID
这个参数指定了本函数作用的范围。对于影响全局或者当前进程的情况下,本参数只要设置成PROFILE_CURRENTID即可。如果是将影响到dwId参数指定的进程或者线程,那么将本参数设置成它们的ID。
返回值:
表8-7显示了返回值和它们的含义。
表8-7 StopProfile函数返回值
值 | 描 述 |
PROFILE_OK | 本函数调用是十分成功的 |
PROFILE_ERROR_NOT_YET_IMPLEMENTED | 函数调用不成功。在各个级别上,数据监测都没有被内核支持 |
PROFILE_ERROR_MODE_NEVER | 在调用本函数关闭Profile时发现,数据监测功能被设置成never |
PROFILE_ERROR_LEVEL_NO_EXIST | 被指定的作用级别不存在 |
PROFILE_ERROR_ID_NO_EXIST | dwId指定的对象不存在 |
注意 | StartProfile和StopProfile函数控制了Profile的start/stop计数器。这个计数器默认为1,即默认支持数据监测(如果编译内核时选择了相应的选项的话)。 |
当计数器值大于0时,对特定级别的数据监测就被启动。当处于0或者负值时,便停止。
这个函数将一个数字值的标记和一个附属的字符串插入到宿主机的.icp文件中。这个标记可以用来记录某一段代码的执行。Call Trace视图中将显示字符串。
int MarkProfile(
long lMarkID,
char* pszText,
);
参数解释:
n lMarkID
数字值标记,必须大于0。
n pszText
指针,指向字符串,字符串中的字符数量必须少于256个,包括结束字符/0。
返回值:
返回值如表8-8所示。
注意 | 在调用CommentMarkProfile的时候,数据监测功能一定是要被打开的,否则操作会失败。 |
表8-8 CommentMarkProfile函数返回值
返 回 值 | 描 述 |
MARK_OK | 函数调用成功 |
MARK_ERROR_MODE_OFF | 在调用本函数启动Profile时发现,数据监测功能被设置成OFF。数据被忽略 |
MARK_ERROR_MODE_NEVER | 在调用本函数时发现数据监测功能被设置成never |
MARK_ERROR_MARKER_RESERVED | lMarkId参数中的值小于等于0,0是被保留的,因此操作被忽略 |
MARK_TEXTTOOLONG | pszText中的字符超过256个,操作失败 |
3.Callcap程序分析
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_FILE_EXIT:
DestroyWindow(hWnd);
break;
case IDM_WORK:
DoWork();
break;
case IDM_LABEL:
DoLabel();
break;
case IDM_MT:
DoMultiThread();
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
}
void DoLabel()
{
SetCursor(LoadCursor(NULL, IDC_WAIT));
double x = 0;
CommentMarkProfile(10, "+DoLabel");
for (int i=0; i<5; i++)
{
for (int j=0; j<100; j++)
{
DoWork3();
}
CommentMarkProfile(i, "Iteration");
}
CommentMarkProfile(10, "-DoLabel");
SetCursor(LoadCursor(NULL, IDC_ARROW));
MessageBox(0, L"DoLabel() Completed", L"Done", 0);
}
8.2.2 EVC中的性能评测程序
EVC中的监测程序基本和Platform Builder一致,只是受到SDK的限制。另外其图形界面稍有所不同,如图8-20所示。
图8-20 EVC中的监测程序
8.3 远程文件浏览程序(Remote File Viewer)
Remote File Viewer是类似于Windows桌面系统中资源管理器的用户界面。在开发环境中远程文件浏览程序显示出了所有目标机上的文件信息,包括目录。通过这个工具,开发人员可以轻松地管理目标机上的文件。此外,还可以通过Export和Import方式来向目标机存储文件或者提取文件。
使用远程文件浏览程序前,必须将其于目标机相连接。
实验五:使用远程文件浏览程序
在Platform Builder或者EVC中,选择Tools→Remote File Viewer菜单命令,将弹出图8-21所示的对话框,在这里可以选择连接的设备。
单击“OK”按钮后,就可以使用远程文件浏览器了。如图8-22所示。
图8-21 选择连接设备 图8-22 远程文件浏览器
图8-23 向目标机输出文件
|
执行File→Export File菜单命令下可以执行下载文件的功能,可向目标机输出文件如图8-23所示。
当选中文件后,被选中的文件将被下载到在远程文件浏览器中被选择的目录下。也可以执行删除文件的功能。
8.4 远程堆查看程序
远程堆查看程序显示了目标机上各个进程的标识,以及它们状态的信息。要使用这个工具,必须先目标机。
在这个工具中可以详细地记录进程使用内存的情况,这样就可以判别进程是否释放了申请的内存,应用程序是否发生了内存泄露。利用“远程堆查看程序”还能够查看到:
n 内核中正运行的进程的名字、ID,及使用的所有的堆的ID,如图8-24所示;
n 进程的任意一个堆中的首地址、结束地址及标志;
n 堆中每块(Block)的实际内容。
运行此程序后,先列出系统内所有堆的信息。堆的信息包括堆ID、进程ID、进程名、堆的标志。图8-24所示中堆的标志只有一个值“HF32_DEFAULT”,表示这个堆是系统默认分配的堆。图8-24所示中有4个堆所在进程都为“device.exe”,从进程ID可以看出这是一个进程,而不是一个应用程序的4个实例。
图8-24 内核中正在运行的进程列表
双击列表中任何一项,会弹出一个窗口列出这个堆中包含的块的信息。块的信息包括块的首地址、大小、标志。分配了一个堆,就可以在堆中分配数组、结构等,这个块就指每个分配的元素。块标志为“Fixed”则表示不能释放这个块占据的内存空间,而为“Free”则相反,表示能够释放这个块占据的内存空间。
8.5 远程内核跟踪程序(Remote Kernel Tracker)
Remote Kernel Tracker用于跟踪实际的硬件设备中Windows CE内核的执行情况。开发人员可以使用这个工具来对目标机的系统整体运行进行监测。这个程序能够跟踪所有进程中的所有线程的执行情况,包括了系统中断、进程间通信、相互间的依赖等。它从进程开始运行起跟踪,跟踪结束的时间由数据接收缓冲区的大小决定。缓冲区的大小从1MB到100MB,由用户自己设定。跟踪内容为进程是否运行、线程的运行、阻塞和睡眠。在此程序的右边有所有能够跟踪的事件对应的图标。
要跟踪一个内核的启动情况(启动后也能使用这个工具跟踪所有进程、线程),先要使要跟踪的内核具有几个特性。在PlatformBuilder菜单“Platform”→“Settings”,在弹出的对话框中选择选项卡,“Build Options”选中“Enable Event Tracking During Boot”和“Enable Profiling”复选框,单击OK按钮,然后重新编译整个内核。注意在编译时可能提示产生错误,如果出现这种情况那就重建内核。如果编译的是retail版本的内核,则系统默认支持Remote Kernel Tracker。如图8-25所示。
图8-25 数据记录
编译成功后,先打开远程内核跟踪程序,在平台选择对话框中单击“OK”,这时立刻单击主界面的“Download”→“Initialize”调出模拟器。等待一会远程内核跟踪程序就将整个启动过程中发生的所有情况记录并显示出来。线程在哪个时间段运行、睡眠、阻塞,包括发生中断的时间、中断号等都记录下来,如图8-25所示。缺点就是数据量太大。这个程序提供了查找功能和过滤功能,查找功能可以查找想要找的事件,而过滤功能可以让此程序只记录希望记录的事件。最后还可以保存记录的所有数据,保存到扩展名为.clg的文件中。
8.6 远程性能监视程序(Remote Performance Monitor)
Remote Performance Monitor是图形化的,用来测试Windows CE.NET系统整体性能。利用这个工具,开发人员可以简单清晰地监视性能对象的运行状态,例如CPU、线程、进程以及系统内存。每个性能对象都有自己的计数器队列,这些计数器描述了对象的设备使用状态,引用计数、缓存队列长度以及延迟等。Remote Performance Monitor能将这些数据提取出来显示。
在将工具和目标机连接后,便可以查询性能对象的状态。此外还可以添加性能对象。
以下是添加性能对象的大致步骤。
(1)在Edit菜单中选择Add To Chart。
(2)在弹出的对话框中选择一个性能对象。
(3)在计数器对话框中做出选择。
(4)如果可以的话,在Instance对话框中做出选择。
(5)保存退出。
Remote Performance Monitor支持下列的性能对象:
n Remote Access Server (RAS)
n Internet Control Message Protocol (ICMP)
n TCP
n IP
n User Datagram Protocol (UDP)
n Memory
n Battery
n System
n Process
n Thread
在Remote Performance Monitor中可以通过表8-9所示的4种方式来查看性能数据。
表8-9 Remote Performance Monitor查看性能数据的方式
视 图 | 功 能 描 述 |
Chart | 支持实时数据的监测 |
Alert | 当目标机的运行状态达到某一指定状态时,显示数据 |
续表
视 图 | 功 能 描 述 |
Log | 将数据存储到日志文件中 |
Report | 用文本方式显示数据 |
如图8-26所示,为向Remote Performance Monitor工具添加要查看的对象参数。
图8-26 添加要查看的对象参数
如图8-27所示是被选择的%Processor Time的活动图表。
图8-27 选择的%Processor Time的活动图表
8.7 远程进程浏览程序
远程进程浏览程序(Remote Process Viewer)共三个窗口,分别显示当前内核中所有进程、进程中的线程及进程中所有加载的DLL。如图8-28所示。在显示进程的窗口中,分别显示进程名、进程ID、基本优先级级别、拥有的线程总数、基地址、访问键值、主窗口名。在显示线程的窗口中,分别显示线程ID、当前进程ID、线程优先级、访问键。在显示DLL模块的窗口中,分别显示模块名、模块ID、当前进程使用计数、全局使用计数、基地址、大小、模块句柄、路径。这里要说明的是线程窗口中的“当前进程ID”。线程窗口应该显示当前指定进程下的所有线程,怎么会有不同的进程ID呢?这涉及到Windows CE驱动模型。如“explorer.exe”,它包含的线程中就有两个在“当前进程ID”中显示为进程“gwes.exe”,“gwes.exe”为图形、窗口、事件子系统。它负责画出图形和窗口以及收发窗口消息。“explorer.exe”的线程在显示窗口、收发消息时调用“Coredll.dll”,这个DLL调用图形、窗口、事件模块。这些模块实际上是驱动程序(DLL),由gwes.exe来加载、执行、管理这些DLL。当执行此远程调试工具时,此工具会调用ToolHelp函数集快照系统某一时刻的进程、线程、DLL信息。
图8-28 远程进程浏览器
8.8 远程注册表编辑程序
远程注册表编辑程序(Remote Registry Editor)和其他Windows 操作系统下的注册表编辑器非常相似,但它能够同时显示、编辑开发平台中的注册表和实际设备中的注册表数据。如图8-29所示。具体操作和其他注册表编辑器一样,在操作时首先要区分哪个是开发平台中的注册表,哪个是实际设备中的注册表。Windows CE下注册表的限制是键名最大长度255个字符,数据最大4KB,子键深度最大值16层。
图8-29 远程注册表编辑器
8.9 远程桌面截取程序
远程桌面截取程序(Remote Zoomin)能够在计算机上显示一幅从远程设备上截取的屏幕图像。启动Remote Zoomin时,桌面计算机会从目标设备下载一幅屏幕图像的BMP图。使用Remote Zoomin还可以缩放目标设备的屏幕截图或者拷贝屏幕截图到剪贴板。如图8-30所示。
图8-30 远程桌面截取
8.10 远程系统信息监控程序
远程系统信息监控程序(Remote System Information)工具能使开发者在计算机上直接查看远程设备上的系统信息情况,如内存、电源状态、存储、设备等。如图8-31所示。
图8-31 远程系统信息
8.11 远程消息监视程序
远程消息监视程序(Remote Spy)和Visual C++下附带的工具spy非常相似。能够截获并列出所有实际设备中的窗口信息和窗口消息。要监视某一个窗口,先在窗口列表中选择这个窗口,然后系统发送到这个窗口的所有窗口消息都被截获并在“Messages”窗口中显示出来。在“Messages”窗口中列出消息名、两个32位参数值等。如图8-32所示。
图8-32 远程消息监视
8.12 CEPC的探讨
在目标设备上调试操作系统镜像
Platform Builder支持通过串行/并行端口、以太网和(通过加载项组件)JTAG/BDM将操作系统映像下载到设备。我们需要先配置下载并调试传输,然后才能下载操作系统映像,这一部分我们将根据CEPC方式讲解如何进行调试。
1.制作启动目标设备的软磁盘
① 在安装Platform Builder路径下,查找Websetup.exe文件,鼠标双击运行这个程序这个文件具体位置是:G:/Program Files/Windows CE Platform Builder/4.20/cepb/utilities。
运行这个程序之前要安装另外一个程序到C:/Windows(如果Windows目录在C:盘的话)目录下,注意这个目录不要修改,提示安装完成后单击“OK”按钮。
② 双击同Websetup.exe在同一目录下的Cepcboot.144文件,在弹出的对话框中,有两个按钮分别是“A Drive”和“B Drive”,现在一般计算机只有一个软驱,所以我们在A驱动器内放入一张软磁盘,单击“A Drive”这个按钮,对话框的进度条会显示安装文件拷贝到软磁盘的进度,当拷贝完成后单击“Cancel”按钮,退出这个程序。
③ 检查你新建的启动软盘,查看一下是否包含所有需要的文件,为了更好的查看,请将系统文件夹选项中的隐藏框的对号去掉,并且选显示所有文件。
在这张软磁盘中应该包括如表8-10所示的文件:
表8-10 软磁盘中包含的文件项
文 件 名 字 | 说 明 |
Autoexec.bat | MS-DOS需要的自动批处理文件 |
Commond.com | MS-DOS下在三个启动文件之一 |
Config.sys | MS-DOS下的系统配置文件 |
Drvspace.bin | 一个二进制文件,用于支持一个驱动器 |
Eboot.bin | 二进制文件,用于以太网启动 |
Himem.sys | MS-DOS下的内存配置文件 |
Io.sys | MS-DOS下的三个启动文件之一 |
Loadcepc.exe | 可执行文件,加载这个Eboot.bin引导加载镜像 |
Msdos.sys | MS-DOS下的三个启动文件之一 |
Readme.txt | 一个说明的文本文件 |
Sboot.bin | 二进制文件,用于串口启动 |
Sys.com | MS-DOS下的应用程序,主要将系统传到目标盘上 |
Vesatest.exe | 可执行文件,用于测试显卡上的VGA BIOS,以确保可以兼容基于Windows CE驱动程序,Readme.txt文件中有更详细的信息来讲解这个文件的用法 |
④ 修改启动软磁盘上的Autoexec.bat文件,与目标设备上的以太网卡相匹配。
如果以太网卡是PCI总线的,则设置NET_IRQ等于9,而且NET_IOBASE等于0。
如果以太网卡是ISA总线的,则设置NET_IRQ与NIC IRQ相等,设置NET_IOBASE与NIC I/O相等。
2.下载操作系统镜像到目标设备
本节讲解如何建立并配置一个以太网连接,来连接到目标设备,并且下载操作系统镜像到目标设备。
在开始连接、下载操作系统镜像时,先要确定当前开发的计算机与目标设备在同一子网内。
下面开始对每一步进行讲解:
① 在Platform Builder中,选择“Target”菜单,单击“configure Remote Connection”。
② 选择“Services”选项卡。
③ 从Download字样下面的组合框中选择Ethernet。
图8-33 配置以太网下载服务对话框
|
在目标设备启动后,这个目标设备的名字会出现在图8-33中Available Devices:处的列表中。
⑤ 从Available Devices处选择目标设备名,并单击“OK”按钮。
⑥ 在图8-2所示对话框的Kernel选项Ethernet下拉列表中选项。
⑦ 选择Settings选项卡,在Download/Initialize Device中,查看Connect to Device是否已经被选择,如果没有被勾选,就将其勾选上。
⑧ 单击Target菜单,单击Download/Initialize菜单项。
⑨ 等待操作系统镜像的下载完毕。
使用以太网连接,下载的时间与以太网速度及操作系统镜像的大小有关,在下载时,一个对话框会显示在PC机的集成开发环境中,提示你现在正在下载的速度。
在操作系统镜像下载完成并在目标设备上正常启动后,你就可以调试这个操作系统镜像了。