WinCE驱动开发问题精华集锦-2
摘自:
http://hi.baidu.com/mcu%5Fspaces/blog/item/f14d1d2af1a2e33c5243c144.html21、 文件格式如下所示,我想把每行的4个值读到4个变量中,用EVC如何编程? 第一行: 460.000, 3384672.357342, 521268.972763
第二行: 475.117, 3384663.772419, 521281.415271
伪代码如下:
FILE *stream;
stream = _wfopen(L"\\a.txt", L"r+");
if( stream == NULL )
return;
fseek(stream, 0L, SEEK_SET );
while( !feof( stream ) )
{
fwscanf(stream, L"%s", WCHAR1);
fwscanf(stream, L"%f", float1);
fwscanf(stream, L"%f", float2);
fwscanf(stream, L"%f", float3);
}
fclose( stream );
22、GWES组件的功能有哪些? GWES不仅负责GDI、窗口、消息,还负责管理本机设备驱动程序,负责加载显示、键盘鼠标、触摸屏驱动程序,而且GWES本身包含电源、LED驱动程序。
23、如何在PB中预先设定好存储内存和程序内存的大小,我想多划分一些空间给程序内存? 两种办法:
1)、在定制内核时在config.bib文件中设置FSRAMPERCENT = number,具体number可参考标题为“FSRAMPERCENT ”的帮助文档。这种办法是修改内核的设置,所有一直有效。
2)、在应用程序中调用API SetSystemMemoryDivision,如果函数返回SYSMEM_CHANGED表示成功,如果返回SYSMEM_MUSTREBOOT表示需要热启动才能有效。这种办法需要每次启动后调用API才有效。
24、 如何取消鼠标光标? 通过取消SYS变量来实现此目的,在PB命令行下键入“set SYSGEN_CURSOR=”,然后回车确认。
25、EVC下调用TextOut如何编译会出错? 类似这样的问题很多,这是因为EVC的帮助文档内容有错误。可能EVC的帮助文档内容是从桌面Windows帮助文档复制过来的,所以很多API函数还有例子代码都有错误,例如帮助文档中包含一个API函数的说明,但是实际编译的时候提示没有这个API,有的例子代码采用ANSI字符串,而WINCE的API都是宽字符版本,造成直接复制过来编译失败。
因为MFC for WINCE的CDC类中没有TextOut成员函数,所以编译会出错,可以用其它类成员函数ExtTextOut或者DrawText替换。
26、我如何将我的dll软件让现有的ce系统认可?尽管我也知道应该使用signfile.exe程序进行签名,但是我并不知道那个ce系统认可的签名应该是啥
如果你说的WINCE系统内核已经加入了签名认证机制,那么没有私钥对你的DLL文件签名肯定是无法运行在此内核中的,一般签名密钥的密钥长度都是1024位,很难破解。
27、如果查看WINCE注册表中的内容? 两种办法:
1)、建立同步后,用EVC自带的工具“Remote Registry Editor”打开查看。
2)、从网上下载注册表查看工具,放到WINCE设备中。
28、调用directshow出现链接错误,如何解决? player.obj : error LNK2001: unresolved external symbol _IID_IVideoWindow
player.obj : error LNK2001: unresolved external symbol _IID_IMediaControl
这是因为链接器没有找到合适的.lib文件。两种办法:
1)、在EVC菜单Tools—options—directories 里把library files的路径重新调整一下。如果你只安装了EVC自带的Standard SDK而没有其它SDK,可以指定WINCE目录中的.lib文件路径,例如D:\WINCE500\PUBLIC\DIRECTX\OAK\LIB\X86\RETAIL。注意CPU的类型。
2)、安装SDK,前提是导出SDK的PB内核工程必须包括DirectShow或者其它组件。
29、在PB的config.bib文件中,“IMGFLASH”表示什么意思呢? 表示能够刷NK到ROM中,具体请查看标题为“IMG Environment Variables”的帮助文档。
30、x86平台如何映射各种地址空间?如何编写中断服务例程? 如果是x86平台,可以调用HalTranslateBusAddress转换物理总线地址到物理系统地址,调用HalTranslateSystemAddress转换物理系统地址到逻辑总线地址,也可以不调用这两个函数,因为x86平台除32位物理地址外还有16位的IO地址空间,对于16位的IO地址空间,可以直接调用WRITE_PORT_UCHAR或者READ_PORT_UCHAR等函数直接读写端口。对于32位物理地址可以调用VirtualAlloc和VirtualCopy来映射。这样做思路清晰,简单明了。
在x86平台要实现ISR,有如下几个步骤(以Geode BSP为例):
1)、用SETUP_INTERRUPT_MAP宏关联SYSINTR和IRQ。以“SYSINTR_”为前缀的常量由内核使用,用于唯一标识发生中断的硬件,又称为中断ID。在Nkintr.h文件中预定义了一些SYSINTR,OEM可以在Oalintr.h文件中自定义SYSINTR。
2)、用HookInterrupt函数关联硬件中断号和ISR。这里提到的硬件中断号为物理中断号,IRQ为逻辑中断号。在InitPICs函数的最后调用了HookInterrupt函数,如下:
for (i = 64; i < 80; i++)
HookInterrupt(i, (void *)PeRPISR); ///用ISR关联16个中断号
3)、调用InterruptInitialize函数关联SYSINTR和IST创建的事件对象,也是IST等待的事件对象。详细内容请参考Geode BSP源码。
在x86平台要实现可安装ISR,先调用LoadIntChainHandler函数注册在注册表中指定的ISR DLL,然后填充GIISR_INFO结构体并调用KernelLibIoControl函数将此结构体传递给可安装ISR。详细内容请参考WINCE帮助文档或者我著的《Windows CE下驱动开发基础》。
31、修改了WINCE自带的驱动程序后如何编译?如果是自己开发的驱动程序如何编译?
1)、分为IDE方式和命令行方式。
IDE方式的编译很简单,以PB5.0为例,打开定制内核的工程,在左边的“workspace”—“FileView”中找到你已经修改了的目录,然后单击右键弹出菜单,在菜单中选择“Build and Sysgen Current Project”,这样PB就会编译指定的目录中的项目源码文件,然后执行sysgen命令根据source文件中的内容生成目标文件并复制到当前内核工程目录下。
命令行方式的编译需要打开“Build OS”—“Open Release Directory”,以cd命令进入你已经修改的驱动程序目录中,然后键入“build –cfs”,然后键入“sysgen –p 项目名称”,一般项目名称为source文件中的“TARGETNAME”。
2)、如果想完全自己开发驱动程序,建议直接采用EVC或者PB来编写编译。
32、开发PCI设备驱动时,InterruptInitialize函数的第一参数是否是PCI卡配置空间信息中的InterruptLine 参数?是否需要在HKLM\Drivers\BuiltIn\PCI\Template 加一個自己的 subkey,并填写相应内容?如何填? 1)、InterruptInitialize的第一参数是IRQ,也就是逻辑中断号,而不是物理中断号,InterruptLine是指物理中断号
2)、需要在template下加自己的PCI设备的信息,例如:
[HKEY_LOCAL_MACHINE\Drivers\PCI\Template\Serial]
"Dll"="Com16550.Dll"
"Class"=dword:07
"SubClass"=dword:00
"ProgIF"=dword:02
"VendorID"=multi_sz:"0AF0","B320","B320"
"DeviceID"=multi_sz:"0020","0300","0302"
"Prefix"="COM"
而这些信息就来自于你执行pcienum.exe的结果。
33、编译器报错:error C2065: 'CFileFind' : undeclared identifier,如何解决? MFC for WINCE版本没有CFileFind类,所以要查找文件只能调用API FindFirstFile 和FindNextFile。
34、如何设置WINCE系统字体、字号?如何设置自己开发的软件的字体、字号? 1)、系统字体通过注册表设置。如下:
[HKEY_LOCAL_MACHINE\System\GDI\SysFnt] ///系统字体
Wt=420
Ht=18
Nm=Arial
[HKEY_LOCAL_MACHINE\System\GWE\Menu\BarFnt] ///菜单栏字体
[HKEY_LOCAL_MACHINE\System\GWE\Menu\PopFnt] ///弹出窗口字体
[HKEY_LOCAL_MACHINE\System\GWE\Menu] ///菜单字体
HKEY_LOCAL_MACHINE\System\GWE\Button ///按钮字体
2)、创建字体时把字体高度参数设置大点就可以了。如CFont::CreateFont(nHeight,...),也可以在LOGFONT结构中设置字体高度或者字体种类。如果是控件,调用控件的SetFont成员函数。如果是直接画,在OnPaint响应函数中调用SelectObject选字体到DC。
35、 nk.bin和nk.nb0有什么区别? 这里提到的bin是一种二进制镜像格式,以片断(section)为单位组织数据,每个片断都包括一个头,头里指定了起始地址,长度,校验值。Platform Builder调用工具将WINCE内核所有文件以bin格式合并成一个文件,默认文件名为nk.bin。BootLoader又以同样的格式将nk.bin分解成多个文件放到RAM中。可以在命令行中键入“viewbin nk.bin”来查看bin文件中具体包括了哪些内容。键入Cvrtbin命令转换.bin格式文件为.sre格式或者.abx格式。
nb0格式是原始的二进制镜像,它不包括头,一般情况下将内核下载到设备的RAM中运行都采用nb0格式。要生成nbx格式的文件,需要在相关.bib文件中确定如下值:ROMSTART、ROMWIDTH、ROMSIZE。
36、在不采用硬件计时器的情况下如何创建更精确的计时器?最精确周期能否达到1毫秒?
对于精确值的要求不同,所采用的办法不同。以下阐述几种办法。
1)、在单线程中循环调用API Sleep函数,Sleep函数精确程度为如果Sleep(N),那么实际睡眠时间在N到N+1毫秒之间。而且还要注意调用Sleep的线程优先级的问题。如果任务过多并且此线程优先级低,那误差就更大些。
2)、调用API QueryPerformanceCounter函数,举例如下:
LARGE_INTEGER liFrequency;
if (QueryPerformanceFrequency(&liFrequency)) // 查询系统时钟的频率,这里将返回1000
{
liFrequency.QuadPart /= 1000;
LARGE_INTEGER liTimeOut;
if (QueryPerformanceCounter(&liTimeOut)) //得到截至到当前累计发生的系统时钟中断次数
{
liTimeOut.QuadPart += liFrequency.QuadPart; ///计算下一秒到来时总的中断次数是多少
LARGE_INTEGER liCurrent;
do
{
QueryPerformanceCounter(&liCurrent); // 循环查询累计的的中断次数
} while (liCurrent.QuadPart < liTimeOut.QuadPart); ///到达下一秒
}
}
调用QueryPerformanceCounter同调用Sleep在本质上都是一样的,都是在单线程中无限循环等到周期一到执行任务,相比较QueryPerformanceCounter要比Sleep更精确些,越精确就越要求线程的优先级,保障线程能够正常得到处理器。
3)、以上办法难以保证周期精确到1毫秒并且WINCE系统稳定地运行,所以要从中断入手。以x86平台为例,先在Timer.c中将默认的SetTimer0(TIMER_COUNT)中的TIMER_COUNT /=2,SetTimer0函数负责设置系统时钟的频率,默认1毫秒发生一次中断,如果除以2就是0.5毫秒发生一次中断。然后在fwpc.c文件中修改ISR函数PeRPISR,因为原来默认是1毫秒发生一次中断,在处理INTR_TIMER0时系统负责累计计数、管理线程的调度,返回相应的SYSINTR值,而我们没有办法再添加代码返回自己定义的SYSINTR值,所以现在要修改原来的处理代码,例如设置一个BOOL型变量,TRUE就执行原来默认的代码,而FALSE就返回我们自己定义的SYSINTR值,这样即不影响原来的ISR处理,又加入了我们的中断响应代码。ISR返回我们定义的SYSINTR后WINCE内核激活相对应的EVENT事件,我们就可以在我们编写的IST里处理任务了。
37、flash中存放了BootLoader和内核镜像,如何把剩余flash部分划分为一个存储区域供应用程序读写?
以WINCE提供的驱动(FAT文件系统和MSFLASH驱动)来举例说明。如果采用默认common.reg中的注册表设置,那么MSFLASH驱动默认把整个flash作为存储区域来读写,这不符合问题的要求,所以必须告诉MSFLASH驱动程序可供读写的区域的起始地址和长度。以下是一个注册表例子:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\FASLD]
"Dll"="fasld.dll" ///实际Flash存储器的驱动程序
"Order"=dword:2 ///该驱动程序相对于其它驱动程序的加载顺序
"Prefix"="DSK" ///前缀
"Ioctl"=dword:4 ///IOCTL码,设备管理器加载驱动的时候调用IOControl函数,传递这个IOCTL码。
"Profile"="MSFlash" ///Profile名称,也就是[HLM\System\StorageManager\Profiles\MSFlash]
///当设备管理器加载此驱动程序的同时发送通知给系统,IClass(GUID)的值表明这是一个存储设备的驱动程序。
"IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
"MemBase"=dword:00000000 ///Flash中可供读写区域的起始物理地址,也就是Flash的首地址+偏移量
"MemLen"=dword:00000000 ///Flash中可供读写区域的长度
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash]
"DefaultFileSystem"="FATFS" ///MSFlash驱动默认采用的文件系统
"PartitionDriver"="mspart.dll" ///采用的分区驱动程序
"MountAsRoot"=dword:1 ///此目录作为文件系统的根目录
"Folder"="NOR Flash" ///目录名称
"Name"="FLASH Disk Block Device" ///Flash驱动名称
"PartitionDriverName"="MSPART" ///分区驱动名称
"AutoMount"=dword:1 ///自动装载检测到的分区
"AutoPart"=dword:1 ///自动分区
"AutoFormat"=dword:1 ///自动格式化分区
[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\MSFlash]
"DriverPath"="Drivers\\BuiltIn\\FASLD" ///Flash驱动在注册表中的位置
"LoadFlags"=dword:1 ///这个值可以被设置为0、1、2。1表示同步加载,其它表示异步加载
"Order"=dword:0
[HKEY_LOCAL_MACHINE\System\StorageManager\FATFS]
"FriendlyName"="FAT FileSystem" ///文件系统名称
"Dll"="fatfsd.dll" ///文件系统驱动程序
"Flags"=dword:00000064 ///标志,详见帮助文档
"Paging"=dword:1 ///是否分页
"EnableCache"=dword:1 ///是否允许缓存数据
"CacheSize"=dword:0 ///指定缓存大小,0表示默认
38、驱动程序如何发通知给应用程序? 这里介绍一下常见的两种办法。
1)、驱动程序调用API SendNotifyMessage,发送特定的消息给应用程序,这就要求应用程序要有消息循环机制并且要事先做好消息的处理。参数1为窗口句柄,可以设置HWND_BROADCAST表示广播消息。要注意的是不要在参数中传递指针(虚拟地址),因为执行驱动程序的线程和应用程序并不在同一个进程空间中。解决办法可以利用内存映射文件技术,比如在驱动程序中创建一个内存映射文件对象,申请一块物理内存,然后把对象名称和内存长度传递给应用程序,应用程序打开同名的内存映射文件对象,读取里面的数据。对象名称可以事先协定好,也可以通过注册表来传递,内存长度是32位值,通过消息参数就可以传递,也可以通过注册表来传递。另外一种解决办法是在定制内核时候预留一块物理内存,这样驱动程序和应用程序都可以通过VirtualAlloc和VirtualCopy来映射到同一块物理内存,其原理同内存映射文件技术一样,但是这块物理内存不具备通用性。最后一个办法是应用程序事先将一个缓冲区地址传递给驱动程序,驱动程序调用MapPtrToProcess映射应用程序传递过来的地址,当驱动程序调用SendNotifyMessage后应用程序可以直接到该地址中读取数据。
设备管理器就是调用此函数广播WM_DEVICECHANGE消息的。另外WINCE的一个例子程序RNAApp在拨号连接建立的时候也是调用这个函数广播WM_NETCONNECT消息的。
2)、驱动程序调用API CeEventHasOccurred指明一个事件A发生,在此之前应用程序调用API CeRunAppAtEvent将驱动程序指明的A事件和一个应用程序名称相关联,或者和一个事件B相关联。这样当A事件发生时,如果指明和一个应用程序名称关联,那这个应用程序就会被启动。如果指明了和一个事件B相关联,那么等待事件B的线程将被激活。如果想了解当前系统内部所有驱动程序支持哪些类似事件A的事件,调用API CeNotifyPublic_FilterEvent,在该API的帮助文档里也列举了常见的事件,例如NOTIFICATION_EVENT_NET_CONNECT和 NOTIFICATION_EVENT_NET_DISCONNECT。
40、 EVC创建的工程名称如果用中文就出错,该怎么办? 用EVC创建的工程名称如果为中文将导致资源文件打不开和编译出错,可以改资源文件名称为英文,再编辑.rc文件中的资源文件名称。但建议尽量不要用中文为工程名称。
作为习惯,应该在EVC创建一个工程后,立刻在“project”—“settings”中设置资源的语言属性,然后在“resource view”中设置每个资源的语言属性,这些工作做完后再修改资源就没有问题了。有人询问对话框的标题为乱码,其原因就是在没有修改语言属性的情况下设置标题为中文。
posted @
2009-07-16 15:41 Sandy 阅读(732) |
评论 (0) |
编辑 收藏
WinCE驱动开发问题精华集锦-1
摘自:
http://hi.baidu.com/mcu%5Fspaces/blog/item/12662a088108f9d563d9867b.html近日越来越发现知识的匮乏,所以需要好好努力才可以.
加油,加油!
精华集锦1__内容如下
1、在应用程序中,如何向修改本机的ip 地址等网络参数,并使之立即生效? 网络设置保存在注册表中,位置[HKEY_LOCAL_MACHINE\Comm\网卡名称\Parms\TcpIp],例如常见的CS8900网卡设置:
[HKEY_LOCAL_MACHINE\Comm\CS89001\Parms\TcpIp]
"EnableDHCP"=dword:0
"DefaultGateway"="192.168.0.1"
"DNS"="111.111.111.111"
"UseZeroBroadcast"=dword:0
"IpAddress"="192.168.0.2"
"Subnetmask"="255.255.255.0"
设置之后要生效有两种办法:一种热启动,调用KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL),热启动时间很短暂;另外一种调用DevieceIoControl API,传递IOCTL=IOCTL_NDIS_REBIND_ADAPTER。
2、如何向控制面板中那样,修改系统声音的音量
调用API waveOutSetVolume(HWAVEOUT, dwVolume ),一般参数1为0。在[HKEY_CURRENT_USER\ControlPanel\Volume]下是系统声音的注册表设置。
3、在应用程序中如何实现jpg、gif图片的显示 有几种办法:
1)、在MSDN中搜索标题为“Windows CE .NET Technical Frequently Asked Questions”的文档,其中有一个问题“How can I display JPEG, GIF, and other graphics files?”,下面就是答案。
2)、如果安装了Windows CE 5.0,一个例子源码位于WINCE500\PUBLIC\GDIEX\SDK\SAMPLES\SIMPLE。
3)、用IWebBrowser组件实现。
4、 在应用程序中如何实现系统待机
void GwesPowerOffSystem(void);
5、 在WINCE中如何得到网卡MAC地址 事实证明,获得物理网卡的MAC地址并没有被统一成一个API或者IOCTL,如果网卡驱动程序没有提供接口的话只能直接访问寄存器获得。读者可以参考目录WINCE500\PUBLIC\COMMON\OAK\DRIVERS\NETCARD里的一些驱动源码。
6、Windows XP Embedded 和Windows CE有何区别
简单地说Windows XP Embedded采用Windows XP内核,只能运行在x86处理器上,优点是能够运行PC上现有的应用软件,缺点是授权费太高,标价¥900元;Windows CE采用Windows CE内核,能够运行在多种处理器上,如x86、ARM、SHX、MIPS等,优点是授权费低,最低Core版标价¥30元。缺点是需要单独开发应用软件、定制内核,甚至开发BSP、Driver。
7、 wince下只是把调制解调器的驱动挂接在了com1,如何将器驱动挂接在com2上? 1)、在HLM\drivers\buildin\com2\unimodem下复制和com1一样的数据
2)、在HLM\ExtModems\HayesCompat下改写Port为COM2:,再改写FriendlyName为"Hayes Compatible 在 COM2:"。
8、如何定制自己的外壳 1)、先开发一个外壳软件,假设名称为MyShell.exe
2)、删除注册表[HKEY_LOCAL_MACHINE\init]下如下一行:
"Launch50"="explorer.exe"
3)、在注册表[HKEY_LOCAL_MACHINE\init]下添加如下一行:
"Launch50"="MyShell.exe"
上述的“LaunchXX”中的XX为序列数,内核依据这个序列数按由小到大的顺序来分别执行所有子键列出的应用程序,具体数值应该为多少请参考帮助文档的说明。
如果原来的内核中添加了标准外壳(standard shell)组件,或者添加了其它组件而这些组件需要依赖标准外壳,那么在PB中是无法删除标准外壳组件的,解决办法一是保留explorer.exe在内核中,二是删除依赖标准外壳的组件。
9、我原来的工程是x86版本的,编译选项只有x86,我如何能够编译ARM版本的 两种办法:
1)、用EVC新建一个工程的时候,建议复选“CPUs”列表,这样发生了这种事情也能够轻易通过选择“WCE Configuration”工具栏中的CPU列表来编译不同CPU版本的软件
2)、如果打开工程后CPU列表中只有x86,而此时已经安装了ARM版本的SDK,那么单击EVC菜单“build”-“configurations”,然后单击“add”按钮来添加CPU。
10、通常情况下WINCE采用串口1作为调试时输出信息用途,要正式出产品前如何去掉串口1的调试功能,正常情况下串口1只有在编译debug版本的内核时才在BootLoader中初始化串口1用于输出信息,而编译release版本会跳过此代码。而有些BSP设计成没有宏定义,也就是说无论什么版本都会在BootLoader中初始化串口1,这样造成WINCE启动后串口1无法被应用程序使用。对于这种情况只能在BootLoader源码中删除初始化代码,如OEMInitDebugSerial。
11、基于wince的应用程序能建成console project么? 不能
12、ARM系统外扩一片512K RAM,驱动程序经过映射可以使用这一段RAM。1、应用系统如何使用这一段RAM?要加一层驱动吗?2、如果要将这一段RAM当作RAM盘存储系统,该如何作呢?应该要加文件系统吧,如何加呢? 解答这个问题前,先要说一下WINCE的地址映射机制。对于包含MMU(存储器管理单元)的处理器来说,如ARM和x86,WINCE要求OEM在定制内核的时候填写一个虚拟地址与物理地址映射关系的表,称为OEMAddressTable,在这个表中定义了所有物理设备的起始物理地址,对应的起始虚拟地址,地址空间大小,RAM就包括在其中(如果是x86平台还要求RAM起始虚拟地址从0x80000000开始)。如果有多片RAM,应该在OEMAddressTable中将它们定义在一起,使之地址连续。对于非OEM的开发者来说,他们拿到的是定制好的内核,不能做任何修改,如果在产品中外扩一片RAM,只能通过API函数通知操作系统增加一条虚拟地址与物理地址映射关系表项。相关API函数有两个,分别是CreateStaticMapping和VirtualCopy。它们的相同之处是都用于建立物理地址和虚拟地址的映射关系。它们的不同之处是CreateStaticMapping映射的虚拟地址范围在0xC400 0000 到 0xE000 0000之间,这个范围只能由内核访问,一般用于ISR访问,因为ISR只能访问静态映射的虚拟地址空间,不能用VirtualCopy。VirtualCopy通常和VirtualAlloc配合使用,映射的虚拟地址空间在0x8000 0000以下,一般用于驱动程序和应用程序访问。
1)、应用程序要访问这片RAM,和驱动程序访问方法一样,调用VirtualAlloc和VirtualCopy。
2)、可以做一个流驱动程序专门用于读写这片RAM,这样所有应用程序就可以通过调用流驱动接口函数来访问,非要加文件系统也是可行的,通过修改注册表就可以做到,但是麻烦一些。
13、我怎么能在PB左边的定制平台加进我的驱动呢? 两种办法:
1)、在platform.bib或者project.bib的MODULES部分添加一条语句,例如:
MyDriver.dll C:\Driver\MyDriver.dll NK SH
这样编译内核的时候就会把你的驱动DLL文件添加到内核中,如果有注册表需要设置,在platform.reg或者project.reg中添加注册表内容。
2)、通过制作.cec文件来添加驱动,制作.cec文件的优点是只需制作一次,以后就可以通过将.cec文件导入到PB的Catalog中,象PB自带的feature一样通过菜单“Add to OS Design”添加到左边的内核工程中。
14、 WINCE有没有相对路径概念?如果没有如何得到当前模块的路径?
1) 、WINCE没有相对路径概念,只有绝对路径,所以凡是涉及到路径均为绝对路径。
2)、调用API GetModuleFileName,传递一个模块的实例句柄就能够得到模块的绝对路径。
15、 怎样让 POCKET WORD打开*.dat格式(里面都是数据)的文件? 两种办法:
1)、调用API ShellExecuteEx,在结构体SHELLEXECUTEINFO中添加.dat文件的路径。
2)、调用API CreateProcess,在第二个参数中设置.dat文件的路径。
16、 x86 Rom Boot Loader真的可以实现吗?它确实能代替BIOS启动计算机? Rom Boot 被设计存放在Flash/EEPROM中,也就是原来BIOS的位置,这样当上电后CPU到固定地址执行代码,也就是执行了Rom Boot的代码,它对整个硬件系统进行初始化和检测,并且支持通过网卡从远程机器上下载nk.bin或者从本地IDE/ATA 硬盘的活动分区中寻找nk.bin文件加载。Rom Boot的优点就是引导并且加载速度快,而且它自身完成了所有的操作,这样就不用BIOS、MSDOS,更不用Loadcepc了。
17、 对于x86 Rom Boot Loader,如何Build得到Romboot.rom? 1)、在PB中打开一个内核工程(x86的)
2)、单击PB菜单“Build”-“Open Build Release Directory”
30 、用cd命令进入 %_WINCEROOT%\Platform\Geode\Romboot 4、build
18、如何设置、更改显示分辨率
能否设置、更改显示分辨率由显示驱动程序决定,而没有统一的标准。例如CEPC,在启动的时候可以通过设置loadcepc.exe的参数 /L来决定WINCE启动后的显示分辨率,这是由于显示驱动“VGA Linear Framebuffer”支持,而Geode可以通过在定制内核时修改注册表项来决定WINCE启动后的显示分辨率。
19、 几个硬件使用同一个IRQ,那么发生中断的时候系统怎么判断到底是哪一个硬件发生的中断呢?ISR里面又应该怎么控制呢? Windows CE支持多个设备中断共享一个IRQ,当一个共享IRQ发生时,CE内核的异常处理程序检测设备特定的寄存器,因为大多数设备都有一个单独的寄存器用于表示设备的活动状态,所以通过遍历共享这个IRQ的所有设备的寄存器就可以判断哪个设备发生中断。nk.exe加载一个giisr.dll,这个.dll是微软提供的,它其实是第一个可安装ISR。默认CE内核就是调用这个dll来检测寄存器状态的,当然OEM可以编写自己的.dll。
CE内部有一个ISR链,也就是可安装ISR。因为CE允许OEM添加自己的ISR处理程序,所以ISR被设计成一个链表。排在前面的ISR比后面的ISR优先处理中断,如果当前ISR能够处理当前中断,那就返回中断ID由IST处理或者返回SYSINTR_NOP,如果当前ISR不能够处理当前中断,那就返回SYSINTR_CHAIN让下一个ISR处理。
20、请问在wince中如何在内核中增加一个与\windows同级的目录? 在platform.dat或者project.dat中添加语句。例如要创建根目录下子目录Program Files,语句如下:
root:-Directory("Program Files")
posted @
2009-07-16 15:34 Sandy 阅读(522) |
评论 (0) |
编辑 收藏
昨天进行了上一季度的述职总结,自己也罗列了自身的一些问题,如单元测试不充分,需求理解不透彻,等等问题。领导也针对我的总结提出了几点:
一是一定要重视需求。这个赞同。现在所作的项目频繁的需求变更压得有时不怎么重视需求。这点提得对。
二是一定要重视单元测试。这个赞同,的确单元测试做得不是很充分,就拉上了系统测试,暴漏了很多问题。
三是要有条理。这个赞同。首先我的述职报告条理性就没有别人的好。一二三看起来不是很分明。所以这点以后要多加改进。层次也突出不好。其次呢就是学习要有条理,不能什么都想学。一定要有条理的学习。
四是敬业精神。这个一开始不太好接受。自认为还比较敬业,主动发现问题和加班,敬业有佳。但回去思考了一晚,想想自己还真的不是很敬业,离真正的敬业还是很有差距的。主动发现问题,不只是一个方面,应该是多方面的,比如说原先代码的不合理处,自己清楚,却没有主动提出改进方案。这个不是很敬业。所以以后需要好好改进。
有这么多问题,所以一定要从自身找问题,积极改进。做一个积极向上的好人。
posted @
2009-07-16 09:37 Sandy 阅读(491) |
评论 (0) |
编辑 收藏
昨天发现了一个问题,在我们发布的产品中的各个版本都有。这是一个很棘手的问题。还好,已经有人对问题代码进行了优化。
但是问题又出来了,优化的代码的接口变了。这又是问题。
此时我就想把他的代码改呀改,或者改我自己的代码,以便利用他优化后的代码。发现还是错了。
此时,经验丰富的大师会告诉我利用派生,封装。这的确是一个好办法。看来面向对象的思想还没有深入到我的骨髓,不能很好的体会和运用。
这是昨天的一点收获。拿到别人的代码不要着急去改,如果要用的话,要学会派生和封装,否则改坏了代码,维护代价会更大的。
不过收获归收获,代码封装真的不是很好做,我最后还是放弃了。对比代码的不同,进行修改。有些东西需要搞懂原理,这才是根本。
posted @
2009-07-15 09:39 Sandy 阅读(217) |
评论 (0) |
编辑 收藏
解决方案是:在编辑状态下,点项目菜单 -> XXX属性页 -> 配置属性 -> 清单工具,将右面的“使用FAT32解决办法”选为“是”即可。
摘自:
http://space.loudly.cn/index.php/2/action_viewspace_itemid_63.html不过我的是英文的,路径是Property Pages 下, Configuration Properties->Manifest Tool->General中,将Use FAT32 Work-around 选为Yes即可。
posted @
2009-07-14 13:45 Sandy 阅读(264) |
评论 (0) |
编辑 收藏
有一个内存泄露的问题,折腾了我很长时间了,这个问题存在,也确确实实是内存泄露了。把代码查了一遍又一遍,就是没有看出什么问题,也想了很多方式方法,似乎也都不见效。
怎么办呢?
今天都在想是不是指针被修改了,造成的问题。
发现少打印了一处,奇怪,为什么没有走到那里?原来前面一个出错判断,我直接返回了,没有走到删除的那一步。哈哈,终于被我找到了。
分析了一下原因:
1、代码的问题。代码处理的逻辑还未负责,对此就有了遗漏。建议利用goto,最后做一些删除的处理。这个道理明白,有时用起来就忘了。
2、用心的问题。应该及早的发现该问题,但还是没有认真的对自己的代码进行审查造成的。所以以后要走到自己的代码里面调,尽快发现问题。
加油!不要再犯了。
posted @
2009-07-10 16:43 Sandy 阅读(216) |
评论 (0) |
编辑 收藏
今天在看Windows Mobile Team Blog的时候,看到关于SDK, DTK, DRK的文章,通过阅读,简单的了解一些。所以也和大家分享一下。
摘自: SDK, DTK, DRK: WTF?!
http://blogs.msdn.com/windowsmobile/archive/2009/06/04/sdk-dtk-drk-wtf.aspx
SDK: Software Development Kit
We have not released a new SDK for Windows Mobile 6.5. The Windows Mobile 6 Professional SDK or Windows Mobile 6 Standard SDK are required for Windows Mobile 6.5 application development.
6.5 依然沿用了Windows Mobile 6 的SDK。
DTK: Developer Toolkit
The Windows Mobile 6.5 Developer Toolkit (DTK) is not an SDK! The DTK contains emulators, gesture APIs, and samples useful for developing Windows Mobile 6.5 applications. You will still need to install Visual Studio and the Windows Mobile 6 SDK prior to running the toolkit installer.
6.5发布了一个开发包,下载地址是
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=20686a1d-97a8-4f80-bc6a-ae010e085a6e
其中有了简体中文的模拟器。
在机子上安装了一下,界面效果比原来好看许多,但是改动让我有一些不熟悉。
里面增加了几个头文件:
<gesture.h>
<GesturePhysicsEngine.h>
<WindowAutoGesture.h>
还有几个附带的例子。
DRK: Developer Resource Kit
The Windows Mobile Developer Resource Kit (DRK) is an offline DVD copy of the most useful and relevant Windows Mobile application development tools and resources. Traditionally the DRK does not contain any exclusive content, in that nearly everything on the DRK is available for download online. This time we are pleased to publish the Windows Mobile 6.5 DRK with several sample chapters of Microsoft Mobile Development Handbook from Microsoft Press (Wigley, Moth, and Foot).
这个词是我第一次听说。没有下过。
posted @
2009-07-08 15:34 Sandy 阅读(1810) |
评论 (0) |
编辑 收藏
【进程】
Mobile 中的进程信息大体包含在PROCESSENTRY32结构中,我们可以获得进程的诸多信息,此处无法获得进程所占内存和CPU利用率。
数据结构
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
DWORD th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
TCHAR szExeFile[MAX_PATH];
DWORD th32MemoryBase;
DWORD th32AccessKey;
} PROCESSENTRY32;
typedef PROCESSENTRY32* PPROCESSENTRY32;
代码示例
1
2
// 创建快照句柄
3
4
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5
6
if (INVALID_HANDLE_VALUE != hSnapshot)
7
8

{
9
10
// 先搜索系统中第一个进程的信息
11
12
Process32First(hSnapshot, &pe);
13
14
do
{
15
16
// 可通过pe获取指定的信息
17
18
//……
19
20
// 获取感兴趣的进程信息
21
22
//……
23
24
// 获取进程所在路径
25
26
TCHAR processPath[MAX_PATH]
27
28
HPROCESS hProcess = OpenProcess(0, FALSE, pe.th32ProcessID);
29
30
if (NULL != hProcess)
31
GetModuleFileName((HMODULE) hProcess, processPath, sizeof(processPath));
32
33
CloseHandle(hProcess);
34
35
}while ( Process32Next(hSnapshot, &pe));
36
37
// 关闭快照句柄
38
39
CloseToolhelp32Snapshot(hSnapshot);
40
41
}
42
【模块】
已知进程ID,便可获得对应各模块的信息。在此介绍了如何获得模块的信息。
数据结构

代码示例
1
MODULEENTRY32 me; // 定义模块对象
2
me.dwSize = sizeof(me);
3
// 创建对应进程的模块快照
4
HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
5
if (INVALID_HANDLE_VALUE != handle)
6

{
7
// 先搜索系统中第一个模块的信息
8
Module32First(handle, &me);
9
do
{
10
// 获取模块信息
11
//……
12
// 获取感兴趣的模块信息
13
//……
14
15
// 获取模块所在路径
16
GetModuleFileName(me.hModule, me.szExePath, sizeof(me.szExePath));
17
}while (Module32Next(handle, &me));
18
// 关闭快照
19
CloseToolhelp32Snapshot(handle);
20
}
21
posted @
2009-07-03 15:57 Sandy 阅读(830) |
评论 (0) |
编辑 收藏
蓝牙的状态有三种状态,分别为:BTH_POWER_OFF、BTH_CONNECTABLE、BTH_DISCOVERABLE。
三种状态分别是关闭蓝牙;打开蓝牙,使蓝牙可连接;打开连接,使蓝牙可连接和可发现。
获取蓝牙的状态是利用API函数BthGetMode。设置蓝牙的状态是利用API函数BthSetMode。
首先我们看一下BthGetMode
其原型为:
int BthGetMode(
DWORD* pdwMode
);
其作用为:获得蓝牙设备当前的状态模式.
返回值:如果返回ERROR_SUCCESS ,则成功,否则失败。
pdwMode
);
其作用为:获得蓝牙设备当前的状态模式.
返回值:如果返回ERROR_SUCCESS ,则成功,否则失败。
BthSetMode
其原型为:
int BthSetMode(
DWORD dwMode
);
其作用为:设置蓝牙设备的状态模式,并将它表现在控制面板上。自启或硬件插入的时候都将维持此状态模式。
返回值:如果返回ERROR_SUCCESS ,则成功,否则失败。
比较简单吧。不举例了。
posted @
2009-07-03 15:45 Sandy 阅读(488) |
评论 (0) |
编辑 收藏
转自:
http://www.blogjava.net/TiGERTiAN/archive/2009/03/19/260906.html
【实用技巧】Windows Mobile 手机连接电脑时,如何使用GPRS上网,同时跟电脑保持连接。(USB和GPRS共存问题) 最近移动项目接近尾声,以及很多相关的新项目又接踵而至,所以经常需要带着手机到处去演示。现在有个问题就是,我们连接的是移动专网,而且带了手机卡验证,没有办法通过互联网去连接,这就需要我们一边连着电脑一边去连接GPRS上网,之前公司的D600搭配ActiveSync 4.5是可以的,就是把高级网络功能关闭,这样既可以连接电脑,又可以上GPRS,后来不知怎么的,不能用了。只好另想他法,在国外论坛上面,我发现了一个方法就是使用Pocket Controller。
步骤是:
1、先安装PC上面的Pocket Controller,然后通过ActiveSync开启高级网络功能连接手机,然后Pocket Controller在连接时会自动提示给手机安装客户端。
2、安装完之后,在Pocket Controller中的设置里面,建立一个新的连接通过TCP/IP的。IP就是169.254.2.1
3、确认手机开启了TCP/IP连接允许,然后使用Pocket Controller去连接手机。连接成功之后,禁掉ActiveSync,也就是关闭连接设置里面的 允许USB连接和允许通过以下端口连接 两项。
4、这样操作之后Pocket Controller仍然与手机保持连接,而且手机也可以上GPRS或者Edge了。
还未进行验证是否可行,先收入囊中,以防找不到了。
posted @
2009-07-01 11:08 Sandy 阅读(663) |
评论 (0) |
编辑 收藏