00001 /** 00002 * @file crt0.S 00003 * 00004 * @brief Doxygen doesn't handle assembly code well. Look at the source code instead. 00005 * 00006 * Use only one of crt0.S and crt0.c 00007 * 00008 * An assembler file modified by Scott Craig from gcrt1.S 00009 * 00010 * For use in Mantis Cheng's CSC 460 Fall 2007 00011 * 00012 * To use this as startup code in AVR Studio, 00013 * add "-nostartfiles" to [Linker Options] 00014 * in Project>Configuration options>Custom Options. 00015 * 00016 * The name of the function in the last call is where the program starts. 00017 * (For project 2 it should be "OS_Init".) 00018 */ 00019 00020 /* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl> 00021 Copyright (c) 2007, Eric B. Weddington 00022 All rights reserved. 00023 00024 Redistribution and use in source and binary forms, with or without 00025 modification, are permitted provided that the following conditions are met: 00026 00027 * Redistributions of source code must retain the above copyright 00028 notice, this list of conditions and the following disclaimer. 00029 00030 * Redistributions in binary form must reproduce the above copyright 00031 notice, this list of conditions and the following disclaimer in 00032 the documentation and/or other materials provided with the 00033 distribution. 00034 00035 * Neither the name of the copyright holders nor the names of 00036 contributors may be used to endorse or promote products derived 00037 from this software without specific prior written permission. 00038 00039 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00040 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00041 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00042 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00043 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00044 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00045 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00046 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00047 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00048 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00049 POSSIBILITY OF SUCH DAMAGE. */ 00050 00051 #include <avr/io.h> 00052 #include <avr/sfr_defs.h> 00053 00054 /** 00055 * gcc expects this register to contain 0. This loses the use 00056 * of one register, but it speeds up operations such as 00057 * clearing a memory location. 00058 */ 00059 #define __zero_reg__ r1 00060 00061 /** 00062 * A macro to simplify the vector list. 00063 * 00064 * The symbol "__vector_i" is weakly bound to this spot in the 00065 * object file. Later, other object files can reference this 00066 * spot using this symbol. 00067 * 00068 * The value of the symbol is set to "__vector_not_set", 00069 * which is the label of a function below. Other files will 00070 * change this if an ISR is declared. 00071 * 00072 * The instruction at this spot is "jmp (addr)" (4 bytes). 00073 * These addresses are hardwired in the mcu. 00074 */ 00075 .macro vector name 00076 .weak \name 00077 .set \name, __vector_not_set 00078 jmp \name 00079 .endm 00080 00081 /** The vectors section. 00082 * 00083 * The numbers are off by 1 from the hardware manual, 00084 * but consistent with iousbxx6_7.h. 00085 * Vector "0" is the reset vector, which jumps to the 00086 * executable code. 00087 * 00088 * Any interrupt ISR definition in the C code will 00089 * overwrite these default definitions. 00090 */ 00091 .section .vectors,"ax",@progbits 00092 .global __vectors 00093 .func __vectors 00094 __vectors: 00095 jmp __init 00096 vector __vector_1 00097 vector __vector_2 00098 vector __vector_3 00099 vector __vector_4 00100 vector __vector_5 00101 vector __vector_6 00102 vector __vector_7 00103 vector __vector_8 00104 vector __vector_9 00105 vector __vector_10 00106 vector __vector_11 00107 vector __vector_12 00108 vector __vector_13 00109 vector __vector_14 00110 vector __vector_15 00111 vector __vector_16 00112 vector __vector_17 00113 vector __vector_18 00114 vector __vector_19 00115 vector __vector_20 00116 vector __vector_21 00117 vector __vector_22 00118 vector __vector_23 00119 vector __vector_24 00120 vector __vector_25 00121 vector __vector_26 00122 vector __vector_27 00123 vector __vector_28 00124 vector __vector_29 00125 vector __vector_30 00126 vector __vector_31 00127 vector __vector_32 00128 vector __vector_33 00129 vector __vector_34 00130 vector __vector_35 00131 vector __vector_36 00132 vector __vector_37 00133 .endfunc 00134 00135 /** 00136 * A default routine that is called when an interrupt occurs 00137 * for which no ISR was assigned. The default action is to reset, 00138 * but it could be changed to do something else. 00139 */ 00140 .text 00141 .global __vector_not_set 00142 .func __vector_not_set 00143 __vector_not_set: 00144 jmp __vectors 00145 .endfunc 00146 00147 /** 00148 * The beginning of the executable code in this file. 00149 * The section names tell the linker where to place the 00150 * code as specified in the linker script. eg. avr5.x 00151 */ 00152 .section .init0,"ax",@progbits 00153 .weak __init 00154 __init: 00155 .weak __stack 00156 .set __stack, RAMEND 00157 .weak __heap_end 00158 .set __heap_end, 0 00159 00160 /** 00161 * init2 00162 * 00163 * Clear the "zero" register, 00164 * clear the status register, and 00165 * set the stack pointer. 00166 */ 00167 .section .init2,"ax",@progbits 00168 clr __zero_reg__ 00169 out _SFR_IO_ADDR(SREG), __zero_reg__ 00170 ldi r28,lo8(__stack) 00171 ldi r29,hi8(__stack) 00172 out _SFR_IO_ADDR(SPH), r29 00173 out _SFR_IO_ADDR(SPL), r28 00174 00175 /** 00176 * init4 00177 * 00178 * Copy data from __data_load_start in program memory 00179 * to __data_start in SRAM, initializing data in the process. 00180 * A similar routine with the same name is defined in libgcc.S. 00181 * This routine overrides it. 00182 */ 00183 .section .init4,"ax",@progbits 00184 .global __do_copy_data 00185 __do_copy_data: 00186 ldi r17, hi8(__data_end) 00187 ldi r26, lo8(__data_start) 00188 ldi r27, hi8(__data_start) 00189 ldi r30, lo8(__data_load_start) 00190 ldi r31, hi8(__data_load_start) 00191 ldi r16, hh8(__data_load_start) 00192 out _SFR_IO_ADDR(RAMPZ), r16 00193 rjmp .L__do_copy_data_start 00194 .L__do_copy_data_loop: 00195 elpm r0, Z+ 00196 st X+, r0 00197 .L__do_copy_data_start: 00198 cpi r26, lo8(__data_end) 00199 cpc r27, r17 00200 brne .L__do_copy_data_loop 00201 00202 00203 /* set all unitialized data in .bss to 0 00204 * Already included in libgcc.S */ 00205 /* 00206 .global __do_clear_bss 00207 __do_clear_bss: 00208 ldi r17, hi8(__bss_end) 00209 ldi r26, lo8(__bss_start) 00210 ldi r27, hi8(__bss_start) 00211 rjmp .do_clear_bss_start 00212 .do_clear_bss_loop: 00213 st X+, __zero_reg__ 00214 .do_clear_bss_start: 00215 cpi r26, lo8(__bss_end) 00216 cpc r27, r17 00217 brne .do_clear_bss_loop 00218 */ 00219 00220 /** init9 00221 * 00222 * The last of the init functions. 00223 * Usually this would be the jump to "main()" 00224 */ 00225 .section .init9,"ax",@progbits 00226 call OS_Init 00227 00228 /** exit is defined in libgcc.S. It is an rjmp to itself. 00229 * If the function called in init9 returns, it returns 00230 * here. 00231 */ 00232 jmp exit 00233 00234