crt0.c

Go to the documentation of this file.
00001 /** @file crt0.c
00002  *
00003  * @brief A C runtime
00004  *
00005  * Use only one of crt0.S and crt0.c
00006  *
00007  * This file is adapted from grct1.S in the avr source.
00008  *
00009  * For use in Mantis Cheng's CSC 460 Fall 2007
00010  *
00011  * To use this as startup code in AVR Studio,
00012  * add "-nostartfiles" to [Linker Options]
00013  * in Project>Configuration options>Custom Options.
00014  *
00015  * The name of the function in the last call is where the program starts.
00016  * (For project 2 it should be "OS_Init".)
00017  *
00018  * @author Scott Craig
00019  * @author Justin Tanner
00020  */
00021 
00022 #include <avr/io.h>
00023 #include <avr/sfr_defs.h>
00024 
00025 #include "os.h"
00026 
00027 /** The "zero" register*/
00028 #define zero_reg  "r1"
00029 
00030 /**
00031  * @brief A macro to simplify the vector list.
00032  *
00033  * The symbol "__vector_i" is weakly bound to this spot in the
00034  * object file. Later, other object files can reference this
00035  * spot using this symbol.
00036  *
00037  * The value of the symbol is set to "__vector_not_set",
00038  * which is the label of a function below. Other files will
00039  * change this if an ISR is declared.
00040  *
00041  * The instruction at this spot is "jmp (addr)" (4 bytes).
00042  * These addresses are hardwired in the mcu.
00043  */
00044 #define   vector(name)  asm(\
00045     ".weak "  name "\n\t"\
00046     ".set  "  name " , __vector_not_set\n\t"\
00047     "jmp   "  name "\n\t"::);
00048 
00049 
00050 /**
00051  * @brief The vectors section.
00052  *
00053  * The numbers are off by 1 from the hardware manual,
00054  * but consistent with iousbxx6_7.h.
00055  * Vector "0" is the reset vector, which jumps to the
00056  * executable code.
00057  *
00058  * Any interrupt ISR definition in the C code will
00059  * overwrite these default definitions.
00060  */
00061 void __vectors (void) __attribute__ ((naked)) __attribute__ ((section (".vectors")));
00062 void __vectors (void)
00063 {
00064     asm("jmp        __init\n"::);
00065 
00066     vector("__vector_1");
00067     vector("__vector_2");
00068     vector("__vector_3");
00069     vector("__vector_4");
00070     vector("__vector_5");
00071     vector("__vector_6");
00072     vector("__vector_7");
00073     vector("__vector_8");
00074     vector("__vector_9");
00075     vector("__vector_10");
00076     vector("__vector_11");
00077     vector("__vector_12");
00078     vector("__vector_13");
00079     vector("__vector_14");
00080     vector("__vector_15");
00081     vector("__vector_16");
00082     vector("__vector_17");
00083     vector("__vector_18");
00084     vector("__vector_19");
00085     vector("__vector_20");
00086     vector("__vector_21");
00087     vector("__vector_22");
00088     vector("__vector_23");
00089     vector("__vector_24");
00090     vector("__vector_25");
00091     vector("__vector_26");
00092     vector("__vector_27");
00093     vector("__vector_28");
00094     vector("__vector_29");
00095     vector("__vector_30");
00096     vector("__vector_31");
00097     vector("__vector_32");
00098     vector("__vector_33");
00099     vector("__vector_34");
00100     vector("__vector_35");
00101     vector("__vector_36");
00102     vector("__vector_37");
00103 }
00104 
00105 
00106 /**
00107  * @fn __vector_not_set
00108  *
00109  * @brief A default routine that is called when an interrupt occurs
00110  * for which no ISR was assigned. 
00111  *
00112  * The default action is to reset,
00113  * but it could be changed to do something else.
00114  */   
00115 void __vector_not_set (void) __attribute__ ((naked)) __attribute__ ((section (".text")));
00116 void __vector_not_set (void)
00117 {
00118     asm("jmp    __vectors\n\t"::);
00119 }
00120 
00121 
00122 /**
00123  * @brief The beginning of the executable code in this file.
00124  *
00125  * The section names tell the linker where to place the
00126  * code as specified in the linker script. eg. avr5.x
00127  */
00128 void __init (void) __attribute__ ((naked)) __attribute__ ((section (".init0")));
00129 void __init (void)
00130 {
00131     asm(".weak    __init\n\t"
00132         "__init:\n\t"
00133         ".weak    __heap_end\n\t"
00134         ".set    __heap_end, 0\n\t"::);
00135 }
00136 
00137     
00138 /**
00139  * @brief init2
00140  *
00141  * Clear the "zero" register,
00142  * clear the status register, and
00143  * set the stack pointer.
00144  */
00145 void init2 (void) __attribute__ ((naked)) __attribute__ ((section (".init2")));
00146 void init2 (void)
00147 {
00148     asm("clr   " zero_reg "\n\t"::);
00149 
00150     SREG = 0;
00151     SP = RAMEND;
00152 }
00153 
00154 
00155 /** 
00156  * @brief init4
00157  *
00158  * Copy data from __data_load_start in program memory
00159  * to __data_start in SRAM, initializing data in the process.
00160  * A similar routine with the same name is defined in libgcc.S.
00161  * This routine overrides it.
00162  */
00163 void __do_copy_data (void) __attribute__ ((naked)) __attribute__ ((section (".init4")));
00164 void __do_copy_data (void)
00165 {
00166     asm(
00167     "ldi    r17, hi8(__data_end) \n"
00168     "ldi    r26, lo8(__data_start) \n"
00169     "ldi    r27, hi8(__data_start) \n"
00170     "ldi    r30, lo8(__data_load_start) \n"
00171     "ldi    r31, hi8(__data_load_start) \n"
00172     "ldi    r16, hh8(__data_load_start) \n"
00173     "out    %0, r16 \n"
00174     "rjmp    .L__do_copy_data_start \n"
00175 ".L__do_copy_data_loop: \n"
00176     "elpm    r0, Z+ \n"
00177     "st    X+, r0 \n"
00178 ".L__do_copy_data_start: \n"
00179     "cpi    r26, lo8(__data_end) \n"
00180     "cpc    r27, r17 \n"
00181     "brne    .L__do_copy_data_loop \n"::"I" (_SFR_IO_ADDR(RAMPZ)));
00182 
00183 }
00184 
00185     /* set all unitialized data in .bss to 0
00186      * Already included in libgcc.S */
00187 /*
00188     .global __do_clear_bss
00189 __do_clear_bss:
00190     ldi    r17, hi8(__bss_end)
00191     ldi    r26, lo8(__bss_start)
00192     ldi    r27, hi8(__bss_start)
00193     rjmp    .do_clear_bss_start
00194 .do_clear_bss_loop:
00195     st    X+, __zero_reg__
00196 .do_clear_bss_start:
00197     cpi    r26, lo8(__bss_end)
00198     cpc    r27, r17
00199     brne    .do_clear_bss_loop
00200 */
00201 
00202 /** @brief init9
00203  *
00204  * The last of the init functions.
00205  * Usually this would be the jump to "main()"
00206  */
00207 void init9 (void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
00208 void init9 (void)
00209 {
00210     OS_Init();
00211 
00212     for(;;);
00213 
00214 
00215     /** exit is defined in libgcc.S. It is an rjmp to itself.
00216      * If the function called in init9 returns, it returns
00217      * here.
00218      */
00219     /* jmp    exit */
00220 
00221 }

Generated on Tue Oct 23 21:49:51 2007 for RTOS by  doxygen 1.5.1