关于程序固件的远程升级

在嵌入式设备的使用过程中,我们常常需要更新程序的代码的版本,但在设备运行过程中,主控板往往被装在了设备外壳里面,每次烧写难免要进行设备的拆装,一般的好拆装的设备还好,但遇到一些需要做防水屏蔽的比较难拆装的设备,每次烧写拆设备会比较费事费时,浪费人力物力,基于这一现实问题,想到了是否可以通过网络(tcp\udp)的方式,将固件传输到下位机,接到nandflash或者norflash接口上,进行固件的烧写,免去每次拆装设备的麻烦。
思路:将待更新的固件(.bin,.ais,16进制文件,我所使用的是aisgen_d800k008软件进行文件转换(omap-l138开发包中可找到),也用过c6678平台上的一个文件转换工具)通过网络下发到下位机,下位机通过移植后的烧写例程将固件烧写到flash的定义好的内存地址上,完成固件的更新。

(一)UDP网络的固件升级
UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,UDP作为一种无连接的不可靠的信息传输协议,在发送时不保证数据的接收方一定收到所传输的数据,所以,为了保证烧写的文件传输不出错,需要将UDP网络加上握手、确认、校验机制,与上位机拟定通信协议,将UDP网络做成TCP,然后进行文件传输。需要注意的是,udp在进行数据传输时,单包数据的建议大小为1460个字节,当时在进行设计时没有注意到这个问题,导致网络频繁丢包,甚至网络直接挂掉的情况。将文件分包后,需要进行封装,在单个分包数据前加上报头,字节长度,包序号,接收端收到报头,做单包校验,统计收到的包数,并且注意包序号是否累加,在各种校验满足的情况下,将数据存放在烧写的地址入口上进行烧写。
(二)TCP网络的固件升级
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。可实现在不可靠的互联网络上提供可靠的端到端字节流传输,相较于UDP网络,tcp底层能够实现三次握手,数据校验,和ACK确认机制,实现起来更加方便,但要注意以下几个问题:
1.数据传输的快慢对文件的传输和网络的稳定性有影响:
在我做基于tcp的网络固件升级时发现当客户端(文件发送端)发送文件过快时,会导致我网络堵塞,网络会断开,用Wireshark抓包,tcp window full和tcp ZeroWindowProbe的报文出现在所抓的包中如下图所示:网络传输过快导致的tcp网络缓冲池满了,数据放不进去,而客户端一直在发送数据,网络拥塞
tcp window ful和tcp ZeroWindowProbe报文的出现,说明tcp的网络缓冲池被塞满,而客户端还在连续不断的向服务端传输数据导致网络拥塞,我在测试时发现网络直接堵死了,为了解决这个问题,我修改了工程的cfg文件(工程跑的sys/bios系统)中NDK_Core_Stack------>Transport Layer---->TCP module setting设置中的Default TCP recive buffer size,和Default TCP send buffer size,如下图所示:
在这里插入图片描述
通过增大网络buffer的size来解决了 tcp window ful和tcp ZeroWindowProbe的问题。
2.数据传输时一直出现tcp 重传现象,然后网络数据出现错误:
在测试初期,我认为tcp底层有数据包的ACK确认机制,接收端收到以后会回传ack报文,那我就不需要额外增加代码进行数据接收的确认,但后面发现,仅仅依靠tcp底层的确认机制还不够,ack确认机制“不靠谱”(可能能力有限没用好哈哈哈哈,手动狗头),所以手动的增加代码,在收到一包数据之后,给上位机回传一个约定的报文,然后再进行下一包的发送,完美解决上述问题。
3.MMU的地址映射问题:
MMU是Memory Management Unit的缩写,中文名是内存管理单元,有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU)。它是一种负责处理中央处理器(CPU)的内存访问请求的计算机硬件。它的功能包括虚拟地址到物理地址的转换(即虚拟内存管理)、内存保护、中央处理器高速缓存的控制,在较为简单的计算机体系结构中,负责总线的仲裁以及存储体切换(bank switching,尤其是在8位的系统上)。在对OMAP-L138_FlashAndBootUtils_2_40例程进行移植和调试时(该demo原本运行在CCS3.3上)发现对于该例程需要访问的EMIF寄存器地址(0x68000000),我的工程代码中,并没有定义该地址段,导致我访问该地址失败,进而出现Device-ID获取失败,烧写失败,为了解决这个问题,我在cfg文件中进行MMU的虚拟地址映射,将该段地址进行MMU管理,代码如下:在这里插入图片描述

在这里插入图片描述
对地址端段进行映射 解决了这个问题。
以上就是个人关于固件远程更新设计的问题记录,以备后续遇到相同问题可以加以解决,由于能力有限,有表述错误的望多多包容,刚入门小白,勿喷!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值