原创 LPC2214的BOOTBLOCK和中断向量表映射

2011-4-2 17:20 2979 9 9 分类: MCU/ 嵌入式

Arm的映射和重映射很难理解,相信很多初学ARM的人都有这个感受。今天花了一天时间仔细研究了下,自我感觉弄明白了,但是也有可能有些地方理解错误。整理出来和大家探讨。
以LPC2214为例。
下图是复位后从用户角度看到的整个地址空间映射

BOOT BLOCK
Boot block是芯片厂家固化在芯片中的,不能被用户修改和删除。这段代码在复位时首先运行,主要用来判断运行哪个存储器(片内FLASH存储器或片外存储器)上的程序,检查用户代码是否有效,判断芯片是否被加密,系统在系统编程(ISP)和在应用编程(IAP)功能等。
Boot block实际地址在内部flash的顶部,大小8K,对LPC2214,实际地址是0X0003E000-0X0003FFFF.占用了FLASH的存储空间,所以实际可用的FLASH空间是256K-8K.
映射换个说法就是分配地址,复位后为boot block分配地址0X0003E000-0X0003FFFF就是映射。
Boot block的重映射就是在4G地址空间内划分一块8K的空间指向BOOT BLOCK的实际空间,看上图,地址范围0X7FFFE000-0X7FFFFFFF范围就是BOOT BLOCK重映射的地址。访问地址0X7FFFE000就像访问0X0003E000一样。至于重映射是否是把BOOT BLOCK的内容复制了一遍,我就不清楚了。
Boot block为什么要重映射?因为各个芯片内部FLASH大小不尽相同,如果把BOOT BLOCK地址安排在内部FLASH结束的位置上,那就无法固定BOOT BLOCK的地址。上图中可以看出,在LPC2114里,内部FLASH是128K,那么BOOT BLOCK的地址就是0X0001E000-0X0001FFFF。为了解决上面的问题,于是芯片厂家将BOOT BLOCK的地址重映射到片内存储器空间的最高端,也就是接近2G的地方,这样无论片内存储器的大小如何都不会影响BOOT BLOCK的地址,便于用户代码的移植。

上电后首先运行的是BOOT BLOCK,检测是否有ISP的相关引脚被设定,如果设定进入ISP模式,如果没有设定,运行用户程序的启动代码。启动代码主要实现异常向量表的定义,堆栈初始化,系统变量初始化,中断系统初始化,I/O初始化,外围初始化,地址重映射等操作。启动代码执行完后跳转到MAIN()开始运行用户程序。

中断向量表
中断向量表总共64字节。中断向量表有4个:BOOT BLOCK开始部分,重映射后是0X7FFFE000,内部SRAM的开始部分,地址0X40000000,内部FLASH的开始部分,地址0X00000000,如果接有外部存储器,在外部存储器的开始部分0X80000000。
除了“用户片内FLASH模式外”外,其他模式都无法访问0X00000000-0X0000003F区域。
存储器映射控制寄存器器MEMMAP的低两位用来控制存储器映射

MEMMAP的复位值是0,也就是复位后是BOOT装载程序模式,BOOT BLOCK的中断向量映射到0X00000000-0X0000003F。首先运行BOOT BLOCK程序。然后执行用户程序的启动代码,如果用户选择片内FLASH,要把MAP1:0设置成01。这样用户程序在运行过程中有中断发生就会跳转到启动代码开始的中断向量表处。
例如,每当产生一个软件中断请求,ARM内核就从0x0000 0008处取出32位数据。这就意味着当MEMMAP[1:0]=10(用户RAM模式)时,从0x0000 0008的读数/取指是对0x4000 0008单元进行操作。如果MEMMAP[1:0]=01(用户Flash模式),从0x0000 0008的读数/取指是对片内Flash单元0x0000 0008进行操作。当MEMMAP[1:0]=00(Boot装载程序模式)时,从0x0000 0008的读数/取指是对0x7FFF E008单元的数据进行操作(Boot Block从片内Flash存储器重新映射)。

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /4 下一条