为了确保应用程序的在线更新,片外RAM和Flash除了满足应用程序的正常使用外,还必须满足应用程序更新时临时备份代码的需求。
3 应用程序IAP实现方案
如图2所示,需要更新的应用程序代码通过GPRS/CDMA无线网络接口或本地维护接口下载到RAM的程序代码缓存区中。经过校验检查正确后,导入到外部Flash的应用程序代码区。导入成功后,设置相关标志,再通过LPC2214的IAP接口功能函数,将应用程序代码保存到CPU内部Flash中。
由于应用程序运行在CPU内部的高速Flash上,因此产品正常运行过程中无法完成内部Flash中代码的更新。为了解决上述问题,采用“应用boot:”的方式加以实现。将内部Flash分为2个区域:应用boot和应用程序代码区。应用boot为一个简单的应用程序,实现从外部Flash导入应用程序代码以及向应用程序代码区入口跳转的功能。应用boot存放在CPU内部Flash的开始部分,一旦写入后不再修改。产品上电或复位后,CPU的PC指针首先指向应用boot的入口,应用boot开始执行。一旦检测到外部Flash中有完整的用户代码需要更新,则通过LPC2214的IAP接口将应用程序代码导入到内部Flash的应用程序代码区,并跳转到应用程序代码的入口处执行新的应用程序;如果没有应用程序需要更新,boot程序会直接跳转到当前应用程序代码的入口处执行。
在整个应用程序在线升级过程中,应用程序代码正常写入片外Flash之前都不影响产品的正常运行。正确写入片外Flash后,应用程序自动复位,然后启动应用boot,通过应用boot将新的应用程序写入内部Flash。经测试,该过程可以在10 s内完成,完全满足用户的使用要求。
4 应用boot设计
应用boot是应用代码更新的关键,它不但解决了在线升级的问题,而且提供了一种异常防护机制。即使在内部Flash的应用程序代码区写入失败的情况下,由于boot可以正常运行,仍然可以通过boot程序的功能重新更新应用程序。boot程序基本功能包括:内部Flash更新、向应用程序跳转以及本地下载更新应用程序。为保证该软件的可靠性,同时考虑硬件配置情况,采用μC/OS-II嵌入式操作系统。通过对该操作系统的合理裁剪和软件优化,可以将boot程序代码控制在12 KB以内,从而为应用程序代码提供了足够的片内Flash存储空间。
当boot程序从内部Flash中读取指令执行时,不能擦除该Flash。为解决该问题,boot程序执行时首先将boot程序代码复制到RAM中,然后跳转到RAM中执行,这样就可以对内部Flash的应用程序代码区进行修改操作。boot程序的启动部分非常重要,会直接影响整个系统的运行情况。启动代码首先初始化CPU总线控制器;然后初始化RAM和外部Flash片选,将boot程序代码复制到RAM中并在RAM中执行;最后初始化堆栈和基本系统后进入主程序入口。
boot程序的IAP实现,主要包括两个接口函数:CPU内部Flash扇区的擦除和写入。对于擦除操作,按照IAP提供的操作方式即可实现,注意发送完擦除指令后需要一段时间的延时,并借助指令检查擦除是否成功。对于写入操作,需要根据IAP操作的相关要求,将数据首先复制到CPU的内部RAM中;然后通过相应的IAP写入命令将其写入到内部Flash中;写入操作完成后,需要进行一定的延时并检查写入是否成功。为了保证上述操作过程的完整性,对于μC/OS-II操作系统,需要借助OS_ENTER_CRITICAL函数进行必要的保护。