下面先介绍LPC1100处理器IAP的基础知识:
1. LPC1100处理器(LPC1114)Flash分配:LPC1114一共有32K Flash,共分为8个扇区,每个扇区的大小为4K,具体如下:
2.NXP的IAP命令都一样,一共有9条:
3.IAP命令是通过寄存器R0和R1进行参数传递的,R0传递参数,R1传递返回值:
IAP功能应用:
1.定义IAP程序的入口地址
代码:
#define IAP_ENTER_ADR 0x1FFF1FF1 /* IAP入口地址定义 */
2.定义参数
代码:
uint32 ParamIn[8]; /* IAP入口参数缓冲区 */
uint32 ParamOut[8]; /* IAP出口参数缓冲区 */
3.定义函数类型指针
代码:
void (*IAP_Entry)(uint32 *param_tab, uint32 *result_tab) =
(void(*)())IAP_ENTER_ADR; // 定义函数指针
4.注意事项:
①按照上面函数类型调用IAP函数即可,不过要注意函数的参数。
②由于在擦写操作期间,片上Flash存储器不可访问。IAP代码不能使用或禁止中断。
③Flash编程命令使用片上RAM顶端32字节,用户程序不能使用此空间。
IAP命令应用(代码来自周工):
1.准备写操作扇区
代码:
/*****************************************************************************
** Function name: SectorPrepare
** Descriptions: IAP操作扇区选择,命令代码50
** input parameters: sec1: 起始扇区
** sec2: 终止扇区
** output parameters: ParamOut[0]: IAP操作状态码,IAP返回值
** Returned value: ParamOut[0]: IAP操作状态码,IAP返回值
*******************************************************************************/
uint32 SectorPrepare(uint8 sec1, uint8 sec2)
{
ParamIn[0] = IAP_Prepare; /* 设置命令字 */
ParamIn[1] = sec1; /* 设置参数 */
ParamIn[2] = sec2;
(*IAP_Entry)(ParamIn, ParamOut); /* 调用IAP服务程序 */
return (ParamOut[0]); /* 返回状态码 */
}
2.将RAM 内容复制到Flash
代码:
/*******************************************************************************
** Function name: RamToFlash
** Descriptions: 复制RAM的数据到FLASH,命令代码51
** input parameters: dst: 目标地址,即FLASH起始地址。以512字节为分界
** src: 源地址,即RAM地址。地址必须字对齐
** no: 复制字节个数,为512/1024/4096/8192
** output parameters: ParamOut[0]: IAP操作状态码,IAP返回值
** Returned value: ParamOut[0]: IAP操作状态码,IAP返回值
********************************************************************************/
uint32 RamToFlash(uint32 dst, uint32 src, uint32 no)
{
ParamIn[0] = IAP_RAMTOFLASH; /* 设置命令字 */
ParamIn[1] = dst; /* 设置参数 */
ParamIn[2] = src;
ParamIn[3] = no;
ParamIn[4] = IAP_FCCLK;
(*IAP_Entry)(ParamIn, ParamOut); /* 调用IAP服务程序 */
return (ParamOut[0]); /* 返回状态码 */
}
3.擦除扇区
代码:
/*******************************************************************************
** Function name: SectorErase
** Descriptions: 扇区擦除,命令代码52
** input parameters: sec1 起始扇区
** sec2 终止扇区92
** output parameters: ParamOut[0]: IAP操作状态码,IAP返回值
** Returned value: ParamOut[0]: IAP操作状态码,IAP返回值
********************************************************************************/
uint32 SectorErase(uint8 sec1, uint8 sec2)
{
ParamIn[0] = IAP_ERASESECTOR; /* 设置命令字 */
ParamIn[1] = sec1; /* 设置参数 */
ParamIn[2] = sec2;
ParamIn[3] = IAP_FCCLK;
(*IAP_Entry)(ParamIn, ParamOut); /* 调用IAP服务程序 */
return (ParamOut[0]); /* 返回状态码 */
}
4.扇区查空
代码:
/**********************************************************************************
** Function name: BlankChk
** Descriptions: 扇区查空,命令代码53
** input parameters: sec1: 起始扇区
** sec2: 终止扇区92
** output parameters: ParamOut[0]: IAP操作状态码,IAP返回值
** Returned value: ParamOut[0]: IAP操作状态码,IAP返回值
**********************************************************************************/
uint32 BlankChk(uint8 sec1, uint8 sec2)
{
ParamIn[0] = IAP_BLANKCHK; /* 设置命令字 */
ParamIn[1] = sec1; /* 设置参数 */
ParamIn[2] = sec2;
(*IAP_Entry)(ParamIn, ParamOut); /* 调用IAP服务程序 */
return (ParamOut[0]); /* 返回状态码 */
}
5.比较<地址1><地址2><字节数>
代码:
/*******************************************************************************
** Function name: DataCompare
** Descriptions: 校验数据,命令代码56
** input parameters: dst: 目标地址,即RAM/FLASH起始地址。地址必须字对齐
** src: 源地址,即FLASH/RAM地址。地址必须字对齐
** no: 复制字节个数,必须能被4整除
** output parameters: ParamOut[0]: IAP操作状态码,IAP返回值
** Returned value: ParamOut[0]: IAP操作状态码,IAP返回值
********************************************************************************/
uint32 DataCompare(uint32 dst, uint32 src, uint32 no)
{
ParamIn[0] = IAP_COMPARE; /* 设置命令字 */
ParamIn[1] = dst; /* 设置参数 */
ParamIn[2] = src;
ParamIn[3] = no;
(*IAP_Entry)(ParamIn, ParamOut); /* 调用IAP服务程序 */
return (ParamOut[0]); /* 返回状态码 */
}
有上面的几个函数后,下面就可以根据需要编写SD卡升级函数了:
1.定义用户程序地址
代码:
#define APP_CODE_START_ADDR 0x00006000 // 用户程序起始地址
2.从SD卡中读写bin文件更新升级
从SD卡中升级程序很简单,从SD卡中打开升级文件,每次读取512自己,然后写入Flash,直到编写完成。
代码:
/**********************************************************************************
* FunctionName : UCSDCardProgram()
* Description : 从SD卡编程
* EntryParameter : fileName - 应用程序在SD卡中的名字, buf - 缓冲
* ReturnValue : None
*********************************************************************************/
uint8 UCSDCardProgram(uint8 *fileName, uint8 *buf)
{
uint32 addr = 0;
FATFS fs; /*Work area (file system object) for logical drive*/
FIL file; /*file objects*/
UINT br; /*File R/W count*/
FRESULT res;
DisableIRQ(); // 禁止中断
SectorPrepare(6, 6); // 选择扇区
SectorErase(6, 6); // 擦除扇区
EnableIRQ(); // 使能中断
/*Register a work area for logical drive 0*/
f_mount(0, &fs);
/*Create file*/
res = f_open(&file, (const TCHAR *)fileName, FA_OPEN_EXISTING|FA_READ);
if(res != FR_OK)
{
return res;
}
else
{
while (1)
{
res = f_read(&file, buf, 512, &br); // 读取数据
DisableIRQ();
SectorPrepare(6, 6);
RamToFlash(APP_CODE_START_ADDR + addr, (uint32)buf, 512); // 写数据到FLASH
EnableIRQ();
addr += 512;
if ((res != FR_OK) || (br < 512))
{
break;
}
}
}
/*Close all files*/
f_close(&file); // 关闭文件,必须和f_open函数成对出现
/*Unregister a work area before discard it*/
f_mount(0, 0);
return FR_OK;
}
3.主函数:
主函数实现按键扫描,如果有按键,进行SD卡升级,如果没有按键直接跳转到应用程序
代码:
/**********************************************************************************
* FunctionName : main()
* Description : 主函数
* EntryParameter : None
* ReturnValue : None
*********************************************************************************/
int main(void)
{
void (*userProgram)() = (void (*)())OSInit; // 函数指针
OSInit(); // 初始化系统
while (1)
{
if (KeyGetValue())
{
UCSDCardProgram(\"LPC1114.bin\", SDBuf);
}
userProgram = (void (*)())(APP_CODE_START_ADDR + 1);
(*userProgram)(); // 启动程序
}
}
到此IAP程序完成了,下面就是编写应用程序了。。。。。。。。。。。。。。。。。。。。。。
应用程序编写:
应用程序编写没有什么特殊的,只是需要注意几个地方的设置
1.设置编译地址:
2.编译设置
3.生存bin文件
4.编写应用程序,并把bin文件存放SD卡中,运行IAP升级程序。
上一篇:STM32F105 USB管脚Vbus的处理
下一篇:LPC11U14实现SD卡U盘
推荐阅读最新更新时间:2024-03-16 15:00