参考代码

This commit is contained in:
LokLiang
2024-03-28 12:19:52 +08:00
commit 7b86aa3362
96 changed files with 19986 additions and 0 deletions

131
sal/esp32s3/chip/uart_esp32.c Executable file
View File

@@ -0,0 +1,131 @@
#include "drivers/chip/uart.h"
#include "driver/uart.h"
#define SYS_LOG_DOMAIN "uart"
#include "sys_log.h"
void drv_uart_pin_configure_txd(hal_id_t id, uint8_t pin)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_pin_configure_rxd(hal_id_t id, uint8_t pin)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_enable(hal_id_t id)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_disable(hal_id_t id)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_init(hal_id_t id, const uart_param_t *param)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_deinit(hal_id_t id)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_set_br(hal_id_t id, unsigned clk, unsigned baudrate)
{
SYS_LOG_ERR("func not set");
}
unsigned drv_uart_get_br(hal_id_t id, unsigned clk)
{
SYS_LOG_ERR("func not set");
return -1;
}
int drv_uart_poll_read(hal_id_t id, void *data)
{
return uart_read_bytes(id, data, 1, 0);
}
int drv_uart_poll_write(hal_id_t id, uint8_t data)
{
SYS_LOG_ERR("func not set");
return 0;
}
int drv_uart_fifo_read(hal_id_t id, void *data, int size)
{
int ret = 0;
for (int i = 0; i < size; i++)
{
if (drv_uart_poll_read(id, &((char *)data)[i]) <= 0)
{
break;
}
++ret;
}
return 0;
}
int drv_uart_fifo_fill(hal_id_t id, const void *data, int size)
{
for (unsigned i = 0; i < size; i++)
{
if (drv_uart_poll_write(id, ((char *)data)[i]) < 0)
{
return -1;
}
}
return size;
}
int drv_uart_irq_callback_enable(hal_id_t id, uart_isr_cb_fn cb)
{
SYS_LOG_ERR("func not set");
return -1;
}
int drv_uart_irq_callback_disable(hal_id_t id)
{
SYS_LOG_ERR("func not set");
return -1;
}
void drv_uart_irq_tx_enable(hal_id_t id, int priority)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_irq_tx_disable(hal_id_t id)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_irq_rx_enable(hal_id_t id, int priority)
{
SYS_LOG_ERR("func not set");
}
void drv_uart_irq_rx_disable(hal_id_t id)
{
SYS_LOG_ERR("func not set");
}
bool drv_uart_wait_tx_busy(hal_id_t id)
{
return false;
}
bool drv_uart_is_tx_ready(hal_id_t id)
{
return true;
}
bool drv_uart_is_rx_ready(hal_id_t id)
{
return true;
}

27
sal/esp32s3/kernel/os_debug.h Executable file
View File

@@ -0,0 +1,27 @@
#ifndef _OS_DEBUG_H_
#define _OS_DEBUG_H_
#undef CONFIG_SYS_LOG_LEVEL
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
#define SYS_LOG_DOMAIN "OS"
#include "sys_log.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define OS_LOG(FLAG, FMT, ...) _DO_SYS_LOG(FLAG, FMT, ##__VA_ARGS__)
#define OS_DBG(FMT, ...) SYS_LOG_DBG(FMT, ##__VA_ARGS__)
#define OS_INF(FMT, ...) SYS_LOG_INF(FMT, ##__VA_ARGS__)
#define OS_WRN(FMT, ...) SYS_LOG_WRN(FMT, ##__VA_ARGS__)
#define OS_ERR(FMT, ...) SYS_LOG_ERR(FMT, ##__VA_ARGS__)
#define OS_ASS_ISR() SYS_ASSERT(!os_is_isr_context(), "function '%s' exec in ISR contex", __FUNCTION__)
#define OS_ASS_HDL(EXP, HANDLE) SYS_ASSERT(EXP, "handle %p", HANDLE)
#ifdef __cplusplus
}
#endif
#endif /* _OS_DEBUG_H_ */

46
sal/esp32s3/kernel/os_heap.c Executable file
View File

@@ -0,0 +1,46 @@
#include "os/os.h"
#include "os_util.h"
#include "portable.h"
#include <string.h>
void *os_malloc(size_t size)
{
return pvPortMalloc(size);
}
void *os_calloc(size_t size)
{
void *ret = os_malloc(size);
if (ret)
{
memset(ret, 0, size);
}
return ret;
}
void *os_realloc(void *p, size_t size)
{
#if (configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1)
return realloc(p, size);
#else
OS_DBG("%s() fail @ %d function not support!\r\n", __func__, __LINE__);
return NULL;
#endif
}
void os_free(void *p)
{
vPortFree(p);
}
void os_heap_info(size_t *used_size, size_t *free_size, size_t *max_block_size)
{
if (max_block_size)
{
*max_block_size = 0;
}
if (used_size)
*used_size = 0;
if (free_size)
*free_size = xPortGetFreeHeapSize();
}

124
sal/esp32s3/kernel/os_hook.c Executable file
View File

@@ -0,0 +1,124 @@
#define SYS_LOG_DOMAIN "OS"
#include "os/os.h"
#include "sys_log.h"
#include "FreeRTOS.h"
#include "task.h"
StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
void vAssertCalled(void);
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName);
void vApplicationMallocFailedHook(void);
void vApplicationIdleHook(void);
void vApplicationTickHook(void);
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize);
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize);
void vAssertCalled(void)
{
volatile unsigned long looping = 0;
os_interrupt_disable();
{
/* Use the debugger to set ul to a non-zero value in order to step out
* of this function to determine why it was called. */
while (looping == 0LU)
{
}
}
os_interrupt_enable();
}
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName)
{
SYS_LOG_ERR("task %p(%s) stack over flow\n", pxTask, pcTaskName);
/* Run time stack overflow checking is performed if
* configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
* function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for (;;)
{
}
}
void vApplicationMallocFailedHook(void)
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
* free memory available in the FreeRTOS heap. pvPortMalloc() is called
* internally by FreeRTOS API functions that create tasks, queues, software
* timers, and semaphores. The size of the FreeRTOS heap is set by the
* configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for (;;)
{
}
}
void vApplicationIdleHook(void)
{
/* This is just a trivial example of an idle hook. It is called on each
* cycle of the idle task. It must *NOT* attempt to block. In this case the
* idle task just queries the amount of FreeRTOS heap that remains. See the
* memory management section on the https://www.FreeRTOS.org web site for memory
* management options. If there is a lot of heap memory free then the
* configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up
* RAM. */
}
void vApplicationTickHook(void)
{
}
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
/* If the buffers to be provided to the Timer task are declared inside this
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
/* Pass out a pointer to the StaticTask_t structure in which the Timer
* task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
* used by the Idle task. */
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
/* If the buffers to be provided to the Idle task are declared inside this
* function then they must be declared static - otherwise they will be allocated on
* the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
* state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
* Note that, as the array is necessarily of type StackType_t,
* configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

886
sal/esp32s3/kernel/os_kit.c Executable file
View File

@@ -0,0 +1,886 @@
#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;
}
}
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;
}
}

80
sal/esp32s3/kernel/os_mutex.c Executable file
View File

@@ -0,0 +1,80 @@
#include "os/os.h"
#include "os_util.h"
#include "semphr.h"
os_state os_mutex_create(os_mutex_t *mutex)
{
OS_ASS_HDL(!os_mutex_is_valid(mutex), mutex->handle);
mutex->handle = xSemaphoreCreateMutex();
if (mutex->handle == NULL)
{
OS_ERR("err %p\r\n", mutex->handle);
return OS_FAIL;
}
return OS_OK;
}
os_state os_mutex_delete(os_mutex_t *mutex)
{
OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle);
vSemaphoreDelete(mutex->handle);
mutex->handle = NULL;
return OS_OK;
}
os_state os_mutex_lock(os_mutex_t *mutex, os_time_t wait_ms)
{
BaseType_t ret;
OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle);
ret = xSemaphoreTake(mutex->handle, os_calc_msec_to_ticks(wait_ms));
if (ret != pdPASS)
{
OS_DBG("%s() fail @ %d, %u ms\n", __func__, __LINE__, wait_ms);
return OS_FAIL;
}
return OS_OK;
}
os_state os_mutex_unlock(os_mutex_t *mutex)
{
BaseType_t ret;
OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle);
ret = xSemaphoreGive(mutex->handle);
if (ret != pdPASS)
{
OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
return OS_FAIL;
}
return OS_OK;
}
os_thread_handle_t os_mutex_get_holder(os_mutex_t *mutex)
{
if (!os_mutex_is_valid(mutex))
{
return OS_INVALID_HANDLE;
}
return (os_thread_handle_t)xSemaphoreGetMutexHolder(mutex->handle);
}
bool os_mutex_is_valid(os_mutex_t *mutex)
{
if (mutex && mutex->handle)
{
return true;
}
else
{
return false;
}
}

105
sal/esp32s3/kernel/os_semaphore.c Executable file
View File

@@ -0,0 +1,105 @@
#include "os/os.h"
#include "os_util.h"
#include "semphr.h"
os_state os_sem_create(os_sem_t *sem, size_t init_value, size_t max_value)
{
OS_ASS_HDL(!os_sem_is_valid(sem), sem->handle);
sem->handle = xSemaphoreCreateCounting(max_value, init_value);
if (sem->handle == NULL)
{
OS_ERR("err %p\r\n", sem->handle);
return OS_FAIL;
}
return OS_OK;
}
os_state os_sem_delete(os_sem_t *sem)
{
OS_ASS_HDL(os_sem_is_valid(sem), sem->handle);
vSemaphoreDelete(sem->handle);
sem->handle = NULL;
return OS_OK;
}
os_state os_sem_take(os_sem_t *sem, os_time_t wait_ms)
{
BaseType_t ret;
BaseType_t taskWoken;
OS_ASS_HDL(os_sem_is_valid(sem), sem->handle);
if (os_is_isr_context())
{
if (wait_ms != 0)
{
OS_ERR("%s() in ISR, wait %u ms\n", __func__, wait_ms);
return OS_E_ISR;
}
taskWoken = pdFALSE;
ret = xSemaphoreTakeFromISR(sem->handle, &taskWoken);
if (ret != pdPASS)
{
OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
return OS_E_TIMEOUT;
}
portYIELD_FROM_ISR(taskWoken);
}
else
{
ret = xSemaphoreTake(sem->handle, os_calc_msec_to_ticks(wait_ms));
if (ret != pdPASS)
{
OS_DBG("%s() fail @ %d, %u ms\n", __func__, __LINE__, wait_ms);
return OS_E_TIMEOUT;
}
}
return OS_OK;
}
os_state os_sem_release(os_sem_t *sem)
{
BaseType_t ret;
BaseType_t taskWoken;
OS_ASS_HDL(os_sem_is_valid(sem), sem->handle);
if (os_is_isr_context())
{
taskWoken = pdFALSE;
ret = xSemaphoreGiveFromISR(sem->handle, &taskWoken);
if (ret != pdPASS)
{
OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
return OS_FAIL;
}
portYIELD_FROM_ISR(taskWoken);
}
else
{
ret = xSemaphoreGive(sem->handle);
if (ret != pdPASS)
{
OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
return OS_FAIL;
}
}
return OS_OK;
}
bool os_sem_is_valid(os_sem_t *sem)
{
if (sem && sem->handle)
{
return true;
}
else
{
return false;
}
}

184
sal/esp32s3/kernel/os_service.c Executable file
View File

@@ -0,0 +1,184 @@
#include "os/os.h"
#include "os_util.h"
#include "task.h"
static size_t int_flag;
static portMUX_TYPE s_os_service = portMUX_INITIALIZER_UNLOCKED;
int os_start(void *heap_mem, size_t heap_size)
{
extern int os_entry(void *heap, size_t size);
return os_entry(heap_mem, heap_size);
}
void os_int_entry(void)
{
os_interrupt_disable();
++int_flag;
os_interrupt_enable();
}
void os_int_exit(void)
{
os_interrupt_disable();
int_flag -= !!int_flag;
os_interrupt_enable();
}
bool os_is_isr_context(void)
{
if (int_flag)
{
return true;
}
else
{
return false;
}
}
void os_interrupt_disable(void)
{
portENTER_CRITICAL(&s_os_service);
}
void os_interrupt_enable(void)
{
portEXIT_CRITICAL(&s_os_service);
}
void os_scheduler_suspend(void)
{
vTaskSuspendAll();
}
void os_scheduler_resume(void)
{
xTaskResumeAll();
}
bool os_scheduler_is_running(void)
{
return (bool)(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING);
}
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
void os_sys_print_info(void)
{
const size_t bytes_per_task = 40; /* see vTaskList description */
char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
if (task_list_buffer == NULL)
{
OS_LOG(1, "failed to allocate buffer for vTaskList output\r\n");
return;
}
fputs("Task Name\tStatus\tPrio\tHWM\tTask#", stdout);
#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
fputs("\tAffinity", stdout);
#endif
fputs("\n", stdout);
vTaskList(task_list_buffer);
fputs(task_list_buffer, stdout);
free(task_list_buffer);
}
#else
void os_sys_print_info(void)
{
OS_LOG(1, "os_sys_print_info() not supported, please set configUSE_TRACE_FACILITY to 1\n");
}
#endif
os_time_t os_get_sys_time(void)
{
os_time_t ticks_count = xTaskGetTickCount();
return OS_TicksToMSecs(ticks_count);
}
size_t os_get_sys_ticks(void)
{
return (size_t)xTaskGetTickCount();
}
os_time_t os_calc_ticks_to_msec(size_t ticks)
{
os_time_t msec;
if (ticks == OS_WAIT_FOREVER)
{
msec = portMAX_DELAY;
}
else if (ticks == 0)
{
msec = 0;
}
else
{
msec = OS_TicksToMSecs(ticks);
if (msec == 0)
{
msec = 1;
}
}
return msec;
}
size_t os_calc_msec_to_ticks(os_time_t msec)
{
size_t tick;
if (msec == OS_WAIT_FOREVER)
{
tick = portMAX_DELAY;
}
else if (msec == 0)
{
tick = 0;
}
else
{
tick = OS_MSecsToTicks(msec);
if (tick == 0)
{
tick = 1;
}
}
return tick;
}
size_t os_cpu_usage(void)
{
return 100;
}
#if (configUSE_POSIX_ERRNO == 1)
extern int FreeRTOS_errno;
int os_get_err(void)
{
return FreeRTOS_errno;
}
void os_set_err(int err)
{
FreeRTOS_errno = err;
}
#elif (configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0)
#define OS_ERRNO_LOCATION_IDX 0
int os_get_err(void)
{
return (int)pvTaskGetThreadLocalStoragePointer(NULL, OS_ERRNO_LOCATION_IDX);
}
void os_set_err(int err)
{
vTaskSetThreadLocalStoragePointer(NULL, OS_ERRNO_LOCATION_IDX, (void *)err);
}
#endif

277
sal/esp32s3/kernel/os_thread.c Executable file
View 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,
1);
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;
}
}

219
sal/esp32s3/kernel/os_timer.c Executable file
View File

@@ -0,0 +1,219 @@
#include "os/os.h"
#include "os_util.h"
#include "timers.h"
/* TODO: what block time should be used ? */
#define OS_TIMER_WAIT_FOREVER portMAX_DELAY
#define OS_TIMER_WAIT_NONE 0
/* Timer private data definition */
typedef struct OS_TimerPriv
{
TimerHandle_t handle; /* Timer handle */
os_timer_cb_fn callback; /* Timer expire callback function */
void *argument; /* Argument of timer expire callback function */
} OS_TimerPriv_t;
static void _os_timer_cb(TimerHandle_t xTimer)
{
OS_TimerPriv_t *priv;
priv = pvTimerGetTimerID(xTimer);
if (priv && priv->callback)
{
priv->callback(priv->argument);
}
else
{
OS_WRN("Invalid timer callback\n");
}
}
os_state os_timer_create(os_timer_t *timer, os_timer_cb_fn cb, void *arg)
{
OS_TimerPriv_t *priv;
OS_ASS_HDL(!os_timer_is_valid(timer), timer->handle);
priv = os_malloc(sizeof(OS_TimerPriv_t));
if (priv == NULL)
{
return OS_E_NOMEM;
}
priv->callback = cb;
priv->argument = arg;
priv->handle = xTimerCreate("",
os_calc_msec_to_ticks(OS_WAIT_FOREVER),
pdFALSE,
priv,
_os_timer_cb);
if (priv->handle == NULL)
{
OS_ERR("err %p\r\n", priv->handle);
os_free(priv);
return OS_FAIL;
}
timer->handle = priv;
return OS_OK;
}
static TimerHandle_t _os_timer_get_handle(os_timer_t *timer)
{
OS_TimerPriv_t *priv = timer->handle;
return priv->handle;
}
os_state os_timer_delete(os_timer_t *timer)
{
TimerHandle_t handle;
int ret;
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
handle = _os_timer_get_handle(timer);
ret = xTimerDelete(handle, OS_TIMER_WAIT_FOREVER);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
OS_TimerPriv_t *priv = timer->handle;
timer->handle = NULL;
os_free(priv);
return OS_OK;
}
os_state os_timer_start(os_timer_t *timer)
{
TimerHandle_t handle;
int ret;
BaseType_t taskWoken;
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
handle = _os_timer_get_handle(timer);
if (os_is_isr_context())
{
taskWoken = pdFALSE;
ret = xTimerStartFromISR(handle, &taskWoken);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
portYIELD_FROM_ISR(taskWoken);
}
else
{
ret = xTimerStart(handle, OS_TIMER_WAIT_NONE);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
}
return OS_OK;
}
os_state os_timer_set_period(os_timer_t *timer, os_timer_type_t type, os_time_t period_ms)
{
TimerHandle_t handle;
TickType_t ticks;
int ret;
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
handle = _os_timer_get_handle(timer);
ticks = os_calc_msec_to_ticks(period_ms);
if (os_is_isr_context())
{
BaseType_t taskWoken = pdFALSE;
ret = xTimerChangePeriodFromISR(handle, ticks, &taskWoken);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
portYIELD_FROM_ISR(taskWoken);
}
else
{
ret = xTimerChangePeriod(handle, ticks, OS_TIMER_WAIT_NONE);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
}
vTimerSetReloadMode(handle, type == OS_TIMER_PERIODIC ? pdTRUE : pdFALSE);
return OS_OK;
}
os_state os_timer_stop(os_timer_t *timer)
{
TimerHandle_t handle;
int ret;
BaseType_t taskWoken;
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
handle = _os_timer_get_handle(timer);
if (os_is_isr_context())
{
taskWoken = pdFALSE;
ret = xTimerStopFromISR(handle, &taskWoken);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
portYIELD_FROM_ISR(taskWoken);
}
else
{
ret = xTimerStop(handle, OS_TIMER_WAIT_FOREVER);
if (ret != pdPASS)
{
OS_ERR("err %d\r\n", ret);
return OS_FAIL;
}
}
return OS_OK;
}
bool os_timer_is_pending(os_timer_t *timer)
{
TimerHandle_t handle;
if (!os_timer_is_valid(timer))
{
return 0;
}
handle = _os_timer_get_handle(timer);
return (xTimerIsTimerActive(handle) != pdFALSE);
}
bool os_timer_is_valid(os_timer_t *timer)
{
if (timer && timer->handle)
{
return true;
}
else
{
return false;
}
}

33
sal/esp32s3/kernel/os_util.h Executable file
View File

@@ -0,0 +1,33 @@
#ifndef __OS_UTIL_H__
#define __OS_UTIL_H__
#include "list/slist.h"
#include "os/os_common.h"
#include "os_debug.h"
#include "k_kit.h"
#include "FreeRTOS.h"
#include "task.h"
#define OS_TICK_RATE configTICK_RATE_HZ
typedef struct os_work_q_list
{
k_work_q_t work_q_handle;
os_sem_t sem_handle;
os_thread_t thread;
} os_work_q_list_t;
struct os_thread_handle
{
slist_node_t node;
TaskHandle_t pxCreatedTask;
os_thread_t *thread;
os_work_q_list_t *work_q_list;
os_thread_entry_t entry;
void *arg;
uint8_t flag_free;
};
#endif /* __OS_UTIL_H__ */

27
sal/esp32s3/soc_shell.c Normal file
View File

@@ -0,0 +1,27 @@
#include "shell/sh.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#define CONFIG_SYS_LOG_DUMP_ON 1
#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_INF
#define SYS_LOG_DOMAIN "SOC"
#include "sys_log.h"
#include "soc_shell_base.c"
#include "soc_shell_nvs.c"
SH_DEF_SUB_CMD(
sub_soc,
SH_SETUP_CMD("base", "Basic information of the system", NULL, sub_soc_base), //
SH_SETUP_CMD("nvs", "Partition for operating nvs", NULL, sub_soc_nvs), //
);
SH_DEF_CMD(
_register_cmd_soc,
SH_SETUP_CMD("soc", "System on chip", NULL, sub_soc), );
void soc_shell_register(void)
{
sh_register_cmd(&_register_cmd_soc);
}

View File

@@ -0,0 +1,141 @@
/**
* @file soc_shell_base.c
* @author LokLiang
* @brief 仅被 soc_shell.c 所包含,完成子命令列表及功能
* @version 0.1
* @date 2023-09-15
*
* @copyright Copyright (c) 2023
*
*/
#ifndef __SOC_SHELL_BASE_C__
#define __SOC_SHELL_BASE_C__
#include "shell/sh.h"
#include "esp_heap_caps.h"
#include "spi_flash_mmap.h"
#include "esp_flash.h"
#include "esp_chip_info.h"
#include "task.h"
/* Unsigned integers. */
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 __PRI64_PREFIX "u"
SH_CMD_FN(_base_free);
SH_CMD_FN(_base_heap);
SH_CMD_FN(_base_version);
SH_CMD_FN(_base_tasks);
SH_CMD_FN(_base_restart);
SH_DEF_SUB_CMD(
sub_soc_base,
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
SH_SETUP_CMD("tasks", "Get information about running tasks", _base_tasks, NULL), //
#endif
SH_SETUP_CMD("free", "Get the current size of free heap memory", _base_free, NULL), //
SH_SETUP_CMD("heap", "Get minimum size of free heap memory that was available during program execution", _base_heap, NULL), //
SH_SETUP_CMD("version", "Get version of chip and SDK", _base_version, NULL), //
SH_SETUP_CMD("restart", "Software reset of the chip", _base_restart, NULL), //
);
SH_CMD_FN(_base_free)
{
sh_echo(sh_hdl, "当前堆内存空闲大小: %d bytes\r\n", esp_get_free_heap_size());
return 0;
}
SH_CMD_FN(_base_heap)
{
sh_echo(sh_hdl, "当前堆内存最少剩余: %d bytes\r\n", heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT));
return 0;
}
SH_CMD_FN(_base_version)
{
const char *model;
esp_chip_info_t info;
uint32_t flash_size;
esp_chip_info(&info);
switch (info.model)
{
case CHIP_ESP32:
model = "ESP32";
break;
case CHIP_ESP32S2:
model = "ESP32-S2";
break;
case CHIP_ESP32S3:
model = "ESP32-S3";
break;
case CHIP_ESP32C3:
model = "ESP32-C3";
break;
case CHIP_ESP32H2:
model = "ESP32-H2";
break;
case CHIP_ESP32C2:
model = "ESP32-C2";
break;
default:
model = "Unknown";
break;
}
if (esp_flash_get_size(NULL, &flash_size) != ESP_OK)
{
sh_echo(sh_hdl, "Get flash size failed");
return 1;
}
sh_echo(sh_hdl, "IDF Version:%s\r\n", esp_get_idf_version());
sh_echo(sh_hdl, "Chip info:\r\n");
sh_echo(sh_hdl, "\tmodel:%s\r\n", model);
sh_echo(sh_hdl, "\tcores:%d\r\n", info.cores);
sh_echo(sh_hdl, "\tfeature:%s%s%s%s%" PRIu32 "%s\r\n",
info.features & CHIP_FEATURE_WIFI_BGN ? "/802.11bgn" : "",
info.features & CHIP_FEATURE_BLE ? "/BLE" : "",
info.features & CHIP_FEATURE_BT ? "/BT" : "",
info.features & CHIP_FEATURE_EMB_FLASH ? "/Embedded-Flash:" : "/External-Flash:",
flash_size / (1024 * 1024), " MB");
sh_echo(sh_hdl, "\trevision number:%d\r\n", info.revision);
return 0;
}
SH_CMD_FN(_base_tasks)
{
#ifdef CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
const size_t bytes_per_task = 40; /* see vTaskList description */
char *task_list_buffer = malloc(uxTaskGetNumberOfTasks() * bytes_per_task);
if (task_list_buffer == NULL)
{
sh_echo(sh_hdl, "failed to allocate buffer for vTaskList output\r\n");
return -1;
}
sh_echo(sh_hdl, "Task Name\tStatus\tPrio\tHWM\tTask#", stdout);
#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
sh_echo(sh_hdl, "\tAffinity", stdout);
#endif
sh_echo(sh_hdl, "\r\n", stdout);
vTaskList(task_list_buffer);
sh_echo(sh_hdl, task_list_buffer, stdout);
sh_echo(sh_hdl, "Task_Name\tRun_Cnt\t\tUsage_Rate\r\n", stdout);
vTaskGetRunTimeStats(task_list_buffer);
sh_echo(sh_hdl, task_list_buffer, stdout);
free(task_list_buffer);
#endif
return 0;
}
SH_CMD_FN(_base_restart)
{
esp_restart();
return 0;
}
#endif

117
sal/esp32s3/soc_shell_nvs.c Normal file
View File

@@ -0,0 +1,117 @@
/**
* @file soc_shell_nvs.c
* @author LokLiang
* @brief 仅被 soc_shell.c 所包含,完成子命令列表及功能
* @version 0.1
* @date 2023-09-15
*
* @copyright Copyright (c) 2023
*
*/
#ifndef __SOC_SHELL_NVS_C__
#define __SOC_SHELL_NVS_C__
#include "shell/sh.h"
#include "shell/sh_vset.h"
#include "nvs_flash.h"
#include "os/os.h"
static char s_nvs_str_buf[0x40];
static int _value_set_str(const char *argv[]) { SET_VAR(&s_nvs_str_buf, 0, 0); }
SH_CMD_FN(_nvs_dump);
SH_CMD_FN(_nvs_erase);
SH_DEF_SUB_CMD(
sub_soc_nvs,
SH_SETUP_CMD("dump", "Dump blob value for given key <namespace> <key>", _nvs_dump, NULL), //
SH_SETUP_CMD("erase", "Erase the default NVS partition", _nvs_erase, NULL), //
);
SH_CMD_FN(_nvs_dump)
{
const char *argv_r[2] = {"", ""};
size_t required_size;
char namespace_buf[sizeof(s_nvs_str_buf)];
char key_buf[sizeof(s_nvs_str_buf)];
int err = 0;
argv_r[0] = argv[0];
err = err ? err : _value_set_str(argv_r);
if (err == 0)
strcpy(namespace_buf, s_nvs_str_buf);
argv_r[0] = argv[1];
err = err ? err : _value_set_str(argv_r);
if (err == 0)
strcpy(key_buf, s_nvs_str_buf);
if (err == 0)
{
nvs_handle nvs_hdl;
if (nvs_open(namespace_buf, NVS_READONLY, &nvs_hdl) == ESP_OK)
{
err = nvs_get_blob(nvs_hdl, key_buf, NULL, &required_size);
if (err == 0)
{
if (required_size)
{
void *data = os_malloc(required_size);
if (data)
{
err = nvs_get_blob(nvs_hdl, key_buf, data, &required_size);
if (err == 0)
{
SYS_LOG_DUMP(data, required_size, 0, 0);
}
else
{
sh_echo(sh_hdl, "Can not get blob key: '%s'\r\n", key_buf);
}
os_free(data);
}
else
{
sh_echo(sh_hdl, "os_malloc() fail\r\n");
}
}
else
{
sh_echo(sh_hdl, "Blob data empty\r\n");
}
}
else
{
sh_echo(sh_hdl, "Can not get blob key: '%s'\r\n", key_buf);
}
nvs_close(nvs_hdl);
}
else
{
sh_echo(sh_hdl, "Can not open name space: '%s'\r\n", namespace_buf);
}
}
return err;
}
SH_CMD_FN(_nvs_erase)
{
sh_echo(sh_hdl, "正在擦除 NVS 分区 ...\r\n");
esp_err_t err = nvs_flash_erase();
if (err == ESP_OK)
{
sh_echo(sh_hdl, "操作成功,重启系统 ...\r\n");
esp_restart();
return 0;
}
else
{
sh_echo(sh_hdl, "操作异常: err = %d\r\n", err);
return -1;
}
}
#endif