1,在__main入口的模式下,汇编代码的指令为 b __main, 编译器在跳转到main之前还要作一系列的工作,这其中就包括对运行环境的初始化,在中提到: copies nonroot(RO&RW) execution regions from load addr to exec addr, and Zeros ZI region. 借助编译器,我们就可以定义更为复杂的运行环境,这里要用到scatter文件(.scf),比如我们要的目标运行环境是:将启动代码以外的所有代码都 拷贝到SDRAM的初始地址中运行,比且把RW段设在0x30800000,那么对应的scf文件如下:
FLASH 0x0 0x200000 { EXEC1 0x0 0x200000 { 2410init.o(Init, +First) __main.o(+RO) ; copy code * (Region$$Table) ; RO/RW addresses to copy * (ZISection$$Table) ; ZI addresses to zero } EXEC2 0x30000000 0x00800000 { *(+RO) } SDRAM 0x30800000 0x00800000 { *(+RW,+ZI) } } ;Sections named Region$$Table and ZISection$$Table which contain the addresses of the code/data to be copied.
配置时钟比、重新设置PLL 2410内部有三个时钟:FCLK、HCLK、PCLK,分别供CPU、AHB总线和APB总线使用,为了降低功耗,一般都选择周期比为1:2:4的合理配置。 同时将PLL配置为运行环境时钟,一般都达到最高202M。 (注:FCLK is used by ARM920T. HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block. PCLK is used for APB bus, which is used by the peripherals such as WDT, IIS, I2C, PWM timer, MMC interface, ADC, UART, GPIO, RTC and SPI)
IO初始化 将IO口配置为对应的功能选项,同时一般会点亮相应的LED灯。
中断初始化 2410的内存空间没有remap的机制,应该中断入口时钟位于零地址。因此中断服务机制可以描述如下: 首先,不管使用那种启动方式,必须确保一下代码段位于内存的0x0地址: b ResetHandler b HandlerUndef ;handler for Undefined mode b HandlerSWI ;handler for SWI interrupt b HandlerPabort ;handler for PAbort b HandlerDabort ;handler for DAbort b . ;reserved b HandlerIRQ ;handler for IRQ interrupt b HandlerFIQ ;handler for FIQ interrupt 除ResetHandler外,其余各项都是由如下的宏定义的一段代码: HandlerFIQ HANDLER HandleFIQ MACRO $HandlerLabel HANDLER $HandleLabel $HandlerLabel sub sp,sp,#4 ; decrement sp(to store jump address) stmfd sp!,{r0} ; PUSH the work register to stack ldr r0,=$HandleLabel ; load the address of HandleXXX to r0 ldr r0,[r0] ; load the contents str r0,[sp,#4] ; store the contents(ISR) of HandleXXX to stack ldmfd sp!,{r0,pc} ; POP the work register and pc(jump to ISR) MEND 这段代码的含义是通过堆栈将中断向量表中的内容赋给PC指针(如HandleFIQ是存放着FIQ服务程序入口地址的地址),自然程序就跳到相应的入口地址。 可见,中断向量表存放的是各个中断服务程序的入口地址,它是用来被加载的,而并不是可执行代码。为了统一,所有示例程序都将中断向量表放在0x33ffff00开始的地址,并根据入口地址依次排列。 需要注意的是如果各种模式的服务程序用C语言定义,那么类型必须用__irq定义,以保证能够正确返回。
初始化串口 串口统一选用UART0,模式采用115200、1bit STOP、No Parity。
最后跳转到我们自己的应用程序!
附:我得程序所使用的地址空间结构以及MMU中C、B的设置:
Blank Area: RW_FAULT 0x5b000000 ~ 0xffffffff
Sram & SFR: NCNB 0x40000000 ~ 0x4affffff
Blank Area: RW_FAULT 0x34000000 ~ 0x3fffffff
Int_Vec, Stack, MTT: CNB 0x33f00000 ~ 0x33ffffff
SDRAM Download: NCNB 0x31000000 ~ 0x33efffff
SDRAM Exec RW: CB 0x30800000 ~ 0x30ffffff
SDRAM Exec R CNB 0x30000000 ~ 0x307fffff
Bank5, FPGA: NCNB 0x28000000 ~ 0x2fffffff
Bank4, FPGA: NCNB 0x20000000 ~ 0x27ffffff
Bank3, Bottom NIC: NCNB 0x18000000 ~ 0x1fffffff
Bank2, Bottom Flash: CNB 0x10000000 ~ 0x17ffffff
Bank1, Bottom Sram: CNB 0x08000000 ~ 0x0fffffff
Bank0, Flash or Sram: CNB 0x00000000 ~ 0x07ffffff
Nor Flash Bootloader
这是我着手写的第一个程序,我的想*是让这个程序同时支持通过串口对Nand 和 Nor FLASH的烧写,如果不进行任何烧写,那么就跳到Nor Flash的第二个section启动应用程序,这样一来,即使脱离JTGA,我也可以使用串口进行盲调。
文章评论(0条评论)
登录后参与讨论