简述

ARM7的Memory空间为4G(32 bit寻址空间决定)。不过对于嵌入式的这种MCU而言,其实很多空间都是保留的,只使用了其中的一小部分。

Memory Map

先看总体的图:

[ARM7--LPC2478]Memory Map_map

AHB

AHB部分的memory map如下:

[ARM7--LPC2478]Memory Map_中断向量表_02


AHB部分在LPC2478的系统框架部分有介绍过其模块,这里就是对应那些模块的控制时所设计的一些memory分配。VIC, LCD, USB, EMC, GDMA, Ethernet。

APB

APB各外设模块控制的memory地址分配:

[ARM7--LPC2478]Memory Map_中断向量表_03

Memory remap和boot ROM

Memory remap即内存重映射,其实这里只重映射了一部分,即中断向量表部分,使得在访问被重映射后的区域的memory时能起到进入中断向量表的作用。boot ROM则是IC内部其实除了Flash区域,还有小部分的ROM代码用来启动用的,这部分代码是在IC生产时就固化不可更改的。

中断向量地址表

[ARM7--LPC2478]Memory Map_LPC2478_04


ARM7的中断向量地址是固定的,在地址空间的起始部分的0x0000 0000到0x0000 001C这段。

Memory mapping 模式

Memory remap中断向量表是因为需要在不同的模式下都要能够访问到中断向量表。为何不同的模式中断向量表要remap呢?
觉得一种可能是因为考虑到在不同的代码运行模式下,具体的中断服务(ISR)的处理方式可能是不一样的,可能在正常用户代码运行模式下,IRQ发生时就会立即处理,而在IC的Boot代码运行模式下,可能是另外的处理方法。
另外一种可能,中断向量地址所处位置是Flash地址,比如在Boot Loader阶段的时候,Flash中如果并没有烧写代码(起始用户代码在编写的时候看到定义了中断向量表的入口了,但这些只是用户代码会用到的处理方式,Boot Loader可不一定是这么来用的),此时Boot Loader代码中有需要用到中断来处理的,此时就必须将Boot代码中的中断向量表给重映射到地址空间的起始位置了。
先看下不同的模式:

Boot Loader模式

在IC reset之后,都会来执行这段Boot Loader,而此时Boot ROM interrupt vectors并重映射到地址空间的底部,用来处理在Boot Loader模式下的中断。

User Flash模式

在进入User Flash模式(Boot Loader完成,将用户代码运行环境等准备好了,一般会看到是跳入main来表示进入用户代码)后,前面Boot Loader阶段的Boot ROM interrupt vectors不再重映射,这样User Flash模式下就用户代码中的中断向量表了。

User RAM模式

会将中断向量表重映射到Static RAM的底部,即0x4000 0000地址开始的地方。

User External memory模式

会将中断向量表重映射到external memory bank 0。

不同模式的可被remap部分的示意图

[ARM7--LPC2478]Memory Map_Memory_05

关于remap的一些理解

由于系统在上电复位时要从0X00000000 开始运行,而第一要运行的就是厂家固化在片子里的Boot Loader,这是判断运行哪个存储器上的程序,检查用户代码是否有效,判断芯片是否加密,芯片是否IAP(在应用编程),芯片是否ISP(在系统编程),所以这个Boot Loader要首先执行。而芯片中的Boot Loader不能放在FLASH的头部(即0x0000 0000开始的地方),因为那要存放用户的异常向量表的,以便在运行、中断时跳到这来找入口,所以Boot Loader只能放在FLSAH尾部(即上图中的BOOT FLASH部分)才能好找到。
Boot Loader存在于内部Flash(LPC2400系列大小为8kb,它占用了用户的Flash空间,但也有其他的LPC系列不占用FLash空间的,而部分没有内部Flash空间的ARM处理器仍然存在Boot Block)。 重映射的原因: Boot Loader中有些程序可被用户调用,如擦写片内Flash的IAP 代码。为了增加用户代码的可移植性,所以最好把Boot Loader的代码固定的某个地址上。但由于各芯片的片内Flash大小不尽相同,如果把Boot Loader的地址安排在内部Flash结束的位置上,那就无法固定Boot Loader的地址。 为了解决上面的问题,于是芯片厂家将Boot Loader的地址重映射到片内存储器空间的最高端,即接近2GB的地方,这样无论片内存储器的大小如何,都不会影响Boot Loader的地址。因此当Boot Loader中包含可被用户调用的IAP 操作的代码时,不用修改IAP 的操作地址就可以在不同的LPC系列的ARM上运行了。
Boot Loader运行完就是要运行用户自己写的启动代码了,而启动代码中最重要的就是异常向量表,这个表是放在FLASH的头部首先执行的,而异常向量表中要处理多方面的事情,包括复位、未定义指令、软中断、预取指中止、数据中止、IRQ(中断) ,FIQ (快速中断),而这个异常向量表是总表,还包括许多分散的异常向量表,比如在外部存储器,Boot Loader,SRAM中固化的,不可能都由用户直接定义,所以还是需要重映射把那些异常向量表的地址映到总表中。为存储器分配地址的过程称为存储器映射。