版權聲明:本文爲博主原創文章,未經博主允許不得轉載。聯繫郵箱:[email protected]
ARM7 IAP函數
對於在應用編程( IAP) 來說,應當通過寄存器 r0 中的字指針指向包含命令代碼和參數的存儲器(RAM)來調用 IAP 程序。 IAP 命令的結果返回到寄存器 r1 所指向的結果表( resulttable)。用戶可通過傳遞寄存器 r0 和 r1 中的相同指針來重新使用命令表以獲取結果。參數表應當大到足夠存放所有的結果以防結果的數目大於參數的數目。參數傳遞的過程如下圖所示。
參數和結果的數目根據 IAP 命令而有所不同。參數的最大數目爲 5, 被傳遞給“將RAM 內容複製到 Flash”命令。結果的最大數目爲 2,由“扇區查空”命令返回。命令處理程序在接收到一個未定義的命令時發送狀態代碼 INVALID_COMMAND。 IAP 程序是 thumb代碼,位於地址 0x7FFF FFF0 處。
IAP 功能可用下面的 C 代碼來調用。定義 IAP 程序的入口地址。由於 IAP 地址的第 0 位是 1,因此,當程序計數器轉移到該地址時會引起 Thumb 指令集的變化。下面附上IAP函數代碼:
/**************************************************
名稱: 宏定義(Flash操作)
**************************************************/
#define IAP_LOCATION 0x7FFFFFF1 //定義IAP程序的入口地址
#define IapGetAddr(addr) (volatile uint16 *)(0x80000000|(addr<<1)) //轉換地址
/**************************************************
名稱: IAP參數定義
**************************************************/
uint32 paramin[5]; // IAP入口參數緩衝區
uint32 paramout[2]; // IAP出口參數緩衝區
typedef void(*IAP)(uint32 [],uint32 []); //定義函數類型指針
IAP iap_entry=(IAP)IAP_LOCATION; //設置函數指針
/****************************************************************************
* 名稱:SelSector()
* 功能:IAP操作扇區選擇,命令代碼50。 //hmm 準備編程扇區
* 入口參數:sec1 起始扇區
* sec2 終止扇區
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCCESS,BUSY,INVALID_SECTOR
****************************************************************************/
void SelSector(uint8 sec1, uint8 sec2)
{ paramin[0] = IAP_SELSECTOR; // 設置命令字
paramin[1] = sec1; // 設置參數
paramin[2] = sec2;
iap_entry(paramin, paramout); // 調用IAP服務程序
}
/****************************************************************************
* 名稱:RamToFlash()
* 功能:複製RAM的數據到FLASH,命令代碼51。 //hmm 將RAM的內容複製到到FLASH
* 入口參數:dst 目標地址,即FLASH起始地址。以512字節爲分界
* src 源地址,即RAM地址。地址必須字對齊
* no 複製字節個數,爲512/1024/4096/8192
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCCESS,SRC_ADDR_ERROR,DST_ADDR_ERROR,
SRC_ADDR_NOT_MAPPED,DST_ADDR_NOT_MAPPED,COUNT_ERROR,BUSY,未選擇扇區
****************************************************************************/
void RamToFlash(uint32 dst, uint32 src, uint32 no)
{ paramin[0] = IAP_RAMTOFLASH; // 設置命令字
paramin[1] = dst; // 設置參數
paramin[2] = src;
paramin[3] = no;
paramin[4] = Fcclk/1000; // 當不使用PLL功能時,Fcclk=Fosc
iap_entry(paramin, paramout); // 調用IAP服務程序
}
/****************************************************************************
* 名稱:EraseSector()
* 功能:扇區擦除,命令代碼52。 //hmm 擦除扇區
* 入口參數:sec1 起始扇區
* sec2 終止扇區
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCCESS,BUSY,INVALID_SECTOR,未選擇扇區
****************************************************************************/
void EraseSector(uint8 sec1, uint8 sec2)
{ paramin[0] = IAP_ERASESECTOR; // 設置命令字
paramin[1] = sec1; // 設置參數
paramin[2] = sec2;
paramin[3] = Fcclk/1000; // 當不使用PLL功能時,Fcclk=Fosc
iap_entry(paramin, paramout); // 調用IAP服務程序
}
/****************************************************************************
* 名稱:BlankCHK()
* 功能:扇區查空,命令代碼53。 //hmm 扇區查空
* 入口參數:sec1 起始扇區
* sec2 終止扇區
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCCESS,BUSY,INVALID_SECTOR,SECTOR_NOT_BLANK
****************************************************************************/
void BlankCHK(uint8 sec1, uint8 sec2)
{ paramin[0] = IAP_BLANKCHK; // 設置命令字
paramin[1] = sec1; // 設置參數
paramin[2] = sec2;
iap_entry(paramin, paramout); // 調用IAP服務程序
}
/****************************************************************************
* 名稱:ReadParID()
* 功能:讀器件ID,命令代碼54。 //hmm 讀器件ID
* 入口參數:無
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCCESS
****************************************************************************/
void ReadParID(void)
{ paramin[0] = IAP_READPARTID; // 設置命令字
iap_entry(paramin, paramout); // 調用IAP服務程序
}
/****************************************************************************
* 名稱:BootCodeID()
* 功能:讀取boot代碼版本號,命令代碼55。 //hmm 讀boot代碼版本
* 入口參數:無
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCDESS
****************************************************************************/
void BootCodeID(void)
{ paramin[0] = IAP_BOOTCODEID; // 設置命令字
iap_entry(paramin, paramout); // 調用IAP服務程序
}
/****************************************************************************
* 名稱:Compare()
* 功能:校驗數據,命令代碼56。 //hmm 比較
* 入口參數:dst 目標地址,即RAM/FLASH起始地址。地址必須字對齊
* src 源地址,即FLASH/RAM地址。地址必須字對齊
* no 複製字節個數,必須能被4整除
* 出口參數:IAP返回值(paramout緩衝區) CMD_SUCCESS,COMPARE_ERROR,ADDR_ERROR
****************************************************************************/
void Compare(uint32 dst, uint32 src, uint32 no)
{ paramin[0] = IAP_COMPARE; // 設置命令字
paramin[1] = dst; // 設置參數
paramin[2] = src;
paramin[3] = no;
iap_entry(paramin, paramout); // 調用IAP服務程序
}