#include "zthread.hpp" #include "zoslogger.hpp" using namespace iflytop; using namespace std; static void zosthread_default_task(void const *argument) { ZThread *thread = (ZThread *)argument; ZASSERT(thread); thread->m_threadisworkingFlag = false; thread->m_threadisWaitingForStopFlag = false; while (true) { if (thread->m_threadisworkingFlagCallSide) { thread->m_threadisworkingFlag = true; thread->m_taskfunction(); thread->m_threadisWaitingForStopFlag = true; while (thread->m_threadisworkingFlagCallSide) { vTaskDelay(10); } thread->m_threadisworkingFlag = false; thread->m_threadisWaitingForStopFlag = false; } 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) { stop(); m_taskfunction = cb; ZASSERT(m_taskfunction); xSemaphoreTake(m_lock, portMAX_DELAY); m_threadisworkingFlagCallSide = true; // xEventGroupSetBits(m_zthreadstartworkevent, 0x01); while (!m_threadisworkingFlag) { 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_threadisworkingFlag) { 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); } }