Diff: scmRTOS/Common/usrlib.h
- Revision:
- 0:331db0b44b67
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/usrlib.h Tue Sep 21 19:48:05 2010 +0000
@@ -0,0 +1,298 @@
+//******************************************************************************
+//*
+//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System
+//*
+//* NICKNAME: scmRTOS
+//*
+//* PURPOSE: User Suport Library Header
+//*
+//* Version: 3.10
+//*
+//* $Revision: 256 $
+//* $Date:: 2010-01-22 #$
+//*
+//* Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//* Permission is hereby granted, free of charge, to any person
+//* obtaining a copy of this software and associated documentation
+//* files (the "Software"), to deal in the Software without restriction,
+//* including without limitation the rights to use, copy, modify, merge,
+//* publish, distribute, sublicense, and/or sell copies of the Software,
+//* and to permit persons to whom the Software is furnished to do so,
+//* subject to the following conditions:
+//*
+//* The above copyright notice and this permission notice shall be included
+//* in all copies or substantial portions of the Software.
+//*
+//* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+//* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+//* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+//* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+//* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//* =================================================================
+//* See http://scmrtos.sourceforge.net for documentation, latest
+//* information, license and contact details.
+//* =================================================================
+//*
+//******************************************************************************
+
+#ifndef USRLIB_H
+#define USRLIB_H
+
+#include <commdefs.h>
+
+//------------------------------------------------------------------------------
+//
+// DESCRIPTON: user namespace for some useful types and functions
+//
+//
+namespace usr
+{
+ //------------------------------------------------------------------------------
+ //
+ /// The Circular Buffer
+ //
+ /// Byte-wide FIFO.
+ //
+ /// Allows to:
+ /// add byte,
+ /// get byte,
+ /// write bytes from array,
+ /// read bytes to array,
+ /// and some other service actions.
+ //
+ class TCbuf
+ {
+ public:
+ TCbuf(byte* const Address, const byte Size);
+ bool write(const byte* data, const byte Count);
+ void read(byte* const data, const byte Count);
+ byte get_count() const { return count; }
+ byte get_free_size() const { return size - count; }
+ byte get_byte(const byte index) const;
+ void clear() { count = 0; last = first; }
+ bool put(const byte item);
+ byte get();
+
+ private:
+ //------------------------------------------------------------------------------
+ //
+ // DESCRIPTON: For internal purposes
+ //
+ void push(const byte item); ///< Use this function with care - it doesn't perform free size check
+ byte pop(); ///< Use this function with care - it doesn't perform count check
+ //------------------------------------------------------------------------------
+
+ private:
+ byte* buf;
+ byte size;
+ volatile byte count;
+ byte first;
+ byte last;
+ };
+ //------------------------------------------------------------------------------
+
+
+
+ //-----------------------------------------------------------------------
+ //
+ /// The Ring Buffer Template
+ ///
+ /// Carries out FIFO functionality for
+ /// arbitrary data types
+ ///
+ /// Allows to:
+ /// add item to back (default),
+ /// add item to front,
+ /// get item at front (default),
+ /// get item from back,
+ /// write items from array,
+ /// read items to array and some other actions
+ //
+ //
+ //
+ template<typename T, word Size, typename S = byte>
+ class ring_buffer
+ {
+ public:
+ ring_buffer() : Count(0), First(0), Last(0) { }
+
+ //----------------------------------------------------------------
+ //
+ // Data transfer functions
+ //
+ bool write(const T* data, const S cnt);
+ void read(T* const data, const S cnt);
+
+ bool push_back(const T item);
+ bool push_front(const T item);
+
+ T pop_front();
+ T pop_back();
+
+ bool push(const T item) { return push_back(item); }
+ T pop() { return pop_front(); }
+
+ //----------------------------------------------------------------
+ //
+ // Service functions
+ //
+ S get_count() const { return Count; }
+ S get_free_size() const { return Size - Count; }
+ T& operator[](const S index);
+ void flush() { Count = 0; Last = First; }
+
+ private:
+ //--------------------------------------------------------------
+ // DESCRIPTON: For internal purposes
+ // Use this functions with care: it don't perform
+ // free size and count check
+ //
+ void push_item(const T item);
+ void push_item_front(const T item);
+ T pop_item();
+ T pop_item_back();
+ //--------------------------------------------------------------
+
+ private:
+ S Count;
+ S First;
+ S Last;
+ T Buf[Size];
+ };
+ //------------------------------------------------------------------
+}
+//---------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//
+// The ring buffer function-member definitions
+//
+//
+//
+template<typename T, word Size, typename S>
+bool usr::ring_buffer<T, Size, S>::write(const T* data, const S cnt)
+{
+ if( cnt > (Size - Count) )
+ return false;
+
+ for(S i = 0; i < cnt; i++)
+ push_item(*(data++));
+
+ return true;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void usr::ring_buffer<T, Size, S>::read(T* data, const S cnt)
+{
+ S nItems = cnt <= Count ? cnt : Count;
+
+ for(S i = 0; i < nItems; i++)
+ data[i] = pop_item();
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T& usr::ring_buffer<T, Size, S>::operator[](const S index)
+{
+ S x = First + index;
+
+ if(x < Size)
+ return Buf[x];
+ else
+ return Buf[x - Size];
+}
+
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool usr::ring_buffer<T, Size, S>::push_back(const T item)
+{
+ if(Count == Size)
+ return false;
+
+ push_item(item);
+ return true;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool usr::ring_buffer<T, Size, S>::push_front(const T item)
+{
+ if(Count == Size)
+ return false;
+
+ push_item_front(item);
+ return true;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_front()
+{
+ if(Count)
+ return pop_item();
+ else
+ return Buf[First];
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_back()
+{
+ if(Count)
+ return pop_item_back();
+ else
+ return Buf[First];
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void usr::ring_buffer<T, Size, S>::push_item(const T item)
+{
+ Buf[Last] = item;
+ Last++;
+ Count++;
+
+ if(Last == Size)
+ Last = 0;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void usr::ring_buffer<T, Size, S>::push_item_front(const T item)
+{
+ if(First == 0)
+ First = Size - 1;
+ else
+ --First;
+ Buf[First] = item;
+ Count++;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_item()
+{
+ T item = Buf[First];
+
+ Count--;
+ First++;
+ if(First == Size)
+ First = 0;
+
+ return item;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_item_back()
+{
+
+ if(Last == 0)
+ Last = Size - 1;
+ else
+ --Last;
+
+ Count--;
+ return Buf[Last];;
+}
+//------------------------------------------------------------------------------
+
+
+#endif // USRLIB_H