在线时间56 小时
UID2078208
注册时间2014-3-10
NXP金币0
TA的每日心情 | 慵懒 2016-12-22 14:33 |
---|
签到天数: 4 天 连续签到: 1 天 [LV.2]偶尔看看I
金牌会员
 
- 积分
- 1378
- 最后登录
- 1970-1-1
|
昨天收到了社区的K64的板子,很是兴奋,板子比想象中的小很多,板上只有一个LED灯可以供我玩,其他都是留的接口。之前用过cortexM3,昨晚下了下这快芯片跟cortexM3基本一样,网上下载了一个启动代码,看了下启动代码。由于我只熟悉IAR,所以这里只分析了IAR启动代码。
首先看一下源文件中提供的.icf文件。*.icf文件是IAR中的分散描述文件,相当于ADS中的*.src文件或keil中的*.sct文件或GNU中的*.lds链接脚本文件。
这个文件中前面部分是各个变量的定义,关键看后面部分:
***********
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:__code_start__ { readonly section .noinit };
place in RAM_region { readonly, block CodeRelocate };
place in RAM_region { readwrite, block CodeRelocateRam,
block CSTACK, block HEAP };
************
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }
这段代码表示要把.intvec代码段中的只读部分放在存储空间(mem,前面已定义的名称)中__ICFEDIT_intvec_start__ 地址上,前面部分已经定义__ICFEDIT_intvec_start__=0x1fff0000,是SRAM的起始地址。也就是先把向量表放到内存中的最前面。 .intvec 这个段是在vectors.c文件中出现的
typedef void (*vector_entry)(void);
#pragma location = ".intvec"
const vector_entry __vector_table[] = //@ ".intvec" =
{
VECTOR_000,
VECTOR_001,
VECTOR_002,
VECTOR_003,
......(中间省略)
}
从源文件中可以看到这里定义了一个向量表__vector_table(前面的const 很重要不能省,这样才能保证向量表是只读的),向量表中的每一项都是一个指向函数的指针,这里总共有256+4=260个指针,所以占据空间为260*4=1040=0x410.
place at address mem:__code_start__ { readonly section .noinit }
这段代码表示要把 .noinit段中的只读部分放到地址空间 __code_start__ 开始的地址上,前面有定义 __code_start__= 0x1fff0410 ,也就是把 .noinit段放到0x1fff0410开始的地址上。所以在内存中代码就连续了,先是向量表,接着的是.noinitd 段。
.noinit 段在crt0.s汇编文件中出现:
SECTION .noinit : CODE
这段代码算是芯片复位后执行的第一段代码(如果没有其他异常的话)。作为一个通常的规则,推荐先把通用寄存器(R0-R12)清零。然后是使能中断,跳转到start标号(或函数)处继续执行。
start函数中,首先执行 wdog_disable()函数来禁用看门狗,然后调用 common_startup()函数初始化RAM(复制向量表、清零.bss段等,为C语言运行环境做准备),接着执行sysinit()函数初始化芯片(时钟、用到的外设等)。
common_startup
初始化RAM(复制向量表、清零.bss段等,为C语言运行环境做准备)。
1
2 #include "common.h"
3 #pragma section = ".data"
4 #pragma section = ".data_init"
5 #pragma section = ".bss"
6 #pragma section = "CodeRelocate"
7 #pragma section = "CodeRelocateRam"
在IAR中, #pragma section="NAME" [align] 用来在C语言中指定一个名称是NAME的段,align指定对齐方式。指定的段可以被段操作符来引用,段操作符包括 __section_begin, __section_end, 和 __section_size.
在存储器最前面放置好向量表-->把通用寄存器清零-->开中断-->跳转到start函数继续执行初始化。在start函数中,顺次执行三个函数:禁用看门狗-->初始化C语言环境(向量表重定向、拷贝数据段到RAM、清零bss段等)-->系统外设初始化。
然后进入了main函数。
|
|