Compare commits

..

No commits in common. "7638f37db70d0afea0b7fb9e7bb923a5073dce38" and "6bbdf4cb718bac1754f2701c41054bbd8912bccb" have entirely different histories.

5 changed files with 34 additions and 200 deletions

View File

@ -17,7 +17,6 @@
#include "threads_primitivethread.hpp"
#include "threads_signal.hpp"
#include "threads_timer.hpp"
namespace Threads
{
@ -37,53 +36,14 @@ public:
(*dd)();
},
this, name, priority, stack_size),
msg_queue_(xQueueCreate(queue_size, sizeof(value_type))), signal_(this)
msg_queue_(xQueueCreate(queue_size, sizeof(value_type))), signal_(*this)
{
assert(msg_queue_);
}
virtual ~Actor() {}
template<typename T>
struct Signal : Signallable<T>
{
using parent = Actor<CRTP, Ts...>;
static_assert(std::is_convertible_v<T, parent::value_type>, "value_type cannot be constructed from T.");
explicit Signal(parent* q)
: q_(q)
{}
bool emit(const T& data) override
{
parent::value_type to_send = data;
const BaseType_t success = xQueueSend(q_->msg_queue_, &to_send, 0);
return success == pdTRUE;
}
std::pair<bool, BaseType_t> emitFromIsr(const T& data) override
{
parent::value_type to_send = data;
BaseType_t was_awoken = pdFALSE;
const BaseType_t success = xQueueSendFromISR(q_->msg_queue_, &to_send, &was_awoken);
return {success == pdTRUE, was_awoken};
}
private:
parent* q_;
};
template<typename U>
Signal<U> getSignal()
{
static_assert(std::is_convertible_v<U, value_type>, "value_type cannot be constructed from U.");
return Signal<U>(this);
}
Signallable<value_type>* getStaticSignal()
Signallable<value_type>* getSignal()
{
return &signal_;
}
@ -129,7 +89,33 @@ private:
}
}
Signal<value_type> signal_;
friend struct Signal_;
struct Signal_ : Signallable<value_type>
{
using parent = Actor<CRTP, Ts...>;
parent& q;
explicit Signal_(parent& q)
: q(q)
{}
bool emit(const value_type& data) override
{
const BaseType_t success = xQueueSend(q.msg_queue_, &data, 0);
return success == pdTRUE;
}
std::pair<bool, BaseType_t> emitFromIsr(const value_type& data) override
{
BaseType_t was_awoken = pdFALSE;
const BaseType_t success = xQueueSendFromISR(q.msg_queue_, &data, &was_awoken);
return {success == pdTRUE, was_awoken};
}
};
Signal_ signal_;
};
template<typename CRTP>

View File

@ -8,7 +8,7 @@
#ifndef THREADS_INC_THREADS_SIGNAL_HPP_
#define THREADS_INC_THREADS_SIGNAL_HPP_
#include <freertos_os2.h>
#include <FreeRTOSConfig.h>
namespace Threads
{

View File

@ -1,54 +0,0 @@
/*
* threads_timer.hpp
*
* Created on: Jun 23, 2021
* Author: erki
*/
#ifndef SKULLC_THREADS_TIMER_HPP_
#define SKULLC_THREADS_TIMER_HPP_
#include <cstdint>
#include <tuple>
#include "threads_signal.hpp"
extern "C" {
struct tmrTimerControl;
typedef struct tmrTimerControl* TimerHandle_t;
}
namespace Threads
{
struct TimeoutSignal
{
};
class Timer
{
public:
Timer(Signallable<TimeoutSignal>* signal, const char* name, const std::int32_t period_ms, const bool auto_reload = true);
~Timer();
void setAutoReload(const bool auto_reload);
void setPeriod(const std::int32_t period_ms);
BaseType_t setPeriodFromIsr(const std::int32_t period_ms);
bool start();
bool stop();
std::pair<bool, BaseType_t> startFromIsr();
std::pair<bool, BaseType_t> stopFromIsr();
private:
TimerHandle_t timer_;
Signallable<TimeoutSignal>* signal_;
static void timeoutHandler_(TimerHandle_t timer);
};
}// namespace Threads
#endif /* SKULLC_THREADS_TIMER_HPP_ */

View File

@ -1,88 +0,0 @@
/*
* threads_timer.cpp
*
* Created on: Jun 23, 2021
* Author: erki
*/
#include "threads_timer.hpp"
#include <algorithm>
#include <array>
#include <freertos_os2.h>
#include <timers.h>
namespace Threads
{
Timer::Timer(Signallable<TimeoutSignal>* signal, const char* name, const std::int32_t period_ms, const bool auto_reload)
: timer_(xTimerCreate(name, pdMS_TO_TICKS(period_ms), auto_reload, this, &Timer::timeoutHandler_)), signal_(signal)
{
assert(timer_);
}
Timer::~Timer()
{
xTimerDelete(timer_, 0);
}
void Timer::setAutoReload(const bool auto_reload)
{
vTimerSetReloadMode(timer_, auto_reload ? pdTRUE : pdFALSE);
}
void Timer::setPeriod(const std::int32_t period_ms)
{
xTimerChangePeriod(timer_, pdMS_TO_TICKS(period_ms), 0);
}
BaseType_t Timer::setPeriodFromIsr(const std::int32_t period_ms)
{
BaseType_t was_awoken = false;
xTimerChangePeriodFromISR(timer_, pdMS_TO_TICKS(period_ms), &was_awoken);
return was_awoken;
}
bool Timer::start()
{
const BaseType_t success = xTimerStart(timer_, 0);
return success != pdFAIL;
}
bool Timer::stop()
{
const BaseType_t success = xTimerStop(timer_, 0);
return success != pdFAIL;
}
std::pair<bool, BaseType_t> Timer::startFromIsr()
{
BaseType_t was_awoken = false;
const BaseType_t success = xTimerStartFromISR(timer_, &was_awoken);
return {success != pdFAIL, was_awoken};
}
std::pair<bool, BaseType_t> Timer::stopFromIsr()
{
BaseType_t was_awoken = false;
const BaseType_t success = xTimerStopFromISR(timer_, &was_awoken);
return {success != pdFAIL, was_awoken};
}
void Timer::timeoutHandler_(TimerHandle_t timer)
{
void* source = pvTimerGetTimerID(timer);
if (!source)
return;
static_cast<Timer*>(source)->signal_->emit(TimeoutSignal{});
}
}// namespace Threads

View File

@ -27,24 +27,14 @@ struct StaticPointer
return *(new (storage) value_type(std::forward<Args>(args)...));
}
const value_type& operator*() const
value_type& operator*() const
{
return *reinterpret_cast<T*>(storage);
return reinterpret_cast<T*>(storage);
}
value_type& operator*()
value_type* operator->() const noexcept
{
return *reinterpret_cast<T*>(storage);
}
value_type* operator->() noexcept
{
return reinterpret_cast<value_type*>(storage);
}
const value_type* operator->() const noexcept
{
return reinterpret_cast<value_type*>(storage);
return reinterpret_cast<T*>(storage);
}
constexpr explicit operator bool() const