74 lines
1.4 KiB
C++
74 lines
1.4 KiB
C++
/*
|
|
* utility_asynchuartlogger.cpp
|
|
*
|
|
* Created on: Mar 20, 2021
|
|
* Author: erki
|
|
*/
|
|
|
|
#include "utility_asyncaurtlogger.hpp"
|
|
|
|
#include <cstdlib>
|
|
#include <cstdarg>
|
|
#include <cassert>
|
|
|
|
#include "utility_atomicscopeguard.hpp"
|
|
|
|
namespace Utility
|
|
{
|
|
|
|
AsyncUARTLogger* AsyncUARTLogger::_this = nullptr;
|
|
|
|
AsyncUARTLogger::AsyncUARTLogger(UART_HandleTypeDef* huart)
|
|
: _huart(huart)
|
|
{
|
|
assert(!_this);
|
|
|
|
_this = this;
|
|
_huart->TxCpltCallback = &AsyncUARTLogger::_txCompleteCallback;
|
|
}
|
|
|
|
void AsyncUARTLogger::log(const char* format, ...)
|
|
{
|
|
{
|
|
AtomicScopeGuard s;
|
|
|
|
if (_buffer_queue.size() == _buffer_queue.max_size())
|
|
return;
|
|
}
|
|
|
|
std::va_list args;
|
|
va_start(args, format);
|
|
|
|
auto tail = _buffer_queue.end();
|
|
std::array<char, 255>& buffer = tail->buffer;
|
|
|
|
tail->length = vsnprintf(buffer.data(), buffer.size(), format, args);
|
|
|
|
{
|
|
AtomicScopeGuard s;
|
|
_buffer_queue.increment_tail();
|
|
|
|
if (!_in_flight)
|
|
_sendNextLog();
|
|
}
|
|
}
|
|
|
|
void AsyncUARTLogger::_txCompleteCallback(UART_HandleTypeDef*)
|
|
{
|
|
if (!AsyncUARTLogger::_this->_buffer_queue.empty())
|
|
AsyncUARTLogger::_this->_sendNextLog();
|
|
else
|
|
AsyncUARTLogger::_this->_in_flight = false;
|
|
}
|
|
|
|
void AsyncUARTLogger::_sendNextLog()
|
|
{
|
|
_in_flight = true;
|
|
|
|
_Data& head = _buffer_queue.front();
|
|
HAL_UART_Transmit_DMA(_huart, reinterpret_cast<uint8_t*>(head.buffer.data()), head.length);
|
|
_buffer_queue.pop_front();
|
|
}
|
|
|
|
}
|