平台:MT2503A
待实现功能:Fota
现象描述:
通过网络(wifi/lan)接收fota的分包并存储进文件系统,接收完毕进入bootloader升级后总是不能正常升级,将收到记录的Fota文件通过工具读出并和原始文件做对比发现许多地方不相同,开始怀疑是接收是出错,利用debug打印出每一包的校验信息发现并没有出错,继续向上查看处理接收fota封包的函数(拆包后,存储前),在存储前做二次校验,发现也没有错误。由此可以断定错误应该出在存储过程中。
处理需要写入的数据步骤:
1. fs_seek()
2. fs_write()
3.fs_fflush()
先将代码贴上,大家试试看能不能找到错误的地方:
/* MT2503 SDK中自带函数 */
int FS_Seek(FS_HANDLE FileHandle, int Offset, int Whence)
{
if (Whence != FS_FILE_BEGIN &&
Whence != FS_FILE_CURRENT &&
Whence != FS_FILE_END)
{
return FS_PARAM_ERROR;
}
return fs_bl_seek(FileHandle, Offset, Whence);
}
/* 同事重新封装一次的代码 */
void fota_file_seek(FS_HANDLE handle, hal_uint16 position)
{
FS_Seek(handle, position, FS_FILE_BEGIN);
}
void fota_file_writr(FS_HANDLE handle, kal_char *data, kal_uint16 total_len)
{
........
write_ret = FS_Write(handle, (kal_uint8 *)(data + len), total_len - len, &size);
FS_Commit(handle);
........
}
void fota_handle_firmware_package(kal_char *firm_data, kal_uint16 package_id, kal_uint16 package_len)
{
........
fota_file_seek(fota_context.kedas_firmware, (package_id-1)*FIRM_WARE_PACKAGE_SIZE);
fota_file_write(fota_context.kedas_firmware, firm_data, package_len);
........
}
第一次检查代码时还没有发现错误,所以又去查看一次文件比对,发现错误总在文件64kB的地方之后开始出现,隐约觉得是不是MT2503的SDK限制写入文件大小,遂打电话给供应商的FAE询问,文件系统有没有限制大小,FAE回答绝不可能出现只能写了64KB。一般来说只要不超过剩余flash大小的上限是都可以写入的。
所以我再次去查看代码,发现了一个很费解的错误,同事将fs_seek()函数重新打包了一下,SDK中的fs_seek()需要传入三个参数分别是:fs_handle(相当于文件描述符),int型的offset(偏移位置,请注意是int型,2^31寻址范围),int型的whence(表明从头,从尾查找),同事二次封装的fota_file_seek(FS_HANDLE handle, hal_uint16 position) 函数只有两个参数,相比他是想省一个函数并且让只在fota的功能中使用,但是注意这个position参数是 hal_uint16 类型(2^16寻址范围,刚好64KB啊,o(╥﹏╥)o,原来是你啊),恍然大悟。。。,将参数修改为int,再次测试一遍升级流程,接收文件没有错误,写入正确,升级成功。
最后,总结一下关于这次debug得出的编程经验:
1. 如果SDK中没有必要二次封装的函数就不要封装了(就是这种你只能省下一个参数,没有特殊的数据处理),老老实实调用就好,
2. 对于系统函数,该传什么类型参数就传什么。
再留一点地方,有时间把寻址范围推到一下。嘿嘿嘿。