(1) 芯片启动时,是从0地址开始,但是这时引导程序被映射到了地址0,所以这时启动的就是引导程序。
(2) 引导程序检查ISP引脚的状态和BOOT【1】和BOOT【0】,根据不同的状态,将不同的内容映射到地址0,例如
0x80000000或者0x40000000,这个要看你的配置了,从而进行重新映射。
(3) 重新映射后,就跳转到0再运行,这时候实际上运行的是0x80000000或者0x40000000的程序了。
注意:设置RW和RO的目的是为了告诉编译器把生成的代码放在存储器的什么地方。代码实际是存在0x80000000或者0x40000000那里的,只是通过映射的方式,将前面的中断向量表部分映射到地址0去了。、
2.bootLoader 的功能:
(1) 功能: 开启串口下载
(2)过程:首先,是通过检测P0.14口的状态。如果为低电平,则运行ISP的程序,它是BOOTLOADER的一部分,这段程序是引导串口接收数据并放进片内FLASH中;如果P0.14口的状态不为0,那么它就检测你是运行片内FLASH的程序还是外部FLASH的。
先说说片外的FLASH,因为我们下载片外FLASH时是把BIN文件烧进去的,所有的代码都是在一起的,这是什么意思呢,最开始是RO段的程序,紧接着是RW段的程序,但是执行时为了提高执行速度,把RO段放ROM区,RW段放RAM区,这动作是怎么实现的呢,其实就是在进行运行复位程序前就已经重映射了,具体是怎么实现的呢,其实就是一段程序搬运程序,由硬件实现,呵呵。如果是片内的,个人认为应该是一样的过程,只是速度快些而已。
无论怎么样,复位,PC肯定指向0x00000000,但是它从这个地址取出了一个跳转指令,跳到了bootloader区,为什么这么说呢,明明这一区域放的是中断向量表吗?呵呵,不错,但是这个向量表它源于bootloader区,所以相当于执行它的bootloader一样拉,接下来就要检测是否要下载(对P0.14进行检测,看是否是低电平),如果不下载就执行用户程序。
具体的重映射过程,上电复位后,由于ARM里面的FLASH和RAM它是没有地址编码的,所以要经过一次重映射,FLASH映射到0x80000000开始,RAM映射到0x40000000,系统根据BOOT[1:0]这两个脚自动把代码映射,也就是这段时间该怎么映射就怎么映射。不过很短,因为是由硬件实现的。
3.存储器的重映射
(1)存储器映射: 为存储器分配地址的过程称为存储器映射
(2)存储器重映射:为了增加系统的灵活性,系统中有部分地址可以同时出现在不同的地址上,这就叫做存储器重映射。
(3)重映射的内容:主要包括引导块“Boot Block”重映射和异常向量表的重映射。
4.引导块“Boot Block”及其重映射
(1)Boot Block 定义: Boot Block是芯片设计厂商在LPC2000系列ARM内部固化的一段代码,用户无法对其进行修改或者删除;
这段代码在复位时被首先运行。
(2)Boot Block 作用: a. 要用来判断运行哪个存储器上面的程序
b. 检查用户代码是否有效
c. 判断芯片是否被加密
d. 系统的在应用编程(IAP)以及在系统编程功能(ISP)
(3)Boot Block的位置:存在于内部Flash,LPC2200系列大小为8kb,它占用了用户的Flash空间;但也有其他的LPC系列不占
FLash空的, 而部分没有内部Flash空间的ARM处理器仍然存在Boot Block。
(4)Boot Block的重映射原因: Boot Block中有些程序可被用户调用,如擦写片内Flash的IAP代码。为了增加用户代码的可移植性,
所以最好把Boot Block的代码固定的某个地址上。但由于各芯片的片内Flash大小不尽相同,如果把Boot Block的地址安排在内部
Flash结束的位置上,那就无法固定Boot Block的地址。
为了解决上面的问题,于是芯片厂家将Boot Block的地址重映射到片内存储器空间的最高端,即接近2Gb的地方,这样无论片内存储器的大小如何,都不会影响Boot Block的地址。因此当Boot Block中包含可被用户调用的IAP操作的代码时,不用修改IAP的操作地址就可以在不同的LPC系列的ARM上运行了。
5. 中断异常向量表的重映射
ARM内核在发生异常后,会使程序跳转到位于0x0000~0x001C的异常向量表处,再经过向量跳转到异常服务程序。但ARM单条指令的寻址范围有限,无法用一条指令实现4G范围的跳转,所以应在其后面的0x0020~0x003F地址上放置跳转目标,这样就可以实现4G范围内的任意跳转,因此一个异常向量表实际上占用了16个字的存储单元。以下为一张中断向量表:
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
重映射的原因:
由于ARM处理器的存储器结构比较复杂,可能同时存在片内存储器和片外存储器等,他们在存储器映射上的起始地址都不一样,因此ARM内核要访问的中断向量表可能不在0x0000~0x003F地址上,因此采用了存储器重映射来实现将存在与不同地方的中断向量表都映射到0x0000~0x003F地址上。
注意:Boot Block 也存在中断向量表,而且复位后这段代码首先映射到 0x0000~0x003F地址上,也就是说复位后首先运行的是Boot Block程序。各个存储区域的中断向量表也不尽相同。
从上面可以看出中断向量表可以来自4个不同的存储区域。通过下图的激活方式,可以在0x0000~0x003F地址处访问到从其他存储区域重映射过来的中断向量表。
注意:除了“用户片内FLASH模式”外,其他模式下都无法访问片内FLASH的0x0000~0x003F区域。
6.系统启动代码
从系统上电到正式运行用户的main函数之前,要运行一段代码,这段代码称为“启动代码”。
启动代码大部分是由汇编指令构成,它可以实现向量表定义,堆栈的初始化,系统变量初始化,中断系统初始化,I/O初始化,外围初始
化,地址重映射等操作。
启动代码与ARM的Boot Block不同,Boot Block是芯片厂家固化在芯片中的,不能对其进行修改,而启动代码是用户添加的。系统上
电后首先运行的是Boot Block,然后才运行启动代码。
上一篇:LPC中的中断处理小结
下一篇:6410平台上配置Linux的DDR参数
推荐阅读最新更新时间:2024-03-16 14:51