Use ring buffer for console_handler

This commit is contained in:
Attila Body 2025-06-14 08:48:07 +02:00
parent b2eee97903
commit 3e904a2e71
Signed by: abody
GPG key ID: BD0C6214E68FB5CF
8 changed files with 141 additions and 40 deletions

View file

@ -18,12 +18,26 @@ class console_handler : public usart_core, public initialized_singleton<console_
friend class initialized_singleton<console_handler>;
public:
using size_type = iringbuffer::size_type;
class iconsole_input
{
public:
virtual void input_available(size_type len) = 0;
};
void print(char const *s);
void flush();
size_t append(char const *s);
size_type append(char const *s);
iringbuffer &get_rx_buffer() { return m_rx_buffer; }
private:
console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx);
console_handler(
USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, uint8_t *rx_buffer, size_type x_buffer_size,
uint8_t *tx_buffer, size_type tx_buffer_size, iconsole_input *rx_callback);
void setup_receive(void);
// LL_UsartCore pure virtual function implementations
virtual void receiver_idle(void) override;
@ -37,8 +51,13 @@ private:
virtual void tx_dma_half_transfer(void) override;
virtual void tx_dma_error(dma_helper::dma_error_type reason) override;
ringbuffer<128> m_tx_buffer;
iringbuffer::size_type m_in_flight_size = 0;
ringbuffer_ext m_tx_buffer;
size_type m_bytes_sent = 0;
ringbuffer_ext m_rx_buffer;
size_type m_bytes_requested = 0;
size_type m_reqd_bytes_registered = 0;
iconsole_input *m_rx_callback;
};
} /* namespace f4ll */

View file

@ -38,9 +38,9 @@ public:
private:
DMA_TypeDef *m_dma;
uint32_t m_stream;
volatile uint32_t *m_is_reg;
volatile uint32_t *m_ifc_reg;
uint32_t const m_stream;
volatile uint32_t * const m_is_reg;
volatile uint32_t * const m_ifc_reg;
static constexpr uint32_t const m_fe_masks[8] = {DMA_LISR_FEIF0, DMA_LISR_FEIF1, DMA_LISR_FEIF2, DMA_LISR_FEIF3,
DMA_HISR_FEIF4, DMA_HISR_FEIF5, DMA_HISR_FEIF6, DMA_HISR_FEIF7};

View file

@ -35,22 +35,30 @@ public:
/// without registering the consumption.
/// The caller should also call report_consumption using the returned
/// chunk length after it finished processing the data.
/// @param[in] len_requested Length of the data requested from the buffer.
/// The length of the actual data provided
/// might be actually smaller (because either reaching the end of
/// the buffer or not enough data in the buffer).
/// @param[out] data Receives a pointer to the first byte of the available
/// data in the buffer
/// @param[out] len Receives the length of the chunk available in the buffer.
/// Will not exceed len_requested.
/// @retval true if the buffer has more available data, false otherwise.
virtual bool get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const = 0;
virtual bool get_chunk(uint8_t const *&data, size_type &len) const = 0;
/// @brief Marks the chunk returned by ringbuffer_GetChunk as available.
/// @param consumed The length of the chunk as returned by
/// ringbuffer_GetChunk(..., len)
virtual void consumed(size_type len) = 0;
/// @brief Gets a pointer to the next free chunk in the buffer
/// @retval Pointer to the beginning of the next free buffer chmemory area
/// @param[out] len Receives the length of the returned buffer area.
virtual uint8_t *get_free_chunk(size_type &len) = 0;
/// @brief Registers the data written in the free buffer chunk.
/// IMPORTANT: Do not call put() after start modifying the buffer
/// returned by get_free_chunk() before registering the written data by
/// calling supplied()
/// @param len The length of the data written in the buffer
virtual bool produced(size_type len) = 0;
/// @brief Returns the number of uncommited bytes in the ring buffer.
virtual size_type uncommited() const = 0;
@ -80,8 +88,13 @@ public:
size_type put(uint8_t const *data, size_type len) override;
void commit() override;
bool get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const override;
bool get_chunk(uint8_t const *&data, size_type &len) const override;
void consumed(size_type len) override;
uint8_t *get_free_chunk(size_type &len) override;
bool produced(size_type len) override;
size_type uncommited() const override;
size_type commited() const override;
void discard() override;
@ -98,6 +111,7 @@ private:
size_type m_tail = 0; //!< Read position
size_type marker_diff(size_type m1, size_type m2) const;
size_type max_chunk_len() const;
};
//

View file

@ -31,6 +31,7 @@ protected:
dma_helper m_tx_dma;
private:
// these functions are called from interrup context!
virtual void receiver_idle(void) = 0;
virtual void transmission_complete(void) = 0;
virtual void framing_error(void) = 0;