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 
00059 #include <sys/heap.h>
00060 
00061 #include <stdint.h>
00062 
00068 
00069 #include <sys/bankmem.h>
00070 
00071 static char segbuf_empty;
00072 static uint32_t segbuf_total;
00073 static uint32_t segbuf_used;
00074 
00075 static char *segbuf_start;
00076 static char *segbuf_end;
00077 
00078 
00079 static char *segbuf_wp;
00080 static char segbuf_ws;
00081 static char *segbuf_rp;
00082 static char segbuf_rs;
00083 
00089 char *NutSegBufReset(void)
00090 {
00091     segbuf_rp = segbuf_wp = segbuf_start;
00092     segbuf_rs = segbuf_ws = 0;
00093     NutSegBufEnable(0);
00094     segbuf_empty = 1;
00095     segbuf_used = 0;
00096 
00097     return segbuf_start;
00098 }
00099 
00112 char *NutSegBufInit(size_t size)
00113 {
00114 
00115 #if NUTBANK_COUNT
00116     segbuf_start = (char *)(NUTBANK_START);
00117     segbuf_end = (char *)(NUTBANK_START) + NUTBANK_SIZE;
00118     segbuf_total = (uint32_t) NUTBANK_COUNT *(uint32_t) NUTBANK_SIZE;
00119 #else
00120     if (size == 0)
00121         size = NutHeapAvailable() / 2;
00122     if (segbuf_start) {
00123         NutHeapFree(segbuf_start);
00124     }
00125     if ((segbuf_start = NutHeapAlloc(size)) != 0)
00126         segbuf_end = segbuf_start + size;
00127     segbuf_total = size;
00128 #endif
00129 
00130     return NutSegBufReset();
00131 }
00132 
00145 char *NutSegBufWriteRequest(size_t * bcp)
00146 {
00147     if (segbuf_empty || segbuf_ws != segbuf_rs || segbuf_wp > segbuf_rp)
00148         *bcp = segbuf_end - segbuf_wp;
00149     else
00150         *bcp = segbuf_rp - segbuf_wp;
00151 
00152     NutSegBufEnable(segbuf_ws);
00153     return segbuf_wp;
00154 }
00155 
00168 char *NutSegBufReadRequest(size_t * bcp)
00169 {
00170     if (segbuf_empty)
00171         *bcp = 0;
00172     else if (segbuf_ws != segbuf_rs || segbuf_rp >= segbuf_wp)
00173         *bcp = segbuf_end - segbuf_rp;
00174     else if ((*bcp = segbuf_wp - segbuf_rp) == 0 && segbuf_ws == segbuf_rs)
00175         segbuf_empty = 1;
00176 
00177     NutSegBufEnable(segbuf_rs);
00178     return segbuf_rp;
00179 }
00180 
00192 char *NutSegBufWriteCommit(size_t bc)
00193 {
00194     if (bc) {
00195         segbuf_wp += bc;
00196         segbuf_empty = 0;
00197         segbuf_used += bc;
00198         if (segbuf_wp == segbuf_end) {
00199             segbuf_wp = segbuf_start;
00200 #if NUTBANK_COUNT > 0
00201             if (++segbuf_ws >= NUTBANK_COUNT)
00202                 segbuf_ws = 0;
00203 #endif
00204             NutSegBufEnable(segbuf_ws);
00205         }
00206     }
00207     return segbuf_wp;
00208 }
00209 
00221 char *NutSegBufReadCommit(size_t bc)
00222 {
00223     if (bc) {
00224         segbuf_rp += bc;
00225         segbuf_used -= bc;
00226         if (segbuf_rp == segbuf_end) {
00227             segbuf_rp = segbuf_start;
00228 #if NUTBANK_COUNT > 0
00229             if (++segbuf_rs >= NUTBANK_COUNT)
00230                 segbuf_rs = 0;
00231 #endif
00232             NutSegBufEnable(segbuf_rs);
00233         }
00234         if (segbuf_rp == segbuf_wp  && segbuf_rs == segbuf_ws)
00235             segbuf_empty = 1;
00236     }
00237     return segbuf_rp;
00238 }
00239 
00240 
00250 void NutSegBufWriteLast(size_t bc)
00251 {
00252     if (bc) {
00253         segbuf_wp += bc;
00254         segbuf_used += bc;
00255         segbuf_empty = 0;
00256         if (segbuf_wp == segbuf_end) {
00257             segbuf_wp = segbuf_start;
00258 #if NUTBANK_COUNT > 0
00259             if (++segbuf_ws >= NUTBANK_COUNT)
00260                 segbuf_ws = 0;
00261 #endif
00262         }
00263     }
00264     NutSegBufEnable(segbuf_rs);
00265 }
00266 
00276 void NutSegBufReadLast(size_t bc)
00277 {
00278     if (bc) {
00279         segbuf_rp += bc;
00280         segbuf_used -= bc;
00281         if (segbuf_rp == segbuf_end) {
00282             segbuf_rp = segbuf_start;
00283 #if NUTBANK_COUNT > 0
00284             if (++segbuf_rs >= NUTBANK_COUNT)
00285                 segbuf_rs = 0;
00286 #endif
00287         }
00288         if (segbuf_rp == segbuf_wp && segbuf_rs == segbuf_ws)
00289             segbuf_empty = 1;
00290     }
00291     NutSegBufEnable(segbuf_ws);
00292 }
00293 
00294 
00300 uint32_t NutSegBufAvailable(void)
00301 {
00302     return segbuf_total - segbuf_used;
00303 }
00304 
00310 uint32_t NutSegBufUsed(void)
00311 {
00312     return segbuf_used;
00313 }
00314 

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