Add thread wrapper class

This commit is contained in:
Henrik Stickann 2022-12-02 16:34:52 +01:00
parent 57d0dd0bcd
commit 4e355d244b
2 changed files with 162 additions and 0 deletions

116
include/sta/rtos/thread.hpp Normal file
View File

@ -0,0 +1,116 @@
#ifndef STA_RTOS_THREAD_HPP
#define STA_RTOS_THREAD_HPP
#include <sta/rtos/defs.hpp>
#include <sta/rtos/handle.hpp>
#include <cmsis_os2.h>
/**
* @ingroup STA_RTOS_API
* @{
*/
/**
* @brief Number of bits in task notification flags used internally.
*/
#define STA_RTOS_MAX_BITS_THREAD_SYS_NOTIFY 1U
/**
* @brief Number of user usable bits in task notification flags.
*/
#define STA_RTOS_MAX_BITS_THREAD_USER_NOTIFY ( STA_RTOS_MAX_BITS_THREAD_NOTIFY - STA_RTOS_MAX_BITS_THREAD_SYS_NOTIFY )
/**
* @brief Mask for valid system task notification flag bits.
*/
#define STA_RTOS_THREAD_FLAGS_VALID_SYS_BITS ( ( ( 1UL << STA_RTOS_MAX_BITS_THREAD_SYS_NOTIFY ) - 1U ) << STA_RTOS_MAX_BITS_THREAD_USER_NOTIFY )
/**
* @brief Mask for valid user task notification flag bits.
*/
#define STA_RTOS_THREAD_FLAGS_VALID_USER_BITS ( ( 1UL << STA_RTOS_MAX_BITS_THREAD_USER_NOTIFY ) - 1U )
/**
* @brief Indicate error code instead of flag values.
*/
#define STA_RTOS_THREAD_FLAG_ERROR_CODE ( 1UL << 31 )
/**
* @brief Request thread termination.
*/
#define STA_RTOS_THREAD_FLAG_TERMINATE ( 1UL << 30 )
#define STA_RTOS_THREAD_FLAGS_ERROR_CODE_BITS UINT32_C( 0x0000000F )
#define STA_RTOS_THREAD_FLAGS_ERROR_CODE_EXT_BITS UINT32_C( 0x7FFFFFF0 )
#define STA_RTOS_THREAD_FLAGS_GET_EXT_ERROR_CODE(flags) (~flags & STA_RTOS_THREAD_FLAGS_ERROR_CODE_EXT_BITS)
#define STA_RTOS_THREAD_FLAGS_WAIT_ANY(timeout) osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, timeout)
/** @} */
namespace sta
{
/**
* @brief Wrapper for RTOS thread control.
*
* @ingroup STA_RTOS_API
*/
class RtosThread
{
public:
using Handle = RtosHandle<osThreadId_t>; /**< Thread handle type */
public:
RtosThread();
/**
* @param handle Thread handle
*/
RtosThread(const Handle & handle);
/**
* @brief Send user notification flags to thread.
*
* @param flags User flags
*/
void notify(uint32_t flags);
/**
* @brief Send termination request to thread.
*/
void requestTermination();
/**
* @brief Forcibly terminate thread.
*/
void terminate();
/**
* @brief Send system notification flags to thread.
*
* @param flags System flags
*/
void sysNotify(uint32_t flags);
private:
Handle handle_;
};
} // 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

46
src/thread.cpp Normal file
View File

@ -0,0 +1,46 @@
#include <sta/rtos/thread.hpp>
#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 )
namespace sta
{
RtosThread::RtosThread()
: handle_(nullptr)
{}
RtosThread::RtosThread(const Handle & handle)
: handle_{handle}
{}
void RtosThread::notify(uint32_t flags)
{
STA_ASSERT(handle_.get() != nullptr);
STA_ASSERT_MSG(IS_THREAD_USER_FLAGS(flags), "Only user flags allowed");
osThreadFlagsSet(handle_.get(), flags);
}
void RtosThread::sysNotify(uint32_t flags)
{
STA_ASSERT(handle_.get() != nullptr);
STA_ASSERT_MSG(IS_THREAD_SYS_FLAGS(flags), "Only system flags allowed");
osThreadFlagsSet(handle_.get(), flags);
}
void RtosThread::requestTermination()
{
sysNotify(STA_RTOS_THREAD_FLAG_TERMINATE);
}
void RtosThread::terminate()
{
STA_ASSERT(handle_.get() != nullptr);
osThreadTerminate(handle_.get());
}
} // namespace sta