fsfw/src/fsfw/container/RingBufferBase.h

90 lines
2.4 KiB
C
Raw Normal View History

2020-09-04 15:09:24 +02:00
#ifndef FSFW_CONTAINER_RINGBUFFERBASE_H_
#define FSFW_CONTAINER_RINGBUFFERBASE_H_
2020-09-04 15:09:24 +02:00
#include <cstddef>
2022-08-16 12:48:22 +02:00
#include "../returnvalues/returnvalue.h"
2022-02-02 10:29:30 +01:00
template <uint8_t N_READ_PTRS = 1>
class RingBufferBase {
2022-02-02 10:29:30 +01:00
public:
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld)
: start(startAddress), write(startAddress), size(size), overwriteOld(overwriteOld) {
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
read[count] = startAddress;
}
2022-02-02 10:29:30 +01:00
}
2022-02-02 10:29:30 +01:00
virtual ~RingBufferBase() {}
2022-02-02 10:29:30 +01:00
bool isFull(uint8_t n = 0) { return (availableWriteSpace(n) == 0); }
bool isEmpty(uint8_t n = 0) { return (getAvailableReadData(n) == 0); }
2022-02-02 10:29:30 +01:00
size_t getAvailableReadData(uint8_t n = 0) const { return ((write + size) - read[n]) % size; }
size_t availableWriteSpace(uint8_t n = 0) const {
// One less to avoid ambiguous full/empty problem.
return (((read[n] + size) - write - 1) % size);
}
2022-02-02 10:29:30 +01:00
bool overwritesOld() const { return overwriteOld; }
2022-02-02 10:29:30 +01:00
size_t getMaxSize() const { return size - 1; }
2022-02-02 10:29:30 +01:00
void clear() {
write = start;
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
read[count] = start;
}
2022-02-02 10:29:30 +01:00
}
2022-02-02 10:29:30 +01:00
size_t writeTillWrap() { return (start + size) - write; }
2022-02-02 10:29:30 +01:00
size_t readTillWrap(uint8_t n = 0) { return (start + size) - read[n]; }
2022-02-02 10:29:30 +01:00
size_t getStart() const { return start; }
2020-09-04 15:09:24 +02:00
2022-02-02 10:29:30 +01:00
protected:
const size_t start;
size_t write;
size_t read[N_READ_PTRS];
const size_t size;
const bool overwriteOld;
2022-02-02 10:29:30 +01:00
void incrementWrite(uint32_t amount) { write = ((write + amount - start) % size) + start; }
void incrementRead(uint32_t amount, uint8_t n = 0) {
read[n] = ((read[n] + amount - start) % size) + start;
}
2022-02-02 10:29:30 +01:00
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
if (getAvailableReadData(n) >= amount) {
incrementRead(amount, n);
2022-08-15 20:28:16 +02:00
return returnvalue::OK;
2022-02-02 10:29:30 +01:00
} else {
2022-08-15 20:28:16 +02:00
return returnvalue::FAILED;
}
2022-02-02 10:29:30 +01:00
}
2022-02-02 10:29:30 +01:00
ReturnValue_t writeData(uint32_t amount) {
if (availableWriteSpace() >= amount or overwriteOld) {
incrementWrite(amount);
2022-08-15 20:28:16 +02:00
return returnvalue::OK;
2022-02-02 10:29:30 +01:00
} else {
2022-08-15 20:28:16 +02:00
return returnvalue::FAILED;
}
2022-02-02 10:29:30 +01:00
}
2022-02-02 10:29:30 +01:00
size_t getRead(uint8_t n = 0) const { return read[n]; }
2022-02-02 10:29:30 +01:00
void setRead(uint32_t read, uint8_t n = 0) {
if (read >= start && read < (start + size)) {
this->read[n] = read;
}
2022-02-02 10:29:30 +01:00
}
2022-02-02 10:29:30 +01:00
uint32_t getWrite() const { return write; }
2022-02-02 10:29:30 +01:00
void setWrite(uint32_t write) { this->write = write; }
};
2020-09-04 15:09:24 +02:00
#endif /* FSFW_CONTAINER_RINGBUFFERBASE_H_ */