查看: 1308|回复: 0
打印 上一主题 下一主题

WinCE驱动开发问题精华集锦1

[复制链接]
跳转到指定楼层
沙发
发表于 2015-3-30 12:31:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在mediaplayer全屏播放的时候,我可以用键盘上的某一个键调节声音大小,现在我想在屏幕上显示调节的结果就跟我们看电视一样能出来一些标记。当声音变大在屏幕上就增多,当声音变小的时候就减少
得到播放窗口的DC,然后在上面显示一个不同颜色的矩形或者其它形状。

在ce自制平台中如何添加自己的驱动?cec文件和reg,bib文件有何区别?看混了,不知道如何才能让驱动注册到平台中。另外,reg和bib是我在编写驱动必须要自己写的么
CE 的驱动分为本机驱动和流驱动,本机驱动你可以修改源码(在%_WINCEROOT%/PUBLIC/COMMON/OAK/DRIVERS),然后 build驱动源码,之后用PB编译内核。流驱动是以DLL的形式被系统程序加载的。加载流驱动要在注册表中添加信息,这和cec文件没关。如果你想把此驱动DLL和注册信息作为一个整体给别人使用,那么就要做一个cec文件,PB能够读取cec文件内容并加载到内核工程中。cec文件相当于安装程序。

我安装的是evc4.0,我开发的系统要显示中文比如姓名什么的。在编辑的时候是中文显示,但是到了输出时,显示的都是乱码。不知道应该怎么去解决
EVC的模拟器不支持中文。所以显示出来的都是乱码。1、你可以只显示英文,调试结束后在改界面为中文。2、安装PB,PB的模拟器支持中文。   

CStatic及其控件的文字无法垂直居中显示,虽然在evc的资源编辑器中可设置,但是一旦运行,却无法垂直居中显示
这种情况正常,而且除此之外还不能右对齐。

获取设备ID的种类有哪些
除了手机模块外,还有CF卡有序列号、硬盘有ID号、网卡有MAC号等。这几种方法数获取手机模块ID最简单。

   
      在应用程序中,如何向修改本机的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。

如何向控制面板中那样,修改系统声音的音量
调用API waveOutSetVolume(HWAVEOUT, dwVolume ),一般参数1为0。在[HKEY_CURRENT_USER/ControlPanel/Volume]下是系统声音的注册表设置。

在应用程序中如何实现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组件实现。

   
      在应用程序中如何实现系统待机
void GwesPowerOffSystem(void);

   
      在WINCE下如何实现键盘钩子
我写了一个简单的例子,把其中主要部分截取出来放到了我的FTP里。用户名以及密码均为winceuser,地址是ftp://211.95.73.26/fllsoft@sina.com/SourceCode/用钩子禁止系统键.rar。

   
      在WINCE中如何得到网卡MAC地址
事实证明,获得物理网卡的MAC地址并没有被统一成一个API或者IOCTL,如果网卡驱动程序没有提供接口的话只能直接访问寄存器获得。读者可以参考目录WINCE500/PUBLIC/COMMON/OAK/DRIVERS/NETCARD里的一些驱动源码。

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。

   
      wince下只是把调制解调器的驱动挂接在了com1,如何将器驱动挂接在com2上?
1、在HLM/drivers/buildin/com2/unimodem下复制和com1一样的数据 2、在HLM/ExtModems/ HayesCompat下改写Port为COM2:,再改写FriendlyName为"Hayes Compatible 在 COM2:"。

如何定制自己的外壳
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在内核中,二是删除依赖标准外壳的组件。

   
      我原来的工程是x86版本的,编译选项只有x86,我如何能够编译ARM版本的
两种办法:
1、用EVC新建一个工程的时候,建议复选“CPUs”列表,这样发生了这种事情也能够轻易通过选择“WCE Configuration”工具栏中的CPU列表来编译不同CPU版本的软件
2、如果打开工程后CPU列表中只有x86,而此时已经安装了ARM版本的SDK,那么单击EVC菜单“build”-“configurations”,然后单击“add”按钮来添加CPU。

   
      通常情况下WINCE采用串口1作为调试时输出信息用途,要正式出产品前如何去掉串口1的调试功能
正常情况下串口1只有在编译debug版本的内核时才在BootLoader中初始化串口1用于输出信息,而编译release版本会跳过此代码。而有些 BSP设计成没有宏定义,也就是说无论什么版本都会在BootLoader中初始化串口1,这样造成WINCE启动后串口1无法被应用程序使用。对于这种情况只能在BootLoader源码中删除初始化代码,如OEMInitDebugSerial。

基于wince的应用程序能建成console project么?
不能

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,这样所有应用程序就可以通过调用流驱动接口函数来访问,非要加文件系统也是可行的,通过修改注册表就可以做到,但是麻烦一些。

   
      我怎么能在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”添加到左边的内核工程中。

   
      WINCE有没有相对路径概念?如果没有如何得到当前模块的路径?
1、WINCE没有相对路径概念,只有绝对路径,所以凡是涉及到路径均为绝对路径。
2、调用API GetModuleFileName,传递一个模块的实例句柄就能够得到模块的绝对路径。

   
      怎样让 POCKET WORD打开*.dat格式(里面都是数据)的文件?   
两种办法:
1、调用API ShellExecuteEx,在结构体SHELLEXECUTEINFO中添加.dat文件的路径。
2、调用API CreateProcess,在第二个参数中设置.dat文件的路径。

   
      x86 Rom Boot Loader真的可以实现吗?它确实能代替BIOS启动计算机?   
Rom Boot 被设计存放在Flash/EEPROM中,也就是原来BIOS的位置,这样当上电后CPU到固定地址执行代码,也就是执行了Rom Boot的代码,它对整个硬件系统进行初始化和检测,并且支持通过网卡从远程机器上下载nk.bin或者从本地IDE/ATA 硬盘的活动分区中寻找nk.bin文件加载。 Rom Boot的优点就是引导并且加载速度快,而且它自身完成了所有的操作,这样就不用BIOS、MSDOS,更不用Loadcepc了。

对于x86 Rom Boot Loader,如何Build得到Romboot.rom?
1、在PB中打开一个内核工程(x86的) 2、单击PB菜单“Build”-“Open Build Release Directory” 3、用cd命令进入 %_WINCEROOT%/Platform/Geode/Romboot 4、build

如何设置、更改显示分辨率
能否设置、更改显示分辨率由显示驱动程序决定,而没有统一的标准。例如CEPC,在启动的时候可以通过设置loadcepc.exe的参数 /L来决定 WINCE启动后的显示分辨率,这是由于显示驱动“VGA Linear Framebuffer”支持,而Geode可以通过在定制内核时修改注册表项来决定WINCE启动后的显示分辨率。

几个硬件使用同一个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处理。

请问在wince中如何在内核中增加一个与/windows同级的目录?
在platform.dat或者project.dat中添加语句。例如要创建根目录下子目录Program Files,语句如下:
root:-Directory("Program Files")   

文件格式如下所示,我想把每行的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 );

GWES组件的功能有哪些?
GWES不仅负责GDI、窗口、消息,还负责管理本机设备驱动程序,负责加载显示、键盘鼠标、触摸屏驱动程序,而且GWES本身包含电源、LED驱动程序。

如何在PB中预先设定好存储内存和程序内存的大小,我想多划分一些空间给程序内存?   
两种办法:
1、在定制内核时在config.bib文件中设置FSRAMPERCENT = number,具体number可参考标题为“FSRAMPERCENT ”的帮助文档。这种办法是修改内核的设置,所有一直有效。
2、在应用程序中调用API SetSystemMemoryDivision,如果函数返回SYSMEM_CHANGED表示成功,如果返回SYSMEM_MUSTREBOOT表示需要热启动才能有效。这种办法需要每次启动后调用API才有效。

如何取消鼠标光标?
通过取消SYS变量来实现此目的,在PB命令行下键入“set SYSGEN_CURSOR=”,然后回车确认。

EVC下调用TextOut如何编译会出错?
类似这样的问题很多,这是因为EVC的帮助文档内容有错误。可能EVC的帮助文档内容是从桌面Windows帮助文档复制过来的,所以很多API函数还有例子代码都有错误,例如帮助文档中包含一个API函数的说明,但是实际编译的时候提示没有这个API,有的例子代码采用ANSI字符串,而WINCE的 API都是宽字符版本,造成直接复制过来编译失败。
因为MFC for WINCE的CDC类中没有TextOut成员函数,所以编译会出错,可以用其它类成员函数ExtTextOut或者DrawText替换。

我如何将我的dll软件让现有的ce系统认可?尽管我也知道应该使用signfile.exe程序进行签名,但是我并不知道那个ce系统认可的签名应该是啥
如果你说的WINCE系统内核已经加入了签名认证机制,那么没有私钥对你的DLL文件签名肯定是无法运行在此内核中的,一般签名密钥的密钥长度都是1024位,很难破解。

如果查看WINCE注册表中的内容?
两种办法:
1、建立同步后,用EVC自带的工具“Remote Registry Editor”打开查看。
2、从网上下载注册表查看工具,放到WINCE设备中。

调用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或者其它组件。
   
      在PB的config.bib文件中,“IMGFLASH”表示什么意思呢?
表示能够刷NK到ROM中,具体请查看标题为“IMG Environment Variables”的帮助文档。

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下驱动开发基础》。

修改了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来编写编译。

开发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的结果。   

编译器报错:error C2065: 'CFileFind' : undeclared identifier,如何解决?
MFC for WINCE版本没有CFileFind类,所以要查找文件只能调用API FindFirstFile 和FindNextFile。

如何设置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。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表