User | Revision | Line number | New 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
|