嵌入式开发底层——KEIL中启动文件详解(汇编语言)

概述

在嵌入式系统中,启动文件是整个系统非常关键的部分,它会进行一些底层的初始化,构建程序运行必要的环境,比如堆栈初始化,变量初始化等。如果启动文件出现错误,则整个系统就跑不起来,因此研究启动文件非常必要。

在keil中,启动文件由汇编代码编写,一般命名为startup_xxx.s,xxx为支持的某种芯片,比如可以是lpc15xx(NXP的LPC15xx系列)、MK60D10(飞思卡尔)、stm32f10x(意法半导体stm32f10x系列)等Cortext-M0/M3/M4内核芯片。它们的代码格式非常相近,根据启动文件代码由上到下的编写顺序.

可以将其分为以下5个典型部分:
  1. 堆栈空间定义;
  2. 存放中断向量表;
  3. 复位中断函数(Reset_Handler);
  4. 其它中断异常服务函数,以及弱[WEAK]声明;
  5. 将堆栈地址传递给库函数,利用库函数初始化堆栈,和库函数自身初始化。
5个部分具体说明如下:

1 堆栈空间定义

如下图所示,定义了栈大小Stack_Size = 0X200,即512字节;堆大小Heap_Size = 0X100,256字节。还定义了三个标号:__initial_sp(栈顶)__heap_base(堆起始地址)__heap_limit(堆终止地址),它们的空间由SPACE关键字来申请,并记作Stack_MemHeap_Mem

堆栈大小定义

通过这些我们可以很容易的知道堆栈的大小,但是它们的绝对地址或者说基地址仅仅从这里是得不到的。编译器编译完工程后,根据生成.bss段(比如未初始化的全局变量)和.data段(比如初始化的全局变量)的大小以及RAM的起始地址,来计算堆栈的基地址。

举个例子:

一个芯片的RAM起始地址为0x0200_0000,RAM大小为0x500字节,程序编译后.bss段为0x100个字节,.data段为0x100个字节。堆栈大小定义如上图。则:

  • A:堆起始地址__heap_base==Heap_Mem==0x0200_0200;

  • B:堆终止地址即栈底__heap_limit==Stack_Mem==0x0200_0300;

  • C:栈顶地址__initial_sp==0x0200_0500(栈是向下生长,栈顶处于RAM最大地址处)。

其实,我可以在.map文件中查看堆栈的大小和基地址,如下图所示:

.map文件

2 存放中断向量表

在启动代码中,会见到许多由DCD申请空间存放的一个个函数入口,即中断向量表,如下图所示,只列出了部分。

中断向量表

关键字DCD代表申请一个字的空间,后面的函数名即为中断服务函数入口地址。另外中断向量表一般存放在Flash0地址。

另外,对于NXP微控制器,均实现了芯片的加密,加密的设置在向量表的结尾处,具体地址为0x02FC处。通过在此地址存放不同的值实现是否加密或者加密的等级。加密分为三个等级,CRP1:0x12345678;CRP2:0x87654321;CRP3:0x43218765。至于每个等级的具体说明请参考芯片用户手册。下面说一下加密步骤,以CRP1为例:

CRP加密

首先将上图中0xFFFFFFFF,修改为0x12345678。
其次,图中IF :LNOT::DEF:NOCRP表示如果没有定义宏NOCRP则执行下面的代码,那么必须保证汇编中没有定义NOCRP宏。即保证下图中Define:一栏中没有定义NOCRP即可。

是否加密在这里设置

3 复位中断函数(Reset_Handler)

程序上电后,首先加载SP和PC,ARM规定从0地址处加载SP,从偏移为4的地址(0x00000004)处加载PC。然后将程序控制权交给程序。我们知道0地址处存放__initial_sp,0x00000004地址处存放Reset_Handler,加载PC后,程序跳转到Reset_Handler开始运行。Reset_Handler函数体如下图所示:

复位中断

首先调用SystemInit函数来初始化系统的各种时钟,然后调用__main函数(由KEIL微库或者C库实现),在__main函数中:.data段数据的初始化->.bss段变量清零->设置堆栈指针->库函数初始化(比如常用的malloc函数)->如果必要会设置main函数的argc和argv两个参数->调用用户main函数->退出。

4 其它中断异常服务函数,以及弱[WEAK]声明

WEAK弱声明

如上图所示,这里的中断服务函数是弱声明的(由[WEAK]关键字标注)。所谓弱声明,即:如果用户定义了相同的函数则此处函数失效而使用用户定义的中断服务函数。这样是为了防止用户使能了中断而没有中断服务函数,从而造成程序崩溃。假设使能了中断,而用户又没有定义中断服务函数则会进入默认中断,如下图所示,默认中断为死循环(死循环与程序崩溃不是一个概念)。

默认中断

5 将堆栈地址传递给库函数

第三步骤中,调用__main函数,然后__main调用库函数初始化堆栈,但库函数并不知道堆栈的大小,因此我们需要告诉它,具体做法就是传递参数或声明标号。

下图为具体做法,可以看到第一行为:

IF      :DEF:__MICROLIB

是条件编译选项,如果定义__MICROLIB,则编译图中红线上面部分,否则编译红线下面部分。那么就分2种情况。

微库选择

2种情况的选择可以如下实现:
如果勾选【Options for Target】->【Target】->【Use MicroLIB】,如下图所示。即使用微库,则__MICROLIB会被定义,编译器编译红线以上代码。用EXPORT声明 __initial_sp__heap_base__heap_limit

微库选择

如果不勾选【Use MicroLIB】,则缺省使用KEIL C库,上图红线以下会参与编译,KEIL C库函数会调用__user_initial_stackheap,通过R0~R3将堆栈以参数形式传递给KEIL C库。

参考:http://www.cnblogs.com/mddblog/p/4920063.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容