Use ring_buffer for console
untested
This commit is contained in:
parent
c86e9d4fc8
commit
8790695688
4 changed files with 323 additions and 62 deletions
|
@ -4,14 +4,12 @@
|
||||||
* Created on: Oct 28, 2019
|
* Created on: Oct 28, 2019
|
||||||
* Author: abody
|
* Author: abody
|
||||||
*/
|
*/
|
||||||
#ifdef USE_CPLUSPLUS
|
#include "f4ll/console_handler.h"
|
||||||
|
|
||||||
#include "f4ll/consolehandler.h"
|
|
||||||
#include "f4ll/crc_handler.h"
|
#include "f4ll/crc_handler.h"
|
||||||
#include "f4ll/irqlock.h"
|
#include "f4ll/irq_lock.h"
|
||||||
#include "f4ll/memcpydma.h"
|
#include "f4ll/memcpy_dma.h"
|
||||||
#include "f4ll/packetusart.h"
|
#include "f4ll/packet_usart.h"
|
||||||
#include "f4ll/strutil.h"
|
#include "f4ll/str_util.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -20,16 +18,42 @@ extern "C" {
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
}
|
}
|
||||||
#include "globals_cpp.h"
|
#include "globals.h"
|
||||||
|
|
||||||
#define PACKAGE_DELAY_MS 0
|
#define PACKAGE_DELAY_MS 0
|
||||||
#define STATS_DELAY_MS 1000
|
#define STATS_DELAY_MS 1000
|
||||||
|
|
||||||
|
|
||||||
#define ADDINFO(b,s,u) \
|
#define ADDINFO(b,s,u) \
|
||||||
b += strcpy_ex(b,s); \
|
b += strcpy_ex(b,s); \
|
||||||
b += uitodec(b,u);
|
b += uitodec(b,u);
|
||||||
|
|
||||||
|
void PrintStats(f4ll::console_handler &con, uint8_t id, f4ll::packet_usart &usart)
|
||||||
|
{
|
||||||
|
// char ids[] = " : ";
|
||||||
|
// char *buffer = m_buffer;
|
||||||
|
// packet_usart::stats const &stats = usart.get_stats();
|
||||||
|
|
||||||
|
// ids[0] = id + '0';
|
||||||
|
// buffer += strcpy_ex(buffer, ids);
|
||||||
|
// ADDINFO(buffer, " s: ", stats.sent);
|
||||||
|
// ADDINFO(buffer, " r: ", stats.rcvd);
|
||||||
|
// ADDINFO(buffer, " sk: ", stats.skiped);
|
||||||
|
// ADDINFO(buffer, " or: ", stats.overrun);
|
||||||
|
// ADDINFO(buffer, " he: ", stats.hdr_error);
|
||||||
|
// ADDINFO(buffer, " pe: ", stats.payload_errror);
|
||||||
|
// buffer += strcpy_ex(buffer, ",0x");
|
||||||
|
// buffer += uitohex(buffer, stats.pep1, 8);
|
||||||
|
// buffer += strcpy_ex(buffer, ",0x");
|
||||||
|
// buffer += uitohex(buffer, stats.pep2, 8);
|
||||||
|
// ADDINFO(buffer, " rde: ", stats.rx_dma_error);
|
||||||
|
// ADDINFO(buffer, " tde: ", stats.tx_dma_error);
|
||||||
|
// ADDINFO(buffer, " pmh: ", stats.premature_hdr);
|
||||||
|
// ADDINFO(buffer, " pmp: ", stats.premature_payload);
|
||||||
|
// buffer += strcpy_ex(buffer, "\r\n");
|
||||||
|
|
||||||
|
// setup_transmit(m_buffer, buffer - m_buffer + 1);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void MainLoop()
|
extern "C" void MainLoop()
|
||||||
{
|
{
|
||||||
uint8_t const text2Send[] __attribute__((aligned(16))) =
|
uint8_t const text2Send[] __attribute__((aligned(16))) =
|
||||||
|
@ -37,17 +61,17 @@ extern "C" void MainLoop()
|
||||||
"--------------------------------------------\r\n\0\0\0";
|
"--------------------------------------------\r\n\0\0\0";
|
||||||
|
|
||||||
|
|
||||||
f4ll::MemcpyDma::Init(MEMCPY_DMA_ENGINE, MEMCPY_DMA_STREAM);
|
f4ll::memcpy_dma::init(MEMCPY_DMA_ENGINE, MEMCPY_DMA_STREAM);
|
||||||
f4ll::crc_handler::Init(DMA2, LL_DMA_STREAM_4);
|
f4ll::crc_handler::init(DMA2, LL_DMA_STREAM_4);
|
||||||
f4ll::ConsoleHandler::Init(UART4, CONSOLE_DMA_ENGINE, 0u, CONSOLE_TX_DMA_STREAM);
|
f4ll::console_handler::init(UART4, CONSOLE_DMA_ENGINE, 0u, CONSOLE_TX_DMA_STREAM);
|
||||||
|
|
||||||
f4ll::PacketUsart u1{ USART1, DMA2, LL_DMA_STREAM_2, LL_DMA_STREAM_7 };
|
f4ll::packet_usart u1{ USART1, DMA2, LL_DMA_STREAM_2, LL_DMA_STREAM_7 };
|
||||||
f4ll::PacketUsart u2{ USART2, DMA1, LL_DMA_STREAM_5, LL_DMA_STREAM_6 };
|
f4ll::packet_usart u2{ USART2, DMA1, LL_DMA_STREAM_5, LL_DMA_STREAM_6 };
|
||||||
f4ll::PacketUsart u3{ USART3, DMA1, LL_DMA_STREAM_1, LL_DMA_STREAM_3 };
|
f4ll::packet_usart u3{ USART3, DMA1, LL_DMA_STREAM_1, LL_DMA_STREAM_3 };
|
||||||
f4ll::PacketUsart u6{ USART6, DMA2, LL_DMA_STREAM_1, LL_DMA_STREAM_6 };
|
f4ll::packet_usart u6{ USART6, DMA2, LL_DMA_STREAM_1, LL_DMA_STREAM_6 };
|
||||||
|
|
||||||
f4ll::PacketUsart * usarts[] = { &u1, &u2, &u3, &u6 };
|
f4ll::packet_usart * usarts[] = { &u1, &u2, &u3, &u6 };
|
||||||
f4ll::PacketUsart **dst = g_usarts;
|
f4ll::packet_usart **dst = g_usarts;
|
||||||
for(auto usart: usarts)
|
for(auto usart: usarts)
|
||||||
*dst++ = usart;
|
*dst++ = usart;
|
||||||
|
|
||||||
|
@ -67,7 +91,7 @@ extern "C" void MainLoop()
|
||||||
lastStatsTick = HAL_GetTick();
|
lastStatsTick = HAL_GetTick();
|
||||||
|
|
||||||
for(auto u : g_usarts)
|
for(auto u : g_usarts)
|
||||||
u->SetupReceive();
|
u->setup_receive();
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
uint32_t tick = HAL_GetTick();
|
uint32_t tick = HAL_GetTick();
|
||||||
|
@ -77,22 +101,22 @@ extern "C" void MainLoop()
|
||||||
prevSentTick += PACKAGE_DELAY_MS;
|
prevSentTick += PACKAGE_DELAY_MS;
|
||||||
|
|
||||||
for(auto u : g_usarts) {
|
for(auto u : g_usarts) {
|
||||||
if(!u->IsTxBusy() && send) {
|
if(!u->is_tx_busy() && send) {
|
||||||
//DIAG_ENTER_BUSY();
|
//DIAG_ENTER_BUSY();
|
||||||
auto len = sizeof(text2Send) - 1 - (rand() & randmask);
|
auto len = sizeof(text2Send) - 1 - (rand() & randmask);
|
||||||
f4ll::MemcpyDma::Instance().Copy(u->GetTxPacketBuffer(), text2Send, len);
|
f4ll::memcpy_dma::instance().copy(u->get_tx_packet_buffer(), text2Send, len);
|
||||||
u->PostPacket(nullptr, len);
|
u->post_packet(nullptr, len);
|
||||||
//DIAG_EXIT_BUSY();
|
//DIAG_EXIT_BUSY();
|
||||||
}
|
}
|
||||||
for(uint16_t rIdx = 0; rIdx < 2; ++rIdx)
|
for(uint16_t rIdx = 0; rIdx < 2; ++rIdx)
|
||||||
if(u->IsRxBusy((bool)rIdx) || u->IsRxFailed(rIdx)) {
|
if(u->is_rx_busy((bool)rIdx) || u->is_rx_failed(rIdx)) {
|
||||||
u->GetRxPacketBuffer(rIdx);
|
u->get_rx_packet_buffer(rIdx);
|
||||||
// ...
|
// ...
|
||||||
u->RxProcessed((bool)rIdx);
|
u->rx_processed((bool)rIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(tick - lastStatsTick > STATS_DELAY_MS) {
|
if(tick - lastStatsTick > STATS_DELAY_MS) {
|
||||||
f4ll::ConsoleHandler::Instance().PrintStats(statId, *g_usarts[statId]);
|
PrintStats(f4ll::console_handler::instance(), statId, *g_usarts[statId]);
|
||||||
lastStatsTick += STATS_DELAY_MS;
|
lastStatsTick += STATS_DELAY_MS;
|
||||||
++statId;
|
++statId;
|
||||||
if(statId >= sizeof(g_usarts) / sizeof(g_usarts[0]))
|
if(statId >= sizeof(g_usarts) / sizeof(g_usarts[0]))
|
||||||
|
@ -105,5 +129,3 @@ extern "C" void MainLoop()
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_CPLUSPLUS
|
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
* Author: abody
|
* Author: abody
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LL_CONSOLEHANDLER_H_
|
#pragma once
|
||||||
#define LL_CONSOLEHANDLER_H_
|
|
||||||
|
|
||||||
#include <f4ll/packet_usart.h>
|
#include <f4ll/packet_usart.h>
|
||||||
|
#include <f4ll/ringbuffer.h>
|
||||||
#include <f4ll/singleton.h>
|
#include <f4ll/singleton.h>
|
||||||
|
|
||||||
namespace f4ll {
|
namespace f4ll {
|
||||||
|
@ -18,7 +18,9 @@ class console_handler : public usart_core, public singleton<console_handler>
|
||||||
friend class singleton<console_handler>;
|
friend class singleton<console_handler>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void PrintStats(uint8_t id, packet_usart &usart);
|
void print(char const *s);
|
||||||
|
void flush();
|
||||||
|
size_t append(char const *s);
|
||||||
|
|
||||||
private:
|
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);
|
||||||
|
@ -35,10 +37,8 @@ private:
|
||||||
virtual void tx_dma_half_transfer(void) override;
|
virtual void tx_dma_half_transfer(void) override;
|
||||||
virtual void tx_dma_error(dma_helper::dma_error_type reason) override;
|
virtual void tx_dma_error(dma_helper::dma_error_type reason) override;
|
||||||
|
|
||||||
char m_buffer[128];
|
ringbuffer<128> m_tx_buffer;
|
||||||
uint16_t m_used = 0;
|
iringbuffer::size_type m_in_flight_size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace f4ll */
|
} /* namespace f4ll */
|
||||||
|
|
||||||
#endif /* LL_CONSOLEHANDLER_H_ */
|
|
||||||
|
|
218
components/f4ll/inc/f4ll/ringbuffer.h
Normal file
218
components/f4ll/inc/f4ll/ringbuffer.h
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* ringbuffer.h
|
||||||
|
*
|
||||||
|
* Created on: May 31, 2025
|
||||||
|
* Author: Attila Body
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace f4ll {
|
||||||
|
|
||||||
|
class iringbuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using size_type = size_t;
|
||||||
|
|
||||||
|
/// @brief Copies data to the ring buffer (without committing it)
|
||||||
|
/// @param data Pointer to the data to copy
|
||||||
|
/// @param len Length of the data to copy
|
||||||
|
/// @retval Length of the data copied (differs when not all data can fit)
|
||||||
|
virtual size_type put(uint8_t const *data, size_type len) = 0;
|
||||||
|
|
||||||
|
/// @brief Commits the data already placed into the buffer and notifies the
|
||||||
|
/// consumer about it's availability
|
||||||
|
virtual void commit() = 0;
|
||||||
|
|
||||||
|
/// @brief Waits until all the data from the ring buffer gets consumed.
|
||||||
|
// void flush();
|
||||||
|
|
||||||
|
/// @brief Gets a pointer to the next chunk of committed data in the buffer
|
||||||
|
/// 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;
|
||||||
|
|
||||||
|
/// @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 Returns the number of uncommited bytes in the ring buffer.
|
||||||
|
virtual size_type uncommited() const = 0;
|
||||||
|
|
||||||
|
/// @brief Returns the number of commited bytes in the ring buffer.
|
||||||
|
virtual size_type commited() const = 0;
|
||||||
|
|
||||||
|
/// @brief Discards the uncommited data in the ring buffer.
|
||||||
|
virtual void discard() = 0;
|
||||||
|
|
||||||
|
/// @brief Returns the size of the internal buffer.
|
||||||
|
/// One byte in the buffer is always reserved as separator
|
||||||
|
virtual size_type size() const = 0;
|
||||||
|
|
||||||
|
/// @brief Returns the size of the used place in the buffer
|
||||||
|
// (including non-commited data)
|
||||||
|
virtual size_type used() const = 0;
|
||||||
|
|
||||||
|
/// @brief Returns the free storage capacity of the buffer
|
||||||
|
virtual size_type unused() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <iringbuffer::size_type SZ> class ringbuffer : public iringbuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ringbuffer() = default;
|
||||||
|
|
||||||
|
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;
|
||||||
|
void consumed(size_type len) override;
|
||||||
|
size_type uncommited() const override;
|
||||||
|
size_type commited() const override;
|
||||||
|
void discard() override;
|
||||||
|
size_type size() const override;
|
||||||
|
size_type used() const override;
|
||||||
|
size_type unused() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t m_buffer[SZ]; //!< Data bufer
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
template <iringbuffer::size_type SZ> iringbuffer::size_type ringbuffer<SZ>::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 = 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <iringbuffer::size_type SZ> bool ringbuffer<SZ>::get_chunk(size_type len_requested, uint8_t const *&data, size_type &len) const
|
||||||
|
{
|
||||||
|
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
|
|
@ -6,8 +6,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <f4ll/console_handler.h>
|
#include <f4ll/console_handler.h>
|
||||||
|
#include <f4ll/irq_lock.h>
|
||||||
#include <f4ll/str_util.h>
|
#include <f4ll/str_util.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace f4ll {
|
namespace f4ll {
|
||||||
|
|
||||||
console_handler::console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx)
|
console_handler::console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx)
|
||||||
|
@ -17,7 +20,19 @@ console_handler::console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_
|
||||||
|
|
||||||
void console_handler::receiver_idle(void) {}
|
void console_handler::receiver_idle(void) {}
|
||||||
|
|
||||||
void console_handler::transmission_complete(void) {}
|
void console_handler::transmission_complete(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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_in_flight_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void console_handler::framing_error(void) {}
|
void console_handler::framing_error(void) {}
|
||||||
|
|
||||||
|
@ -45,35 +60,41 @@ void console_handler::tx_dma_error(dma_helper::dma_error_type reason)
|
||||||
(void)reason;
|
(void)reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADDINFO(b, s, u) \
|
size_t console_handler::append(char const *s)
|
||||||
b += strcpy_ex(b, s); \
|
|
||||||
b += uitodec(b, u);
|
|
||||||
|
|
||||||
void console_handler::PrintStats(uint8_t id, packet_usart &usart)
|
|
||||||
{
|
{
|
||||||
char ids[] = " : ";
|
size_t len = strlen(s);
|
||||||
char *buffer = m_buffer;
|
if (!len) {
|
||||||
packet_usart::stats const &stats(usart.get_stats());
|
return 0;
|
||||||
|
}
|
||||||
|
return len - m_tx_buffer.put(reinterpret_cast<uint8_t const *>(s), len);
|
||||||
|
}
|
||||||
|
|
||||||
ids[0] = id + '0';
|
void console_handler::flush()
|
||||||
buffer += strcpy_ex(buffer, ids);
|
{
|
||||||
ADDINFO(buffer, " s: ", stats.sent);
|
bool busy;
|
||||||
ADDINFO(buffer, " r: ", stats.rcvd);
|
|
||||||
ADDINFO(buffer, " sk: ", stats.skiped);
|
|
||||||
ADDINFO(buffer, " or: ", stats.overrun);
|
|
||||||
ADDINFO(buffer, " he: ", stats.hdr_error);
|
|
||||||
ADDINFO(buffer, " pe: ", stats.payload_errror);
|
|
||||||
buffer += strcpy_ex(buffer, ",0x");
|
|
||||||
buffer += uitohex(buffer, stats.pep1, 8);
|
|
||||||
buffer += strcpy_ex(buffer, ",0x");
|
|
||||||
buffer += uitohex(buffer, stats.pep2, 8);
|
|
||||||
ADDINFO(buffer, " rde: ", stats.rx_dma_error);
|
|
||||||
ADDINFO(buffer, " tde: ", stats.tx_dma_error);
|
|
||||||
ADDINFO(buffer, " pmh: ", stats.premature_hdr);
|
|
||||||
ADDINFO(buffer, " pmp: ", stats.premature_payload);
|
|
||||||
buffer += strcpy_ex(buffer, "\r\n");
|
|
||||||
|
|
||||||
setup_transmit(m_buffer, buffer - m_buffer + 1);
|
if (!m_tx_buffer.uncommited()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_tx_buffer.commit();
|
||||||
|
{
|
||||||
|
irq_lock l;
|
||||||
|
busy = m_in_flight_size != 0;
|
||||||
|
}
|
||||||
|
if (busy) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_handler::print(char const *s)
|
||||||
|
{
|
||||||
|
append(s);
|
||||||
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace f4ll */
|
} /* namespace f4ll */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue