From 499994b2392fb7dcb486b027ef6ee93bb66a8bf1 Mon Sep 17 00:00:00 2001 From: LokLiang Date: Tue, 20 May 2025 09:00:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20FALLTHROUGH=20=E5=AE=8F=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=80=92=E5=BD=92=E4=BA=92=E6=96=A5?= =?UTF-8?q?=E9=94=81=E6=94=AF=E6=8C=81=EF=BC=8C=E6=94=B9=E8=BF=9B=E8=B0=83?= =?UTF-8?q?=E5=BA=A6=E5=99=A8=E6=8C=82=E8=B5=B7=E5=92=8C=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E5=A2=9E=E5=BC=BA=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/system/include/sys_types.h | 2 +- components/system/source/k_kit/k_kit.c | 107 ++++++++++++++----------- components/system/source/k_kit/k_kit.h | 6 ++ components/system/source/shell/sh.c | 25 +++++- sal/esp32/kernel/os_mutex.c | 6 +- sal/esp32/kernel/os_service.c | 21 ++--- 6 files changed, 104 insertions(+), 63 deletions(-) diff --git a/components/system/include/sys_types.h b/components/system/include/sys_types.h index 6830ec9..6a26341 100755 --- a/components/system/include/sys_types.h +++ b/components/system/include/sys_types.h @@ -65,7 +65,7 @@ extern "C" #endif #ifndef FALLTHROUGH -#define FALLTHROUGH +#define FALLTHROUGH do {} while (0) #endif #ifndef __nop diff --git a/components/system/source/k_kit/k_kit.c b/components/system/source/k_kit/k_kit.c index c42e0bf..ff0c955 100755 --- a/components/system/source/k_kit/k_kit.c +++ b/components/system/source/k_kit/k_kit.c @@ -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,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_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_time_remain(resume_work) < resume_delay) { - 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)) - { - k_work_submit(work->work_q_handle, 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) + + if ((size_t)delay_ticks > _SIGNED_MAX(delay_ticks)) { - _DBG_WRN("you must using k_work_submit() to define one work_queue first"); - } - 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); + 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); diff --git a/components/system/source/k_kit/k_kit.h b/components/system/source/k_kit/k_kit.h index 14a590f..f00ae34 100755 --- a/components/system/source/k_kit/k_kit.h +++ b/components/system/source/k_kit/k_kit.h @@ -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, diff --git a/components/system/source/shell/sh.c b/components/system/source/shell/sh.c index 49eec14..ffffecb 100755 --- a/components/system/source/shell/sh.c +++ b/components/system/source/shell/sh.c @@ -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, " "); } - 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) { @@ -3370,6 +3391,8 @@ SH_CMD_FN(_cmd_print_which) } } } + + memcpy(last_depth, cp_param.save_depth, sizeof(last_depth)); } return 0; diff --git a/sal/esp32/kernel/os_mutex.c b/sal/esp32/kernel/os_mutex.c index 7a59b1d..433982a 100755 --- a/sal/esp32/kernel/os_mutex.c +++ b/sal/esp32/kernel/os_mutex.c @@ -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__); diff --git a/sal/esp32/kernel/os_service.c b/sal/esp32/kernel/os_service.c index aa92058..4d8e6cb 100755 --- a/sal/esp32/kernel/os_service.c +++ b/sal/esp32/kernel/os_service.c @@ -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) { - xTaskResumeAll(); + // 只有在非中断上下文中才恢复调度器 + if (!os_is_isr_context()) + { + xTaskResumeAll(); + } } bool os_scheduler_is_running(void)