系列文章目录
1.连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下
5.Keil配置使用(使用 RASC 生成 Keil 工程)
6.Keil配置使用(使用 RASC 生成 Keil 工程)
文章目录
前言
今天学习理论知识,启动文件详解。本文参考野火官方文件。
一、启动文件是什么?
启动文件是系统上电复位后执行的第一个程序。
初始化堆栈。
使能FPU(float-point unit,即浮点单元)。
定位中断向量表。
配置系统时钟。
启用CORTEX-M33栈监视器。
初始化C语言运行环境。
初始化变量SystemCoreClock,这个变量存放的是处理器时钟的频率。
初始化用于触发NVIC中断的ELC(Event Link Controller)事件。
初始化IO口
二、启动文件的详解
1.复位程序
如stm32的复位程序:
void Sys_Soft_Reset(void)// 软重启 { SCB->AIRCR =0X05FA0000|(u32)0x04; } void SoftReset(void) { __set_FAULTMASK(1); // 关闭所有中端 NVIC_SystemReset(); // 复位 }
如RA2E1的复位程序:
void Reset_Handler (void) { /* 使用BSP对系统进行初始化. */ SystemInit(); /* Call user application. */ main(); while (1) { /* Infinite Loop. */ } }
这是系统上电或复位后执行的第一个程序,使用BSP对系统进行初始化,随后通过main函数进入用户代码。 BSP负责使MCU从复位状态进入到用户的应用程序。在到达用户的应用程序之前,BSP设置栈、堆、时钟、中断、C语言运行环境和堆栈监视器。
2.栈区初始化
/* Main stack */
static uint8_t g_main_stack[BSP_CFG_STACK_MAIN_BYTES + BSP_TZ_STACK_SEAL_SIZE]
BSP_ALIGN_VARIABLE(BSP_STACK_ALIGNMENT) //宏展开后为“__attribute__((aligned(8)))”
BSP_PLACE_IN_SECTION(BSP_SECTION_STACK); //宏展开后为“__attribute__((section( ".stack"))) __attribute__((__used__))”
栈是一种先进后出的内存结构,存放函数的参数值、返回值、局部变量等,在程序运行过程中实时加载和释放。 如果代码中使用的局部变量和函数嵌套较多,则需要增加栈区的大小,需要注意的是, 栈区分配大小不能超过RAM的大小。
3.堆区初始化
/* Heap */
#if (BSP_CFG_HEAP_BYTES > 0) //若分配堆区大小为0则不进行初始化
BSP_DONT_REMOVE static uint8_t g_heap[BSP_CFG_HEAP_BYTES]
BSP_ALIGN_VARIABLE(BSP_STACK_ALIGNMENT) //宏展开后为“__attribute__((aligned(8)))”
BSP_PLACE_IN_SECTION(BSP_SECTION_HEAP); //宏展开后为“__attribute__((section(".heap"))) __attribute__((__used__))”
#endif
堆没有栈那样先进后出的顺序,用于动态内存分配,一般由程序员使用malloc和free进行分配和释放。 BSP_CFG_HEAP_BYTES用于配置堆区大小,当这个宏定义为0,则不对堆区进行初始化。 由于MCU中可用的片上SRAM相对较少,且缺乏内存保护,这意味着必须非常小心地控制堆的使用,以避免内存泄漏、溢出和试图过度分配。 因此默认堆区大小被设置为0。如果用户需要(例如一些C标准库函数需要使用堆), 可以在FSP Configuration中“BSP”属性栏的“RA Common”中通过修改“Heap size”来设置堆区大小。
4.中断向量表初始化
/* Vector table. */
BSP_DONT_REMOVE const exc_ptr_t __Vectors[BSP_CORTEX_VECTOR_TABLE_ENTRIES]
BSP_PLACE_IN_SECTION(BSP_SECTION_FIXED_VECTORS) =
{
(exc_ptr_t) (&g_main_stack[0] + BSP_CFG_STACK_MAIN_BYTES), /* Initial Stack Pointer */
Reset_Handler, /* Reset Handler */
NMI_Handler, /* NMI Handler */
HardFault_Handler, /* Hard Fault Handler */
MemManage_Handler, /* MPU Fault Handler */
BusFault_Handler, /* Bus Fault Handler */
UsageFault_Handler, /* Usage Fault Handler */
SecureFault_Handler, /* Secure Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* SVCall Handler */
DebugMon_Handler, /* Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
};
宏“BSP_PLACE_IN_SECTION(BSP_SECTION_FIXED_VECTORS)”展开后为“__attribute__((section(“.fixed_vectors”))) __attribute__((__used__))”。 意为将表放到名为“.fixed_vectors”的输入段中,并且即使不被使用,编译器也不会警告。
5. SystemInit()
void SystemInit (void)
{
#if __FPU_USED
/* Enable the FPU only when it is used.
* Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) */
/* Set bits 20-23 (CP10 and CP11) to enable FPU. */
SCB->CPACR = (uint32_t) CP_MASK;
#endif
#if BSP_TZ_SECURE_BUILD
uint32_t * p_main_stack_top = (uint32_t *) __Vectors[0];
*p_main_stack_top = BSP_TZ_STACK_SEAL_VALUE;
#endif
.............. //由于篇幅所限,省略中间代码
/* Call Post C runtime initialization hook. */
R_BSP_WarmStart(BSP_WARM_START_POST_C);
/* Initialize ELC events that will be used to trigger NVIC interrupts. */
bsp_irq_cfg();
/* Call any BSP specific code. No arguments are needed so NULL is sent. */
bsp_init(NULL);
}
这是MCU进入Reset_Handler后执行的第一个函数,正如函数的字面意思,用于初始化MCU和运行环境, 运行完这段代码后将由main进入用户的hal_entry函数,由于代码较长,下面将分为几个部分对代码进行分析。
6.使能FPU
#if __FPU_USED
/* Enable the FPU only when it is used.
* Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) */
/* Set bits 20-23 (CP10 and CP11) to enable FPU. */
SCB->CPACR = (uint32_t) CP_MASK;
#endif
FPU(Float-Point Unit)支持单精度加、减、乘、除、乘、累加、平方根运算。它还提供了定点和浮点数据格式以及浮点常量之间的转换的命令。
总结
对启动文件进行了一个整体的了解,感谢野火官方珍贵的资料,持续学习和努力,坚持不懈。