Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usrlib.h Source File

usrlib.h

00001 //******************************************************************************
00002 //*
00003 //*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
00004 //*
00005 //*     NICKNAME:  scmRTOS
00006 //*               
00007 //*     PURPOSE:  User Suport Library Header
00008 //*               
00009 //*     Version: 3.10
00010 //*
00011 //*     $Revision: 256 $
00012 //*     $Date:: 2010-01-22 #$
00013 //*
00014 //*     Copyright (c) 2003-2010, Harry E. Zhurov
00015 //*
00016 //*     Permission is hereby granted, free of charge, to any person 
00017 //*     obtaining  a copy of this software and associated documentation 
00018 //*     files (the "Software"), to deal in the Software without restriction, 
00019 //*     including without limitation the rights to use, copy, modify, merge, 
00020 //*     publish, distribute, sublicense, and/or sell copies of the Software, 
00021 //*     and to permit persons to whom the Software is furnished to do so, 
00022 //*     subject to the following conditions:
00023 //*
00024 //*     The above copyright notice and this permission notice shall be included 
00025 //*     in all copies or substantial portions of the Software.
00026 //*
00027 //*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00028 //*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
00029 //*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00030 //*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
00031 //*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
00032 //*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
00033 //*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00034 //*
00035 //*     =================================================================
00036 //*     See http://scmrtos.sourceforge.net for documentation, latest
00037 //*     information, license and contact details.
00038 //*     =================================================================
00039 //*
00040 //******************************************************************************
00041 
00042 #ifndef USRLIB_H
00043 #define USRLIB_H
00044 
00045 #include <commdefs.h>
00046 
00047 //------------------------------------------------------------------------------
00048 //
00049 //  DESCRIPTON: user namespace for some useful types and functions
00050 //
00051 //
00052 namespace usr
00053 {
00054     //------------------------------------------------------------------------------
00055     //
00056     ///     The Circular Buffer
00057     //
00058     ///         Byte-wide FIFO.
00059     //
00060     ///         Allows to:
00061     ///             add byte,
00062     ///             get byte,
00063     ///             write bytes from array,
00064     ///             read bytes to array,
00065     ///             and some other service actions.
00066     //
00067     class TCbuf
00068     {
00069     public:
00070         TCbuf(byte* const Address, const byte Size);
00071         bool write(const byte* data, const byte Count);
00072         void read(byte* const data, const byte Count);
00073         byte get_count() const { return count; }
00074         byte get_free_size() const { return size - count; }
00075         byte get_byte(const byte index) const;
00076         void clear() { count = 0; last = first; }
00077         bool put(const byte item);
00078         byte get();
00079 
00080     private:
00081        //------------------------------------------------------------------------------
00082        //
00083        //  DESCRIPTON: For internal purposes
00084        //
00085         void push(const byte item); ///< Use this function with care - it doesn't perform free size check
00086         byte pop();                 ///< Use this function with care - it doesn't perform count check
00087        //------------------------------------------------------------------------------
00088 
00089     private:
00090         byte* buf;
00091         byte  size;
00092         volatile byte count;
00093         byte  first;
00094         byte  last;
00095     };
00096     //------------------------------------------------------------------------------
00097 
00098 
00099 
00100     //-----------------------------------------------------------------------
00101     //
00102     ///     The Ring Buffer Template
00103     ///
00104     ///         Carries out FIFO functionality for
00105     ///         arbitrary data types
00106     ///
00107     ///         Allows to:
00108     ///             add item to back (default),
00109     ///             add item to front,
00110     ///             get item at front (default),
00111     ///             get item from back,
00112     ///             write items from array,
00113     ///             read items to array and some other actions
00114     //
00115     //
00116     //
00117     template<typename T, word Size, typename S = byte>
00118     class ring_buffer
00119     {
00120     public:
00121         ring_buffer() : Count(0), First(0), Last(0) { }
00122 
00123         //----------------------------------------------------------------
00124         //
00125         //    Data transfer functions
00126         //
00127         bool write(const T* data, const S cnt);
00128         void read(T* const data, const S cnt);
00129 
00130         bool push_back(const T item);
00131         bool push_front(const T item);
00132 
00133         T pop_front();
00134         T pop_back();
00135 
00136         bool push(const T item) { return push_back(item); }
00137         T pop() { return pop_front(); }
00138 
00139         //----------------------------------------------------------------
00140         //
00141         //    Service functions
00142         //
00143         S get_count() const { return Count; }
00144         S get_free_size() const { return Size - Count; }
00145         T& operator[](const S index);
00146         void flush() { Count = 0; Last = First; }
00147 
00148     private:
00149         //--------------------------------------------------------------
00150         //  DESCRIPTON: For internal purposes
00151         //              Use this functions with care: it don't perform
00152         //              free size and count check
00153         //
00154         void push_item(const T item);
00155         void push_item_front(const T item);
00156         T pop_item();
00157         T pop_item_back();
00158         //--------------------------------------------------------------
00159 
00160     private:
00161         S  Count;
00162         S  First;
00163         S  Last;
00164         T  Buf[Size];
00165     };
00166     //------------------------------------------------------------------
00167 }
00168 //---------------------------------------------------------------------------
00169 
00170 
00171 //------------------------------------------------------------------------------
00172 //
00173 //    The ring buffer function-member definitions
00174 //
00175 //
00176 //
00177 template<typename T, word Size, typename S>
00178 bool usr::ring_buffer<T, Size, S>::write(const T* data, const S cnt)
00179 {
00180     if( cnt > (Size - Count) )
00181         return false;
00182 
00183     for(S i = 0; i < cnt; i++)
00184         push_item(*(data++));
00185 
00186     return true;
00187 }
00188 //------------------------------------------------------------------------------
00189 template<typename T, word Size, typename S>
00190 void usr::ring_buffer<T, Size, S>::read(T* data, const S cnt)
00191 {
00192     S nItems = cnt <= Count ? cnt : Count;
00193 
00194     for(S i = 0; i < nItems; i++)
00195         data[i] = pop_item();
00196 }
00197 //------------------------------------------------------------------------------
00198 template<typename T, word Size, typename S>
00199 T& usr::ring_buffer<T, Size, S>::operator[](const S index)
00200 {
00201     S x = First + index;
00202 
00203     if(x < Size)
00204         return Buf[x];
00205     else
00206         return Buf[x - Size];
00207 }
00208 
00209 //------------------------------------------------------------------------------
00210 template<typename T, word Size, typename S>
00211 bool usr::ring_buffer<T, Size, S>::push_back(const T item)
00212 {
00213     if(Count == Size)
00214         return false;
00215 
00216     push_item(item);
00217     return true;
00218 }
00219 //------------------------------------------------------------------------------
00220 template<typename T, word Size, typename S>
00221 bool usr::ring_buffer<T, Size, S>::push_front(const T item)
00222 {
00223     if(Count == Size)
00224         return false;
00225 
00226     push_item_front(item);
00227     return true;
00228 }
00229 //------------------------------------------------------------------------------
00230 template<typename T, word Size, typename S>
00231 T usr::ring_buffer<T, Size, S>::pop_front()
00232 {
00233     if(Count)
00234         return pop_item();
00235     else
00236         return Buf[First];
00237 }
00238 //------------------------------------------------------------------------------
00239 template<typename T, word Size, typename S>
00240 T usr::ring_buffer<T, Size, S>::pop_back()
00241 {
00242     if(Count)
00243         return pop_item_back();
00244     else
00245         return Buf[First];
00246 }
00247 //------------------------------------------------------------------------------
00248 template<typename T, word Size, typename S>
00249 void usr::ring_buffer<T, Size, S>::push_item(const T item)
00250 {
00251     Buf[Last] = item;
00252     Last++;
00253     Count++;
00254 
00255     if(Last == Size)
00256         Last = 0;
00257 }
00258 //------------------------------------------------------------------------------
00259 template<typename T, word Size, typename S>
00260 void usr::ring_buffer<T, Size, S>::push_item_front(const T item)
00261 {
00262     if(First == 0)
00263         First = Size - 1;
00264     else
00265         --First;
00266     Buf[First] = item;
00267     Count++;
00268 }
00269 //------------------------------------------------------------------------------
00270 template<typename T, word Size, typename S>
00271 T usr::ring_buffer<T, Size, S>::pop_item()
00272 {
00273     T item = Buf[First];
00274 
00275     Count--;
00276     First++;
00277     if(First == Size)
00278         First = 0;
00279 
00280     return item;
00281 }
00282 //------------------------------------------------------------------------------
00283 template<typename T, word Size, typename S>
00284 T usr::ring_buffer<T, Size, S>::pop_item_back()
00285 {
00286 
00287     if(Last == 0)
00288         Last = Size - 1;
00289     else
00290         --Last;
00291 
00292     Count--;
00293     return Buf[Last];;
00294 }
00295 //------------------------------------------------------------------------------
00296 
00297 
00298 #endif // USRLIB_H