stm32启动文件详解

合集下载

STM32启动文件详解

STM32启动文件详解

STM32启动文件详解(2012-07-28 11:22:34)转载▼分类:STM32标签:stm32启动在<<STM32不完全手册里面>>,用的是STM32F103RBT6,所有的例程都采用了一个叫STM32F10x.s的启动文件,里面定义了STM32的堆栈大小以及各种中断的名字及入口函数名称,还有启动相关的汇编代码。

STM32F10x.s是MDK提供的启动代码,从其里面的内容看来,它只定义了3个串口,4个定时器。

实际上STM32的系列产品有5个串口的型号,也只有有2个串口的型号,定时器也是,做多的有8个定时器。

比如,如果你用的STM32F103ZET6,而启动文件用的是STM32F10x.s的话,你可以正常使用串口1~3的中断,而串口4和5的中断,则无**常使用。

又比如,你TIM1~4的中断可以正常使用,而5~8的,则无法使用。

而在固件库里出现3个文件startup_stm32f10x_ld.sstartup_stm32f10x_md.sstartup_stm32f10x_hd.s其中,ld.s适用于小容量产品;md.s适用于中等容量产品;hd适用于大容量产品;这里的容量是指FLASH的大小.判断方法如下:小容量:FLASH≤32K中容量:64K≤FLASH≤128K大容量:256K≤FLASH;******************** (C) COPYRIGHT 2011 STMicroelectronics ******************** ;* File Name : startup_stm32f10x_hd.s;* Author : MCD Application Team;* Version : V3.5.0;* Date : 11-March-2011;* Description : STM32F10x High Density Devices vector table for MDK-ARM;* toolchain.;* This module performs:;* - Set the initial SP;* - Set the initial PC == Reset_Handler;* - Set the vector table entries with the exceptions ISR address;* - Configure the clock system and also configure the external;* SRAM mounted on STM3210E-EVAL board to be used as data;* memory (optional, to be enabled by user);* - Branches to __main in the C library (which eventually;* calls main()).;* After Reset the CortexM3 processor is in Thread mode,;* priority is Privileged, and the Stack is set to Main.;* 说明: 此文件为STM32F10x高密度设备的MDK工具链的启动文件;* 该模块执行以下操作:;* -设置初始堆栈指针(SP);* -设置初始程序计数器(PC)为复位向量,并在执行main函数前初始化系统时钟;* -设置向量表入口为异常事件的入口地址;* -复位之后处理器为线程模式,优先级为特权级,堆栈设置为MSP主堆栈;* <<< Use Configuration Wizard in Context Menu >>>; 首先对栈和堆的大小进行定义,并在代码区的起始处建立中断向量表,其第一个表项是栈; 顶地址,第二个表项是复位中断服务入口地址。

stm32启动文件详解及SystemInit函数分析

stm32启动文件详解及SystemInit函数分析
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
;__main函数由编译器生成,负责初始化栈、堆等,并在最后跳转到用户自定义的main()函数,来到C的世界。
Stack_Size EQU 0x00000400 ;//定义堆栈大小
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段 按8字节对齐 ;AREA 伪指令用于定义一个代码段或数据段 NOINIT:指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0
;链接器检查要求堆栈八字节对齐的任何代码是否仅由保持堆栈八字节对齐的代码直接或间接地调用。
PRESERVE8 ;//指示编译器8字节对齐
Байду номын сангаас THUMB ;//指示编译器以后的指令为THUMB指令
;中断向量表定义
; Vector Table Mapped to Address 0 at Reset
;中断函数仅仅实现了Reset_Handler,其他要么是死循环,要么仅仅定义了函数名称
;STM32被设置为从内部FLASH启动时(这也是最常见的一种情况),当STM32遇到复位信号后,

STM32固件库V3.5.0的CMSIS文件解析

STM32固件库V3.5.0的CMSIS文件解析

STM32固件库V3.5.0的CMSIS文件解析1.首先选择启动文件:根据自己所用芯片的型号,选择正确的启动文件。

例如选择STM32F107系列的处理器,我们就选择startup_stm32f10x_hd.s。

在这个文件里首先要定义自己堆栈的大小,根据自己的需要确定。

文件中已经定义好了中断向量的位置及堆栈的初始化操作。

/* Reset handler*/Reset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT __mainIMPORT SystemInitLDR R0, =SystemInitBLX R0LDR R0, =__mainBX R0ENDP通过上面的代码可以看到先执行SystemInit()函数在进入main()函数。

SystemInit()函数在文件system_stm32f10x.c中有定义。

2.stm32f10x.h:这个头文件包含了STM32的大部份定义:①定义了芯片的类型,例如:#define STM32F10X_CL②定义是否包含标准外设库,#defined USE_STDPERIPH_DRIVER③定义外部振荡器频率,#defined HSE_V ALUE上面的三个定义,最好在编译器选项中定义好,这样就不用修改stm32f10x.h文件,最好不要修改这个文件。

④采用枚举的方式定义中断号。

⑤包含core_cm3.h,system_stm32f10x.h。

#include "core_cm3.h"#include "system_stm32f10x.h"#include <stdint.h>⑥定义数据类型,例如:typedef uint32_t u32此外还定义了FlagStatus,ITStatus及ErrorStatus等。

⑦定义外设结构体,地址及用到的常量。

⑧包含stm32f10x_conf.h来配置外设。

stm32启动文件和汇编指令简析

stm32启动文件和汇编指令简析

stm32启动⽂件和汇编指令简析
以stm32fxxxx为例
⼀、启动⽂件,startup_stm32f40_41xxx.S
1.定义:启动⽂件由汇编填写,是系统上电复位后第⼀个执⾏的程序。

2.特征
(1)初始化堆栈指针SP=_initial_sp
(2)初始化PC指针=Reset_Handler
(3)初始化中断向量表。

(4)配置系统时钟。

(5)调⽤c库函数_main初始化⽤户堆栈,从⽽最终调⽤main函数去到c的内容。

⼆、汇编指令
启动⽂件使⽤ARM汇编指令汇总
EQU 给数字常量取⼀个符号名,相当于c语⾔define。

AREA 汇编⼀个新的代码段或数据段。

SPACE 分配内存空间。

PRESERVE8 当前⽂件堆栈需按照8字节对齐。

EXPORT 声明⼀个标号具有全局性,可被外部⽂件使⽤。

DCD 以字为单位分配内存,要求4字节对齐,并要求初始化这些内存。

PROC 定义⼦程序,与ENDP成对使⽤,表⽰⼦程序结束。

WEAK 弱定义,如果外部⽂件声明⼀个标号,则优先使⽤外部⽂件定义的标号,如果外部⽂件没有定义也不会出错。

要注意这个不是ARM 指令,是编译器的。

IMPORT 声明标号来⾃外部⽂件,跟c语⾔EXTERN关键字类似。

B 跳转到⼀个标志号。

STM32之启动文件详解

STM32之启动文件详解

STM32 之启动文件详解在嵌入式应用程序开发过程里,由于使用C 语言编程,基本很少涉及到机器底层寄存器的执行过程,一般都会直接在main 函数里开始写代码,似乎main 成为了理所当然的起点,尽管从C 程序的角度来看程序都是直接从main 函数开始执行。

然而,MCU 上电后,是如何寻找到并执行main 函数这一问题却很自然的被忽略了!事实上微控制器是无法从硬件上去定位main 函数的入口地址,因为使用C 语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,因此main 函数的入口地址在编译后便不一定是一个绝对地址。

MCU 上电后又是如何寻找到这个入口地址呢?以前接触无论是PIC、AVR、MSP430 或是51 过程中都没涉及到启动文件的配置,仅仅只有熔丝位或配置字是需要根据实际使用配置来设置,其实并非没有,而是由于大部分的开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main 函数开始进行应用程序的设计即可。

然而,但接触到嵌入内核比如Linux 系统移植过程bootloader 却是很重要也是必不可少的一个环节。

事实上,每一种微控制器,无论性能高下,结构简繁,价格贵贱都是必须有启动文件才能正常工作的,它的作用同bootloader 类似。

启动文件完成了微控制器从复位到开始执行main 函数中间这段时间的必要启动配置。

在STM32 中,如果是在MDK 下创建一个工程,一般都有提示是否加入Star up Code 文件,这个就是启动文件,这里有个误区,一般对于初学者来看,很容易误以为STM32F10x.s 这个启动文件是STM32 所有类型芯片的通用启动文件,因此也自然不会去理会它的作用,事实上,这个启动文件只是。

STM32启动文件的选择及宏定义及芯片型号更改IAP总结

STM32启动文件的选择及宏定义及芯片型号更改IAP总结

STM32启动文件的选择及宏定义及芯片型号更改IAP总结对于STM32芯片,启动文件主要包括以下几个部分:1.启动向量表:包含中断服务程序的地址信息,用于系统初始化和中断处理等功能。

2.中断服务程序:对中断进行处理的代码,包括系统初始化时的复位中断和其他外部中断。

3.系统初始化代码:完成芯片的初始化工作,包括时钟配置、外设初始化、堆栈初始化等。

在选择启动文件时,需要注意以下几点:1.芯片型号匹配:确保所选择的启动文件与使用的芯片型号兼容,以确保正常的系统初始化和中断处理。

2. 如需使用外部存储器:如果需要使用外部存储器,如外部Flash 或RAM,需要选择支持外部存储器的启动文件。

3. 如需使用操作系统:如果需要在系统中运行操作系统,如FreeRTOS或uc/OS等,需要选择对应操作系统的启动文件。

在启动文件中,还涉及宏定义的使用。

宏定义是一种预处理指令,用于在编译时替换特定的文本字符串。

在启动文件中,通常会使用宏定义来配置系统的时钟频率、中断向量表的起始地址等参数。

在更改芯片型号时1.切换器件描述文件:在工程文件中,需要将所使用的芯片型号对应的器件描述文件进行切换。

这个文件通常在项目设置中进行配置。

2.修改启动文件:将原有的启动文件替换为新的芯片型号所对应的启动文件。

3.更新宏定义:在新的启动文件中,需要确认并更新宏定义,以确保系统的配置和参数正确。

4.复查外设配置:在启动文件中,有可能包含对外设的初始化代码。

在更改芯片型号后,需要复查外设的配置和初始化。

总结起来,选择合适的STM32启动文件,需要根据所使用的芯片型号来进行选择,并注意更改宏定义和复查外设配置。

这样才能确保系统正常初始化和中断处理的功能。

STM32启动文件的选择及宏定义及芯片型号更改IAP总结(精)

STM32启动文件的选择及宏定义及芯片型号更改IAP总结(精)

STM32启动文件的选择及宏定义及芯片型号更改 IAP总结startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xxstartup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_hd_vl.s 大容量的STM32F100xxstartup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_ld_vl.s 小容量的STM32F100xxstartup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_md_vl.s 中容量的STM32F100xxstartup_stm32f10x_xl.s FLASH在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xxcl:互联型产品,stm32f105/107系列vl:超值型产品,stm32f100系列xl:超高密度产品,stm32f101/103系列ld:低密度产品,FLASH小于64Kmd:中等密度产品,FLASH=64 or 128hd:高密度产品,FLASH大于128在KEIL下可以在项目的选项C/C++/PREPROMCESSOR symbols的Define栏里定义,比如STM32F10X_CL也可以在STM32F10X.H里用宏定义#if !defined (STM32F10X_LD && !defined (STM32F10X_LD_VL && !defined (STM32F10X_MD && !defined (STM32F10X_MD_VL && !defined(STM32F10X_HD && !defined (STM32F10X_XL && !defined (STM32F10X_CL#define STM32F10X_HD#endif如果芯片更换,除了做如上所述的更改外,还需以下几步:第一步 system_stm32f10x.c的系统主频率,依实际情况修改#if defined (STM32F10X_LD_VL || (defined STM32F10X_MD_VL#define SYSCLK_FREQ_24MHz 24000000#else#define SYSCLK_FREQ_72MHz 72000000#endif另外外部时钟在文件:stm32f10x.h 依实际修改第二步定时器的参数依系统主时钟做适当修改第三步 flash地址misc.h中的NVIC_VectTab_Flash 0x08000000 要与KEIL选项target的IROM1的地址一致,如果是IAP程序,依ISP程序占用大小,APP的FLASH地址向后延,比如0X8002000,那么KEIL选项target的IROM1的地址也要就0x8002000,SIZE因为ISP占用了2000,所以就为0x40000-0x2000,即只能填写0X3E000第四步 ISP程序与APP程序连接----(这一步我还不明白意思,需要验证)打开 User 选项卡在 Run User Programs Before Build/Rebuild 中,勾选 Run#1,并在其中填入D:\Keil\ARM\BIN40\fromelf.exe --bin -o ./obj/Project.bin ./obj/Project.axf 其中,Project.bin 和 Project.axf 要和 Output 选项卡中的 Name of Executable 的名字IAP我的总结1 先FLASH_Unlock(;2 小于或等于128K的STM每页为1k bytes,大于128K的每页为2K BYTES,减去从地址0x8002000占用的0x2000后,算出页数,比如IAP占用8K,则64K的MD的STM32F系列用for(i=0;i<(64-8;i++ FLASH_ErasePage(0x8002000+0x400*i;循环按页擦除FLASH3 按从外部串口获取到的数据,FLASH_ProgramWord(address,dat;//注意是按4字节方式写入的 if (*(uint32_t*address!= dat//字编程后校验。

一文了解STM32启动过程

一文了解STM32启动过程

一文了解STM32启动过程1 概述说明每一款(芯片)的启动文件都值得去研究,因为它可是你的程序跑的最初一段路,不可以不知道。

通过了解启动文件,我们可以体会到处理器的架构、指令集、中断向量安排等内容,是非常值得玩味的。

(STM32)作为一款高端Cortex-M3系列(单片机),有必要了解它的启动文件。

打好基础,为以后优化程序,写出高质量的代码最准备。

本文以一个实际测试代码--START_(TE)ST为例进行阐述。

整体过程STM32整个启动过程是指从上电开始,一直到运行到main 函数之间的这段过程,步骤为(以使用微库为例):①上电后(硬件)设置SP、PC②设置系统(时钟)③软件设置SP④加载.data、.bss,并初始化栈区⑤跳转到C文件的main函数代码启动过程涉及的文件不仅包含startup_stm32f10x_hd.s,还涉及到了MDK自带的连接库文件entry.o、entry2.o、entry5.o、entry7.o 等(从生成的map文件可以看出来)。

2 程序在Flash上的存储结构在真正讲解启动过程之前,先要讲解程序下载到Flash上的结构和程序运行时(执行到main函数)时的S(RAM)数据结构。

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

下图是通过阅读hex文件和在MDK下调试综合提炼出来的。

上图中:MSP初始值由编译器生成,是主堆栈的初始值。

初始化数据段是.data未初始化数据段是.bss.data和.bss是在__main里进行初始化的,对于(ARM)Com (pi)ler,__main主要执行以下函数:其中__scatterlo(ad)会对.data和.bss进行初始化。

加载数据段和初始化栈的参数加载数据段和初始化栈的参数分别有4个,这里只讲解加载数据段的参数,至于初始化栈的参数类似。

0x0800033c Flash上的数据段(初始化数据段和未初始化数据段)起始地址0x20000000加载到SRAM上的目的地址0x0000000c数据段的总大小0x080002f4调用函数_scatterload_copy需要说明的是初始化栈的函数-- 0x08000304与加载数据段的函数不一样,为_scatterload_zeroinit,它的目的就是将栈空间清零。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32启动文件详解一、启动文件的作用1.初始化堆栈指针SP;2.初始化程序计数器指针PC;3.设置堆、栈的大小;4.设置异常向量表的入口地址;5.配置外部SRAM作为数据存储器(这个由用户配置,一般的开发板可没有外部SRAM);6.设置C库的分支入口__main(最终用来调用main函数);7.在版的启动文件还调用了在文件中的SystemIni()函数配置系统时钟。

二、汇编指令三、启动代码----- 栈Stack_Size EQU 0x00000400 ; 栈的大小AREA STACK, NOINIT, READWRITE,ALIGN=3Stack_Mem SPACE Stack_Size ; 分配栈空间__initial_sp ; 栈的结束地址(栈顶地址)分配名为STACK,不初始化,可读可写,8(2^3)字节对齐的1KB空间。

栈:局部变量,函数形参等。

栈的大小不能超过内部SRAM大小。

AREA:汇编一个新的代码段或者数据段。

STACK段名,任意命名;NOINIT表示不初始化;READWRITE可读可写;ALIGN=3(2^3= 8字节对齐)。

__initial_sp紧挨了SPACE放置,表示栈的结束地址,栈是从高往低生长,结束地址就是栈顶地址。

----- 堆Heap_Size EQU 0x00000200 ; 堆的大小(512Bytes)AREA HEAP, NOINIT, READWRITE,ALIGN=3__heap_base ; 堆的起始地址Heap_Mem SPACE Heap_Size ; 分配堆空间__heap_limit ; 堆的结束地址分配名为HEAP,不初始化,可读可写,8(2^3)字节对齐的512字节空间。

__heap_base堆的起始地址,__heap_limit堆的结束地址。

堆由低向高生长。

动态分配内存用到堆。

PRESERVE8 -- 指定当前文件的堆/栈按照8 字节对齐。

THUMB-- 表示后面指令兼容THUMB 指令。

THUBM 是ARM 以前的指令集,16bit;现在Cortex-M 系列的都使用THUMB-2 指令集,THUMB-2 是32 位的,兼容16 位和32 位的指令,是THUMB 的超级。

3.向量表AREA RESET, DATA, READONLYEXPORT __VectorsE XPORT __Vectors_EndE XPORT __Vectors_Size定义一个名为RESET,可读的数据段。

并声明__Vectors、__Vectors_End 和__Vectors_Size 这三个标号可被外部的文件使用。

__Vectors DCD __initial_sp ; Top of StackDCD Reset_Handler ; Reset HandlerDCD NMI_Handler ; NMI HandlerDCD HardFault_Handler ; Hard Fault HandlerDCD MemManage_Handler ; MPU Fault HandlerDCD BusFault_Handler ; Bus Fault HandlerDCD UsageFault_Handler ; Usage Fault HandlerDCD 0 ; ReservedDCD 0 ; ReservedDCD 0 ; ReservedDCD 0 ; ReservedDCD SVC_Handler ; SVCall HandlerDCD DebugMon_Handler ; Debug Monitor HandlerDCD 0 ; ReservedDCD PendSV_Handler ; PendSV HandlerDCD SysTick_Handler ; SysTick Handler; External InterruptsDCD WWDG_IRQHandler ; Window Watchdog...__Vectors_End__Vectors_Size EQU __Vectors_End - __Vectors ;向量表大小__Vectors 为向量表起始地址,__Vectors_End 为向量表结束地址,两个相减即可算出向量表大小。

向量表从Flash 的0x0 地址开始放置,以 4 个字节为一个单位,地址0 存放的是栈顶地址,0x04 存放的是复位程序的地址,以此类推。

从代码上看,向量表中存放的都是中断服务函数的函数名,可我们知道 C 语言中的函数名就是一个地址。

4.复位程序AREA |.text|, CODE, READONLY定义一个名为.text,可读的代码段Reset_Handler PROC ;复位子程序开始EXPORT Reset_Handler [WEAK]IMPORT __mainIMPORT SystemInitLDR R0, =SystemInitBLX R0LDR R0, =__mainBX R0ENDP ;子程序结束复位子程序是系统上电后第一个执行的程序,调用SystemInit ()函数初始化系统时钟,然后调用 C 库函数_main。

备注:__main() 和main()当所有的系统初始化工作完成之后,就需要把程序流程转入主应用程序,即呼叫主应用程序。

最简单的一种情况是:IMPORT mainB main直接从启动代码跳转到应用程序的主函数入口,当然主函数名字可以由用户随便定义。

在ARM ADS环境中,还另外提供了一套系统级的呼叫机制。

IMPORT __mainB __main__main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()。

所以说,前者是库函数,后者就是我们自己编写的main()主函数;因此我们用的B __main其实是执行库函数,然后该库函数再调用我们的main() 函数,因此在单步调试时会看到先要跑一段程序(其实是库函数),然后再单步到我们自己的main函数(这个同时也说明如果有B __main 则就对应必须有main函数,否则编译出错),如果我们用 B main来进入我们的主函数的话,那在单步调试时就看到直接进入到我们自己的main函数了,中间不会看到其他程序;那么用B __main和用B main 这两这进入我们的main函数方式有什么不同呢如果采用前者则会由编译器加入一段"段拷贝"程序,即我们说的从加载域到执行域转化程序;而采用后者就没有这个了,因此如果要进行"段拷贝"只能自己动手编写程序来实现了,完成段拷贝后就可以进入我们的主函数了,当然这个主函数不一定是叫做main(),可以起个其他好听的名字,这个有别于使用B __main方式;不管采用哪种方式进入我们的程序,都要有一段"段拷贝"程序,跑完了段拷贝后才能可以进入我们主程序了!(顺便提一下:这个文件并没有所谓的"段拷贝"功能,再看也无益!)对含有启动程序来说,"执行地址与加载地址相同"不容易实现:如果执行地址与加载地址相同那当然不需要做"段拷贝",但是个人理解编译器还会加入"段拷贝"程序(如果用B __main的话),只是因为条件不满足而不执行而已;但是对含有启动程序来说,"执行地址与加载地址相同"就不容易了。

因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM等。

因此,对含有启动程序来说,"执行地址与加载地址相同"就不容易实现;程序的入口点在C 库中的__main 处,在该点,库代码执行以下操作:1. 将非零(只读和读写)运行区域从其载入地址复制到运行地址。

2. 清零ZI 区域。

3. 跳转到__rt_entry。

5.终端服务程序NMI_Handler PROCEXPORT NMI_Handler [WEAK]B .ENDPHardFault_Handler\PROCEXPORT HardFault_Handler [WEAK]B .ENDPMemManage_Handler\PROCEXPORT MemManage_Handler [WEAK]B .ENDP此处省略部分……启动文件里面已经帮我们写好所有中断的中断服务函数,跟我们平时写的中断服务函数不一样的就是这些函数都是空的,真正的中断复服务程序需要我们在外部的 C 文件里面重新实现,这里只是提前占了一个位置而已。

如果我们在使用某个外设的时候,开启了某个中断,但是又忘记编写配套的中断服务程序或者函数名写错,那当中断来临的时,程序就会跳转到启动文件预先写好的空的中断服务程序中,并且在这个空函数中无线循环,即程序就死在这里。

B:跳到一个“.”,表示无限循环。

6.用户堆栈初始化ALIGN:对指令或者数据存放的地址进行对齐,后面会跟一个立即数。

缺省表示 4 字节对齐。

IF :DEF:__MICROLIBEXPORT __initial_spEXPORT __heap_baseEXPORT __heap_limitELSEIMPORT __use_two_region_memoryEXPORT __user_initial_stackheap;初始化堆&&栈__user_initial_stackheapLDR R0, = Heap_MemLDR R1, = (Stack_Mem + Stack_Size)LDR R2, = (Heap_Mem + Heap_Size)LDR R3, = Stack_MemBX LRALIGNENDIFEND判断是否定义了__MICROLIB ,如果定义了则赋予标号__initial_sp(栈顶地址)、__heap_base(堆起始地址)、__heap_limit(堆结束地址)全局属性,可供外部文件调用;如果没有定义(实际的情况就是我们没定义__MICROLIB)则使用默认的 C 库,然后初始化用户堆栈大小,这部分有 C 库函数__main 来完成。

四、附录;******************** (C) COPYRIGHT 2011 STMicroelectronics ********************;* File Name :;* Author : MCD Application Team;* Version : Date : 11-March-2011;* Description : STM32F10x High Density Devices vector table for MDK-ARM;* toolchain.;* This module performs:;* - Set the initial SP;* - Set the initial PC == Reset_Handler;* - Set the vector table entries with the exceptions ISR address;* - Configure the clock system and also configure theexternal;* SRAM mounted on STM3210E-EVAL board to be used as data;* memory (optional, to be enabled by user);* - Branches to __main in the C library (which eventually;* calls main()).;* After Reset the CortexM3 processor is in Thread mode,;* priority is Privileged, and the Stack is set to Main.;* <<< Use Configuration Wizard in Context Menu >>>;***************************************************************** **************; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.;***************************************************************** **************; Amount of memory (in bytes) allocated for Stack; Tailor this value to your application needs;/*********************栈定义*********************/; <h> Stack Configuration; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>; </h>Stack_Size EQU 0x00000400 ;EQU伪指令,作用是左边的符号名代表右边的表达式AREA STACK, NOINIT, READWRITE, ALIGN=3 ;定义栈段:名称为STACK,未初始化,可读写,ELF 的栈段按2^3=8对齐Stack_Mem SPACE Stack_Size ;分配一片连续的存储区域并初始化为0,栈空间:0x400(1024B)个字节__initial_sp ;栈空间顶地址;/*********************堆定义*********************/; <h> Heap Configuration; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>; </h>Heap_Size EQU 0x00000200AREA HEAP, NOINIT, READWRITE, ALIGN=3__heap_base ;堆空间起始地址Heap_Mem SPACE Heap_Size ;堆空间:0x200(512B)个字节__heap_limit ;堆空间结束地址PRESERVE8 ;PRESERVE8 指令指定当前文件保持堆栈八字节对齐THUMB ;告诉汇编器下面是32位的Thumb指令,如果需要汇编器将插入位以保证对齐; 中断向量表定义; Vector Table Mapped to Address 0 at Reset; 实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x08000000)AREA RESET, DATA, READONLY ;定义一块数据段<DATA>,只可读<READONLY,默认READWRITE>,段名字是RESETEXPORT __Vectors ;EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用EXPORT __Vectors_End ;在程序中声明一个全局的标号__Vectors_EndEXPORT __Vectors_Size ;在程序中声明一个全局的标号__Vectors_Size;DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始化。

相关文档
最新文档