更新模板到最新状态
This commit is contained in:
277
sal/esp32/kernel/os_thread.c
Executable file
277
sal/esp32/kernel/os_thread.c
Executable file
@@ -0,0 +1,277 @@
|
||||
#include "os/os.h"
|
||||
#include "os_util.h"
|
||||
#include "task.h"
|
||||
#include "list/slist.h"
|
||||
|
||||
/* Macro used to convert os_priority to the kernel's real priority */
|
||||
#define OS_KERNEL_PRIO(prio) (prio)
|
||||
|
||||
static slist_t s_thread_list;
|
||||
|
||||
static void _os_delete(struct os_thread_handle *thread_handle)
|
||||
{
|
||||
os_scheduler_suspend();
|
||||
|
||||
slist_remove(&s_thread_list, &thread_handle->node);
|
||||
thread_handle->thread->handle = NULL;
|
||||
if (thread_handle->flag_free)
|
||||
{
|
||||
os_free(thread_handle->thread);
|
||||
}
|
||||
os_free(thread_handle);
|
||||
|
||||
os_scheduler_resume();
|
||||
}
|
||||
|
||||
static void _os_thread_start(void *arg)
|
||||
{
|
||||
struct os_thread_handle *thread_handle = arg;
|
||||
thread_handle->entry(thread_handle->arg);
|
||||
_os_delete(thread_handle);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
os_state os_thread_init(os_thread_t *thread,
|
||||
const char *name,
|
||||
os_thread_entry_t entry,
|
||||
void *arg,
|
||||
void *stack_base,
|
||||
size_t stack_size,
|
||||
os_priority priority)
|
||||
{
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
OS_ASS_HDL(!os_thread_is_valid(thread), thread->handle);
|
||||
|
||||
if (stack_size <= sizeof(struct os_thread_handle) + sizeof(StaticTask_t))
|
||||
{
|
||||
OS_ERR("err size: %d <= %d\r\n", stack_size, sizeof(struct os_thread_handle) + sizeof(StaticTask_t));
|
||||
return OS_FAIL;
|
||||
}
|
||||
|
||||
struct os_thread_handle *thread_handle = stack_base;
|
||||
StaticTask_t *pxTaskBuffer = (StaticTask_t *)&thread_handle[1];
|
||||
StackType_t *puxStackBuffer = (StackType_t *)&pxTaskBuffer[1];
|
||||
|
||||
thread_handle->thread = thread;
|
||||
thread_handle->entry = entry;
|
||||
thread_handle->arg = arg;
|
||||
thread_handle->flag_free = 0;
|
||||
thread_handle->pxCreatedTask = xTaskCreateStatic(_os_thread_start,
|
||||
name,
|
||||
stack_size / sizeof(StackType_t),
|
||||
thread_handle,
|
||||
OS_KERNEL_PRIO(priority),
|
||||
puxStackBuffer,
|
||||
pxTaskBuffer);
|
||||
thread->handle = thread_handle;
|
||||
return OS_OK;
|
||||
|
||||
#else
|
||||
|
||||
OS_ERR("err configSUPPORT_STATIC_ALLOCATION != 1\r\n");
|
||||
return OS_FAIL;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
os_state os_thread_create(os_thread_t *thread,
|
||||
const char *name,
|
||||
os_thread_entry_t entry,
|
||||
void *arg,
|
||||
size_t stack_size,
|
||||
os_priority priority)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (thread)
|
||||
{
|
||||
OS_ASS_HDL(!os_thread_is_valid(thread), thread->handle);
|
||||
}
|
||||
|
||||
struct os_thread_handle *thread_handle = os_malloc(sizeof(struct os_thread_handle));
|
||||
if (thread_handle == NULL)
|
||||
{
|
||||
return OS_E_NOMEM;
|
||||
}
|
||||
|
||||
if (thread == NULL)
|
||||
{
|
||||
thread = os_malloc(sizeof(os_thread_t));
|
||||
if (thread == NULL)
|
||||
{
|
||||
os_free(thread_handle);
|
||||
return OS_E_NOMEM;
|
||||
}
|
||||
memset(thread, 0, sizeof(os_thread_t));
|
||||
thread_handle->flag_free = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_handle->flag_free = 0;
|
||||
}
|
||||
thread->handle = thread_handle;
|
||||
thread_handle->work_q_list = NULL;
|
||||
thread_handle->thread = thread;
|
||||
thread_handle->entry = entry;
|
||||
thread_handle->arg = arg;
|
||||
slist_init_node(&thread_handle->node);
|
||||
|
||||
os_scheduler_suspend();
|
||||
slist_insert_tail(&s_thread_list, &thread_handle->node);
|
||||
os_scheduler_resume();
|
||||
|
||||
ret = xTaskCreatePinnedToCore(_os_thread_start,
|
||||
name,
|
||||
stack_size / sizeof(StackType_t),
|
||||
thread_handle,
|
||||
OS_KERNEL_PRIO(priority),
|
||||
&thread_handle->pxCreatedTask,
|
||||
0);
|
||||
if (ret != pdPASS)
|
||||
{
|
||||
OS_ERR("err %d\r\n", ret);
|
||||
|
||||
os_scheduler_suspend();
|
||||
slist_remove(&s_thread_list, &thread_handle->node);
|
||||
os_scheduler_resume();
|
||||
|
||||
if (thread_handle->flag_free == 0)
|
||||
{
|
||||
thread->handle = NULL;
|
||||
}
|
||||
if (thread_handle->thread)
|
||||
{
|
||||
os_free(thread_handle->thread);
|
||||
}
|
||||
os_free(thread_handle);
|
||||
return OS_FAIL;
|
||||
}
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
os_state os_thread_delete(os_thread_t *thread)
|
||||
{
|
||||
if (thread == NULL) /* delete self */
|
||||
{
|
||||
struct os_thread_handle *thread_handle = os_thread_get_self();
|
||||
_os_delete(thread_handle);
|
||||
vTaskDelete(NULL);
|
||||
return OS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_ASS_HDL(os_thread_is_valid(thread), thread->handle);
|
||||
struct os_thread_handle *thread_handle = thread->handle;
|
||||
vTaskDelete(thread_handle->pxCreatedTask);
|
||||
_os_delete(thread_handle);
|
||||
return OS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void os_thread_sleep(os_time_t msec)
|
||||
{
|
||||
vTaskDelay((TickType_t)os_calc_msec_to_ticks(msec));
|
||||
}
|
||||
|
||||
void os_thread_yield(void)
|
||||
{
|
||||
taskYIELD();
|
||||
}
|
||||
|
||||
void os_thread_suspend(os_thread_t *thread)
|
||||
{
|
||||
if (thread)
|
||||
{
|
||||
OS_ASS_HDL(os_thread_is_valid(thread), thread->handle);
|
||||
struct os_thread_handle *thread_handle = thread->handle;
|
||||
vTaskSuspend(thread_handle->pxCreatedTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void os_thread_resume(os_thread_t *thread)
|
||||
{
|
||||
OS_ASS_HDL(os_thread_is_valid(thread), thread->handle);
|
||||
struct os_thread_handle *thread_handle = thread->handle;
|
||||
vTaskResume(thread_handle->pxCreatedTask);
|
||||
}
|
||||
|
||||
os_thread_handle_t os_thread_get_self(void)
|
||||
{
|
||||
os_thread_handle_t ret = NULL;
|
||||
|
||||
os_scheduler_suspend();
|
||||
TaskHandle_t xTask = xTaskGetCurrentTaskHandle();
|
||||
struct os_thread_handle *thread_handle;
|
||||
struct os_thread_handle *prev_handle = NULL;
|
||||
int cnt = 0;
|
||||
SLIST_FOR_EACH_CONTAINER(&s_thread_list, thread_handle, node)
|
||||
{
|
||||
if (thread_handle->pxCreatedTask == xTask)
|
||||
{
|
||||
ret = thread_handle->thread->handle;
|
||||
break;
|
||||
}
|
||||
prev_handle = thread_handle;
|
||||
cnt++;
|
||||
}
|
||||
if (cnt > 5)
|
||||
{
|
||||
slist_remove_next(&s_thread_list, &prev_handle->node, &thread_handle->node);
|
||||
slist_insert_font(&s_thread_list, &thread_handle->node);
|
||||
}
|
||||
os_scheduler_resume();
|
||||
SYS_ASSERT(ret, "xTask: %p", xTask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *os_thread_get_name(os_thread_t *thread)
|
||||
{
|
||||
struct os_thread_handle *thread_handle = thread->handle;
|
||||
return pcTaskGetName(thread_handle->pxCreatedTask);
|
||||
}
|
||||
|
||||
size_t os_thread_stack_min(os_thread_t *thread)
|
||||
{
|
||||
#if INCLUDE_uxTaskGetStackHighWaterMark
|
||||
TaskHandle_t xTask;
|
||||
|
||||
if (thread != NULL)
|
||||
{
|
||||
if (os_thread_is_valid(thread))
|
||||
{
|
||||
struct os_thread_handle *thread_handle = thread->handle;
|
||||
xTask = thread_handle->pxCreatedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xTask = NULL;
|
||||
}
|
||||
|
||||
extern UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask);
|
||||
return (uxTaskGetStackHighWaterMark(xTask) * sizeof(StackType_t));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool os_thread_is_valid(os_thread_t *thread)
|
||||
{
|
||||
if (thread && thread->handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user