From 0d350b14bb83e239c9e8c07e2be4bf14945bcb04 Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Tue, 4 Oct 2022 22:48:49 +0200 Subject: [PATCH] Migrated _rxBuffer from CircularBuffer to queue --- lib/CircularBuffer/CircularBuffer.h | 166 ---------------------------- lib/Hoymiles/src/HoymilesRadio.cpp | 34 +++--- lib/Hoymiles/src/HoymilesRadio.h | 3 +- 3 files changed, 17 insertions(+), 186 deletions(-) delete mode 100644 lib/CircularBuffer/CircularBuffer.h diff --git a/lib/CircularBuffer/CircularBuffer.h b/lib/CircularBuffer/CircularBuffer.h deleted file mode 100644 index 32db3871..00000000 --- a/lib/CircularBuffer/CircularBuffer.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - CircularBuffer - An Arduino circular buffering library for arbitrary types. - - Created by Ivo Pullens, Emmission, 2014 -- www.emmission.nl - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CircularBuffer_h -#define CircularBuffer_h - -#include - -#ifdef ESP8266 -#define DISABLE_IRQ noInterrupts() -#define RESTORE_IRQ interrupts() -#elif ESP32 -#define DISABLE_IRQ ; -#define RESTORE_IRQ ; -#else -#define DISABLE_IRQ \ - uint8_t sreg = SREG; \ - cli(); - -#define RESTORE_IRQ \ - SREG = sreg; -#endif - -template -class CircularBuffer { - - typedef BUFFERTYPE BufferType; - BufferType Buffer[BUFFERSIZE]; - - public: - CircularBuffer() : m_buff(Buffer) { - m_size = BUFFERSIZE; - clear(); - } - - /** Clear all entries in the circular buffer. */ - void clear(void) - { - m_front = 0; - m_fill = 0; - } - - /** Test if the circular buffer is empty */ - inline bool empty(void) const - { - return !m_fill; - } - - /** Return the number of records stored in the buffer */ - inline uint8_t available(void) const - { - return m_fill; - } - - /** Test if the circular buffer is full */ - inline bool full(void) const - { - return m_fill == m_size; - } - - inline uint8_t getFill(void) const { - return m_fill; - } - - /** Aquire record on front of the buffer, for writing. - * After filling the record, it has to be pushed to actually - * add it to the buffer. - * @return Pointer to record, or NULL when buffer is full. - */ - BUFFERTYPE* getFront(void) const - { - DISABLE_IRQ; - BUFFERTYPE* f = NULL; - if (!full()) - f = get(m_front); - RESTORE_IRQ; - return f; - } - - /** Push record to front of the buffer - * @param record Record to push. If record was aquired previously (using getFront) its - * data will not be copied as it is already present in the buffer. - * @return True, when record was pushed successfully. - */ - bool pushFront(BUFFERTYPE* record) - { - bool ok = false; - DISABLE_IRQ; - if (!full()) - { - BUFFERTYPE* f = get(m_front); - if (f != record) - *f = *record; - m_front = (m_front+1) % m_size; - m_fill++; - ok = true; - } - RESTORE_IRQ; - return ok; - } - - /** Aquire record on back of the buffer, for reading. - * After reading the record, it has to be pop'ed to actually - * remove it from the buffer. - * @return Pointer to record, or NULL when buffer is empty. - */ - BUFFERTYPE* getBack(void) const - { - BUFFERTYPE* b = NULL; - DISABLE_IRQ; - if (!empty()) - b = get(back()); - RESTORE_IRQ; - return b; - } - - /** Remove record from back of the buffer. - * @return True, when record was pop'ed successfully. - */ - bool popBack(void) - { - bool ok = false; - DISABLE_IRQ; - if (!empty()) - { - m_fill--; - ok = true; - } - RESTORE_IRQ; - return ok; - } - - protected: - inline BUFFERTYPE * get(const uint8_t idx) const - { - return &(m_buff[idx]); - } - inline uint8_t back(void) const - { - return (m_front - m_fill + m_size) % m_size; - } - - uint8_t m_size; // Total number of records that can be stored in the buffer. - BUFFERTYPE* const m_buff; - volatile uint8_t m_front; // Index of front element (not pushed yet). - volatile uint8_t m_fill; // Amount of records currently pushed. -}; - -#endif // CircularBuffer_h \ No newline at end of file diff --git a/lib/Hoymiles/src/HoymilesRadio.cpp b/lib/Hoymiles/src/HoymilesRadio.cpp index a011105c..9272b278 100644 --- a/lib/Hoymiles/src/HoymilesRadio.cpp +++ b/lib/Hoymiles/src/HoymilesRadio.cpp @@ -42,17 +42,15 @@ void HoymilesRadio::loop() if (_packetReceived) { Serial.println(F("Interrupt received")); while (_radio->available()) { - if (!_rxBuffer.full()) { - fragment_t* f; - f = _rxBuffer.getFront(); - memset(f->fragment, 0xcc, MAX_RF_PAYLOAD_SIZE); - f->len = _radio->getDynamicPayloadSize(); - f->channel = _radio->getChannel(); - if (f->len > MAX_RF_PAYLOAD_SIZE) - f->len = MAX_RF_PAYLOAD_SIZE; - - _radio->read(f->fragment, f->len); - _rxBuffer.pushFront(f); + if (!(_rxBuffer.size() > FRAGMENT_BUFFER_SIZE)) { + fragment_t f; + memset(f.fragment, 0xcc, MAX_RF_PAYLOAD_SIZE); + f.len = _radio->getDynamicPayloadSize(); + f.channel = _radio->getChannel(); + if (f.len > MAX_RF_PAYLOAD_SIZE) + f.len = MAX_RF_PAYLOAD_SIZE; + _radio->read(f.fragment, f.len); + _rxBuffer.push(f); } else { Serial.println(F("Buffer full")); _radio->flush_rx(); @@ -63,16 +61,16 @@ void HoymilesRadio::loop() } else { // Perform package parsing only if no packages are received if (!_rxBuffer.empty()) { - fragment_t* f = _rxBuffer.getBack(); - if (checkFragmentCrc(f)) { - std::shared_ptr inv = Hoymiles.getInverterByFragment(f); + fragment_t f = _rxBuffer.back(); + if (checkFragmentCrc(&f)) { + std::shared_ptr inv = Hoymiles.getInverterByFragment(&f); if (nullptr != inv) { // Save packet in inverter rx buffer char buf[30]; - snprintf(buf, sizeof(buf), "RX Channel: %d --> ", f->channel); - dumpBuf(buf, f->fragment, f->len); - inv->addRxFragment(f->fragment, f->len); + snprintf(buf, sizeof(buf), "RX Channel: %d --> ", f.channel); + dumpBuf(buf, f.fragment, f.len); + inv->addRxFragment(f.fragment, f.len); } else { Serial.println(F("Inverter Not found!")); } @@ -82,7 +80,7 @@ void HoymilesRadio::loop() } // Remove paket from buffer even it was corrupted - _rxBuffer.popBack(); + _rxBuffer.pop(); } } diff --git a/lib/Hoymiles/src/HoymilesRadio.h b/lib/Hoymiles/src/HoymilesRadio.h index 7c624681..189321df 100644 --- a/lib/Hoymiles/src/HoymilesRadio.h +++ b/lib/Hoymiles/src/HoymilesRadio.h @@ -1,6 +1,5 @@ #pragma once -#include "CircularBuffer.h" #include "TimeoutHelper.h" #include "commands/CommandAbstract.h" #include "types.h" @@ -57,7 +56,7 @@ private: volatile bool _packetReceived = false; - CircularBuffer _rxBuffer; + std::queue _rxBuffer; TimeoutHelper _rxTimeout; serial_u _dtuSerial;