You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.3 KiB
135 lines
3.3 KiB
#include "zthread.hpp"
|
|
|
|
#include <map>
|
|
|
|
#include "zoslogger.hpp"
|
|
|
|
using namespace iflytop;
|
|
using namespace std;
|
|
|
|
static bool s_map_inited = false;
|
|
static zmutex s_zthread_map_lock;
|
|
static map<osThreadId, ZThread *> s_zthread_map;
|
|
static ZThread g_default_thread;
|
|
|
|
static void zosthread_default_task(void const *argument) {
|
|
ZThread *thread = (ZThread *)argument;
|
|
ZASSERT(thread);
|
|
thread->threadcb();
|
|
};
|
|
|
|
void ZThread::zthread_module_init() {
|
|
if (s_map_inited) return;
|
|
s_map_inited = true;
|
|
s_zthread_map_lock.init();
|
|
}
|
|
|
|
ZThread *ZThread::getThread() {
|
|
ZThread *thread = nullptr;
|
|
{
|
|
zlock_guard guard(s_zthread_map_lock);
|
|
thread = s_zthread_map[osThreadGetId()];
|
|
}
|
|
return thread;
|
|
}
|
|
|
|
void ZThread::threadcb() {
|
|
m_status = kidle;
|
|
|
|
{
|
|
zlock_guard guard(s_zthread_map_lock);
|
|
s_zthread_map[osThreadGetId()] = this;
|
|
}
|
|
|
|
while (true) {
|
|
if (m_threadisworkingFlagCallSide) {
|
|
m_status = kworking;
|
|
if (m_taskfunction) m_taskfunction();
|
|
if (m_taskfunction_exitcb) m_taskfunction_exitcb();
|
|
m_status = kdead;
|
|
|
|
while (m_threadisworkingFlagCallSide) {
|
|
vTaskDelay(10);
|
|
}
|
|
m_status = kidle;
|
|
}
|
|
vTaskDelay(10);
|
|
}
|
|
}
|
|
|
|
void ZThread::init(const char *threadname, int stack_size, osPriority priority) {
|
|
// int r_task_create = 0;
|
|
ZASSERT(threadname);
|
|
|
|
m_lock = xSemaphoreCreateMutex();
|
|
ZASSERT(m_lock);
|
|
|
|
m_stacksize = stack_size;
|
|
m_uxPriority = osPriorityNormal;
|
|
m_taskfunction = nullptr;
|
|
m_zthreadstartworkevent = xEventGroupCreate();
|
|
m_name = threadname;
|
|
|
|
osThreadDef(zosthread_default_task, zosthread_default_task, m_uxPriority, 0, m_stacksize);
|
|
m_defaultTaskHandle = osThreadCreate(osThread(zosthread_default_task), this);
|
|
ZASSERT(m_defaultTaskHandle != NULL);
|
|
}
|
|
void ZThread::start(zosthread_cb_t cb) { start(cb, nullptr); }
|
|
|
|
void ZThread::start(zosthread_cb_t cb, zosthread_cb_t exitcb) {
|
|
stop();
|
|
|
|
m_taskfunction = cb;
|
|
m_taskfunction_exitcb = exitcb;
|
|
|
|
ZASSERT(m_taskfunction);
|
|
xSemaphoreTake(m_lock, portMAX_DELAY);
|
|
m_threadisworkingFlagCallSide = true;
|
|
// xEventGroupSetBits(m_zthreadstartworkevent, 0x01);
|
|
while (m_status == kidle) {
|
|
xTaskNotifyGive(m_defaultTaskHandle);
|
|
vTaskDelay(1);
|
|
}
|
|
xSemaphoreGive(m_lock);
|
|
}
|
|
|
|
void ZThread::stop() {
|
|
xSemaphoreTake(m_lock, portMAX_DELAY);
|
|
m_threadisworkingFlagCallSide = false;
|
|
// xEventGroupSetBits(m_zthreadstartworkevent, 0x01);
|
|
while (m_status != kidle) {
|
|
xTaskNotifyGive(m_defaultTaskHandle);
|
|
vTaskDelay(1);
|
|
}
|
|
xSemaphoreGive(m_lock);
|
|
}
|
|
|
|
void ZThread::sleep(uint32_t ms) { ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(ms)); }
|
|
void ZThread::wake() {
|
|
BaseType_t state;
|
|
if (xPortIsInsideInterrupt()) {
|
|
vTaskNotifyGiveFromISR(m_defaultTaskHandle, &state);
|
|
} else {
|
|
xTaskNotifyGive(m_defaultTaskHandle);
|
|
}
|
|
}
|
|
|
|
ThisThread::ThisThread() {
|
|
ZThread *thread = ZThread::getThread();
|
|
this->thread = thread;
|
|
}
|
|
bool ThisThread::getExitFlag() {
|
|
if (thread) return thread->getExitFlag();
|
|
return false;
|
|
}
|
|
bool ThisThread::isworking() {
|
|
if (thread) return thread->isworking();
|
|
return true;
|
|
}
|
|
void ThisThread::sleep(uint32_t ms) {
|
|
if (thread) {
|
|
thread->sleep(ms);
|
|
} else {
|
|
vTaskDelay(pdMS_TO_TICKS(ms));
|
|
}
|
|
}
|