rabbit 在线升级

 首先loader把DLM程序搬移到ram中,然后跳转到DLM_WEB,DLM_WEB负责接受image程序到serial flash。

第一步骤:image moto sflash。

但是为什么要把sflash进行分区呢?为什么要做文件系统呢?

flash先要擦除4k,然后再写,擦除的起始地址只能是4k的整数倍。

在跳转之前要copy跳转代码到ram的顶部,原因是:当切换MBXCR时,xpc不会改变,这样xpc:pc指针执行的下一条指令不是预期的jp 0指令,而是映射后的一段未知指令。

 

当upload时,超过0x3000的长度就会发生异常

找到原因了,之所以超过3000就异常中断,是因为越界。原因就是我判断upload,还是download的依据库中的state,但是这个state是被库改变的。所以当借宿的时候这个state会变成0,就会进入download分之,写g_commbuf,当超过0x3000时就会越界。

总结:
尽量不要使用由引用传给库的变量,很有可能会被库更改。造成意想不到的结果。所以变量要在用户程序的掌控之中。

程序切换核心:

 

完成切换的代码段如下:
     ld a, 0xC5
     ld (MB3CRShadow), a
     ld (MB2CRShadow), a
     ld (MB1CRShadow), a
     ld (MB0CRShadow), a
     ioi ld (MB3CR),a
     ioi ld (MB2CR),a
     ioi ld (MB1CR),a
     ioi ld (MB0CR),a                                    (1)
     ld a, DATASEGVAL                                     (2)
     sub 0x80
     ioi ld (DATASEG), a
     ld    (DATASEGVAL), a
     ioi ld a, (STACKSEG)
     sub 0x80
     ioi ld (STACKSEG), a
     call MainLoop
如前所述,MB0CR指向了程序的代码空间,为了使程序能够在RAM运行,必须使MB0CR指向RAM。在执行完语句(1)之后,运行空间就指向了RAM,同时高低512KB重合在一起了,对地址0x80000-0xFFFFF的访问等同于对0x0-0x7FFFF的访问。由于切换前后pc不变,因此程序继续从语句(2)开始运行。
代码空间已经切换过来了,但是要想使程序继续运行,仅有代码是不够的。因此,接下来就是如何继续使用原先位于RAM中的数据和堆栈空间。

BOOTROM*.map文件可以看出,它的数据段(包括堆栈)是在RAM空间中,也就是地址大于0x80000的空间中,因此,DATASEGSTACKSEG都在0x80以上。当切换到RAM中运行时,代码和数据同时位于RAM中,因此段寄存器存在一个0x80的差值。

如果仅仅是使BOOTROM切换到RAM中运行,段寄存器可以不作任何处理,因为高低512KB空间是重合的。但是,由于我们需要将高512KB的地址空间映射到FLASH,以便对其进行读写,因此,必须将有关的段寄存器进行调整,也就是减去0x80,使其能够继续访问原来的数据和堆栈空间。

当然,从相应的*.map文件可以看出,512KBSRAM只使用了一半!而BOOTROM通常小于256KB。那么,可以用MB0CR指向BOOTROM,而利用MB2CR访问RAM;剩余的MB1CRMB3CR不是提供一个完整512KB的空间吗?这样不就可以实现对512KB FLASH的访问了吗?

答案是:不可以!

原因在于,假定可以访问512KB FLASH,那么MB1CR=MB3CR=0xC3,也就是说,0x40000-0x7FFFF0xC0000-0xFFFFF指向了第二块512KBFLASH。同时,假定MB1CR对应于低256KBMB3CR对应高256KB

当需要访问FLASH当中高低256KB空间时,比如偏移量为0x20的内容时,也就是地址为0x400200xC0020 的内容,我们来看看实际上发生了什么。

第一个访问的空间所使用的物理地址是0x40020,此时RABBITCS2选中第二块FLASH,同时地址线上送出0100,0000,0000,0010,0000,由于FLASH512KBFLASH只使用低19条地址线。同样的,第二个访问的空间所使用的物理地址是0xC0020Rabbit使用CS2选中第二块FLASH,同时地址线上送出1100,0000,0000,0010,0000,同样的,FLASH只使用低19条地址线,最高地址位被忽略了。可见,两个地址空间的访问实际上都是FLASH当中的同一位置。

为了能够访问完整的512KB空间,地址位A18必须可以从0变到1,而使用MB1CRMB3CR都无法使地址位A180变到1。因此,用这种方法不能进行第二块FLASH512KB寻址。

 

 

 

BOOTROM MB0CR MB1CR 映射到了 FLASH 空间( 0 0x7FFFF ),而系统软件中的 MB0CR MB1CR 映射到 RAM 空间( 0 0x7FFFF 。要想实现BOOTROM向系统软件的切换,实际上就是改变MB0CR的映射空间,使其从FLASH指向RAM。
可事实证明:简单的地址切换是不能实现程序切换的。
经过分析,找到了失败的原因:Rabbit内部使用16位逻辑地址, 因此其程序指针 pc 也是 16 位的。当修改MB0CR的映射关系时,pc并不随着改变, 于是 Rabbit 将从切换后的地址空间中的 pc 处继续执行,可是新的地址空间的pc处不一定是一条完整和有效的Rabbit指令,因此会出错。同时,因为pc不是0,因此切换以后,程序也没有从头运行。程序切换的过程见下图。

1       修改后的方法是这样的:BOOTROM进行切换之前,首先将一段执行切换的代码拷贝到RAM当中(0x80000起始的某一个位置),然后使BOOTROM“跳转到”(而不是切换!)相应的RAM地址执行,在这里实现MB0CR的切换。由于MB0CR的切换前后都是发生在RAM当中,结合Dynamic C的特点,程序可以继续在RAM当中运行,此时可以执行“跳转到0地址”使系统程序从RAM的0地址开始执行,从而实现从BOOTROM到系统软件的切换。

你可能感兴趣的:(rabbit 在线升级)