Nut/OS  4.10.3
API Reference
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 
00064 #include <sys/heap.h>
00065 
00066 #include <stdint.h>
00067 
00073 
00074 #include <sys/bankmem.h>
00075 
00076 static char segbuf_empty;
00077 static uint32_t segbuf_total;
00078 static uint32_t segbuf_used;
00079 
00080 static char *segbuf_start;
00081 static char *segbuf_end;
00082 
00083 
00084 static char *segbuf_wp;
00085 static char segbuf_ws;
00086 static char *segbuf_rp;
00087 static char segbuf_rs;
00088 
00094 char *NutSegBufReset(void)
00095 {
00096     segbuf_rp = segbuf_wp = segbuf_start;
00097     segbuf_rs = segbuf_ws = 0;
00098     NutSegBufEnable(0);
00099     segbuf_empty = 1;
00100     segbuf_used = 0;
00101 
00102     return segbuf_start;
00103 }
00104 
00117 char *NutSegBufInit(size_t size)
00118 {
00119 
00120 #if NUTBANK_COUNT
00121     segbuf_start = (char *)(NUTBANK_START);
00122     segbuf_end = (char *)(NUTBANK_START) + NUTBANK_SIZE;
00123     segbuf_total = (uint32_t) NUTBANK_COUNT *(uint32_t) NUTBANK_SIZE;
00124 #else
00125     if (size == 0)
00126         size = NutHeapAvailable() / 2;
00127     if (segbuf_start) {
00128         NutHeapFree(segbuf_start);
00129     }
00130     if ((segbuf_start = NutHeapAlloc(size)) != NULL)
00131         segbuf_end = segbuf_start + size;
00132     segbuf_total = size;
00133 #endif
00134 
00135     return NutSegBufReset();
00136 }
00137 
00150 char *NutSegBufWriteRequest(size_t * bcp)
00151 {
00152     if (segbuf_empty || segbuf_ws != segbuf_rs || segbuf_wp > segbuf_rp)
00153         *bcp = segbuf_end - segbuf_wp;
00154     else
00155         *bcp = segbuf_rp - segbuf_wp;
00156 
00157     NutSegBufEnable(segbuf_ws);
00158     return segbuf_wp;
00159 }
00160 
00173 char *NutSegBufReadRequest(size_t * bcp)
00174 {
00175     if (segbuf_empty)
00176         *bcp = 0;
00177     else if (segbuf_ws != segbuf_rs || segbuf_rp >= segbuf_wp)
00178         *bcp = segbuf_end - segbuf_rp;
00179     else if ((*bcp = segbuf_wp - segbuf_rp) == 0 && segbuf_ws == segbuf_rs)
00180         segbuf_empty = 1;
00181 
00182     NutSegBufEnable(segbuf_rs);
00183     return segbuf_rp;
00184 }
00185 
00197 char *NutSegBufWriteCommit(size_t bc)
00198 {
00199     if (bc) {
00200         segbuf_wp += bc;
00201         segbuf_empty = 0;
00202         segbuf_used += bc;
00203         if (segbuf_wp == segbuf_end) {
00204             segbuf_wp = segbuf_start;
00205 #if NUTBANK_COUNT > 0
00206             if (++segbuf_ws >= NUTBANK_COUNT)
00207                 segbuf_ws = 0;
00208 #endif
00209             NutSegBufEnable(segbuf_ws);
00210         }
00211     }
00212     return segbuf_wp;
00213 }
00214 
00226 char *NutSegBufReadCommit(size_t bc)
00227 {
00228     if (bc) {
00229         segbuf_rp += bc;
00230         segbuf_used -= bc;
00231         if (segbuf_rp == segbuf_end) {
00232             segbuf_rp = segbuf_start;
00233 #if NUTBANK_COUNT > 0
00234             if (++segbuf_rs >= NUTBANK_COUNT)
00235                 segbuf_rs = 0;
00236 #endif
00237             NutSegBufEnable(segbuf_rs);
00238         }
00239         if (segbuf_rp == segbuf_wp  && segbuf_rs == segbuf_ws)
00240             segbuf_empty = 1;
00241     }
00242     return segbuf_rp;
00243 }
00244 
00245 
00255 void NutSegBufWriteLast(size_t bc)
00256 {
00257     if (bc) {
00258         segbuf_wp += bc;
00259         segbuf_used += bc;
00260         segbuf_empty = 0;
00261         if (segbuf_wp == segbuf_end) {
00262             segbuf_wp = segbuf_start;
00263 #if NUTBANK_COUNT > 0
00264             if (++segbuf_ws >= NUTBANK_COUNT)
00265                 segbuf_ws = 0;
00266 #endif
00267         }
00268     }
00269     NutSegBufEnable(segbuf_rs);
00270 }
00271 
00281 void NutSegBufReadLast(size_t bc)
00282 {
00283     if (bc) {
00284         segbuf_rp += bc;
00285         segbuf_used -= bc;
00286         if (segbuf_rp == segbuf_end) {
00287             segbuf_rp = segbuf_start;
00288 #if NUTBANK_COUNT > 0
00289             if (++segbuf_rs >= NUTBANK_COUNT)
00290                 segbuf_rs = 0;
00291 #endif
00292         }
00293         if (segbuf_rp == segbuf_wp && segbuf_rs == segbuf_ws)
00294             segbuf_empty = 1;
00295     }
00296     NutSegBufEnable(segbuf_ws);
00297 }
00298 
00299 
00305 uint32_t NutSegBufAvailable(void)
00306 {
00307     return segbuf_total - segbuf_used;
00308 }
00309 
00315 uint32_t NutSegBufUsed(void)
00316 {
00317     return segbuf_used;
00318 }
00319