Compare commits
No commits in common. "faa1685e183476a1db1f2e21e70319ee20115101" and "d945e7a79992bf0734907917c965cea5a27df63e" have entirely different histories.
faa1685e18
...
d945e7a799
@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
||||
|
||||
add_library(utility STATIC
|
||||
Src/utility_logging.cpp
|
||||
Src/utility_itmlogger.cpp
|
||||
)
|
||||
|
||||
add_library(skullc::utility ALIAS utility)
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* utility_asyncaurtlogger.hpp
|
||||
*
|
||||
* Created on: Mar 20, 2021
|
||||
* Author: erki
|
||||
*/
|
||||
|
||||
#ifndef SKULLC_UTILITY_ASYNCAURTLOGGER_HPP_
|
||||
#define SKULLC_UTILITY_ASYNCAURTLOGGER_HPP_
|
||||
|
||||
#include "utility_ilogger.hpp"
|
||||
#include "utility_ringbuffer.hpp"
|
||||
|
||||
#include "usart.h"
|
||||
|
||||
namespace Utility
|
||||
{
|
||||
|
||||
class AsyncUARTLogger : public ILogger
|
||||
{
|
||||
public:
|
||||
explicit AsyncUARTLogger(UART_HandleTypeDef* huart);
|
||||
AsyncUARTLogger() = delete;
|
||||
AsyncUARTLogger(const AsyncUARTLogger&) = delete;
|
||||
AsyncUARTLogger(AsyncUARTLogger&&) = delete;
|
||||
|
||||
void log(const char* format, ...);
|
||||
|
||||
private:
|
||||
struct _Data
|
||||
{
|
||||
std::array<char, 255> buffer;
|
||||
std::int32_t length;
|
||||
};
|
||||
|
||||
Ringbuffer<_Data, 10> _buffer_queue;
|
||||
UART_HandleTypeDef* _huart;
|
||||
bool _in_flight = false;
|
||||
|
||||
static AsyncUARTLogger* _this;
|
||||
static void _txCompleteCallback(UART_HandleTypeDef* huart);
|
||||
|
||||
void _sendNextLog();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* SKULLC_UTILITY_ASYNCAURTLOGGER_HPP_ */
|
||||
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* utility_atomicscopeguard.hpp
|
||||
*
|
||||
* Created on: Mar 21, 2021
|
||||
* Author: erki
|
||||
*/
|
||||
|
||||
#ifndef UTILITY_INC_UTILITY_ATOMICSCOPEGUARD_HPP_
|
||||
#define UTILITY_INC_UTILITY_ATOMICSCOPEGUARD_HPP_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Utility
|
||||
{
|
||||
|
||||
class AtomicScopeGuard
|
||||
{
|
||||
public:
|
||||
AtomicScopeGuard();
|
||||
AtomicScopeGuard(const AtomicScopeGuard&) = delete;
|
||||
AtomicScopeGuard(AtomicScopeGuard&&) = delete;
|
||||
|
||||
~AtomicScopeGuard();
|
||||
|
||||
private:
|
||||
static std::int32_t _reentrancy_counter;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* UTILITY_INC_UTILITY_ATOMICSCOPEGUARD_HPP_ */
|
||||
@ -155,9 +155,6 @@ public:
|
||||
|
||||
*_tail = value;
|
||||
++_tail;
|
||||
|
||||
if (_tail == _head)
|
||||
_is_full = true;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -170,21 +167,12 @@ public:
|
||||
++_tail;
|
||||
}
|
||||
|
||||
void increment_tail()
|
||||
{
|
||||
if (_tail == _head)
|
||||
++_head;
|
||||
|
||||
++_tail;
|
||||
}
|
||||
|
||||
void pop_front()
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
++_head;
|
||||
_is_full = false;
|
||||
}
|
||||
|
||||
reference front()
|
||||
@ -210,12 +198,7 @@ public:
|
||||
size_type size() const
|
||||
{
|
||||
if (_head == _tail)
|
||||
{
|
||||
if (_is_full)
|
||||
return N;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
const typename Ringbuffer<T, N>::iterator::difference_type distance = _tail - _head;
|
||||
|
||||
@ -225,15 +208,10 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
return _head - _tail + 1;
|
||||
return _head - _tail;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr size_type max_size() const
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return size() == 0;
|
||||
@ -241,7 +219,6 @@ public:
|
||||
|
||||
private:
|
||||
std::array<T, N> _data;
|
||||
bool _is_full = false;
|
||||
|
||||
iterator _head;
|
||||
iterator _tail;
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* utility_atomicscopeguard.cpp
|
||||
*
|
||||
* Created on: Mar 21, 2021
|
||||
* Author: erki
|
||||
*/
|
||||
|
||||
#include "utility_atomicscopeguard.hpp"
|
||||
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
namespace Utility
|
||||
{
|
||||
|
||||
std::int32_t AtomicScopeGuard::_reentrancy_counter;
|
||||
|
||||
AtomicScopeGuard::AtomicScopeGuard()
|
||||
{
|
||||
__disable_irq();
|
||||
_reentrancy_counter++;
|
||||
}
|
||||
|
||||
AtomicScopeGuard::~AtomicScopeGuard()
|
||||
{
|
||||
_reentrancy_counter--;
|
||||
|
||||
if (!_reentrancy_counter)
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -96,50 +96,6 @@ TEST_CASE("Constructed buffer is empty.", "[ringbuffer]")
|
||||
REQUIRE(buffer.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("Buffer reports size properly.", "[ringbuffer]")
|
||||
{
|
||||
Ringbuffer<3> buffer;
|
||||
|
||||
buffer.push_back(1);
|
||||
buffer.push_back(2);
|
||||
|
||||
SECTION("max_size() reports maximum size properly.")
|
||||
{
|
||||
REQUIRE(buffer.max_size() == 3);
|
||||
}
|
||||
|
||||
SECTION("After pushing 2 elements, size is reported properly.")
|
||||
{
|
||||
REQUIRE(buffer.size() == 2);
|
||||
}
|
||||
|
||||
SECTION("A full buffer reports size as max_size.")
|
||||
{
|
||||
buffer.push_back(3);
|
||||
REQUIRE(buffer.size() == 3);
|
||||
REQUIRE(buffer.size() == buffer.max_size());
|
||||
}
|
||||
|
||||
SECTION("Removing an element updates size properly.")
|
||||
{
|
||||
buffer.pop_front();
|
||||
|
||||
REQUIRE(buffer.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("Removing and adding an element updates size properly.")
|
||||
{
|
||||
buffer.pop_front();
|
||||
buffer.push_back(4);
|
||||
|
||||
REQUIRE(buffer.size() == 2);
|
||||
|
||||
buffer.push_back(5);
|
||||
|
||||
REQUIRE(buffer.size() == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Adding single element.", "[ringbuffer]")
|
||||
{
|
||||
Ringbuffer<10> buffer;
|
||||
@ -292,53 +248,3 @@ TEST_CASE("Clearing a ringbuffer works.", "[ringbuffer]")
|
||||
REQUIRE(buffer.begin() == buffer.end());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Manually incrementing tail works.", "[ringbuffer]")
|
||||
{
|
||||
Ringbuffer<10> buffer;
|
||||
|
||||
buffer.push_back(1);
|
||||
|
||||
auto old_end = buffer.end();
|
||||
*old_end = 2;
|
||||
|
||||
buffer.increment_tail();
|
||||
|
||||
SECTION("New end is set forward by 1.")
|
||||
{
|
||||
const auto new_end = buffer.end();
|
||||
REQUIRE(old_end != new_end);
|
||||
REQUIRE(new_end - old_end == 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Manually incrementing tail when full deletes data.", "[ringbuffer]")
|
||||
{
|
||||
Ringbuffer<2> buffer;
|
||||
|
||||
buffer.push_back(1);
|
||||
buffer.push_back(2);
|
||||
|
||||
const auto old_start = buffer.begin();
|
||||
const auto old_end = buffer.end();
|
||||
|
||||
REQUIRE(buffer.size() == buffer.max_size());
|
||||
|
||||
buffer.increment_tail();
|
||||
|
||||
REQUIRE(buffer.size() == buffer.max_size());
|
||||
|
||||
SECTION("End is incremented properly.")
|
||||
{
|
||||
const auto new_end = buffer.end();
|
||||
REQUIRE(old_end != new_end);
|
||||
REQUIRE(new_end - old_end == 1);
|
||||
}
|
||||
|
||||
SECTION("Begin is incremented properly.")
|
||||
{
|
||||
const auto new_start = buffer.begin();
|
||||
REQUIRE(old_start != new_start);
|
||||
REQUIRE(new_start - old_start == 1);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user