OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8138|回复: 2

刚在网上看了一篇关于STM32启动代码的概述 有些不懂得地方想请教下大家

[复制链接]

28

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2012-6-17
在线时间
0 小时
发表于 2012-8-3 09:35:23 | 显示全部楼层 |阅读模式
            

一般嵌入式开发流程就是先建立一个工程,再编写源文件,然后进行编译,把所有的 *.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


fficeffice" />


; 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:ORLLCON_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 EF:__MICROLIB



EXPORT __heap_base


EXPORT __heap_limit



ELSE



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



点击看大图



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


不懂得地方 

为什么我一调试就跳到了这里啊

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  __main
    光标指向这里 LDR     R0, =__main
                BX      R0
                ENDP

根本就没指向到初始化CPU的频率这些地方 直接跳到LDR R0, =__main 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-8-3 09:47:46 | 显示全部楼层
回复【楼主位】sunwei056056:
---------------------------------
CPU频率在main里面设置的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

38

主题

292

帖子

1

精华

高级会员

Rank: 4

积分
614
金钱
614
注册时间
2012-7-6
在线时间
0 小时
发表于 2012-8-3 10:48:03 | 显示全部楼层
这个问题不错!虽然我不会 但是不能让帖子沉了!
STM32F3系列公司现有货供应!STM32F0,STM32F2,STM32F3,STM32F4 银洋电子专业一级代理http://www.y-ec.com 联系电话:021-53086303  淘宝网:http://y-ec.taobao.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 03:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表