mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/rtos2-utils.git
synced 2025-06-10 01:55:59 +00:00
Thread rework to support watchdog restarting
This commit is contained in:
parent
ce2bb459cf
commit
3feedc948f
@ -60,7 +60,7 @@ namespace sta
|
|||||||
/**
|
/**
|
||||||
* @brief Access handle value.
|
* @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.
|
* evaluated on the first call to this method.
|
||||||
*
|
*
|
||||||
* @return Handle value
|
* @return Handle value
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#define STA_RTOS_THREAD_HPP
|
#define STA_RTOS_THREAD_HPP
|
||||||
|
|
||||||
#include <sta/rtos/defs.hpp>
|
#include <sta/rtos/defs.hpp>
|
||||||
#include <sta/rtos/handle.hpp>
|
|
||||||
|
|
||||||
#include <cmsis_os2.h>
|
#include <cmsis_os2.h>
|
||||||
|
|
||||||
@ -73,15 +72,30 @@ namespace sta
|
|||||||
class RtosThread
|
class RtosThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Handle = RtosHandle<osThreadId_t>; /**< Thread handle type */
|
/**
|
||||||
|
* @brief Create an RtosThread.
|
||||||
public:
|
*
|
||||||
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.
|
* @brief Sets the thread to BLOCKED for a given number of ticks.
|
||||||
@ -117,23 +131,6 @@ namespace sta
|
|||||||
*/
|
*/
|
||||||
uint32_t clear(uint32_t flags);
|
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.
|
* @brief Forcibly terminate thread.
|
||||||
*/
|
*/
|
||||||
@ -145,22 +142,22 @@ namespace sta
|
|||||||
* @param flags System flags
|
* @param flags System flags
|
||||||
*/
|
*/
|
||||||
void sysNotify(uint32_t flags);
|
void sysNotify(uint32_t flags);
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @brief A function that wraps this task's functionality.
|
||||||
|
*/
|
||||||
|
virtual void loop() = 0;
|
||||||
|
|
||||||
private:
|
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
|
} // 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
|
#endif // STA_RTOS_THREAD_HPP
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <sta/rtos/thread.hpp>
|
#include <sta/rtos/thread.hpp>
|
||||||
|
#include <sta/debug/assert.hpp>
|
||||||
|
|
||||||
#define IS_THREAD_SYS_FLAGS(flags) ( ( flags & STA_RTOS_THREAD_FLAGS_VALID_SYS_BITS ) == flags )
|
#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 )
|
#define IS_THREAD_USER_FLAGS(flags) ( ( flags & STA_RTOS_THREAD_FLAGS_VALID_USER_BITS ) == flags )
|
||||||
@ -7,35 +7,64 @@
|
|||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
RtosThread::RtosThread()
|
RtosThread::RtosThread(const char* name, osPriority_t prio)
|
||||||
: handle_(nullptr),
|
: instance_{NULL},
|
||||||
terminate_{false}
|
attribs_{ .name = name, .priority = prio }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RtosThread::RtosThread(const Handle & handle)
|
osThreadId_t RtosThread::getInstance()
|
||||||
: handle_{handle},
|
{
|
||||||
terminate_{false}
|
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<RtosThread*>(arg) ;
|
||||||
|
instance->loop();
|
||||||
|
}
|
||||||
|
|
||||||
void RtosThread::sleep(uint32_t ticks)
|
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);
|
osDelay(ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtosThread::notify(uint32_t flags)
|
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");
|
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)
|
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");
|
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 != osFlagsErrorUnknown, "Unknown thread flag error.");
|
||||||
STA_ASSERT_MSG(rslt != osFlagsErrorParameter, "Parameter thread_id is not a valid thread or flags has highest bit set.");
|
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)
|
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);
|
return osThreadFlagsWait(flags, osFlagsWaitAny, osWaitForever);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RtosThread::clear(uint32_t flags)
|
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);
|
uint32_t setFlags = osThreadFlagsClear(flags);
|
||||||
|
|
||||||
STA_ASSERT(setFlags != (uint32_t)osError);
|
STA_ASSERT(setFlags != (uint32_t)osError);
|
||||||
@ -58,29 +95,17 @@ namespace sta
|
|||||||
|
|
||||||
uint32_t RtosThread::getFlags()
|
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();
|
return osThreadFlagsGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtosThread::requestTermination()
|
|
||||||
{
|
|
||||||
terminate_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtosThread::deleteTerminationRequest()
|
|
||||||
{
|
|
||||||
terminate_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RtosThread::isTerminationRequested()
|
|
||||||
{
|
|
||||||
return terminate_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtosThread::kill()
|
void RtosThread::kill()
|
||||||
{
|
{
|
||||||
STA_ASSERT(handle_.get() != nullptr);
|
STA_ASSERT(instance_ != NULL);
|
||||||
osThreadTerminate(handle_.get());
|
osThreadTerminate(instance_);
|
||||||
|
instance_ = NULL;
|
||||||
}
|
}
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
Loading…
x
Reference in New Issue
Block a user