git subrepo pull components/f4ll
subrepo: subdir: "components/f4ll" merged: "f86c164d" upstream: origin: "ssh://git@codeberg.org/abody/f4ll.git" branch: "master" commit: "f86c164d" git-subrepo: version: "0.4.9" origin: "???" commit: "???"
This commit is contained in:
parent
d72d3af2a7
commit
66575aa1b4
13 changed files with 291 additions and 155 deletions
4
components/f4ll/.gitignore
vendored
Normal file
4
components/f4ll/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
build.ninja
|
||||
cmake_install.cmake
|
|
@ -6,7 +6,7 @@
|
|||
[subrepo]
|
||||
remote = ssh://git@codeberg.org/abody/f4ll.git
|
||||
branch = master
|
||||
commit = a4c1baa4109ed591c9db556da430fadfac0642a6
|
||||
parent = 4e1f01c4d45a06b03c631b229402f8c625900922
|
||||
commit = f86c164de5c279c378c5cde408af5fe75497c474
|
||||
parent = d72d3af2a7e99af89780fcfa66071f99db11c766
|
||||
method = merge
|
||||
cmdver = 0.4.9
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
add_library(f4ll STATIC
|
||||
src/console_handler.cpp
|
||||
src/crc_handler.cpp
|
||||
|
@ -5,6 +7,7 @@ add_library(f4ll STATIC
|
|||
src/fault.cpp
|
||||
src/memcpy_dma.cpp
|
||||
src/packet_usart.cpp
|
||||
src/ringbuffer.cpp
|
||||
src/str_util.cpp
|
||||
src/usart_core.cpp
|
||||
)
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <f4ll/initialized_singleton.h>
|
||||
#include <f4ll/packet_usart.h>
|
||||
#include <f4ll/ringbuffer.h>
|
||||
#include <f4ll/usart_core.h>
|
||||
|
||||
#include <platform/dma_ll.h>
|
||||
|
||||
namespace f4ll {
|
||||
|
||||
|
@ -18,12 +20,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 +53,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 */
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <platform/dma_ll.h>
|
||||
|
||||
#include <f4ll/dma_helper.h>
|
||||
#include <f4ll/initialized_singleton.h>
|
||||
#include <inttypes.h>
|
||||
#include <platform/dma_ll.h>
|
||||
|
||||
namespace f4ll {
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <platform/dma_ll.h>
|
||||
|
||||
namespace f4ll {
|
||||
|
@ -38,9 +39,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};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <f4ll/dma_helper.h>
|
||||
#include <f4ll/initialized_singleton.h>
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace f4ll {
|
||||
|
||||
|
@ -35,22 +34,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;
|
||||
|
||||
|
@ -72,15 +79,21 @@ public:
|
|||
virtual size_type unused() const = 0;
|
||||
};
|
||||
|
||||
template <iringbuffer::size_type SZ> class ringbuffer : public iringbuffer
|
||||
//
|
||||
class ringbuffer_ext : public iringbuffer
|
||||
{
|
||||
public:
|
||||
ringbuffer() = default;
|
||||
ringbuffer_ext(uint8_t *bptr, size_type bsize);
|
||||
|
||||
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;
|
||||
|
@ -89,130 +102,32 @@ public:
|
|||
size_type unused() const override;
|
||||
|
||||
private:
|
||||
uint8_t m_buffer[SZ]; //!< Data bufer
|
||||
uint8_t *m_buffer; //!< Data bufer
|
||||
size_type const m_bsize; //!< Data buffer size
|
||||
size_type m_head = 0; //!< Write position
|
||||
size_type m_head_shadow = 0; //!< Shadowed write position for collecting data
|
||||
//!< before committing it
|
||||
size_type m_tail = 0; //!< Read position
|
||||
|
||||
size_type marker_diff(size_type m1, size_type m2) const;
|
||||
size_type max_chunk_len() const;
|
||||
};
|
||||
|
||||
//
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::put(uint8_t const *data, size_type len)
|
||||
template <iringbuffer::size_type SZ> class ringbuffer : public ringbuffer_ext
|
||||
{
|
||||
size_type chunk1 = 0;
|
||||
size_type chunk2 = 0;
|
||||
public:
|
||||
ringbuffer();
|
||||
|
||||
if (!data || !len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_type max_len = unused();
|
||||
len = len < max_len ? len : max_len;
|
||||
|
||||
chunk1 = sizeof(m_buffer) - m_head_shadow;
|
||||
if (chunk1 >= len) {
|
||||
chunk1 = len;
|
||||
} else {
|
||||
chunk2 = len - chunk1;
|
||||
}
|
||||
|
||||
std::memcpy(m_buffer + m_head_shadow, data, chunk1);
|
||||
m_head_shadow += chunk1;
|
||||
if (m_head_shadow == sizeof(m_buffer)) {
|
||||
m_head_shadow = 0;
|
||||
}
|
||||
|
||||
if (chunk2) {
|
||||
std::memcpy(m_buffer, data + chunk1, chunk2);
|
||||
m_head_shadow += chunk2;
|
||||
if (m_head_shadow == sizeof(m_buffer)) {
|
||||
m_head_shadow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> void ringbuffer<SZ>::commit()
|
||||
{
|
||||
m_head = m_head_shadow;
|
||||
private:
|
||||
uint8_t m_buffer[SZ];
|
||||
};
|
||||
|
||||
template <iringbuffer::size_type SZ> bool ringbuffer<SZ>::get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const
|
||||
//
|
||||
template <iringbuffer::size_type SZ>
|
||||
ringbuffer<SZ>::ringbuffer()
|
||||
: ringbuffer_ext(m_buffer, SZ)
|
||||
{
|
||||
if (!len_requested) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_type head = m_head;
|
||||
size_type tail = m_tail;
|
||||
size_type chunk_size = head >= tail ? head - tail : sizeof(m_buffer) - tail;
|
||||
|
||||
if (!chunk_size) {
|
||||
len = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (chunk_size > len_requested) {
|
||||
chunk_size = len_requested;
|
||||
}
|
||||
data = m_buffer + tail;
|
||||
len = chunk_size;
|
||||
|
||||
tail += chunk_size;
|
||||
if (tail == sizeof(m_buffer)) {
|
||||
tail = 0;
|
||||
}
|
||||
|
||||
return tail != head;
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> void ringbuffer<SZ>::consumed(size_type len)
|
||||
{
|
||||
if (!len) {
|
||||
return;
|
||||
}
|
||||
m_tail += len;
|
||||
if (m_tail == sizeof(m_buffer)) {
|
||||
m_tail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::uncommited() const
|
||||
{
|
||||
return marker_diff(m_head_shadow, m_head);
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::commited() const
|
||||
{
|
||||
return marker_diff(m_head, m_tail);
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> void ringbuffer<SZ>::discard()
|
||||
{
|
||||
m_head_shadow = m_head;
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::size() const
|
||||
{
|
||||
return SZ;
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::used() const
|
||||
{
|
||||
return marker_diff(m_head_shadow, m_tail);
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::unused() const
|
||||
{
|
||||
return SZ - used() - 1;
|
||||
}
|
||||
|
||||
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::marker_diff(size_type m1, size_type m2) const
|
||||
{
|
||||
return (m1 >= m2) ? (m1 - m2) : (SZ - m2 + m1);
|
||||
}
|
||||
|
||||
} // namespace f1ll
|
||||
} // namespace f1ll
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -6,31 +6,42 @@
|
|||
*/
|
||||
|
||||
#include <f4ll/console_handler.h>
|
||||
#include <f4ll/irq_lock.h>
|
||||
#include <f4ll/str_util.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace f4ll {
|
||||
|
||||
console_handler::console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx)
|
||||
: usart_core(usart, dma, stream_rx, stream_tx)
|
||||
console_handler::console_handler(
|
||||
USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx, uint8_t *rx_buffer, size_type rx_buffer_size,
|
||||
uint8_t *tx_buffer, size_type tx_buffer_size, iconsole_input *rx_callback)
|
||||
: usart_core(usart, dma, stream_rx, stream_tx),
|
||||
m_tx_buffer(tx_buffer, tx_buffer_size),
|
||||
m_rx_buffer(rx_buffer, rx_buffer_size),
|
||||
m_rx_callback(rx_callback)
|
||||
{
|
||||
LL_USART_EnableIT_IDLE(usart);
|
||||
LL_USART_EnableIT_ERROR(usart);
|
||||
setup_receive();
|
||||
}
|
||||
|
||||
void console_handler::receiver_idle(void) {}
|
||||
|
||||
void console_handler::transmission_complete(void)
|
||||
void console_handler::setup_receive(void)
|
||||
{
|
||||
m_tx_buffer.consumed(m_in_flight_size);
|
||||
if (m_tx_buffer.commited()) {
|
||||
uint8_t const *chunk;
|
||||
m_tx_buffer.get_chunk(m_tx_buffer.size(), chunk, m_in_flight_size);
|
||||
if (m_in_flight_size) {
|
||||
setup_transmit(chunk, m_in_flight_size);
|
||||
uint8_t *bptr = m_rx_buffer.get_free_chunk(m_bytes_requested);
|
||||
m_reqd_bytes_registered = 0;
|
||||
usart_core::setup_receive(bptr, m_bytes_requested);
|
||||
}
|
||||
|
||||
void console_handler::receiver_idle(void)
|
||||
{
|
||||
uint16_t rcvd_bytes = m_bytes_requested - m_reqd_bytes_registered - LL_DMA_GetDataLength(m_rx_dma.get_dma(), m_rx_dma.get_stream());
|
||||
if (rcvd_bytes) {
|
||||
m_reqd_bytes_registered += rcvd_bytes;
|
||||
m_rx_buffer.produced(rcvd_bytes);
|
||||
m_rx_buffer.commit();
|
||||
if (m_rx_callback) {
|
||||
m_rx_callback->input_available(rcvd_bytes);
|
||||
}
|
||||
} else {
|
||||
m_in_flight_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +49,19 @@ void console_handler::framing_error(void) {}
|
|||
|
||||
void console_handler::overrun(void) {}
|
||||
|
||||
void console_handler::rx_dma_transfer_complete(void) {}
|
||||
void console_handler::rx_dma_transfer_complete(void)
|
||||
{
|
||||
LL_DMA_DisableStream(m_rx_dma.get_dma(), m_rx_dma.get_stream());
|
||||
uint16_t rcvd_bytes = m_bytes_requested - m_reqd_bytes_registered - LL_DMA_GetDataLength(m_rx_dma.get_dma(), m_rx_dma.get_stream());
|
||||
if (rcvd_bytes) {
|
||||
m_rx_buffer.produced(rcvd_bytes);
|
||||
setup_receive();
|
||||
m_rx_buffer.commit();
|
||||
if (m_rx_callback) {
|
||||
m_rx_callback->input_available(rcvd_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void console_handler::rx_dma_half_transfer(void) {}
|
||||
|
||||
|
@ -53,6 +76,20 @@ void console_handler::tx_dma_transfer_complete(void)
|
|||
LL_DMA_DisableStream(m_tx_dma.get_dma(), m_tx_dma.get_stream());
|
||||
}
|
||||
|
||||
void console_handler::transmission_complete(void)
|
||||
{
|
||||
m_tx_buffer.consumed(m_bytes_sent);
|
||||
if (m_tx_buffer.commited()) {
|
||||
uint8_t const *chunk;
|
||||
m_tx_buffer.get_chunk(chunk, m_bytes_sent);
|
||||
if (m_bytes_sent) {
|
||||
setup_transmit(chunk, m_bytes_sent);
|
||||
}
|
||||
} else {
|
||||
m_bytes_sent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void console_handler::tx_dma_half_transfer(void) {}
|
||||
|
||||
void console_handler::tx_dma_error(dma_helper::dma_error_type reason)
|
||||
|
@ -60,7 +97,7 @@ void console_handler::tx_dma_error(dma_helper::dma_error_type reason)
|
|||
(void)reason;
|
||||
}
|
||||
|
||||
size_t console_handler::append(char const *s)
|
||||
console_handler::size_type console_handler::append(char const *s)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
if (!len) {
|
||||
|
@ -76,14 +113,14 @@ void console_handler::flush()
|
|||
}
|
||||
m_tx_buffer.commit();
|
||||
|
||||
if (m_in_flight_size) {
|
||||
if (m_bytes_sent) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t const *chunk;
|
||||
m_tx_buffer.get_chunk(m_tx_buffer.size(), chunk, m_in_flight_size);
|
||||
if (m_in_flight_size) {
|
||||
setup_transmit(chunk, m_in_flight_size);
|
||||
m_tx_buffer.get_chunk(chunk, m_bytes_sent);
|
||||
if (m_bytes_sent) {
|
||||
setup_transmit(chunk, m_bytes_sent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* -c "tpiu config internal <logfile_full_path> uart off <cpufreq>"
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
// #include <core_cm4.h>
|
||||
|
||||
#include <f4ll/fault.h>
|
||||
#include <f4ll/str_util.h>
|
||||
#include <stm32f4xx.h>
|
||||
|
|
152
components/f4ll/src/ringbuffer.cpp
Normal file
152
components/f4ll/src/ringbuffer.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include <f4ll/ringbuffer.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace f4ll {
|
||||
|
||||
ringbuffer_ext::ringbuffer_ext(uint8_t *bptr, size_type bsize)
|
||||
: m_buffer(bptr),
|
||||
m_bsize(bsize)
|
||||
{
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::put(uint8_t const *data, size_type len)
|
||||
{
|
||||
size_type chunk1 = 0;
|
||||
size_type chunk2 = 0;
|
||||
|
||||
if (!data || !len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_type max_len = unused();
|
||||
len = len < max_len ? len : max_len;
|
||||
|
||||
chunk1 = m_bsize - m_head_shadow;
|
||||
if (chunk1 >= len) {
|
||||
chunk1 = len;
|
||||
} else {
|
||||
chunk2 = len - chunk1;
|
||||
}
|
||||
|
||||
std::memcpy(m_buffer + m_head_shadow, data, chunk1);
|
||||
m_head_shadow += chunk1;
|
||||
if (m_head_shadow == m_bsize) {
|
||||
m_head_shadow = 0;
|
||||
}
|
||||
|
||||
if (chunk2) {
|
||||
std::memcpy(m_buffer, data + chunk1, chunk2);
|
||||
m_head_shadow += chunk2;
|
||||
if (m_head_shadow == m_bsize) {
|
||||
m_head_shadow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void ringbuffer_ext::commit()
|
||||
{
|
||||
m_head = m_head_shadow;
|
||||
}
|
||||
|
||||
bool ringbuffer_ext::get_chunk(uint8_t const *&data, size_type &len) const
|
||||
{
|
||||
size_type head = m_head;
|
||||
size_type tail = m_tail;
|
||||
size_type chunk_size = head >= tail ? head - tail : m_bsize - tail;
|
||||
|
||||
if (!chunk_size) {
|
||||
len = 0;
|
||||
return tail != head;
|
||||
}
|
||||
|
||||
data = m_buffer + tail;
|
||||
len = chunk_size;
|
||||
|
||||
tail += chunk_size;
|
||||
if (tail == m_bsize) {
|
||||
tail = 0;
|
||||
}
|
||||
|
||||
return tail != head;
|
||||
}
|
||||
|
||||
void ringbuffer_ext::consumed(size_type len)
|
||||
{
|
||||
if (!len) {
|
||||
return;
|
||||
}
|
||||
m_tail += len;
|
||||
if (m_tail == m_bsize) {
|
||||
m_tail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::max_chunk_len() const
|
||||
{
|
||||
if (m_tail <= m_head_shadow) {
|
||||
return m_bsize - m_head_shadow - (m_tail ? 0 : 1);
|
||||
} else {
|
||||
return m_tail - m_head_shadow - 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *ringbuffer_ext::get_free_chunk(size_type &len)
|
||||
{
|
||||
len = max_chunk_len();
|
||||
|
||||
return m_buffer + m_head_shadow;
|
||||
}
|
||||
|
||||
bool ringbuffer_ext::produced(size_type len)
|
||||
{
|
||||
size_type max_len = max_chunk_len();
|
||||
if (len > max_len) {
|
||||
return false;
|
||||
}
|
||||
m_head_shadow += len;
|
||||
if (m_head_shadow == m_bsize) {
|
||||
m_head_shadow = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::uncommited() const
|
||||
{
|
||||
return marker_diff(m_head_shadow, m_head);
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::commited() const
|
||||
{
|
||||
return marker_diff(m_head, m_tail);
|
||||
}
|
||||
|
||||
void ringbuffer_ext::discard()
|
||||
{
|
||||
m_head_shadow = m_head;
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::size() const
|
||||
{
|
||||
return m_bsize;
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::used() const
|
||||
{
|
||||
return marker_diff(m_head_shadow, m_tail);
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::unused() const
|
||||
{
|
||||
return m_bsize - used() - 1;
|
||||
}
|
||||
|
||||
iringbuffer::size_type ringbuffer_ext::marker_diff(size_type m1, size_type m2) const
|
||||
{
|
||||
return (m1 >= m2) ? (m1 - m2) : (m_bsize - m2 + m1);
|
||||
}
|
||||
|
||||
//
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
#include <f4ll/str_util.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
size_t strcpy_ex(char *dst, char const *src)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue