当前的嵌入式应用程序开发过程里, 并且 C 语言成为了绝大部分场合的最佳选择。 如此 一来 main 函数似乎成为了理所当然的起点——因为 C 程序往往从 main 函数开始执行。但 一个经常会被忽略的问题是:微控制器(单片机)上电后,是如何寻找到并执行 main 函数 的呢? 在讨论STM32微控制器的启动过程时,首先需要了解嵌入式系统中程序启动的基本原理。嵌入式系统中的程序启动不同于通用计算机系统,其启动过程需要遵循特定的硬件和软件协议。在嵌入式系统中,由于资源限制,启动程序(Bootloader)是必不可少的组件之一。 C语言因其高效的性能和简洁的表达方式,在嵌入式开发中广泛使用,大多数嵌入式程序都是用C语言编写的。不过,问题在于C语言编译器在编译程序时会根据优化需求动态地为变量和函数分配内存地址,因此main函数的位置并不是固定的。这就引出了启动文件(Bootloader)的重要性,它负责初始化系统并找到main函数的入口点来启动主程序。 在讨论STM32的启动过程之前,先梳理一下ARM架构中不同内核的启动方式变化。传统的ARM7/ARM9架构在复位后CPU会直接从存储空间的绝对地址0x000000取指令执行复位中断服务程序。而Cortex-M3架构则不同,它的启动方式更为灵活。Cortex-M3允许中断向量表可以被配置到SRAM区或FLASH区,也可以配置到内置的Bootloader区域。为了适应这种变化,Cortex-M3的启动过程需要将堆顶指针放在起始地址,紧接着第二个地址存放复位中断入口向量地址,复位后,CPU会从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。 接下来,基于STM32的启动文件“stm32f10x_vector.s”来看具体是如何实现启动过程的。该文件首先定义了堆栈和堆的大小。在ARM体系结构中,堆栈是存储程序运行中临时数据的重要区域。启动文件中也包含了中断向量的定义,这些中断向量包括异常中断向量和硬件中断向量。异常中断向量处理非屏蔽中断(NMI)、硬fault、内存管理异常、总线fault、使用fault以及SVC调用等。硬件中断向量则涉及到各种外设中断,例如窗口看门狗(WWDG)、电源电压监测(PVD)、时钟安全系统(CSS)、实时时钟(RTC)等。 在STM32启动过程中,复位后,CPU会立即执行一个初始化堆栈指针的指令,而堆栈的大小是由编译时指定的。接着,启动文件中会定义中断向量表,CPU从中读取中断向量信息,用于引导后续的中断处理流程。中断向量表的初始化通常涉及到一系列的跳转指令,用于将各种中断事件与相应的中断服务程序相联系。 简而言之,STM32的启动过程涉及以下几个关键步骤: 1. 初始化堆栈指针。 2. 设置中断向量表,确保CPU能够在响应中断时跳转到正确处理程序。 3. 设置堆栈大小和堆的大小。 4. 配置其他必要的硬件特性,如时钟系统。 5. 完成必要的系统初始化后,跳转到main函数,开始执行用户程序。 STM32微控制器通过启动文件负责初始化硬件,设置内存,配置中断向量表,并最终启动用户程序。通过上述步骤,开发人员可以不必担心启动过程的复杂性,而专注于主程序的开发。同时,随着技术的发展,新一代Cortex内核架构相比于老一代架构,在启动方式上做了不少改进,简化了开发流程,提高了系统性能。
剩余7页未读,继续阅读
- 粉丝: 32
- 资源: 27
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助