void *fun() —— 声明一个返回值是任意类型的指针的函数fun()
void (*)() —— 这是一种变量类型,用来定义函数指针变量
IAP (In Application Programming)即在线应用编程,用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信接口对产品中的固件进行更新升级。
一般做法:
在设计固件程序时编写两个项目代码,一个不执行正常的功能操作,只是通过某种通信方式(如USB、USART)接收程序或数据,执行对第二部分代码的更新,称作Boot loader程序;第二个才是真正的功能代码,称作APP程序。
两部分代码都同时烧录在USer Flash中,芯片上电后从Boot loader程序开始运行,其功能主要是:
- 检查是否需要对APP程序进行更新
- 如果不需要则执行APP程序的代码
- 需要则执行更新操作
- 跳转到APP程序代码进行执行
Boot loader程序需通过JTAG或ISP烧入,APP程序则使用Boot loader中的IAP功能烧入或者和Boot loader代码一起烧入
一般从最低地址区开始存放Boot loader,紧跟着就是APP程序。
APP程序起始地址设置方法
在Options for Target中设置IROM1的起始地址,起始地址之前的空间留给Boot loader,起始地址之后的空间则留给Flash APP使用。
APP程序起始地址的要求:
保证偏移量为0x200的倍数;
IROM1的地址区域和IRAM1的地址区域不能重叠;
LPC11Uxx系列IAP介绍
Boot loader大小为16KB,起始地址为0x1FFF0000,复位后,驻留在片内Flash存储器引导模块中的中断向量也将变为有效,即引导模块底部的512个字节也将出现在起始地址为0x00000000的存储器区域中。
LPC11Uxx通过USB连接被PC枚举成MSC设备时,其闪存空间表示为主机文件系统中的驱动器,映射在主机文件夹中默认名称为firmware.bin的文件中,用户可通过复制新的firmware.bin文件实现闪存代码更新。
IAP 例程应该通过寄存器r0的字指针来调用,其指向包含命令代码和参数的内存(RAM)。
IAP 定义和调用方法
IAP程序是Thumb代码,驻留在地址0x1FFF1FF0处,定义
#define IAP_LOCATION 0x1fff1ff1UL
定义IAP函数的数据架构或指针来传递IAP命令表和结果表
unsigned long command[5];
unsigned long result[4];
定义函数类型的指针,它有两个参数并返回void,IAP返回的结果带有驻留在R1中的表的基址
#define IAP_EXECUTE_CMD(a, b) ((void (*)())(IAP_ROM_LOCATION))(a, b)
或者
typedef void (*IAP)(unsigned int [],unsigned int[]);
IAP iap_entry;
iap_entry=(IAP)IAP_LOCATION;
------将IAP_ROM_LOCATION这个地址转化为返回void的函数指针,这个函数接收连个参数,并把这个函数定义为IAP_EXECUTE_CMD(a,b)
调用IAP,可使用以下方法
iap_entry(command,result);
或者
IAP_EXECUTE(command,result);
R0用来存放命令代码和参数,命令结果返回在R1寄存器中
IAP中相关操作举例分析(命令代码由用户事先定义好值)
1、IAP_PrepareSectors(准备写操作扇区)
三个参数(依次存放进Command数组中)
- 命令代码IAP_CMD_PREPARE_SECTORS,50
- 起始扇区号,参数传递
- 结束扇区号,参数传递
返回状态Result[0]
- CMD_SUCCESS
- BUSY
- INVALID_SECTOR
该命令必须在执行“将RAM 内容复制到Flash”或“擦除扇区”命令之前执行
2、IAP_CopyRAMToFlash(将RAM内容复制到Flash)
5个参数
- 命令代码51
- DST:要写入数据字节的目标Flash地址,应当为256字节边界
- SRC:从中读取数据字节的源RAM地址,字边界
- 写入的字节数,256/512/1024/4096
- CCLK系统时钟频率,KHZ
返回码
- CMD_SUCCESS |
SRC_ADDR_ERROR (地址不以字为边界) |
DST_ADDR_ERROR (地址不在正确的边界) |
SRC_ADDR_NOT_MAPPED |
DST_ADDR_NOT_MAPPED |
COUNT_ERROR (字节数不是256 | 512 | 1024 | 4096) |
SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION |
BUSY
同理,相关的操作还有擦除扇区、空白检查扇区、读取器件ID、读Boot代码版本、重调用ISP、读UID、EEPROM读写等