keil main之前执行过程

16 篇文章 0 订阅

硬件复位后,第一步是执行复位处理程序,这个程序的入口在启动代码里(默认),摘录一段cortex-m3的复位处理入口代码:

 
  1. Reset_Handler   PROC        ;PROC等同于FUNCTION,表示一个函数的开始,与ENDP相对?  
  2.                 EXPORT  Reset_Handler             [WEAK]  
  3.         IMPORT  SystemInit  
  4.                 IMPORT  __main  
  5.         LDR     R0, =SystemInit  
  6.                 BLX     R0  
  7.                 LDR     R0, =__main  
  8.                 BX      R0  
  9.                 ENDP  
Reset_Handler   PROC		;PROC等同于FUNCTION,表示一个函数的开始,与ENDP相对?
                EXPORT  Reset_Handler             [WEAK]
		IMPORT  SystemInit
                IMPORT  __main
		LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP
这里SystemInit函数是我自己用C代码写的硬件底层时钟初始化代码,这个可不算是keil mdk给代劳的.初始化堆栈指针、执行完用户定义的底层初始化代码后,发现接下来的代码是调用了__main函数,这里之所以有__main函数,是因为在C代码中定义了main函数, 函数标签 main() 具有特殊含义。main() 函数的存在强制链接器链接到 __main 和 __rt_entry 中的初始化代码。

其中,__main函数执行代码和数据复制、解压缩以及 ZI 数据的零初始化。解释一下,C代码中,已经赋值的全局变量被放在RW属性的输入节中,这些变量的初值被keil mdk压缩后放到ROM或Flash中(RO属性输入节)。什么是赋值的全局变量呢?如果你在代码中这样定义一个全局变量:int nTimerCount=20;变量nTimerCount就是已经赋值的变量,如果是这样定义:int nTimerCount;变量nTimerCount就是一个非赋值的变量,keil默认将它放到属性为ZI的输入节。为什么要压缩呢?这是因为如果赋值变量较多,会占用较多的Flash存储空间,keil 默认用自己的压缩算法。这个“解压缩”就是将存放在RO输入区(一般为ROM或Flash)的变量初值,按照一定算法解压缩后,拷贝到相应RAM区。ZI数据清零是指将ZI区的变量所在的RAM区清零。使用 UNINIT 属性对执行区进行标记可避免 __main 对该区域中的 ZI 数据进行零初始化。这句话很重要,比如我有一些变量,保存一些重要信息,不希望复位后就被清零,这时就可以用分散加载文件定义一块UNINIT属性的区,将不希望零初始化的变量定义到这个区即可。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值