diff --git a/Threads/Inc/threads_thread.hpp b/Threads/Inc/threads_thread.hpp new file mode 100644 index 0000000..4ad267d --- /dev/null +++ b/Threads/Inc/threads_thread.hpp @@ -0,0 +1,120 @@ +/* + * tasks_task.hpp + * + * Created on: Mar 18, 2021 + * Author: erki + */ + +#ifndef SKULLC_THREADS_THREAD_HPP_ +#define SKULLC_THREADS_THREAD_HPP_ + +#include + +#include + +#include +#include +#include + +#include + +namespace Threads +{ + +template +class Thread +{ +public: + Thread(const osThreadAttr_t attrs) + : attributes(attrs) + { + auto f = [](void* d) { + CRTP* dd = static_cast(d); + (*dd)(); + }; + + thread_id = osThreadNew(f, this, &attributes); + assert(thread_id != nullptr); + } + + Thread(const char* name, const osPriority_t priority, const std::uint32_t stack_size) + : Thread(constructThreadAttrs_(name, priority, stack_size)) + {} + + Thread(const Thread&) = delete; + Thread(Thread&&) = delete; + + osThreadId_t thread_id; + osThreadAttr_t attributes; + + constexpr TaskHandle_t taskHandle() const + { + return static_cast(thread_id); + } + + [[nodiscard]] BaseType_t notify(const long value, const eNotifyAction action) + { + return xTaskNotify(taskHandle(), value, action); + } + + /** + * + * @returns Tuple. First member indicating the return value of the underlying notify + * function, the second member indicating whether a higher priority task was awoken. + * + */ + [[nodiscard]] std::pair notifyFromIsr(const long value, const eNotifyAction action) + { + BaseType_t was_notified = pdFALSE; + + const BaseType_t rval = xTaskNotifyFromISR(taskHandle(), value, action, &was_notified); + + return {rval, was_notified}; + } + + void yield() + { + osThreadYield(); + } + + void sleep(const unsigned long delay) + { + osDelay(delay); + } + + void sleepUntil(const unsigned long deadline) + { + osDelayUntil(deadline); + } + +protected: + bool notifyWait(const TickType_t delay) const + { + return xTaskNotifyWait(0, std::numeric_limits::max(), nullptr, delay); + } + + std::pair notifyWait(const TickType_t delay, const unsigned long set_on_entry, const unsigned long set_on_exit) const + { + unsigned long notification_value = 0; + const bool rval = xTaskNotifyWait(set_on_entry, set_on_exit, ¬ification_value, delay); + + return {rval, notification_value}; + } + +private: + osThreadAttr_t constructThreadAttrs_(const char* name, const osPriority_t priority, const std::uint32_t stack_size) + { + auto attrs = Peripherals::zeroInitialized(); + + attrs.name = name; + attrs.priority = priority; + attrs.stack_size = stack_size; + + return attrs; + } +}; + +}// namespace Threads + + +#endif /* SKULLC_THREADS_THREAD_HPP_ */