Cortex-M3 (NXP LPC1788)之啟動代碼分析
- ;/*****************************************************************************
- ;*@file:startup_LPC177x_8x.s
- ;*@purpose:CMSISCortex-M3CoreDeviceStartupFile
- ;*fortheNXPLPC177x_8xDeviceSeries
- ;*@version:V1.20
- ;*@date:07.October2010
- ;*-------<<
>>------------------ - ;*
- ;*Copyright(C)2010ARMLimited.Allrightsreserved.
- ;*ARMLimited(ARM)issupplyingthissoftwareforusewithCortex-M3
- ;*processorbasedmicrocontrollers.Thisfilecanbefreelydistributed
- ;*withindevelopmenttoolsthataresupportingsuchARMbasedprocessors.
- ;*
- ;*THISSOFTWAREISPROVIDED"ASIS".NOWARRANTIES,WHETHEREXPRESS,IMPLIED
- ;*ORSTATUTORY,INCLUDING,BUTNOTLIMITEDTO,IMPLIEDWARRANTIESOF
- ;*MERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAPPLYTOTHISSOFTWARE.
- ;*ARMSHALLNOT,INANYCIRCUMSTANCES,BELIABLEFORSPECIAL,INCIDENTAL,OR
- ;*CONSEQUENTIALDAMAGES,FORANYREASONWHATSOEVER.
- ;*
- ;*****************************************************************************/
- ;
StackConfiguration - ;
StackSize(inBytes)<0x0-0xFFFFFFFF:8> - ;
- Stack_SizeEQU0x00000200
- AREASTACK,NOINIT,READWRITE,ALIGN=3
- Stack_MemSPACEStack_Size
- __initial_sp
- ;
HeapConfiguration - ;
HeapSize(inBytes)<0x0-0xFFFFFFFF:8> - ;
- Heap_SizeEQU0x00000400
- AREAHEAP,NOINIT,READWRITE,ALIGN=3
- __heap_base
- Heap_MemSPACEHeap_Size
- __heap_limit
- PRESERVE8
- THUMB
- ;VectorTableMappedtoAddress0atReset
- AREARESET,DATA,READONLY
- EXPORT__Vectors
- __VectorsDCD__initial_sp;TopofStack
- DCDReset_Handler;ResetHandler
- DCDNMI_Handler;NMIHandler
- DCDHardFault_Handler;HardFaultHandler
- DCDMemManage_Handler;MPUFaultHandler
- DCDBusFault_Handler;BusFaultHandler
- DCDUsageFault_Handler;UsageFaultHandler
- DCD0;Reserved
- DCD0;Reserved
- DCD0;Reserved
- DCD0;Reserved
- DCDSVC_Handler;SVCallHandler
- DCDDebugMon_Handler;DebugMonitorHandler
- DCD0;Reserved
- DCDPendSV_Handler;PendSVHandler
- DCDSysTick_Handler;SysTickHandler
- ;ExternalInterrupts
- DCDWDT_IRQHandler;16:WatchdogTimer
- DCDTIMER0_IRQHandler;17:Timer0
- DCDTIMER1_IRQHandler;18:Timer1
- DCDTIMER2_IRQHandler;19:Timer2
- DCDTIMER3_IRQHandler;20:Timer3
- DCDUART0_IRQHandler;21:UART0
- DCDUART1_IRQHandler;22:UART1
- DCDUART2_IRQHandler;23:UART2
- DCDUART3_IRQHandler;24:UART3
- DCDPWM1_IRQHandler;25:PWM1
- DCDI2C0_IRQHandler;26:I2C0
- DCDI2C1_IRQHandler;27:I2C1
- DCDI2C2_IRQHandler;28:I2C2
- DCDSPIFI_IRQHandler;29:SPIFI
- DCDSSP0_IRQHandler;30:SSP0
- DCDSSP1_IRQHandler;31:SSP1
- DCDPLL0_IRQHandler;32:PLL0Lock(MainPLL)
- DCDRTC_IRQHandler;33:RealTimeClock
- DCDEINT0_IRQHandler;34:ExternalInterrupt0
- DCDEINT1_IRQHandler;35:ExternalInterrupt1
- DCDEINT2_IRQHandler;36:ExternalInterrupt2
- DCDEINT3_IRQHandler;37:ExternalInterrupt3
- DCDADC_IRQHandler;38:A/DConverter
- DCDBOD_IRQHandler;39:Brown-OutDetect
- DCDUSB_IRQHandler;40:USB
- DCDCAN_IRQHandler;41:CAN
- DCDDMA_IRQHandler;42:GeneralPurposeDMA
- DCDI2S_IRQHandler;43:I2S
- DCDENET_IRQHandler;44:Ethernet
- DCDMCI_IRQHandler;45:SD/MMCcardI/F
- DCDMCPWM_IRQHandler;46:MotorControlPWM
- DCDQEI_IRQHandler;47:QuadratureEncoderInterface
- DCDPLL1_IRQHandler;48:PLL1Lock(USBPLL)
- DCDUSBActivity_IRQHandler;49:USBActivityinterrupttowakeup
- DCDCANActivity_IRQHandler;50:CANActivityinterrupttowakeup
- DCDUART4_IRQHandler;51:UART4
- DCDSSP2_IRQHandler;52:SSP2
- DCDLCD_IRQHandler;53:LCD
- DCDGPIO_IRQHandler;54:GPIO
- DCDPWM0_IRQHandler;55:PWM0
- DCDEEPROM_IRQHandler;56:EEPROM
- IF:LNOT::DEF:NO_CRP
- AREA|.ARM.__at_0x02FC|,CODE,READONLY
- CRP_KeyDCD0xFFFFFFFF
- ENDIF
- AREA|.text|,CODE,READONLY
- ;ResetHandler
- Reset_HandlerPROC
- EXPORTReset_Handler[WEAK]
- IMPORTSystemInit
- IMPORT__main
- LDRR0,=SystemInit
- BLXR0
- LDRR0,=__main
- BXR0
- ENDP
- ;DummyExceptionHandlers(infiniteloopswhichcanbemodified)
- NMI_HandlerPROC
- EXPORTNMI_Handler[WEAK]
- B.
- ENDP
- HardFault_Handler
- PROC
- EXPORTHardFault_Handler[WEAK]
- B.
- ENDP
- MemManage_Handler
- PROC
- EXPORTMemManage_Handler[WEAK]
- B.
- ENDP
- BusFault_Handler
- PROC
- EXPORTBusFault_Handler[WEAK]
- B.
- ENDP
- UsageFault_Handler
- PROC
- EXPORTUsageFault_Handler[WEAK]
- B.
- ENDP
- SVC_HandlerPROC
- EXPORTSVC_Handler[WEAK]
- B.
- ENDP
- DebugMon_Handler
- PROC
- EXPORTDebugMon_Handler[WEAK]
- B.
- ENDP
- PendSV_HandlerPROC
- EXPORTPendSV_Handler[WEAK]
- B.
- ENDP
- SysTick_HandlerPROC
- EXPORTSysTick_Handler[WEAK]
- B.
- ENDP
- Default_HandlerPROC
- EXPORTWDT_IRQHandler[WEAK]
- EXPORTTIMER0_IRQHandler[WEAK]
- EXPORTTIMER1_IRQHandler[WEAK]
- EXPORTTIMER2_IRQHandler[WEAK]
- EXPORTTIMER3_IRQHandler[WEAK]
- EXPORTUART0_IRQHandler[WEAK]
- EXPORTUART1_IRQHandler[WEAK]
- EXPORTUART2_IRQHandler[WEAK]
- EXPORTUART3_IRQHandler[WEAK]
- EXPORTPWM1_IRQHandler[WEAK]
- EXPORTI2C0_IRQHandler[WEAK]
- EXPORTI2C1_IRQHandler[WEAK]
- EXPORTI2C2_IRQHandler[WEAK]
- EXPORTSPIFI_IRQHandler[WEAK]
- EXPORTSSP0_IRQHandler[WEAK]
- EXPORTSSP1_IRQHandler[WEAK]
- EXPORTPLL0_IRQHandler[WEAK]
- EXPORTRTC_IRQHandler[WEAK]
- EXPORTEINT0_IRQHandler[WEAK]
- EXPORTEINT1_IRQHandler[WEAK]
- EXPORTEINT2_IRQHandler[WEAK]
- EXPORTEINT3_IRQHandler[WEAK]
- EXPORTADC_IRQHandler[WEAK]
- EXPORTBOD_IRQHandler[WEAK]
- EXPORTUSB_IRQHandler[WEAK]
- EXPORTCAN_IRQHandler[WEAK]
- EXPORTDMA_IRQHandler[WEAK]
- EXPORTI2S_IRQHandler[WEAK]
- EXPORTENET_IRQHandler[WEAK]
- EXPORTMCI_IRQHandler[WEAK]
- EXPORTMCPWM_IRQHandler[WEAK]
- EXPORTQEI_IRQHandler[WEAK]
- EXPORTPLL1_IRQHandler[WEAK]
- EXPORTUSBActivity_IRQHandler[WEAK]
- EXPORTCANActivity_IRQHandler[WEAK]
- EXPORTUART4_IRQHandler[WEAK]
- EXPORTSSP2_IRQHandler[WEAK]
- EXPORTLCD_IRQHandler[WEAK]
- EXPORTGPIO_IRQHandler[WEAK]
- EXPORTPWM0_IRQHandler[WEAK]
- EXPORTEEPROM_IRQHandler[WEAK]
- WDT_IRQHandler
- TIMER0_IRQHandler
- TIMER1_IRQHandler
- TIMER2_IRQHandler
- TIMER3_IRQHandler
- UART0_IRQHandler
- UART1_IRQHandler
- UART2_IRQHandler
- UART3_IRQHandler
- PWM1_IRQHandler
- I2C0_IRQHandler
- I2C1_IRQHandler
- I2C2_IRQHandler
- SPIFI_IRQHandler
- SSP0_IRQHandler
- SSP1_IRQHandler
- PLL0_IRQHandler
- RTC_IRQHandler
- EINT0_IRQHandler
- EINT1_IRQHandler
- EINT2_IRQHandler
- EINT3_IRQHandler
- ADC_IRQHandler
- BOD_IRQHandler
- USB_IRQHandler
- CAN_IRQHandler
- DMA_IRQHandler
- I2S_IRQHandler
- ENET_IRQHandler
- MCI_IRQHandler
- MCPWM_IRQHandler
- QEI_IRQHandler
- PLL1_IRQHandler
- USBActivity_IRQHandler
- CANActivity_IRQHandler
- UART4_IRQHandler
- SSP2_IRQHandler
- LCD_IRQHandler
- GPIO_IRQHandler
- PWM0_IRQHandler
- EEPROM_IRQHandler
- B.
- ENDP
- ALIGN
- ;UserInitialStack&Heap
- IF:DEF:__MICROLIB
- EXPORT__initial_sp
- EXPORT__heap_base
- EXPORT__heap_limit
- ELSE
- IMPORT__use_two_region_memory
- EXPORT__user_initial_stackheap
- __user_initial_stackheap
- LDRR0,=Heap_Mem
- LDRR1,=(Stack_Mem+Stack_Size)
- LDRR2,=(Heap_Mem+Heap_Size)
- LDRR3,=Stack_Mem
- BXLR
- ALIGN
- ENDIF
- END
程序完成如下內(nèi)容的工作:
開辟一塊大小為Stack_Size的??臻g;
標(biāo)號__initial_sp指向棧頂位置;
定義堆空間大小為Heap_Size;
建立中斷向量表Vectors,cortex-M3規(guī)定起始地址必須存放棧頂?shù)刂芳確_initial_sp,緊接著存放復(fù)位入口地址,這樣內(nèi)核復(fù)位后就會自動從起始地址的下32位取出復(fù)位地址執(zhí)行復(fù)位中斷服務(wù)函數(shù)。
Reset_Handler復(fù)位中斷函數(shù)中先EXPORT聲明Reset_Handler的全局性,然后分別執(zhí)行外部的函數(shù)SystemInit和__main。
下面對匯編程序中的幾個關(guān)鍵字做說明:
AREA偽指令:用于定義代碼段和數(shù)據(jù)段,后跟屬性標(biāo)號。其中“READWRITE”表示可讀寫,“READONLY”只讀屬性。根據(jù)LPC1788的數(shù)據(jù)手冊描述的存儲介質(zhì),可知可讀寫段保持在SRAM區(qū),起始地址為0x1000 0000,代碼中的堆棧保存在SRAM空間。只讀段保存在Flash區(qū),起始地址為0x0000 0000,代碼中的中斷向量表保存在Flash空間。 因此可以總結(jié)出,在0x0000 0000 存放的是棧頂?shù)牡刂穇_initial_sp(即0x1000 0200),在0x0000 0004 存放的是Reset_Handler的地址。
圖1:LPC1788 地址映射
圖2: debug中 0地址的值0x1000 0200 即棧頂?shù)刂罚?0x0000 0004 地址值為0x0000 00F9(看反匯編可知該值 即Reset_Handler的入口如下圖)。
DCD指令:開辟內(nèi)存空間,中斷向量表建立中使用相當(dāng)于C語言中的函數(shù)指針,每個成員都是函數(shù)指針,指向各個中斷服務(wù)函數(shù)。
自此分析了LPC1788的啟動,主要包括堆棧初始化,和中斷向量表的初始化。LPC1788有內(nèi)部Flash,所以上點(diǎn)從內(nèi)部Flash啟動,內(nèi)部Flash的起始地址為0x0000 0000,存放棧頂?shù)牡刂?x1000 0200。 0x0000 0004存放復(fù)位中斷的入口地址。LPC1788復(fù)位后,從0x0000 0004取出復(fù)位入口地址,執(zhí)行中斷復(fù)位函數(shù),從而跳轉(zhuǎn)到SystemInit和main C語言函數(shù)執(zhí)行。
評論