RT-Thread内核实现(环境配置:M4启动文件 时钟文件注释)
目录
RT-Thread内核实现(环境配置:M4启动文件 时钟文件注释)
任务一:看见各个文件夹能够知道里面各放的什么文件 实现了什么功能
1.2 Manage Run-Time Environment
1.1 新建本地工程文件夹
任务一:看见各个文件夹能够知道里面各放的什么文件 实现了什么功能
1.2 Manage Run-Time Environment
1.2.1启动文件和时钟文件注释
参见博文:https://www.cnblogs.com/mddblog/p/4920063.html
对启动文件的理解:启动文件中做了些什么事?
A:启动文件由厂家提供,主要是配置相应版本CPU的运行环境,进行了 栈 堆 异常向量表 中断服务函数 复位中断 用户堆栈初始化(将标号等堆栈地址传递给库函数)
AREA:
告诉汇编器分配一个代码段或者数据段 可以选用多个参数(参考网络资料),这里的几个参数是段名为STACK,NOINIT内容不进行初始化或者初始化为0,READWRITE可以读写,ALIGN=3表示8KB对齐(对齐可以提高CPU访问的效率)*/
SPACE:
SPACE和DCD的功能类似,SPACE申请一片内存空间,DCD申请一个字(32bit)的内存空间。
SPACE和DCD的区别在于,SPACE申请空间但不赋初值,DCD申请一个字的空间,并赋初值。标号1 DCD 标号2 : 在标号1的地址分配一个字的空间 这个空间的内容是 标号二(地址)
用于分配一定大小的内存空间,单位为字节。这里指定大小等于 Stack_Size。
栈:
栈的作用是用于局部变量,函数调用,函数形参等的开销,栈的大小不能超过内部SRAM 的大小。如果编写的程序比较大,定义的局部变量很多,那么就需要修改栈的大小。如果某一天,你写的程序出现了莫名奇怪的错误,并进入了硬 fault 的时候,这时你就要考虑下是不是栈不够大,溢出了。
Stack_Mem 和 __initial_sp 暂时还不知道作用 但可以确定是两个标号 可能是后续 main函数会调用。标号__initial_sp 紧挨着 SPACE 语句放置,表示栈的结束地址,即栈顶地址,栈是由高向低生长的。
堆:
开辟堆的大小为 0X00000200(512 字节),名字为 HEAP, NOINIT 即不初始化,可读可写, 8(2^3)字节对齐。 __heap_base 表示对的起始地址, __heap_limit 表示堆的结束地址。堆是由低向高生长的,跟栈的生长方向相反。
堆主要用来动态内存的分配,像 malloc()函数申请的内存就在堆上面。这个在 STM32里面用的比较少。
__heap_base写在分配地址之前所以是堆基地址 然后SPACE过后 标号 __heap_limit是结束地址 后续需要补充哪里用到(用户堆栈初始化)
PRESERVE8
THUMB
PRESERVE8: 指定当前文件的堆栈按照 8 字节对齐。
THUMB:表示后面指令兼容 THUMB 指令。 THUBM 是 ARM 以前的指令集, 16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集, THUMB-2 是 32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超集。
在__Vectors 向量表这个地址定义了一串连续的空间 这些空间里面放着 各种中断异常向量对应的地址(也就是函数名)
PROC:
定义了子程序
main PROC
main ENDP 成对出现 可以利用标号进入子程序 退出子程序采用 BX LR 如果没有异常状态 LR中保存的就是上下文环境
Stack_Size EQU 0x00000400
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 0x00000C00
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__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 ; 0: Watchdog Timer
DCD RTC_IRQHandler ; 1: Real Time Clock
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
DCD MCIA_IRQHandler ; 4: MCIa
DCD MCIB_IRQHandler ; 5: MCIb
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
DCD UART4_IRQHandler ; 9: UART4 - not connected
DCD AACI_IRQHandler ; 10: AACI / AC97
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
DCD ENET_IRQHandler ; 12: Ethernet
DCD USBDC_IRQHandler ; 13: USB Device
DCD USBHC_IRQHandler ; 14: USB Host Controller
DCD CHLCD_IRQHandler ; 15: Character LCD
DCD FLEXRAY_IRQHandler ; 16: Flexray
DCD CAN_IRQHandler ; 17: CAN
DCD LIN_IRQHandler ; 18: LIN
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
DCD 0 ; 20: Reserved
DCD 0 ; 21: Reserved
DCD 0 ; 22: Reserved
DCD 0 ; 23: Reserved
DCD 0 ; 24: Reserved
DCD 0 ; 25: Reserved
DCD 0 ; 26: Reserved
DCD 0 ; 27: Reserved
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
DCD 0 ; 29: Reserved - CPU FPGA
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
//先去执行系统初始化 执行完返回 然后去执行 main
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT WDT_IRQHandler [WEAK]
EXPORT RTC_IRQHandler [WEAK]
EXPORT TIM0_IRQHandler [WEAK]
EXPORT TIM2_IRQHandler [WEAK]
EXPORT MCIA_IRQHandler [WEAK]
EXPORT MCIB_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT UART2_IRQHandler [WEAK]
EXPORT UART3_IRQHandler [WEAK]
EXPORT UART4_IRQHandler [WEAK]
EXPORT AACI_IRQHandler [WEAK]
EXPORT CLCD_IRQHandler [WEAK]
EXPORT ENET_IRQHandler [WEAK]
EXPORT USBDC_IRQHandler [WEAK]
EXPORT USBHC_IRQHandler [WEAK]
EXPORT CHLCD_IRQHandler [WEAK]
EXPORT FLEXRAY_IRQHandler [WEAK]
EXPORT CAN_IRQHandler [WEAK]
EXPORT LIN_IRQHandler [WEAK]
EXPORT I2C_IRQHandler [WEAK]
EXPORT CPU_CLCD_IRQHandler [WEAK]
EXPORT SPI_IRQHandler [WEAK]
WDT_IRQHandler
RTC_IRQHandler
TIM0_IRQHandler
TIM2_IRQHandler
MCIA_IRQHandler
MCIB_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
UART3_IRQHandler
UART4_IRQHandler
AACI_IRQHandler
CLCD_IRQHandler
ENET_IRQHandler
USBDC_IRQHandler
USBHC_IRQHandler
CHLCD_IRQHandler
FLEXRAY_IRQHandler
CAN_IRQHandler
LIN_IRQHandler
I2C_IRQHandler
CPU_CLCD_IRQHandler
SPI_IRQHandler
B .
ENDP
ALIGN
; User Initial Stack & 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 PROC
LDR R0, = Heap_Mem//堆底指针
LDR R1, =(Stack_Mem + Stack_Size)//栈顶指针
LDR R2, = (Heap_Mem + Heap_Size)//堆顶指针
LDR R3, = Stack_Mem//栈底指针
BX LR
ENDP
ALIGN
ENDIF
END
时钟文件配置了默认是中为25MHZ
#define XTAL ( 5000000U) /* Oscillator frequency */
#define SYSTEM_CLOCK (5 * XTAL)//25MHZ