diff --git a/include/sta/rtos/handle.hpp b/include/sta/rtos/handle.hpp index 717466b..4959cfc 100644 --- a/include/sta/rtos/handle.hpp +++ b/include/sta/rtos/handle.hpp @@ -60,7 +60,7 @@ namespace sta /** * @brief Access handle value. * - * If the deferred ctor was used the handle value is + * If the deferred constructor was used the handle value is * evaluated on the first call to this method. * * @return Handle value diff --git a/include/sta/rtos/thread.hpp b/include/sta/rtos/thread.hpp index 8c6d957..7c67f11 100644 --- a/include/sta/rtos/thread.hpp +++ b/include/sta/rtos/thread.hpp @@ -2,7 +2,6 @@ #define STA_RTOS_THREAD_HPP #include -#include #include @@ -73,15 +72,30 @@ namespace sta class RtosThread { public: - using Handle = RtosHandle; /**< Thread handle type */ - - public: - RtosThread(); + /** + * @brief Create an RtosThread. + * + * @param name The thread's name. Will be used for debugging. + * @param prio The thread's priority. + */ + RtosThread(const char* name, osPriority_t prio); /** - * @param handle Thread handle + * @brief Get the currently running instance. + * + * @return The currently running instance id. */ - RtosThread(const Handle & handle); + osThreadId_t getInstance(); + + /** + * @brief Get the name of this thread. + */ + const char* getName() const; + + /** + * @brief Start the execution of this thread. + */ + void start(); /** * @brief Sets the thread to BLOCKED for a given number of ticks. @@ -117,23 +131,6 @@ namespace sta */ uint32_t clear(uint32_t flags); - /** - * @brief Send termination request to thread. - */ - void requestTermination(); - - /** - * @brief Clear the termination request flag for this thread. - */ - void deleteTerminationRequest(); - - /** - * @brief Resets the terminate bool to false. - * - * @return Returns the previous value of this variable. - */ - bool isTerminationRequested(); - /** * @brief Forcibly terminate thread. */ @@ -145,22 +142,22 @@ namespace sta * @param flags System flags */ void sysNotify(uint32_t flags); + protected: + /** + * @brief A function that wraps this task's functionality. + */ + virtual void loop() = 0; private: - Handle handle_; - bool terminate_; + /** + * @brief Static function to pass to RTOS to run as a thread. Calls the loop function implemented here. + */ + static void entry_point(void* arg); + + private: + osThreadId_t instance_; + osThreadAttr_t attribs_; }; } // namespace sta - -/** - * @brief Create RtosThread wrapper object for thread handle. - * - * @param name Thread name - */ -#define STA_RTOS_THREAD_WRAPPER(name) \ - extern osThreadId_t name ## Handle; \ - sta::RtosThread name ## Thread = sta::RtosThread(sta::RtosThread::Handle::Deferred(&name ## Handle)); - - #endif // STA_RTOS_THREAD_HPP diff --git a/src/thread.cpp b/src/thread.cpp index b8d7fa0..16ebd66 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -1,5 +1,5 @@ #include - +#include #define IS_THREAD_SYS_FLAGS(flags) ( ( flags & STA_RTOS_THREAD_FLAGS_VALID_SYS_BITS ) == flags ) #define IS_THREAD_USER_FLAGS(flags) ( ( flags & STA_RTOS_THREAD_FLAGS_VALID_USER_BITS ) == flags ) @@ -7,35 +7,64 @@ namespace sta { - RtosThread::RtosThread() - : handle_(nullptr), - terminate_{false} + RtosThread::RtosThread(const char* name, osPriority_t prio) + : instance_{NULL}, + attribs_{ .name = name, .priority = prio } {} - RtosThread::RtosThread(const Handle & handle) - : handle_{handle}, - terminate_{false} - {} + osThreadId_t RtosThread::getInstance() + { + return instance_; + } + + const char* RtosThread::getName() const + { + return attribs_.name; + } + + void RtosThread::start() + { + // Check if there is no instance that is currently running. + STA_ASSERT(instance_ != NULL); + + instance_ = osThreadNew(entry_point, this, &attribs_); + STA_ASSERT(instance_ != NULL); + + // Send a thread start signal. + sysNotify(STA_RTOS_THREAD_FLAG_START); + } + + void RtosThread::entry_point(void* arg) + { + STA_ASSERT(arg != nullptr); + + RtosThread* instance = reinterpret_cast(arg) ; + instance->loop(); + } void RtosThread::sleep(uint32_t ticks) { + // Make sure that the calling thread is this thread. If not, the + // developer very likely has made a mistake. + STA_ASSERT(osThreadGetId() == instance_); + osDelay(ticks); } void RtosThread::notify(uint32_t flags) { - STA_ASSERT(handle_.get() != nullptr); + STA_ASSERT(instance_ != NULL); STA_ASSERT_MSG(IS_THREAD_USER_FLAGS(flags), "Only user flags allowed"); - osThreadFlagsSet(handle_.get(), flags); + osThreadFlagsSet(instance_, flags); } void RtosThread::sysNotify(uint32_t flags) { - STA_ASSERT(handle_.get() != nullptr); + STA_ASSERT(instance_ != NULL); STA_ASSERT_MSG(IS_THREAD_SYS_FLAGS(flags), "Only system flags allowed"); - uint32_t rslt = osThreadFlagsSet(handle_.get(), flags); + uint32_t rslt = osThreadFlagsSet(instance_, flags); STA_ASSERT_MSG(rslt != osFlagsErrorUnknown, "Unknown thread flag error."); STA_ASSERT_MSG(rslt != osFlagsErrorParameter, "Parameter thread_id is not a valid thread or flags has highest bit set."); @@ -44,11 +73,19 @@ namespace sta uint32_t RtosThread::wait(uint32_t flags) { + // Make sure that the calling thread is this thread. If not, the + // developer very likely has made a mistake. + STA_ASSERT(osThreadGetId() == instance_); + return osThreadFlagsWait(flags, osFlagsWaitAny, osWaitForever); } uint32_t RtosThread::clear(uint32_t flags) { + // Make sure that the calling thread is this thread. If not, the + // developer very likely has made a mistake. + STA_ASSERT(osThreadGetId() == instance_); + uint32_t setFlags = osThreadFlagsClear(flags); STA_ASSERT(setFlags != (uint32_t)osError); @@ -58,29 +95,17 @@ namespace sta uint32_t RtosThread::getFlags() { - STA_ASSERT(handle_.get() != nullptr); + // Make sure that the calling thread is this thread. If not, the + // developer very likely has made a mistake. + STA_ASSERT(osThreadGetId() == instance_); return osThreadFlagsGet(); } - void RtosThread::requestTermination() - { - terminate_ = true; - } - - void RtosThread::deleteTerminationRequest() - { - terminate_ = false; - } - - bool RtosThread::isTerminationRequested() - { - return terminate_; - } - void RtosThread::kill() { - STA_ASSERT(handle_.get() != nullptr); - osThreadTerminate(handle_.get()); + STA_ASSERT(instance_ != NULL); + osThreadTerminate(instance_); + instance_ = NULL; } } // namespace sta