参考网上的资料先学习了IAP实现的基本原理,结合自己板子的实际硬件资源,把芯片自带的512K内部Flash分为两部分,一部分为BootLoader实现IAP和应用程序的加载(跳转),另一部分是应用程序,升级的固件文件存放在外置的NandFlash系统中。为了把BootLoader做的更通用和漂亮一些,启用了RTX操作系统和Emwin,代码量大概在130K左右,因此,BootLoader放在了0~0x30000,应用放在了0x30000~0x80000。

芯片启动时首先运行BootLoader,BootLoader启动NandFlash文件系统,检查是否需要更新固件,NandFlash中放置了一个needup.bin文件,内容为空,只要存在needup.bin文件就说明需要升级,固件放在文件名为firmware.bin中。如果需要升级固件,启动固件升级进程,利用LPC1788的IAP功能,擦除扇区,将firmware.bin文件内容编程到0x30000开始的地方,然后跳转到0x8 0000运行APP。

如果不需要升级固件(没有needup.bin),则直接跳转到0x8 0000运行APP。

在跳转到0x8 0000开始运行APP前,首先判断一下0x80000处的数据(堆栈指针)是否在0x1000 0000~0x1000 FFFF,如果在范围里则为正确的APP,否则没有有效的APP,则不跳转到APP,直接进入到BootLoader程序。

为了防止在将固件文件写到内部Flash过程中出现问题,或固件本身就有问题,导致下载完成后不能正常运行,需要有一种直接进入BootLoader程序的方法,本系统有个按键,就设计为如果开机时按键被按下则直接进入到BootLoader而不加载APP应用,在BootLoader程序下启动USB、串口等进行固件的重新下载。

在实际编程的过程中出现了两个特殊的问题,经过努力查找问题最终得到了解决,下面将两个问题做个总结。

第一个问题是BootLoader程序调用LPC1788的IAP程序代码出现HardFault,在百度、Google各种查找,有一个人也出现类似的问题,但是并没有解决。最后不得已从main函数第一行开始防止IAP的测试代码,发现刚进main函数时调用IAP代码是不出错的,这就给我们一个启示,肯定是程序的某个地方触发了此问题。把IAP的测试代码往后放,放到while(1)前发现出现了HardFault,对这两个地方用仿真器进行跟踪,发现当代码停到两个调用代码前时,IAP所在(0x1FFF1FF0)的程序代码竟然不同。在后面停下时的代码明显的不对,好多mov r0, r0。为了找出来到底是哪句代码出了问题,从上到下一行一行的测试,最终找到了问题,原来在初始化EMC时修改了LPC_SC->MARB,是为了提高LCD占用总线的权限,设置LCD刷新拥有做高权限,数据访问次之,程序再次,其余最低。把这句话屏蔽后,采用缺省的总线仲裁设置后,能够正常的调用IAP。也许出现这种情况的可能性不高,但自己趟过的坑能告诉别人,让别人免走弯路也是一件好事。

第二个问题是从BootLoader跳转到APP时,APP并不能正常的运行。代码也是按照正常的跳转处理的,读取0x30000处的4个字节设置MSP(堆栈指针),将把0x30004的4个字节装入PC进行跳转,APP程序也正确设置了终端向量到0x30000。由于在BootLoader程序中看不到跳转后的源代码,但结合APP的map文件大致能知道程序运行到了哪个函数,用仿真器一直跟踪跳转后的汇编代码,发现程序也是最终停在了HardFault。用仿真器直接调试APP程序,要设置仿真器的初始化文件,如下图所示。其中runflash.ini文件内容如下:

SP = _RDWORD(0x00030000);           // Setup Stack PointerPC = _RDWORD(0x00030004);           // Setup Program Counter

其实就是设置仿真器进入调试状态是把MCU的SP和PC从哪里装载值,这个从BootLoader跳转的代码作用是一样的。进入调试状态,整个APP能够正常运行。这就说明我们在跳转到APP时,由于BootLoader本身已经设置了很多寄存器,导致APP的初始化过程和现有的寄存器设置有冲突。网上资料显示一定要关闭中断,在跳转前加了关全局中断的代码,不管用。又说要把RCC和NVIC复位,做了也不太管用。后来经过思考,最好的解决方法是BootLoader跳转到APP时把MCU做软复位,然后在执行尽量少的代码的情况下进行跳转,这样BootLoader的影响就很小,几乎等同于直接运行APP程序,能够尽早的把控制权交给APP程序。

软复位的代码还是比较好做的,如下:

__set_FAULTMASK(1);NVIC_SystemReset();while(1);

经测试也好用,现在的问题是等MCU重新启动后,如何判断是为了进APP的软重启还是用户断电后的硬启动,这个可以通过读取复位源标识寄存器(RSID—0x400F C180) 确定,如果此寄存器的第4位SYSRESET置位,说明处理器由于系统请求复位而被复位。但是在BootLoader的界面中也有一个复位按钮,也是通过这个方式重启的,这样就不能完全区分出来了。

为了解决这个问题,就在思考有哪些信息能够重启而不会丢失呢?写文件肯定是可以的,但为了让BootLoader尽快进入APP不能加载文件系统。写EEPROM肯定也是可以的,但是EEPROM被APP用了。还有个能用的就是RTC的通用寄存器,LPC1788有4个RTC通用寄存器(GPREG0~GPREG4–地址 0x4002 4044~0x4002 4054),这类寄存器可在主电源断开时保存重要的信息。芯片复位时,不会影响到这些寄存器中的值。而我们的APP正好也没有用到这四个寄存器,就选用其中的GPREG0保存重启的原因。

剩下的工作就简单了,需要跳转到APP时将GPREG0的值置为1,然后软重启。BootLoader程序在SystemInit函数(MCU启动后执行的第一段代码)中加入判断GPREG0的值的代码,如果GPREG0的值为0正常继续启动BootLoader,如果值为1直接跳转到APP。

经过测试发现此方法可行,能够很顺利的从BootLoader跳转到APP。

最终实现的效果可以参考下面的视频:

https://v.youku.com/v_show/id_XMzgxMzczNjk2NA==.html?spm=a2h3j.8428770.3416059.1

在实现过程中参考的资料如下:

NXP LPC1788(ARM Cortex m3) IAP 带UcosII 完结:

https://blog.csdn.net/kennann/article/details/45541511

关于ARM CM3的启动文件分析:

https://www.cnblogs.com/strongwong/p/8657639.html

STM32IAP升级-----编写IAP升级遇到的问题总结:

https://blog.csdn.net/super_demo/article/details/32086541

IAP与APP互相跳转的实现

https://blog.csdn.net/grublyboy/article/details/54909957

LPC1768更改IROM地址,用KEIL生成不了正常的.bin文件,而是生成奇怪的.bin文件夹

https://blog.csdn.net/robert_wzf/article/details/72968532

Keil5生成BIN文件及HEX文件介绍:

https://blog.csdn.net/langeldep/article/details/78202486

LPC1788 IAP的实现及遇见的问题相关推荐

  1. 现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现

    现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现 闲来无事,总结一下前段时间做过的U盘升级项目.一个新手的成长之路在于善于总结,生活也是一样扯远了,我准备了两个软件环境,一个带操作 ...

  2. LPC1788 U盘读写及IAP的实现 第一章

    前言 LPC1788 芯片内部自带硬件usb控制器,可实现usb的主机模式及设备模式,可以使用设备模式将lpc1788模拟成各种usb设备包括键盘.鼠标.U盘等.也可以设置为主机模式实现USB设备的操 ...

  3. 电子产品如何使用IAP方式升级程序

    目录 1.ICP.ISP和IAP的概念 2.IAP升级程序的原理 3.IAP升级程序的流程 4.IAR环境下IAP的实现 4.1.BootLoader程序设计 4.2.User Application ...

  4. 当莎士比亚遇见Google Flax:教你用​字符级语言模型和归递神经网络写“莎士比亚”式句子...

    作者 | Fabian Deuser 译者 | 天道酬勤 责编 | Carol 出品 | AI科技大本营(ID:rgznai100) 有些人生来伟大,有些人成就伟大,而另一些人则拥有伟大. -- 威廉 ...

  5. Nibiru Open Day,OZO 遇见 DigiArtist 国际数字艺术展

    ChinaJoy 首日,Nibiru 带着 OZO 在上海记录了一场有气质.有内涵的艺术展. 中国国际数码互动娱乐展览会(简称:ChinaJoy)于 27 日在上海隆重举办.NibiruOpen Da ...

  6. [转]ghost手动备份及遇见的问题

    昨天才发现在网上广为流传的ghost居然是赛门铁克开发的,百度百科资料介绍硬盘分区魔法大师也是出自之手,这家公司真是了得啊! ghost自动备份那个比较简单,手动备份的教程请参考:手动备份 GHOST ...

  7. 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!...

    为什么80%的码农都做不了架构师?>>>    Himi  原创, 欢迎转载,转载请在明显处注明! 谢谢. 原文地址:http://blog.csdn.net/xiaominghim ...

  8. 遇见你们,真好 ---致我的舍友

    浮生一梦,落地尘埃.遇见你们,是我最美丽的意外. 一年前,因命运的机缘巧合,我们组建了这个新的宿舍.一年间,和着四季的旋律,我们嬉闹着相伴走过.一年后,伴着毕业的节奏,我们也许四散天涯.今夜无眠,写下 ...

  9. iOS快速上手应用内购(IAP)附Demo

    前言:最近项目中接触到内购,本文主要介绍如何开发应用内购(In App Purchase),有一些是根据实际需求做的考虑,有不同的见解欢迎留言指教~本文demo:https://github.com/ ...

  10. 当Elasticsearch遇见Kafka

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由michelmu发表于云+社区专栏 Elasticsearch作为当前主流的全文检索引擎,除了强大的全文检索能力和高扩展性之外,对多种 ...

最新文章

  1. C#字符串与unicode互相转换
  2. linux qos 实现机制,linux的qos机制 - cgroup篇 (4)
  3. 【python】数据结构与算法—双端队列(二)
  4. Spring boot的Hello World入门
  5. VTK:Shaders之SpatterShader
  6. ibatis mysql分页查询语句_简单实现ibatis的物理分页
  7. 单片机小白学步系列(十四) 点亮第一个LED的程序分析
  8. 如何用golang获取linux上文件的访问/创建/修改时间
  9. 能ping通工作组计算机 无法访问,可以ping通不能访问共享,其他电脑可以访问
  10. php reactphp wss_Node和React中如何进行实时通信?
  11. java解三角函数方程_Java 中的三角函数
  12. 计算机文件夹里没有显示桌面,桌面没有图标显示的解决方法
  13. 程序员找工作-----人力资源面试题
  14. 创建android studio桌面图标
  15. Linux中的su 和su -
  16. Gay+Groupon=GayPon
  17. java游戏 暴雨梨花,《梦幻西游》新足迹暴雨梨花和踩浪花游戏效果
  18. Python操作MySQL分享
  19. php中使用视频流的方式播放视频。
  20. 横图图片广告代码html,横向不间断的连续滚动图片/文字广告

热门文章

  1. wget 命令的使用:HTTP文件下载、FTP文件下载
  2. 为什么我们需要PRINCE2认证——上海信息化培训中心
  3. python用于cad_python cad
  4. React 实现 PDF 文件在线预览 - 手把手教你写 React PDF 预览功能
  5. 软件开发生命周期 --瀑布模型
  6. 计算机无法进入pe系统,u盘启动盘无法进入pe解决方法
  7. 基于Python+Django的微博评论热点舆情分析可视化系统的设计与实现-计算机毕业设计选题题目推荐
  8. C语言编译.bat为 .exe
  9. 10. 机器人正运动学---姿态描述之欧拉角
  10. 重置计算机的本地策略,手把手教你win10系统本地组策略重置恢复默认的详细方案...