From 267e95c8d10f3bdd4b830ec647e81aec6cdd6085 Mon Sep 17 00:00:00 2001 From: zhaohonghao Date: Sat, 25 May 2024 11:42:33 +0800 Subject: [PATCH 1/2] cnc: add task support API for cnc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit description: 针对cnc需求增加task相关接口 Signed-off-by: zhaohonghao --- demos/hi3093/config/prt_config.h | 2 +- src/core/kernel/task/amp/CMakeLists.txt | 2 +- src/core/kernel/task/amp/prt_task_period.c | 158 ++++++++++++++++++++ src/core/kernel/task/smp/CMakeLists.txt | 3 +- src/core/kernel/task/smp/prt_task_period.c | 158 ++++++++++++++++++++ src/include/uapi/prt_task.h | 63 ++++++++ src/libc/litelibc/src/thread/pthread_join.c | 5 + 7 files changed, 388 insertions(+), 3 deletions(-) create mode 100644 src/core/kernel/task/amp/prt_task_period.c create mode 100644 src/core/kernel/task/smp/prt_task_period.c diff --git a/demos/hi3093/config/prt_config.h b/demos/hi3093/config/prt_config.h index 19d4ec95..52ee0163 100644 --- a/demos/hi3093/config/prt_config.h +++ b/demos/hi3093/config/prt_config.h @@ -48,7 +48,7 @@ extern "C" { /* ***************************** 配置定时器模块 ***************************** */ /* 基于TICK的软件定时器裁剪开关 */ -#define OS_INCLUDE_TICK_SWTMER NO +#define OS_INCLUDE_TICK_SWTMER YES /* 基于TICK的软件定时器最大个数 */ #define OS_TICK_SWITIMER_MAX_NUM 32 diff --git a/src/core/kernel/task/amp/CMakeLists.txt b/src/core/kernel/task/amp/CMakeLists.txt index f0413375..9b4649ff 100644 --- a/src/core/kernel/task/amp/CMakeLists.txt +++ b/src/core/kernel/task/amp/CMakeLists.txt @@ -15,5 +15,5 @@ add_library_ex(prt_amp_task_minor.c) if(${CONFIG_OS_OPTION_POWEROFF}) add_library_ex(prt_amp_psci.c) endif() - +add_library_ex(prt_task_period.c) diff --git a/src/core/kernel/task/amp/prt_task_period.c b/src/core/kernel/task/amp/prt_task_period.c new file mode 100644 index 00000000..70b09c53 --- /dev/null +++ b/src/core/kernel/task/amp/prt_task_period.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2024-2024 Huawei Technologies Co., Ltd. All rights reserved. + * + * UniProton is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Create: 2024-05-25 + * Description: Task periodic execution implementation + */ +#include "prt_signal.h" +#include "prt_timer.h" +#include "prt_swtmr_external.h" +#include "signal.h" +#include "prt_task_external.h" + +void OsDelieverSigPeriod(TimerHandle tmrHandle, U32 arg1, U32 arg2, U32 arg3, U32 arg4) +{ + (void)tmrHandle; + (void)arg2; + (void)arg3; + (void)arg4; + signalInfo info = {0}; + info.si_signo = SIGALRM; + info.si_code = SI_USER; + uintptr_t intSave = OsIntLock(); + PRT_SignalDeliver(arg1, &info); + OsIntRestore(intSave); +} + +int OsPeriodTimerCreate(TskHandle taskPid, timer_t *timerId) +{ + int ret; + TimerHandle swtmrId; + struct TimerCreatePara timerPara = {0}; + if (!timerId) { + return -EINVAL; + } + + timerPara.type = OS_TIMER_SOFTWARE; + timerPara.mode = OS_TIMER_LOOP; + timerPara.interval = 1; + timerPara.timerGroupId = 0; + timerPara.callBackFunc = OsDelieverSigPeriod; + timerPara.arg1 = taskPid; + ret = PRT_TimerCreate(&timerPara, &swtmrId); + if (ret != OS_OK) { + return -EINVAL; + } + + *timerId = (timer_t)swtmrId; + return OS_OK; +} + +int OsPeriodTimerSetTime(timer_t timerId, U32 idate, U32 period) +{ + int ret; + struct TagSwTmrCtrl *swtmr = NULL; + ret = PRT_TimerStop(0, (TimerHandle)timerId); + if (ret != OS_OK && ret != OS_ERRNO_SWTMR_UNSTART) { + return -EINVAL; + } + + if (idate == 0) { + return OS_OK; + } + + U32 now = (U32)PRT_TickGetCount(); + uintptr_t intSave = OsIntLock(); + swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX((TimerHandle)timerId); + swtmr->mode = (period ? OS_TIMER_LOOP : OS_TIMER_ONCE); + swtmr->interval = (period ? period : idate - now); + swtmr->idxRollNum = idate - now; + swtmr->overrun = 0; + OsIntRestore(intSave); + + ret = PRT_TimerStart(0, (TimerHandle)timerId); + if (ret != OS_OK) { + return -EINVAL; + } + + return OS_OK; +} + +int PRT_TaskSetPeriodic(TskHandle taskPid, U32 idate, U32 period) +{ + int ret; + U32 now; + struct TagTskCb *tskCb = NULL; + if (!taskPid) { + tskCb = RUNNING_TASK; + } else { + tskCb = GET_TCB_HANDLE(taskPid); + } + + uintptr_t intSave = OsIntLock(); + if (!tskCb->itimer && !(tskCb->taskStatus & OS_TSK_SET_PERIODIC)) { + ret = OsPeriodTimerCreate(taskPid, &tskCb->itimer); + if (ret != OS_OK) { + OsIntRestore(intSave); + return ret; + } + + tskCb->taskStatus |= OS_TSK_SET_PERIODIC; + OsIntRestore(intSave); + } + + now = (U32)PRT_TickGetCount(); + if (idate == TM_NOW) { + idate = now + period; + } else if (idate < now) { + (void)PRT_TimerDelete(0, (TimerHandle)tskCb->itimer); + return -ETIMEDOUT; + } + + ret = OsPeriodTimerSetTime(tskCb->itimer, idate, period); + if (ret != OS_OK) { + (void)PRT_TimerDelete(0, (TimerHandle)tskCb->itimer); + } + + OsIntRestore(intSave); + return ret; +} + +int PRT_TaskWaitPeriod(U32 *overruns_r) +{ + int ret; + uintptr_t intSave; + signalInfo prtInfo = {0}; + signalSet prtSet = sigMask(SIGALRM); + struct TagTskCb *tskCb = RUNNING_TASK; + struct TagSwTmrCtrl *swtmr = NULL; + if (!(tskCb->taskStatus & OS_TSK_SET_PERIODIC)) { + return -EWOULDBLOCK; + } + + ret = PRT_SignalWait(&prtSet, &prtInfo, OS_SIGNAL_WAIT_FOREVER); + if (ret != OS_OK) { + return -EINTR; + } + + if (overruns_r) { + swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX((TimerHandle)tskCb->itimer); + intSave = OsIntLock(); + *overruns_r = (U32)swtmr->overrun; + swtmr->overrun = 0; + OsIntRestore(intSave); + if (*overruns_r) { + return -ETIMEDOUT; + } + } + + return OS_OK; +} diff --git a/src/core/kernel/task/smp/CMakeLists.txt b/src/core/kernel/task/smp/CMakeLists.txt index a56e875d..08817269 100644 --- a/src/core/kernel/task/smp/CMakeLists.txt +++ b/src/core/kernel/task/smp/CMakeLists.txt @@ -13,4 +13,5 @@ add_library_ex(prt_smp_task.c) add_library_ex(prt_smp_task_del.c) add_library_ex(prt_smp_task_init.c) add_library_ex(prt_smp_task_suspend.c) -add_library_ex(prt_smp_psci.c) \ No newline at end of file +add_library_ex(prt_smp_psci.c) +add_library_ex(prt_task_period.c) \ No newline at end of file diff --git a/src/core/kernel/task/smp/prt_task_period.c b/src/core/kernel/task/smp/prt_task_period.c new file mode 100644 index 00000000..70b09c53 --- /dev/null +++ b/src/core/kernel/task/smp/prt_task_period.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2024-2024 Huawei Technologies Co., Ltd. All rights reserved. + * + * UniProton is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Create: 2024-05-25 + * Description: Task periodic execution implementation + */ +#include "prt_signal.h" +#include "prt_timer.h" +#include "prt_swtmr_external.h" +#include "signal.h" +#include "prt_task_external.h" + +void OsDelieverSigPeriod(TimerHandle tmrHandle, U32 arg1, U32 arg2, U32 arg3, U32 arg4) +{ + (void)tmrHandle; + (void)arg2; + (void)arg3; + (void)arg4; + signalInfo info = {0}; + info.si_signo = SIGALRM; + info.si_code = SI_USER; + uintptr_t intSave = OsIntLock(); + PRT_SignalDeliver(arg1, &info); + OsIntRestore(intSave); +} + +int OsPeriodTimerCreate(TskHandle taskPid, timer_t *timerId) +{ + int ret; + TimerHandle swtmrId; + struct TimerCreatePara timerPara = {0}; + if (!timerId) { + return -EINVAL; + } + + timerPara.type = OS_TIMER_SOFTWARE; + timerPara.mode = OS_TIMER_LOOP; + timerPara.interval = 1; + timerPara.timerGroupId = 0; + timerPara.callBackFunc = OsDelieverSigPeriod; + timerPara.arg1 = taskPid; + ret = PRT_TimerCreate(&timerPara, &swtmrId); + if (ret != OS_OK) { + return -EINVAL; + } + + *timerId = (timer_t)swtmrId; + return OS_OK; +} + +int OsPeriodTimerSetTime(timer_t timerId, U32 idate, U32 period) +{ + int ret; + struct TagSwTmrCtrl *swtmr = NULL; + ret = PRT_TimerStop(0, (TimerHandle)timerId); + if (ret != OS_OK && ret != OS_ERRNO_SWTMR_UNSTART) { + return -EINVAL; + } + + if (idate == 0) { + return OS_OK; + } + + U32 now = (U32)PRT_TickGetCount(); + uintptr_t intSave = OsIntLock(); + swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX((TimerHandle)timerId); + swtmr->mode = (period ? OS_TIMER_LOOP : OS_TIMER_ONCE); + swtmr->interval = (period ? period : idate - now); + swtmr->idxRollNum = idate - now; + swtmr->overrun = 0; + OsIntRestore(intSave); + + ret = PRT_TimerStart(0, (TimerHandle)timerId); + if (ret != OS_OK) { + return -EINVAL; + } + + return OS_OK; +} + +int PRT_TaskSetPeriodic(TskHandle taskPid, U32 idate, U32 period) +{ + int ret; + U32 now; + struct TagTskCb *tskCb = NULL; + if (!taskPid) { + tskCb = RUNNING_TASK; + } else { + tskCb = GET_TCB_HANDLE(taskPid); + } + + uintptr_t intSave = OsIntLock(); + if (!tskCb->itimer && !(tskCb->taskStatus & OS_TSK_SET_PERIODIC)) { + ret = OsPeriodTimerCreate(taskPid, &tskCb->itimer); + if (ret != OS_OK) { + OsIntRestore(intSave); + return ret; + } + + tskCb->taskStatus |= OS_TSK_SET_PERIODIC; + OsIntRestore(intSave); + } + + now = (U32)PRT_TickGetCount(); + if (idate == TM_NOW) { + idate = now + period; + } else if (idate < now) { + (void)PRT_TimerDelete(0, (TimerHandle)tskCb->itimer); + return -ETIMEDOUT; + } + + ret = OsPeriodTimerSetTime(tskCb->itimer, idate, period); + if (ret != OS_OK) { + (void)PRT_TimerDelete(0, (TimerHandle)tskCb->itimer); + } + + OsIntRestore(intSave); + return ret; +} + +int PRT_TaskWaitPeriod(U32 *overruns_r) +{ + int ret; + uintptr_t intSave; + signalInfo prtInfo = {0}; + signalSet prtSet = sigMask(SIGALRM); + struct TagTskCb *tskCb = RUNNING_TASK; + struct TagSwTmrCtrl *swtmr = NULL; + if (!(tskCb->taskStatus & OS_TSK_SET_PERIODIC)) { + return -EWOULDBLOCK; + } + + ret = PRT_SignalWait(&prtSet, &prtInfo, OS_SIGNAL_WAIT_FOREVER); + if (ret != OS_OK) { + return -EINTR; + } + + if (overruns_r) { + swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX((TimerHandle)tskCb->itimer); + intSave = OsIntLock(); + *overruns_r = (U32)swtmr->overrun; + swtmr->overrun = 0; + OsIntRestore(intSave); + if (*overruns_r) { + return -ETIMEDOUT; + } + } + + return OS_OK; +} diff --git a/src/include/uapi/prt_task.h b/src/include/uapi/prt_task.h index 2f3c5663..fb94c937 100644 --- a/src/include/uapi/prt_task.h +++ b/src/include/uapi/prt_task.h @@ -74,6 +74,9 @@ extern "C" { #define COMPOSE_PID(coreid, handle) \ ((((U32)(coreid)) << OS_TSK_TCB_INDEX_BITS) + ((U8)(handle))) /* 将(coreid)与(handle)组成PID,UIPC不使用该接口 */ +#define TM_NOW 0 +#define TM_INFINITE 0 + /* * 支持的优先级(0~31),OS系统IDLE线程使用最低优先级(31),用户不能使用。 * 可用的任务优先级宏定义。 @@ -578,6 +581,13 @@ extern "C" { */ #define OS_TSK_SIG_PAUSE 0x20000 +/* + * 任务或任务控制块状态标志。 + * + * 任务设置运行周期 + */ +#define OS_TSK_SET_PERIODIC 0x40000 + /* * 任务模块的错误码定义。 */ @@ -1523,6 +1533,59 @@ OS_SEC_ALW_INLINE INLINE U32 PRT_TaskDeleteHookDelete(TskDeleteHook hook) return OsHookDel(OS_HOOK_TSK_DELETE, (OsVoidFunc)hook); } +/* + * @brief 设置任务的周期性执行 + * + * @par 描述 + * 设置任务的执行周期和起始时间,使任务可以按指定的周期执行。 + * + * @attention 无 + * + * @param taskPid [IN] 类型#TskHandle,任务ID。 + * @param idate [IN] 类型#U32,任务周期执行的起始时间。 + * @param period [IN] 类型#U32,任务执行的周期。 + * + * @par 依赖 + * + * @see PRT_TaskSetPeriodic + */ +extern int PRT_TaskSetPeriodic(TskHandle taskPid, U32 idate, U32 period); + +/* + * @brief 任务等待指定的时间周期 + * + * @par 描述 + * 使任务按指定的周期等待一段时间,然后再继续执行下一次任务。 + * + * @attention + * + * + * @param overruns_r [OUT] 类型#U32 *,等待周期内任务定时器的超时次数。 + * + * @par 依赖 + * + * @see PRT_TaskWaitPeriod + */ +extern int PRT_TaskWaitPeriod(U32 *overruns_r); + +/* + * @brief 等待指定任务结束并回收其资源。 + * + * @par 描述 + * 阻塞当前任务直到指定的任务结束,并回收其资源。 + * + * @attention 无 + * + * @param taskPid [IN] 类型#TskHandle,任务ID。 + * + * @par 依赖 + * + * @see PRT_TaskJoin + */ +extern int PRT_TaskJoin(TskHandle taskPid); + #if defined(OS_OPTION_SMP) extern U32 PRT_TaskGetCurrentOnCore(U32 coreId, TskHandle *taskPid); diff --git a/src/libc/litelibc/src/thread/pthread_join.c b/src/libc/litelibc/src/thread/pthread_join.c index 3ae7735a..8f3b316c 100644 --- a/src/libc/litelibc/src/thread/pthread_join.c +++ b/src/libc/litelibc/src/thread/pthread_join.c @@ -86,6 +86,11 @@ int PRT_PthreadTimedJoin(TskHandle thread, void **status, U32 timeout) return ret; } +int PRT_TaskJoin(TskHandle taskPid) +{ + return PRT_PthreadTimedJoin(taskPid, NULL, OS_WAIT_FOREVER); +} + int __pthread_timedjoin_np(pthread_t thread, void **status, const struct timespec *at) { U32 ret; -- Gitee From 0a55ccffedf675b42bb2802cce28b37924fd23c5 Mon Sep 17 00:00:00 2001 From: zhaohonghao Date: Sat, 25 May 2024 16:41:38 +0800 Subject: [PATCH 2/2] task: add task support API for task periodic execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit description: 增加task周期运行相关接口 Signed-off-by: zhaohonghao --- src/core/kernel/task/amp/CMakeLists.txt | 3 ++- src/core/kernel/task/smp/CMakeLists.txt | 4 +++- src/include/uapi/prt_task.h | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/kernel/task/amp/CMakeLists.txt b/src/core/kernel/task/amp/CMakeLists.txt index 9b4649ff..b2d9856f 100644 --- a/src/core/kernel/task/amp/CMakeLists.txt +++ b/src/core/kernel/task/amp/CMakeLists.txt @@ -15,5 +15,6 @@ add_library_ex(prt_amp_task_minor.c) if(${CONFIG_OS_OPTION_POWEROFF}) add_library_ex(prt_amp_psci.c) endif() +if(${CONFIG_OS_OPTION_POSIX_SIGNAL}) add_library_ex(prt_task_period.c) - +endif() diff --git a/src/core/kernel/task/smp/CMakeLists.txt b/src/core/kernel/task/smp/CMakeLists.txt index 08817269..018583ba 100644 --- a/src/core/kernel/task/smp/CMakeLists.txt +++ b/src/core/kernel/task/smp/CMakeLists.txt @@ -14,4 +14,6 @@ add_library_ex(prt_smp_task_del.c) add_library_ex(prt_smp_task_init.c) add_library_ex(prt_smp_task_suspend.c) add_library_ex(prt_smp_psci.c) -add_library_ex(prt_task_period.c) \ No newline at end of file +if(${CONFIG_OS_OPTION_POSIX_SIGNAL}) +add_library_ex(prt_task_period.c) +endif() diff --git a/src/include/uapi/prt_task.h b/src/include/uapi/prt_task.h index fb94c937..5eecac51 100644 --- a/src/include/uapi/prt_task.h +++ b/src/include/uapi/prt_task.h @@ -1533,6 +1533,7 @@ OS_SEC_ALW_INLINE INLINE U32 PRT_TaskDeleteHookDelete(TskDeleteHook hook) return OsHookDel(OS_HOOK_TSK_DELETE, (OsVoidFunc)hook); } +#if defined(OS_OPTION_POSIX_SIGNAL) /* * @brief 设置任务的周期性执行 * @@ -1569,6 +1570,7 @@ extern int PRT_TaskSetPeriodic(TskHandle taskPid, U32 idate, U32 period); * @see PRT_TaskWaitPeriod */ extern int PRT_TaskWaitPeriod(U32 *overruns_r); +#endif /* * @brief 等待指定任务结束并回收其资源。 -- Gitee