LPC1100處理器SD卡升級應(yīng)用程序
下面先介紹LPC1100處理器IAP的基礎(chǔ)知識:
本文引用地址:http://www.ex-cimer.com/article/201611/317393.htm1. LPC1100處理器(LPC1114)Flash分配:LPC1114一共有32K Flash,共分為8個扇區(qū),每個扇區(qū)的大小為4K,具體如下:
2.NXP的IAP命令都一樣,一共有9條:
3.IAP命令是通過寄存器R0和R1進行參數(shù)傳遞的,R0傳遞參數(shù),R1傳遞返回值:
IAP功能應(yīng)用:
1.定義IAP程序的入口地址
代碼:
#define IAP_ENTER_ADR 0x1FFF1FF1 /* IAP入口地址定義 */
2.定義參數(shù)
代碼:
uint32 ParamIn[8]; /* IAP入口參數(shù)緩沖區(qū) */
uint32 ParamOut[8];/* IAP出口參數(shù)緩沖區(qū) */
3.定義函數(shù)類型指針
代碼:
void (*IAP_Entry)(uint32 *param_tab, uint32 *result_tab) =
(void(*)())IAP_ENTER_ADR; // 定義函數(shù)指針
4.注意事項:
①按照上面函數(shù)類型調(diào)用IAP函數(shù)即可,不過要注意函數(shù)的參數(shù)。
②由于在擦寫操作期間,片上Flash存儲器不可訪問。IAP代碼不能使用或禁止中斷。
③Flash編程命令使用片上RAM頂端32字節(jié),用戶程序不能使用此空間。
IAP命令應(yīng)用(代碼來自周工):
1.準備寫操作扇區(qū)
代碼:
/*****************************************************************************
** Function name: SectorPrepare
** Descriptions: IAP操作扇區(qū)選擇,命令代碼50
** input parameters: sec1: 起始扇區(qū)
** sec2: 終止扇區(qū)
** output parameters: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
** Returned value: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
*******************************************************************************/
uint32 SectorPrepare(uint8 sec1, uint8 sec2)
{
ParamIn[0] = IAP_Prepare;/* 設(shè)置命令字 */
ParamIn[1] = sec1; /* 設(shè)置參數(shù)*/
ParamIn[2] = sec2;
(*IAP_Entry)(ParamIn, ParamOut);/* 調(diào)用IAP服務(wù)程序 */
return (ParamOut[0]); /* 返回狀態(tài)碼*/
}
2.將RAM 內(nèi)容復(fù)制到Flash
代碼:
/*******************************************************************************
** Function name: RamToFlash
** Descriptions: 復(fù)制RAM的數(shù)據(jù)到FLASH,命令代碼51
** input parameters: dst: 目標地址,即FLASH起始地址。以512字節(jié)為分界
** src: 源地址,即RAM地址。地址必須字對齊
** no: 復(fù)制字節(jié)個數(shù),為512/1024/4096/8192
** output parameters: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
** Returned value: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
********************************************************************************/
uint32 RamToFlash(uint32 dst, uint32 src, uint32 no)
{
ParamIn[0] = IAP_RAMTOFLASH; /* 設(shè)置命令字 */
ParamIn[1] = dst;/* 設(shè)置參數(shù) */
ParamIn[2] = src;
ParamIn[3] = no;
ParamIn[4] = IAP_FCCLK;
(*IAP_Entry)(ParamIn, ParamOut); /* 調(diào)用IAP服務(wù)程序*/
return (ParamOut[0]); /* 返回狀態(tài)碼*/
}
3.擦除扇區(qū)
代碼:
/*******************************************************************************
** Function name: SectorErase
** Descriptions: 扇區(qū)擦除,命令代碼52
** input parameters: sec1 起始扇區(qū)
** sec2 終止扇區(qū)92
** output parameters: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
** Returned value: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
********************************************************************************/
uint32 SectorErase(uint8 sec1, uint8 sec2)
{
ParamIn[0] = IAP_ERASESECTOR; /* 設(shè)置命令字 */
ParamIn[1] = sec1; /* 設(shè)置參數(shù) */
ParamIn[2] = sec2;
ParamIn[3] = IAP_FCCLK;
(*IAP_Entry)(ParamIn, ParamOut);/* 調(diào)用IAP服務(wù)程序 */
return (ParamOut[0]); /* 返回狀態(tài)碼 */
}
4.扇區(qū)查空
代碼:
/**********************************************************************************
** Function name: BlankChk
** Descriptions: 扇區(qū)查空,命令代碼53
** input parameters: sec1: 起始扇區(qū)
** sec2: 終止扇區(qū)92
** output parameters: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
** Returned value: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
**********************************************************************************/
uint32 BlankChk(uint8 sec1, uint8 sec2)
{
ParamIn[0] = IAP_BLANKCHK; /* 設(shè)置命令字 */
ParamIn[1] = sec1;/* 設(shè)置參數(shù) */
ParamIn[2] = sec2;
(*IAP_Entry)(ParamIn, ParamOut);/* 調(diào)用IAP服務(wù)程序 */
return (ParamOut[0]);/* 返回狀態(tài)碼*/
}
5.比較<地址1><地址2><字節(jié)數(shù)>
代碼:
/*******************************************************************************
** Function name: DataCompare
** Descriptions: 校驗數(shù)據(jù),命令代碼56
** input parameters: dst: 目標地址,即RAM/FLASH起始地址。地址必須字對齊
** src: 源地址,即FLASH/RAM地址。地址必須字對齊
** no: 復(fù)制字節(jié)個數(shù),必須能被4整除
** output parameters: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
** Returned value: ParamOut[0]: IAP操作狀態(tài)碼,IAP返回值
********************************************************************************/
uint32 DataCompare(uint32 dst, uint32 src, uint32 no)
{
ParamIn[0] = IAP_COMPARE; /* 設(shè)置命令字 */
ParamIn[1] = dst; /* 設(shè)置參數(shù) */
ParamIn[2] = src;
ParamIn[3] = no;
(*IAP_Entry)(ParamIn, ParamOut); /* 調(diào)用IAP服務(wù)程序 */
return (ParamOut[0]); /* 返回狀態(tài)碼 */
}
有上面的幾個函數(shù)后,下面就可以根據(jù)需要編寫SD卡升級函數(shù)了:
1.定義用戶程序地址
代碼:
#define APP_CODE_START_ADDR 0x00006000 // 用戶程序起始地址
2.從SD卡中讀寫bin文件更新升級
從SD卡中升級程序很簡單,從SD卡中打開升級文件,每次讀取512自己,然后寫入Flash,直到編寫完成。
代碼:
/**********************************************************************************
* FunctionName : UCSDCardProgram()
* Description : 從SD卡編程
* EntryParameter : fileName - 應(yīng)用程序在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); // 選擇扇區(qū)
SectorErase(6, 6); // 擦除扇區(qū)
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); // 讀取數(shù)據(jù)
DisableIRQ();
SectorPrepare(6, 6);
RamToFlash(APP_CODE_START_ADDR + addr, (uint32)buf, 512); // 寫數(shù)據(jù)到FLASH
EnableIRQ();
addr += 512;
if ((res != FR_OK) || (br < 512))
{
break;
}
}
}
/*Close all files*/
f_close(&file); // 關(guān)閉文件,必須和f_open函數(shù)成對出現(xiàn)
/*Unregister a work area before discard it*/
f_mount(0, 0);
return FR_OK;
}
3.主函數(shù):
主函數(shù)實現(xiàn)按鍵掃描,如果有按鍵,進行SD卡升級,如果沒有按鍵直接跳轉(zhuǎn)到應(yīng)用程序
代碼:
/**********************************************************************************
* FunctionName : main()
* Description : 主函數(shù)
* EntryParameter : None
* ReturnValue : None
*********************************************************************************/
int main(void)
{
void (*userProgram)() = (void (*)())OSInit; // 函數(shù)指針
OSInit(); // 初始化系統(tǒng)
while (1)
{
if (KeyGetValue())
{
UCSDCardProgram("LPC1114.bin", SDBuf);
}
userProgram = (void (*)())(APP_CODE_START_ADDR + 1);
(*userProgram)(); // 啟動程序
}
}
到此IAP程序完成了,下面就是編寫應(yīng)用程序了。。。。。。。。。。。。。。。。。。。。。。
應(yīng)用程序編寫:
應(yīng)用程序編寫沒有什么特殊的,只是需要注意幾個地方的設(shè)置
1.設(shè)置編譯地址:
2.編譯設(shè)置
3.生存bin文件
4.編寫應(yīng)用程序,并把bin文件存放SD卡中,運行IAP升級程序。
評論