周立功LPC2000分散加载详解
周立功的LPC开发板分2100和2200两种,主要区别在于2100不支持外部总线,所以要外扩RAM和FLASH只能用2200的模板。
分散加载语法请参照我的另一篇分散加载日志和相关书籍
一、影响分散加载文件的主要有以下几个因素:
1、从哪儿启动,也就是中断向量表放在哪儿:
该地址需要在ADS的Targets属性->ARM
Linker->Option选项卡->image entry
point中手动设置
1.内部Flash:
最常用的位置,地址0x00000000,需要把存储器映射控制寄存器(MEMMAP–0xE01FC040)最低两位设置为0x01,该寄存器在Target.c文件中设置。
2.内部RAM:
最常用的调试位置,地址0x40000000,需要把存储器映射控制寄存器(MEMMAP–0xE01FC040)最低两位设置为0x10
3.外部存储器:
若要存放中断向量表,不管是外部RAM还是Flash,都只能接在Bank0上,地址0x80000000,需要把存储器映射控制寄存器(MEMMAP–0xE01FC040)最低两位设置为0x11。另外依据外部寄存器位宽,需要在硬件上把BOOT[1,0](P2.26-2.27)配置为
00:8位,01:16位,10:32位,11:从内部Flash启动
2、堆栈放在哪儿:
人们老把堆栈连用,其实堆和栈是两个概念。周立功的启动代码使用了ADS的堆栈管理功能。
ADS的堆栈管理功能分两种:
一段式:堆和栈在同一片地址空间相向生长,需要在启动代码中加上:
EXPORT __user_initial_stackheap
要求定义:
堆底:
EXPORT
bottom_of_heap
栈顶:
EXPORT
StackUsr
__user_initial_stackheap
LDR r0,=bottom_of_heap
;
LDR r1,=StackUsr
MOV pc,lr
二段式:堆和栈在不同的空间,需要在启动代码中加上:
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
要求定义:
堆底:
EXPORT
bottom_of_heap
栈底:
EXPORT
bottom_of_Stacks
堆顶:
EXPORT
top_of_heap
栈顶:
EXPORT
StackUsr
__user_initial_stackheap
LDR r0,=bottom_of_heap
;
LDR r1,=StackUsr
LDR r2,=top_of_heap
LDR r3,=bottom_of_Stacks
MOV pc,lr
以上用到的这些bottom_of_heap、bottom_of_Stacks、top_of_heap、StackUsr都需要在分散加载文件中给出地址
二、举例说明:
一段式:
ROM_LOAD 0x0
{
;启动程序的向量表和只读变量加载地址:1.内部Flash:0x00000000,2.内部RAM:0x40000000,3.外部存储器:地址0x80000000
ROM_EXEC
0x00000000
{
Startup.o (vectors, +First)
* (+RO)
}
;用户栈和启动程序的可读写变量,这个一般放在内部RAM,比较快
IRAM
0x40000000
{
Startup.o (MyStacks)
* (+RW,+ZI)
}
;堆底
;1.内部RAM,接着上面存放
HEAP +0
UNINIT
{
Startup.o (Heap)
}
;16K内部RAM结束地址:0x40003FFF,计算方法:2的10次方=1K:0x400,16k=0x4000
STACKS
0x40004000 UNINIT
{
Startup.o (Stacks)
}
;2.外部RAM,该地址取决于外部RAM挂在哪个Bank上,一般为Bank0,起始地址:0x80000000,
;如果芯片内部没有Flash(例如:2220)需要从外部Flash启动,则外部RAM一般挂在Bank1,起始地址:0x81000000
HEAP
0x80000000 UNINIT
{
Startup.o (Heap)
}
;8M外部RAM结束地址:0x807FFFFF,计算方法2:2的20次方=1M:0x100000,8M=0x800000
STACKS
0x80004000 UNINIT
{
Startup.o (Stacks)
}
}
二段式:
ROM_LOAD 0x00000000
{
;启动程序的向量表和只读变量加载地址:1.内部Flash:0x00000000,2.内部RAM:0x40000000,3.外部存储器:地址0x80000000
ROM_EXEC
0x00000000
{
Startup.o (vectors, +First)
* (+RO)
}
;用户栈和启动程序的可读写变量,这个一般放在内部RAM,比较快
IRAM
0x40000000
{
Startup.o (MyStacks)
* (+RW,+ZI)
}
;1.栈放在内部RAM,接着上面存放
STACKS_BOTTOM +0 UNINIT
{
Startup.o (StackBottom)
}
;16K内部RAM结束地址:0x40003FFF,计算方法:2的10次方=1K:0x400,16k=0x4000
STACKS
0x40004000 UNINIT
{
Startup.o (Stacks)
}
;堆放在外部RAM,该地址取决于外部RAM挂在哪个Bank上,一般为Bank0,起始地址:0x80000000,
HEAP
0x80000000 UNINIT
{
Startup.o (Heap)
}
;8M外部RAM结束地址:0x807FFFFF,计算方法2:2的20次方=1M:0x100000,8M=0x800000
HEAP_BOTTOM
0x80800000 UNINIT
{
Startup.o (HeapTop)
}
;2.堆放在内部RAM
HEAP +0
UNINIT
{
Startup.o (Heap)
}
;16K内部RAM结束地址:0x40003FFF,计算方法:2的10次方=1K:0x400,16k=0x4000
HEAP_BOTTOM
0x40004000 UNINIT
{
Startup.o (HeapTop)
}
;栈放在外部RAM,该地址取决于外部RAM挂在哪个Bank上,一般为Bank0,起始地址:0x80000000,
STACKS_BOTTOM 0x80000000 UNINIT
{
Startup.o (StackBottom)
}
;8M外部RAM结束地址:0x807FFFFF,计算方法2:2的20次方=1M:0x100000,8M=0x800000
STACKS
0x80800000 UNINIT
{
Startup.o (Stacks)
}
}
|