STM32F030的IAP應(yīng)用簡介
程序收尾總想著以后更新的方便性,采用在應(yīng)用編程(In Application Programming),通過Bootload引導(dǎo)單片機(jī)自己往程序存儲(chǔ)器里寫數(shù)據(jù)或修改程序。下面簡介STM32F030的IAP方法。不同于STM32F1系列,F(xiàn)0沒有中斷向量偏移寄存器。所以在APP程序的開頭要添加以下代碼。為什么這樣做??
可以看到函數(shù)用了for循環(huán)將矢量表拷貝到0 x20000000 SRAM的基地址,即將矢量表由Flash映射到了SRAM。所以在MDK里面設(shè)置Flash偏移地址的時(shí)候,同時(shí)要設(shè)置SRAM偏移地址。如下截圖
//APP程序開頭加入IAP_Set(void)函數(shù)
//Falshaddress
#defineAPPLICATION_ADDRESS((uint32_t)0x08001400)
//SRAMAddress0x020000C0
voidIAP_Set(void)
{
uint32_ti=0;
/*RelocatebysoftwarethevectortabletotheinternalSRAMat0x20000000***/
/*CopythevectortablefromtheFlash(mappedatthebaseoftheapplication
loadaddress0x08003000)tothebaseaddressoftheSRAMat0x20000000.*/
for(i=0;i<48;i++)
{
*((uint32_t*)(0x20000000+(i<<2)))=*(__IOuint32_t*)(APPLICATION_ADDRESS+(i<<2));
}
/*EnabletheSYSCFGperipheralclock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
/*RemapSRAMat0x00000000*/
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
}
有Target對(duì)話框可以看出APP程序有Flash地址0x8001400開始執(zhí)行。Sram數(shù)據(jù)則有0x20000c0出開始存儲(chǔ)。
說完APP代碼要處理事項(xiàng),下面說一下IAP代碼編寫
/*Keeptheuserapplicationrunning*/
/*Testifusercodeisprogrammedstartingfromaddress"APPLICATION_ADDRESS"*/
if(((*(__IOuint32_t*)APPLICATION_ADDRESS)&0x2FFE0000)==0x20000000)
{
/*Jumptouserapplication*/
JumpAddress=*(__IOuint32_t*)(APPLICATION_ADDRESS+4);
Jump_To_Application=(pFunction)JumpAddress;
/*Initializeuserapplication'sStackPointer*/
__set_MSP(*(__IOuint32_t*)APPLICATION_ADDRESS);
/*Jumptoapplication*/
Jump_To_Application();
}
程序更新完以后執(zhí)行以上跳轉(zhuǎn)函數(shù)即可執(zhí)行更新的APP代碼。關(guān)于如何通過IAP將代碼將APP代碼(bin文件)傳到單片機(jī)Flash,可以通過串口分包傳輸。因?yàn)镕0Flash是1K為一頁所以這里我用的是1K緩存,即接收串口1K的數(shù)據(jù)量就執(zhí)行一次Flash寫操作,傳輸?shù)阶詈蟛粷M1K,填寫0XFF按照1K數(shù)據(jù)寫。寫Flash代碼如下
//存滿1K的數(shù)據(jù)寫入Flash
if(g_nFlashDataLen==FLASH_PAGE_SIZE)
{
#if(DEBUGIAP==1)
USART1_SendBytesProc(g_nFlashBuf,FLASH_PAGE_SIZE);
g_nSysCommTimerCtrl=0;
while(g_nSysCommTimerCtrl<200);//5ms
#else
//擦除待寫的Flash
FLASH_If_Erase(g_nFlashAddr);
loop1:
//寫入Flash
nFlashData=(u32)g_nFlashBuf;
if(FLASH_If_Write(&g_nFlashAddr,(u32*)nFlashData,(u16)g_nFlashDataLen/4)!=0)
{
if(nCount++<5)
gotoloop1;
}
//地址增加
g_nFlashAddr+=FLASH_PAGE_SIZE;
#endif
//清除g_nFlashDataLen計(jì)數(shù)
g_nFlashDataLen=0;
}
關(guān)于IAP如何接收串口的數(shù)據(jù),我用的是正點(diǎn)原子的XCOM V2.0串口調(diào)試助手通過協(xié)議傳輸每次傳輸128字節(jié)數(shù)據(jù),執(zhí)行的IAP串口數(shù)據(jù)接收。具體操作可在原子論壇搜索。再此留下參考鏈接:http://www.openedv.com/thread-40143-1-1.html http://www.openedv.com/thread-22994-1-1.html