smart kids

【嵌入式】 wince 移植 必杀技

0
阅读(33225)

       结束了嵌入式生涯,现在改行了,以前的东西会慢慢被淡忘,真滴好担心,因此每天晚上都抽时间温习下,让自己每天都进步,我把自己的总结贴出来跟大家一起分享:

 

1.arm上wince的移植概要

需要的仅仅是bsp包,常常由厂家提供,当然可以自己写,唯一的工具就是pb,即是windows的platform builder,也是所说的wince,现在有5.0和6.0,建议从wince5入手,wince加载相应bsp,构建,顺利的话,完成了

2.wince编译出现类似错误

错误类似:

NMAKE :  U1073: don't know how to make 'C:/WINCE500/platform/common/lib/ARMV4I/retail/oal_cache_arm926.lib'

问题出在,厂商提供的bsp版本,安装的过多,只要安装一个即可,例如atmel的可以安装src或者bin都行,最好是src的,可以做一下修改修复错误:

C:/WINCE500/PLATFORM/COMMON/SRC/ARM
下的DIRS文件修改成:
DIRS=/
    common  /
    ARM920T /
    ARM926  /
    INTEL   /
    SAMSUNG /
    ATMEL

即可

3.wince编译选项简单解释

"Sysgen","Build and Sysgen"和"Build and Sysgen current BSP"

Sysgen:

当你在"Catalog"中添加或删除了新的item的时候,用这个。eboot的代码修改了,貌似也要用这个哦~

Build and Sysgen:

当你更新了/public目录下的源代码的时候,需要用这个。一般比如在打patch以后,可能就需要进行Build and Sysgen。

Build and Sysgen current BSP:

当你只改变了你的BSP部分的代码,就可以用这个选项

4.wince环境变量查看等

pb->build os->open release directory打开的窗口中使用set命令可以看到

同样的,用set ENV=XXX,即可添加或者修改,set ENV= 则删除了

发现,set命令虽然能查看环境变量,但是部分环境变量是没有,别着急,看看bsp根目录,也就是platform下你自己的bsp目录,下边有source.cmn没?再看看里边的定义吧,同时注意source文件

5.wince source文件解释

sources.cmn是Common Source文件,BSP内所有的源代码编译都会用到该文件。
source文件是针对特定目录的,只对当前目录有效

5.wince 分析代码结构方法

注意source source.cmn dirs等文件,注意环境变量获取方法,例如eboot代码:

通过查看 C:/WINCE500/PLATFORM/AT91SAM9261EK/SRC/BOOTLOADER/EBOOT/SOURCE

C:/WINCE500/PLATFORM/AT91SAM9261EK/SOURCE.CMN

C:/WINCE500/PUBLIC/COMMON/OAK/MISC/SOURCE.DEFAULT

以及set之后的所有环境变量,同时参考C:/WINCE500/BUILD.log即可清除组成

6.source insight显示完整文件路径

options -> preferences -> Display, 去掉"Trim long path names with ellipses",
这样就可以在source insight下显示文件的完整路径了

7.pb不能生成eboot.nb0

把原来的PBWorkspaces删掉,新建一个工程,导入几个选项,build and sysgen current bsp即可

8.NK.nb0 和 NK.bin区别

nk.bin和nk.nb0都是CE的镜像

首先,NK.BIN中的内容是被压缩过的,NK.NB0中的内容是没有压缩的。
两者大小的区别是因为在生成过程中BIN会将你设定的后面的NULL自动去掉,而NB0就不会。
NB0的大小就是第三个变量ROMSIZE所设置的大小。
由于nk.nb0是非压缩的数据,里面的数据就是NK展开以后在内存里面的数据。
而nk.bin是有压缩的数据,里面的数据是压缩以后类似于成块形的数据,被loader拷贝到内存以后没有区别。
由于bin文件需要解压,因而其下载方式也不一样,
通常,通过串口直接下载用nb0,pb下载用bin。
其次,nk.nb0是可以直接烧到FLASH/ROM中的,是代码镜像,可以直接跳转到其入口执行。
而nk.bin是Microsoft binary image格式的文件,必须按其格式定义解开到其指定的地址空间的位置才能执行。

9.NK.nb0没有生成

编辑

C:/WINCE500/PLATFORM/AT91SAM9261EK/FILES/config.bib

在最后添加

ROMSTART=80069000
ROMWIDTH=32
ROMSIZE=02000000

重新生成下,整个bsp,包括public和private,直接build and sysgen即可

10.虚拟地址和物理地址的映射关系

参考文件

WINCE500/PLATFORM/AT91SAM9261EK/SRC/INC/cfg.inc

可以获得物理到虚拟的映射

参考文件

C:/WINCE500/PLATFORM/AT91SAM9261EK/FILES/config.bib

可以获得内存映射图,内核启示地址等

11.各种配置文件和头文件哪里找

寻找各种src下的inc目录即可,如:

PLATFORM/COMMON/SRC/INC/

PLATFORM/COMMON/SRC/ARM/ATMEL/AT91SAM926x/INC

12.kitl

kitl是一种调试方式,可以在工程设置中禁止掉,kitl通过网络窗口等与pb通信

13.wince中文

在工程设置里,选择默认语言文中文即可,附加选择一个中文字体

14.wince网络配置

其实不用配置什么东西,bsp网卡驱动加入之后,如果成功,进入系统后,会自动建立网络连接的,默认可以上网了~可以参照选择:

Networking – Local Area Network (LAN)  →  Wired Loacal Area Network
Networking – Wide Area Networking→  RAS/PPP→Autodial
Networking – Wide Area Networking  →TAPI→Unimodem

最好是kitl先关闭掉~貌似会有影响~还没研究~

15.wince音频驱动

音频驱动有3种模式:1.MDD/PDD模式.2.Wavedev2模式.3.UAM模式 它们相同的地方很明显:它们公开相同的接口,因为是流驱动!都是透过流接口与上层的waveapi.dll交互.

16.wince音频驱动wavedev生成过程

整个驱动是一个dll,微软的mdd和自己写的pdd要连接成一个dll,此处通过build.log简单跟踪此dll的生成过程,从dll的reg了解到,dll名字为at91sam9261ek_wavedev.dll,.log文件直接搜索:

BUILD: [01:0000000393:INFO  ] C:/WINCE500/PBWorkspaces/newmsg9261/WINCE500/AT91SAM9261EK_ARMV4I/cesysgen/oak/lib/ARMV4I/retail/wavemdd.lib C:/WINCE500/platform/AT91SAM9261EK/lib/ARMV4I/retail/gpio.lib

BUILD: [01:0000000394:INFO  ]    Creating library C:/WINCE500/platform/AT91SAM9261EK/lib/ARMV4I/retail/at91sam9261ek_wavedev.lib and object C:/WINCE500/platform/AT91SAM9261EK/lib/ARMV4I/retail/at91sam9261ek_wavedev.exp

BUILD: [01:0000000395:INFO  ]  set LIB=C:/WINCE500/sdk/CE/lib

BUILD: [01:0000000396:PROGC ] Linking C:/WINCE500/platform/AT91SAM9261EK/target/ARMV4I/retail/at91sam9261ek_wavedev.dll

搜索到以上内容,看到红色部分,就是微软提供的mdd库,并且提供了源码的哦~可以用来跟踪~

17.wince上出现文件找不到的错误

有时候打开一个图片或者视频,音乐什么的,wince会说找不到文件,其实是不识别那个格式

18.wince驱动简单分类

wince驱动分类如下:
--1--实现接口
本地驱动 和 流驱动
本地驱动实现的接口不统一,很复杂的,针对不同的设备接口不同,由操作系统调用,应用程序不能调用
流驱动暴露给系统统一的接口,应用程序可以通过设备文件调用,这个跟linux的驱动很像了哦
所以,一个驱动可以实现成流,也可以实现成本地,都没问题
--2--代码结构
单层 和 多层
单层就是自己实现从上到下所有的功能,所有的调用
多层就是mdd/pdd即,设备无关/设备相关的模式,驱动一般只需要实现pdd即可
综上,一个驱动可以是单层的流,也可以是多层的流,可以是单层的本地,也可以是多层的本地,言之就是用什么样的接口+采取什么样的代码结构~就像人分为男人和女人,又分为好人和坏人,有好男人和好女人,也有坏男人和坏女人咯~

19.wince映射物理内存到虚拟内存的方法

--1--MmMapIoSpace

PaBaseVir = (unsigned int *)MmMapIoSpace(PhysAddr, PIO_REG_SIZE, FALSE);

--2--VirtualAlloc+VirtualCopy

v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
          if (v_pIOPregs == NULL){
                    RetValue = FALSE;
          }
          else {
                    if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE)) {
                             RetValue = FALSE;
                    }
其中PHYSICAL_ADDRESS PhysAddr;类型为:

typedef LARGE_INTEGER PHYSICAL_ADDRESS; -->

typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    };
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;

20.wince组件管理和控制

我们知道在bsp上右键直接添加组件,但是谁来控制添加了哪些组件呢?实际上用的是环境变量!在build-os菜单下(ce5),打开命令行,输入set命令,当然可以set > d:/set.txt,之后查看发现

BSP_AT191SAM9261EK_NANDFLASH=1

在看platform.reg

IF BSP_AT91SAM9261EK_NANDFLASH
#include "$(_TARGETPLATROOT)/SRC/DRIVERS/NandFlash/NandFlashDll/NandFlash.reg"
ENDIF BSP_AT91SAM9261EK_NANDFLASH

明白了pb怎么控制组件的了吧~

21.一个好用的msi安装工具制作工具

Advanced Installer 相当好用~

22.wince的LCD驱动RGB顺序问题

wince这一点非常好的,"forceRGB"=dword:1注册表中的这个项目,这个注册表是lcd驱动的注册表,直接修改,就可以交换rgb的中r和b的位置,实际上,根据不同bsp实现不同,直接按照bsp驱动的实现去跟踪即可,跟踪简要路线是:

GetMasks函数,关键变量是 m_bForceRGB,此变量在初始化时候赋值,初始化函数很诡异,实际上是类的构造函数,找不到调用的地方吧,分析代码一定要注意,这个函数是LCDC6xhw::LCDC6xhw,通过这个函数中的QueryMode函数调用,查找注册表中前边说的"forceRGB"=dword:1,最终确定了rgb的顺序~

23.wince的LCD驱动

LCD实际上分为2种架构

--1--mdd/pdd

一般bsp都实现这个,起码atmel和s3c如此,上层规定下层实现几个特定函数,pdd实现即可

--2--directDraw

让应用少走层次,直接绘图,当然也是通过驱动oal功能函数咯

具体参见http://blog.csdn.net/nanjianhui/archive/2008/09/14/2790871.aspx大师解释,呵呵

24.eboot单独快速译

wince出了名的编译慢,每次修改eboot代码,要整个sysgen一下,很慢,时间浪费了。且看今天的eboot单独快速编译

打开pb的BuildOs菜单下的命令行,之所以从这里打开,是因为各种环境变量已经设置好了,打开之后,要自己确定下你修改了的那个文件所在的文件夹,比如我修改了:

C:/WINCE500/PLATFORM/COMMON/SRC/ARM/ATMEL/AT91SAM926x/BOOTLOADER/GenericEBOOT/main.c

那么我就进入(当然是命令行哦)

C:/WINCE500/PLATFORM/COMMON/SRC/ARM/ATMEL/AT91SAM926x/BOOTLOADER/GenericEBOOT/

然后

build -c

过程中,我们发现,生成的是Linking C:/WINCE500/platform/common/lib/ARMV4I/retail/GenericEBOOT.lib,也就是说,当前编译生成的东东,只是最终使用的一个库而已,那么最终生成运行时镜像的是哪里呢?因为eboot还有其他的文件夹,找到

C:/WINCE500/PLATFORM/AT91SAM9261EK/SRC/BOOTLOADER/EBOOT

我们在此

build -c

发现,生成了含有类型exe的文件,在目录

C:/WINCE500/PLATFORM/AT91SAM9261EK/target/ARMV4I/retail

发现,生成的eboot等最终镜像了~

总结一下规律,要快速编译某个东西,就在被修改那个文件夹build -c,之后再这个东东的“起点”也是“最终点“那里build -c!那么怎么确定哪里是辅助库,哪里是镜像终点呢?也很简单,猜想是由当前文件夹下的sources文件决定的,看到

C:/WINCE500/PLATFORM/AT91SAM9261EK/SRC/BOOTLOADER/EBOOT/sources中

TARGETNAME=eboot
TARGETTYPE=PROGRAM
RELEASETYPE=PLATFORM
EXEENTRY=StartUp
NOMIPS16CODE=1

有exe入口点,有目标类型,看来这里是终点哦~又看到

C:/WINCE500/PLATFORM/COMMON/SRC/ARM/ATMEL/AT91SAM926x/BOOTLOADER/GenericEBOOT/sources

RELEASETYPE=CUSTOM
TARGETTYPE=LIBRARY

类型是lib,可想而知,这里肯定是辅助库咯~

综上分析,在被修改的地方build -c,在源头build -c,参照sources可以知道依赖和类型~

at91sam9261ek,源头build后,在C:/WINCE500/PLATFORM/AT91SAM9261EK/target/ARMV4I/retail中找到生成的镜像!

25.wince驱动快速编译

--23--讨论了eboot的快速编译,实际上驱动的快速编译原理是相通的,首先找到驱动被修改的目录,之后build -c,最后看下他被连接到哪去了,驱动一般是dll的,且被拷贝到了一个lib目录下。build-c之后,找到生成的dll,copy到release目录,此步骤可用命令buildrel,然后执行下makeruntimeimage就行了~超快~当然,命令行的情况下,直接:makeimg命令即可

26.evc程序不能执行

在工程的settings里,设置下mfc用静态库,试试,可能是因为缺少动态库没能执行,静态库链接即可

27.wince的emulator很好用

wince5中,使用emulator很简单,新建一个设备,选择emulator,sysgen的x86版本的工程,之后连接设备就行了;其中,emulator可能造成系统不稳定,所以初次使用要设置下,不然会有错误:

One or more files from the Emulator for Windows CE installation is missing.

实际上是系统禁用了emulator,解决办法:

1.

Click Start, click Run, type sysdm.cpl, and then click OK.

2.

In the System Properties dialog box, click the Advanced tab.

3.

Under Start and Recovery, click Settings.

4.

In the Startup and Recovery dialog box, click Edit.

5.

Disable PAE mode by removing the /pae option if it exists.

6.

Remove the /noexecute option if it exists.

7.

Add the /execute option.

8.

On the File menu, click Save.

9.

To exit Notepad, click Exit on the File menu.

10.

To close System Properties, click OK two times.

11.

Restart your computer.

实际上就是修改下启动参数,照着做就行了~

28.wince的emulator是神级的工具,介绍2点使用

--1--Target菜单中的AttachDevice会自动连接emulator

--2--emulator的FolderSharing更是妙不可言,试了才知道

28.快速删除.svn文件夹

我们知道,svn会在控制的文件夹下生成.svn数据库,发布软件的时候会很讨厌,下面的方法快速的删除.svn文件夹

新建个.reg,内容如下:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/Folder/shell/DeleteSVN] @="Delete SVN Folders"
[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/Folder/shell/DeleteSVN/command]
@="cmd.exe /c /"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r /"%1/" %%f IN (.svn) DO RD /s /q /"%%f/" /""

保存后,导入注册表,亲自试过,好用~

30.wince点灯方法

pa = (unsigned int*)OALPAtoVA((DWORD)0xfffff400, FALSE);
*((unsigned int *)pa) = 0x1<<29;
pa = (unsigned int*)OALPAtoVA((DWORD)0xfffff410, FALSE);
*((unsigned int *)pa) = 0x1<<29;
pa = (unsigned int*)OALPAtoVA((DWORD)0xfffff434, FALSE);
*((unsigned int *)pa) = 0x1<<29;

31.系统加载so动态库查找的位置

动态库的搜索路径搜索的先后顺序是:

1.编译目标代码时指定的动态库搜索路径;

2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;

4.默认的动态库搜索路径/lib

5.默认的动态库搜索路径/usr/lib

在上述123指定动态库搜索路径时,都可指定多个动态库搜索路径,其搜索的先后顺序是按指定路径的先后顺序搜索的。