|
最近在做一個(gè)LPC1778的遠(yuǎn)程燒寫(xiě),應(yīng)用到了IAP編程,所以分享一下。
單片機(jī)源程序如下:
- #include "IAP.h"
- /*********************************************************************************************************
- 宏定義
- *********************************************************************************************************/
-
- #define IAP_ENTER_ADR 0x1FFF1FF1 /* IAP入口地址定義 */
- #if defined ( __CC_ARM )
- __align(4) INT8U GucIapTmp[1024]; /* 定義4K空間,編程Flash時(shí)使用 */
- #elif defined ( __ICCARM__ )
- #pragma pack(push)
- #pragma pack(4)
- INT8U GucIapTmp[1024];
- #pragma pack(pop)
- #endif
- /*
- * 定義CCLK值大小,單位為KHz
- */
- #define IAP_FCCLK (96000)
- #define IAP_ENTER_ADR 0x1FFF1FF1 /* IAP入口地址定義 */
- /*
- * 定義函數(shù)指針
- */
- void (*IAP_Entry) (INT32U param_tab[], INT32U result_tab[]);
- INT32U paramin[8]; /* IAP入口參數(shù)緩沖區(qū) */
- INT32U paramout[8];
- #define UARTBPS 9600 /* 串口通信波特率 */
- volatile INT8U GucRcvOver; /* 接收完成標(biāo)志 1:表示完成 */
- volatile INT32U GulRcvCount; /* 接收字節(jié)數(shù) */
- INT32U *GpulFlagPoint = (INT32U *)UserFlag; /* 用戶(hù)程序標(biāo)志指針 */
- INT32U *pSECTORADDL1 = (INT32U *)SECTORADDL1; /* 用戶(hù)程序標(biāo)志指針 */
- INT32U *pSECTORADDL2 = (INT32U *)SECTORADDL2; /* 用戶(hù)程序標(biāo)志指針 */
- INT32U *pSECTORADDL3 = (INT32U *)SECTORADDL3; /* 用戶(hù)程序標(biāo)志指針 */
- INT32U *pSECTORADDH1 = (INT32U *)SECTORADDH1; /* 用戶(hù)程序標(biāo)志指針 */
- INT32U *pSECTORADDH2 = (INT32U *)SECTORADDH2; /* 用戶(hù)程序標(biāo)志指針 */
- INT32U *pSECTORADDH3 = (INT32U *)SECTORADDH3; /* 用戶(hù)程序標(biāo)志指針 */
- /* IAP出口參數(shù)緩沖區(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返回值
- *********************************************************************************************************/
- INT32U sectorPrepare (INT8U sec1, INT8U 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)碼 */
- }
- /*********************************************************************************************************
- ** Function name: ramCopy
- ** Descriptions: 復(fù)制RAM的數(shù)據(jù)到FLASH,命令代碼51
- ** input parameters: dst: 目標(biāo)地址,即FLASH起始地址。以512字節(jié)為分界
- ** src: 源地址,即RAM地址。地址必須字對(duì)齊
- ** no: 復(fù)制字節(jié)個(gè)數(shù),為512/1024/4096/8192
- ** output parameters: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- ** Returned value: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- *********************************************************************************************************/
- INT32U ramToFlash (INT32U dst, INT32U src, INT32U 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)碼 */
- }
- /*********************************************************************************************************
- ** 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返回值
- *********************************************************************************************************/
- INT32U sectorErase (INT8U sec1, INT8U 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)碼 */
- }
- /*********************************************************************************************************
- ** 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返回值
- *********************************************************************************************************/
- INT32U blankChk (INT8U sec1, INT8U 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)碼 */
- }
- /*********************************************************************************************************
- ** Function name: parIdRead
- ** Descriptions: 扇區(qū)查空,命令代碼54
- ** input parameters: 無(wú)
- ** output parameters: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- ** Returned value: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- *********************************************************************************************************/
- INT32U parIdRead (void)
- {
- paramin[0] = IAP_READPARTID; /* 設(shè)置命令字 */
- (*IAP_Entry)(paramin, paramout); /* 調(diào)用IAP服務(wù)程序 */
- return (paramout[0]); /* 返回狀態(tài)碼 */
- }
- /*********************************************************************************************************
- ** Function name: codeIdBoot
- ** Descriptions: 扇區(qū)查空,命令代碼55
- ** input parameters: 無(wú)
- ** output parameters: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- ** Returned value: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- *********************************************************************************************************/
- INT32U codeIdBoot (void)
- {
- paramin[0] = IAP_BOOTCODEID; /* 設(shè)置命令字 */
- (*IAP_Entry)(paramin, paramout); /* 調(diào)用IAP服務(wù)程序 */
- return (paramout[0]); /* 返回狀態(tài)碼 */
- }
- /*********************************************************************************************************
- ** Function name: dataCompare
- ** Descriptions: 校驗(yàn)數(shù)據(jù),命令代碼56
- ** input parameters: dst: 目標(biāo)地址,即RAM/FLASH起始地址。地址必須字對(duì)齊
- ** src: 源地址,即FLASH/RAM地址。地址必須字對(duì)齊
- ** no: 復(fù)制字節(jié)個(gè)數(shù),必須能被4整除
- ** output parameters: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- ** Returned value: paramout[0]: IAP操作狀態(tài)碼,IAP返回值
- *********************************************************************************************************/
- INT32U dataCompare (INT32U dst, INT32U src, INT32U 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)碼 */
- }
- /*********************************************************************************************************
- ** Function name: u16CRC_Calc16
- ** Descriptions: crc16
- ** input parameters: 無(wú)
- ** output parameters: 無(wú)
- ** Returned value: 無(wú)
- *********************************************************************************************************/
- uint16_t u16CRC_Calc16(const uint8_t *pu8Data, int32_t i32Len)
- {
- uint8_t i;
- uint16_t u16CRC = 0;
- while(--i32Len >= 0)
- {
- i = 8;
- u16CRC = u16CRC ^ (((uint16_t)*pu8Data++) << 8);
- do
- {
- if (u16CRC & 0x8000)
- {
- u16CRC = u16CRC << 1 ^ 0x1021;
- }
- else
- {
- u16CRC = u16CRC << 1;
- }
- }
- while(--i);
- }
- return u16CRC;
- }
- /*********************************************************************************************************
- ** Function name: PrepareUpdate
- ** Descriptions:
- ** input parameters: 無(wú)
- ** output parameters: 無(wú)
- ** Returned value: 無(wú)
- *********************************************************************************************************/
- void PrepareUpdate (void )
- {
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr;
- #endif
- IAP_Entry = (void(*)())IAP_ENTER_ADR;
- if (*GpulFlagPoint==LOWADD) /* 當(dāng)前程序運(yùn)行在LOW區(qū),需要 */
- { /* 對(duì)HIGH區(qū)進(jìn)行升級(jí) */
- OS_ENTER_CRITICAL();
- sectorPrepare(SECTORSNH1, SECTORSNH3); /* 選擇HIGH扇區(qū) */
- sectorErase(SECTORSNH1, SECTORSNH3); /* 擦除HIGH扇區(qū) */
- OS_EXIT_CRITICAL();
- } /* 當(dāng)前程序運(yùn)行在HIGH區(qū)或者固 */
- else{ /* 件區(qū),需要對(duì)LOW區(qū)進(jìn)行升級(jí) */
- OS_ENTER_CRITICAL();
- sectorPrepare(SECTORSNL1, SECTORSNL3); /* 選擇LOW扇區(qū) */
- sectorErase(SECTORSNL1, SECTORSNL3); /* 擦除LOW扇區(qū) */
- OS_EXIT_CRITICAL();
- }
- }
- /*********************************************************************************************************
- ** Function name: userFlagUpdate
- ** Descriptions: 更新用戶(hù)程序標(biāo)志區(qū)
- ** input parameters: 無(wú)
- ** output parameters: 無(wú)
- ** Returned value: 無(wú)
- *********************************************************************************************************/
- void userFlagUpdate (void)
- {
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr;
- #endif
- INT32U *pulDataPoint; /* 更新用戶(hù)程序標(biāo)志空間 */
- memset(GucIapTmp, 0xff, 256); /* 臨時(shí)緩沖區(qū)清空 */
- pulDataPoint = (INT32U *)GucIapTmp;
- if (*GpulFlagPoint==LOWADD){
- *pulDataPoint=HIGHADD;
- }
- else{
- *pulDataPoint=LOWADD;
- }
- OS_ENTER_CRITICAL();
- sectorPrepare (SECTORFLAG, SECTORFLAG); /* 扇區(qū)準(zhǔn)備 */
- sectorErase (SECTORFLAG, SECTORFLAG); /* 擦除扇區(qū) */
- sectorPrepare (SECTORFLAG, SECTORFLAG); /* 選擇扇區(qū) */
- ramToFlash(UserFlag,(INT32U)GucIapTmp, 256); /* 編程FLASH */
- OS_EXIT_CRITICAL();
- }
- /*********************************************************************************************************
- ** Function name: userDataProgram
- ** Descriptions:
- ** input parameters: 無(wú)
- ** output parameters: 無(wú)
- ** Returned value: 無(wú)
- *********************************************************************************************************/
- void user(void)
- {
- defaultVectorHandle();
- }
- #define SECTORSIZE (32*1024) //扇區(qū)大小
- /*********************************************************************************************************
- ** Function name: userDataProgram
- ** Descriptions: 編程用戶(hù)代碼區(qū)
- ** input parameters: 無(wú)
- ** output parameters: 無(wú)
- ** Returned value: 無(wú)
- *********************************************************************************************************/
- uint8_t userDataProgram (uint8_t *pdat)
- {
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr;
- #endif
- uint16_t filedatcrc;
- uint16_t fnum,fsn,flen;
- // void (*userProgram)(); /* 函數(shù)指針 */
- uint16_t NPS;
-
- // userProgram = (void (*)()) user; /* 避免編譯警告 */
- fnum = *pdat + *(pdat+1)*256;
- fsn = *(pdat+2) + *(pdat+3)*256;
- flen = *(pdat+4) + *(pdat+5)*256;
- if(fnum==0 && fsn==0 && flen==0){
- //ANDYDEBUG 20150805
- sPTL_104_I_SND.Rson=0x0007;
- //ANDYDEBUG 20150805
-
- PrepareUpdate();
- SysUpdateFsnBak = fsn;
- SysUpdateFlag = 1; // 啟動(dòng)升級(jí)
- if (*GpulFlagPoint==LOWADD)
- return UPHI;
- else
- return UPLO;
- }
- //ANDYDEBUG 20150805
- sPTL_104_I_SND.Rson=0x000A;
- //ANDYDEBUG 20150805
- if(SysUpdateFlag==0) // 未啟動(dòng)升級(jí)
- return UPERR0;
- if(fnum==fsn && flen==0 && fnum>0) { // 執(zhí)行升級(jí)程序
- userFlagUpdate(); // 升級(jí)扇區(qū)標(biāo)識(shí)
- zyReset(ZY_HARD_RESET);
- return UPOK;
- }
- if(fnum==0 || fsn ==0 || fsn>fnum) // 序號(hào)排錯(cuò)
- return UPERR1;
- #ifndef TP1C
- if (flen != 256 && flen != 512 && flen != 1024 ) // 幀長(zhǎng)歸整
- { // 滿(mǎn)足編程字節(jié)數(shù)的要求,256、512、1024等
- if (flen < 256)
- flen = 256;
- else if (flen < 512)
- flen = 512;
- else if (flen < 1024)
- flen = 1024;
- else
- return UPERR3;
- }
- filedatcrc = u16CRC_Calc16(pdat+6,flen); // CRC16校驗(yàn)
- if(filedatcrc != (*(pdat+6+flen) + *(pdat+7+flen)*256))
- return UPERRcrc;
- if(fsn!=SysUpdateFsnBak+1) // 幀順序校驗(yàn)
- return UPERR2;
- SysUpdateFsnBak=fsn;
- NPS= SECTORSIZE/flen; // 單個(gè)扇區(qū)幀容量
- memcpy(GucIapTmp,pdat+6,flen); // 寫(xiě)升級(jí)數(shù)據(jù)入緩存
- #else
- if(flen != 128 && flen != 256 && flen != 512 && flen != 1024 )
- { // 滿(mǎn)足編程字節(jié)數(shù)的要求,256、512、1024等 // 幀長(zhǎng)歸整
- if (flen < 128)
- flen = 128;
- else if (flen < 256)
- flen = 256;
- else if (flen < 512)
- flen = 512;
- else if (flen < 1024)
- flen = 1024;
- else
- return UPERR3;
- }
- filedatcrc = u16CRC_Calc16(pdat+6,flen); // CRC16校驗(yàn)
- if(filedatcrc != (*(pdat+6+flen) + *(pdat+7+flen)*256))
- return UPERRcrc;
- if(fsn!=SysUpdateFsnBak+1) // 幀順序校驗(yàn)
- return UPERR2;
- SysUpdateFsnBak=fsn;
- NPS= SECTORSIZE/flen; // 單個(gè)扇區(qū)幀容量
- if(flen==128){
- if(fsn%2){
- if(fsn<fnum){
- memcpy(GucIapTmp,pdat+6,flen); // 寫(xiě)升級(jí)數(shù)據(jù)入緩存
- return UPOK;
- }
- else {
- memcpy(GucIapTmp,pdat+6,flen); // 寫(xiě)升級(jí)數(shù)據(jù)入緩存
- memset(GucIapTmp+128,0xff,flen); // 結(jié)束幀補(bǔ)齊256字節(jié)
- NPS/=2;
- fsn/=2;
- fsn++;
- flen*=2;
- }
- }
- else {
- memcpy(GucIapTmp+128,pdat+6,flen); // 寫(xiě)升級(jí)數(shù)據(jù)入緩存
- NPS/=2;
- fsn/=2;
- flen*=2;
- }
- }
- else
- memcpy(GucIapTmp,pdat+6,flen); // 寫(xiě)升級(jí)數(shù)據(jù)入緩存
- #endif
- if (*GpulFlagPoint==LOWADD) /* 當(dāng)前程序運(yùn)行在LOW區(qū),需要 */
- { /* 對(duì)HIGH區(qū)進(jìn)行升級(jí) */
- OS_ENTER_CRITICAL();
- if(fsn>0 && fsn<=NPS){
- sectorPrepare(SECTORSNH1, SECTORSNH1); /* 準(zhǔn)備HIGH扇區(qū) */
- ramToFlash(SECTORADDH1 + (fsn-1)*flen,(INT32U)GucIapTmp, flen); /* 寫(xiě)數(shù)據(jù)到FLASH */
- if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDH1+(fsn-1)*flen,flen))
- return UPERRwrt;
- }
- if(fsn>NPS && fsn<=NPS*2){
- sectorPrepare(SECTORSNH2, SECTORSNH2);
- ramToFlash(SECTORADDH2 + (fsn-NPS-1)*flen,(INT32U)GucIapTmp, flen);
- if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDH2+(fsn-NPS-1)*flen,flen))
- return UPERRwrt;
- }
- if(fsn>NPS*2 && fsn<=NPS*3){
- sectorPrepare(SECTORSNH3, SECTORSNH3);
- ramToFlash(SECTORADDH3 + (fsn-NPS*2-1)*flen,(INT32U)GucIapTmp, flen);
- if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDH3+(fsn-NPS*2-1)*flen, flen))
- return UPERRwrt;
- }
- OS_EXIT_CRITICAL();
- }
- else /* 當(dāng)前程序運(yùn)行在HIGH區(qū),需要 */
- { /* 對(duì)LOW區(qū)進(jìn)行升級(jí) */
- OS_ENTER_CRITICAL();
- if(fsn>0 && fsn<=NPS){
- sectorPrepare(SECTORSNL1, SECTORSNL1); /* 準(zhǔn)備LOW扇區(qū) */
- ramToFlash(SECTORADDL1 + (fsn-1)*flen,(INT32U)GucIapTmp, flen); /* 寫(xiě)數(shù)據(jù)到FLASH */
- if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDL1+(fsn-1)*flen,flen))
- return UPERRwrt;
- }
- if(fsn>NPS && fsn<=NPS*2){
- sectorPrepare(SECTORSNL2, SECTORSNL2);
- ramToFlash(SECTORADDL2 + (fsn-NPS-1) * flen,(INT32U)GucIapTmp, flen);
- if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDL2+(fsn-NPS-1)*flen,flen))
- return UPERRwrt;
- }
- if(fsn>NPS*2 && fsn<=NPS*3){
- sectorPrepare(SECTORSNL3, SECTORSNL3);
- ramToFlash(SECTORADDL3 + (fsn-NPS*2-1)*flen,(INT32U)GucIapTmp, flen);
- if(CMD_SUCCESS != dataCompare((INT32U)GucIapTmp,SECTORADDL3+(fsn-NPS*2-1)*flen,flen))
- return UPERRwrt;
- }
- OS_EXIT_CRITICAL();
- }
- return UPOK;
- }
- /*********************************************************************************************************
- ** Function name: zyReset
- ** Descriptions: 系統(tǒng)復(fù)位
- ** input parameters: uiMode: ZY_POWER_RESET: 上電復(fù)位
- ** ZY_HARD_RESET: 硬件復(fù)位
- ** ZY_SOFT_RESET: 軟件復(fù)位
- ** 其它: 與系統(tǒng)相關(guān)
- ** output parameters: none
- ** Returned value: none
- ** Created by: Chenmingji
- ** Created Date: 2009-07-23
- **--------------------------------------------------------------------------------------------------------
- ** Modified by:
- ** Modified date:
- *********************************************************************************************************/
- void zyReset (unsigned int uiMode)
- {
- switch (uiMode) {
- case ZY_POWER_RESET: /* 此系統(tǒng)上電復(fù)位等同硬件復(fù)位 */
- #if 0
- break;
- #endif /* 0 */
- case ZY_HARD_RESET:
- //changeToSYSMode();
- //AITCR = (0x05fa << 16) + 4;
- wdt_entry();
- break;
- case ZY_SOFT_RESET:
- //changeToSYSMode();
- //AITCR = (0x05fa << 16) + 1;
- wdt_entry();
- break;
-
- default: /* 參數(shù)不正確不復(fù)位 */
- break;
- }
- }
- /*********************************************************************************************************
- ** Function name: defaultVectorHandle
- ** Descriptions: ????????
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *********************************************************************************************************/
- void defaultVectorHandle (void)
- {
- #ifdef DEBUG
- while (1);
- #else
- zyReset(ZY_HARD_RESET);
- #endif /* DEBUG */
- }
- /*********************************************************************************************************
- End Of File
- *********************************************************************************************************/
復(fù)制代碼
所有資料51hei提供下載:
LPC1778 IAP燒寫(xiě)源碼.docx
(23.1 KB, 下載次數(shù): 20)
2018-4-26 09:37 上傳
點(diǎn)擊文件名下載附件
IAP源碼,已經(jīng)過(guò)測(cè)試 下載積分: 黑幣 -5
|
|