From 8d7468b44c9241192cc7d3aacd989cfec74ef470 Mon Sep 17 00:00:00 2001 From: JerryH Date: Thu, 20 Jan 2022 10:06:59 +0800 Subject: [PATCH] feature: Support kernel signal and POSIX API. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 内核支持信号功能,支持注册、屏蔽、等待及触发等操作。 close #I4R72Q Signed-off-by: JerryH Change-Id: I26fb11a03d1899c6f7e665f0798824c578d592a6 --- Kconfig | 2 + arch/arm/arm9/gcc/los_context.c | 13 +- arch/arm/cortex-m3/keil/los_context.c | 12 +- arch/arm/cortex-m33/gcc/NTZ/los_context.c | 27 +- arch/arm/cortex-m33/gcc/NTZ/los_dispatch.S | 24 +- .../gcc/TZ/non_secure/los_context.c | 26 +- .../gcc/TZ/non_secure/los_dispatch.S | 22 +- arch/arm/cortex-m33/iar/NTZ/los_context.c | 25 +- arch/arm/cortex-m33/iar/NTZ/los_dispatch.S | 15 +- .../iar/TZ/non_secure/los_context.c | 26 +- .../iar/TZ/non_secure/los_dispatch.S | 16 +- arch/arm/cortex-m4/gcc/los_context.c | 25 +- arch/arm/cortex-m4/gcc/los_dispatch.S | 20 +- arch/arm/cortex-m4/iar/los_context.c | 29 +- arch/arm/cortex-m4/iar/los_dispatch.S | 19 +- arch/arm/cortex-m7/gcc/los_context.c | 25 +- arch/arm/cortex-m7/gcc/los_dispatch.S | 15 +- arch/arm/cortex-m7/iar/los_context.c | 25 +- arch/arm/cortex-m7/iar/los_dispatch.S | 17 +- arch/csky/v2/gcc/los_context.c | 12 +- arch/include/los_context.h | 1 + arch/risc-v/nuclei/gcc/los_context.c | 5 +- arch/risc-v/riscv32/gcc/los_context.c | 11 +- arch/xtensa/lx6/gcc/los_context.c | 12 +- components/BUILD.gn | 2 + components/signal/BUILD.gn | 38 ++ components/signal/Kconfig | 6 + components/signal/los_signal.c | 441 ++++++++++++++++++ components/signal/los_signal.h | 234 ++++++++++ kal/posix/BUILD.gn | 4 + kal/posix/Kconfig | 7 + kal/posix/src/pipe.c | 10 +- kal/posix/src/signal.c | 231 +++++++++ kernel/include/los_config.h | 8 +- kernel/include/los_task.h | 25 + kernel/src/los_init.c | 12 + kernel/src/los_task.c | 24 +- testsuites/BUILD.gn | 3 + testsuites/include/osTest.h | 2 + testsuites/sample/kernel/signal/BUILD.gn | 40 ++ .../sample/kernel/signal/It_los_signal.c | 40 ++ .../sample/kernel/signal/It_los_signal.h | 56 +++ .../sample/kernel/signal/It_los_signal_001.c | 80 ++++ .../sample/kernel/signal/It_los_signal_002.c | 72 +++ .../sample/kernel/signal/It_los_signal_003.c | 111 +++++ .../sample/kernel/signal/It_los_signal_004.c | 88 ++++ .../sample/kernel/signal/It_los_signal_005.c | 71 +++ testsuites/src/osTest.c | 5 +- utils/los_error.h | 1 + 49 files changed, 1847 insertions(+), 188 deletions(-) mode change 100755 => 100644 arch/arm/cortex-m33/gcc/NTZ/los_context.c mode change 100755 => 100644 arch/arm/cortex-m33/gcc/NTZ/los_dispatch.S mode change 100755 => 100644 arch/arm/cortex-m33/gcc/TZ/non_secure/los_context.c mode change 100755 => 100644 arch/include/los_context.h create mode 100644 components/signal/BUILD.gn create mode 100644 components/signal/Kconfig create mode 100644 components/signal/los_signal.c create mode 100644 components/signal/los_signal.h create mode 100644 kal/posix/src/signal.c create mode 100644 testsuites/sample/kernel/signal/BUILD.gn create mode 100644 testsuites/sample/kernel/signal/It_los_signal.c create mode 100644 testsuites/sample/kernel/signal/It_los_signal.h create mode 100644 testsuites/sample/kernel/signal/It_los_signal_001.c create mode 100644 testsuites/sample/kernel/signal/It_los_signal_002.c create mode 100644 testsuites/sample/kernel/signal/It_los_signal_003.c create mode 100644 testsuites/sample/kernel/signal/It_los_signal_004.c create mode 100644 testsuites/sample/kernel/signal/It_los_signal_005.c diff --git a/Kconfig b/Kconfig index f394150a..0bed3e8f 100644 --- a/Kconfig +++ b/Kconfig @@ -286,6 +286,8 @@ config KERNEL_CPPSUPPORT help If you wish to build LiteOS with support for C++. +rsource "components/signal/Kconfig" + config BASE_CORE_CPUP bool default n diff --git a/arch/arm/arm9/gcc/los_context.c b/arch/arm/arm9/gcc/los_context.c index 00437f08..035beaec 100644 --- a/arch/arm/arm9/gcc/los_context.c +++ b/arch/arm/arm9/gcc/los_context.c @@ -75,18 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - PRINT_ERR("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); context->r0 = taskID; context->r1 = 0x01010101L; diff --git a/arch/arm/cortex-m3/keil/los_context.c b/arch/arm/cortex-m3/keil/los_context.c index bcbeb96e..96506b2e 100644 --- a/arch/arm/cortex-m3/keil/los_context.c +++ b/arch/arm/cortex-m3/keil/los_context.c @@ -76,17 +76,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) diff --git a/arch/arm/cortex-m33/gcc/NTZ/los_context.c b/arch/arm/cortex-m33/gcc/NTZ/los_context.c old mode 100755 new mode 100644 index b705af47..293a884c --- a/arch/arm/cortex-m33/gcc/NTZ/los_context.c +++ b/arch/arm/cortex-m33/gcc/NTZ/los_context.c @@ -75,17 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -146,6 +136,21 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +#if (LOSCFG_KERNEL_SIGNAL == 1) +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + UNUSED(stackTop); + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} +#endif + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m33/gcc/NTZ/los_dispatch.S b/arch/arm/cortex-m33/gcc/NTZ/los_dispatch.S old mode 100755 new mode 100644 index e6134d1f..a50263e1 --- a/arch/arm/cortex-m33/gcc/NTZ/los_dispatch.S +++ b/arch/arm/cortex-m33/gcc/NTZ/los_dispatch.S @@ -47,6 +47,15 @@ .section .text .thumb +.macro SIGNAL_CONTEXT_RESTORE + push {r12, lr} + blx OsSignalTaskContextRestore + pop {r12, lr} + cmp r0, #0 + mov r1, r0 + bne SignalContextRestore +.endm + .type HalStartToRun, %function .global HalStartToRun HalStartToRun: @@ -90,10 +99,8 @@ __DisabledFPU: MOV lr, r5 cpsie I BX r6 - .fnend - .type ArchIntLock, %function .global ArchIntLock ArchIntLock: @@ -140,9 +147,6 @@ ArchTaskSchedule: bx lr .fnend - - - .type HalPendSV, %function .global HalPendSV HalPendSV: @@ -153,6 +157,8 @@ HalPendSV: cpsid I HalTaskSwitch: + SIGNAL_CONTEXT_RESTORE + push {r12, lr} blx OsSchedTaskSwitch pop {r12, lr} @@ -182,9 +188,11 @@ __DisabledFPU1: ldr r0, [r5, #4] str r0, [r5] - ldr r1, [r0] +SignalContextRestore: + ldr.w r3, =OS_FPU_CPACR + ldr r3, [r3] and r3, r3, #OS_FPU_CPACR_ENABLE cmp r3, #OS_FPU_CPACR_ENABLE bne __DisabledFPU2 @@ -193,9 +201,7 @@ __DisabledFPU1: __DisabledFPU2: ldmfd r1!, {r4-r12} msr psp, r1 - msr PRIMASK, r12 - - bx lr + .fnend diff --git a/arch/arm/cortex-m33/gcc/TZ/non_secure/los_context.c b/arch/arm/cortex-m33/gcc/TZ/non_secure/los_context.c old mode 100755 new mode 100644 index cef24560..9ed84f0f --- a/arch/arm/cortex-m33/gcc/TZ/non_secure/los_context.c +++ b/arch/arm/cortex-m33/gcc/TZ/non_secure/los_context.c @@ -75,17 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -150,6 +140,20 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->stackLimit = (UINT32)stackTop; + context->excReturn = 0xFFFFFFBC; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m33/gcc/TZ/non_secure/los_dispatch.S b/arch/arm/cortex-m33/gcc/TZ/non_secure/los_dispatch.S index 77e9673d..85af40fe 100644 --- a/arch/arm/cortex-m33/gcc/TZ/non_secure/los_dispatch.S +++ b/arch/arm/cortex-m33/gcc/TZ/non_secure/los_dispatch.S @@ -45,6 +45,15 @@ .section .text .thumb +.macro SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} + BLX OsSignalTaskContextRestore + POP {R12, LR} + CMP R0, #0 + MOV R1, R0 + BNE SignalContextRestore +.endm + .type HalStartFirstTask, %function .global HalStartFirstTask HalStartFirstTask: @@ -132,6 +141,8 @@ HalPendSV: cpsid I HalTaskSwitch: + SIGNAL_CONTEXT_RESTORE + push {r12, lr} blx OsSchedTaskSwitch pop {r12, lr} @@ -175,8 +186,9 @@ __DisabledFPU2: LDR R0, [R5, #4] STR R0, [R5] - LDR R1, [R0] + +SignalContextRestore: LDMIA R1!, {R0, R2-R3} /* Restore secureContext, PSPLIM and LR from the current task stack. */ MSR PSPLIM, R2 MOV LR, R3 @@ -205,7 +217,7 @@ __DisabledFPU3: .fnend .type HalSVCStartSchedule, %function - .global HalSVCStartSchedule + .global HalSVCStartSchedule HalSVCStartSchedule: .fnstart .cantunwind @@ -219,7 +231,7 @@ HalSVCStartSchedule: .fnend .type HalSVCSecureContextAlloc, %function - .global HalSVCSecureContextAlloc + .global HalSVCSecureContextAlloc HalSVCSecureContextAlloc: .fnstart .cantunwind @@ -228,7 +240,7 @@ HalSVCSecureContextAlloc: .fnend .type HalSVCSecureContextFree, %function - .global HalSVCSecureContextFree + .global HalSVCSecureContextFree HalSVCSecureContextFree: .fnstart .cantunwind @@ -237,7 +249,7 @@ HalSVCSecureContextFree: .fnend .type HalSVCHandler, %function - .global HalSVCHandler + .global HalSVCHandler HalSVCHandler: .fnstart .cantunwind diff --git a/arch/arm/cortex-m33/iar/NTZ/los_context.c b/arch/arm/cortex-m33/iar/NTZ/los_context.c index bea396b9..9e03eac5 100644 --- a/arch/arm/cortex-m33/iar/NTZ/los_context.c +++ b/arch/arm/cortex-m33/iar/NTZ/los_context.c @@ -75,17 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -146,6 +136,19 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + UNUSED(stackTop); + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m33/iar/NTZ/los_dispatch.S b/arch/arm/cortex-m33/iar/NTZ/los_dispatch.S index f8f0d188..98461ca7 100644 --- a/arch/arm/cortex-m33/iar/NTZ/los_dispatch.S +++ b/arch/arm/cortex-m33/iar/NTZ/los_dispatch.S @@ -38,6 +38,7 @@ EXPORT ArchTaskSchedule EXPORT HalPendSV IMPORT OsSchedTaskSwitch + IMPORT OsSignalTaskContextRestore IMPORT g_losTask OS_FPU_CPACR EQU 0xE000ED88 @@ -52,6 +53,15 @@ OS_TASK_STATUS_RUNNING EQU 0x0010 THUMB REQUIRE8 + MACRO SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} + BLX OsSignalTaskContextRestore + POP {R12, LR} + CMP R0, #0 + MOV R1, R0 + BNE SignalContextRestore + ENDM + HalStartToRun LDR R4, =OS_NVIC_SYSPRI2 LDR R5, =OS_NVIC_PENDSV_PRI @@ -145,8 +155,11 @@ __DisabledFPU1 LDR R0, [R5, #4] STR R0, [R5] - LDR R1, [R0] + +SignalContextRestore + LDR.W R3, =OS_FPU_CPACR + LDR R3, [R3] AND R3, R3, #OS_FPU_CPACR_ENABLE CMP R3, #OS_FPU_CPACR_ENABLE BNE __DisabledFPU2 diff --git a/arch/arm/cortex-m33/iar/TZ/non_secure/los_context.c b/arch/arm/cortex-m33/iar/TZ/non_secure/los_context.c index 3672ac32..995fb722 100644 --- a/arch/arm/cortex-m33/iar/TZ/non_secure/los_context.c +++ b/arch/arm/cortex-m33/iar/TZ/non_secure/los_context.c @@ -75,17 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -150,6 +140,20 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->stackLimit = (UINT32)stackTop; + context->excReturn = 0xFFFFFFBC; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m33/iar/TZ/non_secure/los_dispatch.S b/arch/arm/cortex-m33/iar/TZ/non_secure/los_dispatch.S index 03a8696f..f03285fc 100644 --- a/arch/arm/cortex-m33/iar/TZ/non_secure/los_dispatch.S +++ b/arch/arm/cortex-m33/iar/TZ/non_secure/los_dispatch.S @@ -41,7 +41,7 @@ EXPORT HalSVCStartSchedule EXPORT HalSVCSecureContextAlloc EXPORT HalSVCSecureContextFree - + IMPORT OsSignalTaskContextRestore IMPORT OsSchedTaskSwitch IMPORT g_losTask @@ -62,6 +62,15 @@ OS_TASK_STATUS_RUNNING EQU 0x0010 THUMB REQUIRE8 + MACRO SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} + BLX OsSignalTaskContextRestore + POP {R12, LR} + CMP R0, #0 + MOV R1, R0 + BNE SignalContextRestore + ENDM + HalStartFirstTask MOV R0, #2 MSR CONTROL, R0 @@ -118,6 +127,8 @@ HalPendSV CPSID I HalTaskSwitch + SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} BLX OsSchedTaskSwitch POP {R12, LR} @@ -161,8 +172,9 @@ __DisabledFPU2 LDR R0, [R5, #4] STR R0, [R5] - LDR R1, [R0] + +SignalContextRestore LDMIA R1!, {R0, R2-R3} /* Restore secureContext, PSPLIM and LR from the current task stack. */ MSR PSPLIM, R2 MOV LR, R3 diff --git a/arch/arm/cortex-m4/gcc/los_context.c b/arch/arm/cortex-m4/gcc/los_context.c index b5ce64e8..78c383d4 100644 --- a/arch/arm/cortex-m4/gcc/los_context.c +++ b/arch/arm/cortex-m4/gcc/los_context.c @@ -74,17 +74,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -145,6 +135,19 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + UNUSED(stackTop); + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m4/gcc/los_dispatch.S b/arch/arm/cortex-m4/gcc/los_dispatch.S index 19f0b9da..d21b274d 100644 --- a/arch/arm/cortex-m4/gcc/los_dispatch.S +++ b/arch/arm/cortex-m4/gcc/los_dispatch.S @@ -44,6 +44,15 @@ .section .text .thumb +.macro SIGNAL_CONTEXT_RESTORE + push {r12, lr} + blx OsSignalTaskContextRestore + pop {r12, lr} + cmp r0, #0 + mov r1, r0 + bne SignalContextRestore +.endm + .type HalStartToRun, %function .global HalStartToRun HalStartToRun: @@ -88,7 +97,6 @@ __DisabledFPU: .fnend - .type ArchIntLock, %function .global ArchIntLock ArchIntLock: @@ -135,9 +143,6 @@ ArchTaskSchedule: isb .fnend - - - .type HalPendSV, %function .global HalPendSV HalPendSV: @@ -148,6 +153,8 @@ HalPendSV: cpsid I HalTaskSwitch: + SIGNAL_CONTEXT_RESTORE + push {r12, lr} blx OsSchedTaskSwitch pop {r12, lr} @@ -176,8 +183,11 @@ __DisabledFPU1: ldr r0, [r5, #4] str r0, [r5] - ldr r1, [r0] + +SignalContextRestore: + ldr.w r3, =OS_FPU_CPACR + ldr r3, [r3] and r3, r3, #OS_FPU_CPACR_ENABLE cmp r3, #OS_FPU_CPACR_ENABLE bne __DisabledFPU2 diff --git a/arch/arm/cortex-m4/iar/los_context.c b/arch/arm/cortex-m4/iar/los_context.c index 8712baab..6d5d6d35 100644 --- a/arch/arm/cortex-m4/iar/los_context.c +++ b/arch/arm/cortex-m4/iar/los_context.c @@ -77,17 +77,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -141,13 +131,26 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO context->uwR2 = 0x02020202L; context->uwR3 = 0x03030303L; context->uwR12 = 0x12121212L; - context->uwLR = (UINT32)(UINTPTR)ArchSysExit; - context->uwPC = (UINT32)(UINTPTR)OsTaskEntry; + context->uwLR = (UINTPTR)ArchSysExit; + context->uwPC = (UINTPTR)OsTaskEntry; context->uwxPSR = 0x01000000L; return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + UNUSED(stackTop); + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m4/iar/los_dispatch.S b/arch/arm/cortex-m4/iar/los_dispatch.S index f8f0d188..2dc0e8e4 100644 --- a/arch/arm/cortex-m4/iar/los_dispatch.S +++ b/arch/arm/cortex-m4/iar/los_dispatch.S @@ -38,6 +38,7 @@ EXPORT ArchTaskSchedule EXPORT HalPendSV IMPORT OsSchedTaskSwitch + IMPORT OsSignalTaskContextRestore IMPORT g_losTask OS_FPU_CPACR EQU 0xE000ED88 @@ -52,6 +53,15 @@ OS_TASK_STATUS_RUNNING EQU 0x0010 THUMB REQUIRE8 + MACRO SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} + BLX OsSignalTaskContextRestore + POP {R12, LR} + CMP R0, #0 + MOV R1, R0 + BNE SignalContextRestore + ENDM + HalStartToRun LDR R4, =OS_NVIC_SYSPRI2 LDR R5, =OS_NVIC_PENDSV_PRI @@ -117,6 +127,8 @@ HalPendSV CPSID I HalTaskSwitch + SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} BLX OsSchedTaskSwitch POP {R12, LR} @@ -128,8 +140,8 @@ HalTaskSwitch TaskContextSwitch MOV LR, R0 - MRS R0, PSP + MRS R0, PSP STMFD R0!, {R4-R12} LDR.W R3, =OS_FPU_CPACR LDR R3, [R3] @@ -145,8 +157,11 @@ __DisabledFPU1 LDR R0, [R5, #4] STR R0, [R5] - LDR R1, [R0] + +SignalContextRestore + LDR.W R3, =OS_FPU_CPACR + LDR R3, [R3] AND R3, R3, #OS_FPU_CPACR_ENABLE CMP R3, #OS_FPU_CPACR_ENABLE BNE __DisabledFPU2 diff --git a/arch/arm/cortex-m7/gcc/los_context.c b/arch/arm/cortex-m7/gcc/los_context.c index b705af47..5eff6372 100644 --- a/arch/arm/cortex-m7/gcc/los_context.c +++ b/arch/arm/cortex-m7/gcc/los_context.c @@ -75,17 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -146,6 +136,19 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + UNUSED(stackTop); + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m7/gcc/los_dispatch.S b/arch/arm/cortex-m7/gcc/los_dispatch.S index 46193a64..4e1393ae 100644 --- a/arch/arm/cortex-m7/gcc/los_dispatch.S +++ b/arch/arm/cortex-m7/gcc/los_dispatch.S @@ -35,8 +35,6 @@ .fpu fpv5-d16 //;.arch_extension sec - - .equ OS_NVIC_INT_CTRL, 0xE000ED04 .equ OS_NVIC_SYSPRI2, 0xE000ED20 .equ OS_NVIC_PENDSV_PRI, 0xF0F00000 @@ -46,6 +44,15 @@ .section .text .thumb +.macro SIGNAL_CONTEXT_RESTORE + push {r12, lr} + blx OsSignalTaskContextRestore + pop {r12, lr} + cmp r0, #0 + mov r1, r0 + bne SignalContextRestore +.endm + .type HalStartToRun, %function .global HalStartToRun HalStartToRun: @@ -142,6 +149,8 @@ HalPendSV: cpsid I HalTaskSwitch: + SIGNAL_CONTEXT_RESTORE + push {r12, lr} blx OsSchedTaskSwitch pop {r12, lr} @@ -167,9 +176,9 @@ TaskContextSwitch: ldr r0, [r5, #4] str r0, [r5] - ldr r1, [r0] + SignalContextRestore: #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) vldmia r1!, {d8-d15} diff --git a/arch/arm/cortex-m7/iar/los_context.c b/arch/arm/cortex-m7/iar/los_context.c index b705af47..5eff6372 100644 --- a/arch/arm/cortex-m7/iar/los_context.c +++ b/arch/arm/cortex-m7/iar/los_context.c @@ -75,17 +75,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) @@ -146,6 +136,19 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO return (VOID *)context; } +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param) +{ + UNUSED(stackTop); + TaskContext *context = (TaskContext *)((UINTPTR)stackPointer - sizeof(TaskContext)); + (VOID)memset_s((VOID *)context, sizeof(TaskContext), 0, sizeof(TaskContext)); + + context->uwR0 = param; + context->uwPC = sigHandler; + context->uwxPSR = 0x01000000L; /* Thumb flag, always set 1 */ + + return (VOID *)context; +} + LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID) { (VOID)LOS_IntLock(); diff --git a/arch/arm/cortex-m7/iar/los_dispatch.S b/arch/arm/cortex-m7/iar/los_dispatch.S index f8f0d188..1c165bd3 100644 --- a/arch/arm/cortex-m7/iar/los_dispatch.S +++ b/arch/arm/cortex-m7/iar/los_dispatch.S @@ -38,6 +38,7 @@ EXPORT ArchTaskSchedule EXPORT HalPendSV IMPORT OsSchedTaskSwitch + IMPORT OsSignalTaskContextRestore IMPORT g_losTask OS_FPU_CPACR EQU 0xE000ED88 @@ -52,6 +53,15 @@ OS_TASK_STATUS_RUNNING EQU 0x0010 THUMB REQUIRE8 + MACRO SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} + BLX OsSignalTaskContextRestore + POP {R12, LR} + CMP R0, #0 + MOV R1, R0 + BNE SignalContextRestore + ENDM + HalStartToRun LDR R4, =OS_NVIC_SYSPRI2 LDR R5, =OS_NVIC_PENDSV_PRI @@ -117,6 +127,8 @@ HalPendSV CPSID I HalTaskSwitch + SIGNAL_CONTEXT_RESTORE + PUSH {R12, LR} BLX OsSchedTaskSwitch POP {R12, LR} @@ -145,8 +157,11 @@ __DisabledFPU1 LDR R0, [R5, #4] STR R0, [R5] - LDR R1, [R0] + +SignalContextRestore + LDR.W R3, =OS_FPU_CPACR + LDR R3, [R3] AND R3, R3, #OS_FPU_CPACR_ENABLE CMP R3, #OS_FPU_CPACR_ENABLE BNE __DisabledFPU2 diff --git a/arch/csky/v2/gcc/los_context.c b/arch/csky/v2/gcc/los_context.c index afca82f5..6a82b9cd 100644 --- a/arch/csky/v2/gcc/los_context.c +++ b/arch/csky/v2/gcc/los_context.c @@ -77,17 +77,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) **************************************************************************** */ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); context->R0 = taskID; context->R1 = 0x01010101L; diff --git a/arch/include/los_context.h b/arch/include/los_context.h old mode 100755 new mode 100644 index e9d7a9da..5ce62b03 --- a/arch/include/los_context.h +++ b/arch/include/los_context.h @@ -106,6 +106,7 @@ LITE_OS_SEC_TEXT_MINOR NORETURN VOID ArchSysExit(VOID); VOID ArchTaskSchedule(VOID); UINT32 ArchStartSchedule(VOID); +VOID *ArchSignalContextInit(VOID *stackPointer, VOID *stackTop, UINTPTR sigHandler, UINT32 param); #ifdef __cplusplus #if __cplusplus diff --git a/arch/risc-v/nuclei/gcc/los_context.c b/arch/risc-v/nuclei/gcc/los_context.c index 1207dd11..49712e93 100644 --- a/arch/risc-v/nuclei/gcc/los_context.c +++ b/arch/risc-v/nuclei/gcc/los_context.c @@ -45,10 +45,7 @@ LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VO { UINT32 index; UINT8 *stk = 0; - TaskContext *context = NULL; - - /* initialize the task stack, write magic num to stack top */ - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; + TaskContext *context = NULL; stk = ((UINT8 *)topStack) + stackSize + sizeof(STACK_TYPE); stk = (UINT8 *)ALIGN_DOWN((uintptr_t)stk, REGBYTES); diff --git a/arch/risc-v/riscv32/gcc/los_context.c b/arch/risc-v/riscv32/gcc/los_context.c index acb9aed8..7f266fbf 100644 --- a/arch/risc-v/riscv32/gcc/los_context.c +++ b/arch/risc-v/riscv32/gcc/los_context.c @@ -81,16 +81,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - UINT32 index; - TaskContext *context = NULL; - - /* initialize the task stack, write magic num to stack top */ - for (index = 1; index < (stackSize / sizeof(UINT32)); index++) { - *((UINT32 *)topStack + index) = OS_TASK_STACK_INIT; - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); context->mstatus = RISCV_MSTATUS_MPP | RISCV_MSTATUS_MPIE; context->mepc = (UINT32)(UINTPTR)OsTaskEntry; diff --git a/arch/xtensa/lx6/gcc/los_context.c b/arch/xtensa/lx6/gcc/los_context.c index 25d6824b..c693cf50 100644 --- a/arch/xtensa/lx6/gcc/los_context.c +++ b/arch/xtensa/lx6/gcc/los_context.c @@ -110,17 +110,7 @@ LITE_OS_SEC_TEXT_MINOR VOID ArchSysExit(VOID) LITE_OS_SEC_TEXT_INIT VOID *ArchTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) { - TaskContext *context = NULL; - errno_t result; - - /* initialize the task stack, write magic num to stack top */ - result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); - if (result != EOK) { - printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); - } - *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; - - context = (TaskContext *)((((UINTPTR)topStack + stackSize) - sizeof(TaskContext))); + TaskContext *context = (TaskContext *)((UINTPTR)topStack + stackSize - sizeof(TaskContext)); /* initialize the task context */ result = memcpy_s(context, sizeof(TaskContext), g_stackDefault, sizeof(TaskContext)); diff --git a/components/BUILD.gn b/components/BUILD.gn index b10a09ae..b957e43f 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn @@ -42,6 +42,7 @@ group("components") { "net", "power", "shell", + "signal", "trace", ] } @@ -60,5 +61,6 @@ config("public") { "trace:public", "lmk:public", "lms:public", + "signal:public", ] } diff --git a/components/signal/BUILD.gn b/components/signal/BUILD.gn new file mode 100644 index 00000000..e473daa9 --- /dev/null +++ b/components/signal/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//kernel/liteos_m/liteos.gni") + +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { + sources = [ "los_signal.c" ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/components/signal/Kconfig b/components/signal/Kconfig new file mode 100644 index 00000000..c9bd7c97 --- /dev/null +++ b/components/signal/Kconfig @@ -0,0 +1,6 @@ +config KERNEL_SIGNAL + bool "Enable Signal" + default n + depends on KERNEL_EXTKERNEL + help + Select y to build LiteOS with signal. diff --git a/components/signal/los_signal.c b/components/signal/los_signal.c new file mode 100644 index 00000000..b9d80a87 --- /dev/null +++ b/components/signal/los_signal.c @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_signal.h" +#include "securec.h" +#include "los_config.h" +#include "los_interrupt.h" +#include "los_task.h" +#include "los_sched.h" +#include "los_debug.h" +#include "los_memory.h" +#include "los_context.h" +#include "los_arch_context.h" + +UINTPTR OsSignalTaskContextRestore(VOID) +{ +#if (LOSCFG_KERNEL_SIGNAL == 1) + LosTaskCB *task = OsCurrTaskGet(); + OsSigCB *sigCB = (OsSigCB *)task->sig; + UINTPTR sp; + + if ((sigCB == NULL) || (sigCB->sigRestoreSP == NULL)) { + return 0; + } + + sp = (UINTPTR)sigCB->sigRestoreSP; + sigCB->sigRestoreSP = NULL; + + return sp; +#else + return 0; +#endif +} + +#if (LOSCFG_KERNEL_SIGNAL == 1) +STATIC LOS_DL_LIST g_waitSignalList; + +STATIC VOID SignalDefaultHandler(INT32 signo) +{ + PRINTK("signal default handler, signo = %d\n", signo); +} + +STATIC UINT32 AddSigInfoToList(OsSigCB *sigCB, siginfo_t *info) +{ + OsSigInfoNode *tmpInfo = NULL; + BOOL findFlag = FALSE; + + LOS_DL_LIST_FOR_EACH_ENTRY(tmpInfo, &sigCB->sigInfoList, OsSigInfoNode, node) { + if (tmpInfo->info.si_signo == info->si_signo) { + findFlag = TRUE; + break; + } + } + + if (findFlag == FALSE) { + tmpInfo = (OsSigInfoNode *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(OsSigInfoNode)); + if (tmpInfo == NULL) { + return LOS_NOK; + } + LOS_ListAdd(&sigCB->sigInfoList, &tmpInfo->node); + } + (VOID)memcpy_s(&tmpInfo->info, sizeof(siginfo_t), info, sizeof(siginfo_t)); + return LOS_OK; +} + +STATIC VOID DeleteSigInfoFromList(OsSigCB *sigCB, INT32 sigNo) +{ + OsSigInfoNode *tmpInfo = NULL; + BOOL findFlag = FALSE; + + LOS_DL_LIST_FOR_EACH_ENTRY(tmpInfo, &sigCB->sigInfoList, OsSigInfoNode, node) { + if (tmpInfo->info.si_signo == sigNo) { + LOS_ListDelete(&tmpInfo->node); + findFlag = TRUE; + break; + } + } + + if (findFlag == TRUE) { + (VOID)memcpy_s(&sigCB->sigInfo, sizeof(siginfo_t), &tmpInfo->info, sizeof(siginfo_t)); + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, tmpInfo); + } +} + +STATIC VOID SignalHandle(LosTaskCB *task, BOOL cleanStatus) +{ + UINT32 intSave; + OsSigCB *sigCB = NULL; + + intSave = LOS_IntLock(); + sigCB = task->sig; + if (sigCB == NULL) { + LOS_IntRestore(intSave); + return; + } + + while (sigCB->sigPendFlag & sigCB->sigSetFlag) { + UINT32 sigFlag = sigCB->sigPendFlag & sigCB->sigSetFlag; + INT32 sigNo = LOS_SIGNAL_SUPPORT_MAX - CLZ(sigFlag) + 1; + DeleteSigInfoFromList(sigCB, sigNo); + + SIG_HANDLER handler = sigCB->sigHandlers[sigNo - 1]; + sigCB->sigPendFlag &= ~LOS_SIGNAL_MASK(sigNo); + LOS_IntRestore(intSave); + + if (handler != NULL) { + handler(sigNo); + } + intSave = LOS_IntLock(); + + if (cleanStatus == TRUE) { + task->taskStatus &= ~OS_TASK_FLAG_SIGNAL; + } + } + LOS_IntRestore(intSave); +} + +STATIC VOID SignalEntry(INT32 sigNo) +{ + LosTaskCB *task = OsCurrTaskGet(); + OsSigCB *sigCB = (OsSigCB *)task->sig; + + SignalHandle(task, FALSE); + + task->stackPointer = sigCB->sigSaveSP; + sigCB->sigSaveSP = NULL; + sigCB->sigRestoreSP = task->stackPointer; + task->taskStatus &= ~OS_TASK_FLAG_SIGNAL; + + LOS_Schedule(); +} + +STATIC VOID SignalSend(LosTaskCB *task, INT32 sigNo) +{ + UINT32 intSave; + OsSigCB *sigCB = NULL; + sigset_t mask = LOS_SIGNAL_MASK(sigNo); + + intSave = LOS_IntLock(); + sigCB = task->sig; + if (sigCB == NULL) { + LOS_IntRestore(intSave); + return; + } + + if (!(sigCB->sigPendFlag & mask)) { + sigCB->sigPendFlag |= mask; + } + + if (task == OsCurrTaskGet()) { + task->taskStatus |= OS_TASK_FLAG_SIGNAL; + LOS_IntRestore(intSave); + + if (!OS_INT_ACTIVE) { + SignalHandle(task, TRUE); + } + } else { + if (sigCB->sigStatus & OS_SIGNAL_STATUS_WAIT) { + if (sigCB->sigWaitFlag & LOS_SIGNAL_MASK(sigNo)) { + DeleteSigInfoFromList(sigCB, sigNo); + OsSchedTaskWake(task); + task->taskStatus |= OS_TASK_FLAG_SIGNAL; + } + } else if (!(task->taskStatus & OS_TASK_FLAG_SIGNAL)) { + task->taskStatus |= OS_TASK_FLAG_SIGNAL; + sigCB->sigSaveSP = task->stackPointer; + sigCB->sigRestoreSP = NULL; + task->stackPointer = ArchSignalContextInit(task->stackPointer, (VOID *)task->topOfStack, + (UINTPTR)SignalEntry, sigNo); + } + LOS_IntRestore(intSave); + LOS_Schedule(); + } +} + +STATIC OsSigCB *SignalCBInit(LosTaskCB *task) +{ + OsSigCB *sigCB = NULL; + UINT32 i; + + if (task->sig == NULL) { + sigCB = (OsSigCB *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(OsSigCB)); + if (sigCB == NULL) { + return NULL; + } + (VOID)memset_s(sigCB, sizeof(OsSigCB), 0, sizeof(OsSigCB)); + LOS_ListInit(&sigCB->sigInfoList); + + for (i = 0; i <= LOS_SIGNAL_SUPPORT_MAX; i++) { + sigCB->sigHandlers[i] = SignalDefaultHandler; + } + + task->sig = (VOID *)sigCB; + } else { + sigCB = (OsSigCB *)task->sig; + } + + return sigCB; +} + +SIG_HANDLER LOS_SignalSet(INT32 sigNo, SIG_HANDLER handler) +{ + UINT32 intSave; + SIG_HANDLER old = NULL; + LosTaskCB *task = OsCurrTaskGet(); + OsSigCB *sigCB = NULL; + + if (task == NULL) { + return SIG_ERR; + } + + if (!OS_SIGNAL_VALID(sigNo)) { + return SIG_ERR; + } + + intSave = LOS_IntLock(); + sigCB = SignalCBInit(task); + if (sigCB == NULL) { + LOS_IntRestore(intSave); + return SIG_ERR; + } + + old = sigCB->sigHandlers[sigNo - 1]; /* signal number from 1, but index from 0 */ + if (handler == SIG_IGN) { + sigCB->sigHandlers[sigNo - 1] = NULL; + sigCB->sigSetFlag &= ~LOS_SIGNAL_MASK(sigNo); + } else if (handler == SIG_DFL) { + sigCB->sigHandlers[sigNo - 1] = SignalDefaultHandler; + sigCB->sigSetFlag |= LOS_SIGNAL_MASK(sigNo); + } else { + sigCB->sigHandlers[sigNo - 1] = handler; + sigCB->sigSetFlag |= LOS_SIGNAL_MASK(sigNo); + } + LOS_IntRestore(intSave); + + return old; +} + +UINT32 LOS_SignalMask(INT32 how, const sigset_t *set, sigset_t *oldSet) +{ + UINT32 intSave; + LosTaskCB *task = OsCurrTaskGet(); + OsSigCB *sigCB = NULL; + + if (task == NULL) { + return LOS_ERRNO_SIGNAL_CAN_NOT_CALL; + } + + intSave = LOS_IntLock(); + sigCB = SignalCBInit(task); + if (sigCB == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SIGNAL_NO_MEMORY; + } + + if (oldSet != NULL) { + *oldSet = sigCB->sigSetFlag; + } + + if (set == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SIGNAL_INVALID; + } + + switch (how) { + case SIG_BLOCK: + sigCB->sigSetFlag &= ~*set; + break; + case SIG_SETMASK: + sigCB->sigSetFlag = *set; + break; + case SIG_UNBLOCK: + sigCB->sigSetFlag |= *set; + break; + default: + PRINT_ERR("The error parameter how = %d\n", how); + break; + } + LOS_IntRestore(intSave); + + return LOS_OK; +} + +STATIC INLINE UINT32 SignalTimedWait(LosTaskCB *task, const sigset_t *set, UINT32 timeout, UINT32 *intSave) +{ + OsSigCB *sigCB = (OsSigCB *)task->sig; + INT32 sigNo; + + if (timeout == 0) { + LOS_IntRestore(*intSave); + return LOS_ERRNO_SIGNAL_INVALID; + } + + if (OS_INT_ACTIVE) { + LOS_IntRestore(*intSave); + return LOS_ERRNO_SIGNAL_PEND_INTERR; + } + + sigCB->sigWaitFlag |= *set; + sigCB->sigStatus |= OS_SIGNAL_STATUS_WAIT; + + OsSchedTaskWait(&g_waitSignalList, timeout); + LOS_IntRestore(*intSave); + LOS_Schedule(); + + *intSave = LOS_IntLock(); + task->taskStatus &= ~OS_TASK_FLAG_SIGNAL; + sigCB->sigStatus &= ~OS_SIGNAL_STATUS_WAIT; + sigCB->sigWaitFlag = 0; + if (task->taskStatus & OS_TASK_STATUS_TIMEOUT) { + task->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + LOS_IntRestore(*intSave); + return LOS_ERRNO_SIGNAL_TIMEOUT; + } + sigNo = sigCB->sigInfo.si_signo; + sigCB->sigPendFlag &= ~LOS_SIGNAL_MASK(sigNo); + return sigNo; +} + +UINT32 LOS_SignalWait(const sigset_t *set, siginfo_t *info, UINT32 timeout) +{ + UINT32 intSave; + LosTaskCB *task = OsCurrTaskGet(); + OsSigCB *sigCB = NULL; + sigset_t sigFlag; + INT32 sigNo; + + if ((set == NULL) || (*set == 0)) { + return LOS_ERRNO_SIGNAL_INVALID; + } + + if (task == NULL) { + return LOS_ERRNO_SIGNAL_CAN_NOT_CALL; + } + + intSave = LOS_IntLock(); + sigCB = SignalCBInit(task); + if (sigCB == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SIGNAL_NO_MEMORY; + } + + sigFlag = sigCB->sigPendFlag & *set; + if (sigFlag) { + sigCB->sigPendFlag ^= sigFlag; + sigNo = LOS_SIGNAL_SUPPORT_MAX - CLZ(sigFlag) + 1; + DeleteSigInfoFromList(sigCB, sigNo); + } else { + sigNo = SignalTimedWait(task, set, timeout, &intSave); + if (sigNo > LOS_SIGNAL_SUPPORT_MAX) { + LOS_IntRestore(intSave); + return sigNo; + } + } + + if (info != NULL) { + (VOID)memcpy_s(info, sizeof(siginfo_t), &sigCB->sigInfo, sizeof(siginfo_t)); + } + LOS_IntRestore(intSave); + + return sigNo; +} + +UINT32 LOS_SignalSend(UINT32 taskID, INT32 sigNo) +{ + siginfo_t info; + UINT32 intSave; + OsSigCB *sigCB = NULL; + LosTaskCB *task = NULL; + + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return LOS_ERRNO_SIGNAL_INVALID; + } + + if (!OS_SIGNAL_VALID(sigNo)) { + return LOS_ERRNO_SIGNAL_INVALID; + } + + info.si_signo = sigNo; + info.si_code = SI_USER; + info.si_value.sival_ptr = NULL; + + intSave = LOS_IntLock(); + task = OS_TCB_FROM_TID(taskID); + sigCB = SignalCBInit(task); + if (sigCB == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SIGNAL_NO_MEMORY; + } + + if (!(sigCB->sigSetFlag & LOS_SIGNAL_MASK(sigNo))) { /* the signal has not been set */ + LOS_IntRestore(intSave); + return LOS_ERRNO_SIGNAL_NO_SET; + } + + UINT32 ret = AddSigInfoToList(sigCB, &info); + if (ret != LOS_OK) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SIGNAL_NO_MEMORY; + } + LOS_IntRestore(intSave); + + /* send signal to this thread */ + SignalSend(task, sigNo); + + return LOS_OK; +} + +UINT32 OsSignalInit(VOID) +{ + LOS_ListInit(&g_waitSignalList); + return LOS_OK; +} +#endif \ No newline at end of file diff --git a/components/signal/los_signal.h b/components/signal/los_signal.h new file mode 100644 index 00000000..b076aef5 --- /dev/null +++ b/components/signal/los_signal.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_SIGNAL_H +#define _LOS_SIGNAL_H + +#include +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_signal + * Signal error code: The parameters of interface is error. + * + * Value: 0x02003200 + * + */ +#define LOS_ERRNO_SIGNAL_INVALID LOS_ERRNO_OS_FATAL(LOS_MOD_SIGNAL, 0x00) + +/** + * @ingroup los_signal + * Signal error code: The memory requests failed. + * + * Value: 0x02003201 + * + */ +#define LOS_ERRNO_SIGNAL_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SIGNAL, 0x01) + +/** + * @ingroup los_signal + * Signal error code: The signal is not set. + * + * Value: 0x02003202 + * + */ +#define LOS_ERRNO_SIGNAL_NO_SET LOS_ERRNO_OS_ERROR(LOS_MOD_SIGNAL, 0x02) + +/** + * @ingroup los_signal + * Signal error code: Waiting for signal timeout. + * + * Value: 0x02003203 + * + */ +#define LOS_ERRNO_SIGNAL_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_SIGNAL, 0x03) + +/** + * @ingroup los_signal + * Signal error code: The interface is used before system start. + * + * Value: 0x02003204 + * + */ +#define LOS_ERRNO_SIGNAL_CAN_NOT_CALL LOS_ERRNO_OS_ERROR(LOS_MOD_SIGNAL, 0x04) + +/** +* @ingroup los_signal +* Mutex error code: Waiting for signal in interrupt callback. +* +* Value: 0x02003205 +* +*/ +#define LOS_ERRNO_SIGNAL_PEND_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_SIGNAL, 0x05) + +/** + * @ingroup los_signal + * Add the signal num to the signal set. + */ +#define LOS_SIGNAL_MASK(sigNo) (1U << ((sigNo) - 1)) + +/** + * @ingroup los_signal + * Maximum signal supported num. + */ +#define LOS_SIGNAL_SUPPORT_MAX 31 + +/** + * @ingroup los_signal + * Signal handler type. + */ +typedef VOID (*SIG_HANDLER)(INT32 sigNo); + +typedef struct { + sigset_t sigSetFlag; /**< installing signals */ + sigset_t sigPendFlag; /**< pending signals */ + sigset_t sigWaitFlag; /**< waiting signals */ + siginfo_t sigInfo; /**< signal info */ + SIG_HANDLER sigHandlers[LOS_SIGNAL_SUPPORT_MAX + 1]; /**< signal handler */ + LOS_DL_LIST sigInfoList; /**< signal info list */ + VOID *sigSaveSP; /**< save stack pointer */ + VOID *sigRestoreSP; /**< restore stack pointer */ + UINT32 sigStatus; /**< status of signal */ +} OsSigCB; + +typedef struct { + LOS_DL_LIST node; + siginfo_t info; +} OsSigInfoNode; + +#define OS_SIGNAL_STATUS_WAIT 0x0001 +#define OS_SIGNAL_VALID(sigNo) (((sigNo) > 0) && ((sigNo) <= LOS_SIGNAL_SUPPORT_MAX)) + +UINT32 OsSignalInit(VOID); +UINTPTR OsSignalTaskContextRestore(VOID); + +/** + * @ingroup los_signal + * @brief Register the handler for the specified signal. + * + * @par Description: + * This API is used to register the handler for the specified signal, otherwise it is the default handler. + * + * @attention None. + * + * @param sigNo [IN] The specified signal num. + * @param handler [IN] The handler for this signal, which is either SIG_IGN, SIG_DFL, + * or the address of a programmer-defined function. + * + * @retval: SIG_ERR Type#SIG_HANDLER: error code. + * @retval: old Type#SIG_HANDLER: success, the previous handler is returned. + *
  • los_signal.h: the header file that contains the API declaration.
+ * @see None + */ +SIG_HANDLER LOS_SignalSet(INT32 sigNo, SIG_HANDLER handler); + +/** + * @ingroup los_signal + * @brief Shield the specified signal set. + * + * @par Description: + * This API is used to shield the specified signal set and get the current signal set. + * + * @attention None. + * + * @param how [IN] The behavior of the call is dependent on the value of how, which is either SIG_BLOCK, + * SIG_UNBLOCK, SIG_SETMASK. + * @param set [IN] The new signal set. + * @param oldSet [OUT] The old signal set. + * + * @retval: LOS_ERRNO_SIGNAL_CAN_NOT_CALL Type#UINT32: The interface is used before system start. + * @retval: LOS_ERRNO_SIGNAL_NO_MEMORY Type#UINT32: The memory requests failed. + * @retval: LOS_ERRNO_SIGNAL_INVALID Type#UINT32: The parameters of interface is error. + * @retval: LOS_OK Type#UINT32: success. + *
  • los_signal.h: the header file that contains the API declaration.
+ * @see None + */ +UINT32 LOS_SignalMask(INT32 how, const sigset_t *set, sigset_t *oldSet); + +/** + * @ingroup los_signal + * @brief Suspend execution of the calling thread until one of the signals specified in + * the signal set becomes pending. + * + * @par Description: + * This API is used to suspend execution of the calling thread until one of the signals + * specified in the signal set becomes pending and return the signal number in sig. + * + * @attention None. + * + * @param set [IN] The specified signal set which waiting for. + * @param info [OUT] The info of signal becomes pending. + * @param timeout [IN] The waiting time. + * + * @retval: LOS_ERRNO_SIGNAL_INVALID Type#UINT32: The parameters of interface is error. + * @retval: LOS_ERRNO_SIGNAL_CAN_NOT_CALL Type#UINT32: The interface is used before system start. + * @retval: LOS_ERRNO_SIGNAL_NO_MEMORY Type#UINT32: The memory requests failed. + * @retval: LOS_ERRNO_SIGNAL_PEND_INTERR Type#UINT32: Waiting for signal in interrupt callback. + * @retval: LOS_ERRNO_SIGNAL_TIMEOUT Type#UINT32: Waiting for signal timeout. + * @retval: signo Type#UINT32: success, returning the signal num which becomes pending. + *
  • los_signal.h: the header file that contains the API declaration.
+ * @see LOS_SignalSend + */ +UINT32 LOS_SignalWait(const sigset_t *set, siginfo_t *info, UINT32 timeout); + +/** + * @ingroup los_signal + * @brief Send the specified signal to the specified task. + * + * @par Description: + * This API is used to send the specified signal to the specified task. + * + * @attention None. + * + * @param taskID [IN] Send a signal to this task. + * @param sigNo [IN] The signal num. + * + * @retval: LOS_ERRNO_SIGNAL_NO_MEMORY Type#UINT32: The memory requests failed. + * @retval: LOS_ERRNO_SIGNAL_INVALID Type#UINT32: The parameters of interface is error. + * @retval: LOS_ERRNO_SIGNAL_NO_SET Type#UINT32: The signal is not set. + * @retval: LOS_OK Type#UINT32: success. + *
  • los_signal.h: the header file that contains the API declaration.
+ * @see None + */ +UINT32 LOS_SignalSend(UINT32 taskID, INT32 sigNo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SIGNAL_H */ \ No newline at end of file diff --git a/kal/posix/BUILD.gn b/kal/posix/BUILD.gn index 1f766e06..11fbcfe9 100644 --- a/kal/posix/BUILD.gn +++ b/kal/posix/BUILD.gn @@ -63,6 +63,10 @@ kernel_module(module_name) { sources += [ "src/pipe.c" ] sources += [ "src/poll.c" ] } + + if (defined(LOSCFG_POSIX_SIGNAL_API)) { + sources += [ "src/signal.c" ] + } } config("public") { diff --git a/kal/posix/Kconfig b/kal/posix/Kconfig index 5c4877ce..dcf32c15 100644 --- a/kal/posix/Kconfig +++ b/kal/posix/Kconfig @@ -66,4 +66,11 @@ config POSIX_PIPE_API help Answer Y to enable LiteOS support POSIX Pipe API. +config POSIX_SIGNAL_API + bool "Enable POSIX Signal API" + default n + depends on KERNEL_SIGNAL + help + Answer Y to enable LiteOS support POSIX Signal API. + endif # POSIX_API diff --git a/kal/posix/src/pipe.c b/kal/posix/src/pipe.c index 0950b242..845b5450 100644 --- a/kal/posix/src/pipe.c +++ b/kal/posix/src/pipe.c @@ -28,6 +28,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include "securec.h" #include "los_fs.h" #include "los_list.h" @@ -262,7 +264,7 @@ STATIC INT32 PipeDevRegister(CHAR *devName, UINT32 len) LOS_ListAdd(&g_devList, &dev->list); (VOID)LOS_MuxPost(g_devListMutex); - return ENOERR; + return 0; ERROR: if (dev != NULL) { (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev); @@ -303,7 +305,7 @@ STATIC INT32 PipeDevUnregister(struct PipeDev *dev) dev->ringBuffer = NULL; (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev); - return ENOERR; + return 0; } STATIC INT32 PipeDevFdAlloc(VOID) @@ -469,7 +471,7 @@ INT32 PipeClose(INT32 fd) PIPE_DEV_UNLOCK(dev->mutex); } - return ENOERR; + return 0; ERROR: (VOID)LOS_MuxPost(g_devFdMutex); return -1; @@ -677,7 +679,7 @@ int pipe(int filedes[2]) filedes[0] = open(devName, O_RDONLY); filedes[1] = open(devName, O_WRONLY); - return ENOERR; + return 0; } UINT32 OsPipeInit(VOID) diff --git a/kal/posix/src/signal.c b/kal/posix/src/signal.c new file mode 100644 index 00000000..dd8dc1f2 --- /dev/null +++ b/kal/posix/src/signal.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "los_config.h" +#include "los_signal.h" +#include "los_task.h" +#include "los_tick.h" + +#if (LOSCFG_KERNEL_SIGNAL == 1) + +static inline unsigned int TimeSpec2Tick(const struct timespec *tp) +{ + unsigned long long tick, ns; + + ns = (unsigned long long)tp->tv_sec * OS_SYS_NS_PER_SECOND + tp->tv_nsec; + /* round up for ticks */ + tick = (ns * LOSCFG_BASE_CORE_TICK_PER_SECOND + (OS_SYS_NS_PER_SECOND - 1)) / OS_SYS_NS_PER_SECOND; + if (tick > LOS_WAIT_FOREVER) { + tick = LOS_WAIT_FOREVER; + } + return (unsigned int)tick; +} + +int raise(int sig) +{ + unsigned int ret = LOS_SignalSend(LOS_CurTaskIDGet(), sig); + if (ret != LOS_OK) { + return -1; + } + + return 0; +} + +void (*signal(int sig, void (*func)(int)))(int) +{ + SIG_HANDLER h = NULL; + + if (!OS_SIGNAL_VALID(sig)) { + errno = EINVAL; + return SIG_ERR; + } + + h = LOS_SignalSet(sig, func); + if (h == SIG_ERR) { + errno = EINVAL; + } + return h; +} + +int sigemptyset(sigset_t *set) +{ + if (set == NULL) { + errno = EINVAL; + return -1; + } + + *set = 0; + return 0; +} + +int sigfillset(sigset_t *set) +{ + if (set == NULL) { + errno = EINVAL; + return -1; + } + + *set = ~0; + return 0; +} + +int sigaddset(sigset_t *set, int sig) +{ + if ((set == NULL) || !OS_SIGNAL_VALID(sig)) { + errno = EINVAL; + return -1; + } + + *set |= LOS_SIGNAL_MASK(sig); + return 0; +} + +int sigdelset(sigset_t *set, int sig) +{ + if ((set == NULL) || !OS_SIGNAL_VALID(sig)) { + errno = EINVAL; + return -1; + } + + *set &= ~LOS_SIGNAL_MASK(sig); + return 0; +} + +int sigismember(const sigset_t *set, int sig) +{ + if ((set == NULL) || !OS_SIGNAL_VALID(sig)) { + errno = EINVAL; + return -1; + } + + return ((*set & LOS_SIGNAL_MASK(sig)) != 0); +} + +int sigprocmask(int how, const sigset_t *set, sigset_t *oset) +{ + unsigned int ret = LOS_SignalMask(how, set, oset); + if (ret != LOS_OK) { + errno = EINVAL; + return -1; + } + return 0; +} + +int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) +{ + SIG_HANDLER old = NULL; + + if (!OS_SIGNAL_VALID(sig)) { + errno = EINVAL; + return -1; + } + + if (act != NULL) { + old = LOS_SignalSet(sig, act->sa_handler); + } else { + old = LOS_SignalSet(sig, NULL); + (void)LOS_SignalSet(sig, old); + } + + if (oldact != NULL) { + oldact->sa_handler = old; + } + + return 0; +} + +int sigwait(const sigset_t *set, int *sig) +{ + siginfo_t info = {0}; + + int ret = LOS_SignalWait(set, &info, 0); + if (ret < 0) { + errno = EINVAL; + return -1; + } + + *sig = info.si_signo; + return 0; +} + +int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) +{ + int tick = LOS_WAIT_FOREVER; + int ret; + + if (timeout != NULL) { + tick = TimeSpec2Tick(timeout); + } + + ret = LOS_SignalWait(set, info, tick); + if (ret == LOS_OK) { + return 0; + } else { + if (ret == LOS_ERRNO_SIGNAL_PEND_INTERR) { + errno = EINTR; + } else if (ret == LOS_ERRNO_SIGNAL_TIMEOUT) { + errno = EAGAIN; + } else { + errno = EINVAL; + } + return -1; + } +} + +int sigwaitinfo(const sigset_t *set, siginfo_t *info) +{ + return sigtimedwait(set, info, NULL); +} + +int pthread_kill(pthread_t pid, int sig) +{ + unsigned int ret = LOS_SignalSend((unsigned int)pid, sig); + if (ret != LOS_OK) { + errno = EINVAL; + return -1; + } + + return 0; +} + +int kill(pid_t pid, int sig) +{ + unsigned int ret = LOS_SignalSend((unsigned int)pid, sig); + if (ret != LOS_OK) { + errno = EINVAL; + return -1; + } + + return 0; +} +#endif diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h index ed337b15..9b4c01a3 100644 --- a/kernel/include/los_config.h +++ b/kernel/include/los_config.h @@ -651,12 +651,10 @@ extern UINT8 *m_aucSysMem0; /** * @ingroup los_config - * Configuration item to enable pipe device. + * Configuration item to enable kernel signal. */ -#ifndef LOSCFG_POSIX_PIPE_API -#ifndef LOSCFG_PIPE_DEV -#define LOSCFG_POSIX_PIPE_API 0 -#endif +#ifndef LOSCFG_KERNEL_SIGNAL +#define LOSCFG_KERNEL_SIGNAL 0 #endif #ifdef __cplusplus diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h index f1cf6c5e..52f3312d 100644 --- a/kernel/include/los_task.h +++ b/kernel/include/los_task.h @@ -430,6 +430,16 @@ extern "C" { */ #define LOS_ERRNO_TSK_SCHED_LOCKED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x28) +/** + * @ingroup los_task + * Task error code: The task is processing signals. + * + * Value: 0x02000229 + * + * Solution: Check and Stop the trigger signal so that the task is not processing the signal. + */ +#define LOS_ERRNO_TSK_PROCESS_SIGNAL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x29) + /** * @ingroup los_task * Define the type of the task entry function. @@ -1293,6 +1303,13 @@ extern UINT32 LOS_TaskDetach(UINT32 taskID); */ #define OS_TASK_FLAG_SYSTEM_TASK 0x1000U +/** + * @ingroup los_task + * Flag that indicates the task is processing signal. + * + */ +#define OS_TASK_FLAG_SIGNAL 0x2000 + /** * @ingroup los_task * Flag that indicates the task or task control block status. @@ -1480,6 +1497,9 @@ typedef struct { UINT32 eventMode; /**< Event mode */ VOID *msg; /**< Memory allocated to queues */ INT32 errorNo; +#if (LOSCFG_KERNEL_SIGNAL == 1) + VOID *sig; /**< Task signal */ +#endif LOSCFG_TASK_STRUCT_EXTENSION /**< Task extension field */ } LosTaskCB; @@ -1754,6 +1774,11 @@ extern VOID *OsTskUserStackInit(VOID* stackPtr, VOID* userSP, UINT32 userStackSi extern UINT32 OsPmEnterHandlerSet(VOID (*func)(VOID)); +STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) +{ + return g_losTask.runTask; +} + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/src/los_init.c b/kernel/src/los_init.c index 2a47fc88..012cf2db 100644 --- a/kernel/src/los_init.c +++ b/kernel/src/los_init.c @@ -78,6 +78,10 @@ #include "pipe_impl.h" #endif +#if (LOSCFG_KERNEL_SIGNAL == 1) +#include "los_signal.h" +#endif + /***************************************************************************** Function : LOS_Reboot Description : system exception, die in here, wait for watchdog. @@ -250,6 +254,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID) } #endif +#if (LOSCFG_KERNEL_SIGNAL == 1) + ret = OsSignalInit(); + if (ret != LOS_OK) { + PRINT_ERR("Signal init failed!\n"); + return ret; + } +#endif + return LOS_OK; } diff --git a/kernel/src/los_task.c b/kernel/src/los_task.c index 4fe63c1f..50d08f5a 100644 --- a/kernel/src/los_task.c +++ b/kernel/src/los_task.c @@ -683,7 +683,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S * taskCB->eventMask = 0; taskCB->taskName = taskInitParam->pcName; taskCB->msg = NULL; - taskCB->stackPointer = ArchTskStackInit(taskCB->taskID, taskInitParam->uwStackSize, topOfStack); +#if (LOSCFG_KERNEL_SIGNAL == 1) + taskCB->sig = NULL; +#endif + SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME); LOS_EventInit(&(taskCB->event)); @@ -691,6 +694,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S * taskCB->taskStatus |= OS_TASK_FLAG_JOINABLE; LOS_ListInit(&taskCB->joinList); } + + *((UINT32 *)taskCB->topOfStack) = OS_TASK_MAGIC_WORD; + taskCB->stackPointer = ArchTskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack); + return LOS_OK; } @@ -744,6 +751,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S LOS_IntRestore(intSave); return LOS_ERRNO_TSK_NO_MEMORY; } + /* initialize the task stack, write magic num to stack top */ + (VOID)memset_s(topOfStack, taskInitParam->uwStackSize, + (INT32)(OS_TASK_STACK_INIT & 0xFF), taskInitParam->uwStackSize); retVal = OsNewTaskInit(taskCB, taskInitParam, topOfStack); if (retVal != LOS_OK) { @@ -1066,6 +1076,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) return LOS_ERRNO_TSK_ALREADY_EXIT; } + if (taskCB->taskStatus & OS_TASK_FLAG_SIGNAL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_PROCESS_SIGNAL; + } + /* If the task is running and scheduler is locked then you can not delete it */ if (((taskCB->taskStatus) & OS_TASK_STATUS_RUNNING) && (g_losTaskLock != 0)) { PRINT_INFO("In case of task lock, task deletion is not recommended\n"); @@ -1084,6 +1099,13 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) (VOID)memset_s((VOID *)&g_cpup[taskCB->taskID], sizeof(OsCpupCB), 0, sizeof(OsCpupCB)); #endif +#if (LOSCFG_KERNEL_SIGNAL == 1) + if (taskCB->sig != NULL) { + LOS_MemFree(OS_SYS_MEM_ADDR, taskCB->sig); + taskCB->sig = NULL; + } +#endif + LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB); if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { diff --git a/testsuites/BUILD.gn b/testsuites/BUILD.gn index 525d4f6f..dad5f6c8 100644 --- a/testsuites/BUILD.gn +++ b/testsuites/BUILD.gn @@ -76,6 +76,9 @@ group("testsuites") { if (defined(LOSCFG_KERNEL_LMK)) { deps += [ "sample/kernel/lmk:test_lmk" ] } + if (defined(LOSCFG_KERNEL_SIGNAL)) { + deps += [ "sample/kernel/signal:test_signal" ] + } if (!module_switch) { deps = [] } diff --git a/testsuites/include/osTest.h b/testsuites/include/osTest.h index 27fab219..23e6eace 100644 --- a/testsuites/include/osTest.h +++ b/testsuites/include/osTest.h @@ -88,6 +88,7 @@ extern "C" { #define LOS_KERNEL_PM_TEST 1 #define LOS_KERNEL_LMS_TEST 0 #define LOS_KERNEL_LMK_TEST 0 +#define LOS_KERNEL_SIGNAL_TEST 0 #define LITEOS_CMSIS_TEST 0 #define LOS_CMSIS2_CORE_TASK_TEST 0 @@ -344,6 +345,7 @@ extern VOID ItSuiteLosDynlink(void); extern VOID ItSuite_Los_FatFs(void); extern VOID ItSuiteLosPm(void); extern VOID ItSuiteLosLmk(void); +extern VOID ItSuiteLosSignal(void); extern VOID ItSuite_Cmsis_Lostask(void); extern VOID ItSuite_Cmsis_Lostask_add(void); diff --git a/testsuites/sample/kernel/signal/BUILD.gn b/testsuites/sample/kernel/signal/BUILD.gn new file mode 100644 index 00000000..a33822e1 --- /dev/null +++ b/testsuites/sample/kernel/signal/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("test_signal") { + sources = [ + "It_los_signal.c", + "It_los_signal_001.c", + "It_los_signal_002.c", + "It_los_signal_003.c", + "It_los_signal_004.c", + "It_los_signal_005.c", + ] + + configs += [ "//kernel/liteos_m/testsuites:include" ] +} diff --git a/testsuites/sample/kernel/signal/It_los_signal.c b/testsuites/sample/kernel/signal/It_los_signal.c new file mode 100644 index 00000000..c275709a --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_signal.h" + +void ItSuiteLosSignal(void) +{ + ItLosSignal001(); + ItLosSignal002(); + ItLosSignal003(); + ItLosSignal004(); + ItLosSignal005(); +} diff --git a/testsuites/sample/kernel/signal/It_los_signal.h b/testsuites/sample/kernel/signal/It_los_signal.h new file mode 100644 index 00000000..32b62c2d --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "osTest.h" +#include "los_signal.h" + +#ifndef IT_LOS_SIGNAL_H +#define IT_LOS_SIGNAL_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +void ItLosSignal001(void); +void ItLosSignal002(void); +void ItLosSignal003(void); +void ItLosSignal004(void); +void ItLosSignal005(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* IT_LOS_SIGNAL_H */ + diff --git a/testsuites/sample/kernel/signal/It_los_signal_001.c b/testsuites/sample/kernel/signal/It_los_signal_001.c new file mode 100644 index 00000000..8deee6a4 --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal_001.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_signal.h" +#include "los_task.h" + +STATIC volatile INT32 g_sigValue = -1; + +STATIC VOID SigHandler(INT32 sig) +{ + g_sigValue = sig; +} + +static UINT32 Testcase(VOID) +{ + SIG_HANDLER h = NULL; + UINT32 ret; + + h = LOS_SignalSet(0, SigHandler); + ICUNIT_ASSERT_EQUAL(h, SIG_ERR, h); + + h = LOS_SignalSet(LOS_SIGNAL_SUPPORT_MAX + 1, SigHandler); + ICUNIT_ASSERT_EQUAL(h, SIG_ERR, h); + + h = LOS_SignalSet(SIGUSR1, SIG_DFL); + ICUNIT_ASSERT_NOT_EQUAL(h, SIG_ERR, h); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_sigValue, -1, g_sigValue); + + h = LOS_SignalSet(SIGUSR1, SigHandler); + ICUNIT_ASSERT_NOT_EQUAL(h, SIG_ERR, h); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_sigValue, SIGUSR1, g_sigValue); + g_sigValue = -1; + + h = LOS_SignalSet(SIGUSR1, SIG_IGN); + ICUNIT_ASSERT_NOT_EQUAL(h, SIG_ERR, h); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SIGNAL_NO_SET, ret); + ICUNIT_ASSERT_EQUAL(g_sigValue, -1, g_sigValue); + + return LOS_OK; +} + +VOID ItLosSignal001(VOID) +{ + TEST_ADD_CASE("ItLosSignal001", Testcase, TEST_LOS, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/sample/kernel/signal/It_los_signal_002.c b/testsuites/sample/kernel/signal/It_los_signal_002.c new file mode 100644 index 00000000..6686f1e1 --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal_002.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_signal.h" +#include "los_task.h" + +STATIC volatile INT32 g_sigValue1 = -1; +STATIC volatile INT32 g_sigValue2 = -1; + +STATIC VOID SigHandler1(INT32 sig) +{ + g_sigValue1 = sig; +} + +STATIC VOID SigHandler2(INT32 sig) +{ + g_sigValue2 = sig; +} + +STATIC UINT32 Testcase(VOID) +{ + SIG_HANDLER h = NULL; + UINT32 ret; + + h = LOS_SignalSet(SIGUSR1, SigHandler1); + ICUNIT_ASSERT_NOT_EQUAL(h, SIG_ERR, h); + + h = LOS_SignalSet(SIGUSR2, SigHandler2); + ICUNIT_ASSERT_NOT_EQUAL(h, SIG_ERR, h); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_sigValue1, SIGUSR1, g_sigValue1); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_sigValue2, SIGUSR2, g_sigValue2); + + return LOS_OK; +} + +VOID ItLosSignal002(VOID) +{ + TEST_ADD_CASE("ItLosSignal002", Testcase, TEST_LOS, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/sample/kernel/signal/It_los_signal_003.c b/testsuites/sample/kernel/signal/It_los_signal_003.c new file mode 100644 index 00000000..5fd9bd48 --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal_003.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_signal.h" +#include "los_task.h" + +STATIC volatile INT32 g_sigValue1 = -1; +STATIC volatile INT32 g_sigValue2 = -1; +STATIC UINT32 g_task1End = 0; +STATIC UINT32 g_task2End = 0; + +STATIC VOID SigHandler1(INT32 sig) +{ + g_sigValue1 = sig; +} + +STATIC VOID SigHandler2(INT32 sig) +{ + g_sigValue2 = sig; +} + +STATIC VOID TaskF01(VOID) +{ + LOS_SignalSet(SIGUSR1, SigHandler1); + + while (g_sigValue1 != SIGUSR1) { + LOS_TaskDelay(1); + } + + g_task1End = 1; +} + +STATIC VOID TaskF02(VOID) +{ + LOS_SignalSet(SIGUSR2, SigHandler2); + + while (g_sigValue2 != SIGUSR2) { + LOS_TaskDelay(1); + } + + g_task2End = 1; +} + +STATIC UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S task = {0}; + UINT32 taskID1, taskID2; + UINT32 ret; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "Signal1"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + + ret = LOS_TaskCreate(&taskID1, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF02; + task.pcName = "Signal2"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + + ret = LOS_TaskCreate(&taskID2, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SignalSend(taskID1, SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_sigValue1, SIGUSR1, g_sigValue1); + ICUNIT_ASSERT_EQUAL(g_task1End, 1, g_task1End); + + ret = LOS_SignalSend(taskID2, SIGUSR2); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + LOS_TaskDelay(10); + ICUNIT_ASSERT_EQUAL(g_sigValue2, SIGUSR2, g_sigValue2); + ICUNIT_ASSERT_EQUAL(g_task2End, 1, g_task2End); + + return LOS_OK; +} + +VOID ItLosSignal003(VOID) +{ + TEST_ADD_CASE("ItLosSignal003", Testcase, TEST_LOS, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/sample/kernel/signal/It_los_signal_004.c b/testsuites/sample/kernel/signal/It_los_signal_004.c new file mode 100644 index 00000000..dc4c5b0a --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal_004.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_signal.h" +#include "los_task.h" + +STATIC UINT32 g_taskErrorFlag = 0; +STATIC UINT32 g_taskEnd = 0; + + +STATIC VOID TaskF01(VOID) +{ + UINT32 ret; + sigset_t set = LOS_SIGNAL_MASK(SIGUSR1); + siginfo_t info = {0}; + + LOS_SignalSet(SIGUSR1, SIG_DFL); + + ret = LOS_SignalWait(&set, &info, 10); + if (ret != LOS_ERRNO_SIGNAL_TIMEOUT) { + g_taskErrorFlag = ret; + return; + } + + ret = LOS_SignalWait(&set, &info, LOS_WAIT_FOREVER); + if (ret != SIGUSR1) { + g_taskErrorFlag = ret; + return; + } + + g_taskEnd = 1; +} + +STATIC UINT32 Testcase(VOID) +{ + TSK_INIT_PARAM_S task = {0}; + UINT32 taskID; + UINT32 ret; + + task.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskF01; + task.pcName = "Signal"; + task.uwStackSize = TASK_STACK_SIZE_TEST; + task.usTaskPrio = TASK_PRIO_TEST - 1; + + ret = LOS_TaskCreate(&taskID, &task); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + LOS_TaskDelay(20); + ret = LOS_SignalSend(taskID, SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_taskErrorFlag, 0, g_taskErrorFlag); + ICUNIT_ASSERT_EQUAL(g_taskEnd, 1, g_taskEnd); + + return LOS_OK; +} + +VOID ItLosSignal004(VOID) +{ + TEST_ADD_CASE("ItLosSignal004", Testcase, TEST_LOS, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} + diff --git a/testsuites/sample/kernel/signal/It_los_signal_005.c b/testsuites/sample/kernel/signal/It_los_signal_005.c new file mode 100644 index 00000000..c308c431 --- /dev/null +++ b/testsuites/sample/kernel/signal/It_los_signal_005.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_los_signal.h" +#include "los_task.h" + +STATIC volatile INT32 g_sigValue = -1; + +STATIC VOID SigHandler(INT32 sig) +{ + g_sigValue = sig; +} + +STATIC UINT32 Testcase(VOID) +{ + sigset_t newSet; + sigset_t oldSet; + UINT32 ret; + SIG_HANDLER h = NULL; + + h = LOS_SignalSet(SIGUSR1, SigHandler); + ICUNIT_ASSERT_NOT_EQUAL(h, SIG_ERR, h); + + newSet = LOS_SIGNAL_MASK(SIGUSR1); + ret = LOS_SignalMask(SIG_BLOCK, &newSet, &oldSet); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_ERRNO_SIGNAL_NO_SET, ret); + + ret = LOS_SignalMask(SIG_SETMASK, &oldSet, NULL); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + + ret = LOS_SignalSend(LOS_CurTaskIDGet(), SIGUSR1); + ICUNIT_ASSERT_EQUAL(ret, LOS_OK, ret); + ICUNIT_ASSERT_EQUAL(g_sigValue, SIGUSR1, g_sigValue); + + return LOS_OK; +} + +VOID ItLosSignal005(VOID) +{ + TEST_ADD_CASE("ItLosSignal005", Testcase, TEST_LOS, TEST_SIGNAL, TEST_LEVEL0, TEST_FUNCTION); +} diff --git a/testsuites/src/osTest.c b/testsuites/src/osTest.c index 05b580cb..feceee46 100644 --- a/testsuites/src/osTest.c +++ b/testsuites/src/osTest.c @@ -178,8 +178,11 @@ void TestKernel(void) #if (LOS_KERNEL_LMK_TEST == 1) ItSuiteLosLmk(); #endif -} +#if (LOS_KERNEL_SIGNAL_TEST == 1) + ItSuiteLosSignal(); +#endif +} #if (CMSIS_OS_VER == 2) void TestCmsis2(void) diff --git a/utils/los_error.h b/utils/los_error.h index 21082b86..8747b993 100644 --- a/utils/los_error.h +++ b/utils/los_error.h @@ -202,6 +202,7 @@ enum LOS_MODULE_ID { LOS_MOD_PM = 0x20, LOS_MOD_LMK = 0x21, LOS_MOD_SHELL = 0x31, + LOS_MOD_SIGNAL = 0x32, LOS_MOD_BUTT };