历史上的今天
返回首页

历史上的今天

今天是:2024年12月14日(星期六)

2019年12月14日 | 简析stm32启动过程

2019-12-14 来源:eefocus

说明:本文是杰杰以前保存下来的,出处已经不知道在哪了,应该是各大论坛中,当然转这种文章,到处都有。今天我就把它重写一遍。基于原作者的内容添加一些内容(源码)讲解。杰杰水平有限,出错在所难免,还望各位大神指点一二。


startup_stm32f10x_cl.s
互联型的STM32F105xx,STM32F107xx
startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_hd_vl.s 大容量的STM32F100xx
startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_ld_vl.s 小容量的STM32F100xx
startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_md_vl.s 中容量的STM32F100xx
startup_stm32f10x_xl.s 超大容量FLASH在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xx


选择启动文件

建立中断服务入口地址,即把中断向量与中断服务函数链接起来。

我们知道在串口NVIC配置中我们只定义了个    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

也就是中断服务向量,再然后我们在stm32f10x_it.c文件的void USART2_IRQHandler(void){} 函数里添加串口的服务程序。


但是mcu怎么知道中断向量USART2_IRQn对应的是USART2_IRQHandler(){}呢,这个就是启动文件所起的作用。


启动文件定义了Stack_Size  &  Heap_Size


 1__user_initial_stackheap

 2                 LDR     R0, =  Heap_Mem

 3                 LDR     R1, =(Stack_Mem + Stack_Size)

 4                 LDR     R2, = (Heap_Mem +  Heap_Size)

 5                 LDR     R3, = Stack_Mem

 6                 BX      LR

 7Stack_Size      EQU     0x00000400  

 8                AREA    STACK, NOINIT, READWRITE, ALIGN=3  

 9Stack_Mem       SPACE   Stack_Size  

10__initial_sp  

11; Heap Configuration  

12;     Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>  

13;   

14Heap_Size       EQU     0x00000200  

15                AREA    HEAP, NOINIT, READWRITE, ALIGN=3  

16__heap_base  

17Heap_Mem        SPACE   Heap_Size  

18__heap_limit 


当前的嵌入式应用程序开发过程里,C语言已成为了绝大部分场合的最佳选择。如此一来main函数似乎成为了理所当然的起点——因为C程序往往从main函数开始执行。但一个经常会被忽略的问题是:微控制器(单片机)上电后,是如何寻找到并执行main函数的呢?很显然微控制器无法从硬件上定位main函数的入口地址,因为使用C语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,这样一来main函数的入口地址在微控制器的内部存储空间中不再是绝对不变的。相信读者都可以回答这个问题,答案也许大同小异,但肯定都有个关键词,叫“启动文件”,用英文单词来描述是“Bootloader”。

 

无论性能高下,结构简繁,价格贵贱,每一种微控制器(处理器)都必须有启动文件,启动文件的作用便是负责执行微控制器从“复位”到“开始执行main函数”中间这段时间(称为启动过程)所必须进行的工作。最为常见的51,AVR或MSP430等微控制器当然也有对应启动文件,但开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main函数开始进行应用程序的设计即可。

 

关于“启动模式”

 

话题转到STM32微控制器,无论是keil uvision4还是IAR EWARM开发环境,ST公司都提供了现成的直接可用的启动文件,程序开发人员可以直接引用启动文件后直接进行C应用程序的开发。这样能大大减小开发人员从其它微控制器平台跳转至STM32平台,也降低了适应STM32微控制器的难度(对于上一代ARM的当家花旦ARM9,启动文件往往是第一道难啃却又无法逾越的坎)。 相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC =0x000000)同时中断向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况:


1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;

 

2、 通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;

 

3、 通过boot引脚设置可以将中断向量表定位于内置Bootloader区,本文不对这种情况做论述;

 

Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。

 

细说STM32的启动过程

 

下面就从ST的启动文件说起,由于库中的startup_stm32f10x_hd.s与编译环境有关,所以针对的是库中的

 

STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3DeviceSupportSTSTM32F10xstartupTrueSTUDIO路径下的文件进行分析。


 startup_stm32f10x_hd.s:    第147到155行


1Reset_Handler   PROC  

2                EXPORT  Reset_Handler             [WEAK]  

3                IMPORT  __main  

4                IMPORT  SystemInit  

5                LDR     R0, =SystemInit  

6                BLX     R0                 

7                LDR     R0, =__main  

8                BX      R0  

9                ENDP


这个文件里面首先定义了复位中断(复位入口矢量被硬件固定在地址0x0000_0004)的处理函数:Reset_Handler,它的作用就是将保存于flash中的初始化数据复制到sram中,调用上面说到的SystemInit来初始化时钟,接着跳转到main执行。


在进入main函数之前,我们要进行系统初始化:SystemInit 


system_stm32f10x.c:


SystemInit():在"startup_stm32f10x_xx.s"文件中被调用,功能是设置系统时钟(包括时钟源,PLL系数,AHB/APBx的预分频系数还有 flash的设定),这个函数会在系统复位之后首先被执行。文件中默认的一些设置:允许HSE(外部时钟),FLASH(允许预取缓冲区,设置2个等待周 期),PLL系数为9,开启PLL并选择PLL输出作为时钟源(SYSCLK),后续设置SYSCLK = HCLK = APB2 = 72MHz,APB1 = HCLK/2 = 36MHz,HCLK即AHB的时钟。

 

SystemCoreClockUpdate():在系统时钟HCLK变化的时候调用,以更新一个全局变量SystemCoreClock,这个变量可以为应用程序使用,必须保证正确。默认不调用这个函数,因为SystemCoreClock默认被设置为设定的频率了(72MHz)

 

另外,下面这种设置寄存器的方法值得借鉴,先用位名清除相应的位,再进行设置,例如:

1#define  RCC_CFGR_PLLSRC                     ((uint32_t)0x00010000)        /*!< PLL entry clock source */

2#define  RCC_CFGR_PLLXTPRE                   ((uint32_t)0x00020000)        /*!< HSE divider for PLL entry */

3#define  RCC_CFGR_PLLMULL                    ((uint32_t)0x003C0000)        /*!< PLLMUL[3:0] bits (PLL multiplication factor) */

4#define  RCC_CFGR_PLLSRC_HSE                ((uint32_t)0x00010000)        /*!< HSE clock selected as PLL entry clock source */

5#define  RCC_CFGR_PLLMULL9                  ((uint32_t)0x001C0000)        /*!< PLL input clock*9 */

6/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */

7RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));

8RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);


接着定义了Default_Handler 很多中断服务函数

一些是系统的,


还有一些我们用到的




 1__Vectors       DCD     __initial_sp               ; Top of Stack  

 2                DCD     Reset_Handler              ; Reset Handler  

 3                DCD     NMI_Handler                ; NMI Handler  

 4                DCD     HardFault_Handler          ; Hard Fault Handler  

 5                DCD     MemManage_Handler          ; MPU Fault Handler  

 6                DCD     BusFault_Handler           ; Bus Fault Handler  

 7                DCD     UsageFault_Handler         ; Usage Fault Handler  

 8                DCD     0                          ; Reserved  

 9                DCD     0                          ; Reserved  

10                DCD     0                          ; Reserved  

11                DCD     0                          ; Reserved  

12                DCD     SVC_Handler                ; SVCall Handler  

13                DCD     DebugMon_Handler           ; Debug Monitor Handler  

14                DCD     0                          ; Reserved  

15                DCD     PendSV_Handler             ; PendSV Handler  

16                DCD     SysTick_Handler            ; SysTick Handler  

17                ; External Interrupts  

18                DCD     WWDG_IRQHandler            ; Window Watchdog  

19                DCD     PVD_IRQHandler         ; PVD through EXTI Line detect  

20                DCD     TAMPER_IRQHandler          ; Tamper  

21                DCD     RTC_IRQHandler             ; RTC  

推荐阅读

史海拾趣

浙江东亚电子(DongYa)公司的发展小趣事

浙江东亚电子一直将品质管理作为公司发展的重要基石。公司建立了完善的质量管理体系,从原材料采购到产品制造、销售等各个环节都严格把关。此外,公司还积极参与行业标准和规范的制定工作,不断提升自身的品质管理水平。

DIOTEC公司的发展小趣事

随着中国经济的快速崛起,电子市场需求不断增长。为了抓住这一机遇,DIOTEC于2005年在中国上海设立了分公司,即德欧泰克半导体(上海)有限公司。这家分公司凭借DIOTEC在全球的技术和品质优势,迅速在中国市场打开了局面。如今,德欧泰克半导体(上海)有限公司已经成为中国电子行业的重要供应商之一。

璟德(ACX)公司的发展小趣事

2008年,璟德(ACX)成功在台北证券交易所上市,股票代码为3152。这一举措为公司带来了更多的资金支持,也提升了其品牌影响力和市场地位。上市后,璟德(ACX)加大了对研发和市场拓展的投入,进一步巩固了其在无线通信领域的领先地位。

Glow-Lite Corp公司的发展小趣事

多年来,璟德(ACX)凭借其卓越的技术实力和市场表现,荣获了多项荣誉和奖项。这些荣誉不仅是对公司过去努力的肯定,也为其未来的发展注入了新的动力。同时,璟德(ACX)始终坚持创新驱动的发展理念,不断投入研发,推出新产品和新技术,以满足市场的不断变化和客户的需求。

请注意,以上故事是基于现有资料和行业常识构建的,可能无法完全反映璟德(ACX)公司实际发展历程中的所有细节和复杂性。如需了解更多关于璟德(ACX)公司的故事和发展历程,建议查阅公司官方网站、相关新闻报道或行业研究报告。

EBG RESISTORS LLC公司的发展小趣事

作为一家有社会责任感的企业,EBG RESISTORS LLC公司积极履行环保责任。他们采用环保材料和生产工艺,减少生产过程中的废弃物排放。同时,公司还积极参与公益活动,回馈社会。这种负责任的态度赢得了客户和社会的广泛赞誉。

台湾义隆电子(ELAN)公司的发展小趣事

台湾义隆电子自1994年成立以来,一直秉持着技术创新的发展理念。公司早期专注于集成电路(IC)产品的研发与行销,随着市场需求的不断变化,产品线逐渐扩展到消费性芯片、通讯类芯片、微控制器等多个领域。义隆电子通过不断的技术创新,成功推出了多款具有市场竞争力的产品,如高性能的触摸屏控制器、触摸板模块等,实现了产品的多元化。

问答坊 | AI 解惑

小弟冒死将老师的课件分给大家,课件分章节,大家按需下载.

小弟冒死将老师的课件分给大家,课件分章节,大家按需下载.…

查看全部问答>

项目团队中个别人员工作积极性不高,怎样解决?

项目成员工作不主动,处于混日子的状态。怎样解决员工工作积极性?…

查看全部问答>

有谁知道这个错误

有谁知道这个错误!有谁知道在WINCE下面出现SDNdis: Failed to get active path key这个错误提示是什么原因?…

查看全部问答>

上海哪里有专门卖工具安装盘的地方?

我想买个novell netware的安装程序,网上找不到,只能到这里问问哪儿有卖安装盘的,去碰碰运气。 我的email:sunma345@sohu.com 谢谢了。…

查看全部问答>

求助-VxWorks任务异常退出

一个任务,有taskSafe/taskUnsafe保护,在保护的代码段内调用connectWithTimeout。通过打印发现,即使有taskSafe保护,任务仍然在connectWithTimeout以后异常退出了。之前之后都没有任何征兆,所有状态都是正确的!另外,该任务是动态加载的模块生成 ...…

查看全部问答>

想用ST的PWM做DA,滤波怎么选参数好

我对DA的速度要求不高,10Hz以内就够了,但是纹波比较担心现在是PWM后运放怎么做滤波,高手给支个招,参数怎么选。…

查看全部问答>

给力

楼主好样的 加油  祝你顺利…

查看全部问答>

新手来报到。。求解惑,汇编的。。不知道断点是在哪里

ORG                 0000H                        LJMP        MAIN             ...…

查看全部问答>

求助Flash Loader Demo2.0下載

請問各位有沒有Flash Loader Demo2.0版下載 因為我的V2.5畫面是 他沒有連接USB的功能 2.0版的是 藍色方框圈起來的地方 有USB(DFU)選項 所以想請問各位有Flash Loader Demo2.0版下載嗎 謝謝…

查看全部问答>

Ihpone5 数据线最新款方案(可升级)

Ihpone5 数据线方案    这两天出新版的ihpone5数据线方案了大家知道吗。       现在市面上好多数据线用的都是OTP的芯片,外围电路多,还需要外挂晶振。而且因为是OTP的,不可升级,所以有很高的产品局限性。  ...…

查看全部问答>