招标厂商海尔机的升级区代码结构比较清楚,从flash 400到1FFFF。装载到内存的5CF400处运行。
清楚地分为两部分,一部分是starter,代码空间5CF400~5CFFFF。对应到Flash的400~0FFF
另一部分是downloader,代码空间从5D0000~5EF000。对应到Flash的1000~1FFFF。
这两部分的命名纯粹个人理解,不一定符合原厂定义。以下涉及地址部分均是代码运行时地址,对应到flash必须减去5CF400再加400。
卓异系列的对升级代码作了较多改变,首先为了适应更多硬件,加了许多硬件驱动代码在里面,内部有若干个表结构来查找并驱动各硬件组合。详情可见op2010大侠的贴。
另外也许是驱动代码太多,为了节约空间,starter和downloader合并在一起,代码空间通通到5D0000里。所以卓异的升级代码运行时地址到flash地址需要减5D0000再加400。
starter的作用是各区块的crc校验,与升级条件检测,流程基本是固定的。手动升级通过定时中端,监控面板按键。如果有按键组合则进入升级程序。
按键组合在flash的820~82F处定义[color=darkred][6/8更正][/color],另外还有监控面板按键程序也和硬件相关。其余部分几个招标厂家的代码是一致的。即便加上卓异系列的,starter的升级流程部分也是一样的。
招标海尔的5D0000开始的downloader,是标准的Keil C编写的代码。包括以后的应用程序区,也是标准的Keil C编写。byzx早就分析出许多Keil C编写的uc OS的代码入口。
应用程序区和dowloader区看起来像两个没有关联的工程,dowloader区有的Keil C库。应用程序区还会有自己独立的一份。
所以使用卓异的升级区代码组合招标的应用程序,并不能享受到卓异升级区的各硬件驱动代码。但是可以利用卓异的升级代码配合适当的key和硬件标示信息修改,空中升级到想要的招标应用程序。至于这个应用程序能不能用于山鸡,这要看造化了。
Keil C库的汇编代码比较难理解的。Keil C的startup代码,俺没做接触过嵌入式系统开发,但俺估计初入行的初级程序员也不会了解startup的过程。海尔的bin就是一个活得教科书。
以最早流传的招标海尔的downloader为例,说明一下Keil C的startup过程。俺也是初学乍练,不对之处请斧正。
startup过程主要在两个文件中定义。这两个文件都在Keil的lib目录中。也可复制到源代码工程中,进行定制。具体见Keil手册。
startup.a51
init.a51
Keil C先执行startup.a51,执行cpu初始化,内存初始化,堆栈初始化。然后跳转到init.a51,执行watchdog初始化、全局变量初始化。最后跳转到main函数。
L5D0ACF~L5D0AFC startup.a51代码。
L5D0AFC~L5D0BB2 init.a51代码。初始化全局变量代码比较难懂,看了老半天,后来发现init.a51有注释。
STARTUP过程的几个重要标号地址如下:
?C_STARTUP L5D0000 ;STARTUP.A51代码入口。即Download入口
?STARTUP1 L5D0ACF ;STARTUP.A51中初始化cpu和stack等。因Download区在进入前已经初始化cpu和内存控制器,所以此处无初始化cpu代码和内存控制器。
?C_START L5D0B27 ;INIT.A51代码入口。
MAIN L5DAD79 ;main函数。即初始化后的downloader主代码入口
?C_INITSEG L5D0C4C ;全局变量的segment。
在L5D0ACF~L5D0AFC区域内, 有这样两条神秘代码:
MOV 3A, #00
MOV 3B, #00
对比startup.a51源码,可发现是这两条语句:
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
这里XBPSTACKTOP等于0。那么?C_XBP和XBPSTACKTOP是什么意思呢?这里就有一个Keil C的模拟栈的概念。
因为51机的堆栈比较小,而且访问堆栈效率也不高。而某些情况下,又需要额外的堆栈。所以Keil C自己维护了一个堆栈空间和系统的堆栈区别开来。
?C_XBP就是Keil C自己维护的模拟堆栈空间的指针。XBPSTACKTOP则是模拟堆栈空间的顶部地址,从高往低处长,XBPSTACKTOP - 1溢出后就是FFFF。
?C_XBP还有两个内部库函数操作,?C?XBPADD, ?C?XBPOFF。分别用于入栈时的指针操作和堆栈访问。
downloader区不使用模拟栈,应用程序区使用模拟栈。uc OS在创建Task时使用模拟栈保护Task数据。
附件是整理的Keil C运行库的说明。俺中文打字太慢,所以作了一些蹩脚的英文注释。[color=orangered]奇怪,昨天上传的附件怎么没有了,重传了一下。cd51.lib更贴近实际使用的库。[/color]
另,升级中使用的SHA1签名算法入口:
L5DB8BC
用C表示的函数原形是:
char GetSHA1(long[5] sha1Value, long addressSourceData, long length);
//sha1Value, output buffer the SHA1 Value
//addressSourceData, the address of Source Data. [color=orangered]6/8修改,这个地方用地址值描述更准确一些。[/color]
//length, the bytes count of source data.
对算法有兴趣研究,建议不要看这里的代码,实在是又臭又长。
[color=darkred]原cd51_lib.xls有一个重大错误。请看cd51_lib-0609.xls。[/color]