Files
ESPC3-wireless/sal/esp32/kernel/os_kit.c
2025-02-13 17:17:07 +08:00

904 lines
21 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "os/os.h"
#include "os_util.h"
#include "k_kit.h"
static os_work_q_t s_default_work_q_handle;
os_work_q_t *default_os_work_q_hdl = &s_default_work_q_handle;
static void _os_work_q_thread(void *arg);
static void _os_work_q_resume(void *arg);
static void _os_work_q_thread(void *arg)
{
os_work_q_list_t *list = arg;
for (;;)
{
k_tick_t tick = k_work_q_handler(&list->work_q_handle);
os_sem_take(&list->sem_handle, OS_TicksToMSecs(tick));
}
}
static void _os_work_q_resume(void *arg)
{
os_sem_release(arg);
}
os_state os_work_q_create(os_work_q_t *work_q_handle, // 队列句柄
const char *name, // 队列名
size_t stack_size, // 栈大小(字节)
os_priority priority // 0 CONFIG_OS_MAX_PRIORITY (CONFIG_OS_MAX_PRIORITY + 1 + priority)
)
{
os_work_q_list_t *list = NULL;
os_state ret;
do
{
if (os_work_q_is_valid(work_q_handle) != false)
{
OS_WRN("work_q is initialized");
ret = OS_FAIL;
break;
}
list = os_malloc(sizeof(*list));
if (list == NULL)
{
ret = OS_E_NOMEM;
break;
}
else
{
memset(list, 0, sizeof(*list));
}
if (k_work_q_create(&list->work_q_handle) != 0)
{
ret = OS_E_NOMEM;
break;
}
ret = os_sem_create(&list->sem_handle, 0, 1);
if (ret != OS_OK)
{
break;
}
ret = os_thread_create(&list->thread,
name,
_os_work_q_thread,
list,
stack_size,
priority);
if (ret != OS_OK)
{
break;
}
if (work_q_handle)
{
work_q_handle->handle = list;
}
struct os_thread_handle *thread_handle = list->thread.handle;
thread_handle->work_q_list = list;
k_work_q_resume_regist(&list->work_q_handle, _os_work_q_resume, &list->sem_handle);
ret = OS_OK;
} while (0);
if (ret != OS_OK)
{
if (list)
{
if (list->thread.handle)
os_thread_delete(&list->thread);
if (list->sem_handle.handle)
os_sem_delete(&list->sem_handle);
if (list->work_q_handle.hdl)
k_work_q_delete(&list->work_q_handle);
os_free(list);
}
}
return ret;
}
os_state os_work_q_delete(os_work_q_t *work_q_handle)
{
OS_ASS_ISR();
os_state ret;
do
{
if (os_work_q_is_valid(work_q_handle) == false)
{
OS_WRN("work_q is invalid");
ret = OS_FAIL;
break;
}
os_scheduler_suspend();
os_work_q_list_t *list = work_q_handle->handle;
if (list)
{
os_thread_delete(&list->thread);
os_sem_delete(&list->sem_handle);
k_work_q_delete(&list->work_q_handle);
os_free(list);
work_q_handle->handle = NULL;
ret = OS_OK;
}
else
{
OS_ERR("err %p", work_q_handle);
ret = OS_E_PARAM;
}
os_scheduler_resume();
} while (0);
return ret;
}
bool os_work_q_is_valid(os_work_q_t *work_q_handle)
{
bool ret;
if (work_q_handle == NULL || work_q_handle->handle == NULL)
{
ret = false;
}
else
{
ret = k_work_q_is_valid(work_q_handle->handle);
}
return ret;
}
bool os_work_q_delayed_state(os_work_q_t *work_q_handle)
{
bool ret;
if (os_work_q_is_valid(work_q_handle) == false)
{
OS_WRN("work_q is invalid");
ret = false;
}
else
{
ret = k_work_q_delayed_state(work_q_handle->handle);
}
return ret;
}
bool os_work_q_ready_state(os_work_q_t *work_q_handle)
{
bool ret;
if (os_work_q_is_valid(work_q_handle) == false)
{
OS_WRN("work_q is invalid");
ret = false;
}
else
{
ret = k_work_q_ready_state(work_q_handle->handle);
}
return ret;
}
os_state os_work_create(os_work_t *work_handle, const char *name, os_work_fn work_route, void *arg, uint8_t sub_prior)
{
OS_ASS_ISR();
k_err_t ret = k_work_create((k_work_t *)work_handle, name, (k_work_fn)work_route, arg, sub_prior);
if (ret == 0)
{
return OS_OK;
}
else
{
return OS_E_NOMEM;
}
}
os_state os_work_create_default(os_work_t *work_handle, const char *name, os_work_fn work_route, void *arg, uint8_t sub_prior, os_time_t delay_ms)
{
if (!os_work_is_valid(work_handle))
{
os_state ret = os_work_create(work_handle, name, work_route, arg, sub_prior);
if (ret == OS_OK)
{
os_work_submit(default_os_work_q_hdl, work_handle, delay_ms);
}
return ret;
}
else
{
return OS_OK;
}
}
void os_work_delete(os_work_t *work_handle)
{
OS_ASS_ISR();
k_work_delete((k_work_t *)work_handle);
}
bool os_work_is_valid(os_work_t *work_handle)
{
bool ret = k_work_is_valid((k_work_t *)work_handle);
return ret;
}
bool os_work_is_pending(os_work_t *work_handle)
{
bool ret = k_work_is_pending((k_work_t *)work_handle);
return ret;
}
os_time_t os_work_time_remain(os_work_t *work_handle)
{
k_tick_t ret = k_work_time_remain((k_work_t *)work_handle);
return os_calc_ticks_to_msec(ret);
}
void os_work_submit(os_work_q_t *work_q_handle, os_work_t *work_handle, os_time_t delay_ms)
{
if (os_work_q_is_valid(work_q_handle) == false)
{
OS_WRN("work_q is invalid");
}
else
{
k_work_submit(work_q_handle->handle, (k_work_t *)work_handle, os_calc_msec_to_ticks(delay_ms));
}
}
void os_work_resume(os_work_t *work_handle, os_time_t delay_ms)
{
k_work_resume((k_work_t *)work_handle, os_calc_msec_to_ticks(delay_ms));
}
void os_work_suspend(os_work_t *work_handle)
{
k_work_suspend((k_work_t *)work_handle);
}
void os_work_yield(os_time_t ms)
{
k_work_yield(os_calc_msec_to_ticks(ms));
}
void os_work_sleep(os_time_t ms)
{
k_work_sleep(os_calc_msec_to_ticks(ms));
}
void os_work_later(os_time_t ms)
{
k_work_later(os_calc_msec_to_ticks(ms));
}
void os_work_later_until(os_time_t ms)
{
k_work_later_until(os_calc_msec_to_ticks(ms));
}
#include "os/os.h"
#include "os_util.h"
#include "k_kit.h"
#include "os/os_semaphore.h"
#include "queue.h"
#include <stdarg.h>
static void *_os_wait_memory(void *(*fn)(void *func_handle, va_list arp), void *func_handle, os_sem_t *sem, os_time_t wait_ms, ...);
static void *_os_ipc_fifo_take(void *fifo_handle, va_list arp);
static void *_os_ipc_queue_recv(void *queue_handle, va_list arp);
static void *_os_ipc_queue_send(void *queue_handle, va_list arp);
static void *_os_ipc_queue_alloc(void *queue_handle, va_list arp);
static void *_os_ipc_queue_take(void *queue_handle, va_list arp);
struct os_fifo_q_handle
{
k_fifo_t handle;
os_sem_t sem_take;
};
os_state os_fifo_q_create(os_fifo_t *fifo_handle)
{
os_state ret;
do
{
struct os_fifo_q_handle *fifo = os_malloc(sizeof(*fifo));
if (fifo == NULL)
{
fifo_handle->handle = NULL;
ret = OS_E_NOMEM;
break;
}
memset(fifo, 0, sizeof(*fifo));
if (k_fifo_q_create(&fifo->handle) != 0)
{
os_free(fifo);
ret = OS_E_NOMEM;
break;
}
os_sem_create(&fifo->sem_take, 0, 1);
fifo_handle->handle = fifo;
ret = OS_OK;
} while (0);
return ret;
}
os_state os_fifo_q_delete(os_fifo_t *fifo_handle)
{
OS_ASS_HDL(os_fifo_q_is_valid(fifo_handle), fifo_handle->handle);
struct os_fifo_q_handle *fifo = fifo_handle->handle;
os_scheduler_suspend();
os_sem_delete(&fifo->sem_take);
k_fifo_q_delete(&fifo->handle);
os_free(fifo);
fifo_handle->handle = NULL;
os_scheduler_resume();
return OS_OK;
}
os_state os_fifo_q_clr(os_fifo_t *fifo_handle)
{
OS_ASS_HDL(os_fifo_q_is_valid(fifo_handle), fifo_handle->handle);
struct os_fifo_q_handle *fifo = fifo_handle->handle;
k_fifo_q_clr(&fifo->handle);
return OS_OK;
}
static void *_os_wait_memory(void *(*fn)(void *func_handle, va_list arp), void *func_handle, os_sem_t *sem, os_time_t wait_ms, ...)
{
va_list arp;
va_start(arp, wait_ms);
void *ret = fn(func_handle, arp);
va_end(arp);
if (ret == NULL && os_scheduler_is_running() != false && !os_is_isr_context())
{
TickType_t wait_ticks = os_calc_msec_to_ticks(wait_ms);
int wakeup_tick = os_get_sys_ticks() + wait_ticks;
if (wait_ms)
{
while (wait_ticks == portMAX_DELAY || (int)(wakeup_tick - os_get_sys_ticks()) > 0)
{
os_sem_take(sem, wait_ms);
va_start(arp, wait_ms);
ret = fn(func_handle, arp);
va_end(arp);
if (ret)
{
os_sem_release(sem);
break;
}
wait_ms = wakeup_tick - os_get_sys_ticks();
}
}
if (ret == NULL)
{
OS_DBG("waiting semaphore %p timeout", sem);
}
}
return ret;
}
void os_fifo_q_regist(os_fifo_t *fifo_handle, os_work_t *work_handle, int delay_ticks)
{
struct os_fifo_q_handle *fifo = fifo_handle->handle;
k_fifo_q_regist(&fifo->handle, (k_work_t *)work_handle, delay_ticks);
}
void os_fifo_q_unregist(os_fifo_t *fifo_handle)
{
struct os_fifo_q_handle *fifo = fifo_handle->handle;
k_fifo_q_unregist(&fifo->handle);
}
void *os_fifo_alloc(size_t size)
{
OS_ASS_ISR();
return k_fifo_alloc(size);
}
os_state os_fifo_free(void *fifo_data)
{
os_state ret;
if (k_fifo_free(fifo_data) == 0)
{
ret = OS_OK;
}
else
{
ret = OS_E_PARAM;
}
return ret;
}
os_state os_fifo_put(os_fifo_t *fifo_handle, void *fifo_data)
{
OS_ASS_HDL(os_fifo_q_is_valid(fifo_handle), fifo_handle->handle);
struct os_fifo_q_handle *fifo = fifo_handle->handle;
os_state ret;
if (k_fifo_put(&fifo->handle, fifo_data) == 0)
{
os_sem_release(&fifo->sem_take);
ret = OS_OK;
}
else
{
ret = OS_E_PARAM;
}
return ret;
}
static void *_os_ipc_fifo_take(void *fifo_handle, va_list arp)
{
return k_fifo_take(fifo_handle);
}
void *os_fifo_take(os_fifo_t *fifo_handle, os_time_t wait_ms)
{
OS_ASS_HDL(os_fifo_q_is_valid(fifo_handle), fifo_handle->handle);
struct os_fifo_q_handle *fifo = fifo_handle->handle;
void *ret = _os_wait_memory(_os_ipc_fifo_take, &fifo->handle, &fifo->sem_take, wait_ms);
return ret;
}
void *os_fifo_peek_head(os_fifo_t *fifo_handle)
{
OS_ASS_HDL(os_fifo_q_is_valid(fifo_handle), fifo_handle->handle);
struct os_fifo_q_handle *fifo = fifo_handle->handle;
void *ret = k_fifo_peek_head(&fifo->handle);
return ret;
}
void *os_fifo_peek_tail(os_fifo_t *fifo_handle)
{
OS_ASS_HDL(os_fifo_q_is_valid(fifo_handle), fifo_handle->handle);
struct os_fifo_q_handle *fifo = fifo_handle->handle;
void *ret = k_fifo_peek_tail(&fifo->handle);
return ret;
}
bool os_fifo_q_is_valid(os_fifo_t *fifo_handle)
{
if (fifo_handle && fifo_handle->handle)
{
return true;
}
else
{
return false;
}
}
struct os_queue_handle
{
k_queue_t handle;
os_sem_t sem_send;
os_sem_t sem_recv;
};
os_state os_queue_create(os_queue_t *queue_handle, size_t queue_length, size_t item_size)
{
os_state ret;
do
{
struct os_queue_handle *queue = os_malloc(sizeof(*queue));
if (queue == NULL)
{
queue_handle->handle = NULL;
ret = OS_E_NOMEM;
break;
}
memset(queue, 0, sizeof(*queue));
if (k_queue_create(&queue->handle, queue_length, item_size) != 0)
{
os_free(queue);
ret = OS_E_NOMEM;
break;
}
os_sem_create(&queue->sem_recv, 0, 1);
os_sem_create(&queue->sem_send, 0, 1);
queue_handle->handle = queue;
ret = OS_OK;
} while (0);
return ret;
}
os_state os_queue_delete(os_queue_t *queue_handle)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
os_scheduler_suspend();
os_sem_delete(&queue->sem_recv);
os_sem_delete(&queue->sem_send);
k_queue_delete(&queue->handle);
os_free(queue);
queue_handle->handle = NULL;
os_scheduler_resume();
return OS_OK;
}
os_state os_queue_clr(os_queue_t *queue_handle)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
k_queue_clr(&queue->handle);
return OS_OK;
}
void os_queue_regist(os_queue_t *queue_handle, os_work_t *work_handle, int delay_ticks)
{
struct os_queue_handle *queue = queue_handle->handle;
k_queue_regist(&queue->handle, (k_work_t *)work_handle, delay_ticks);
}
void os_queue_unregist(os_queue_t *queue_handle)
{
struct os_queue_handle *queue = queue_handle->handle;
k_queue_unregist(&queue->handle);
}
static void *_os_ipc_queue_recv(void *queue_handle, va_list arp)
{
void *dst = va_arg(arp, void *);
if (k_queue_recv(queue_handle, dst) == 0)
{
return (void *)!NULL;
}
else
{
return NULL;
}
}
os_state os_queue_recv(os_queue_t *queue_handle, void *dst, os_time_t wait_ms)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
os_state ret;
if (_os_wait_memory(_os_ipc_queue_recv, &queue->handle, &queue->sem_recv, wait_ms, dst) == NULL)
{
ret = OS_E_TIMEOUT;
}
else
{
os_sem_release(&queue->sem_send);
ret = OS_OK;
}
return ret;
}
static void *_os_ipc_queue_send(void *queue_handle, va_list arp)
{
const void *src = va_arg(arp, void *);
if (k_queue_send(queue_handle, src) == 0)
{
return (void *)!NULL;
}
else
{
return NULL;
}
}
os_state os_queue_send(os_queue_t *queue_handle, const void *src, os_time_t wait_ms)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
os_state ret;
if (_os_wait_memory(_os_ipc_queue_send, &queue->handle, &queue->sem_send, wait_ms, src) == NULL)
{
ret = OS_E_TIMEOUT;
}
else
{
os_sem_release(&queue->sem_recv);
ret = OS_OK;
}
return ret;
}
static void *_os_ipc_queue_alloc(void *queue_handle, va_list arp)
{
return k_queue_alloc(queue_handle);
}
void *os_queue_alloc(os_queue_t *queue_handle, os_time_t wait_ms)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
void *ret = _os_wait_memory(_os_ipc_queue_alloc, &queue->handle, &queue->sem_send, wait_ms);
return ret;
}
os_state os_queue_free(void *queue_data)
{
os_state ret;
if (k_queue_free(queue_data) == 0)
{
k_queue_t *handle = k_queue_read_handle(queue_data);
struct os_queue_handle *queue = OS_CONTAINER_OF(handle, struct os_queue_handle, handle);
os_sem_release(&queue->sem_send);
ret = OS_OK;
}
else
{
ret = OS_E_PARAM;
}
return ret;
}
os_state os_queue_put(void *queue_data)
{
os_state ret;
if (k_queue_put(queue_data) == 0)
{
k_queue_t *handle = k_queue_read_handle(queue_data);
struct os_queue_handle *queue = OS_CONTAINER_OF(handle, struct os_queue_handle, handle);
os_sem_release(&queue->sem_recv);
ret = OS_OK;
}
else
{
ret = OS_E_PARAM;
}
return ret;
}
static void *_os_ipc_queue_take(void *queue_handle, va_list arp)
{
return k_queue_take(queue_handle);
}
void *os_queue_take(os_queue_t *queue_handle, os_time_t wait_ms)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
void *ret = _os_wait_memory(_os_ipc_queue_take, &queue->handle, &queue->sem_recv, wait_ms);
return ret;
}
void *os_queue_peek_head(os_queue_t *queue_handle)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
void *ret = k_queue_peek_head(&queue->handle);
return ret;
}
void *os_queue_peek_tail(os_queue_t *queue_handle)
{
OS_ASS_HDL(os_queue_is_valid(queue_handle), queue_handle->handle);
struct os_queue_handle *queue = queue_handle->handle;
void *ret = k_queue_peek_tail(&queue->handle);
return ret;
}
size_t os_queue_get_item_size(os_queue_t *queue_handle)
{
struct os_queue_handle *queue = queue_handle->handle;
size_t ret = k_queue_get_item_size(&queue->handle);
return ret;
}
bool os_queue_is_valid(os_queue_t *queue_handle)
{
if (queue_handle && queue_handle->handle)
{
return true;
}
else
{
return false;
}
}
struct os_pipe_handle
{
k_pipe_t handle;
};
os_state os_pipe_create(os_pipe_t *pipe_handle, size_t pipe_size)
{
os_state ret;
do
{
struct os_pipe_handle *pipe = os_malloc(sizeof(*pipe));
if (pipe == NULL)
{
pipe_handle->handle = NULL;
ret = OS_E_NOMEM;
}
memset(pipe, 0, sizeof(*pipe));
if (k_pipe_create(&pipe->handle, pipe_size) != 0)
{
os_free(pipe);
ret = OS_E_NOMEM;
}
pipe_handle->handle = pipe;
ret = OS_OK;
} while (0);
return ret;
}
os_state os_pipe_delete(os_pipe_t *pipe_handle)
{
OS_ASS_HDL(os_pipe_is_valid(pipe_handle), pipe_handle->handle);
struct os_pipe_handle *pipe = pipe_handle->handle;
k_pipe_delete(&pipe->handle);
os_free(pipe);
pipe_handle->handle = NULL;
return OS_OK;
}
os_state os_pipe_clr(os_pipe_t *pipe_handle)
{
OS_ASS_HDL(os_pipe_is_valid(pipe_handle), pipe_handle->handle);
struct os_pipe_handle *pipe = pipe_handle->handle;
k_pipe_clr(&pipe->handle);
return OS_OK;
}
void os_pipe_regist(os_pipe_t *pipe_handle, os_work_t *work_handle, int delay_ticks)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
k_pipe_regist(&pipe->handle, (k_work_t *)work_handle, delay_ticks);
}
void os_pipe_unregist(os_pipe_t *pipe_handle)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
k_pipe_unregist(&pipe->handle);
}
size_t os_pipe_poll_write(os_pipe_t *pipe_handle, uint8_t data)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
size_t ret = k_pipe_poll_write(&pipe->handle, data);
return ret;
}
size_t os_pipe_fifo_fill(os_pipe_t *pipe_handle, const void *data, size_t size)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
size_t ret = k_pipe_fifo_fill(&pipe->handle, data, size);
return ret;
}
size_t os_pipe_poll_read(os_pipe_t *pipe_handle, uint8_t *data)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
size_t ret = k_pipe_poll_read(&pipe->handle, data);
return ret;
}
size_t os_pipe_fifo_read(os_pipe_t *pipe_handle, void *data, size_t size)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
size_t ret = k_pipe_fifo_read(&pipe->handle, data, size);
return ret;
}
bool os_pipe_is_ne(os_pipe_t *pipe_handle)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
bool ret = k_pipe_is_ne(&pipe->handle);
return ret;
}
size_t os_pipe_get_valid_size(os_pipe_t *pipe_handle)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
size_t ret = k_pipe_get_valid_size(&pipe->handle);
return ret;
}
size_t os_pipe_get_empty_size(os_pipe_t *pipe_handle)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
size_t ret = k_pipe_get_empty_size(&pipe->handle);
return ret;
}
void os_pipe_peek_valid(os_pipe_t *pipe_handle, void **dst_base, size_t *dst_size)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
k_pipe_peek_valid(&pipe->handle, dst_base, dst_size);
}
void os_pipe_peek_empty(os_pipe_t *pipe_handle, void **dst_base, size_t *dst_size)
{
struct os_pipe_handle *pipe = pipe_handle->handle;
k_pipe_peek_empty(&pipe->handle, dst_base, dst_size);
}
bool os_pipe_is_valid(os_pipe_t *pipe_handle)
{
if (pipe_handle && pipe_handle->handle)
{
return true;
}
else
{
return false;
}
}