我会在blog中将开发CE5.0时遇到的问题总结出来,供有遇到相同问题的朋友参考。因为我在解决这些问题时,也是参考了网上很多朋友的文章或帖子,在这里对他们表示一下感谢呵呵。 我对问题的解释如果有不对的地方还请高手指正,免得误人子弟哈。
<!--[if !supportLists]-->1. <!--[endif]-->如何加入或删除 BSP 中的模块。
这里以 display 驱动为例来讲解。
BSP 的根目录下有一个 $(platform name).bat 文件。里面定义了一系列的开关,比如:
set BSP_NODISPLAY=
或
set BSP_NODISPLAY=1
我们可以在 workspace 下的 platform.bib 中可以看到有这么一段定义:
IF BSP_NODISPLAY !
S3C2440DISP.dll $(_FLATRELEASEDIR)/S3C2440DISP.dll NK SH
ENDIF BSP_NODISPLAY !
因此,如果我们在 .bat 中定义了 BSP_NODISPLAY 为 1 ,则 S3C2440DISP.dll 不会被加入到 NK 中。反之,则在生成 NK 的时候需要加入 S3C2440DISP.dll 。
而如何将 display 驱动加入编译列表呢。这就要看 WINCE500/PLATFORM/$(platform name)/Src/Drivers 下的 dirs 文件了。文件里枚举了要参与编译的子文件夹。 display 驱动在 Display 文件夹内。因此,如果要将 display 驱动加入编译,则要在 dirs 文件中加入 Display 文件夹,反之则去掉。
再看 Display 文件夹内的内容,看到有一个 sources 文件,里面有这么一段:
TARGETNAME=S3C2440DISP
TARGETTYPE=DYNLINK
表示将会生成一个名为 S3C2440DISP 的动态链接库。
看到这里就明白了,如果要加入或删除 BSP 中的驱动,要改动文件有:
$(platform name).bat :添加或修改开关
dirs :决定驱动代码是否参与编译
platform.bib :如果在加入新的驱动时,需要修改这里,把新的驱动加入 NK 中。
<!--[if !supportLists]-->2. <!--[endif]-->在 build 自己配置的 OS 时,可能遇到的几个错误及其解决方法
我曾经遇到过这个错误:
BUILD: [01:0000000341:ERRORE] PowerButton.obj : error LNK2019: unresolved external symbol SetSystemPowerState referenced in function PWR_IST
BUILD: [01:0000000342:ERRORE] PowerButton.obj : error LNK2019: unresolved external symbol GetSystemPowerState referenced in function PWR_IST
BUILD: [01:0000000343:ERRORE] C:/WINCE500/platform/smdk2440a/target/ARMV4I/debug/PowerButton.dll : fatal error LNK1120: 2 unresolved externals
根据信息,看出是在生成 driver 里的 power button 时,找不到两个函数。我查了文档,这两个函数都是声明在 coredll.lib 中的,然后我又去看了我生成的 coredll.lib ,发现的确找不到这两个函数。检查了一下 OS 的组件,发现原来是因为没有把 power management 组件添加进来。
而下面这个错误就明显了:
BUILD: [01:0000000445:ERRORE] NMAKE : U1073: don''t know how to make ''C:/WINCE500/PBWorkspaces/tiny_kernel/WINCE500/smdk2440a_ARMV4I/cesysgen/sdk/lib/ARMV4I/debug/ndis.lib''
BUILD: [01:0000000447:ERRORE] NMAKE.EXE -i -c BUILDMSG=Stop. LINKONLY=1 NOPASS0=1 MAKEDLL=1 failed - rc = 2
这个就是因为没有添加 NDIS 相关组件,导致在编译 BSP 里网络相关的 driver 时,找不到相应的 lib 而报错。
<!--[if !supportLists]-->3. <!--[endif]-->没有生成 stepldr.bin 和 eboot.bin
检查一下是不是在 debug 模式下,如果是,切换到 release 模式下就可以了。
<!--[if !supportLists]-->4. <!--[endif]-->遇到 Error - cannot open input file <...> /postproc/nlscfg.inf
运行 Build OS 下的 Copy Files to Release Directory
<!--[if !supportLists]-->5. <!--[endif]-->BLDDEMO: There were errors building (projectname) ,但 error 为 0
把 clean before building 勾上,再 sysgen 一次。
<!--[if !supportLists]-->6. <!--[endif]-->在编译 BSP 的内容时,出现:
NMAKE : U1073: don''t know how to make ''C:/WINCE500/public/common/sdk/lib/ARMV4I/retail/coredll.lib''
我检查了 log ,发现在此之前是一句
Linking /WINCE500/PLATFORM/SMDK2440A/Src/Common/Smartmedia/Dll/ directory.
因此看出是在 smartmedia/dll 文件夹里面出了问题。打开这个文件夹,打开里面的 sources 文件,可以看到 coredll.lib 被定义为
$(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib
而 error 信息为 C:/WINCE500/public/common/sdk/lib/ARMV4I/retail/coredll.lib
说明 _COMMONSDKROOT 等于 C:/WINCE500/public/common/sdk ,而此时 _COMMONSDKROOT 应该跟 _SYSGENSDKROOT 一样才是对的。
在 WINCE500/PUBLIC/COMMON/OAK/MISC/sources.default 中,有如下定义
_COMMONSDKROOT=$(_COMMONPUBROOT)/sdk
_COMMONOAKROOT=$(_COMMONPUBROOT)/oak
_COMMONDDKROOT=$(_COMMONPUBROOT)/ddk
_SYSGENSDKROOT=$(_PROJECTROOT)/cesysgen/sdk
_SYSGENOAKROOT=$(_PROJECTROOT)/cesysgen/oak
_SYSGENDDKROOT=$(_PROJECTROOT)/cesysgen/ddk
我又参看了 makefile.def 中对 _ COMMONPUBROOT 的定义:
比较长,共分了四种情况
(1) OS projects during sysgen
(2) OS projects during compile
(3) WINCEPROJ projects
(4) Other projects.
其中,在 build BSP 的时候,应该是属于第四种。
为了便于理解,我去掉了 log 和注释。
!if "$(_IN_CESYSGEN)" != ""
_COMMONPUBROOT=$(_PUBLICROOT)/common
__PROJROOT = $(_PROJECTROOT)/cesysgen
!else if ("$(WINCETREE)" == "winceos") || EXIST($(_PUBLICROOT)/$(WINCETREE)/cesysgen/makefile)
_COMMONPUBROOT=$(_PUBLICROOT)/common
__PROJROOT = $(_PUBLICROOT)/$(WINCEPROJ)
!else if "$(WINCEPROJ)" != ""
_COMMONPUBROOT=$(_PROJECTROOT)/cesysgen
__PROJROOT = $(_PUBLICROOT)/$(WINCEPROJ)
!else
_COMMONPUBROOT=$(_PROJECTROOT)/cesysgen
__PROJROOT = $(_PROJECTROOT)
!endif
为了搞清楚是怎么回事,我修改了 makefile.def ,加入 MESSAGE 语句,看看在 build 的时候到底跑到了哪个分支里。
修改完后,进入控制台,进入 smartmedia/dll 文件夹下,输入 build 。运行完后,打开文件夹下的 build.log ,发现跑到了第二种情况里。
原来是因为 EXIST($(_PUBLICROOT)/$(WINCETREE)/cesysgen/makefile 这个条件满足了。
其中 _PUBLICROOT 即 WINCE500/public ,而 WINCETREE 在 makefile.def 中定义为 WINCETREE=$(_CURSLMTREE) ,从 set 命令中可以查到, _CURSLMTREE 是项目名,我的项目名是 voip 。则整个路径就成了
WINCE500/public/voip/cesysgen/makefile ,结果这个路径恰好存在,囧。
看来以后给项目起名字要复杂点,避免这个冲突,不然真是搞死人啊。
<!--[if !supportLists]-->7. <!--[endif]-->Warning: Image exceeds specified memory size by 4012 bytes and may not run.
内核组件加多了,超出了 config.bib 原有的定义。因此修改 config.bib ,增加 RAMIMAGE 的大小。注意,修改的是 workspace 下的 config.bib 而不是 PLATFORM 下的。我之前直接在 platform builder 的 parameter view 里面修改,结果改的 config.bib 根本就不会被工程访问到。
另外,最好把 ROMSIZE 也改成 RAMIMAGE 一样的大小,这样 NK.nb0 就可以装下整个 NK 了,否则会生成 NK.nb1 甚至更多。
但有可能在下载 NK.bin 的时候会发生错误,原因是 eboot 中有两个宏定义要和 config.bib 保持一致。 ROM_RAMIMAGE_START 和 ROM_RAMIMAGE_SIZE 。这两个宏要和 config.bib 中的 RAMIMAGE 的相关定义保持一致。
这样改完后,就可以正常运行了。
<!--[if !supportLists]-->8. <!--[endif]-->直接用 DNW 将 .nb0 下载到 RAM 中无法运行
检查一下 DNW 的 configuration 中的 download address ,要和你下载的 .nb0 对应的 .bib 中 RAMIMAGE 的起始地址保持一致,但 RAMIMAGE 规定的是虚拟地址,而 DNW 的 download address 是物理地址,要通过查找 MMU 映射表,将其转换为物理地址。 CE5.0 上的映射表在 oemaddrtab_cfg.inc 文件中。
原文地址:http://hi.baidu.com/lth93/blog/item/3483ce2a32b22c90023bf65b.html