花了点时间整理sep4020 sample代码中的最底层部分的代码,把自己的整理笔记贴出来,供以后参考:
一.发现的问题:
1.usr的sp和sys的sp是相同的,所以不需要定义两个sp;SP仍然是以8M的sdram为标准的,而现在都是32M的了;
2.在msr cpsr_cf, R4时只需要cpsr_c即可;
3.PMU_PCSR的注释有问题;
4.配置结束之后缘何没有回到user模式??
5.中断返回代码混乱,已重新修改。
6.heap.s直接通过定义个内存空间来取地址是不是太随意了,经验值heap.s得到的堆空间在30002XXX,但是我们程序一般的load地址是30008000意味着如果malloc一段很大的空间就直接会把程序冲掉。需要重新管理堆栈。
7.stack.s是不需要的,因为我们栈的上限在系统一上电的时候已经赋值了,如果进retarget.c也会发现没有用到stack.s中的内容。
二、关于retarget.c 中的__user_intial_stackheap()
If you are using scatter loading, however, you must retarget
__user_intial_stackheap() to initialize the stack and heap. An example of how to do
this is in retarget.c.
Printf()是通过在Retarget.C中自定义sendchar()实现的,所以这个文件就是实现Printf()函数的底层驱动
__user_initial_stackheap() must be reimplemented if you are using
scatter loading. Ensure that you have reimplemented the function
correctly and that the new module is linked with your code. Use the
reimplementation provided in the Examples directory as a starting point
for your reimplementation.
__user_initial_stackheap()是在__main当中实现的,主要是为应用程序实现heap,stack.因此我们的启动代码可以分成两个部分:
一是系统的初始化,包括中断向量表的建立、时钟、存储系统初始化、关键I/O口初始化、各处理器模式下的栈指针初始化等;比如我们常见的boot_gfd
二是应用程序初始化(或说C库函数初始化),包括RW段的搬移和ZI段的清零、C应用程序堆栈区的建立(__user_initial_stackheap()函数初始化堆栈指针)等。__main函数,包括我们的heap.s, stack.s, retarget.c
关于这点,在开发指南中的3.5节讲的非常好。
文档中说有了scatf文件,就需要使用__user_initial_stackheap来重载,我们是使用了这个,但是只初始化了堆,没有初始化栈,而堆的地址又仅仅是通过取地址得到的,栈的地址还是系统复位的时候在esram中的地址,而照理堆向上增长,栈向下增长,栈应该大于堆的地址??
——————这个问题是由于之前版本的基础文件的问题,统一后的基础文件没有这个问题。
三、关于启动方式
simple模式:
其实地址为esram的地址,利用simple可以使boot_gfd和int_gfd两个文件合二为一,系统其实就可以从int_gfd中开始。但此时要把esram映射到0地址,这样中断才能跳到那里。这里也可以通过scattered模式来实现simple,如下:
ESRAM 0x04000000
{
ESRAM 0x04000000
{
int_gfd.o (INT, +First)
* (+RO,+RW,+ZI)
}
}
如果是要实际烧到板子上的话,需要使用bootloader将norflash中的内容搬运到esram中。
scattered模式:
我们的代码是将程序入口放在esram中,所以需要将boot_gfd定位在esram中,此处我们没有将esram remap到0地址,而是将sdram映射到0地址,所以把int_gfd定位到sdram的30000000中,并且将ro rw zi段也映射到此处。
实际烧到板子上的话应该也应该用bootloader。
阅读(1130) | 评论(0) | 转发(0) |