Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
circbuf.h
- Committer:
- arnoz
- Date:
- 2021-10-01
- Revision:
- 116:7a67265d7c19
- Parent:
- 77:0b96f6867312
File content as of revision 116:7a67265d7c19:
// Circular buffer for incoming reports. We write reports in the IRQ // handler, and we read reports in the main loop in normal application // (non-IRQ) context. // // The design is organically safe for IRQ threading; there are no critical // sections. The IRQ context has exclusive access to the write pointer, // and the application context has exclusive access to the read pointer, // so there are no test-and-set or read-and-modify race conditions. #ifndef _CIRCBUF_H_ #define _CIRCBUF_H_ // Circular buffer with a fixed buffer size template<class T, int cnt> class CircBuf { public: CircBuf() { iRead = iWrite = 0; } // Read an item from the buffer. Returns true if an item was available, // false if the buffer was empty. (Called in the main loop, in application // context.) bool read(T &result) { if (iRead != iWrite) { //{uint8_t *d = buf[iRead].data; printf("circ read [%02x %02x %02x %02x %02x %02x %02x %02x]\r\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);} memcpy(&result, &buf[iRead], sizeof(T)); iRead = advance(iRead); return true; } else return false; } // is an item ready to read? bool readReady() const { return iRead != iWrite; } // Write an item to the buffer. (Called in the IRQ handler, in interrupt // context.) bool write(const T &item) { int nxt = advance(iWrite); if (nxt != iRead) { memcpy(&buf[iWrite], &item, sizeof(T)); iWrite = nxt; return true; } else return false; } private: int advance(int i) { ++i; return i < cnt ? i : 0; } int iRead; int iWrite; T buf[cnt]; }; // Circular buffer with a variable buffer size template<class T> class CircBufV { public: CircBufV(int cnt) { buf = new T[cnt]; this->cnt = cnt; iRead = iWrite = 0; } ~CircBufV() { delete[] buf; } // Read an item from the buffer. Returns true if an item was available, // false if the buffer was empty. (Called in the main loop, in application // context.) bool read(T &result) { if (iRead != iWrite) { //{uint8_t *d = buf[iRead].data; printf("circ read [%02x %02x %02x %02x %02x %02x %02x %02x]\r\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]);} memcpy(&result, &buf[iRead], sizeof(T)); iRead = advance(iRead); return true; } else return false; } // is an item ready to read? bool readReady() const { return iRead != iWrite; } // Write an item to the buffer. (Called in the IRQ handler, in interrupt // context.) bool write(const T &item) { int nxt = advance(iWrite); if (nxt != iRead) { memcpy(&buf[iWrite], &item, sizeof(T)); iWrite = nxt; return true; } else return false; } private: int advance(int i) { ++i; return i < cnt ? i : 0; } int iRead; int iWrite; int cnt; T *buf; }; #endif