由于工作需要,用到ARM7的芯片LPC2132的IAP,初次接触ARM7,历时2天时间,终于成功完成BootLoader的编写,下面和大家分享一下使用心得,方便大家的使用。
要完成BootLoader,首先得实现IAP。
LPC21XX的IAP使用比较简单,芯片手册上有具体介绍,我就不多说了。主要用到以下几个函数。
以下是一些定义:
#define IAP_ENTER_ADR
0x7FFFFFF1
// IAP入口地址定义
/*
*
定义IAP命令字
*/
#define IAP_Prepare
50
#define IAP_RAMTOFLASH
51
#define IAP_ERASESECTOR
52
#define IAP_BLANKCHK
53
#define IAP_READPARTID
54
#define IAP_BOOTCODEID
55
#define IAP_COMPARE
56
/*
*
定义IAP返回状态字
*/
#define CMD_SUCCESS
0
#define INVALID_COMMAND
1
#define SRC_ADDR_ERROR
2
#define DST_ADDR_ERROR
3
#define SRC_ADDR_NOT_MAPPED
4
#define DST_ADDR_NOT_MAPPED
5
#define COUNT_ERROR
6
#define INVALID_SECTOR
7
#define SECTOR_NOT_BLANK
8
#defineSECTOR_NOT_PREPARED_FOR_WRITE_OPERATION
9
#define COMPARE_ERROR
10
#define BUSY
11
/*
*
定义CCLK值大小,单位为KHz
*/
#define IAP_FCCLK
(60000)
/* 此频率值必须同主频相同 */
#define EEPROM_STARTSEC
4
#define EEPROM_ENDSEC
8
#define EE_SUUCEESS
0
#define IAP_ERROR
1
#define PARA_BANK_ERROR
2
#define PARA_SRCADDR_ERROR
3
#define PARA_OVERFLOW_ERROR
4
//IAP写入字节数
typedef enum
{
MODE0 = 256,
MODE1 = 512,
MODE2= 1024,
MODE3 = 4096,
}IAPWRITEMODE;
//IAP擦除的扇区
typedef enum
{
SECTOR0,
SECTOR1,
SECTOR2,
SECTOR3,
SECTOR4,
SECTOR5,
SECTOR6,
SECTOR7,
SECTOR8,
}IAPCHANNEL;
IAP函数实现:
/*
*
定义函数指针
*/
void (*IAP_Entry) (unsigned longulParam_tab[], unsigned long ulPesult_tab[]) = (void(*)())IAP_ENTER_ADR;
unsigned long
GulParamin[8]; /* IAP入口参数缓冲区 */
unsigned long
GulParamout[8];
/*
IAP出口参数缓冲区 */
/*********************************************************************************************************
** Function name:
sectorPrepare
** Descriptions:
IAP操作扇区选择,命令代码50
** input parameters:
ucSec1:
起始扇区
**
ucSec2:
终止扇区
** output parameters:
GulParamout[0]:
IAP操作状态码,IAP返回值
** Returned value:
GulParamout[0]:
IAP操作状态码,IAP返回值
*********************************************************************************************************/
unsigned long
sectorPrepare (unsigned char
ucSec1, unsigned char
ucSec2)
{
GulParamin[0] = IAP_Prepare; /* 设置命令字 */
GulParamin[1] = ucSec1; /* 设置参数 */
GulParamin[2] = ucSec2;
(*IAP_Entry)(GulParamin, GulParamout); /* 调用IAP服务程序 */
return (GulParamout[0]); /* 返回状态码 */
}
/*********************************************************************************************************
** Function name:
ramCopy
** Descriptions:
复制RAM的数据到FLASH,命令代码51
** input parameters:
ulDst:
目标地址,即FLASH起始地址。以512字节为分界
**
ulSrc:
源地址,即RAM地址。地址必须字对齐
**
ulNo:
复制字节个数,为512/1024/4096/8192
** output parameters:
GulParamout[0]:
IAP操作状态码,IAP返回值
** Returned value:
GulParamout[0]:
IAP操作状态码,IAP返回值
*********************************************************************************************************/
unsigned long
ramCopy (unsigned long
ulDst, unsigned long
ulSrc, unsigned long
ulNo)
{
GulParamin[0] = IAP_RAMTOFLASH; /* 设置命令字 */
GulParamin[1] = ulDst; /* 设置参数 */
GulParamin[2] = ulSrc;
GulParamin[3] = ulNo;
GulParamin[4] = IAP_FCCLK;
(*IAP_Entry)(GulParamin, GulParamout); /* 调用IAP服务程序 */
return (GulParamout[0]); /* 返回状态码 */
}
/*********************************************************************************************************
** Function name:
sectorErase
** Descriptions:
扇区擦除,命令代码52
** input parameters:
ucSec1
起始扇区
**
ucSec2
终止扇区92
** output parameters:
GulParamout[0]:
IAP操作状态码,IAP返回值
** Returned value:
GulParamout[0]:
IAP操作状态码,IAP返回值
*********************************************************************************************************/
unsigned long
sectorErase (unsigned char ucSec1, unsignedchar
ucSec2)
{
GulParamin[0] = IAP_ERASESECTOR; /* 设置命令字 */
GulParamin[1] = ucSec1; /* 设置参数 */
GulParamin[2] = ucSec2;
GulParamin[3] = IAP_FCCLK;
(*IAP_Entry)(GulParamin, GulParamout); /* 调用IAP服务程序 */
return (GulParamout[0]); /* 返回状态码 */
} |