新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > LPC1768 IAP升级解析及例程分享

LPC1768 IAP升级解析及例程分享

作者:时间:2016-11-21来源:网络收藏
1、IAP介绍

IAP即“inapplicatinprogramming”在应用编程的缩写,指MCU可以在系统中获取新代码并对自己重新编程,即改变应用程序。它与我们所熟悉的ISP编程不同, LPC1768 的ISP编程接口为串口1,如果使用其他的串口或其他总线则不能对其进行编程。而我们这里所说的IAP通过下载一段引导程序Bootloader程序,如果我们想要从串口2或网口更新应用程序,在Bootloader中初始化相应的串口或网口,使其接收应用程序,将接收到的应用程序写入到Flash里面,IAP完成后跳转到应用程序入口执行应用程序。所以现在的IAP程序涉及到两个概念:Bootloader和应用程序。

本文引用地址:http://www.eepw.com.cn/article/201611/319433.htm

Bootloader:BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。这里我们所说的Bootloader也是系统开机前的一段小程序,其主要任务是用来初始化串口和IAP端口(网口CAN接口等)的,通过判断状态是否需要从IAP端口进行更新应用程序,若需要更新则从端口接收应用程序,并存放到指定的Flash里面,更新完成后则跳入到指定的Flash里面执行应用程序。

应用程序:即我们需要开发板实现功能的程序,其中应用程序主要分为两种:hex文件和bin文件。在我们经常使用的KEIL中默认编译生成的可执行文件(应用程序)为hex格式的,若需要编译生成bin格式需要做如下修改,加入“D:KeilARMARMCCbinfromelf.exe--bin--output./Obj/Can_Updata.bin./Obj/test.axf”,重新编译生成的Can_Updata.bin文件存放在Obj文件夹下。


2、bin格式文件与hex格式文件的区别

bin格式文件是纯粹的二进制文件,使用下载其将其下载到开发板时其内容完全不变,所以对于IAP下载使用bin格式文件是比较方便的,如下图是bin文件的内容与写入到开发板后使用仿真器观察到Flash存放的内容(这段程序当然是可以执行的)。

Hex格式文件:Hex全称(IntelHEX)文件是由一行行符合IntelHEX文件格式的文本所构成的ASCII文本文件。在IntelHEX文件中,每一行包含一个HEX记录。这些记录由对应机器语言码和/或常量数据的十六进制编码数字组成。如下图是hex文件的部分数据,其组成由“:CCAAAARR...ZZ”,CC=10代表长度为16字节,AAAA=0000本条记录中的数据在存储区中的起始地址,RR=00,数据区,ZZ=38为校验,这里就不做仔细说明了。

3、LPC1768IAP原理

LPC1768复位后开始执行Boot代码,Boot代码可以执行ISP程序或用户的应用代码。发生硬件复位后,P2.10引脚为低电平,这就被当作启动ISP命令处理器的外部硬件请求。假定在/RESET引脚上出现上升沿时,电源引脚出现正确的信号,那么在采样P2.10之前有3ms的时间决定是执行用户代码还是ISP处理程序。如果P2.10为低电平且看门狗溢出标志置位,那么忽略启动ISP命令处理器的外部硬件请求。在没有ISP命令处理器的请求(硬件复位后P2.10引脚为高电平)时,将搜索有效的用户程序。若发现有效的用户程序,执行控制权就被转移给用户程序。若没有找到有效的用户程序,就将调用自动波特率程序。这里不讨论ISP下载及命令,有兴趣的朋友可以查看LPC1768技术手册第三十二章ISP命令。

在IAP升级中,程序正常执行即用户代码(这里的用户代码是我们所说的IAP引导程序),如下是IAP升级流程图,程序将预留端口(这里提供有串口和CAN总线接口两种)接收到的APP程序bin文件,将接收到的数据写入到指定的Flash区域(例程APP地址为0x00010000),程序通过IAP命令将数据写入到Flash里面,LPC1768提供了一系列IAP命令对片内Flash进行擦除编写等。

4、IAP命令

LPC1768通过IAP函数对片内Flash进行操作,IAP函数是固化在0x1FFF1FF1处的一个有传入参数和返回参数的一个函数,在LPC1768技术手册第三十二章IAP命令中有有详细的说明。主要提供有如下命令:准备下操作扇区、将RAM内容复制到Flash、清除扇区、扇区查空、读器件ID、读boot版本、比较、重新调用ISP等。

�体; ����Sx�S��的外部硬件请求。假定在/RESET引脚上出现上升沿时,电源引脚出现正确的信号,那么在采样P2.10之前有3ms的时间决定是执行用户代码还是ISP处理程序。如果P2.10为低电平且看门狗溢出标志置位,那么忽略启动ISP命令处理器的外部硬件请求。在没有ISP命令处理器的请求(硬件复位后P2.10引脚为高电平)时,将搜索有效的用户程序。若发现有效的用户程序,执行控制权就被转移给用户程序。若没有找到有效的用户程序,就将调用自动波特率程序。这里不讨论ISP下载及命令,有兴趣的朋友可以查看LPC1768技术手册第三十二章ISP命令。

5、串口IAP升级

本例程是根据官方提供的串口IAP更新图片进行修改而来,直接使用官方的IAP.c文件,该文件中提供了如上图IAP命令的各种函数,其具体参数可以参考IAP命令。根据官方例程里面将bmp图片经过串口采用Xmodem1K协议发送到开发板存放在地址0x00010000,如下图是LPC1768Flash分配地址,第16~21扇区为应用程序存放空间。这里我们将要传送的bmp图片改为传输应用程序bin文件

�体;q�kr�Sx�S255,255,255); mso-shading:rgb(255,255,255); " >扇区查空、读器件ID、读boot版本、比较、重新调用ISP等。

�体; ����Sx�S��的外部硬件请求。假定在/RESET引脚上出现上升沿时,电源引脚出现正确的信号,那么在采样P2.10之前有3ms的时间决定是执行用户代码还是ISP处理程序。如果P2.10为低电平且看门狗溢出标志置位,那么忽略启动ISP命令处理器的外部硬件请求。在没有ISP命令处理器的请求(硬件复位后P2.10引脚为高电平)时,将搜索有效的用户程序。若发现有效的用户程序,执行控制权就被转移给用户程序。若没有找到有效的用户程序,就将调用自动波特率程序。这里不讨论ISP下载及命令,有兴趣的朋友可以查看LPC1768技术手册第三十二章ISP命令。

在IAP升级中,程序正常执行即用户代码(这里的用户代码是我们所说的IAP引导程序),如下是IAP升级流程图,程序将预留端口(这里提供有串口和CAN总线接口两种)接收到的APP程序bin文件,将接收到的数据写入到指定的Flash区域(例程APP地址为0x00010000),程序通过IAP命令将数据写入到Flash里面,LPC1768提供了一系列IAP命令对片内Flash进行擦除编写等。在IAP升级中,程序正常执行即用户代码(这里的用户代码是我们所说的IAP引导程序),如下是IAP升级流程图,程序将预留端口(这里提供有串口和CAN总线接口两种)接收到的APP程序bin文件,将接收到的数据写入到指定的Flash区域(例程APP地址为0x00010000),程序通过IAP命令将数据写入到Flash里面,LPC1768提供了一系列IAP命令对片内Flash进行擦除编写等。

5、串口IAP程序分析

例程通过按键对开发板进行控制,INT0键擦除Flash,确认键等待串口IAP,向上键显示菜单,向下键执行应用程序,使用LCD来开发板状态,其主函数如下

intmain(void)

{

uint32_tints[4];

SystemClockUpdate();

LCD_BSP_Init(); //LCD初始化

LCD_Clear(Black);

LCD_SetBackColor(Black);

LCD_SetTextColor(White);

cmd=MENU; //命令状态初始化,显示菜单

while(1)

{

switch(cmd)

{

caseREADY:

if (!(LPC_GPIO2->FIOPIN&(1<<10)))

{

Screen_Fresh("ErasingImages...");

cmd=ERASE_FLASH;

}

elseif(!(LPC_GPIO1->FIOPIN&(1<<29)))

{

cmd=MENU;

}

elseif(!(LPC_GPIO1->FIOPIN&(1<<25)))

{

Screen_Fresh("WaitingforXMODEMXfer...");

cmd=FLASH_IMG;

}

elseif(!(LPC_GPIO1->FIOPIN&(1<<26)))

{

Screen_Fresh("Executeprogram");

cmd=SHOW;

}

break;

caseMENU:

if(u32IAP_ReadBootVersion(&ints[0],&ints[1])==IAP_STA_CMD_SUCCESS)

{

snprintf((char*)string[0],MAX_STRING_SIZE,"BootCodeversion%d.%d",ints[0],ints[1]);

}

if(u32IAP_ReadPartID(&ints[0])==IAP_STA_CMD_SUCCESS)

{

snprintf((char*)string[1],MAX_STRING_SIZE,"PartID:%d(%#x)",ints[0],ints[0]);

}

u32IAP_ReadSerialNumber(&ints[0],&ints[1],&ints[2],&ints[3]);

snprintf((char*)string[2],MAX_STRING_SIZE,"Serial#:X:X:X:X",ints[0],ints[1],ints[2],ints[3]);

Screen_Fresh("Menu");

cmd=READY;

break;

caseERASE_FLASH:

if((u32IAP_PrepareSectors(16,20)==IAP_STA_CMD_SUCCESS)&&

(u32IAP_EraseSectors(16,20)==IAP_STA_CMD_SUCCESS))

Screen_Fresh("EraseDone");

else

Screen_Fresh("EraseFAIL");

cmd=READY;

break;

caseFLASH_IMG:

received_data=0;

vXmodem1k_Client(&load_image);

Screen_Fresh("UpdataComplete");

cmd=READY;

break;

caseSHOW:

Boot();

cmd=READY;

break;

}

}

}

当串口接收到数据后将数据写入到Flash,其写入步骤是:发送准备写扇区命令,执行RAM内容复制到Flash最后比较复制内容,其代码如下:

staticuint32_tload_image(uint8_t*data,uint16_tlength)

{

if(length>0){

if(u32IAP_PrepareSectors(16,20)==IAP_STA_CMD_SUCCESS)

{

if(u32IAP_CopyRAMToFlash(IMG_START_SECTOR+received_data,(uint32_t)data,length)==IAP_STA_CMD_SUCCESS)

{

if(u32IAP_Compare(IMG_START_SECTOR+received_data,(uint32_t)data,length,0)==IAP_STA_CMD_SUCCESS)

{

received_data+=length;

return1;

}

}

}

Screen_Fresh("FAIL(RESET&ERASEIMAGE)");

return0;

}

else

return0;

}

当程序全部写入到Flash后,按下向下按键,跳转到应用程序,首先修改中断向量表然后进入应用程序

voidBoot(void)

{

SCB->VTOR=IMG_START_SECTOR&0x1FFFFF80; //修改中断向量表

JMP_Boot(IMG_START_SECTOR);

}

堆栈地址更新,PC地址更新

__asmvoidJMP_Boot(uint32_taddress){

LDRSP,[R0] ;堆栈地址更新

LDRPC,[R0,#4] ;进入应用程序

}

7、操作步骤及实验现象

1、下载“宝马开发板串口IAP升级”例程,插上USB转串口线,打开超级终端,复位开发板。

2、按下按键INT0按键--擦除扇区

3、按下方向键确认键--等待从串口接收程序

4、串口打印‘C’字符等待接收数据

5、串口发送文件,选择“1K Xmodem”协议,选择要下载的应用程序bin文件,这里使用DAC例程作为测试。

6、发送文件

7、按下方向键向下键开始执行应用程序,可以用示波器测试P0.26输出正弦波信号

bin文件生成方法及设置:

打开要更新应用程序工程,这里使用“IAP升级DAC转换”程序,设置ROM空间地址(程序下载到Flash的地址),这里也是我们应用程序的入口地址0x10000

打开User选项,利用Keil自带的fromelf.exe生成bin文件,bin文件保存在Obj文件夹中,如下图添加“D:KeilARMARMCCbinfromelf.exe--bin--output./Obj/app.bin./Obj/app.axf”,输入文件为app.axf,所以工程编译生成输出文件名设置为app,命令执行生成app.bin文件

打开Asm选项,定义“NO_CRP”,我们可以打开启动文件,当定义了“NO_CRP”后,那么我们后面的代码也就不起作用了,所以在需要加密的时候前面就一定不能再定义了代码读保护,也就是加密的关键字,经过加密后芯片再也无法擦除,由于我们这里程序需要使用到IAP升级,因此添加此定义

8、CAN总线

CAN是ControllerAreaNetwork的缩写(以下称为CAN),是ISO国际标准化的串行通信协议。在汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。CAN属于现场总线的范畴,它是一种有效支持分布式控制或实时控制的串行通信网络。较之许多RS-485基于R线构建的分布式控制系统而言,基于CAN总线的分布式控制系统在以下方面具有明显的优越性:

1)网络各节点之间的数据通信实时性强

2)缩短了开发周期

3)已形成国际标准的现场总线

4)最有前途的现场总线之一

9、CANIAP升级

关于LPC1768CAN总线介绍可以参考“宝马开发板基础例程文档”第十九章“CAN总线”,这里就不在赘述了,CANIAP例程使用两块宝马开发板进行实验,分为“CANIAP编程板”与“CANIAP接收板”,将编程板(ID=0x01)与接收板(ID=0x02)的CAN1进行连接(CAN1L对CAN1L,CAN1H对CAN1H),波特率为500K,编程板通过读取板上SD卡内的app.bin文件然后传输给接收板,每次传送1024字节,然后等待接收板发送“CONTINUE”信号继续发送下一个1K数据,直到发送完成,发送“UPDATAOK”通知接收板发送完成。其操作步骤与串口IAP类似,只是将通信方式有串口改为CAN总线,有兴趣的朋友可以修改成其他方式进行IAP下载。




关键词: LPC1768IAP升级解

评论


技术专区

关闭