正在接手一个关于AT91M55800A的工程。<br />问题:<br />AT91M55800是有重影射功能的,重影射命令在什么时候执行?<br />按理应该是在跳入main函数之前、应该是从ROM里面拷贝完数代码到RAM后就执行重影射命令的吗?这段代码里面我怎么没有看到相关的重影射命令?<br /><br />以下是整个启动代码的源代码(编译环境ADS1.2)<br />;------------------------------------------------------------------------------<br />;- ATMEL Microcontroller Software Support - ROUSSET -<br />;------------------------------------------------------------------------------<br />; The software is delivered "AS IS" without warranty or condition of any<br />; kind, either express, implied or statutory. This includes without<br />; limitation any warranty or condition with respect to merchantability or<br />; fitness for any particular purpose, or against the infringements of<br />; intellectual property rights of others.<br />;-----------------------------------------------------------------------------<br />;- File source : Cstartup.arm<br />;- Object : Generic CStartup for ARM ADS 1.2 and EB55<br />;- Compilation flag : None<br />;-<br />;- 1.0 17/Feb/03 JPP : Creation<br />;------------------------------------------------------------------------------<br /><br /><br /> INCLUDE ..LibincludeAT91M55800A.inc<br /><br />;--------------------------------<br />;- ARM Core Mode and Status Bits<br />;--------------------------------<br /><br />ARM_MODE_USER EQU 0x10<br />ARM_MODE_FIQ EQU 0x11<br />ARM_MODE_IRQ EQU 0x12<br />ARM_MODE_SVC EQU 0x13<br />ARM_MODE_ABORT EQU 0x17<br />ARM_MODE_UNDEF EQU 0x1B<br />ARM_MODE_SYS EQU 0x1F<br /><br />I_BIT EQU 0x80<br />F_BIT EQU 0x40<br />T_BIT EQU 0x20<br /><br /> <br />;- Get the start Ram address<br />;- For Flash definition<br /> IF :DEF:FLASH<br />TOP_INTERNAL_MEMORY EQU AT91C_SRAM_BEFORE_REMAP<br /> ELSE ; not use FLASH USE ICE<br />;- For Ice definition<br />TOP_INTERNAL_MEMORY EQU AT91C_SRAM_AFTER_REMAP<br /> ENDIF ; endif SEMIHOSTING<br /><br />;------------------------------------------------------------------------------<br />;- Area Definition<br />;------------------------------------------------------------------------------<br /><br /> AREA reset, CODE, READONLY<br />;------------------------------------------------------------------------------<br />;- Define "__main" to ensure that C runtime system is not linked<br /> IF :DEF:RAMRUN<br /> EXPORT __main<br />__main <br /> ENDIF<br /> CODE32<br /> ENTRY<br /> EXPORT entry<br />entry<br />;------------------------------------------------------------------------------<br />;- Exception vectors ( before Remap )<br />;------------------------------------<br />;- These vectors can be read at address 0 or at RAM address<br />;- They ABSOLUTELY requires to be in relative addressing mode in order to<br />;- guarantee a valid jump. For the moment, all are just looping.<br />;- If an exception occurs before remap, this would result in an infinite loop.<br />;- To ensure if a exception occurs before start application to infinite loop.<br />;------------------------------------------------------------------------------<br /><br /> B InitReset ; Reset handler<br />undefvec<br /> B undefvec ; Undefined Instruction<br />swivec<br /> B swivec ; Software Interrupt<br />pabtvec<br /> B pabtvec ; Prefetch Abort<br />dabtvec<br /> B dabtvec ; Data Abort<br />rsvdvec<br /> B rsvdvec ; reserved<br />irqvec<br /> B irqvec ; IRQ<br />fiqvec<br /> B fiqvec ; FIQ<br /><br />;------------------------------------------------------------------------------<br />;- Exception vectors ( after cstartup execution )<br />;------------------------------------<br />;- These vectors are read at RAM address after the remap command is performed in<br />;- the EBI. As they will be relocated at address 0x0 to be effective, a<br />;- RELATIVE addressing is FORBIDDEN. The only possibility to get an absolute<br />;- addressing for an ARM vector is to read a PC relative value at a defined<br />;- offset. It is easy to reserve the locations 0x20 to 0x3C (the 8 next<br />;- vectors) for storing the absolute exception handler address.<br />;- The AIC vectoring access vectors are saved in the interrupt and fast<br />;- interrupt ARM vectors. So, only 5 offsets are required (reserved vector<br />;- offset is never used).<br />;- The provisory handler addresses are defined on infinite loop and can be<br />;- modified at any time.<br />;- Note also that the reset is only accessible by a jump from the application<br />;- to 0. It is an actual software reset.<br />;- As the 13 (8+5) first location are used by the vectors, the read/write link<br />;- address must be defined from 0x34 if internal data mapping is required.<br />;- (use for that the option -rw- base=0x34<br />;------------------------------------------------------------------------------<br /> EXPORT VectorTable<br /><br />VectorTable<br /> ldr pc, [pc, #&18] ; SoftReset<br /> ldr pc, [pc, #&18] ; UndefHandler<br /> ldr pc, [pc, #&18] ; SWIHandler<br /> ;subs pc,r14,#8<br /> ldr pc, [pc, #&18] ; PrefetchAbortHandler<br /> ldr pc, [pc, #&18] ; DataAbortHandler<br /> nop ; Reserved<br /> ldr pc, [pc,#-0xF20] ; IRQ : read the AIC<br /> ldr pc, [pc,#-0xF20] ; FIQ : read the AIC<br /><br />;- There are only 5 offsets as the vectoring is used.<br /> DCD SoftReset<br /> DCD UndefHandler<br /> DCD SWIHandler<br /> DCD PrefetchAbortHandler<br /> DCD DataAbortHandler<br /><br />;- Vectoring Execution function run at absolute address<br />SoftReset<br /> b SoftReset<br />UndefHandler<br /> b UndefHandler<br />SWIHandler<br /> b SWIHandler<br />PrefetchAbortHandler<br /> b PrefetchAbortHandler<br />DataAbortHandler<br /> b DataAbortHandler<br />;--------------------<br />;- The reset handler<br />;--------------------<br />InitReset<br />;------------------------------------------------------------------------------<br />;- Low level Init (APMC, AIC, EBI, ....) by C function AT91F_LowLevelInit<br />;------------------------------------------------------------------------------<br /> IMPORT AT91F_LowLevelInit<br /><br />TOP_EXCEPTION_STACK EQU (TOP_INTERNAL_MEMORY+AT91C_SRAM_AFTER_REMAP_SIZE)<br />;- minimum C initialization<br /><br /> ldr r13,=TOP_EXCEPTION_STACK ; temporary stack in internal Ram<br /> ldr r1,=TOP_INTERNAL_MEMORY<br /> add r0, pc,#-(8+.-VectorTable) ; @ where to read values (relative)<br /> bl AT91F_LowLevelInit<br /><br />;--------------------------------------------<br />;- Remap Command and jump on ABSOLUTE address<br />;--------------------------------------------<br /><br /> ldr r12, PtInitRemap ; Get the real jump address ( after remap )<br /> mov r1,#AT91C_EBI_RCB ; Get the REMAP value<br /> str r1, [r0] ; Store the complete image with the remap command<br /><br /> ;ldr r0,=AT91C_EBI_RCR<br /> ;mov r1,#6<br /> ;str r1, [r0]<br /> <br />;- Jump to LINK address at its absolute address<br /> mov pc, r12 ; Jump and break the pipeline<br /><br />PtInitRemap<br /> DCD InitRemap ; Address where to jump after REMAP<br />;------------------------------------------------------------------------------<br />;- The Reset Handler after Remap<br />;-------------------------------<br />;- From here, the code is executed from its link address, ie. 0x100 0000.<br />;------------------------------------------------------------------------------<br />InitRemap<br /><br />;------------------------------------------------------------------------------<br />;- Stack Sizes Definition<br />;------------------------<br />;- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using<br />;- the vectoring. This assume that the IRQ_ENTRY/IRQ_EXIT macro are used.<br />;- The Interrupt Stack must be adjusted depending on the interrupt handlers.<br />;- Fast Interrupt not requires stack If in your application it required you must<br />;- be define here.<br />;- Other stacks are defined by default to save one word each.<br />;- The System stack size is not defined and is limited by the free internal<br />;- SRAM.<br />;- User stack size is not defined and is limited by the free external SRAM.<br />;------------------------------------------------------------------------------<br /><br />IRQ_STACK_SIZE EQU (1024*8*4) ; 2 words per interrupt priority level<br />FIQ_STACK_SIZE EQU (30*4) ; 0 words<br />ABT_STACK_SIZE EQU (30*4) ; 1 word<br />UND_STACK_SIZE EQU (30*4) ; 1 word<br /><br /><br />;------------------------------------------------------------------------------<br />;- Setup the stack for each mode<br />;-------------------------------<br /> ldr r0, =EXT_SRAM_LIMIT<br /><br />;- Set up Fast Interrupt Mode and set FIQ Mode Stack<br /> msr CPSR_c, #ARM_MODE_FIQ:OR:I_BIT:OR:F_BIT<br /> mov r13, r0 ; Init stack FIQ<br /> sub r0, r0, #FIQ_STACK_SIZE<br /><br />;- Set up Interrupt Mode and set IRQ Mode Stack<br /> msr CPSR_c, #ARM_MODE_IRQ:OR:I_BIT:OR:F_BIT<br /> mov r13, r0 ; Init stack IRQ<br /> sub r0, r0, #IRQ_STACK_SIZE<br /><br />;- Set up Abort Mode and set Abort Mode Stack<br /> msr CPSR_c, #ARM_MODE_ABORT:OR:I_BIT:OR:F_BIT<br /> mov r13, r0 ; Init stack Abort<br /> sub r0, r0, #ABT_STACK_SIZE<br /><br />;- Set up Undefined Instruction Mode and set Undef Mode Stack<br /> msr CPSR_c, #ARM_MODE_UNDEF:OR:I_BIT:OR:F_BIT<br /> mov r13, r0 ; Init stack Undef<br /> sub r0, r0, #UND_STACK_SIZE<br /><br />;- Set up Supervisor Mode and set Supervisor Mode Stack<br /> msr CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT<br /> mov r13, r0 ; Init stack Sup<br /><br />;------------------------------------------------------------------------------<br />;- Before Init C Initialize C variables you can copy the from FLASH to RAM<br />;------------------------------------------------------------------------------<br /><br />;Enable interrupt<br /> msr CPSR_c, #ARM_MODE_SVC :OR: F_BIT<br /><br />;------------------------------------------------------------------------------<br />;- Initialise C variables<br />;------------------------<br />;- Following labels are automatically generated by the linker. <br />;- RO: Read-only = the code<br />;- RW: Read Write = the data pre-initialized and zero-initialized.<br />;- ZI: Zero-Initialized.<br />;- Pre-initialization values are located after the code area in the image.<br />;- Zero-initialized datas are mapped after the pre-initialized.<br />;- Note on the Data position : <br />;- If using the ARMSDT, when no -rw-base option is used for the linker, the <br />;- data area is mapped after the code. You can map the data either in internal<br />;- SRAM ( -rw-base=0x40 or 0x34) or in external SRAM ( -rw-base=0x2000000 ).<br />;- Note also that to improve the code density, the pre_initialized data must <br />;- be limited to a minimum.<br />;------------------------------------------------------------------------------<br /> IF :DEF:RAMRUN<br /> IMPORT |Image$$EXSRAM$$Base| ; End of ROM code (=start of ROM data)<br /> IMPORT |Image$$EXSRAM$$Length| ; End of ROM code (=start of ROM data)<br /> IMPORT |Load$$EXSRAM$$Base| ; Base of RAM to initialise<br /> IMPORT |Image$$EXSRAM$$ZI$$Base| ; Base and limit of area<br /> IMPORT |Image$$EXSRAM$$ZI$$Limit| ; to zero initialise<br /> <br /> IMPORT |Image$$INTERSRAM$$Base|<br /> IMPORT |Image$$INTERSRAM$$Length|<br /> IMPORT |Load$$INTERSRAM$$Base|<br /> IMPORT |Image$$INTERSRAM$$ZI$$Base|<br /> IMPORT |Image$$INTERSRAM$$ZI$$Limit|<br /> <br /> ldr r0, =|Load$$INTERSRAM$$Base| ; Get pointer to ROM data<br /> ldr r1, =|Image$$INTERSRAM$$Base| ; and RAM copy<br /> ldr r4, =|Image$$INTERSRAM$$Length| ; and RAM copy<br /> ldr r3, =|Image$$INTERSRAM$$ZI$$Base| ; Zero init base => top of initialised data<br /> cmp r0, r1 ; Check that they are different<br /> beq NoRW1<br /><br />LoopRw1 cmp r1, r3 ; Copy init data<br /><br /> ldrcc r2, [r0], #4 <br /> strcc r2, [r1], #4<br /> bcc LoopRw1<br /><br />NoRW1 ldr r1, =|Image$$INTERSRAM$$ZI$$Limit| ; Top of zero init segment<br /> mov r2, #0<br />LoopZI1 cmp r3, r1 ; Zero init<br /> strcc r2, [r3], #4<br /> bcc LoopZI1<br /> <br /><br /> <br /><br /> ldr r0, =|Load$$EXSRAM$$Base| ; Get pointer to ROM data<br /> ldr r1, =|Image$$EXSRAM$$Base| ; and RAM copy<br /> ldr r4, =|Image$$EXSRAM$$Length| ; and RAM copy<br /> ldr r3, =|Image$$EXSRAM$$ZI$$Base| ; Zero init base => top of initialised data<br /> cmp r0, r1 ; Check that they are different<br /> beq NoRW<br /><br />LoopRw cmp r1, r3 ; Copy init data<br /><br /> ldrcc r2, [r0], #4 <br /> strcc r2, [r1], #4<br /> bcc LoopRw<br /><br />NoRW ldr r1, =|Image$$EXSRAM$$ZI$$Limit| ; Top of zero init segment<br /> mov r2, #0<br />LoopZI cmp r3, r1 ; Zero init<br /> strcc r2, [r3], #4<br /> bcc LoopZI<br /> ENDIF<br /><br />;- Branch must be performed by an interworking call as either an ARM or Thumb<br />;- main C function must be supported. This makes the code not position-<br />;- independent. A Branch with link would generate errors<br />;------------------------------------------------------------------------------<br /> IF :DEF:RAMRUN<br /> IMPORT main<br /> <br /> ldr r0, =main<br /> mov lr, pc<br /> bx r0<br /> <br /> ELSE<br /> IMPORT __main<br /> <br /> ldr r0, =__main<br /> mov lr, pc<br /> bx r0<br /> ENDIF <br /> <br />;------------------------------------------------------------------------------<br />;- Loop for ever<br />;---------------<br />;- End of application. Normally, never occur.<br />;- Could jump on Software Reset ( B 0x0 ).<br />;------------------------------------------------------------------------------<br />End<br /> b End<br /><br /><br /><br /><br />;------------------------------------------------------------------------------<br />;- Manage exception<br />;---------------<br />;- The exception must be ensure in ARM mode<br />;------------------------------------------------------------------------------<br /><br /> EXPORT AT91F_Default_FIQ_handler<br />AT91F_Default_FIQ_handler<br /> b AT91F_Default_FIQ_handler<br /><br /><br /> EXPORT AT91F_Default_IRQ_handler<br />AT91F_Default_IRQ_handler<br /> b AT91F_Default_IRQ_handler<br /><br /> EXPORT AT91F_Spurious_handler<br />AT91F_Spurious_handler<br /> b AT91F_Spurious_handler<br /><br /> END<br /><br /> |
|