bankmem.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00056 #include <sys/heap.h>
00057 
00063 
00064 #include <sys/bankmem.h>
00065 
00066 static char segbuf_empty;
00067 static u_long segbuf_total;
00068 static u_long segbuf_used;
00069 
00070 static char *segbuf_start;
00071 static char *segbuf_end;
00072 
00073 
00074 static char *segbuf_wp;
00075 static char segbuf_ws;
00076 static char *segbuf_rp;
00077 static char segbuf_rs;
00078 
00084 char *NutSegBufReset(void)
00085 {
00086     segbuf_rp = segbuf_wp = segbuf_start;
00087     segbuf_rs = segbuf_ws = 0;
00088     NutSegBufEnable(0);
00089     segbuf_empty = 1;
00090     segbuf_used = 0;
00091 
00092     return segbuf_start;
00093 }
00094 
00107 char *NutSegBufInit(size_t size)
00108 {
00109 
00110 #if NUTBANK_COUNT
00111     segbuf_start = (char *)(NUTBANK_START);
00112     segbuf_end = (char *)(NUTBANK_START) + NUTBANK_SIZE;
00113     segbuf_total = (u_long) NUTBANK_COUNT *(u_long) NUTBANK_SIZE;
00114 #else
00115     if (size == 0)
00116         size = NutHeapAvailable() / 2;
00117     if (segbuf_start) {
00118         NutHeapFree(segbuf_start);
00119     }
00120     if ((segbuf_start = NutHeapAlloc(size)) != 0)
00121         segbuf_end = segbuf_start + size;
00122     segbuf_total = size;
00123 #endif
00124 
00125     return NutSegBufReset();
00126 }
00127 
00140 char *NutSegBufWriteRequest(size_t * bcp)
00141 {
00142     if (segbuf_empty || segbuf_ws != segbuf_rs || segbuf_wp > segbuf_rp)
00143         *bcp = segbuf_end - segbuf_wp;
00144     else
00145         *bcp = segbuf_rp - segbuf_wp;
00146 
00147     NutSegBufEnable(segbuf_ws);
00148     return segbuf_wp;
00149 }
00150 
00163 char *NutSegBufReadRequest(size_t * bcp)
00164 {
00165     if (segbuf_empty)
00166         *bcp = 0;
00167     else if (segbuf_ws != segbuf_rs || segbuf_rp >= segbuf_wp)
00168         *bcp = segbuf_end - segbuf_rp;
00169     else if ((*bcp = segbuf_wp - segbuf_rp) == 0 && segbuf_ws == segbuf_rs)
00170         segbuf_empty = 1;
00171 
00172     NutSegBufEnable(segbuf_rs);
00173     return segbuf_rp;
00174 }
00175 
00187 char *NutSegBufWriteCommit(size_t bc)
00188 {
00189     if (bc) {
00190         segbuf_wp += bc;
00191         segbuf_empty = 0;
00192         segbuf_used += bc;
00193         if (segbuf_wp == segbuf_end) {
00194             segbuf_wp = segbuf_start;
00195 #if NUTBANK_COUNT > 0
00196             if (++segbuf_ws >= NUTBANK_COUNT)
00197                 segbuf_ws = 0;
00198 #endif
00199             NutSegBufEnable(segbuf_ws);
00200         }
00201     }
00202     return segbuf_wp;
00203 }
00204 
00216 char *NutSegBufReadCommit(size_t bc)
00217 {
00218     if (bc) {
00219         segbuf_rp += bc;
00220         segbuf_used -= bc;
00221         if (segbuf_rp == segbuf_end) {
00222             segbuf_rp = segbuf_start;
00223 #if NUTBANK_COUNT > 0
00224             if (++segbuf_rs >= NUTBANK_COUNT)
00225                 segbuf_rs = 0;
00226 #endif
00227             NutSegBufEnable(segbuf_rs);
00228         }
00229         if (segbuf_rp == segbuf_wp  && segbuf_rs == segbuf_ws)
00230             segbuf_empty = 1;
00231     }
00232     return segbuf_rp;
00233 }
00234 
00235 
00245 void NutSegBufWriteLast(size_t bc)
00246 {
00247     if (bc) {
00248         segbuf_wp += bc;
00249         segbuf_used += bc;
00250         segbuf_empty = 0;
00251         if (segbuf_wp == segbuf_end) {
00252             segbuf_wp = segbuf_start;
00253 #if NUTBANK_COUNT > 0
00254             if (++segbuf_ws >= NUTBANK_COUNT)
00255                 segbuf_ws = 0;
00256 #endif
00257         }
00258     }
00259     NutSegBufEnable(segbuf_rs);
00260 }
00261 
00271 void NutSegBufReadLast(size_t bc)
00272 {
00273     if (bc) {
00274         segbuf_rp += bc;
00275         segbuf_used -= bc;
00276         if (segbuf_rp == segbuf_end) {
00277             segbuf_rp = segbuf_start;
00278 #if NUTBANK_COUNT > 0
00279             if (++segbuf_rs >= NUTBANK_COUNT)
00280                 segbuf_rs = 0;
00281 #endif
00282         }
00283         if (segbuf_rp == segbuf_wp && segbuf_rs == segbuf_ws)
00284             segbuf_empty = 1;
00285     }
00286     NutSegBufEnable(segbuf_ws);
00287 }
00288 
00289 
00295 u_long NutSegBufAvailable(void)
00296 {
00297     return segbuf_total - segbuf_used;
00298 }
00299 
00305 u_long NutSegBufUsed(void)
00306 {
00307     return segbuf_used;
00308 }
00309 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/