欢迎来到查IC网

从芯片架构到stm32

来源:互联网   2022-07-18 阅读:49

一.stm32的发展历程
1.芯片领域三大架构

和stm32有啥关系?别急!

 

2.ARM架构发展历程

注:

1>ARM公司在经典的ARM11以后的产品改用cortex命名,并分为A,R和M三类(针对不同市场需求),cortex系列属于ARMv7架构,ARMv7架构定义了三大分工明确的系列:“A”系列面向尖端的基于虚拟内存的操作系统和用户应用;“R”系列针对实时系统;“M”系列对微控制器。我们所用的stm32就属于M系列

2>以stm32F103为例,就是属于ARMv7架构,cortex-M系列下的M3核

3.ST公司及产品线

上面我们也说了,ARM公司只负责设计不负责生产芯片。stm32是ST公司生产的芯片。

简介:

意法半导体(ST)集团于1987年成立,是由意大利的SGS微电子公司和法国Thomson半导体公司合并而成。1998年5月,SGS-THOMSON MICroelectronics将公司名称改为意法半导体有限公司。

产品线:

二.ARM处理器框图

注:流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器的效率和吞吐率。简单来说,执行某条指令至少要通过取指、译码、执行三个步骤。

1.第一周期,PC指向指令1,此时指令1进入流水线取指阶段

2.第二周期,PC指向指令2,此时进入译码阶段,同时取出指令2

3.第三周期,PC指向指令3,此时进入执行阶段,同时指令2进入译码阶段,指令3取指

4.第四周期,指令1执行完成,指令2和三同时推进一级,开始指令4取指。。

就想水一样,一级级推进。

三.Stm32 存储器映射(详细地址可查看stm32 datasheet)

四.stm32编译流程
在我们平时stm32的开发中,一般都是使用keil和IAR等集成开发环境,整个的编译过程其实我们并不理解,一些配置也是按照流程进行配置,一些参数为什要这么配置?一些文件为什么要添加?其实有时我们是并不太清楚的。

这里先说一下,stm32的一个编译下载过程。

我们的平时开发中,可能就是写好.c文件,点下编译后,生成了.hex文件,然后通过j-flash将程序下载到芯片中。

那么图中的.s文件,.ld文件我们有用到吗??用的什么编译工具链。

 

1.其实我们在做芯片移植的时候,一般还要更改一个.s文件,它就是启动文件,下面一会说启动流程的时候详细说。

它长这样。

2. .ld文件是链接脚本,用来将多个.o链接起来的,我们在建工程后会有默认的链接脚本。在keil中也可以进行更改

Project -> Options for Target ... -> linker

3.我们的编译工具链也是可以更改的,

Project -> Manage-> Components ... -> Folders/Extensions

五.stm32上电启动流程
我们正常在开发的时候,都是从main函数开始进行编程的,但是上电是从main函数开始执行的吗?答案当然是否定的。

 

1.STM32三种启动方式

STM32有三种启动模式,通过设置BOOT0和BOOT1的引脚电平状态,来选择复位后的启动模式。

需要注意的是STM32上电复位以后,代码区都是从0x00000000开始的,三种启动模式只是将各自存储空间的地址映射到0x00000000中。

1)从Flash启动,将Flash地址0x08000000映射到0x00000000,这样启动以后就相当于从0x08000000开始的,这是我们最常用的模式;

2)从SRAM启动,将SRAM地址0x20000000映射到0x00000000,这样启动以后就相当于从0x20000000开始的,用于调试;

3)从系统存储器启动,将系统存储器地址0x1FFFF000映射到0x00000000,这样启动以后就相当于从0x1FFFF000开始执行的,值得注意的是这个系统存储器里面存储的其实是STM32自带的Bootloader代码,这其实是一个官方的IAP,它提供了可以通过UART1接口将用户的代码下载到Flash中的功能,下载完以后再切换到从Flash中启动就可以正常运行了。

 

注:这里其实有个不太好理解的点。

我们在STM32的Flash在MDK里被设置为起始地址0x08000000,而CM3手册规定芯片复位时要从0x00000000地址开始取出中断向量。是不是我们可以将地址改到0地址呢??这样问题不就解决了。

答案是不行的,STM32设计的Flash起始地址是在0x0800 0000位置开始的。全部代码都只能从这里开始存储。

CM3中规定上电后CPU是从0地址开始执行,但是这里中断向量表却被烧写在0x0800 0000地址里,那启动时不就找不到中断向量表了?既然CM3定下的规矩是从0地址启动,SMT32当然不能破坏ARM定下的“规矩”,所以它做了一个启动映射的过程。

当选择从主Flash启动模式后,芯片一上电,Flash的0x0800 0000地址被映射到0地址处,不影响CM3内核的读取,所以这时的CM3既可以在0地址处访问中断向量表,也可以在0x0800 0000地址处访问中断向量表,而代码还是在0x0800 0000地址处存储的。

 

2.以FLASH启动的方式从上电到main函数之间的这段时间都做了什么??

直接打开我们的startup_stm32f10x_md.s看一下就知道了,它也给了相关描述。

总的执行流程如下所示:

1)第一步是硬件设置SP、PC,设置中断向量表

初始化堆栈指针SP=_initial_sp

_initial_sp的值是怎么得到的呢?这是根据STM32的SRAM分配规则计算的,SRAM从规定的地址开始分别存储已初始全局和静态变量、未初化全局和静态变量、堆、栈,其中变量的长度是你写程序后就固定了,堆和栈的长度则是在启动代码中定义的,那么把它们加起来就会得于_initial_sp的值,编译后,_initial_sp就被替代为上述计算好的地址。

初始化PC指针=Reset_Handler

 

设置中断向量表:

下面是.s文件中部分截图:(stm32的有哪些异常可以查看数据手册)

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

这里的起始地址是0x00000000而不是0x80000000上面已经说明。

程序在用户Flash上的结构如下图所示:

初始化数据段       .data

未初始化数据段      .bss 

加载数据段和初始化栈的参数(各4个)

2)第三步是设置系统时钟

我们发现运行到了SystemInit,在项目文件的system_stm32f10x.c里面可以找到SystemInit函数,也就是初始化系统时钟了。

 

3)第三步是__main(初始化用户堆栈)

到这里大家可能会以为已经到了main函数了,其实不是这样的。___main和main是不一样的,我们寻找这个___main会发现找不到,startup文件里面没有,map文件里面也没有。其实它是在MDK自带的库里面了,主要的功能是软件加载.data.bss并初始化栈区。

注:第一步中只是将_initial_sp值存入了SP寄存器,只是一个栈顶指针,但堆的大小和栈的大小并没有初始化,所以在_main中要把在启动文件中定义好的值传给C库进行堆栈大小的初始化。无论是带系统的,还是裸机程序,都要管理堆栈的大小,这就是会产生堆栈溢出的原因。

 

4)在执行到___main的最后就跳转到了C文件的main函数了。


免责声明:
以上相关内容来自互联网公开信息分享;如涉及内容、版权、图片等问题,请联系我们。会第一时间删除!

查IC网

服务热线

400-861-9258

客服企业微信