CQ出版 Interface 2014年10月号のC027(MAX7-Q)GPSテスト記事のプログラム。 CQ publishing Interface 2014.10 issue, C027 GPS(MAX-7Q) test program.

Dependencies:   C027 C027_Support mbed

Committer:
ntaka206
Date:
Wed Jun 04 02:37:42 2014 +0000
Revision:
0:1ababa0d0c42
Initial

Who changed what in which revision?

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