This class provides an API to communicate with a u-blox GNSS chip. The files here were originally part of the C027_Support library (https://developer.mbed.org/teams/ublox/code/C027_Support/ at revision 138:dafbbf31bf76) but have been separated out, primarily for use on the u-blox C030 board where the cellular interace portion of the C027_Support library will instead be provided through the new mbed Cellular API.
Dependents: example-ublox-at-cellular-interface-ext example-low-power-sleep example-C030-out-of-box-demo example-C030-out-of-box-demo ... more
pipe.h
00001 /* Copyright (c) 2017 Michael Ammann 00002 * 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 00014 */ 00015 00016 #ifndef PIPE_H 00017 #define PIPE_H 00018 00019 /** pipe, this class implements a buffered pipe that can be savely 00020 written and read between two context. E.g. Written from a task 00021 and read from a interrupt. 00022 */ 00023 template <class T> 00024 class Pipe 00025 { 00026 public: 00027 /* Constructor 00028 \param n size of the pipe/buffer 00029 \param b optional buffer that should be used. 00030 if NULL the constructor will allocate a buffer of size n. 00031 */ 00032 Pipe(int n, T* b = NULL) 00033 { 00034 _a = b ? NULL : n ? new T[n] : NULL; 00035 _r = 0; 00036 _w = 0; 00037 _b = b ? b : _a; 00038 _s = n; 00039 } 00040 /** Destructor 00041 frees a allocated buffer. 00042 */ 00043 ~Pipe(void) 00044 { 00045 if (_a) 00046 delete [] _a; 00047 } 00048 00049 /* This function can be used during debugging to hexdump the 00050 content of a buffer to the stdout. 00051 */ 00052 void dump(void) 00053 { 00054 int o = _r; 00055 printf("pipe: %d/%d ", size(), _s); 00056 while (o != _w) { 00057 T t = _b[o]; 00058 printf("%0*X", sizeof(T)*2, t); 00059 o = _inc(o); 00060 } 00061 printf("\n"); 00062 } 00063 00064 // writing thread/context API 00065 //------------------------------------------------------------- 00066 00067 /** Check if buffer is writeable (=not full) 00068 \return true if writeable 00069 */ 00070 bool writeable(void) 00071 { 00072 return free() > 0; 00073 } 00074 00075 /** Return the number of free elements in the buffer 00076 \return the number of free elements 00077 */ 00078 int free(void) 00079 { 00080 int s = _r - _w; 00081 if (s <= 0) 00082 s += _s; 00083 return s - 1; 00084 } 00085 00086 /* Add a single element to the buffer. (blocking) 00087 \param c the element to add. 00088 \return c 00089 */ 00090 T putc(T c) 00091 { 00092 int i = _w; 00093 int j = i; 00094 i = _inc(i); 00095 while (i == _r) // = !writeable() 00096 /* nothing / just wait */; 00097 _b[j] = c; 00098 _w = i; 00099 return c; 00100 } 00101 00102 /* Add a buffer of elements to the buffer. 00103 \param p the elements to add 00104 \param n the number elements to add from p 00105 \param t set to true if blocking, false otherwise 00106 \return number elements added 00107 */ 00108 int put(const T* p, int n, bool t = false) 00109 { 00110 int c = n; 00111 while (c) 00112 { 00113 int f; 00114 for (;;) // wait for space 00115 { 00116 f = free(); 00117 if (f > 0) break; // data avail 00118 if (!t) return n - c; // no more space and not blocking 00119 /* nothing / just wait */; 00120 } 00121 // check free space 00122 if (c < f) f = c; 00123 int w = _w; 00124 int m = _s - w; 00125 // check wrap 00126 if (f > m) f = m; 00127 memcpy(&_b[w], p, f); 00128 _w = _inc(w, f); 00129 c -= f; 00130 p += f; 00131 } 00132 return n - c; 00133 } 00134 00135 // reading thread/context API 00136 // -------------------------------------------------------- 00137 00138 /** Check if there are any emelemnt available (readble / not empty) 00139 \return true if readable/not empty 00140 */ 00141 bool readable(void) 00142 { 00143 return (_r != _w); 00144 } 00145 00146 /** Get the number of values available in the buffer 00147 return the number of element available 00148 */ 00149 int size(void) 00150 { 00151 int s = _w - _r; 00152 if (s < 0) 00153 s += _s; 00154 return s; 00155 } 00156 00157 /** get a single value from buffered pipe (this function will block if no values available) 00158 \return the element extracted 00159 */ 00160 T getc(void) 00161 { 00162 int r = _r; 00163 while (r == _w) // = !readable() 00164 /* nothing / just wait */; 00165 T t = _b[r]; 00166 _r = _inc(r); 00167 return t; 00168 } 00169 00170 /*! get elements from the buffered pipe 00171 \param p the elements extracted 00172 \param n the maximum number elements to extract 00173 \param t set to true if blocking, false otherwise 00174 \return number elements extracted 00175 */ 00176 int get(T* p, int n, bool t = false) 00177 { 00178 int c = n; 00179 while (c) 00180 { 00181 int f; 00182 for (;;) // wait for data 00183 { 00184 f = size(); 00185 if (f) break; // free space 00186 if (!t) return n - c; // no space and not blocking 00187 /* nothing / just wait */; 00188 } 00189 // check available data 00190 if (c < f) f = c; 00191 int r = _r; 00192 int m = _s - r; 00193 // check wrap 00194 if (f > m) f = m; 00195 memcpy(p, &_b[r], f); 00196 _r = _inc(r, f); 00197 c -= f; 00198 p += f; 00199 } 00200 return n - c; 00201 } 00202 00203 // the following functions are useful if you like to inspect 00204 // or parse the buffer in the reading thread/context 00205 // -------------------------------------------------------- 00206 00207 /** set the parsing index and return the number of available 00208 elments starting this position. 00209 \param ix the index to set. 00210 \return the number of elements starting at this position 00211 */ 00212 int set(int ix) 00213 { 00214 int sz = size(); 00215 ix = (ix > sz) ? sz : ix; 00216 _o = _inc(_r, ix); 00217 return sz - ix; 00218 } 00219 00220 /** get the next element from parsing position and increment parsing index 00221 \return the extracted element. 00222 */ 00223 T next(void) 00224 { 00225 int o = _o; 00226 T t = _b[o]; 00227 _o = _inc(o); 00228 return t; 00229 } 00230 00231 /** commit the index, mark the current parsing index as consumed data. 00232 */ 00233 void done(void) 00234 { 00235 _r = _o; 00236 } 00237 00238 private: 00239 /** increment the index 00240 \param i index to increment 00241 \param n the step to increment 00242 \return the incremented index. 00243 */ 00244 inline int _inc(int i, int n = 1) 00245 { 00246 i += n; 00247 if (i >= _s) 00248 i -= _s; 00249 return i; 00250 } 00251 00252 T* _b; //!< buffer 00253 T* _a; //!< allocated buffer 00254 int _s; //!< size of buffer (s - 1) elements can be stored 00255 volatile int _w; //!< write index 00256 volatile int _r; //!< read index 00257 int _o; //!< offest index used by parsing functions 00258 }; 00259 00260 #endif 00261 00262 // End Of File
Generated on Tue Jul 12 2022 14:18:20 by 1.7.2