幾千行的程序都寫完了 從ADS轉到IAR下的時候 頭疼了三天程序都沒跑起來 在失望之余 猛然看到了這個帖子 內牛滿面啊!!!
摘要:
當系統中,只有一個程序時,可以直接從起始地址開始運行;但當系統中有兩個程序時,例如帶bootloader的系統,則應用程序的運行需要通過bootloader跳轉,和bootloader相比,應用程序的地址和中斷向量表地址都發生改變,如何告訴編譯器來分配bootloader和應用程序在flash中的地址以及如何告訴CPU中斷表向表的位置,是本文討論的主要內容。
簡介:
1、如何設置bootloader和user app的程序地址
首先我們來看看IAR下LPC2478的分散加載文件:LPC2478_Flash.icf
/*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000;//中斷向量表的起始地址 /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000044; //程序ROM起始地址 define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x40000000; //數據RAM的起始地址 define symbol __ICFEDIT_region_RAM_end__ = 0x4000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x100; define symbol __ICFEDIT_size_svcstack__ = 0x100; define symbol __ICFEDIT_size_irqstack__ = 0x100; define symbol __ICFEDIT_size_fiqstack__ = 0x40; define symbol __ICFEDIT_size_undstack__ = 0x40; define symbol __ICFEDIT_size_abtstack__ = 0x40; define symbol __ICFEDIT_size_heap__ = 0x1000; /**** End of ICF editor section. ###ICF###*/
從上面可以看出,中斷向量表是放在起始地址0處的,它占64個字節,從0x44開始存放用戶程序,保證用戶程序不占用中斷向量表的空間;這是bootloader的設置。
理解了地址設置的方法,user app的地址就好辦了:
比如說,bootloader在0x0~0x4000,那么用戶程序為了保證不覆蓋bootloader,則應該從0x4000開始,我們作如下設置
/*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$/config/ide/IcfEditor/a_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00004000; //中斷向量表的起始地址 /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00004044;//程序ROM起始地址 define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x40000040;//數據RAM的起始地址 為什么要空出0x40,后面再解釋 define symbol __ICFEDIT_region_RAM_end__ = 0x4000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x100; define symbol __ICFEDIT_size_svcstack__ = 0x100; define symbol __ICFEDIT_size_irqstack__ = 0x100; define symbol __ICFEDIT_size_fiqstack__ = 0x40; define symbol __ICFEDIT_size_undstack__ = 0x40; define symbol __ICFEDIT_size_abtstack__ = 0x40; define symbol __ICFEDIT_size_heap__ = 0x1000; /**** End of ICF editor section. ###ICF###*/
地址是設置好了,我們分別編譯bootloader和user app,並下載到目標系統中去運行,程序真的跑起來了,說明地址設置是正確的,可是一用中斷,程序就死掉了,這是怎么回事呢。
原來,user app中的中斷向量表在0x4000,CPU中斷不會跳轉到這里來,而是跳轉到0x0,0x0是bootloader的中斷向量表,當然會出錯,那么如何設置user app的中斷向量表呢。
2、如何設置bootloader和user app的中斷向量表
在lpc系列AR7的中斷向量表,它不像STM32(cortex-m3)那樣可以通過 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000); 來設置,它的中斷向量表只能是幾個固定的位置:
這里我們可以將中斷向量表映射到RAM中(RAM起始地址0x40000000~0x400000040),然后在0x4000處將中斷向量表復制到RAM里,那么這樣就能正常中斷了,在user app初始化時,加入如下代碼:
//將向量表復制到內存 //注意在分散加載文件中將內存:0x40000000~0x40000000+16*4.保留. if(1) { memcpy((BYTE *)0x40000000, (BYTE *)0x4000,16*4); MEMMAP = 0x02; //中斷向量表設置在RAM中 }
為了保證RAM址0x40000000~0x400000040不被程序占用,在ICF文件中的 define symbol __ICFEDIT_region_RAM_start__ = 0x40000040; 而不是0x40000000了。
結語:
對於不是在起始地址運行的程序,除了修改分散加載文件中的起始地址外,還需要注意中斷向量表,否則系統將不能正常的工作。
===================================================================
博主注:不用直接編輯.icf文件,修改各種地址可以在這修改:工程上右鍵-options-linker-config-edit
eMotion項目的hw_config.c中
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures Vector Table base location.
*******************************************************************************/
#ifdef USE_DFU
void NVIC_Configuration(void)
{
/* Set the Vector Table base location at 0x3000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);
}
#endif