前两天做了个WinCE的微内核,8MB,不到2s就启动起来了。但在实际项目中,最终的映像一般都高达好几十M,将如此大坨的映像从非易失性的存储器中搬运到内存,就需要2s多,那么一个功能完善的WinCE系统,最快多久能启动起来呢。希望是3s,这可能吗?加速WinCE的启动,又有几种可行的方法?
采用更强劲的硬件平台肯定是行之有效的方法。但种种因素会导致实际情况中,这个最简便的方法往往最不可能实施。在特定的硬件平台下,提高系统的工作频率也会有所改善。但这也面临着系统功耗增加和系统稳定性降低等一系列问题。一般情况下,MCU的工作频率都略低于它的标称值。在项目方案基本确定的情况下,改动硬件是不太现实的,只有从软件的角度挖掘潜力。下面从软件的角度描述一些可行的方法。
优化BOOT,提高BOOT运行时的工作频率。在一些平台上BOOT启动时,MCU并没有全速运行。这是可以尝试的一种方法,并能提高读取内核映像的速度。但如果BOOT已经全速运行,那可以看看是否可以再精简一些,总之是想尽一切办法,让它以最快的速度启动并加载内核到内存,然后将控制权交给内核。另外,在一些系统中会增加启动进度显示。如果要实现快速启动,并且系统能在5s内起来,进度条可以省了,因为本身它也会占用一定的时间。
缩小NK,这是最关键也是最有效的一个方向。具体实施有两个考虑,首先是精简系统,既然WinCE是可定制的操作系统,就要用好这个特性,只在系统中添加必要的组件,项目应用无须的一概去掉。WinCE系统中一般占用空间较大的有标准Shell(大概6M多)、字体(有大有小)、IE浏览器、.NET CF等。这些都是大户,需要重点关注。能不放在NK中,就绝不留下。尤其是字体,完全可以单独加载。最近改造了一下WinCE6.0下的触摸屏校准程序,实现了动态修改触摸屏校准程序的界面以支持多国语言提示。实验证明,字体确实没必要放在NK中,而且能节省好几M的内存。从这个角度实现时,需要考虑如何确定哪些组件可以不放在NK.bin中,而哪些是必须的。不放在NK.bin中的文件,以什么方式存入到设备上。另外一个考虑就是实现MULTIBIN了,将整个WinCE内核切割中几分,CE启动时只加载一个最小的NK.bin,更多的文件放在EXT.bin中。这个方法曾在WinCE5.0下用过,效果相当好。2410上20多M的操作系统,分割成的NK.bin大概1M多,从复位到启动完成,大概5s,并且节省了的宝贵内存,64M的物理内存,可供WinCE使用的有60M左右,省了20M左右的内存。这个方法显然能一举多得,但需要BOOTLOADER支持。目前采用的BOOTLOADER是不支持该方式的,而且要实现MULTIBIN就必须修改固化操作系统的方法。现在通过USB的方式直接固化BOOT和NK肯定行不通了,也许会增加生产的麻烦。总之,投入产出基本成正比,要在WinCE6.0下实现这个,估计有一定的工作量,但实现完了肯定会有彻底的改善。
在WinCE启动过程中,还有一个很重要的阶段就是加载驱动程序了。这个阶段在进入WinCE界面之前,往往也是比较费时间的。一般快的也要1~2S,慢的就不好说了。如果驱动的初始化代码中有很多延时或者读写硬件的操作,单线程方式加载驱动肯定会导致系统启动很慢。这个问题,已经有前人提供了解决方法,定制BusEnum,将单线程同步加载驱动的方式,改为异步加载并且提供了WinCE6.0下的示例代码BusEnum2。这个想法非常棒!我下载了他的示例代码,并编译到系统中,不过比较不幸,这代码只能在Debug模式下才能正常工作,在Release模式下总是会出现Data Abort,异步加载的驱动不能成功加载,很是诧异,目前还没找到原因,囧。实在不行,倒可以使用驱动调试助手的方法,自己单独写一个驱动来做这个事情。不过,解决问题最好还是能从根源着手,从根本上解决。问题不根治,只解决表象,总会有些隐患,心里也不踏实。有用过BusEnum2的同学,欢迎交流,希望能帮我解决这个疑惑。^_^
总的来说,提高WinCE的启动速度,差不多就这些方法,你如果有高招,也请不吝指教。以上都是理论分析,实际情况如何需要实验和事实来证明,后续将进一步跟进,有进展会贴出来跟大家分享。