Migrated _rxBuffer from CircularBuffer to queue

This commit is contained in:
Thomas Basler 2022-10-04 22:48:49 +02:00
parent 8e7f40f56c
commit 0d350b14bb
3 changed files with 17 additions and 186 deletions

View File

@ -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 <Arduino.h>
#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 BUFFERTYPE, uint8_t BUFFERSIZE>
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

View File

@ -42,17 +42,15 @@ void HoymilesRadio::loop()
if (_packetReceived) { if (_packetReceived) {
Serial.println(F("Interrupt received")); Serial.println(F("Interrupt received"));
while (_radio->available()) { while (_radio->available()) {
if (!_rxBuffer.full()) { if (!(_rxBuffer.size() > FRAGMENT_BUFFER_SIZE)) {
fragment_t* f; fragment_t f;
f = _rxBuffer.getFront(); memset(f.fragment, 0xcc, MAX_RF_PAYLOAD_SIZE);
memset(f->fragment, 0xcc, MAX_RF_PAYLOAD_SIZE); f.len = _radio->getDynamicPayloadSize();
f->len = _radio->getDynamicPayloadSize(); f.channel = _radio->getChannel();
f->channel = _radio->getChannel(); if (f.len > MAX_RF_PAYLOAD_SIZE)
if (f->len > MAX_RF_PAYLOAD_SIZE) f.len = MAX_RF_PAYLOAD_SIZE;
f->len = MAX_RF_PAYLOAD_SIZE; _radio->read(f.fragment, f.len);
_rxBuffer.push(f);
_radio->read(f->fragment, f->len);
_rxBuffer.pushFront(f);
} else { } else {
Serial.println(F("Buffer full")); Serial.println(F("Buffer full"));
_radio->flush_rx(); _radio->flush_rx();
@ -63,16 +61,16 @@ void HoymilesRadio::loop()
} else { } else {
// Perform package parsing only if no packages are received // Perform package parsing only if no packages are received
if (!_rxBuffer.empty()) { if (!_rxBuffer.empty()) {
fragment_t* f = _rxBuffer.getBack(); fragment_t f = _rxBuffer.back();
if (checkFragmentCrc(f)) { if (checkFragmentCrc(&f)) {
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterByFragment(f); std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterByFragment(&f);
if (nullptr != inv) { if (nullptr != inv) {
// Save packet in inverter rx buffer // Save packet in inverter rx buffer
char buf[30]; char buf[30];
snprintf(buf, sizeof(buf), "RX Channel: %d --> ", f->channel); snprintf(buf, sizeof(buf), "RX Channel: %d --> ", f.channel);
dumpBuf(buf, f->fragment, f->len); dumpBuf(buf, f.fragment, f.len);
inv->addRxFragment(f->fragment, f->len); inv->addRxFragment(f.fragment, f.len);
} else { } else {
Serial.println(F("Inverter Not found!")); Serial.println(F("Inverter Not found!"));
} }
@ -82,7 +80,7 @@ void HoymilesRadio::loop()
} }
// Remove paket from buffer even it was corrupted // Remove paket from buffer even it was corrupted
_rxBuffer.popBack(); _rxBuffer.pop();
} }
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include "CircularBuffer.h"
#include "TimeoutHelper.h" #include "TimeoutHelper.h"
#include "commands/CommandAbstract.h" #include "commands/CommandAbstract.h"
#include "types.h" #include "types.h"
@ -57,7 +56,7 @@ private:
volatile bool _packetReceived = false; volatile bool _packetReceived = false;
CircularBuffer<fragment_t, FRAGMENT_BUFFER_SIZE> _rxBuffer; std::queue<fragment_t> _rxBuffer;
TimeoutHelper _rxTimeout; TimeoutHelper _rxTimeout;
serial_u _dtuSerial; serial_u _dtuSerial;