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 
00051 #include <sys/heap.h>
00052 
00058 
00059 #include <sys/bankmem.h>
00060 
00061 static char segbuf_empty;
00062 static u_long segbuf_total;
00063 static u_long segbuf_used;
00064 
00065 static char *segbuf_start;
00066 static char *segbuf_end;
00067 
00068 
00069 static char *segbuf_wp;
00070 static char segbuf_ws;
00071 static char *segbuf_rp;
00072 static char segbuf_rs;
00073 
00079 char *NutSegBufReset(void)
00080 {
00081     segbuf_rp = segbuf_wp = segbuf_start;
00082     segbuf_rs = segbuf_ws = 0;
00083     NutSegBufEnable(0);
00084     segbuf_empty = 1;
00085     segbuf_used = 0;
00086 
00087     return segbuf_start;
00088 }
00089 
00102 char *NutSegBufInit(size_t size)
00103 {
00104 
00105 #if NUTBANK_COUNT
00106     segbuf_start = (char *)(NUTBANK_START);
00107     segbuf_end = (char *)(NUTBANK_START) + NUTBANK_SIZE;
00108     segbuf_total = (u_long) NUTBANK_COUNT *(u_long) NUTBANK_SIZE;
00109 #else
00110     if (size == 0)
00111         size = NutHeapAvailable() - 8192;
00112     if ((segbuf_start = NutHeapAlloc(size)) != 0)
00113         segbuf_end = segbuf_start + size;
00114     segbuf_total = size;
00115 #endif
00116 
00117     return NutSegBufReset();
00118 }
00119 
00132 char *NutSegBufWriteRequest(size_t * bcp)
00133 {
00134     if (segbuf_empty || segbuf_ws != segbuf_rs || segbuf_wp > segbuf_rp)
00135         *bcp = segbuf_end - segbuf_wp;
00136     else
00137         *bcp = segbuf_rp - segbuf_wp;
00138 
00139     NutSegBufEnable(segbuf_ws);
00140     return segbuf_wp;
00141 }
00142 
00155 char *NutSegBufReadRequest(size_t * bcp)
00156 {
00157     if (segbuf_empty)
00158         *bcp = 0;
00159     else if (segbuf_ws != segbuf_rs || segbuf_rp >= segbuf_wp)
00160         *bcp = segbuf_end - segbuf_rp;
00161     else if ((*bcp = segbuf_wp - segbuf_rp) == 0 && segbuf_ws == segbuf_rs)
00162         segbuf_empty = 1;
00163 
00164     NutSegBufEnable(segbuf_rs);
00165     return segbuf_rp;
00166 }
00167 
00179 char *NutSegBufWriteCommit(size_t bc)
00180 {
00181     if (bc) {
00182         segbuf_wp += bc;
00183         segbuf_empty = 0;
00184         segbuf_used += bc;
00185         if (segbuf_wp == segbuf_end) {
00186             segbuf_wp = segbuf_start;
00187 #if NUTBANK_COUNT > 0
00188             if (++segbuf_ws >= NUTBANK_COUNT)
00189                 segbuf_ws = 0;
00190 #endif
00191             NutSegBufEnable(segbuf_ws);
00192         }
00193     }
00194     return segbuf_wp;
00195 }
00196 
00208 char *NutSegBufReadCommit(size_t bc)
00209 {
00210     if (bc) {
00211         segbuf_rp += bc;
00212         segbuf_used -= bc;
00213         if (segbuf_rp == segbuf_end) {
00214             segbuf_rp = segbuf_start;
00215 #if NUTBANK_COUNT > 0
00216             if (++segbuf_rs >= NUTBANK_COUNT)
00217                 segbuf_rs = 0;
00218 #endif
00219             NutSegBufEnable(segbuf_rs);
00220         }
00221         if (segbuf_rp == segbuf_wp  && segbuf_rs == segbuf_ws)
00222             segbuf_empty = 1;
00223     }
00224     return segbuf_rp;
00225 }
00226 
00227 
00237 void NutSegBufWriteLast(size_t bc)
00238 {
00239     if (bc) {
00240         segbuf_wp += bc;
00241         segbuf_used += bc;
00242         segbuf_empty = 0;
00243         if (segbuf_wp == segbuf_end) {
00244             segbuf_wp = segbuf_start;
00245 #if NUTBANK_COUNT > 0
00246             if (++segbuf_ws >= NUTBANK_COUNT)
00247                 segbuf_ws = 0;
00248 #endif
00249         }
00250     }
00251     NutSegBufEnable(segbuf_rs);
00252 }
00253 
00263 void NutSegBufReadLast(size_t bc)
00264 {
00265     if (bc) {
00266         segbuf_rp += bc;
00267         segbuf_used -= bc;
00268         if (segbuf_rp == segbuf_end) {
00269             segbuf_rp = segbuf_start;
00270 #if NUTBANK_COUNT > 0
00271             if (++segbuf_rs >= NUTBANK_COUNT)
00272                 segbuf_rs = 0;
00273 #endif
00274         }
00275         if (segbuf_rp == segbuf_wp && segbuf_rs == segbuf_ws)
00276             segbuf_empty = 1;
00277     }
00278     NutSegBufEnable(segbuf_ws);
00279 }
00280 
00281 
00287 u_long NutSegBufAvailable(void)
00288 {
00289     return segbuf_total - segbuf_used;
00290 }
00291 
00297 u_long NutSegBufUsed(void)
00298 {
00299     return segbuf_used;
00300 }
00301 

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