优化代码,修改 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
#ifndef FALLTHROUGH
#define FALLTHROUGH
#define FALLTHROUGH do {} while (0)
#endif
#ifndef __nop

View File

@@ -267,14 +267,14 @@ typedef struct
__dlist_t event_list;
__slist_t ready_list[8];
__slist_t delayed_list;
unsigned priority_tab;
size_t priority_tab;
k_work_t *curr_work;
k_work_handle_t *yield_work;
k_work_q_fn work_q_resume;
void *work_q_resume_arg;
k_work_fn hook_entry;
k_tick_t timeout_early;
volatile unsigned resume_flag;
volatile size_t resume_flag;
} k_work_q_handle_t;
typedef struct
@@ -298,7 +298,7 @@ typedef struct
union
{
__slist_node_t state_node;
unsigned free_flag;
size_t free_flag;
} ctrl;
} k_fifo_handle_t;
@@ -316,7 +316,7 @@ typedef struct
union
{
__slist_node_t state_node;
unsigned free_flag;
size_t free_flag;
} ctrl;
k_queue_t *queue_handle;
} k_queue_data_t;
@@ -334,8 +334,8 @@ typedef struct
static struct
{
unsigned interrupt_call;
unsigned interrupt_nest;
size_t interrupt_call;
size_t interrupt_nest;
k_work_t *curr_hook;
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)
{
unsigned max_index = sizeof(s_cm_kit.work_log) / sizeof(s_cm_kit.work_log[0]);
unsigned index;
size_t max_index = sizeof(s_cm_kit.work_log) / sizeof(s_cm_kit.work_log[0]);
size_t 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)
{
unsigned i;
size_t i;
for (i = index; i + 1 < max_index; i++)
{
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_t *work_handle;
unsigned max_index;
size_t max_index;
_K_DIS_SCHED();
@@ -1262,33 +1262,22 @@ static void _k_work_do_submit(k_work_q_t *work_q_handle, k_work_t *work_handle,
*
* @param resume_work 已注册的任务
* @param resume_delay 唤醒延时
* @param resume_mode 预留的。 resume_delay 为非 0 时有效:
* 0 - 计时从首次收到信号后开始;
* 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)
{
k_work_handle_t *work = resume_work->hdl;
if (work != NULL && work->work_q_handle != NULL)
{
if (resume_delay == 0)
{
if (!k_work_is_pending(resume_work))
{
_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))
if (k_work_time_remain(resume_work) < resume_delay)
{
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));
if (work_q != NULL)
{
unsigned i;
size_t i;
memset(work_q, 0, sizeof(*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 创建由工作队列管理的任务
* 任务对象数据由堆内存自动分配
@@ -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)
{
_TEST_HANDLE(work_handle, return -1);
k_work_handle_t *work = work_handle->hdl;
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
{
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks))
if ((size_t)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)
{
_TEST_HANDLE(work_handle, return);
k_work_handle_t *work = work_handle->hdl;
if (work->work_q_handle == NULL)
{
_DBG_WRN("you must using k_work_submit() to define one work_queue first");
}
else
{
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks))
if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks))
{
delay_ticks = _SIGNED_MAX(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_t *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);
}
@@ -1996,7 +2005,7 @@ void k_work_later_until(k_tick_t delay_ticks)
_k_read_curr_handle(&work_q_handle, &work_handle);
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);
}
@@ -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");
if ((unsigned)delay_ticks > _SIGNED_MAX(delay_ticks))
if ((size_t)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;
if (work)
{
if ((unsigned)period > _SIGNED_MAX(period))
if ((size_t)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
{
unsigned i;
size_t 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];
@@ -3323,7 +3332,7 @@ k_err_t k_fifo_put(k_fifo_t *fifo_handle, void *data)
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;
@@ -3745,7 +3754,7 @@ k_err_t k_queue_put(void *data)
if (resume_flag)
{
_k_ipc_resume(queue->resume_work, queue->resume_delay, 0);
_k_ipc_resume(queue->resume_work, queue->resume_delay);
}
return 0;
@@ -4026,7 +4035,7 @@ size_t k_pipe_poll_write(k_pipe_t *pipe_handle, uint8_t data)
if (resume_flag)
{
_k_ipc_resume(pipe->resume_work, pipe->resume_delay, 0);
_k_ipc_resume(pipe->resume_work, pipe->resume_delay);
}
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)
{
_k_ipc_resume(pipe->resume_work, pipe->resume_delay, 0);
_k_ipc_resume(pipe->resume_work, pipe->resume_delay);
}
return ret;
@@ -4366,7 +4375,7 @@ void k_log_sched(void)
#if (CONFIG_K_KIT_LOG_ON)
#define _WORK_NAME(WORK) ((k_work_handle_t *)WORK->hdl)->name
k_work_t *work = s_cm_kit.curr_hook;
unsigned flag;
size_t flag;
if (s_cm_kit.curr_log == work)
{
@@ -4383,9 +4392,9 @@ void k_log_sched(void)
do
{
unsigned index;
size_t index;
const char *arg;
unsigned max_index;
size_t max_index;
flag = 0;
@@ -4421,7 +4430,7 @@ void k_log_sched(void)
}
else
{
unsigned i;
size_t i;
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_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,
const char *name,
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
#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,
sys_pslist_t *new_list,
uint16_t save_depth[_MAX_SAVE_DEPTH],
@@ -3297,6 +3309,7 @@ SH_CMD_FN(_cmd_print_which)
return 0;
}
uint16_t last_depth[_MAX_SAVE_DEPTH] = {0};
for (int i = 0; true; i++)
{
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};
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);
if (i == 1)
@@ -3348,7 +3362,14 @@ SH_CMD_FN(_cmd_print_which)
{
sh_echo(sh_hdl, " ");
}
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)
{
@@ -3370,6 +3391,8 @@ SH_CMD_FN(_cmd_print_which)
}
}
}
memcpy(last_depth, cp_param.save_depth, sizeof(last_depth));
}
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);
mutex->handle = xSemaphoreCreateMutex();
mutex->handle = xSemaphoreCreateRecursiveMutex();
if (mutex->handle == NULL)
{
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);
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)
{
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);
ret = xSemaphoreGive(mutex->handle);
ret = xSemaphoreGiveRecursive(mutex->handle);
if (ret != pdPASS)
{
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)
{
if (int_flag)
{
return true;
}
else
{
return false;
}
return xPortInIsrContext() || (int_flag > 0);
}
void os_interrupt_disable(void)
@@ -49,12 +42,22 @@ void os_interrupt_enable(void)
void os_scheduler_suspend(void)
{
// 在进入临界区前检查是否在中断上下文中
if (os_is_isr_context())
{
OS_ERR("Called in isr"); // 在中断中不要挂起调度器,可能会导致死锁
return;
}
vTaskSuspendAll();
}
void os_scheduler_resume(void)
{
// 只有在非中断上下文中才恢复调度器
if (!os_is_isr_context())
{
xTaskResumeAll();
}
}
bool os_scheduler_is_running(void)