1、向量表__vector_table位于startup_iar.c
__root void (* const __vector_table[])(void) @ ".intvec" =
{
(void (*)(void))&STACK_TOP, // 0 The initial stack pointer
ResetISR, // 1 The reset handler
NmiSR, // 2 The NMI handler
FaultISR, // 3 The hard fault handler
MPUFaultIntHandler, // 4 Memory Management (MemManage) Fault
BusFaultIntHandler, // 5 The bus fault handler
UsageFaultIntHandler, // 6 The usage fault handler
0, // 7 Reserved
0, // 8 Reserved
0, // 9 Reserved
0, // 10 Reserved
SVCallIntHandler, // 11 Supervisor Call (SVCall)
DebugMonIntHandler, // 12 Debug monitor handler
0, // 13 Reserved
PendSVIntHandler, // 14 The PendSV handler
SysTickIntHandler, // 15 The SysTick handler
//--- External interrupts ---
GPIOIntHandler, // 16 AON edge detect
I2CIntHandler, // 17 I2C
RFCCPE1IntHandler, // 18 RF Core Command & Packet Engine 1
PKAIntHandler, // 19 PKA Interrupt event
AONRTCIntHandler, // 20 AON RTC
UART0IntHandler, // 21 UART0 Rx and Tx
AUXSWEvent0IntHandler, // 22 AUX software event 0
SSI0IntHandler, // 23 SSI0 Rx and Tx
SSI1IntHandler, // 24 SSI1 Rx and Tx
RFCCPE0IntHandler, // 25 RF Core Command & Packet Engine 0
RFCHardwareIntHandler, // 26 RF Core Hardware
RFCCmdAckIntHandler, // 27 RF Core Command Acknowledge
I2SIntHandler, // 28 I2S
AUXSWEvent1IntHandler, // 29 AUX software event 1
WatchdogIntHandler, // 30 Watchdog timer
Timer0AIntHandler, // 31 Timer 0 subtimer A
Timer0BIntHandler, // 32 Timer 0 subtimer B
Timer1AIntHandler, // 33 Timer 1 subtimer A
Timer1BIntHandler, // 34 Timer 1 subtimer B
Timer2AIntHandler, // 35 Timer 2 subtimer A
Timer2BIntHandler, // 36 Timer 2 subtimer B
Timer3AIntHandler, // 37 Timer 3 subtimer A
Timer3BIntHandler, // 38 Timer 3 subtimer B
CryptoIntHandler, // 39 Crypto Core Result available
uDMAIntHandler, // 40 uDMA Software
uDMAErrIntHandler, // 41 uDMA Error
FlashIntHandler, // 42 Flash controller
SWEvent0IntHandler, // 43 Software Event 0
AUXCombEventIntHandler, // 44 AUX combined event
AONProgIntHandler, // 45 AON programmable 0
DynProgIntHandler, // 46 Dynamic Programmable interrupt
// source (Default: PRCM)
AUXCompAIntHandler, // 47 AUX Comparator A
AUXADCIntHandler, // 48 AUX ADC new sample or ADC DMA
// done, ADC underflow, ADC overflow
TRNGIntHandler, // 49 TRNG event
OSCIntHandler, // 50 Combined event from Oscillator control
AUXTimer2IntHandler, // 51 AUX Timer2 event 0
UART1IntHandler, // 52 UART1 combined interrupt
BatMonIntHandler // 53 Combined event from battery monitor
};
2、复位向量ResetISR
void ResetISR(void)
{
//
// Final trim of device
//
SetupTrimDevice();
//
// Jump to IAR initialization routine
//
__iar_program_start();
//
// If we ever return signal Error
//
FaultISR();
}
3、跳转到IAR初始化程序 __iar_program_start 位于boot.s文件
PUBLIC __iar_program_start
EXTERN CSTACK$$Limit
EXTERN __iar_program_startC
THUMB
__iar_program_start:
LDR R0, cstacklimit
MOV SP, R0
LDR R0, program_startc
BLX R0
DATA
ALIGNROM 2
cstacklimit:
DC32 CSTACK$$Limit
program_startc:
DC32 __iar_program_startC
通过下面两条汇编代码可以看出,程序跳转到program_startc
LDR R0, program_startc;
BLX R0
program_startc对应的是__iar_program_startC,所以程序实际是跳转到__iar_program_startC
program_startc:
DC32 __iar_program_startC
4、__iar_program_startC函数位于cstartup_M.c文件
void __iar_program_startC( void )
{
/* XDC startup reset hook */
iar_xdc_startup_reset();
__iar_init_core();
#if defined (__ARMVFP__)
/*------------------------------------------------------
* SETUP FULL ACCESS TO COPROCESSORS 10 AND 11,
* REQUIRED FOR FP. COPROCESSOR ACCESS CONTROL REG
* BITS [23:22] - CP11, [21:20] - CP10
* SET TO 0b11 TO ENABLE FULL ACCESS
*------------------------------------------------------
*/
asm volatile(
" MOVW r1, #0xE000ED88 & 0xFFFF\n"
" MOVT r1, #0xE000ED88 >> 16\n"
" LDR r0, [ r1 ]\n"
" MOV r3, #0xf0\n"
" ORR r0,r0,r3, LSL #16\n"
" STR r0, [ r1 ]\n"
);
#endif
__cmain();
}
程序最后调用汇编的__cmain,位于文件cmain.s
PUBLIC __cmain
;; Keep ?main for legacy reasons, it is accessed in countless instances of cstartup.s around the world...
PUBLIC ?main
EXTWEAK __iar_data_init3
EXTERN __low_level_init
EXTERN iar_xdc_startup_exec
EXTERN __call_ctors
EXTERN main
EXTERN xdc_runtime_System_exit__E
THUMB
__cmain:
?main:
; Initialize segments.
; __segment_init and __low_level_init are assumed to use the same
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).
FUNCALL __cmain, __low_level_init
bl __low_level_init
cmp r0,#0
beq ?l1
FUNCALL __cmain, __iar_data_init3
bl __iar_data_init3
; XDC startup exec hook
FUNCALL __cmain, iar_xdc_startup_exec
bl iar_xdc_startup_exec
?l1:
REQUIRE ?l3
SECTION .text:CODE:NOROOT(2)
PUBLIC _main
PUBLIC _call_main
THUMB
__iar_init$$done: ; Copy initialization is done
?l3:
_call_main:
MOVS r0,#0 ; No parameters
FUNCALL __cmain, main
BL main
_main:
FUNCALL __cmain, xdc_runtime_System_exit__E
BL xdc_runtime_System_exit__E
END
a、程序调用__low_level_init函数
int __low_level_init(void)
{
IntMasterDisable();
//
// Final trim of device
//
SetupTrimDevice();
/*==================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit seg_init */
/* 1 to run seg_init */
/*==================================*/
return 1;
}
b、程序调用__iar_data_init3函数
void __iar_data_init3(void)
{
char const * p = __section_begin("Region$$Table");
uint32_t const * pe = __section_end("Region$$Table");
uint32_t const * pi = (uint32_t const *)(p);
while (pi != pe)
{
init_fun_t * fun = (init_fun_t *)((char *)pi + *(int32_t *)pi);
pi++;
pi = fun(pi);
}
}
c、程序调用iar_xdc_startup_exec函数
void iar_xdc_startup_exec(void)
{
/*------------------------------------------------------------------------*/
/* Process XDC Startup */
/*------------------------------------------------------------------------*/
if (&xdc_runtime_Startup__EXECFXN__C == (int*)1) {
xdc_runtime_Startup_exec__E();
}
}
d、最后程序执行下面语句,进入c的main函数
BL main
int main()
{
/* Register Application callback to trap asserts raised in the Stack */
RegisterAssertCback(AssertHandler);
Board_initGeneral();
// Enable iCache prefetching
VIMSConfigure(VIMS_BASE, TRUE, TRUE);
// Enable cache
VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
#if !defined( POWER_SAVING )
/* Set constraints for Standby, powerdown and idle mode */
// PowerCC26XX_SB_DISALLOW may be redundant
Power_setConstraint(PowerCC26XX_SB_DISALLOW);
Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
#endif // POWER_SAVING
/* Update User Configuration of the stack */
user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod;
user0Cfg.appServiceInfo->timerMaxMillisecond = ICall_getMaxMSecs();
/* Initialize ICall module */
ICall_init();
#if (!defined(STACK_LIBRARY) && (defined(SPLIT_APP_STACK_IMAGE)))
{
/* Find stack entry page */
uint32_t stackAddr = findStackBoundaryAddr();
if(stackAddr == 0xFFFFFFFF)
{
// If we cannot find the stack start address, exit
ICall_abort();
}
/* set the stack image header based on the stack addr */
stackImageHeader = (imgHdr_t *)stackAddr;
/* Start tasks of external images - Priority 5 */
const ICall_RemoteTask_t remoteTaskTbl[] =
{
(ICall_RemoteTaskEntry) (stackImageHeader->prgEntry),
5,
1000,
&user0Cfg
};
/* Start tasks of external images - Priority 5 */
ICall_createRemoteTasksAtRuntime((ICall_RemoteTask_t *) remoteTaskTbl,
(sizeof(remoteTaskTbl)/sizeof(ICall_RemoteTask_t)));
}
#else
/* Start tasks of external images - Priority 5 */
ICall_createRemoteTasks();
#endif
SimplePeripheral_createTask();
/* enable interrupts and start SYS/BIOS */
BIOS_start();
return (0);
}