联系方式

    深圳市英瑞尔芯科技有限公司

    电话:

    186 6591 0262

    E-mail:

    sally@szinter.com.cn

    地址:

    深圳市福田区振华路现代之窗A座7B

STM32F0单片机快速入门三: MCU启动过程

发布时间:2021-12-29 08:30:00

来源:http://www.szinter.com.cn/news745391.html

1.MCU 代码如何启动

最先大家必须回应一个问题,什么叫 Startup Code,什么是 Bootloader?由于总见到有同学们混合使用这两个定义。

Bootloader 可以译为正确引导程序流程。初期的单片机是沒有 Bootloader 这类定义的。如大伙儿了解的 MCS51,最开始集成ic内是不可以储存代码的,必须外挂软件EPROM,便是下边这类带个小窗户的储存器。擦掉 EPROM 中的代码必须用紫外线照射数分钟才行。

之后发生了 Flash 这类可电可读写的储存器,并集成化在了单片机內部。但在出厂的情况下单片机的程序流程储存区依然是一片空白的,没有代码。客户编译程序后,在线下载到单片机后才可以运作。那麼在商品发送给客户后,假如看到有Bug怎么办呢?就得用开发板把新代码再次在线下载一次。这着实是有点不便,尤其是假如顾客间距很远得话。因此有聪慧的程序员想了一个方法,写一小段独特的代码放到程序流程里,这一段代码可以根据一定方法,例如用功能键开启进到运作,它可以根据串口通信(初期的 PC 串口通信是标准配置)接受新的代码并载入Flash,进而在沒有硬件配置开发板的情形下也可以进行代码的升级。

程序员们也是当代历史时间前行的关键驱动力啊!

之后,有集成ic生产商把这类代码在出产时就干固在集成ic里,巨大的便捷了代码在线下载和程序流程升级。STM32F030內部就干固了Bootloader。在我们把一个管脚 BOOT0 拉升的与此同时,再次给集成ic通电或复位,便会开启Boootloader进到运作。这时大家根据单片机的串口通信就可以把新程序流程发给单片机,推送完后把 BOOT0 降低,再复位单片机,新程序流程便会运作起來。

Startup Code 可以译为运行代码。单片机通电或复位后最开始实行的一段代码。一般关键会进行堆栈指针的设定,复位空间向量的获得和载入,随后复位自变量,最终自动跳转到客户代码。在详尽看运行代码以前,大家先看一下 STM32F030 的内存映射。

2.STM32F030内存映射(Memory Map)

下边是 STM32F030 的内存映射,其他集成ic会由于 Flash,SRAM 室内空间尺寸不一样而略有不同。

由于是32位机,因此可寻址方式从 0x0000_0000 到 0xFFFF_FFFF 的一共 4G 室内空间。

这也是选用32位机的益处,详细地址室内空间够用。并不像8位或16位机,非常容易发生详细地址室内空间不足用,总是必须用 Page 来间接性寻址方式。

大家从低详细地址到高地址逐段看一下:

0x0000 0000 Virtual memory

这一段详细地址室内空间,会由于不一样的 BOOT 方式而投射到不一样的物理内存。

当集成ic复位,或从 Standby 功耗低方式唤起时:

假如管脚 BOOT0 是被降低的,将投射到 Flash memory。这也是最常见的代码运行模式;

假如管脚 BOOT0 是被拉升的,且nBOOT1为 1 ,将投射到 System memory。进入bootloader方式;

假如管脚 BOOT0 是被拉升的,且nBOOT1为 0 ,将投射到 SRAM。

注:nBOOT1 为Flash存储器中的一位,客户缘何设定。

0x0800 0000 Flash memory

储放客户代码

0x1FFF EC00 System memory

储放 bootloader, 片内集成化温度感应器的校准数据信息,和片内集成化工作电压参照的校准数据信息

这种代码和数字是在加工厂干固好的。

0x2000 0000 SRAM

储放客户自变量,堆(Heap)和栈(Stack)。还可以把代码载入到 SRAM 运作。

0x4000 0000 Pheriperals

集成ic集成化的外接设备,如 USART, SPI, GPIO等的寄存器地址在这里一地区。

0xE000 0000 Cortex-M0 internal pheriperals

M0核心的外接设备投射到此地区。如 systick (System Tick),NVIC,Debug Registers。这种存储器在集成ic指南里是查不出的,必须到 ARM 的指南里搜索。

3.运行代码(Startup Code)

大家就以下边这一非常简单的GPIO旋转代码为例子:

STM32Cube_FW_F0_V1.11.0ProjectsSTM32F030R8-Nucleo

ExamplesGPIOGPIO_IOToggleMDK-ARMProject.uvprojx

把此工程项目在线下载到单片机后,用程序调试观查下边2个详细地址的內容:

大家会发觉0x0000_0000逐渐的地区, 和0x0800_0000逐渐的地区,內容完全一致。这表明 Flash 区的內容投射到了 0x0000_0000起止的这一段详细地址地区。

留意STM32F030应用的是小端模式(Litlle Edian)。

有别于 MCS51 在 0x0000 放的是复位空间向量,STM32F030 也有其他 ARM 集成ic在零详细地址储放的是原始堆栈指针详细地址。

0x0000 0000: (0x2000 0428) 原始堆栈指针

0x0000 0004: (0x0800 00C9) 复位空间向量,通电或复位后最开始加加载PC

注:单片机通电或复位后,堆栈指针复位和 PC 默认值的载入一直从详细地址 0x0000_0000,0x0000_0004获得。在上面这类客户方式下,具体是以 Flash 区的 0x0800_0000,0x0800_0004 获得的。

我们可以根据程序调试观查一下集成ic复位后 M0 核心的存储器:

仔细的同学们这时很有可能发觉了一个问题。

堆栈指针 SP 的具体内容和前边储存器中的內容是对的上的。可是 PC 里的內容仿佛不一样啊?PC 里的值是 0x0800_00C8,储存器里我也是 0x0800_00C9 啊!

这儿涉及到了 ARM 管理体系里的二种运行状态 ARM 和 Thumb。ARM 情况下实行32位命令,Thumb情况下实行16位命令。那麼怎样在这彼此之间转换呢,一个办法便是靠自动跳转详细地址的最少位(Bit0), 当 Bit0 设为 1 时进到 Thumb 情况,当 Bit0 设为 0 时进到 ARM 情况。

针对单片机而言,16位的 Thumb 命令就充足了,并且16位命令比32位指令能节约储存器室内空间。因此 M0 核心只适用 Thumb 命令。

到这儿大家就可以了解复位空间向量为什么是 0x0800_00C9 了。

下面大家看来复位空间向量 0x0800_00C8 偏向的第一条命令:

单片机即将实行的第一条命令 0x4804,是啥意思呢?

先说结果:它便是下面的图中,单片机复位后鼠标光标偏向的这一条命令:

LDR R0, =SystemInit

在这儿详尽解释一下 0x4804 这条命令:

它相匹配的序列号是 0 ** 0000000100

Bit15 to Bit11 (01001)为LDR(literal)命令,既从PC偏位详细地址取数据信息送至存储器Rt。

Bit10 to Bit8 (000)表明目地存储器Rt为 R0

Bit7 to Bit0 (00000100)表明相对性于 PC 的偏移为 0b10000,既0x10。

留意PC的值是当今详细地址 4。

那麼从 0x080000C8 0x4 0x10 = 0x080000DC 取下数据信息 0x0800092D 送至存储器 R0。此详细地址是 SystemInit( )函数公式的详细地址。下一条句子 BLX R0 便是读取此系统软件复位函数公式。

SystemInit( ) 这一变量在 system_stm32f0xx.c 这一文档里,关键进行系统软件钟表的复位。可以点进来看一下实际的內容。

函数公式 SystemInit( ) 实行完以后,程序流程自动跳转回家,获得 __ ** in( ) 函数公式的详细地址,自动跳转到 __ ** in() 函数公式实行。必须留意,这一函数公式并不是大家客户代码里的 ** in( ) 函数公式。

__ ** in() 函数是 Keil 的库给予的,大家看不见代码,它关键进行自变量的复位。这儿无需太担心,假如想进一步细究可以看一下 ARM Compiler User Guide 的 Reset and initialization 这一节。

__ ** in() 函数公式实行完,基本上工作中就做完了,这才自动跳转到客户代码的 ** in( ) 函数公式。

参考文献:

STM32F030 Datasheet

STM32F030 Reference Manual

ARM Compiler User Guide

ARM®v6-M Architecture Reference Manual

热烈欢迎了解大家,微信公众平台:TopSemic

相关标签: