| 帮同学宣传一下http://shop57644665.taobao.com/ |
| 帮同学宣传一下http://shop57644665.taobao.com/ |
作为一个平台的系统工程师,首先就是必须要熟悉自己所做的平台。对于编译器,链接器,程序执行的原理要有一定的了解。对于平台的MCU,系统的boot流程要熟悉,当然汇编代码一定要基本能读懂。
个人觉得FOTA最主要的核心就是FOTA程序的独立性,也就是说该部分程序要完全独立于其他部分。
如何检查FOTA部分代码没有调用到其他部分的代码呢?我们的编译和链接器所生成的符号表文件中就有这些信息。
在TI系统所生成的MAP符号表文件中,跨段调用的形式如下
06007830 00000010 (.T$0000)
FAR CALL TRAMPOLINES
callee addr tramp addr call addr call info
——– ——– ——– ——– ——— —————-
IND$CALL 08019fac .T$0000 06007830 06001b1a bootloader.lib : dm_drv.obj (.text)
通过查找对应的地址就能找到对应的函数。
注:在TI的编译和链接器是通过一个IND$CALL函数来“曲线”实现长跳转的,IND$CALL的实现是在编译和链接器中实现的。
MTK平台的ADS编译器是如下形式
$Ven$AT$L$$_fp_display 0×400049b8 ARM Code 0 anon$$obj.o(Veneer$$Code)
在你的FOTA部分应该只有一个类似的跳转,那就是从FOTA部分跳转到系统正常执行的入口函数。
FOTA程序注意不要使用实时运行库函数(RTS),也就是诸如memcpy的C库函数。另外要注意除法也是RTS函数。
FOTA需要的UART,LCD,FLASH驱动的实现难度不算很大,但是因为不能使用已存在的要被更新部分的函数,所以工作量还是有一点的。FLASH驱动需要放到RAM中执行,LCD在显示图片时最好直接将图片转换成LCD能够直接显示的格式然后送到LCD的buffer中就可以了。
因为FOTA的测试标准对升级时间也有要求,代码稳定调试完毕后可以考虑注释掉TRACE函数以缩短时间。
| 帮同学宣传一下http://shop57644665.taobao.com/ |
该项目平台是MTK6225,ARM7处理器,nor boot,128+32
DM技术方案提供商为Red Bend公司。
在加入DM方案以后,系统的划分如下
ROM1 0×00000000 0×00040000
ROM2 0×00040000 0×00d00000
ROM3 0×00d40000 0×000C0000
ROM1用来放FOTA更新程序和Red Bend 提供的lib部分。
ROM2为原来MTK程序,也是版本需要更新部分。
ROM3用来存放差分包,最后两个block一个用来做临时备份使用,一个用来做标志(安全但是浪费啊)。
注意:ARM的中断向量当然要放到ROM1中,*.obj的LEADING_PART部分也是需要的,否则可能无法boot。
片外RAM部分
FOTA部分将会使用很小的一部分,原来的MTK程序依次向后就可以了。FOTA部分程序当然会使用到MTK程序部分的内存,这个是因为FOTA需要很大的heap,并且这样做是没有问题的,因为MTK程序部分后面会再次初始化一次。
片内RAM部分
在这个项目的实现中,我将FLASH驱动代码放在了片内RAM中去执行。MTK程序依次向后就可以了。
进入FOTA的bootloader后,依然是先切换到svc模式,设置系统堆栈,设置EMI和DPLL.配置需要的GPIO,UART,手动将INTSRAM_CODE部分由FLASH copy到对应的RAM中,将FOTA必须的FLASH驱动copy到片内RAM中,禁掉watchdog timer,完成必须的lcd的初始化,然后
int i=0;
char *a=(char *)BACK_BLOCK_ADDR1;char *b=(char *)BACK_BLOCK_ADDR2;
char *backbuferr[2];
backbuferr[0]=a;backbuferr[1]=b;
i = RB_ImageUpdate((unsigned long int)UPDATE_ADDRESS_BEGIN,(unsigned long int)UPDATE_ADDRESS_END,(unsigned char*)FOTA_MEMORY_BEGIN,(unsigned long int)FOTA_MEMORY_SIZE,(unsigned char*)0,(unsigned long int)0,
(unsigned long int *)backbuferr,(unsigned long int)2,(unsigned long int)0);
if(i==S_RB_SUCCESS)
{
PW_Set_FOTA_Flag();
set_successed_flag();
clear_need_update_flag();
return;
}
Done.
Redbend提供给我们的RB_flash.c和RB_ImageUpdate.c是我们必须要完成接口函数,当我们将对应的驱动实现后,这些函数还是很容易完成的。
| 帮同学宣传一下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)
Read the rest of this post »
| 帮同学宣传一下http://shop57644665.taobao.com/ |
FOTA在中国移动终端管理中指的是将手机软件由旧版本升级到新版本的实现部分。其原理是首先根据特殊的算法将新旧版本之间的差别做成一个差分包,然后手机从网络上下载到手机中,然后重新启动。在手机重启时通过对应的算法读取差分包中的信息,然后通过直接擦写flash的方式完成版本的更新。
版本更新时运行的程序当然是放在bootloader 那部分的,这部分代码一般来说是不会被更新的,因为如果这部分flash在更新时被擦除,代码被擦除后就无法继续进行了。当然如果一定要对这部分进行更新,那么就必须将这部分代码放到ram中去执行。
Flash擦写是以block为单位的,这是flash的驱动决定的。FOTA更新和恢复现场需要对版本进行校验,是通过对每个flash block中数据的checksum来进行的,以此来决定该block是否已经进行了更新,以及整个版本是不是对应的版本。
更新的区域当然不能包括用户使用的区域,因为这里保存的用户个人的数据。
同时我们手机的flash除了版本外当然必须还有空余的空间用手存放升级的差分包,用于临时使用的备份的flash block,以及为掉电后恢复现场的标志。
只有完全明白FOTA的实现原理,系统工程师才能对系统部分进行重新划分,这其实也是实现FOTA的核心所在。
有无FOTA时对应flash的使用分布情况
Bootloader和Update Agent 部分主要的功能就是实现了通过对差分包信息的提取然后直接擦写flash来完成版本的更新。这里是FOTA的核心程序所在。这部分包括系统的bootloader,FOTA运行时所需要的FLASH,LCD,TRACE等驱动,FOTA运行控制的Update Agent部分。
更新时临时备份区域主要是用来备份flash block 上的数据的,以block为单位。具体需要的空间大小根据update agent需要分配。
标志区域主要是用来标识是否需要FOTA升级,是否升级成功。
关于RAM划分。在FOTA的过程中,除掉FOTA必须的RAM(FOTA部分的全局变量)其余部分都是可用的。也就是说FOTA可以复用版本所使用的RAM,因为FOTA是在bootloader部分,FOTA完成后的正常系统流程会再一次对全局变量进行清零等操作。
需要注意的地方:
Flash的擦写函数需要放到RAM中去执行,因为同一块bank不能同时读写。Flash的驱动是放在bootloader部分的,因为该段使用较小,不可能独占一个bank。
各个段的起始地址一定要以flash的block开始。
Bootloader部分注意不要调用标准的实时库函数,例如memcpy之类,类似copy这样的函数可以自己实现。实时库函数在升级过程中会被完全擦除掉。
Bootloader和Update Agent部分必须完全独立。检验方法一个是从生成的符号表文件中查看该区域是否有其他函数,另一个方法是将除该部分的代码外将其余部分全部擦除,然后开机看能否正常运行。
| 帮同学宣传一下http://shop57644665.taobao.com/ |
终端第一次开机,应将终端IMEI,厂商名称,终端型号,软件版本以短信方式上传到终端管理(DM)平台。终端发送短信的特服号码和端口号在DM 管理生命周期中不可变。终端第一次开机发送自注册信息后,转入手机正常开机后的空闲状态。
如果终端收到来自终端管理(DM)平台特服号码的短信,正确解析短信,从短信中得到成功的信息,则终端纪录此次注册成功的SIM 卡的IMSI 信息到终端某个预先确定的位置,(这个位置的数值应是终端自注册功能专用的标记位,终端其他部分不能修改此值。)以便终端可以在下次开机的时候检测此IMSI。
此后,每次终端重新启动,都应检测SIM 卡的IMSI 与保存在终端中的IMSI 是否一致,如果不一致,则终端应重新向平台侧发送自注册信息更新对应信息。
终端只向预制的DM 平台的短信特服号码和端口号发送信息,并只认为来自这个特服号码的短信是可以信任的DM 信息。终端自注册短信(上行)及DM 平台确认短信(下行)均为为带端口号的短信。
终端自注册时应判断SIM 卡是中国移动的SIM 卡,否则终端不发送任何信息。
终端网络参数配置应通过OMA DM 方式设置,平台侧使用get 命令将终端参数收集到平台侧后,平台侧经过分析和诊断,判断参数配置是否有误,及错误点,平台使用DM 的Replace 命令更新错误配置值。平台侧也可以不收集参数而直接使用Replace 命令更新参数设置。
DM 平台侧发起终端固件除错和功能升级更新操作,该操作使用标准的OMA FUMO 对象。为实现断点续传功能,推荐使用OMA DL 协议下载更新数据包,升级状态必须使用DM 方式报告给平台侧。
平台侧主动发起的固件升级FOTA基本流程如下:
a) 平台侧发起,通过短信提示用户现在有新版本的软件包, 询问用户是否下载升级;
b) 如下载应出现一个状态条, 提示用户下载进度状态;
c) 如果下载中断, 提示用户是否继续下载;
d) 下载完成后, 提示用户是否立即升级或稍后升级.;
e) 如果选择稍后升级,用户下次开机时终端自动升级;
f) 如果选择立即升级, 用户手机重启, 接着进行终端软件升级;
g) 升级,过程中显示升级进度状态条;
h) 升级成功后, 手机重新启动到正常开机状态;
i) 终端上报升级完成的信息;
新版本的软件包的下载必须支持断点续传,终端更新过程中掉电,再次开机,终端应返回断电前的更新现场,继续更新,直到更新完成。

















