分类: 嵌入式
2009-09-22 14:06:03
一.C启动部分
;引入at91库完成相关全局变量配置
INCLUDE D:\7月5日启动程序test\AT91\software\parts\r40008\r40008.inc
;根据开发板对应的配置
INCLUDE D:\7月5日启动程序test\AT91\myt\target.inc
;define the stack size
;定义堆栈的大小
SVC_STACK_LEGTH EQU 3
FIQ_STACK_LEGTH EQU 3
IRQ_STACK_LEGTH EQU 24
ABT_STACK_LEGTH EQU 1
UND_STACK_LEGTH EQU 1
IMPORT __use_no_semihosting_swi
IMPORT __use_two_region_memory
EXPORT bottom_of_heap
EXPORT bottom_of_Stacks
EXPORT top_of_heap
EXPORT StackUsr
EXPORT VectorTable
EXPORT __user_initial_stackheap
;/*********************************************************************************
;- Area Definition
;-----------------
;- Must be defined as function to put first in the code as it must be mapped
;- at offset 0 of the flash EBI_CSR0, ie. at address 0 before remap.
;********************************************************************************/
AREA reset, CODE, READONLY, INTERWORK
;/*********************************************************************************
;- Remove any semihosting support
;--------------------------------
;- The C runtime library is the IO functions provided by the semihosting.
;- They are generally costly in code and unused as the debugger is not
;- connected to the target.
;- Must be removed if using the embedded C library is used.
;*********************************************************************************/
;- Define "__main" to ensure that C runtime system is not linked
EXPORT __main
__main
;/*********************************************************************************
;- Define the entry point
;------------------------
;- Note on the link address and the Remap command.
;- In order to guarantee that the non position-independant code (the ARM linker
;- armlink doesn't generate position-independant code) can work on the ARM,
;- it must be linked at address at which it expects to run.
;- So the -ro-base must be used to define the link address as the base
;- address of the flash.
;- In this startup example, we use 0x100 0000 as base address. That's flash
;- address for all AT91 Evaluation Boards.
;*********************************************************************************/
ENTRY
;/*********************************************************************************
;- Exception vectors ( before Remap )
;------------------------------------
;- These vectors are read at address 0 before remap.
;- They absolutely requires to be in relative addresssing mode in order to
;- guarantee a valid jump. For the moment, all are just looping (what may be
;- dangerous in a final system). If an exception occurs before remap, this
;- would result in an infinite loop.
;- After Remap, these vectors are mapped at address 0x100 0000 and only a
;- reset (internal or external) can make of them the actual ARM vectors.
;- Note that the infinite loop has advantage that a debugger can to show up
;- very quickly an hardware issue during the boot sequence.
;*********************************************************************************/
B InitReset ; reset
undefvec
B undefvec ; Undefined Instruction
swivec
B swivec ; Software Interrupt
pabtvec
B pabtvec ; Prefetch Abort
dabtvec
B dabtvec ; Data Abort
rsvdvec
B rsvdvec ; reserved
irqvec
B irqvec ; reserved
fiqvec
B fiqvec ; reserved
;/*********************************************************************************
;- Exception vectors ( after Remap )
;------------------------------------
;- These vectors are read at address 0 after the remap command is performed in
;- the EBI. As they will be relocated at address 0x0 to be effective, a
;- relative addressing is forbidden. The only possibility to get an absolute
;- addressing for an ARM vector is to read a PC relative value at a defined
;- offset. It is easy to reserve the locations 0x20 to 0x3C (the 8 next
;- vectors) for storing the absolute exception handler address.
;- The AIC vectoring access vectors are saved in the interrupt and fast
;- interrupt ARM vectors. So, only 5 offsets are required ( reserved vector
;- offset is never used).
;- The provisory handler addresses are defined on infinite loop and can be
;- modified at any time.
;- Note also that the reset is only accessible by a jump from the application
;- to 0. It is an actual software reset.
;- As the 13 first location are used by the vectors, the read/write link
;- address must be defined from 0x34 if internal data mapping is required.
;- (use for that the option -rw- base=0x34
;*********************************************************************************/
VectorTable
ldr pc, [pc, #&18] ; SoftReset
ldr pc, [pc, #&18] ; UndefHandler
ldr pc, [pc, #&18] ; SWIHandler
ldr pc, [pc, #&18] ; PrefetchAbortHandler
ldr pc, [pc, #&18] ; DataAbortHandler
nop ; Reserved
ldr pc, [pc,#-0xF20] ; IRQ : read the AIC
ldr pc, [pc,#-0xF20] ; FIQ : read the AIC
;- There are only 5 offsets as the vectoring is used.
DCD SoftReset
DCD UndefHandler
DCD SWIHandler
DCD PrefetchAbortHandler
DCD DataAbortHandler
;- Vectoring Execution function run at absolut addresss
SoftReset
b SoftReset
UndefHandler
b UndefHandler
SWIHandler
b SWIHandler
PrefetchAbortHandler
b PrefetchAbortHandler
DataAbortHandler
b DataAbortHandler
;/*********************************************************************************
;- EBI Initialization Data
;-------------------------
;- The EBI values depend to target choice , Clock, and memories access time.
;- Yous must be define these values in include file
;- The EBI User Interface Image which is copied by the boot.
;- The EBI_CSR_x are defined in the target and hardware depend.
;- That's hardware! Details in the Electrical Datasheet of the AT91 device.
;- EBI Base Address is added at the end for commodity in copy code.
;*********************************************************************************/
InitTableEBI
DCD EBI_CSR_0
DCD EBI_CSR_1
DCD EBI_CSR_2
DCD EBI_CSR_3
DCD EBI_CSR_4
DCD EBI_CSR_5
DCD EBI_CSR_6
DCD EBI_CSR_7
DCD 0x00000001 ; REMAP command
DCD 0x00000000 ; 6 memory regions, standard read
PtEBIBase
DCD EBI_BASE ; EBI Base Address
;/*********************************************************************************
;- The reset handler before Remap
;--------------------------------
;- From here, the code is executed from address 0. Take care, as it is linked
;- in 0x100 0000.
;*********************************************************************************/
InitReset
;/*********************************************************************************
;- Speed up the Boot sequence
;----------------------------
;- After reset, the number os wait states on chip select 0 is 8. All AT91
;- Evaluation Boards fits fast flash memories, so that the number of wait
;- states can be optimized to fast up the boot sequence.
;*********************************************************************************/
;- Load System EBI Base address and CSR0 Init Value
ldr r0, PtEBIBase
ldr r1, [pc,#-(8+.-InitTableEBI)] ; values (relative)
;- Speed up code execution by disabling wait state on Chip Select 0
str r1, [r0]
;/*********************************************************************************
;- low level init
;--------------------------------
; Call __low_level_init to perform initialization before initializing
;AIC and calling main.
;********************************************************************************/
__low_level_init
;/*********************************************************************************
;- Reset the Interrupt Controller
;--------------------------------
;- Normally, the code is executed only if a reset has been actually performed.
;- So, the AIC initialization resumes at setting up the default vectors.
;*********************************************************************************/
;- Load the AIC Base Address and the default handler addresses
add r0, pc,#-(8+.-AicData) ; @ where to read values (relative)
ldmia r0, {r1-r4}
;- Setup the Spurious Vector
str r4, [r1, #AIC_SPU] ; r4 = spurious handler
;- Set up the default interrupt handler vectors
str r2, [r1, #AIC_SVR] ; SVR[0] for FIQ
add r1, r1, #AIC_SVR
mov r0, #31 ; counter
LoopAic1
str r3, [r1, r0, LSL #2] ; SVRs for IRQs
subs r0, r0, #1 ; do not save FIQ
bhi LoopAic1
b EndInitAic
;- Default Interrupt Handlers
AicData
DCD AIC_BASE ; AIC Base Address
;/*********************************************************************************
;- Default Interrupt Handler异常入口
;------------------------------------------------------
;- These function are defined in the AT91 library. If you want to change this
;- you can redifine these function in your appication code
;*********************************************************************************/
IMPORT at91_default_fiq_handler
IMPORT at91_default_irq_handler
IMPORT at91_spurious_handler
PtDefaultHandler
DCD at91_default_fiq_handler
DCD at91_default_irq_handler
DCD at91_spurious_handler
EndInitAic
;/*****************************************************
;- Setup Exception Vectors in Internal RAM before Remap
;------------------------------------------------------
;- That's important to perform this operation before Remap in order to guarantee
;- that the core has valid vectors at any time during the remap operation.
;- Note: There are only 5 offsets as the vectoring is used.
;***************************************************/
;- Copy the ARM exception vectors
mov r8, #RAM_BASE_BOOT ; @ of the hard vector in internal RAM 0x300000
add r9, pc,#-(8+.-VectorTable) ; @ where to read values (relative)
ldmia r9!, {r0-r7} ; read 8 vectors
stmia r8!, {r0-r7} ; store them
ldmia r9!, {r0-r4} ; read 5 absolute handler addresses
stmia r8!, {r0-r4} ; store them
;/*********************************************************************************
; Initialise the Memory Controller
;---------------------------------
;- That's principaly the Remap Command. Actually, all the External Bus
;- Interface is configured with some instructions and the User Interface Image
;- as described above. The jump "mov pc, r12" could be unread as it is after
;- located after the Remap but actually it is thanks to the Arm core pipeline.
;- The IniTableEBI addressing must be relative .
;- The PtInitRemap must be absolute as the processor jumps at this address
;- immediatly after the Remap is performed.
;- Note also that the EBI base address is loaded in r11 by the "ldmia".
;*********************************************************************************/
;- Copy the Image of the Memory Controller
sub r10, pc,#(8+.-InitTableEBI) ; get the address of the chip select register image
ldr r12, PtInitRemap ; get the real jump address ( after remap )
;- Copy Chip Select Register Image to Memory Controller and command remap
ldmia r10!, {r0-r9,r11} ; load the complete image and the EBI base
stmia r11!, {r0-r9} ; store the complete image with the remap command
;- Jump to ROM at its new address
mov pc, r12 ; jump and break the pipeline
PtInitRemap
DCD InitRemap ; address where to jump after REMAP
;/*********************************************************************************
;- The Reset Handler after Remap
;-------------------------------
;- From here, the code is executed from its link address, ie. 0x100 0000.
;---------------------------------------------------------------------------**/
InitRemap
;/*********************************************************************************************************
;** unction name 函数名称: InitStack
;** Descriptions 功能描述: Initialize the stacks 初始化堆栈
;** input parameters 输 入: None 无
;** Returned value 输 出 : None 无
;** Used global variables 全局变量: None 无
;** Calling modules 调用模块: None 无
;**-------------------------------------------------------------------------------------------------------
;** Modified by 修 改:
;** Modified date 日 期:
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
InitStack
;Build the SVC stack
;设置管理模式堆栈
MSR CPSR_c, #0xd3
LDR SP, StackSvc
;Build the IRQ stack
;设置中断模式堆栈
MSR CPSR_c, #0xd2
LDR SP, StackIrq
;Build the FIQ stack
;设置快速中断模式堆栈
MSR CPSR_c, #0xd1
LDR SP, StackFiq
;Build the DATAABORT stack
;设置中止模式堆栈
MSR CPSR_c, #0xd7
LDR SP, StackAbt
;Build the UDF stack
;设置未定义模式堆栈
MSR CPSR_c, #0xdb
LDR SP, StackUnd
;Build the SYS stack
;设置系统模式堆栈
MSR CPSR_c, #0xdf
LDR SP, =StackUsr
;/*********************************************************************************
;- Branch on C code Main function (with interworking)
;----------------------------------------------------
;- Branch must be performed by an interworking call as either an ARM or Thumb
;- main C function must be supported. This makes the code not position-
;- independant. A Branch with link would generate errors
;*********************************************************************************/
IMPORT main
ldr r0, =main
mov lr, pc
bx r0
__user_initial_stackheap
LDR r0,=bottom_of_heap
LDR r1,=StackUsr
LDR r2,=top_of_heap
LDR r3,=bottom_of_Stacks
MOV pc,lr
StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4
AREA MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;Stack spaces for Administration Mode 管理模式堆栈空间
IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;Stack spaces for Interrupt ReQuest Mode 中断模式堆栈空间
FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;Stack spaces for Fast Interrupt reQuest Mode 快速中断模式堆栈空间
AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;Stack spaces for Suspend Mode 中止义模式堆栈空间
UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;Stack spaces for Undefined Mode 未定义模式堆栈
AREA Heap, DATA, NOINIT
bottom_of_heap SPACE 1
AREA StackBottom, DATA, NOINIT
bottom_of_Stacks SPACE 1
AREA HeapTop, DATA, NOINIT
top_of_heap
AREA Stacks, DATA, NOINIT
StackUsr
END
;/********************************************************************************
;** End Of File
;********************************************************************************/
二.CONFIG部分
/********************************************************************************************************/
#ifndef __CONFIG_H
#define __CONFIG_H
/*============================================================================*/
#include "periph/stdc/std_c.h"
#include "parts/r40008/reg_r40008.h"
//==============================================================================
/******************************************************************************/
// 预定义
typedef unsigned int UINT32;
typedef unsigned char UINT8;
typedef char INT8;
/*============================================================================*/
// 定义时钟频率
#define MCK 64000000
#define MCKKHz (MCK/1000)
#endif
三.分散加载文件
FLASH 0x01000000 0x0200000
{
ROM_EXEC 0x01000000
{
cstartup_flash.o (reset, +First)
* (+RO)
}
IRAM 0x1000
{
cstartup_flash.o (MyStacks)
}
STACKS_BOTTOM 0x30000 UNINIT
{
cstartup_flash.o (StackBottom)
}
STACKS 0x40000 UNINIT
{
cstartup_flash.o (Stacks)
}
SRAM 0x2000
{
* (+RW,+ZI)
}
HEAP +0 UNINIT
{
cstartup_flash.o (Heap)
}
HEAP_BOTTOM 0x10000 UNINIT
{
cstartup_flash.o (HeapTop)
}
}