优化代码,修改 FALLTHROUGH 宏定义,增加递归互斥锁支持,改进调度器挂起和恢复逻辑,增强命令查找功能

This commit is contained in:
LokLiang
2025-05-20 09:00:06 +08:00
parent 66f799bd1c
commit 499994b239
6 changed files with 104 additions and 63 deletions

View File

@@ -65,7 +65,7 @@ extern "C"
#endif #endif
#ifndef FALLTHROUGH #ifndef FALLTHROUGH
#define FALLTHROUGH #define FALLTHROUGH do {} while (0)
#endif #endif
#ifndef __nop #ifndef __nop

View File

@@ -267,14 +267,14 @@ typedef struct
__dlist_t event_list; __dlist_t event_list;
__slist_t ready_list[8]; __slist_t ready_list[8];
__slist_t delayed_list; __slist_t delayed_list;
unsigned priority_tab; size_t priority_tab;
k_work_t *curr_work; k_work_t *curr_work;
k_work_handle_t *yield_work; k_work_handle_t *yield_work;
k_work_q_fn work_q_resume; k_work_q_fn work_q_resume;
void *work_q_resume_arg; void *work_q_resume_arg;
k_work_fn hook_entry; k_work_fn hook_entry;
k_tick_t timeout_early; k_tick_t timeout_early;
volatile unsigned resume_flag; volatile size_t resume_flag;
} k_work_q_handle_t; } k_work_q_handle_t;
typedef struct typedef struct
@@ -298,7 +298,7 @@ typedef struct
union union
{ {
__slist_node_t state_node; __slist_node_t state_node;
unsigned free_flag; size_t free_flag;
} ctrl; } ctrl;
} k_fifo_handle_t; } k_fifo_handle_t;
@@ -316,7 +316,7 @@ typedef struct
union union
{ {
__slist_node_t state_node; __slist_node_t state_node;
unsigned free_flag; size_t free_flag;
} ctrl; } ctrl;
k_queue_t *queue_handle; k_queue_t *queue_handle;
} k_queue_data_t; } k_queue_data_t;
@@ -334,8 +334,8 @@ typedef struct
static struct static struct
{ {
unsigned interrupt_call; size_t interrupt_call;
unsigned interrupt_nest; size_t interrupt_nest;
k_work_t *curr_hook; k_work_t *curr_hook;
k_work_t *curr_log; k_work_t *curr_log;
@@ -862,8 +862,8 @@ static void _k_work_delete(k_work_t *work_handle)
#if (CONFIG_K_KIT_LOG_ON) #if (CONFIG_K_KIT_LOG_ON)
{ {
unsigned max_index = sizeof(s_cm_kit.work_log) / sizeof(s_cm_kit.work_log[0]); size_t max_index = sizeof(s_cm_kit.work_log) / sizeof(s_cm_kit.work_log[0]);
unsigned index; size_t index;
if (max_index > s_cm_kit.log_index) if (max_index > s_cm_kit.log_index)
{ {
@@ -874,7 +874,7 @@ static void _k_work_delete(k_work_t *work_handle)
{ {
if (s_cm_kit.work_log[index] == work_handle) if (s_cm_kit.work_log[index] == work_handle)
{ {
unsigned i; size_t i;
for (i = index; i + 1 < max_index; i++) for (i = index; i + 1 < max_index; i++)
{ {
s_cm_kit.work_log[i] = s_cm_kit.work_log[i + 1]; s_cm_kit.work_log[i] = s_cm_kit.work_log[i + 1];
@@ -1136,7 +1136,7 @@ static void _k_work_log(void *arg)
k_work_q_t *work_q_handle; k_work_q_t *work_q_handle;
k_work_t *work_handle; k_work_t *work_handle;
unsigned max_index; size_t max_index;
_K_DIS_SCHED(); _K_DIS_SCHED();
@@ -1262,30 +1262,19 @@ static void _k_work_do_submit(k_work_q_t *work_q_handle, k_work_t *work_handle,
* *
* @param resume_work 已注册的任务 * @param resume_work 已注册的任务
* @param resume_delay 唤醒延时 * @param resume_delay 唤醒延时
* @param resume_mode 预留的。 resume_delay 为非 0 时有效:
* 0 - 计时从首次收到信号后开始; * 0 - 计时从首次收到信号后开始;
* 1 - 计时从最后一次收到信号后开始; * 1 - 计时从最后一次收到信号后开始;
*/ */
static void _k_ipc_resume(k_work_t *resume_work, k_tick_t resume_delay, int resume_mode) static void _k_ipc_resume(k_work_t *resume_work, k_tick_t resume_delay)
{ {
if (resume_work != NULL) if (resume_work != NULL)
{ {
k_work_handle_t *work = resume_work->hdl; k_work_handle_t *work = resume_work->hdl;
if (work != NULL && work->work_q_handle != NULL) if (work != NULL && work->work_q_handle != NULL)
{ {
if (resume_delay == 0) if (k_work_time_remain(resume_work) < resume_delay)
{ {
if (!k_work_is_pending(resume_work)) k_work_submit(work->work_q_handle, resume_work, resume_delay);
{
_k_work_do_submit(work->work_q_handle, resume_work, _K_PORT->get_sys_ticks(), _FALSE);
}
}
else
{
if (resume_mode != 0 || !k_work_is_pending(resume_work))
{
k_work_submit(work->work_q_handle, resume_work, resume_delay);
}
} }
} }
} }
@@ -1521,7 +1510,7 @@ k_err_t k_work_q_create(k_work_q_t *work_q_handle)
work_q = _K_PORT->malloc(sizeof(k_work_q_handle_t)); work_q = _K_PORT->malloc(sizeof(k_work_q_handle_t));
if (work_q != NULL) if (work_q != NULL)
{ {
unsigned i; size_t i;
memset(work_q, 0, sizeof(*work_q)); memset(work_q, 0, sizeof(*work_q));
work_q_handle->hdl = work_q; work_q_handle->hdl = work_q;
@@ -1714,6 +1703,28 @@ bool k_work_q_ready_state(k_work_q_t *work_q_handle)
} }
} }
k_err_t k_work_create_default(k_work_t *work_handle,
const char *name,
k_work_fn work_route,
void *arg,
uint8_t priority,
k_tick_t delay_ticks)
{
if (!k_work_is_valid(work_handle))
{
k_err_t ret = k_work_create(work_handle, name, work_route, arg, priority);
if (ret == 0)
{
k_work_submit(default_work_q_hdl, work_handle, delay_ticks);
}
return ret;
}
else
{
return 0;
}
}
/** /**
* @brief 创建由工作队列管理的任务 * @brief 创建由工作队列管理的任务
* 任务对象数据由堆内存自动分配 * 任务对象数据由堆内存自动分配
@@ -1868,6 +1879,8 @@ bool k_work_is_pending(k_work_t *work_handle)
*/ */
k_tick_t k_work_time_remain(k_work_t *work_handle) k_tick_t k_work_time_remain(k_work_t *work_handle)
{ {
_TEST_HANDLE(work_handle, return -1);
k_work_handle_t *work = work_handle->hdl; k_work_handle_t *work = work_handle->hdl;
k_tick_t ret = 0; k_tick_t ret = 0;
@@ -1900,7 +1913,7 @@ void k_work_submit(k_work_q_t *work_q_handle, k_work_t *work_handle, k_tick_t de
} }
else else
{ {
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks)) if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks))
{ {
delay_ticks = _SIGNED_MAX(delay_ticks); delay_ticks = _SIGNED_MAX(delay_ticks);
} }
@@ -1916,19 +1929,15 @@ void k_work_submit(k_work_q_t *work_q_handle, k_work_t *work_handle, k_tick_t de
*/ */
void k_work_resume(k_work_t *work_handle, k_tick_t delay_ticks) void k_work_resume(k_work_t *work_handle, k_tick_t delay_ticks)
{ {
_TEST_HANDLE(work_handle, return);
k_work_handle_t *work = work_handle->hdl; k_work_handle_t *work = work_handle->hdl;
if (work->work_q_handle == NULL)
if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks))
{ {
_DBG_WRN("you must using k_work_submit() to define one work_queue first"); delay_ticks = _SIGNED_MAX(delay_ticks);
}
else
{
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks))
{
delay_ticks = _SIGNED_MAX(delay_ticks);
}
k_work_submit(work->work_q_handle, work_handle, delay_ticks);
} }
k_work_submit(work->work_q_handle, work_handle, delay_ticks);
} }
/** /**
@@ -1941,7 +1950,7 @@ void k_work_later(k_tick_t delay_ticks)
k_work_q_t *work_q_handle; k_work_q_t *work_q_handle;
k_work_t *work_handle; k_work_t *work_handle;
_k_read_curr_handle(&work_q_handle, &work_handle); _k_read_curr_handle(&work_q_handle, &work_handle);
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks)) if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks))
{ {
delay_ticks = _SIGNED_MAX(delay_ticks); delay_ticks = _SIGNED_MAX(delay_ticks);
} }
@@ -1996,7 +2005,7 @@ void k_work_later_until(k_tick_t delay_ticks)
_k_read_curr_handle(&work_q_handle, &work_handle); _k_read_curr_handle(&work_q_handle, &work_handle);
work = work_handle->hdl; work = work_handle->hdl;
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks)) if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks))
{ {
delay_ticks = _SIGNED_MAX(delay_ticks); delay_ticks = _SIGNED_MAX(delay_ticks);
} }
@@ -2048,7 +2057,7 @@ void k_work_sleep(k_tick_t delay_ticks)
_ASSERT_FALSE(s_kit_init_struct.malloc == NULL, "Never use 'k_init()' to initialize"); _ASSERT_FALSE(s_kit_init_struct.malloc == NULL, "Never use 'k_init()' to initialize");
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks)) if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks))
{ {
delay_ticks = _SIGNED_MAX(delay_ticks); delay_ticks = _SIGNED_MAX(delay_ticks);
} }
@@ -2753,7 +2762,7 @@ void k_timer_set_period(k_timer_t *timer_handle, bool periodic, k_tick_t period)
k_work_handle_t *work = timer_handle->hdl; k_work_handle_t *work = timer_handle->hdl;
if (work) if (work)
{ {
if ((unsigned)period > _SIGNED_MAX(period)) if ((size_t)period > _SIGNED_MAX(period))
{ {
period = _SIGNED_MAX(period); period = _SIGNED_MAX(period);
} }
@@ -2946,7 +2955,7 @@ void k_timer_cancel(k_timer_q_t *timer_q_handle, k_timer_fn timer_route)
do do
{ {
unsigned i; size_t i;
for (i = 0; i < sizeof(work_q->ready_list) / sizeof(work_q->ready_list[0]); i++) for (i = 0; i < sizeof(work_q->ready_list) / sizeof(work_q->ready_list[0]); i++)
{ {
__slist_t *test_list = &work_q->ready_list[i]; __slist_t *test_list = &work_q->ready_list[i];
@@ -3323,7 +3332,7 @@ k_err_t k_fifo_put(k_fifo_t *fifo_handle, void *data)
if (resume_flag) if (resume_flag)
{ {
_k_ipc_resume(fifo_q->resume_work, fifo_q->resume_delay, 0); _k_ipc_resume(fifo_q->resume_work, fifo_q->resume_delay);
} }
return 0; return 0;
@@ -3745,7 +3754,7 @@ k_err_t k_queue_put(void *data)
if (resume_flag) if (resume_flag)
{ {
_k_ipc_resume(queue->resume_work, queue->resume_delay, 0); _k_ipc_resume(queue->resume_work, queue->resume_delay);
} }
return 0; return 0;
@@ -4026,7 +4035,7 @@ size_t k_pipe_poll_write(k_pipe_t *pipe_handle, uint8_t data)
if (resume_flag) if (resume_flag)
{ {
_k_ipc_resume(pipe->resume_work, pipe->resume_delay, 0); _k_ipc_resume(pipe->resume_work, pipe->resume_delay);
} }
return 1; return 1;
@@ -4096,7 +4105,7 @@ size_t k_pipe_fifo_fill(k_pipe_t *pipe_handle, const void *data, size_t size)
if (resume_flag && ret) if (resume_flag && ret)
{ {
_k_ipc_resume(pipe->resume_work, pipe->resume_delay, 0); _k_ipc_resume(pipe->resume_work, pipe->resume_delay);
} }
return ret; return ret;
@@ -4366,7 +4375,7 @@ void k_log_sched(void)
#if (CONFIG_K_KIT_LOG_ON) #if (CONFIG_K_KIT_LOG_ON)
#define _WORK_NAME(WORK) ((k_work_handle_t *)WORK->hdl)->name #define _WORK_NAME(WORK) ((k_work_handle_t *)WORK->hdl)->name
k_work_t *work = s_cm_kit.curr_hook; k_work_t *work = s_cm_kit.curr_hook;
unsigned flag; size_t flag;
if (s_cm_kit.curr_log == work) if (s_cm_kit.curr_log == work)
{ {
@@ -4383,9 +4392,9 @@ void k_log_sched(void)
do do
{ {
unsigned index; size_t index;
const char *arg; const char *arg;
unsigned max_index; size_t max_index;
flag = 0; flag = 0;
@@ -4421,7 +4430,7 @@ void k_log_sched(void)
} }
else else
{ {
unsigned i; size_t i;
CONFIG_K_KIT_PRINT(" ==> '" _COLOR_C "%s" _COLOR_END "'", arg); CONFIG_K_KIT_PRINT(" ==> '" _COLOR_C "%s" _COLOR_END "'", arg);

View File

@@ -86,6 +86,12 @@ void k_work_hook(k_work_q_t *work_q_handle, k_work_fn hook); // 设置切换任
bool k_work_q_delayed_state(k_work_q_t *work_q_handle); // 获取是否有正在延时状态的任务 bool k_work_q_delayed_state(k_work_q_t *work_q_handle); // 获取是否有正在延时状态的任务
bool k_work_q_ready_state(k_work_q_t *work_q_handle); // 获取工作队列中是否有就绪的任务 bool k_work_q_ready_state(k_work_q_t *work_q_handle); // 获取工作队列中是否有就绪的任务
k_err_t k_work_create_default(k_work_t *work_handle,
const char *name,
k_work_fn work_route,
void *arg,
uint8_t priority,
k_tick_t delay_ticks);
k_err_t k_work_create(k_work_t *work_handle, k_err_t k_work_create(k_work_t *work_handle,
const char *name, const char *name,
k_work_fn work_route, k_work_fn work_route,

View File

@@ -126,6 +126,18 @@ static const char *_skipwhite(const char *q);
static double _strtod(const char *str, char **end); // https://gitee.com/mirrors_mattn/strtod/blob/master/strtod.c static double _strtod(const char *str, char **end); // https://gitee.com/mirrors_mattn/strtod/blob/master/strtod.c
#endif #endif
/**
* @brief 在所有命令列表中,查找注册的命令。
* 函数会根据 save_depth 参数,保存当前命令的索引值,
* 当下次调用时,函数会从上次保存的位置开始查找。
*
* @param sh_hdl 由 sh_init_vt100() 初始化的对象
* @param new_list 允许临时插入的命令列表,这个列表在最后查找
* @param save_depth 记录查找索引值 uint16_t save_depth[_MAX_SAVE_DEPTH] = {0};
* @param argc 命令数量
* @param argv 命令字符串指针
* @return sh_cmd_info_t
*/
static sh_cmd_info_t _find_registered_command(sh_t *sh_hdl, static sh_cmd_info_t _find_registered_command(sh_t *sh_hdl,
sys_pslist_t *new_list, sys_pslist_t *new_list,
uint16_t save_depth[_MAX_SAVE_DEPTH], uint16_t save_depth[_MAX_SAVE_DEPTH],
@@ -3297,6 +3309,7 @@ SH_CMD_FN(_cmd_print_which)
return 0; return 0;
} }
uint16_t last_depth[_MAX_SAVE_DEPTH] = {0};
for (int i = 0; true; i++) for (int i = 0; true; i++)
{ {
sh_cmd_info_t cp_info = _find_registered_command(sh_hdl, NULL, cp_param.save_depth, argc, argv); sh_cmd_info_t cp_info = _find_registered_command(sh_hdl, NULL, cp_param.save_depth, argc, argv);
@@ -3332,6 +3345,7 @@ SH_CMD_FN(_cmd_print_which)
uint16_t save_depth[_MAX_SAVE_DEPTH] = {0}; uint16_t save_depth[_MAX_SAVE_DEPTH] = {0};
for (int i = 1; i <= cp_info.cmd_count; i++) for (int i = 1; i <= cp_info.cmd_count; i++)
{ {
memcpy(save_depth, last_depth, sizeof(save_depth));
sh_cmd_info_t tmp = _find_registered_command(sh_hdl, NULL, save_depth, i, argv); sh_cmd_info_t tmp = _find_registered_command(sh_hdl, NULL, save_depth, i, argv);
if (i == 1) if (i == 1)
@@ -3348,7 +3362,14 @@ SH_CMD_FN(_cmd_print_which)
{ {
sh_echo(sh_hdl, " "); sh_echo(sh_hdl, " ");
} }
sh_echo(sh_hdl, "-- %s\r\n", tmp.match_cmd->help); if (tmp.match_cmd && tmp.match_cmd->help)
{
sh_echo(sh_hdl, "-- %s\r\n", tmp.match_cmd->help);
}
else
{
sh_echo(sh_hdl, "\r\n");
}
if (i == cp_info.cmd_count) if (i == cp_info.cmd_count)
{ {
@@ -3370,6 +3391,8 @@ SH_CMD_FN(_cmd_print_which)
} }
} }
} }
memcpy(last_depth, cp_param.save_depth, sizeof(last_depth));
} }
return 0; return 0;

View File

@@ -6,7 +6,7 @@ os_state os_mutex_create(os_mutex_t *mutex)
{ {
OS_ASS_HDL(!os_mutex_is_valid(mutex), mutex->handle); OS_ASS_HDL(!os_mutex_is_valid(mutex), mutex->handle);
mutex->handle = xSemaphoreCreateMutex(); mutex->handle = xSemaphoreCreateRecursiveMutex();
if (mutex->handle == NULL) if (mutex->handle == NULL)
{ {
OS_ERR("err %p\r\n", mutex->handle); OS_ERR("err %p\r\n", mutex->handle);
@@ -31,7 +31,7 @@ os_state os_mutex_lock(os_mutex_t *mutex, os_time_t wait_ms)
OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle); OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle);
ret = xSemaphoreTake(mutex->handle, os_calc_msec_to_ticks(wait_ms)); ret = xSemaphoreTakeRecursive(mutex->handle, os_calc_msec_to_ticks(wait_ms));
if (ret != pdPASS) if (ret != pdPASS)
{ {
OS_DBG("%s() fail @ %d, %u ms\n", __func__, __LINE__, wait_ms); OS_DBG("%s() fail @ %d, %u ms\n", __func__, __LINE__, wait_ms);
@@ -47,7 +47,7 @@ os_state os_mutex_unlock(os_mutex_t *mutex)
OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle); OS_ASS_HDL(os_mutex_is_valid(mutex), mutex->handle);
ret = xSemaphoreGive(mutex->handle); ret = xSemaphoreGiveRecursive(mutex->handle);
if (ret != pdPASS) if (ret != pdPASS)
{ {
OS_DBG("%s() fail @ %d\n", __func__, __LINE__); OS_DBG("%s() fail @ %d\n", __func__, __LINE__);

View File

@@ -27,14 +27,7 @@ void os_int_exit(void)
bool os_is_isr_context(void) bool os_is_isr_context(void)
{ {
if (int_flag) return xPortInIsrContext() || (int_flag > 0);
{
return true;
}
else
{
return false;
}
} }
void os_interrupt_disable(void) void os_interrupt_disable(void)
@@ -49,12 +42,22 @@ void os_interrupt_enable(void)
void os_scheduler_suspend(void) void os_scheduler_suspend(void)
{ {
// 在进入临界区前检查是否在中断上下文中
if (os_is_isr_context())
{
OS_ERR("Called in isr"); // 在中断中不要挂起调度器,可能会导致死锁
return;
}
vTaskSuspendAll(); vTaskSuspendAll();
} }
void os_scheduler_resume(void) void os_scheduler_resume(void)
{ {
xTaskResumeAll(); // 只有在非中断上下文中才恢复调度器
if (!os_is_isr_context())
{
xTaskResumeAll();
}
} }
bool os_scheduler_is_running(void) bool os_scheduler_is_running(void)