Вот... CSTARTUP
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено JTAG 17 августа 2003 г. 17:21
В ответ на: Стартап кинь, тот который на ассемблере. отправлено si 17 августа 2003 г. 17:01

;-----------------------------------------------------------------------------
; This file contains the startup code used by the ICCARM C compiler.
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbols ?cstartup etc.
; If this entire file is assembled and linked with the provided
; libraries, the XLINK option -C must be used to avoid a clash with
; PROGRAM module ?RESET.
; EWARM also has a check box to "Ignore CSTARTUP in library", that has
; the same effect.
;
; All code in the modules (except ?RESET) will be placed in the ICODE segment,
; that must be reachable by a B instruction in ARM mode from segment INTVEC
; (within the first 32 Mbytes).
;
; Define preprocessor symbol __THUMB_LIBRARY__ for Thumb libraries
; or __ARM_LIBRARIES__ for ARM libraries.
;
; $Revision: 1.2 $
;
;-----------------------------------------------------------------------------

#include "config.h"

; Make sure that __ARM_LIBRARY__ or __THUMB_LIBRARY__ is defined

#ifdef __ARM_LIBRARY__
#ifdef __THUMB_LIBRARY__
#error "Cannot have both __ARM_LIBRARY__ and __THUMB_LIBRARY__ set!"
#endif
#else
#ifndef __THUMB_LIBRARY__
#error "Must have one of __ARM_LIBRARY__ or __THUMB_LIBRARY__ set!"
#endif
#endif


;
; Naming covention of labels in this file:
;
; ?xxx - External labels only accessed from assembler.
; __xxx - External labels accessed from or defined in C.
; xxx - Labels local to one module (note: this file contains
; several modules).
; main - The starting point of the user program.
;

;---------------------------------------------------------------
; Macros and definitions for the whole file
;---------------------------------------------------------------

; Mode, correspords to bits 0-5 in CPSR
MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR
USR_MODE DEFINE 0x10 ; User mode
FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
SVC_MODE DEFINE 0x13 ; Supervisor mode
ABT_MODE DEFINE 0x17 ; Abort mode
UND_MODE DEFINE 0x1B ; Undefined Instruction mode
SYS_MODE DEFINE 0x1F ; System mode

#if __LITTLE_ENDIAN__==1
; RTMODEL attribute __endian

#define ENDIAN_MODE "little"

#else
#define ENDIAN_MODE "big"
#endif


#ifdef __THUMB_LIBRARY__

; RTMODEL attribute __cpu_mode
#define CPU_MODE_NAME "thumb"
; Segment used for libraries
#define LIB_SEGMENT NEARFUNC_T
SEGMENT_ALIGN DEFINE 1 ; Align Thumb segments to 2^1

CPU_MODE MACRO
CODE16
ENDM

#else ;;;;;;; __ARM_LIBRARY__

; RTMODEL attribute __cpu_mode
#define CPU_MODE_NAME "arm"
; Segment used for libraries
#define LIB_SEGMENT NEARFUNC_A
SEGMENT_ALIGN DEFINE 2 ; Align ARM segments to 2^2

CPU_MODE MACRO
CODE32
ENDM

#endif


;---------------------------------------------------------------
; ?RESET
; Reset Vector.
; Normally, segment INTVEC is linked at address 0.
; For debugging purposes, INTVEC may be placed at other
; addresses.
; A debugger that honors the entry point will start the
; program in a normal way even if INTVEC is not at address 0.
;---------------------------------------------------------------

PROGRAM ?RESET
COMMON INTVEC:CODE:ROOT(2)
EXTERN ?boot
CODE32 ; Always ARM mode after reset
org 0
reset B ?boot
; org 18h
; ldr pc,[pc,#-0xf20]
; ldr pc,[pc,#-0xf20]
ENDMOD

;---------------------------------------------------------------
; ?BOOT
;---------------------------------------------------------------
PROGRAM ?BOOT
RSEG ICODE:CODE:NOROOT(2)
EXTERN ?cstartup
CODE32
PUBLIC ?boot
?boot:
;#if AT91_REMAP
; The memory controller is initialized immediately before the remap
ldr r10, =EBI_init_table ; EBI register initialization table
; If pc > 0x100000
movs r0, pc, LSR #20
; Mask the 12 highest bits of the address
moveq r10, r10, LSL #12
moveq r10, r10, LSR #12

; Load the address where to jump
ldr r12, =after_remap ; 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
; this instruction was loaded into the pipeline before the remap was done
mov pc, r12 ; jump and break the pipeline

; Put constant table here.
LTORG

; EBI initialization table
; 32,768 MHz master clock assumed for timing
EBI_init_table:
dc32 0x01002529 ; Flash at 0x01000000, 16MB, 2 hold, 16 bits, 3 WS
dc32 0x20000000 ; RAM at 0x02000000, 1MB, 0 hold, 16 bits, 1 WS
dc32 0x20000000 ; unused
dc32 0x30000000 ; unused
dc32 0x40000000 ; unused
dc32 0x50000000 ; unused
dc32 0x60000000 ; unused
dc32 0x70000000 ; unused
dc32 0x00000001 ; REMAP command
dc32 0x00000006 ; standard read
dc32 __EBI_CSR0 ; EBI Base address

after_remap:
;#endif
; Execute C startup code.
b ?cstartup
ENDMOD ?boot ; Entry point = ?boot

;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
PROGRAM ?CSTARTUP

; RTMODEL attributes ensure that
RTMODEL "__rt_version", "4"
RTMODEL "__endian", ENDIAN_MODE
RTMODEL "__thumb_aware", "enabled"
RTMODEL "__cpu_mode", "*" ; CPU_MODE_NAME
RTMODEL "__code_model", "*" ; Match all code models

; Declare segment used with SFE below
#ifdef _ECPLUSPLUS
RSEG DIFUNCT(2)
#endif /* _ECPLUSPLUS */

RSEG IRQ_STACK:DATA(2)
RSEG SVC_STACK:DATA:NOROOT(2)
RSEG CSTACK:DATA(2)
RSEG ICODE:CODE:NOROOT(2)
PUBLIC ?cstartup
EXTERN __segment_init
EXTERN __low_level_init
#ifdef _ECPLUSPLUS
EXTERN __call_ctors
#endif /* _ECPLUSPLUS */
EXTERN main
EXTERN exit
EXTERN _exit

; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.

LTORG

CODE32
?cstartup

; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.
mrs r0,cpsr ; Original PSR value
bic r0,r0,#MODE_BITS ; Clear the mode bits
orr r0,r0,#IRQ_MODE ; Set IRQ mode bits
msr cpsr_c,r0 ; Change the mode
ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; End of IRQ_STACK

; Changed to the preferred mode
bic r0,r0,#MODE_BITS ; Clear the mode bits
orr r0,r0,#SVC_MODE ; Set Supervisor mode bits
msr cpsr_c,r0 ; Change the mode
ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK

; Change to the preferred intsruction set
#ifdef __THUMB_LIBRARY__
adr r0,?thumb_entry ; bit 0 is set on a Thumb code label
bx r0
CODE16
PUBLIC ?thumb_entry ; Symbol to make debuggers happy
?thumb_entry

#endif

; Initialize segments.
; __segment_init and __low_level_init are assumed to use the same
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).
bl __low_level_init
cmp r0,#0
beq after_segment_init

bl __segment_init
b after_segment_init

LTORG

after_segment_init:

REQUIRE ?jump_to_main

; Call the constructors of all global objects. This code will only
; be used if any EC++ modules defines global objects that need to
; have its constructor called before main.

#ifdef _ECPLUSPLUS

RSEG ICODE:CODE:NOROOT(2)

PUBLIC ?call_ctors

?call_ctors:
LDR R0,=SFB(DIFUNCT)
LDR R1,=SFE(DIFUNCT)

bl __call_ctors
b after_call_ctors

LTORG

after_call_ctors:

#endif /* _ECPLUSPLUS */

; Jump to main, using BX. Set _exit as the return address.
; main may be located anywhere in memory, and be of
; either ARM or Thumb mode, since BX is used.
; main is assumed to return using BX (__interwork) if it is of
; a different mode than cstartup, otherwise it will return
; in the wrong mode, causing unpredicatble behaviour.
require _exit
RSEG ICODE:CODE:NOROOT(2)
PUBLIC __main
?jump_to_main:
ldr r0,=?call_exit
mov lr,r0 ; Return address = _exit
ldr r0,=main
__main:
bx r0

?call_exit:
ldr r4,=_exit
mov lr,r4
ldr r4,=exit
bx r4

; It is not possible to fall through to _exit, because it is linked
; in a different segment.

LTORG
ENDMOD


;-------------------------------------------------------------dl-sanl0.r79--
; ?_EXIT
; main may return an exit code in R0, or _exit may be called with
; the exit code in R0.
; If the exit code is needed for som reason, R0 should be stored
; in e.g. one of the registers R4-R7, so that the value is
; preserved when calling __call_dtors and _Close_all.
;---------------------------------------------------------------
MODULE ?_EXIT
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC _exit
; EXTERN ?jump_to_exit
REQUIRE ?jump_to_exit

CPU_MODE ; Either Thumb or ARM mode
_exit:
; Fall through to the next module

RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
; EXTERN ?exit_restore
; REQUIRE ?jump_to_exit
REQUIRE ?exit_restore
PUBLIC ?exit_save
?exit_save:
MOV R4, R0

; ENDMOD

;---------------------------------------------------------------
; ?CALL_DTORS
; This module is only linked if needed by atexit.
;---------------------------------------------------------------
; MODULE ?CALL_DTORS
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC __cstart_call_dtors
; EXTERN ?exit_save
EXTERN __call_dtors
REQUIRE ?exit_save

; CPU_MODE ; Either Thumb or ARM mode
; This label is required by "__record_needed_destruction".
__cstart_call_dtors:
bl __call_dtors
; Fall through to the next module
; ENDMOD


;---------------------------------------------------------------
; ?CALL_CLOSE
; This module is only linked if needed for closing files.
;---------------------------------------------------------------
; MODULE ?CALL_CLOSE
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC __cstart_closeall
EXTERN _Close_all
; EXTERN ?exit_save
REQUIRE ?exit_save

CPU_MODE ; Either Thumb or ARM mode
; This label is required by functions operating on files
__cstart_closeall:
bl _Close_all
; Fall through to the next module
; ENDMOD


;---------------------------------------------------------------
; ?_EXIT_END
; Restore the argument previously stored by the "save" section
; above.
;---------------------------------------------------------------
; MODULE ?_exit_end
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)

PUBLIC ?exit_restore
?exit_restore:
MOV R0, R4

;; Fall through to the __exit code below

; ENDMOD

;---------------------------------------------------------------
; ?JUMP_TO_EXIT
;---------------------------------------------------------------
; MODULE ?JUMP_TO_EXIT
RSEG LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
PUBLIC ?jump_to_exit
EXTERN __exit

CPU_MODE ; Either Thumb or ARM mode

; It is not possible to fall through to __exit, because the following
; module is only used when linking for debugging (XLINK -r).

?jump_to_exit:
bl __exit ; Thumb BL has longer reach than B
ENDMOD


;---------------------------------------------------------------
; ?__EXIT
; __exit is declared PUBWEAK, which makes XLINK skip this module
; if another module containing a PUBLIC __exit is linked.
;---------------------------------------------------------------

MODULE ?__EXIT
RSEG LIB_SEGMENT:CODE:NOROOT(2)
PUBWEAK __exit

CPU_MODE ; Either Thumb or ARM mode
__exit

#ifdef __THUMB_LIBRARY__
bx pc
nop
#endif

CODE32
b . ; Eternal loop

ENDMOD


;---------------------------------------------------------------
; ?INITTAB
; This module is only linked if needed by e.g. __segment_init.
; The INITTAB segment contains segment initialization entries.
; See segment_init.h.
;---------------------------------------------------------------
MODULE ?INITTAB
RSEG INITTAB:CONST(2) ; Declaration for SFB/SFE below
RSEG HUGE_C:CONST:NOROOT(2)
DATA
PUBLIC __segment_begin_INITTAB
PUBLIC __segment_end_INITTAB

__segment_begin_INITTAB DC32 SFB(INITTAB)
__segment_end_INITTAB DC32 SFE(INITTAB)

ENDMOD

END



Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru