RT-Thread启动流程
1. Boot Loader
LPC17xx系列芯片的Boot Loader一般命名为startup_LPC17xx.s。这个文件是Cortex-M3的启动文件,启动文件由汇编语言组成。LPC17xx硬件初始化主要完成了以下功能:
1.堆和栈的初始化</br>
2.中断向量表定义</br>
3.地址重映射及中断向量表的转移</br>
4.设置系统时钟频率</br>
5.中断寄存器的初始化</br>
6.进入C应用程序</br>
其中,startup_LPC17xx.s完成了1、2和6两个功能。3、4、5三个功能是通过startup_LPC17xx.s调用中的SystemInit函数来完成的。
以下是startup_LPC17xx.s中的代码实现。
- 初始化堆栈,堆顶指针设置为__initial_sp,栈顶指针设置为__heap_limit
Stack_Size EQU 0x00000200
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
- 初始化中断向量表,中断向量表里面存储的都是指针类型的变量,除了第一个变量存储的是初始堆栈指针以外,其他的变量都是对应的中断响应函数的函数指针。
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WDT_IRQHandler ; 16: Watchdog Timer
DCD TIMER0_IRQHandler ; 17: Timer0
DCD TIMER1_IRQHandler ; 18: Timer1
DCD TIMER2_IRQHandler ; 19: Timer2
DCD TIMER3_IRQHandler ; 20: Timer3
DCD UART0_IRQHandler ; 21: UART0
DCD UART1_IRQHandler ; 22: UART1
DCD UART2_IRQHandler ; 23: UART2
DCD UART3_IRQHandler ; 24: UART3
DCD PWM1_IRQHandler ; 25: PWM1
DCD I2C0_IRQHandler ; 26: I2C0
DCD I2C1_IRQHandler ; 27: I2C1
DCD I2C2_IRQHandler ; 28: I2C2
DCD SPI_IRQHandler ; 29: SPI
DCD SSP0_IRQHandler ; 30: SSP0
DCD SSP1_IRQHandler ; 31: SSP1
DCD PLL0_IRQHandler ; 32: PLL0 Lock (Main PLL)
DCD RTC_IRQHandler ; 33: Real Time Clock
DCD EINT0_IRQHandler ; 34: External Interrupt 0
DCD EINT1_IRQHandler ; 35: External Interrupt 1
DCD EINT2_IRQHandler ; 36: External Interrupt 2
DCD EINT3_IRQHandler ; 37: External Interrupt 3
DCD ADC_IRQHandler ; 38: A/D Converter
DCD BOD_IRQHandler ; 39: Brown-Out Detect
DCD USB_IRQHandler ; 40: USB
DCD CAN_IRQHandler ; 41: CAN
DCD DMA_IRQHandler ; 42: General Purpose DMA
DCD I2S_IRQHandler ; 43: I2S
DCD ENET_IRQHandler ; 44: Ethernet
DCD RIT_IRQHandler ; 45: Repetitive Interrupt Timer
DCD MCPWM_IRQHandler ; 46: Motor Control PWM
DCD QEI_IRQHandler ; 47: Quadrature Encoder Interface
DCD PLL1_IRQHandler ; 48: PLL1 Lock (USB PLL)
- 中断响应函数
芯片启动的时候主要是Reset_Handler的中断响应函数在起作用。该函数会先调用system_LPC17xx.c中的函数对系统时针等进行初始化,然后跳转进入main()函数执行C语言代码。到此,芯片启动程序执行完毕,跳转到main()函数中的应用。</br>
- EXPORT Reset_Handler [WEAK]
这条语句中的[weak]告诉编译器,如果用户没有实现对应的中断响应函数的话就将这段代码当做该函数的实现来进行编译连接,如果用户实现了自己的中断响应函数,那么这段对应的汇编语言代码就不算数了。这里的作用优点类似于重载或者面向对象中的虚函数的概念。但是由于C语言中没有重载方法这种语法,所以在外边的C语言函数的实现也只能实现一次,并不能使用这种方法来模拟重载方法的实现。
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
; ……
2. RT-Thread系统启动代码
- main函数
Boot Loader文件执行完成之后程序跳转到main函数。RT-Thread的main函数只干了两件事,关中断和启动RT-Thread。具体的系统启动过程都在rtthread_startup函数中执行。
int main(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
/* startup RT-Thread RTOS */
rtthread_startup();
return 0;
}
- 系统启动函数rtthread_startup