STM32启动代码概述

一般嵌入式开发流程就是先建立一个工程,再编写源文件,然后进行编译,把所有的 *.s文件和 *.c文件编译成一个 *.o文件,再对目标文件进行链接和定位,编译成功后会生成一个 *.hex文件和调试文件,接下来要进行调试,如果成功的话,就可以将它固化到 flash 里面去。


启动代码是用来初始化电路以及用来为高级语言写的软件作好运行前准备的一小段汇编语言,是任何处理器上电复位时的程序运行入口点。


比如,刚上电的过程中,PC机会对系统的一个运行频率进行锁定在一个固定的值,这个设计频率的过程就是在汇编源代码中进行的,也就是在启动代码中进行的。与此同时,设置完后,程序开始运行,注意,程序是在内存中运行的。这个时候,就需要把一些源文件从flash里面copy到内存中,又要对它们进行初始化读写,这又有频率的设置。这些都是初始化。


初始化完成后,我们又要设置一些堆栈,要跳到C语言的main函数里面运行。这就需要堆栈。对普通的ARM CPU有这样一个要求:在绝对地址为零的地方要放置一个异常向量表,但并不是所有的ARM CPU都留有这个一个空间,这就需要用到映射的功能。我们可以将其它地方的一些空间映射到绝对地址里面。当发生异常时,ARM核来读取异常中断表的时候,它会使用映射之后的那个表,这个就可以接着往下执行,否则在绝对地址零的地方找不到任何信息,程序就会死掉。这些运行的环境全部建立好后,程序就会跳转到我们的main函数里面。


总之,启动代码,就是对最小系统的初始化。 包括晶振,CPU频率等。


启动代码的最小系统是: 异常向量表的初始化 – 存储区分配 – 初始化堆栈 – 高级语言入口函数调用 – main()函数。


程序的启动过程:


点击看大图


 


 


以下面这个例子为例,编译完后, DEBUG后,我们可以看到,光标指向绝对地址为零的地方,这里存放的就是一个异常向量表。


 



 


它对应在 startup.s 里的源文件如下:


 


点击看大图


 


单步运行后,马上跳转到初始化CPU的频率。即初始化锁相环,将其锁在一个固定的频率。具体代码如下:


; Setup PLL


                IF      PLL_SETUP <> 0


                LDR     R0, =PLL_BASE


                MOV     R1, #0xAA


                MOV     R2, #0x55


 


;  Configure and Enable PLL


                MOV     R3, #PLLCFG_Val


                STR     R3, [R0, #PLLCFG_OFS]


                MOV     R3, #PLLCON_PLLE


                STR     R3, [R0, #PLLCON_OFS]


                STR     R1, [R0, #PLLFEED_OFS]


                STR     R2, [R0, #PLLFEED_OFS]


 


;  Wait until PLL Locked


PLL_Loop        LDR     R3, [R0, #PLLSTAT_OFS]


                ANDS    R3, R3, #PLLSTAT_PLOCK


                BEQ     PLL_Loop


 


;  Switch to PLL Clock


                MOV     R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)


                STR     R3, [R0, #PLLCON_OFS]


                STR     R1, [R0, #PLLFEED_OFS]


                STR     R2, [R0, #PLLFEED_OFS]


                ENDIF   ; PLL_SETUP


 


然后再初始化每一种模式的堆栈,再进行单步运行的时候,下面我们可以看到,它自动跳转到 main()函数:


; Enter the C code


 


                IMPORT  __main


                LDR     R0, =__main


                BX      R0


 


 


                IF      :DEF:__MICROLIB


 


                EXPORT  __heap_base


                EXPORT  __heap_limit


 


                ELSE


 


这个时候,程序会运行各种 scatterload函数,将我们的堆栈、全局变量等内容拷贝到内存中去。拷贝完后,就正式跳转到我们的 main() 函数中来执行了。


 


点击看大图


 


这就是启动代码执行的全过程,呵呵,平时我们看到以为只是执行main()函数就行了,是不是没有想到在执行 main() 函数后还有这么多学问呢?


 


如果觉得对你有有帮助,请顶一顶,这是对我很大的支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS是一个流行的实时操作系统(RTOS),适用于多种嵌入式系统,包括STM32微控制器。STM32是意法半导体(STMicroelectronics)推出的一系列32位ARM Cortex-M微控制器。 要在STM32上使用FreeRTOS,您需要进行以下步骤: 1. 下载和安装FreeRTOS:您可以从FreeRTOS官方网站下载最新版本的FreeRTOS。它通常提供了示例代码和文档,以帮助您开始使用。 2. 配置工程:在STM32的开发环境中,您需要配置项目以包含FreeRTOS库和头文件。这通常涉及将FreeRTOS文件夹添加到您的项目中,并配置编译选项。 3. 创建任务:在FreeRTOS中,您可以创建多个任务,每个任务执行特定的功能。您可以使用FreeRTOS提供的API来创建任务、管理任务优先级和控制任务之间的通信。 4. 启动调度程序:一旦您创建了任务,您需要启动FreeRTOS调度程序。调度程序负责按照任务的优先级来调度和执行任务。 5. 编写任务代码:为每个任务编写相应的代码,并使用FreeRTOS提供的API来管理任务的状态、同步和通信。 6. 编译和烧录:编译您的项目,并将生成的可执行文件烧录到STM32微控制器中。 这只是一个简单的概述,以帮助您了解在STM32上使用FreeRTOS的基本步骤。具体的步骤和实现细节可能会因您使用的开发环境和STM32型号而有所不同。您可以参考FreeRTOS的文档和示例代码,以获得更详细的指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值