嵌入式系统——上电流程理解

  • MCU系统结构
  • 整体结构
  • 哈佛结构和冯诺依曼结构
  • 各部分间联系
  • CM3内核
  • 总线
  • 时钟
  • stm32上电过程
  • 1. 选择启动方式
  • 2. 根据复位中断向量表设置SP和PC
  • 3. 初始化系统时钟
  • 4. 软件设置SP


MCU系统结构

整体结构

因为学习的是STM32,所以按照手册进行理解。

哈佛结构和冯诺依曼结构

  1. 首先我们在编写代码的时候,可以将代码分为两部分,一部分是逻辑代码部分,另一部分是定义的变量,逻辑代码是不用改变的,而变量会改变,哈佛结构和冯诺依曼结构就是对于这个两部分代码的存储方式有着一些区别。
    冯诺依曼结构将程序存储器和数据存储器合并在一起的处理器架构设计,他的特点是使用同一个存储器,经由同一个总线传输。
    哈佛结构将程序指令存储和数据存储分开存储,在嵌入式编程中一般使用这种方式,因为可以只修改数据不用修改逻辑代码。
  2. STM32采用的就是这种哈佛结构
    它分为四个驱动单元和四个从动单元
    驱动单元:CM3,系统总线和数据总线,DMA
    从动单元: SRAM,FLASH,FSMA,AHB到APB的桥以及连接的所有设备。

可以从这个总线矩阵来看,它的前级是CM3和DMA,它的后级是从设备——也就是存储器以及各个外设控制器。

双mcu 架构 功能安全 mcu芯片的系统架构框图_双mcu 架构 功能安全

各部分间联系

CM3内核

双mcu 架构 功能安全 mcu芯片的系统架构框图_mcu_02


内核里面有NVIC嵌套中断向量控制器:ALU,寄存器组,内存保护单元,总线的内连接等。

NVIC:关于中断的内容可以看这一篇:

中断的概念与机制 寄存器组:其中寄存器组的R0-R12为通用寄存器。R13为堆栈指针寄存器,有2个寄存器,当时同一时间只能用一个,一个是主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程);另一个是进程堆栈指针(PSP):由用户的应用程序代码使用。

R14为连接寄存器,当呼叫一个寄存器,R14存储返回地址;R15是程序计数器PC。

其中还有特殊功能寄存器组:

  1. 程序状态字寄存器组(PSRs),记录ALU的标志。
  2. 中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)
    PRIMASK相当于中断总开关,关闭后只有NMI和硬fault才会响应;FAULTMASK打开后只有NMI才会响应;
  3. BASEPRI定义被屏蔽优先级的阈值。
  4. 控制寄存器(CONTROL):选择堆栈的指针和线程模式。

总线

Icode指令总线:和FLASH的接口相连,用于取指令,它不经过总线矩阵,不需要切换,速度更快。
Dcode数据总线:主要用来读取存储在SRAM和Flash里的数据。
哈佛结构在这里我理解为SRAM是处理变量和堆栈记录,而Flash是我们烧进去的代码,SRAM是由锁存器构成,掉电之后内容就会没有,而Flash相当于逻辑代码。
DMA总线:可以访问Flash,SRAM,数据寄存器,然后三者间交换数据并且不占用CPU。
而总线矩阵在这里协调CM3内核和DMA的竞争。
系统总线:也叫外设总线,连接CM3的内核和外设。AHB通过桥接的方式进行了分频,APB2为72HZ上面搭载着GPIO口,ADC,TIM1等外设,而APB1为36HZ,上面挂着串口,看门狗等慢速设备。

时钟

STM32F10x时钟源
HSI:(高速内部)RC振荡器,频率8MHz,精度不高
HSE:(高速外部)外接石英/陶瓷晶振(4MHz——16MHz)
LSI:(低速内部)RC振荡器,频率40KHz,LSI是作为看门狗时钟源和RTC时钟源而独立使用
LSE:(低速外部)外接晶振,32.768KHz石英晶振
PLL:锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz

多个时钟源是因为兼容不同速度的外设,有些高速,有些低速,不同的时钟对应不同的模块。

系统时钟SYSCLK可来源于三个时钟源:

  1. HSI振荡器时钟
  2. HSE振荡器时钟
  3. PLL时钟

系统时钟—>AHB分频器—>各个外设分频倍频器 —> 外设时钟的设置

stm32上电过程

1. 选择启动方式

STM32 上电复位后代码从0x00000000开始,选择不同的启动模式就是将不同的地址映射到0x00000000
从Flash启动,将0x80000000映射到0x00000000;
从系统存储器启动,一般是将stm32里带的Bootloader的代码映射到0x00000000,这个Bootloader就是将用户的代码通过串口下载到Flash,再从Flash启动;
从SRAM启动,将0x20000000映射到0x00000000。

2. 根据复位中断向量表设置SP和PC

假定从Flash启动

向量表的存储位置是可以设置的,通过 NVIC 中的一个重定位寄存器来指出向量表的地址。在复位后,该寄存器的值为 0。因此,在地址 0 处必须包含一张向量表,用于初始时的异常分配。

双mcu 架构 功能安全 mcu芯片的系统架构框图_学习_03


起始地址存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。

3. 初始化系统时钟

在复位中断函数中调用 SystemInit 函数,初始化时钟,配置中断向量表等。

4. 软件设置SP

在复位中断服务程序中会跳转__main函数,在这里面加载.data.bss,初始化栈区,在__main函数中调用C函数main。