Committer:
segundo
Date:
Thu Nov 11 10:30:39 2010 +0000
Revision:
7:6fab7e5aa489
Parent:
0:d7810ff946c1

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:d7810ff946c1 1 //******************************************************************************
segundo 0:d7810ff946c1 2 //*
segundo 0:d7810ff946c1 3 //* FULLNAME: Single-Chip Microcontroller Real-Time Operating System
segundo 0:d7810ff946c1 4 //*
segundo 0:d7810ff946c1 5 //* NICKNAME: scmRTOS
segundo 0:d7810ff946c1 6 //*
segundo 0:d7810ff946c1 7 //* PURPOSE: User Suport Library Header
segundo 0:d7810ff946c1 8 //*
segundo 0:d7810ff946c1 9 //* Version: 3.10
segundo 0:d7810ff946c1 10 //*
segundo 0:d7810ff946c1 11 //* $Revision: 256 $
segundo 0:d7810ff946c1 12 //* $Date:: 2010-01-22 #$
segundo 0:d7810ff946c1 13 //*
segundo 0:d7810ff946c1 14 //* Copyright (c) 2003-2010, Harry E. Zhurov
segundo 0:d7810ff946c1 15 //*
segundo 0:d7810ff946c1 16 //* Permission is hereby granted, free of charge, to any person
segundo 0:d7810ff946c1 17 //* obtaining a copy of this software and associated documentation
segundo 0:d7810ff946c1 18 //* files (the "Software"), to deal in the Software without restriction,
segundo 0:d7810ff946c1 19 //* including without limitation the rights to use, copy, modify, merge,
segundo 0:d7810ff946c1 20 //* publish, distribute, sublicense, and/or sell copies of the Software,
segundo 0:d7810ff946c1 21 //* and to permit persons to whom the Software is furnished to do so,
segundo 0:d7810ff946c1 22 //* subject to the following conditions:
segundo 0:d7810ff946c1 23 //*
segundo 0:d7810ff946c1 24 //* The above copyright notice and this permission notice shall be included
segundo 0:d7810ff946c1 25 //* in all copies or substantial portions of the Software.
segundo 0:d7810ff946c1 26 //*
segundo 0:d7810ff946c1 27 //* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
segundo 0:d7810ff946c1 28 //* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
segundo 0:d7810ff946c1 29 //* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
segundo 0:d7810ff946c1 30 //* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
segundo 0:d7810ff946c1 31 //* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
segundo 0:d7810ff946c1 32 //* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
segundo 0:d7810ff946c1 33 //* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
segundo 0:d7810ff946c1 34 //*
segundo 0:d7810ff946c1 35 //* =================================================================
segundo 0:d7810ff946c1 36 //* See http://scmrtos.sourceforge.net for documentation, latest
segundo 0:d7810ff946c1 37 //* information, license and contact details.
segundo 0:d7810ff946c1 38 //* =================================================================
segundo 0:d7810ff946c1 39 //*
segundo 0:d7810ff946c1 40 //******************************************************************************
segundo 0:d7810ff946c1 41
segundo 0:d7810ff946c1 42 #ifndef USRLIB_H
segundo 0:d7810ff946c1 43 #define USRLIB_H
segundo 0:d7810ff946c1 44
segundo 0:d7810ff946c1 45 #include <commdefs.h>
segundo 0:d7810ff946c1 46
segundo 0:d7810ff946c1 47 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 48 //
segundo 0:d7810ff946c1 49 // DESCRIPTON: user namespace for some useful types and functions
segundo 0:d7810ff946c1 50 //
segundo 0:d7810ff946c1 51 //
segundo 0:d7810ff946c1 52 namespace usr
segundo 0:d7810ff946c1 53 {
segundo 0:d7810ff946c1 54 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 55 //
segundo 0:d7810ff946c1 56 /// The Circular Buffer
segundo 0:d7810ff946c1 57 //
segundo 0:d7810ff946c1 58 /// Byte-wide FIFO.
segundo 0:d7810ff946c1 59 //
segundo 0:d7810ff946c1 60 /// Allows to:
segundo 0:d7810ff946c1 61 /// add byte,
segundo 0:d7810ff946c1 62 /// get byte,
segundo 0:d7810ff946c1 63 /// write bytes from array,
segundo 0:d7810ff946c1 64 /// read bytes to array,
segundo 0:d7810ff946c1 65 /// and some other service actions.
segundo 0:d7810ff946c1 66 //
segundo 0:d7810ff946c1 67 class TCbuf
segundo 0:d7810ff946c1 68 {
segundo 0:d7810ff946c1 69 public:
segundo 0:d7810ff946c1 70 TCbuf(byte* const Address, const byte Size);
segundo 0:d7810ff946c1 71 bool write(const byte* data, const byte Count);
segundo 0:d7810ff946c1 72 void read(byte* const data, const byte Count);
segundo 0:d7810ff946c1 73 byte get_count() const { return count; }
segundo 0:d7810ff946c1 74 byte get_free_size() const { return size - count; }
segundo 0:d7810ff946c1 75 byte get_byte(const byte index) const;
segundo 0:d7810ff946c1 76 void clear() { count = 0; last = first; }
segundo 0:d7810ff946c1 77 bool put(const byte item);
segundo 0:d7810ff946c1 78 byte get();
segundo 0:d7810ff946c1 79
segundo 0:d7810ff946c1 80 private:
segundo 0:d7810ff946c1 81 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 82 //
segundo 0:d7810ff946c1 83 // DESCRIPTON: For internal purposes
segundo 0:d7810ff946c1 84 //
segundo 0:d7810ff946c1 85 void push(const byte item); ///< Use this function with care - it doesn't perform free size check
segundo 0:d7810ff946c1 86 byte pop(); ///< Use this function with care - it doesn't perform count check
segundo 0:d7810ff946c1 87 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 88
segundo 0:d7810ff946c1 89 private:
segundo 0:d7810ff946c1 90 byte* buf;
segundo 0:d7810ff946c1 91 byte size;
segundo 0:d7810ff946c1 92 volatile byte count;
segundo 0:d7810ff946c1 93 byte first;
segundo 0:d7810ff946c1 94 byte last;
segundo 0:d7810ff946c1 95 };
segundo 0:d7810ff946c1 96 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 97
segundo 0:d7810ff946c1 98
segundo 0:d7810ff946c1 99
segundo 0:d7810ff946c1 100 //-----------------------------------------------------------------------
segundo 0:d7810ff946c1 101 //
segundo 0:d7810ff946c1 102 /// The Ring Buffer Template
segundo 0:d7810ff946c1 103 ///
segundo 0:d7810ff946c1 104 /// Carries out FIFO functionality for
segundo 0:d7810ff946c1 105 /// arbitrary data types
segundo 0:d7810ff946c1 106 ///
segundo 0:d7810ff946c1 107 /// Allows to:
segundo 0:d7810ff946c1 108 /// add item to back (default),
segundo 0:d7810ff946c1 109 /// add item to front,
segundo 0:d7810ff946c1 110 /// get item at front (default),
segundo 0:d7810ff946c1 111 /// get item from back,
segundo 0:d7810ff946c1 112 /// write items from array,
segundo 0:d7810ff946c1 113 /// read items to array and some other actions
segundo 0:d7810ff946c1 114 //
segundo 0:d7810ff946c1 115 //
segundo 0:d7810ff946c1 116 //
segundo 0:d7810ff946c1 117 template<typename T, word Size, typename S = byte>
segundo 0:d7810ff946c1 118 class ring_buffer
segundo 0:d7810ff946c1 119 {
segundo 0:d7810ff946c1 120 public:
segundo 0:d7810ff946c1 121 ring_buffer() : Count(0), First(0), Last(0) { }
segundo 0:d7810ff946c1 122
segundo 0:d7810ff946c1 123 //----------------------------------------------------------------
segundo 0:d7810ff946c1 124 //
segundo 0:d7810ff946c1 125 // Data transfer functions
segundo 0:d7810ff946c1 126 //
segundo 0:d7810ff946c1 127 bool write(const T* data, const S cnt);
segundo 0:d7810ff946c1 128 void read(T* const data, const S cnt);
segundo 0:d7810ff946c1 129
segundo 0:d7810ff946c1 130 bool push_back(const T item);
segundo 0:d7810ff946c1 131 bool push_front(const T item);
segundo 0:d7810ff946c1 132
segundo 0:d7810ff946c1 133 T pop_front();
segundo 0:d7810ff946c1 134 T pop_back();
segundo 0:d7810ff946c1 135
segundo 0:d7810ff946c1 136 bool push(const T item) { return push_back(item); }
segundo 0:d7810ff946c1 137 T pop() { return pop_front(); }
segundo 0:d7810ff946c1 138
segundo 0:d7810ff946c1 139 //----------------------------------------------------------------
segundo 0:d7810ff946c1 140 //
segundo 0:d7810ff946c1 141 // Service functions
segundo 0:d7810ff946c1 142 //
segundo 0:d7810ff946c1 143 S get_count() const { return Count; }
segundo 0:d7810ff946c1 144 S get_free_size() const { return Size - Count; }
segundo 0:d7810ff946c1 145 T& operator[](const S index);
segundo 0:d7810ff946c1 146 void flush() { Count = 0; Last = First; }
segundo 0:d7810ff946c1 147
segundo 0:d7810ff946c1 148 private:
segundo 0:d7810ff946c1 149 //--------------------------------------------------------------
segundo 0:d7810ff946c1 150 // DESCRIPTON: For internal purposes
segundo 0:d7810ff946c1 151 // Use this functions with care: it don't perform
segundo 0:d7810ff946c1 152 // free size and count check
segundo 0:d7810ff946c1 153 //
segundo 0:d7810ff946c1 154 void push_item(const T item);
segundo 0:d7810ff946c1 155 void push_item_front(const T item);
segundo 0:d7810ff946c1 156 T pop_item();
segundo 0:d7810ff946c1 157 T pop_item_back();
segundo 0:d7810ff946c1 158 //--------------------------------------------------------------
segundo 0:d7810ff946c1 159
segundo 0:d7810ff946c1 160 private:
segundo 0:d7810ff946c1 161 S Count;
segundo 0:d7810ff946c1 162 S First;
segundo 0:d7810ff946c1 163 S Last;
segundo 0:d7810ff946c1 164 T Buf[Size];
segundo 0:d7810ff946c1 165 };
segundo 0:d7810ff946c1 166 //------------------------------------------------------------------
segundo 0:d7810ff946c1 167 }
segundo 0:d7810ff946c1 168 //---------------------------------------------------------------------------
segundo 0:d7810ff946c1 169
segundo 0:d7810ff946c1 170
segundo 0:d7810ff946c1 171 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 172 //
segundo 0:d7810ff946c1 173 // The ring buffer function-member definitions
segundo 0:d7810ff946c1 174 //
segundo 0:d7810ff946c1 175 //
segundo 0:d7810ff946c1 176 //
segundo 0:d7810ff946c1 177 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 178 bool usr::ring_buffer<T, Size, S>::write(const T* data, const S cnt)
segundo 0:d7810ff946c1 179 {
segundo 0:d7810ff946c1 180 if( cnt > (Size - Count) )
segundo 0:d7810ff946c1 181 return false;
segundo 0:d7810ff946c1 182
segundo 0:d7810ff946c1 183 for(S i = 0; i < cnt; i++)
segundo 0:d7810ff946c1 184 push_item(*(data++));
segundo 0:d7810ff946c1 185
segundo 0:d7810ff946c1 186 return true;
segundo 0:d7810ff946c1 187 }
segundo 0:d7810ff946c1 188 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 189 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 190 void usr::ring_buffer<T, Size, S>::read(T* data, const S cnt)
segundo 0:d7810ff946c1 191 {
segundo 0:d7810ff946c1 192 S nItems = cnt <= Count ? cnt : Count;
segundo 0:d7810ff946c1 193
segundo 0:d7810ff946c1 194 for(S i = 0; i < nItems; i++)
segundo 0:d7810ff946c1 195 data[i] = pop_item();
segundo 0:d7810ff946c1 196 }
segundo 0:d7810ff946c1 197 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 198 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 199 T& usr::ring_buffer<T, Size, S>::operator[](const S index)
segundo 0:d7810ff946c1 200 {
segundo 0:d7810ff946c1 201 S x = First + index;
segundo 0:d7810ff946c1 202
segundo 0:d7810ff946c1 203 if(x < Size)
segundo 0:d7810ff946c1 204 return Buf[x];
segundo 0:d7810ff946c1 205 else
segundo 0:d7810ff946c1 206 return Buf[x - Size];
segundo 0:d7810ff946c1 207 }
segundo 0:d7810ff946c1 208
segundo 0:d7810ff946c1 209 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 210 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 211 bool usr::ring_buffer<T, Size, S>::push_back(const T item)
segundo 0:d7810ff946c1 212 {
segundo 0:d7810ff946c1 213 if(Count == Size)
segundo 0:d7810ff946c1 214 return false;
segundo 0:d7810ff946c1 215
segundo 0:d7810ff946c1 216 push_item(item);
segundo 0:d7810ff946c1 217 return true;
segundo 0:d7810ff946c1 218 }
segundo 0:d7810ff946c1 219 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 220 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 221 bool usr::ring_buffer<T, Size, S>::push_front(const T item)
segundo 0:d7810ff946c1 222 {
segundo 0:d7810ff946c1 223 if(Count == Size)
segundo 0:d7810ff946c1 224 return false;
segundo 0:d7810ff946c1 225
segundo 0:d7810ff946c1 226 push_item_front(item);
segundo 0:d7810ff946c1 227 return true;
segundo 0:d7810ff946c1 228 }
segundo 0:d7810ff946c1 229 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 230 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 231 T usr::ring_buffer<T, Size, S>::pop_front()
segundo 0:d7810ff946c1 232 {
segundo 0:d7810ff946c1 233 if(Count)
segundo 0:d7810ff946c1 234 return pop_item();
segundo 0:d7810ff946c1 235 else
segundo 0:d7810ff946c1 236 return Buf[First];
segundo 0:d7810ff946c1 237 }
segundo 0:d7810ff946c1 238 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 239 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 240 T usr::ring_buffer<T, Size, S>::pop_back()
segundo 0:d7810ff946c1 241 {
segundo 0:d7810ff946c1 242 if(Count)
segundo 0:d7810ff946c1 243 return pop_item_back();
segundo 0:d7810ff946c1 244 else
segundo 0:d7810ff946c1 245 return Buf[First];
segundo 0:d7810ff946c1 246 }
segundo 0:d7810ff946c1 247 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 248 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 249 void usr::ring_buffer<T, Size, S>::push_item(const T item)
segundo 0:d7810ff946c1 250 {
segundo 0:d7810ff946c1 251 Buf[Last] = item;
segundo 0:d7810ff946c1 252 Last++;
segundo 0:d7810ff946c1 253 Count++;
segundo 0:d7810ff946c1 254
segundo 0:d7810ff946c1 255 if(Last == Size)
segundo 0:d7810ff946c1 256 Last = 0;
segundo 0:d7810ff946c1 257 }
segundo 0:d7810ff946c1 258 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 259 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 260 void usr::ring_buffer<T, Size, S>::push_item_front(const T item)
segundo 0:d7810ff946c1 261 {
segundo 0:d7810ff946c1 262 if(First == 0)
segundo 0:d7810ff946c1 263 First = Size - 1;
segundo 0:d7810ff946c1 264 else
segundo 0:d7810ff946c1 265 --First;
segundo 0:d7810ff946c1 266 Buf[First] = item;
segundo 0:d7810ff946c1 267 Count++;
segundo 0:d7810ff946c1 268 }
segundo 0:d7810ff946c1 269 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 270 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 271 T usr::ring_buffer<T, Size, S>::pop_item()
segundo 0:d7810ff946c1 272 {
segundo 0:d7810ff946c1 273 T item = Buf[First];
segundo 0:d7810ff946c1 274
segundo 0:d7810ff946c1 275 Count--;
segundo 0:d7810ff946c1 276 First++;
segundo 0:d7810ff946c1 277 if(First == Size)
segundo 0:d7810ff946c1 278 First = 0;
segundo 0:d7810ff946c1 279
segundo 0:d7810ff946c1 280 return item;
segundo 0:d7810ff946c1 281 }
segundo 0:d7810ff946c1 282 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 283 template<typename T, word Size, typename S>
segundo 0:d7810ff946c1 284 T usr::ring_buffer<T, Size, S>::pop_item_back()
segundo 0:d7810ff946c1 285 {
segundo 0:d7810ff946c1 286
segundo 0:d7810ff946c1 287 if(Last == 0)
segundo 0:d7810ff946c1 288 Last = Size - 1;
segundo 0:d7810ff946c1 289 else
segundo 0:d7810ff946c1 290 --Last;
segundo 0:d7810ff946c1 291
segundo 0:d7810ff946c1 292 Count--;
segundo 0:d7810ff946c1 293 return Buf[Last];;
segundo 0:d7810ff946c1 294 }
segundo 0:d7810ff946c1 295 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 296
segundo 0:d7810ff946c1 297
segundo 0:d7810ff946c1 298 #endif // USRLIB_H