Add a bunch of APNs

Fork of C027_Support by Xinlei Cao

Committer:
mazgch
Date:
Fri Apr 11 19:41:05 2014 +0000
Revision:
41:b94a1f410e71
Parent:
40:295099ff5338
Child:
74:208e3e32d263
make some function not virtual

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mazgch 0:cb2d45baaca3 1 #pragma once
mazgch 0:cb2d45baaca3 2
mazgch 40:295099ff5338 3 /** pipe, this class implements a buffered pipe that can be savely
mazgch 40:295099ff5338 4 written and read between two context. E.g. Written from a task
mazgch 40:295099ff5338 5 and read from a interrupt.
mazgch 40:295099ff5338 6 */
mazgch 0:cb2d45baaca3 7 template <class T>
mazgch 0:cb2d45baaca3 8 class Pipe
mazgch 0:cb2d45baaca3 9 {
mazgch 0:cb2d45baaca3 10 public:
mazgch 40:295099ff5338 11 /* Constructor
mazgch 40:295099ff5338 12 \param n size of the pipe/buffer
mazgch 40:295099ff5338 13 \param b optional buffer that should be used.
mazgch 40:295099ff5338 14 if NULL the constructor will allocate a buffer of size n.
mazgch 40:295099ff5338 15 */
mazgch 9:e7a5959ffae1 16 Pipe(int n, T* b = NULL)
mazgch 0:cb2d45baaca3 17 {
mazgch 9:e7a5959ffae1 18 _a = b ? NULL : new T[n];
mazgch 9:e7a5959ffae1 19 _r = 0;
mazgch 9:e7a5959ffae1 20 _w = 0;
mazgch 9:e7a5959ffae1 21 _b = b ? b : _a;
mazgch 9:e7a5959ffae1 22 _s = n;
mazgch 0:cb2d45baaca3 23 }
mazgch 40:295099ff5338 24 /** Destructor
mazgch 40:295099ff5338 25 frees a allocated buffer.
mazgch 40:295099ff5338 26 */
mazgch 41:b94a1f410e71 27 ~Pipe(void)
mazgch 0:cb2d45baaca3 28 {
mazgch 9:e7a5959ffae1 29 if (_a)
mazgch 9:e7a5959ffae1 30 delete [] _a;
mazgch 0:cb2d45baaca3 31 }
mazgch 40:295099ff5338 32
mazgch 40:295099ff5338 33 /* This function can be used during debugging to hexdump the
mazgch 40:295099ff5338 34 content of a buffer to the stdout.
mazgch 40:295099ff5338 35 */
mazgch 21:c4d64830bf02 36 void dump(void)
mazgch 21:c4d64830bf02 37 {
mazgch 21:c4d64830bf02 38 int o = _r;
mazgch 21:c4d64830bf02 39 printf("pipe: %d/%d ", size(), _s);
mazgch 21:c4d64830bf02 40 while (o != _w) {
mazgch 21:c4d64830bf02 41 T t = _b[o];
mazgch 21:c4d64830bf02 42 printf("%0*X", sizeof(T)*2, t);
mazgch 21:c4d64830bf02 43 o = _inc(o);
mazgch 21:c4d64830bf02 44 }
mazgch 21:c4d64830bf02 45 printf("\n");
mazgch 21:c4d64830bf02 46 }
mazgch 40:295099ff5338 47
mazgch 40:295099ff5338 48 // writing thread/context API
mazgch 40:295099ff5338 49 //-------------------------------------------------------------
mazgch 40:295099ff5338 50
mazgch 40:295099ff5338 51 /** Check if buffer is writeable (=not full)
mazgch 40:295099ff5338 52 \return true if writeable
mazgch 40:295099ff5338 53 */
mazgch 40:295099ff5338 54 bool writeable(void)
mazgch 0:cb2d45baaca3 55 {
mazgch 9:e7a5959ffae1 56 return free() > 0;
mazgch 0:cb2d45baaca3 57 }
mazgch 40:295099ff5338 58
mazgch 40:295099ff5338 59 /** Return the number of free elements in the buffer
mazgch 40:295099ff5338 60 \return the number of free elements
mazgch 40:295099ff5338 61 */
mazgch 40:295099ff5338 62 int free(void)
mazgch 0:cb2d45baaca3 63 {
mazgch 9:e7a5959ffae1 64 int s = _r - _w;
mazgch 9:e7a5959ffae1 65 if (s <= 0)
mazgch 9:e7a5959ffae1 66 s += _s;
mazgch 9:e7a5959ffae1 67 return s - 1;
mazgch 0:cb2d45baaca3 68 }
mazgch 40:295099ff5338 69
mazgch 40:295099ff5338 70 /* Add a single element to the buffer. (blocking)
mazgch 40:295099ff5338 71 \param c the element to add.
mazgch 40:295099ff5338 72 \return c
mazgch 40:295099ff5338 73 */
mazgch 13:e2446fcdc246 74 T putc(T c)
mazgch 0:cb2d45baaca3 75 {
mazgch 9:e7a5959ffae1 76 int i = _w;
mazgch 0:cb2d45baaca3 77 int j = i;
mazgch 0:cb2d45baaca3 78 i = _inc(i);
mazgch 9:e7a5959ffae1 79 while (i == _r) // = !writeable()
mazgch 9:e7a5959ffae1 80 /*wait for space*/;
mazgch 9:e7a5959ffae1 81 _b[j] = c;
mazgch 13:e2446fcdc246 82 _w = i;
mazgch 13:e2446fcdc246 83 return c;
mazgch 0:cb2d45baaca3 84 }
mazgch 40:295099ff5338 85
mazgch 40:295099ff5338 86 /* Add a buffer of elements to the buffer.
mazgch 40:295099ff5338 87 \param p the elements to add
mazgch 40:295099ff5338 88 \param n the number elements to add from p
mazgch 40:295099ff5338 89 \param t set to true if blocking, false otherwise
mazgch 40:295099ff5338 90 \return number elements added
mazgch 40:295099ff5338 91 */
mazgch 9:e7a5959ffae1 92 int put(const T* p, int n, bool t = false)
mazgch 0:cb2d45baaca3 93 {
mazgch 9:e7a5959ffae1 94 int c = n;
mazgch 9:e7a5959ffae1 95 while (c)
mazgch 0:cb2d45baaca3 96 {
mazgch 9:e7a5959ffae1 97 int f;
mazgch 9:e7a5959ffae1 98 for (;;) // wait for space
mazgch 0:cb2d45baaca3 99 {
mazgch 9:e7a5959ffae1 100 f = free();
mazgch 9:e7a5959ffae1 101 if (f) break; // data avail
mazgch 9:e7a5959ffae1 102 if (!t) return n - c; // no more space and not blocking
mazgch 0:cb2d45baaca3 103 }
mazgch 9:e7a5959ffae1 104 // check free space
mazgch 9:e7a5959ffae1 105 if (c < f) f = c;
mazgch 9:e7a5959ffae1 106 int w = _w;
mazgch 9:e7a5959ffae1 107 int m = _s - w;
mazgch 9:e7a5959ffae1 108 // check wrap
mazgch 9:e7a5959ffae1 109 if (f > m) f = m;
mazgch 9:e7a5959ffae1 110 memcpy(&_b[w], p, f);
mazgch 9:e7a5959ffae1 111 _w = _inc(w, f);
mazgch 9:e7a5959ffae1 112 c -= f;
mazgch 9:e7a5959ffae1 113 p += f;
mazgch 8:2435cdff8015 114 }
mazgch 9:e7a5959ffae1 115 return n - c;
mazgch 0:cb2d45baaca3 116 }
mazgch 40:295099ff5338 117
mazgch 40:295099ff5338 118 // reading thread/context API
mazgch 0:cb2d45baaca3 119 // --------------------------------------------------------
mazgch 40:295099ff5338 120
mazgch 40:295099ff5338 121 /** Check if there are any emelemnt available (readble / not empty)
mazgch 40:295099ff5338 122 \return true if readable/not empty
mazgch 40:295099ff5338 123 */
mazgch 40:295099ff5338 124 bool readable(void)
mazgch 0:cb2d45baaca3 125 {
mazgch 9:e7a5959ffae1 126 return (_r != _w);
mazgch 0:cb2d45baaca3 127 }
mazgch 40:295099ff5338 128
mazgch 40:295099ff5338 129 /** Get the number of values available in the buffer
mazgch 40:295099ff5338 130 return the number of element available
mazgch 40:295099ff5338 131 */
mazgch 41:b94a1f410e71 132 int size(void)
mazgch 0:cb2d45baaca3 133 {
mazgch 9:e7a5959ffae1 134 int s = _w - _r;
mazgch 9:e7a5959ffae1 135 if (s < 0)
mazgch 9:e7a5959ffae1 136 s += _s;
mazgch 9:e7a5959ffae1 137 return s;
mazgch 0:cb2d45baaca3 138 }
mazgch 40:295099ff5338 139
mazgch 40:295099ff5338 140 /** get a single value from buffered pipe (this function will block if no values available)
mazgch 40:295099ff5338 141 \return the element extracted
mazgch 40:295099ff5338 142 */
mazgch 0:cb2d45baaca3 143 T getc(void)
mazgch 0:cb2d45baaca3 144 {
mazgch 9:e7a5959ffae1 145 int r = _r;
mazgch 9:e7a5959ffae1 146 while (r == _w) // = !readable()
mazgch 9:e7a5959ffae1 147 /*wait for data*/;
mazgch 9:e7a5959ffae1 148 T t = _b[r];
mazgch 9:e7a5959ffae1 149 _r = _inc(r);
mazgch 0:cb2d45baaca3 150 return t;
mazgch 0:cb2d45baaca3 151 }
mazgch 40:295099ff5338 152
mazgch 40:295099ff5338 153 /*! get elements from the buffered pipe
mazgch 40:295099ff5338 154 \param p the elements extracted
mazgch 40:295099ff5338 155 \param n the maximum number elements to extract
mazgch 40:295099ff5338 156 \param t set to true if blocking, false otherwise
mazgch 40:295099ff5338 157 \return number elements extracted
mazgch 40:295099ff5338 158 */
mazgch 41:b94a1f410e71 159 int get(T* p, int n, bool t = false)
mazgch 0:cb2d45baaca3 160 {
mazgch 9:e7a5959ffae1 161 int c = n;
mazgch 9:e7a5959ffae1 162 while (c)
mazgch 0:cb2d45baaca3 163 {
mazgch 9:e7a5959ffae1 164 int f;
mazgch 9:e7a5959ffae1 165 for (;;) // wait for data
mazgch 0:cb2d45baaca3 166 {
mazgch 9:e7a5959ffae1 167 f = size();
mazgch 9:e7a5959ffae1 168 if (f) break; // free space
mazgch 9:e7a5959ffae1 169 if (!t) return n - c; // no space and not blocking
mazgch 0:cb2d45baaca3 170 }
mazgch 9:e7a5959ffae1 171 // check available data
mazgch 9:e7a5959ffae1 172 if (c < f) f = c;
mazgch 9:e7a5959ffae1 173 int r = _r;
mazgch 9:e7a5959ffae1 174 int m = _s - r;
mazgch 9:e7a5959ffae1 175 // check wrap
mazgch 9:e7a5959ffae1 176 if (f > m) f = m;
mazgch 9:e7a5959ffae1 177 memcpy(p, &_b[r], f);
mazgch 9:e7a5959ffae1 178 _r = _inc(r, f);
mazgch 9:e7a5959ffae1 179 c -= f;
mazgch 9:e7a5959ffae1 180 p += f;
mazgch 0:cb2d45baaca3 181 }
mazgch 9:e7a5959ffae1 182 return n - c;
mazgch 0:cb2d45baaca3 183 }
mazgch 9:e7a5959ffae1 184
mazgch 40:295099ff5338 185 // the following functions are useful if you like to inspect
mazgch 40:295099ff5338 186 // or parse the buffer in the reading thread/context
mazgch 40:295099ff5338 187 // --------------------------------------------------------
mazgch 9:e7a5959ffae1 188
mazgch 40:295099ff5338 189 /** set the parsing index and return the number of available
mazgch 40:295099ff5338 190 elments starting this position.
mazgch 40:295099ff5338 191 \param ix the index to set.
mazgch 40:295099ff5338 192 \return the number of elements starting at this position
mazgch 40:295099ff5338 193 */
mazgch 41:b94a1f410e71 194 int set(int ix)
mazgch 9:e7a5959ffae1 195 {
mazgch 21:c4d64830bf02 196 int sz = size();
mazgch 21:c4d64830bf02 197 ix = (ix > sz) ? sz : ix;
mazgch 21:c4d64830bf02 198 _o = _inc(_r, ix);
mazgch 21:c4d64830bf02 199 return sz - ix;
mazgch 9:e7a5959ffae1 200 }
mazgch 40:295099ff5338 201
mazgch 40:295099ff5338 202 /** get the next element from parsing position and increment parsing index
mazgch 40:295099ff5338 203 \return the extracted element.
mazgch 40:295099ff5338 204 */
mazgch 41:b94a1f410e71 205 T next(void)
mazgch 9:e7a5959ffae1 206 {
mazgch 9:e7a5959ffae1 207 int o = _o;
mazgch 9:e7a5959ffae1 208 T t = _b[o];
mazgch 9:e7a5959ffae1 209 _o = _inc(o);
mazgch 9:e7a5959ffae1 210 return t;
mazgch 9:e7a5959ffae1 211 }
mazgch 40:295099ff5338 212
mazgch 40:295099ff5338 213 /** commit the index, mrk the current parsing index as consumed data.
mazgch 40:295099ff5338 214 */
mazgch 41:b94a1f410e71 215 void done(void)
mazgch 9:e7a5959ffae1 216 {
mazgch 9:e7a5959ffae1 217 _r = _o;
mazgch 9:e7a5959ffae1 218 }
mazgch 0:cb2d45baaca3 219
mazgch 0:cb2d45baaca3 220 private:
mazgch 40:295099ff5338 221 /** increment the index
mazgch 40:295099ff5338 222 \param i index to increment
mazgch 40:295099ff5338 223 \param n the step to increment
mazgch 40:295099ff5338 224 \return the incremented index.
mazgch 40:295099ff5338 225 */
mazgch 40:295099ff5338 226 inline int _inc(int i, int n = 1)
mazgch 40:295099ff5338 227 {
mazgch 40:295099ff5338 228 i += n;
mazgch 40:295099ff5338 229 if (i >= _s)
mazgch 40:295099ff5338 230 i -= _s;
mazgch 40:295099ff5338 231 return i;
mazgch 40:295099ff5338 232 }
mazgch 40:295099ff5338 233
mazgch 9:e7a5959ffae1 234 T* _b; //!< buffer
mazgch 9:e7a5959ffae1 235 T* _a; //!< allocated buffer
mazgch 9:e7a5959ffae1 236 int _s; //!< size of buffer (s - 1) elements can be stored
mazgch 9:e7a5959ffae1 237 volatile int _w; //!< write index
mazgch 9:e7a5959ffae1 238 volatile int _r; //!< read index
mazgch 9:e7a5959ffae1 239 int _o; //!< offest index used by parsing functions
mazgch 0:cb2d45baaca3 240 };