帮同学宣传一下http://shop57644665.taobao.com/

该项目平台是TI的locosto,ARM7处理器,nor boot,128+32
DM技术方案提供商为bitfone公司。

在没有加入DM方案以前,系统的划分如下

name            origin    length
———————-  ——–  ———  ——–  —-  ——–
BOOT_MEM                00000000   00100000
D_MEM0                  00400000   00300000
P_MEM0                  06000000   00210000
P_MEM1                  06210000   001f0000
P_MEM2                  06400000   00100000
P_MEM3                  06500000   00180000
R_MEM                   06680000   00380000
FFS_MEM                 06a00000   00600000
S_MEM                   08000000   00037560
S_MEM_JPEG_JUMPTABLE    0804fb60   00000250
S_MEM_JUMPTABLE         0804fdb0   00000250
S_ROM                   08050000   00030000

根据FOTA的实现原理,我们需要划分出Bootloader部分,存放差分包和FOTA标志部分,最后修改后的系统情况如下:
name            origin    length
———————-  ——–  ———  ——–  —-  ——–
BOOT_MEM                00000000   00100000
D_MEM0                  00400000   00300000
P_DMBOOT                06000000   00020000
P_MEM0                  06020000   00210000
P_MEM1                  06230000   001d0000
P_MEM2                  06400000   00030000
P_MEM3                  06430000   00370000
P_DMBIN                 067a0000   00060000
R_MEM                   06800000   00200000
FFS_MEM                 06a00000   00600000
S_MEM                   08000000   00037560
S_MEM_JPEG_JUMPTABLE    0804fb60   00000250
S_MEM_JUMPTABLE         0804fdb0   00000250
S_ROM                   08050000   00030000
FOTA需要的空间是以前空余的代码段,文件系统部分是没有改变的。FOTA的标志部分因为空间原因放在差分包的最后一个block中。
#define DM_FLAG_ADDR        (0×067a0000+0×60000-5)

#define DM_NEED_UPDATE_FLAG     (DM_FLAG_ADDR)
#define DM_REPORT_FLAG     (DM_NEED_UPDATE_FLAG+1)
#define DM_SUCCESSED_FLAG     (DM_REPORT_FLAG+1)
#define DM_VALIDATION_PHASE_FLAG     (DM_SUCCESSED_FLAG+1)
#define DM_UPDATE_PHASE_FLAG     (DM_VALIDATION_PHASE_FLAG+1)

然后我们需要将系统boot时进入到我们的函数中。TI locosto系统的00地址是固化的一块ROM,里面的ARM异常处理部分是一个跳转,会跳转到我们的FLASH片选的地址06000000   。

注意要将ResetVector放到P_DMBOOT的开头。

Bootloader部分修改如下


.sect ".start"
;            .ref    _INT_Initialize

;_ResetVector:
;        B    _INT_Initialize

.ref    _INT_Bootloader_Start

_ResetVector:
B    _INT_Bootloader_Start

//_INT_Bootloader_Start是我们FOTA的入口函数,_INT_Initialize是系统正常启动的入口函数。

_INT_Bootloader_Start
;1. Configure DPLL register
;2. Configure CNTL_ARM_CLK register
;3.进行片选相应设置。
;4.切换到svc模式,设置相应的堆栈。
;5.    BL      _f_load_int_mem1             ; Download FLASH to Internal RAM
;进入FOTA的C函数
; application.

STMFD   sp!, {a1-a4,R12}
BL      _cmcc_dm_mpv
LDMFD   sp!, {a1-a4,R12}
;---add end

B       _INT_Initialize

//cmcc_dm_mpv函数如下:
void cmcc_dm_mpv (void)
{
unsigned char flag;
ser_initialize_serial_uart();//配置UART,我们通过uart来进行调试
ffs_driver_copy_to_ram();//该部分的实现参考TI本身已实现的代码,也就是将代码收到copy到一个数组中,然后使用函数指针方式进行调用。
ffs_init();//nor flash读写驱动部分,在ram中执行。
flag = uaw_get_need_update_flag();//是否需要FOTA的标志。
if(flag)
{
lcd_initialize_lcd_cam();//lcd初始化
dm_update();//更新函数
}
else
{
return;
}
}

//更新函数
void dm_update (void)
{
long i;
trace("start\n");
lcd_clear(0x00);
lcd_show_update_txt();
lcd_display();
uaw_set_report_flag(0x01);

if((i = ua_doUpdate(FALSE))==0x00)
{
trace("success");
uaw_set_need_update_flag(0x00);
uaw_set_successed_flag(0x01);
dm_resetflag=0x12345678;
/*reset*/
watch_dog_reset();
}
else
{
char msg[20]; U32_to_string(msg,i);
trace(msg);
trace("error");
}
}

ua_doUpdate是奔风提供的函数,里面就是具体的解析差分包进行升级流程的控制了,里面会调用我们必须完成的flash读写,lcd显示等函数,对于掉电现场恢复也是由它控制的。
对于奔风要求提供的heap,在FOTA进行时,除了bootloader和update agent所使用的,其余部分都是可以使用的,所以是完全够了的。

基本上一个FOTA的实现就是如此了。