Main Page   Modules   Data Structures   File List   Globals  

memory.c

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2002, 2003, Oliver Tscherwitschke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice,
00009    this list of conditions and the following disclaimer.
00010 2. Redistributions in binary form must reproduce the above copyright notice,
00011    this list of conditions and the following disclaimer in the documentation
00012    and/or other materials provided with the distribution.
00013 3. The name of the author may not be used to endorse or promote products
00014    derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
00017 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00019 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00021 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00022 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00023 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00035 #include <avr/io.h>
00036 #include <stddef.h>
00037 #include <avr/interrupt.h>
00038 
00039 #include "otos_cfg.h"
00040 #include "otos_def.h"
00041 #include "types.h"
00042 #include "task.h"
00043 #include "memory.h"
00044 
00045 
00046 #ifndef OTOS_BANKING
00047     #define NUMBER_OF_BANKS 1
00048 #endif
00049 
00050 extern size_t __bss_end;
00051 
00052 
00053 /*
00054  * check memory configuration
00055  */
00056 
00057 #if XRAMEND > RAMEND                                /* AVR supports external RAM */
00058     #if EXTERNAL_RAM_END > EXTERNAL_RAM_START       /* available ext. RAM defined and reasonable */
00059 
00060         #define XRAM_AVAILABLE
00061 
00062         #if EXTERNAL_RAM_START == (RAMEND + 1)      /* ext. RAM is contiguous to int. RAM */
00063             #define XRAM_CONTIGUOUS
00064         #endif
00065 
00066         #ifndef OTOS_BANKING
00067             #define USE_XRAM_FOR_HEAP               /* use ext. RAM for heap if no banking is used */
00068         #endif
00069     #endif
00070 #endif
00071 
00072 
00073 static otos_size_t  s_nextFreeInt = (otos_size_t) &__bss_end;   /* first free address in int. RAM */
00074 
00075 
00076 #if (defined USE_XRAM_FOR_HEAP) && (!defined XRAM_CONTIGUOUS)
00077 
00078 static otos_size_t  s_nextFreeExt = EXTERNAL_RAM_START;         /* first free address in ext. RAM */
00079 
00096 void* otosAllocate(otos_size_t size)
00097 {
00098     void*               pMem;
00099     uint8_t             iStat;
00100     otos_size_t         blockSize;
00101 
00102 
00103     iStat = SREG;                                   /* save cpu status register (i-bit) */
00104     cli();
00105 
00106     /* try internal RAM */
00107     blockSize = RAMEND - s_nextFreeInt + 1;
00108     if (size <= blockSize)                          /* block is big enough */
00109     {
00110         pMem = (void*) s_nextFreeInt;
00111         s_nextFreeInt += size;
00112     }
00113     else    
00114     {
00115         /* try external RAM */
00116         blockSize = EXTERNAL_RAM_END - s_nextFreeExt + 1;
00117         if (size <= blockSize)                      /* block is big enough */
00118         {
00119             pMem = (void*) s_nextFreeExt;
00120             s_nextFreeExt += size;
00121         }
00122         else                                        /* block is not big enough */
00123             pMem = NULL;
00124     }    
00125 
00126     /* enable interrupts again */
00127     SREG = iStat;                                   /* restore status register (i-bit) */
00128 
00129     return pMem;
00130 }
00131 
00132 #else
00133 
00150 void* otosAllocate(otos_size_t size)
00151 {
00152     void*               pMem;
00153     uint8_t             iStat;
00154     otos_size_t         blockSize;
00155 
00156 
00157     iStat = SREG;                               /* save cpu status register (i-bit) */
00158     cli();
00159 
00160 #if (defined USE_XRAM_FOR_HEAP) && (defined XRAM_CONTIGUOUS)
00161     blockSize = EXTERNAL_RAM_END - s_nextFreeInt + 1;
00162 #else
00163     blockSize = RAMEND - s_nextFreeInt + 1;
00164 #endif
00165 
00166     if (size <= blockSize)                      /* block is big enough */
00167     {
00168         pMem = (void*) s_nextFreeInt;
00169         s_nextFreeInt += size;
00170     }
00171     else                                        /* block is not big enough */
00172         pMem = NULL;
00173 
00174     /* enable interrupts again */
00175     SREG = iStat;                               /* restore status register (i-bit) */
00176 
00177     return pMem;
00178 }
00179 
00180 #endif
00181 
00182 
00190 otos_size_t otosGetFreeHeap(void)
00191 {
00192     otos_size_t free;
00193 
00194 
00195     free = RAMEND - s_nextFreeInt + 1
00196 #if (defined USE_XRAM_FOR_HEAP)
00197             + EXTERNAL_RAM_END - s_nextFreeExt + 1
00198 #endif
00199             ;
00200 
00201     return free;
00202 }
00203 
00204 
00205 /* this functions are only needed, if we support banking */
00206 
00207 #ifdef OTOS_BANKING
00208 
00216 inline void otosSetRamBank(uint8_t bank)
00217 {
00218     SET_RAM_BANK(bank);
00219 }
00220 
00221 
00229 inline uint8_t otosGetRamBank(void)
00230 {
00231     return GET_RAM_BANK();
00232 }
00233 
00234 
00245 void* otosAllocateBanked(otos_size_t size, uint8_t bank)
00246 {
00247     static otos_size_t  s_nextFreeAddr[NUMBER_OF_BANKS];
00248     otos_size_t         mem;
00249     uint8_t             iStat;
00250 
00251 
00252     iStat = SREG;                   /* save cpu status register (i-bit) */
00253     cli();
00254 
00255     if ((s_nextFreeAddr[bank] + size) <= (EXTERNAL_RAM_END - EXTERNAL_RAM_START + 1))
00256     {
00257         mem = s_nextFreeAddr[bank] + EXTERNAL_RAM_START;
00258         s_nextFreeAddr[bank] += size;
00259     }
00260     else
00261         mem = 0;
00262 
00263     /* enable interrupts again */
00264     SREG = iStat;                   /* restore status register (i-bit) */
00265 
00266     return (void*) mem;
00267 }
00268 
00269 #endif
00270 
00271 

Generated on Sat Jan 25 18:41:43 2003 for otOS by doxygen1.3-rc2