diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md new file mode 100755 index 00000000..f09d98dd --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE.zh-CN.md @@ -0,0 +1,13 @@ +### 该问题是怎么引起的? + + + +### 重现步骤 + + + +### 报错信息 + + + + diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md new file mode 100755 index 00000000..33948fdc --- /dev/null +++ b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md @@ -0,0 +1,15 @@ +### 相关的Issue + + +### 原因(目的、解决的问题等) + + +### 描述(做了什么,变更了什么) + + +### 测试用例(新增、改动、可能影响的功能) + + + + + diff --git a/.gitignore b/.gitignore new file mode 100755 index 00000000..9daeafb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test diff --git a/BUILD.gn b/BUILD.gn new file mode 100755 index 00000000..941ad45c --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("//build/lite/config/subsystem/lite_subsystem.gni") + +lite_subsystem("kernel") { + subsystem_components = [ + "//kernel/liteos_m/arch", + "//kernel/liteos_m/components", + "//kernel/liteos_m/kernel", + ] + + if (LOSCFG_TEST) { + subsystem_components += [ "//kernel/liteos_m/test" ] + } +} diff --git a/arch/BUILD.gn b/arch/BUILD.gn new file mode 100755 index 00000000..1d2ca156 --- /dev/null +++ b/arch/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("//build/lite/config/component/lite_component.gni") + +source_set("m4") { + + sources = [ + "arm/cortex-m/cortex-m4/los_dispatch_gcc.S", + "arm/cortex-m/cortex-m4/los_hw_exc_gcc.S", + "arm/cortex-m/cortex-m4/los_hw_sr_gcc.s", + "arm/cortex-m/cortex-m4/los_exc.c", + "arm/cortex-m/src/los_hw.c", + "arm/cortex-m/src/los_hw_tick.c", + "arm/cortex-m/src/los_hwi.c", + ] +} + +lite_component("arch") { + features = [ + ":m4" + ] + +} diff --git a/arch/arm/cortex-a/BUILD.gn b/arch/arm/cortex-a/BUILD.gn new file mode 100755 index 00000000..e69de29b diff --git a/arch/arm/cortex-m/cortex-m4/iar/los_dispatch_iar.S b/arch/arm/cortex-m/cortex-m4/iar/los_dispatch_iar.S new file mode 100755 index 00000000..67c2e8ba --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/iar/los_dispatch_iar.S @@ -0,0 +1,162 @@ +; +; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020, 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. +; + + PRESERVE8 + + EXPORT LOS_IntLock + EXPORT LOS_IntUnLock + EXPORT LOS_IntRestore + EXPORT LOS_StartToRun + EXPORT osTaskSchedule + EXPORT osPendSV + + IMPORT g_losTask + IMPORT g_taskSwitchHook + IMPORT g_taskScheduled + +OS_NVIC_INT_CTRL EQU 0xE000ED04 +OS_NVIC_SYSPRI2 EQU 0xE000ED20 +OS_NVIC_PENDSV_PRI EQU 0xF0F00000 +OS_NVIC_PENDSVSET EQU 0x10000000 +OS_TASK_STATUS_RUNNING EQU 0x0010 + + SECTION .text:CODE(2) + THUMB + REQUIRE8 + +LOS_StartToRun + LDR R4, =OS_NVIC_SYSPRI2 + LDR R5, =OS_NVIC_PENDSV_PRI + STR R5, [R4] + + LDR R0, =g_taskScheduled + MOV R1, #1 + STR R1, [R0] + + MOV R0, #2 + MSR CONTROL, R0 + + + LDR R0, =g_losTask + LDR R2, [R0, #4] + LDR R0, =g_losTask + STR R2, [R0] + + LDR R3, =g_losTask + LDR R0, [R3] + LDRH R7, [R0 , #4] + MOV R8, #OS_TASK_STATUS_RUNNING + ORR R7, R7, R8 + STRH R7, [R0 , #4] + + LDR R12, [R0] + ADD R12, R12, #100 + + LDMFD R12!, {R0-R7} + ADD R12, R12, #72 + MSR PSP, R12 + VPUSH S0; + VPOP S0; + + MOV LR, R5 + ;MSR xPSR, R7 + + CPSIE I + BX R6 + + +LOS_IntLock + MRS R0, PRIMASK + CPSID I + BX LR + +LOS_IntUnLock + MRS R0, PRIMASK + CPSIE I + BX LR + +LOS_IntRestore + MSR PRIMASK, R0 + BX LR + +osTaskSchedule + LDR R0, =OS_NVIC_INT_CTRL + LDR R1, =OS_NVIC_PENDSVSET + STR R1, [R0] + BX LR + +osPendSV + MRS R12, PRIMASK + CPSID I + + LDR R2, =g_taskSwitchHook + LDR R2, [R2] + CBZ R2, TaskSwitch + PUSH {R12, LR} + BLX R2 + POP {R12, LR} + +TaskSwitch + MRS R0, PSP + + STMFD R0!, {R4-R12} + VSTMDB R0!, {D8-D15} + + LDR R5, =g_losTask + LDR R6, [R5] + STR R0, [R6] + + + LDRH R7, [R6 , #4] + MOV R8,#OS_TASK_STATUS_RUNNING + BIC R7, R7, R8 + STRH R7, [R6 , #4] + + + LDR R0, =g_losTask + LDR R0, [R0, #4] + STR R0, [R5] + + + LDRH R7, [R0 , #4] + MOV R8, #OS_TASK_STATUS_RUNNING + ORR R7, R7, R8 + STRH R7, [R0 , #4] + + LDR R1, [R0] + VLDMIA R1!, {D8-D15} + LDMFD R1!, {R4-R12} + MSR PSP, R1 + + MSR PRIMASK, R12 + BX LR + + END diff --git a/arch/arm/cortex-m/cortex-m4/iar/los_hw_exc_iar.S b/arch/arm/cortex-m/cortex-m4/iar/los_hw_exc_iar.S new file mode 100755 index 00000000..80761817 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/iar/los_hw_exc_iar.S @@ -0,0 +1,287 @@ +; +; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020, 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. +; + + PRESERVE8 + SECTION .text:CODE(2) + THUMB + + EXPORT OsExcNMI + EXPORT OsExcHardFault + EXPORT OsExcMemFault + EXPORT OsExcBusFault + EXPORT OsExcUsageFault + EXPORT OsExcSvcCall + + IMPORT OsExcHandleEntry + IMPORT g_vuwLosFlag + IMPORT g_uwCurNestCount + IMPORT g_uwExcTbl + IMPORT g_taskScheduled + +OS_FLG_BGD_ACTIVE EQU 0x0002 + +OS_EXC_CAUSE_NMI EQU 16 +OS_EXC_CAUSE_HARDFAULT EQU 17 + +HF_DEBUGEVT EQU 20 +HF_VECTBL EQU 21 + +FLAG_ADDR_VALID EQU 0x10000 +FLAG_HWI_ACTIVE EQU 0x20000 +FLAG_NO_FLOAT EQU 0x10000000 + +OS_NVIC_FSR EQU 0xE000ED28 ;include BusFault/MemFault/UsageFault State Regeister +OS_NVIC_HFSR EQU 0xE000ED2C ;HardFault State Regeister +OS_NVIC_BFAR EQU 0xE000ED38 +OS_NVIC_MMAR EQU 0xE000ED34 +OS_NVIC_ACT_BASE EQU 0xE000E300 +OS_NVIC_SHCSRS EQU 0xE000ED24 +OS_NVIC_SHCSR_MASK EQU 0xC00 + +OsExcNMI + MOV R0, #OS_EXC_CAUSE_NMI + MOV R1, #0 + B osExcDispatch + +OsExcHardFault + MOV R0, #OS_EXC_CAUSE_HARDFAULT + LDR R2, =OS_NVIC_HFSR + LDR R2, [R2] + + MOV R1, #HF_DEBUGEVT + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x80000000 + BNE osExcDispatch ; DEBUGEVT + + AND R0, R0 , #0x000000FF + MOV R1, #HF_VECTBL + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x00000002 + BNE osExcDispatch ; VECTBL + + ;if not DEBUGEVT and VECTBL then is FORCED + AND R0, R0, #0x000000FF + + LDR R2, =OS_NVIC_FSR + LDR R2, [R2] + + TST R2, #0x8000 ; BFARVALID + BNE _HFBusFault ; BusFault + + TST R2, #0x80 ; MMARVALID + BNE _HFMemFault ; MemFault + + MOV R12,#0 + B osHFExcCommonBMU + +_HFBusFault + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + B osHFExcCommonBMU + +_HFMemFault + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + +osHFExcCommonBMU + CLZ R2, R2 + LDR R3, =g_uwExcTbl + ADD R3, R3, R2 + LDRB R2, [R3] + ORR R0, R0, R2, LSL #0x8 + ORR R0, R0 ,R12 + B osExcDispatch + +OsExcSvcCall + TST LR, #0x4 + ITE EQ + MRSEQ R0, MSP + MRSNE R0, PSP + LDR R1, [R0,#24] + LDRB R0, [R1,#-2] + MOV R1, #0 + B osExcDispatch + +OsExcBusFault + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x8000 ; BFARVALID + BEQ _ExcBusNoADDR + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1F00 + + B osExcCommonBMU + +_ExcBusNoADDR + MOV R12,#0 + B osExcCommonBMU + +OsExcMemFault + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x80 ; MMARVALID + BEQ _ExcMemNoADDR + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1B + + B osExcCommonBMU + +_ExcMemNoADDR + MOV R12,#0 + B osExcCommonBMU + +OsExcUsageFault + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + MOV R1, #0x030F + LSL R1, R1, #16 + AND R0, R0, R1 + MOV R12, #0 + +osExcCommonBMU + CLZ R0, R0 + LDR R3, =g_uwExcTbl + ADD R3, R3, R0 + LDRB R0, [R3] + ORR R0, R0, R12 + +; R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR +osExcDispatch + LDR R2, =OS_NVIC_ACT_BASE + MOV R12, #8 ; R12 is hwi check loop counter + +_hwiActiveCheck + LDR R3, [R2] ; R3 store active hwi register when exc + CMP R3, #0 + BEQ _hwiActiveCheckNext + + ; exc occured in IRQ + ORR R0, R0, #FLAG_HWI_ACTIVE + RBIT R2, R3 + CLZ R2, R2 + AND R12, R12, #1 + ADD R2, R2, R12, LSL #5 ; calculate R2 (hwi number) as uwPid + +_ExcInMSP + CMP LR, #0XFFFFFFED + BNE _NoFloatInMsp + ADD R3, R13, #104 + PUSH {R3} + MRS R12, PRIMASK ; store message-->exc: disable int? + PUSH {R4-R12} ; store message-->exc: {R4-R12} + VPUSH {D8-D15} + B _handleEntry + +_NoFloatInMsp + ADD R3, R13, #32 + PUSH {R3} ; save IRQ SP ; store message-->exc: MSP(R13) + + MRS R12, PRIMASK ; store message-->exc: disable int? + PUSH {R4-R12} ; store message-->exc: {R4-R12} + ORR R0, R0, #FLAG_NO_FLOAT + B _handleEntry + +_hwiActiveCheckNext + ADD R2, R2, #4 ; next NVIC ACT ADDR + SUBS R12, R12, #1 + BNE _hwiActiveCheck + + ;/*NMI interrupt excption*/ + LDR R2, =OS_NVIC_SHCSRS + LDRH R2,[R2] + LDR R3,=OS_NVIC_SHCSR_MASK + AND R2, R2,R3 + CMP R2,#0 + BNE _ExcInMSP + ; exc occured in Task or Init or exc + ; reserved for register info from task stack + + LDR R2, =g_taskScheduled + LDR R2, [R2] + TST R2, #1 ; OS_FLG_BGD_ACTIVE + BEQ _ExcInMSP ; if exc occured in Init then branch + + + CMP LR, #0xFFFFFFED ;auto push floating registers + BNE _NoFloatInPsp + + ; exc occured in Task + MOV R2, R13 + SUB R13, #96 ; add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #104 + PUSH {R12} ; save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + VPUSH {D8-D15} + + ; copy auto saved task register + + LDMFD R3!, {R4-R11} ; R4-R11 store PSP reg(auto push when exc in task) + VLDMIA R3!, {D8-D15} + VSTMDB R2!, {D8-D15} + STMFD R2!, {R4-R11} + B _handleEntry + +_NoFloatInPsp + MOV R2, R13 ;no auto push floating registers + SUB R13, #32 ; add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #32 + PUSH {R12} ; save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + LDMFD R3, {R4-R11} ; R4-R11 store PSP reg(auto push when exc in task) + STMFD R2!, {R4-R11} + ORR R0, R0, #FLAG_NO_FLOAT + +_handleEntry + MOV R3, R13 ; R13:the 4th param + CPSID I + CPSID F + B OsExcHandleEntry + + NOP + END diff --git a/arch/arm/cortex-m/cortex-m4/los_dispatch_gcc.S b/arch/arm/cortex-m/cortex-m4/los_dispatch_gcc.S new file mode 100755 index 00000000..a90dcf84 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/los_dispatch_gcc.S @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + + .syntax unified + .arch armv7e-m + .thumb + .fpu vfpv4 +//;.arch_extension sec + + + +.equ OS_NVIC_INT_CTRL, 0xE000ED04 +.equ OS_NVIC_SYSPRI2, 0xE000ED20 +.equ OS_NVIC_PENDSV_PRI, 0xF0F00000 +.equ OS_NVIC_PENDSVSET, 0x10000000 +.equ OS_TASK_STATUS_RUNNING, 0x0010 + + .section .text + .thumb + + .type LOS_StartToRun, %function + .global LOS_StartToRun + +LOS_StartToRun: + .fnstart + .cantunwind + + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r0, =g_taskScheduled + mov r1, #1 + str r1, [r0] + + mov r0, #2 + msr CONTROL, r0 + + + ldr r0, =g_losTask + ldr r2, [r0, #4] + ldr r0, =g_losTask + str r2, [r0] + + ldr r3, =g_losTask + ldr r0, [r3] + ldrh r7, [r0 , #4] + mov r8, #OS_TASK_STATUS_RUNNING + orr r7, r7, r8 + strh r7, [r0 , #4] + + ldr r12, [r0] + add r12, r12, #100 + + ldmfd r12!, {r0-r7} + add r12, r12, #72 + msr psp, r12 + vpush {S0} + vpop {S0} + mov lr, r5 + //MSR xPSR, R7 + + cpsie I + bx r6 + + .fnend + + + .type LOS_IntLock, %function + .global LOS_IntLock +LOS_IntLock: + .fnstart + .cantunwind + + MRS R0, PRIMASK + CPSID I + BX LR + .fnend + + .type LOS_IntUnLock, %function + .global LOS_IntUnLock +LOS_IntUnLock: + .fnstart + .cantunwind + + MRS R0, PRIMASK + CPSIE I + BX LR + .fnend + + .type LOS_IntRestore, %function + .global LOS_IntRestore +LOS_IntRestore: + .fnstart + .cantunwind + + MSR PRIMASK, R0 + BX LR + .fnend + + .type osTaskSchedule, %function + .global osTaskSchedule +osTaskSchedule: + .fnstart + .cantunwind + + ldr r0, =OS_NVIC_INT_CTRL + ldr r1, =OS_NVIC_PENDSVSET + str r1, [r0] + bx lr + .fnend + + + + + .type osPendSV, %function + .global osPendSV +osPendSV: + .fnstart + .cantunwind + + mrs r12, PRIMASK + cpsid I + + ldr r2, =g_taskSwitchHook + ldr r2, [r2] + cbz r2, TaskSwitch + push {r12, lr} + blx r2 + pop {r12, lr} + +TaskSwitch: + + mrs r0, psp + + stmfd r0!, {r4-r12} + + vstmdb r0!, {d8-d15} + ldr r5, =g_losTask + ldr r6, [r5] + str r0, [r6] + + + ldrh r7, [r6 , #4] + mov r8,#OS_TASK_STATUS_RUNNING + bic r7, r7, r8 + strh r7, [r6 , #4] + + + ldr r0, =g_losTask + ldr r0, [r0, #4] + str r0, [r5] + + + ldrh r7, [r0 , #4] + mov r8, #OS_TASK_STATUS_RUNNING + orr r7, r7, r8 + strh r7, [r0 , #4] + + ldr r1, [r0] + + vldmia r1!, {d8-d15} + ldmfd r1!, {r4-r12} + msr psp, r1 + + msr PRIMASK, r12 + + + bx lr + .fnend + diff --git a/arch/arm/cortex-m/cortex-m4/los_exc.c b/arch/arm/cortex-m/cortex-m4/los_exc.c new file mode 100755 index 00000000..e8939093 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/los_exc.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_exc_pri.h" +#include "los_memcheck_pri.h" +#ifdef LOSCFG_LIB_LIBC +#include "string.h" +#endif +#include "securec.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define EXC_INT_STATUS_LEN OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + OS_NVIC_INT_ACT_SIZE + \ + OS_NVIC_INT_PRI_SIZE + OS_NVIC_EXCPRI_SIZE + OS_NVIC_SHCSR_SIZE + OS_NVIC_INT_CTRL_SIZE +#define TASK_ARRAY_INIT_VALUE 0xff +#define FAULT_STATUS_REG_BIT 32 +#define OS_NVIC_INT_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 +#define USGFAULT (1 << 18) +#define BUSFAULT (1 << 17) +#define MEMFAULT (1 << 16) +#define DIV0FAULT (1 << 4) +#define CORE_TYPE_CORTEX_M4 2 +#define HARDFAULT_IRQN (-13) +static VOID *g_excContent; +UINT32 g_curNestCount = 0; +ExcInfo g_excInfo; + +__attribute__((noinline)) VOID LOS_Panic(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap,fmt); + PRINT_ERR(fmt, ap); + va_end(ap); + asm volatile ("swi 0"); +} + +UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { + 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, + 0, 0, 0, 0, OS_EXC_UF_NOCP, OS_EXC_UF_INVPC, OS_EXC_UF_INVSTATE, OS_EXC_UF_UNDEFINSTR, + 0, 0, 0, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, + 0, 0, 0, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL +}; +UINT32 g_excArraySize = 0; +ExcInfoArray g_excArray[OS_EXC_TYPE_MAX - 1]; + +UINT32 g_LR_regs = 0; +UINT32 g_PC_regs = 0; + +LITE_OS_SEC_TEXT_INIT VOID OsExcInfoDisplay(ExcInfo *exc) +{ + PRINT_INFO("Phase = 0x%x\n", exc->phase); + PRINT_INFO("Type = 0x%x\n", exc->type); + PRINT_INFO("FaultAddr = 0x%x\n", exc->faultAddr); + PRINT_INFO("ThrdPid = 0x%x\n", exc->thrdPid); + PRINT_INFO("R0 = 0x%x\n", exc->context->uwR0); + PRINT_INFO("R1 = 0x%x\n", exc->context->uwR1); + PRINT_INFO("R2 = 0x%x\n", exc->context->uwR2); + PRINT_INFO("R3 = 0x%x\n", exc->context->uwR3); + PRINT_INFO("R4 = 0x%x\n", exc->context->uwR4); + PRINT_INFO("R5 = 0x%x\n", exc->context->uwR5); + PRINT_INFO("R6 = 0x%x\n", exc->context->uwR6); + PRINT_INFO("R7 = 0x%x\n", exc->context->uwR7); + PRINT_INFO("R8 = 0x%x\n", exc->context->uwR8); + PRINT_INFO("R9 = 0x%x\n", exc->context->uwR9); + PRINT_INFO("R10 = 0x%x\n", exc->context->uwR10); + PRINT_INFO("R11 = 0x%x\n", exc->context->uwR11); + PRINT_INFO("R12 = 0x%x\n", exc->context->uwR12); + PRINT_INFO("PriMask = 0x%x\n", exc->context->uwPriMask); + PRINT_INFO("SP = 0x%x\n", exc->context->uwSP); + PRINT_INFO("LR = 0x%x\n", exc->context->uwLR); + PRINT_INFO("PC = 0x%x\n", exc->context->uwPC); + PRINT_INFO("xPSR = 0x%x\n", exc->context->uwxPSR); + + g_LR_regs = exc->context->uwLR; + g_PC_regs = exc->context->uwPC; +} + +/* **************************************************************************** + Function : OsExcHandleEntry + Description : EXC模块的处理分发函数 + Input : excType + : faultAddr + : pid + : excBufAddr --- EXC寄存器信息的首地址 + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, + EXC_CONTEXT_S *excBufAddr) +{ + UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; // 为2在中断中,为1 faultAddr有效 + g_curNestCount++; + g_vuwIntCount++; + g_excInfo.nestCnt = g_curNestCount; + + g_excInfo.type = excType & OS_NULL_SHORT; + g_excContent = (UINT32 *)g_aucTaskArray; + + if (tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) { + g_excInfo.faultAddr = faultAddr; + } else { + g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; + } + + if (g_losTask.runTask != NULL) { + if (tmpFlag & OS_EXC_FLAG_IN_HWI) { + g_excInfo.phase = OS_EXC_IN_HWI; + g_excInfo.thrdPid = pid; + } else { + g_excInfo.phase = OS_EXC_IN_TASK; + g_excInfo.thrdPid = g_losTask.runTask->taskID; + } + } else { + g_excInfo.phase = OS_EXC_IN_INIT; + g_excInfo.thrdPid = OS_NULL_INT; + } + + if (excType & OS_EXC_FLAG_NO_FLOAT) { + g_excInfo.context = (EXC_CONTEXT_S *)((CHAR *)excBufAddr - LOS_OFF_SET_OF(EXC_CONTEXT_S, uwR4)); + } else { + g_excInfo.context = excBufAddr; + } + + OsExcSave2DDR(); + + OsExcInfoDisplay(&g_excInfo); + + LOS_Reboot(); +} +static VOID OsExcSaveIntStatus() +{ + UINT32 ret; + UINT32 failCnt = 0; + *((UINT32 *)g_excContent) = OS_EXC_TYPE_NVIC; + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + + // = OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + OS_NVIC_INT_ACT_SIZE + OS_NVIC_INT_PRI_SIZE + 12 + 4 + 4 + *((UINT32 *)g_excContent) = EXC_INT_STATUS_LEN; + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + /* 保存中断ENABLE寄存器组 */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_SETENA_BASE, OS_NVIC_INT_ENABLE_SIZE); + g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_ENABLE_SIZE; + failCnt += (ret == EOK) ? 0 : 1; + + /* 保存中断PEND寄存器组 */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_SETPEND_BASE, OS_NVIC_INT_PEND_SIZE); + g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_PEND_SIZE; + failCnt += (ret == EOK) ? 0 : 1; + + /* 保存中断ACTIVE寄存器组 */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_INT_ACT_BASE, OS_NVIC_INT_ACT_SIZE); + g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_ACT_SIZE; + failCnt += (ret == EOK) ? 0 : 1; + + /* 保存中断优先级寄存器组 */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_PRI_BASE, OS_NVIC_INT_PRI_SIZE); + g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_PRI_SIZE; + failCnt += (ret == EOK) ? 0 : 1; + + /* 系统异常优先级寄存器组 */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_EXCPRI_BASE, OS_NVIC_EXCPRI_SIZE); + g_excContent = (UINT8 *)g_excContent + OS_NVIC_EXCPRI_SIZE; + failCnt += (ret == EOK) ? 0 : 1; + + /* 保存系统Handler控制及状态寄存器SHCSR */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_SHCSR, OS_NVIC_SHCSR_SIZE); + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + failCnt += (ret == EOK) ? 0 : 1; + + /* 保存中断控制及状态寄存器ICSR */ + ret = memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (const VOID *)OS_NVIC_INT_CTRL, OS_NVIC_INT_CTRL_SIZE); + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + failCnt += (ret == EOK) ? 0 : 1; + + if (failCnt != 0) { + PRINT_ERR("OsExcSaveIntStatus copy register info failed, cnt:%d\n", failCnt); + } + + return; +} + +VOID OsExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) +{ + ExcInfoArray *excInfo = NULL; + if ((type == 0) || (type >= OS_EXC_TYPE_MAX) || (func == NULL)) { + PRINT_ERR("OsExcRegister ERROR!\n"); + return; + } + excInfo = &(g_excArray[type - 1]); + excInfo->uwType = type; + excInfo->pFnExcInfoCb = func; + excInfo->pArg = arg; + excInfo->uwValid = TRUE; +} + +static VOID OsExcSaveSysInfo(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, UINT32 loop, UINT32 length, UINT32 index) +{ + UINT32 ret; + UINT32 buffer[OS_EXC_MAX_BUF_LEN]; + + *((UINT32 *)g_excContent) = type; + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + *((UINT32 *)g_excContent) = length * (loop - index); + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + + for (; index < loop; index++) { + (VOID)memset_s(buffer, sizeof(UINT32) * OS_EXC_MAX_BUF_LEN, 0, sizeof(UINT32) * OS_EXC_MAX_BUF_LEN); + ret = func(index, (VOID *)buffer); + if (ret == LOS_OK) { + if (memcpy_s(g_excContent, MAX_EXC_MEM_SIZE, (VOID *)buffer, length) != EOK) { + PRINT_ERR("OsExcSaveSysInfo copy buffer failed\n"); + return; + } + g_excContent = (UINT8 *)g_excContent + length; + } else { + g_excContent = (UINT8 *)g_excContent + length; + } + } +} + +static VOID OsExcSaveInfo(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) +{ + UINT32 length; + UINT32 index; + UINT32 loop; + UINT32 taskSwitchCount = 0; + TaskSwitchInfo *taskSwitchInfo = NULL; + + if (arg == NULL) { + return; + } + + switch (type) { + case OS_EXC_TYPE_TSK: /* save task info */ + length = sizeof(TSK_INFO_S); + loop = *(UINT32 *)arg; + index = 0; + break; + + case OS_EXC_TYPE_QUE: /* save queue info */ + length = sizeof(QUEUE_INFO_S); + loop = *(UINT32 *)arg + 1; + index = 1; + break; + + case OS_EXC_TYPE_NVIC: + (VOID)func(0, 0); + goto END; + + case OS_EXC_TYPE_TSK_SWITCH: /* save task switch info */ + // not necessary, just for macro int library + taskSwitchInfo = arg; + taskSwitchCount = taskSwitchInfo->cntInfo.maxCnt; + length = sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN; + if (taskSwitchInfo->cntInfo.isFull) { + index = taskSwitchInfo->idx; + loop = index + taskSwitchCount; + } else { + index = 0; + loop = taskSwitchInfo->idx; + } + break; + + case OS_EXC_TYPE_MEM: /* save mem info */ + length = sizeof(MEM_INFO_S); + loop = *(UINT32 *)arg; + index = 0; + break; + + default: + goto END; + } + OsExcSaveSysInfo(type, (EXC_INFO_SAVE_CALLBACK)func, loop, length, index); +END: + return; +} + +static VOID OsExcSave2DDR(VOID) +{ + UINT32 index = 0; + UINT32 ret; + UINT32 failCnt = 0; + + ret = memset_s(g_aucTaskArray, MAX_EXC_MEM_SIZE, TASK_ARRAY_INIT_VALUE, g_excArraySize); + if (ret != EOK) { + PRINT_ERR("memset failed\n"); + return; + } + + /* define core type */ + *((UINT32 *)g_excContent) = CORE_TYPE_CORTEX_M4; // 1 is cortex-M3, 2 is cortex-M4 + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + + /* save exception info */ + *((UINT32 *)g_excContent) = OS_EXC_TYPE_CONTEXT; + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + *((UINT32 *)g_excContent) = sizeof(ExcInfo) - sizeof(UINT32) + sizeof(EXC_CONTEXT_S); + + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + ret = memcpy_s((VOID *)g_excContent, MAX_EXC_MEM_SIZE, (VOID *)&g_excInfo, sizeof(ExcInfo) - sizeof(UINT32)); + g_excContent = (UINT8 *)g_excContent + sizeof(ExcInfo) - sizeof(UINT32); + failCnt += (ret == EOK) ? 0 : 1; + + ret = memcpy_s((VOID *)g_excContent, MAX_EXC_MEM_SIZE, g_excInfo.context, sizeof(EXC_CONTEXT_S)); + g_excContent = (UINT8 *)g_excContent + sizeof(EXC_CONTEXT_S); + failCnt += (ret == EOK) ? 0 : 1; + + if (failCnt != 0) { + PRINT_ERR("OsExcSave2DDR copy exc info failed, cnt:%d\n", failCnt); + } + + for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { + if (g_excArray[index].uwValid == FALSE) { + continue; + } + OsExcSaveInfo(g_excArray[index].uwType, g_excArray[index].pFnExcInfoCb, g_excArray[index].pArg); + } + *((UINT32 *)g_excContent) = OS_EXC_TYPE_MAX; + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + return; +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcInit(UINT32 arraySize) +{ + g_hwiForm[HARDFAULT_IRQN + OS_SYS_VECTOR_CNT] = OsExcHardFault; + g_hwiForm[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = OsExcNMI; + g_hwiForm[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = OsExcMemFault; + g_hwiForm[BusFault_IRQn + OS_SYS_VECTOR_CNT] = OsExcBusFault; + g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = OsExcUsageFault; + g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = OsExcSvcCall; + /* Enable USGFAULT, BUSFAULT, MEMFAULT */ + *(volatile UINT32 *)OS_NVIC_SHCSR |= (USGFAULT | BUSFAULT | MEMFAULT); + /* Enable DIV 0 and unaligned exception */ // 因为文件系统存在非对齐操作,故此异常暂不接管 + + *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; + g_excArraySize = arraySize; + + OsExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)OsExcSaveIntStatus, NULL); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-m/cortex-m4/los_exc_pri.h b/arch/arm/cortex-m/cortex-m4/los_exc_pri.h new file mode 100755 index 00000000..f1b20d6f --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/los_exc_pri.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_EXC_PRI_H +#define _LOS_EXC_PRI_H + +#include "los_exc.h" +#include "los_sys_pri.h" +#ifdef LOSCFG_LIB_LIBC +#include "string.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + OS_EXC_TYPE_CONTEXT = 0, + OS_EXC_TYPE_TSK = 1, + OS_EXC_TYPE_QUE = 2, + OS_EXC_TYPE_NVIC = 3, + OS_EXC_TYPE_TSK_SWITCH = 4, + OS_EXC_TYPE_MEM = 5, + OS_EXC_TYPE_MAX = 6 +} ExcInfoType; + +typedef struct tagExcInfoCallBackArray { + ExcInfoType uwType; + UINT32 uwValid; + EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; + VOID* pArg; +} ExcInfoArray; + + + +#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) +#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) +#define MAX_INT_INFO_SIZE (8 + 0x164) + +#if (LOSCFG_BASE_IPC_QUEUE == YES) +#define MAX_QUEUE_INFO_SIZE (8 + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT) +#else +#define MAX_QUEUE_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) +#define MAX_SWITCH_INFO_SIZE (8 + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT) +#else +#define MAX_SWITCH_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) +#define MAX_MEM_INFO_SIZE (8 + sizeof(MEM_INFO_S) * OS_SYS_MEM_NUM) +#else +#define MAX_MEM_INFO_SIZE (0) +#endif + +#define MAX_EXC_MEM_SIZE ( 4 + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE + 4) + +VOID OsExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg); +VOID LOS_Reboot(VOID); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/arch/arm/cortex-m/cortex-m4/los_hw_exc_gcc.S b/arch/arm/cortex-m/cortex-m4/los_hw_exc_gcc.S new file mode 100755 index 00000000..520de364 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/los_hw_exc_gcc.S @@ -0,0 +1,384 @@ +; +; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020, 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. +; + + .syntax unified + .arch armv7e-m + .thumb +.fpu vfpv4 +.section .text + + + .global OsExcNMI + .global OsExcHardFault + .global OsExcMemFault + .global OsExcBusFault + .global OsExcUsageFault + .global OsExcSvcCall + + .extern OsExcHandleEntry + .extern g_vuwLosFlag + .extern g_uwCurNestCount + .extern g_uwExcTbl + .extern g_taskScheduled + +.equ OS_FLG_BGD_ACTIVE, 0x0002 + +.equ OS_EXC_CAUSE_NMI, 16 +.equ OS_EXC_CAUSE_HARDFAULT, 17 + +.equ HF_DEBUGEVT, 20 +.equ HF_VECTBL, 21 + +.equ FLAG_ADDR_VALID, 0x10000 +.equ FLAG_HWI_ACTIVE, 0x20000 +.equ FLAG_NO_FLOAT, 0x10000000 + +.equ OS_NVIC_FSR , 0xE000ED28 //include BusFault/MemFault/UsageFault State Regeister +.equ OS_NVIC_HFSR , 0xE000ED2C //HardFault State Regeister +.equ OS_NVIC_BFAR , 0xE000ED38 +.equ OS_NVIC_MMAR , 0xE000ED34 +.equ OS_NVIC_ACT_BASE , 0xE000E300 +.equ OS_NVIC_SHCSRS , 0xE000ED24 +.equ OS_NVIC_SHCSR_MASK , 0xC00 + + .type OsExcNMI, %function + .global OsExcNMI +OsExcNMI: + .fnstart + .cantunwind + MOV R0, #OS_EXC_CAUSE_NMI + MOV R1, #0 + B osExcDispatch + .fnend + + .type OsExcHardFault, %function + .global OsExcHardFault +OsExcHardFault: + .fnstart + .cantunwind + MOV R0, #OS_EXC_CAUSE_HARDFAULT + LDR R2, =OS_NVIC_HFSR + LDR R2, [R2] + + MOV R1, #HF_DEBUGEVT + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x80000000 + BNE osExcDispatch // DEBUGEVT + + AND R0, #0x000000FF + MOV R1, #HF_VECTBL + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x00000002 + BNE osExcDispatch // VECTBL + + //if not DEBUGEVT and VECTBL then is FORCED + AND R0, #0x000000FF + + LDR R2, =OS_NVIC_FSR + LDR R2, [R2] + + TST R2, #0x8000 // BFARVALID + BNE _HFBusFault // BusFault + + TST R2, #0x80 // MMARVALID + BNE _HFMemFault // MemFault + + MOV R12,#0 + B osHFExcCommonBMU + .fnend + + .type _HFBusFault, %function + +_HFBusFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + B osHFExcCommonBMU + .fnend + + .type _HFMemFault, %function + +_HFMemFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + .fnend + + .type osHFExcCommonBMU, %function + .global osHFExcCommonBMU +osHFExcCommonBMU: + .fnstart + .cantunwind + CLZ R2, R2 + LDR R3, =g_uwExcTbl + ADD R3, R3, R2 + LDRB R2, [R3] + ORR R0, R0, R2, LSL #0x8 + ORR R0, R12 + B osExcDispatch + .fnend + + .type OsExcSvcCall, %function + .global OsExcSvcCall +OsExcSvcCall: + .fnstart + .cantunwind + TST LR, #0x4 + ITE EQ + MRSEQ R0, MSP + MRSNE R0, PSP + LDR R1, [R0,#24] + LDRB R0, [R1,#-2] + MOV R1, #0 + B osExcDispatch + .fnend + + .type OsExcBusFault, %function + .global OsExcBusFault +OsExcBusFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x8000 // BFARVALID + BEQ _ExcBusNoADDR + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, #0x1F00 + + B osExcCommonBMU + .fnend + + .type _ExcBusNoADDR, %function + .global _ExcBusNoADDR +_ExcBusNoADDR: + .fnstart + .cantunwind + MOV R12,#0 + B osExcCommonBMU + .fnend + + .type OsExcMemFault, %function + .global OsExcMemFault +OsExcMemFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x80 // MMARVALID + BEQ _ExcMemNoADDR + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, #0x1B + + B osExcCommonBMU + .fnend + + .type _ExcMemNoADDR, %function + .global _ExcMemNoADDR +_ExcMemNoADDR: + .fnstart + .cantunwind + MOV R12,#0 + B osExcCommonBMU + .fnend + + .type OsExcUsageFault, %function + .global OsExcUsageFault +OsExcUsageFault: + .fnstart + .cantunwind + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + LDR R1, =#0x030F + LSL R1, #16 + AND R0, R1 + MOV R12, #0 + .fnend + + .type osExcCommonBMU, %function + .global osExcCommonBMU +osExcCommonBMU: + .fnstart + .cantunwind + CLZ R0, R0 + LDR R3, =g_uwExcTbl + ADD R3, R3, R0 + LDRB R0, [R3] + ORR R0, R0, R12 + .fnend +// R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR + + .type osExcDispatch, %function + .global osExcDispatch +osExcDispatch: + .fnstart + .cantunwind + LDR R2, =OS_NVIC_ACT_BASE + MOV R12, #8 // R12 is hwi check loop counter + .fnend + + .type _hwiActiveCheck, %function + .global _hwiActiveCheck +_hwiActiveCheck: + .fnstart + .cantunwind + LDR R3, [R2] // R3 store active hwi register when exc + CMP R3, #0 + BEQ _hwiActiveCheckNext + + // exc occured in IRQ + ORR R0, #FLAG_HWI_ACTIVE + RBIT R2, R3 + CLZ R2, R2 + AND R12, #1 + ADD R2, R2, R12, LSL #5 // calculate R2 (hwi number) as uwPid + .fnend + + .type _ExcInMSP, %function + .global _ExcInMSP +_ExcInMSP: + .fnstart + .cantunwind + CMP LR, #0XFFFFFFED + BNE _NoFloatInMsp + ADD R3, R13, #104 + PUSH {R3} + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} + VPUSH {D8-D15} + B _handleEntry + .fnend + + .type _NoFloatInMsp, %function + .global _NoFloatInMsp +_NoFloatInMsp: + .fnstart + .cantunwind + ADD R3, R13, #32 + PUSH {R3} // save IRQ SP // store message-->exc: MSP(R13) + + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} + ORR R0, R0, #FLAG_NO_FLOAT + B _handleEntry + .fnend + + .type _hwiActiveCheckNext, %function + .global _hwiActiveCheckNext +_hwiActiveCheckNext: + .fnstart + .cantunwind + ADD R2, #4 // next NVIC ACT ADDR + SUBS R12, #1 + BNE _hwiActiveCheck + + /*NMI interrupt excption*/ + LDR R2, =OS_NVIC_SHCSRS + LDRH R2,[R2] + LDR R3,=OS_NVIC_SHCSR_MASK + AND R2, R2,R3 + CMP R2,#0 + BNE _ExcInMSP + // exc occured in Task or Init or exc + // reserved for register info from task stack + + LDR R2, =g_taskScheduled + LDR R2, [R2] + TST R2, #1 // OS_FLG_BGD_ACTIVE + BEQ _ExcInMSP // if exc occured in Init then branch + + + CMP LR, #0xFFFFFFED //auto push floating registers + BNE _NoFloatInPsp + + // exc occured in Task + MOV R2, R13 + SUB R13, #96 // add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #104 + PUSH {R12} // save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + VPUSH {D8-D15} + + // copy auto saved task register + + LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) + VLDMIA R3!, {D8-D15} + VSTMDB R2!, {D8-D15} + STMFD R2!, {R4-R11} + B _handleEntry + .fnend + + .type _NoFloatInPsp, %function + .global _NoFloatInPsp +_NoFloatInPsp: + .fnstart + .cantunwind + MOV R2, R13 //no auto push floating registers + SUB R13, #32 // add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #32 + PUSH {R12} // save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + LDMFD R3, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) + STMFD R2!, {R4-R11} + ORR R0, R0, #FLAG_NO_FLOAT + .fnend + + .type _handleEntry, %function + .global _handleEntry +_handleEntry: + .fnstart + .cantunwind + MOV R3, R13 // R13:the 4th param + CPSID I + CPSID F + B OsExcHandleEntry + + NOP + .fnend diff --git a/arch/arm/cortex-m/cortex-m4/los_hw_sr_gcc.s b/arch/arm/cortex-m/cortex-m4/los_hw_sr_gcc.s new file mode 100755 index 00000000..e0eac9d9 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/los_hw_sr_gcc.s @@ -0,0 +1,131 @@ +; +; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020, 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. +; + + .syntax unified + .arch armv7e-m + .thumb + .fpu vfpv4 + + + .extern g_saveSRContext + .extern g_saveAR + .extern g_losTask + + .global OsSRSaveRegister + .global OsSRRestoreRegister + + .section .text + .thumb + + .type OsSRSaveRegister, %function + .global OsSRSaveRegister +OsSRSaveRegister: + .fnstart + .cantunwind + PUSH {R2} + LDR R2, =g_saveAR + STR R0, [R2] + STR R1, [R2, #4] + POP {R2} + + MRS R0, PSP + + VSTMDB R0!, {D0-D7} + VMRS R1, FPSCR + STMFD R0!, {R1} //FPSCR + STMFD R0!, {R1} //NO_NAME + + MRS R1, PSR + ORR R1, R1, #0x01000000 + STMFD R0!, {R1} + + MOV R1, LR + STMFD R0!, {R1} // ;PC + STMFD R0!, {R1} // ;LR + + STMFD R0!, {R12} + + MOV R12, R0 + + LDR R0, =g_saveAR + LDR R0, [R0] + LDR R1, =g_saveAR + LDR R1, [R1, #4] + + STMFD R12!, {R0-R3} + STMFD R12!, {R4-R11} + VSTMDB R12!, {D8-D15} + + MRS R0, CONTROL + STMFD R12!, {R0} + + MRS R0, MSP + STMFD R12!, {R0} + + LDR R1, =g_losTask + LDR R1, [R1] + STR R12, [R1] + + MSR PSP, R12 + BX LR + .fnend + + .type OsSRSaveRegister, %function + .global OsSRSaveRegister +OsSRRestoreRegister: + .fnstart + .cantunwind + MRS R0, MSP + ADD R0, R0, #8 + MSR MSP, R0 + + LDR R0, =g_losTask + LDR R0, [R0] + LDR R12, [R0] + + LDR R0, =g_saveSRContext + ADD R0, R0, #120 + MSR PSP, R0 + + LDMFD R12!,{R0} + MSR MSP, R0 + + LDMFD R12!,{R0} + MSR CONTROL, R0 + + VLDMIA R12!,{D8-D15} + LDMFD R12!,{R4-R11} + + MSR PSP, R12 + MOV LR, #0xFFFFFFED + BX LR + + .fnend diff --git a/arch/arm/cortex-m/include/los_exc.h b/arch/arm/cortex-m/include/los_exc.h new file mode 100755 index 00000000..2270498d --- /dev/null +++ b/arch/arm/cortex-m/include/los_exc.h @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_EXC_H +#define _LOS_EXC_H + +#include "los_hwi.h" +#include "los_task_pri.h" +#include "los_queue.h" +#include "los_memcheck.h" +#include "los_sys_pri.h" +#ifdef LOSCFG_LIB_LIBC +#include "string.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_EXC_MAX_BUF_LEN 25 +#define OS_EXC_MAX_NEST_DEPTH 1 + +#define OS_NVIC_SHCSR 0xE000ED24 +#define OS_NVIC_CCR 0xE000ED14 + +#define OS_NVIC_INT_ENABLE_SIZE 0x20 +#define OS_NVIC_INT_PRI_SIZE 0xF0 +#define OS_NVIC_EXCPRI_SIZE 0xC + +#define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE +#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE + +#define OS_EXC_FLAG_NO_FLOAT 0x10000000 +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 +#define OS_EXC_FLAG_IN_HWI 0x02 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +/** + *@ingroup los_exc + * the struct of register files + * + * description: the register files that saved when exception triggered + * + * notes:the following register with prefix 'uw' correspond to the registers in the cpu data sheet. + */ +typedef struct tagExcContext { + //handler save +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + UINT32 S16; + UINT32 S17; + UINT32 S18; + UINT32 S19; + UINT32 S20; + UINT32 S21; + UINT32 S22; + UINT32 S23; + UINT32 S24; + UINT32 S25; + UINT32 S26; + UINT32 S27; + UINT32 S28; + UINT32 S29; + UINT32 S30; + UINT32 S31; +#endif + UINT32 uwR4; + UINT32 uwR5; + UINT32 uwR6; + UINT32 uwR7; + UINT32 uwR8; + UINT32 uwR9; + UINT32 uwR10; + UINT32 uwR11; + UINT32 uwPriMask; + //auto save + UINT32 uwSP; + UINT32 uwR0; + UINT32 uwR1; + UINT32 uwR2; + UINT32 uwR3; + UINT32 uwR12; + UINT32 uwLR; + UINT32 uwPC; + UINT32 uwxPSR; +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED) && (__FPU_USED== 1U))) + UINT32 S0; + UINT32 S1; + UINT32 S2; + UINT32 S3; + UINT32 S4; + UINT32 S5; + UINT32 S6; + UINT32 S7; + UINT32 S8; + UINT32 S9; + UINT32 S10; + UINT32 S11; + UINT32 S12; + UINT32 S13; + UINT32 S14; + UINT32 S15; + UINT32 FPSCR; + UINT32 NO_NAME; +#endif +}EXC_CONTEXT_S; + +typedef UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID*); +typedef VOID (*EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *); +VOID OsExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr); + +/** + * @ingroup los_hwi + * @brief: Exception initialization. + * + * @par Description: + * This API is used to configure the exception function vector table. + * + * @attention: + * + * + *@param uwArraySize [IN] Memory size of exception. + * + * @retval: None + * @par Dependency: + * + * @see None. + */ +VOID OsExcInit(UINT32 uwArraySize); + +extern VOID OsExcNMI(VOID); +extern VOID OsExcHardFault(VOID); +extern VOID OsExcMemFault(VOID); +extern VOID OsExcBusFault(VOID); +extern VOID OsExcUsageFault(VOID); +extern VOID OsExcSvcCall(VOID); +extern VOID OsBackTrace(VOID); +extern UINT8 g_aucTaskArray[]; + +/** + *@ingroup los_exc + *@brief Kernel panic function. + * + *@par Description: + *Stack function that prints kernel panics. + *@attention After this function is called and stack information is printed, the system will fail to respond. + *@attention The input parameter can be NULL. + *@param fmt [IN] Type #char* : variadic argument. + * + *@retval #None. + * + *@par Dependency: + *los_exc.h: the header file that contains the API declaration. + *@see None. +*/ +VOID LOS_Panic(const CHAR *fmt, ...); + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器入栈时发生错误 + */ +#define OS_EXC_BF_STKERR 1 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器出栈时发生错误 + */ +#define OS_EXC_BF_UNSTKERR 2 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器不精确的数据访问违例 + */ +#define OS_EXC_BF_IMPRECISERR 3 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器精确的数据访问违例 + */ +#define OS_EXC_BF_PRECISERR 4 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状态寄存器取指时的访问违例 + */ +#define OS_EXC_BF_IBUSERR 5 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器入栈时发生错误 + */ +#define OS_EXC_MF_MSTKERR 6 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器出栈时发生错误 + */ +#define OS_EXC_MF_MUNSTKERR 7 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器数据访问违例 + */ +#define OS_EXC_MF_DACCVIOL 8 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管理状态寄存器取指访问违例 + */ +#define OS_EXC_MF_IACCVIOL 9 + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,表示除法运算时除数为零 + */ +#define OS_EXC_UF_DIVBYZERO 10 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,未对齐访问导致的错误 + */ +#define OS_EXC_UF_UNALIGNED 11 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图执行协处理器相关指令 + */ +#define OS_EXC_UF_NOCP 12 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,在异常返回时试图非法地加载EXC_RETURN到PC + */ +#define OS_EXC_UF_INVPC 13 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图切入ARM状态 + */ +#define OS_EXC_UF_INVSTATE 14 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,执行的指令其编码是未定义的——解码不能 + */ +#define OS_EXC_UF_UNDEFINSTR 15 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:NMI中断 + */ + +#define OS_EXC_CAUSE_NMI 16 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:硬fault + */ +#define OS_EXC_CAUSE_HARDFAULT 17 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:任务处理函数退出 + */ +#define OS_EXC_CAUSE_TASK_EXIT 18 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:致命错误 + */ +#define OS_EXC_CAUSE_FATAL_ERR 19 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:调试事件导致的硬fault + */ +#define OS_EXC_CAUSE_DEBUGEVT 20 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:取向量时发生的硬fault + */ +#define OS_EXC_CAUSE_VECTBL 21 + +/** + *@ingroup los_exc + * 异常信息结构体 + * + * 描述:M4平台下的异常触发时保存的异常信息 + * + */ +typedef struct tagExcInfo { + /**< 异常发生阶段: 0表示异常发生在初始化中,1表示异常发生在任务中,2表示异常发生在中断中 */ + UINT16 phase; + /**< 异常类型,出异常时对照上面列出的1-19号 */ + UINT16 type; + /**< 若为精确地址访问错误表示异常发生时的错误访问地址 */ + UINT32 faultAddr; + /**< 在中断中发生异常,表示中断号。在任务中发生异常,表示任务id,如果发生在初始化中,则为0xffffffff */ + UINT32 thrdPid; + /**< 异常嵌套个数,目前仅支持第一次进入异常时执行注册的钩子函数 */ + UINT16 nestCnt; + /**< 保留 */ + UINT16 reserved; + /**< 自动压栈浮点寄存器的异常发生时刻的硬件上下文 */ + EXC_CONTEXT_S * context; +} ExcInfo; + +extern UINT32 g_curNestCount; +extern UINT32 g_vuwIntCount; + +static VOID OsExcSave2DDR(VOID); +VOID OsExcInfoDisplay(ExcInfo *exc); + + +extern TaskSwitchInfo g_taskSwitchInfo; +extern UINT8 g_uwExcTbl[32]; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_EXC_H */ + diff --git a/arch/arm/cortex-m/include/los_hw.h b/arch/arm/cortex-m/include/los_hw.h new file mode 100755 index 00000000..353d2161 --- /dev/null +++ b/arch/arm/cortex-m/include/los_hw.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_hw hardware + * @ingroup kernel + */ + +#ifndef _LOS_HW_H +#define _LOS_HW_H + +#include "los_base.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* * + * @ingroup los_hw + * The initialization value of stack space. + */ +#define EMPTY_STACK 0xCACA + +/* * + * @ingroup los_hw + * Trigger a task. + */ +#define OsTaskTrap() __asm(" TRAP #31") + +/* * + * @ingroup los_hw + * Check task schedule. + */ +#define LOS_CHECK_SCHEDULE ((!g_losTaskLock)) + +/* * + * @ingroup los_hw + * Define the type of a task context control block. + */ +typedef struct tagTskContext { +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + UINT32 S16; + UINT32 S17; + UINT32 S18; + UINT32 S19; + UINT32 S20; + UINT32 S21; + UINT32 S22; + UINT32 S23; + UINT32 S24; + UINT32 S25; + UINT32 S26; + UINT32 S27; + UINT32 S28; + UINT32 S29; + UINT32 S30; + UINT32 S31; +#endif + UINT32 uwR4; + UINT32 uwR5; + UINT32 uwR6; + UINT32 uwR7; + UINT32 uwR8; + UINT32 uwR9; + UINT32 uwR10; + UINT32 uwR11; + UINT32 uwPriMask; + UINT32 uwR0; + UINT32 uwR1; + UINT32 uwR2; + UINT32 uwR3; + UINT32 uwR12; + UINT32 uwLR; + UINT32 uwPC; + UINT32 uwxPSR; +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + UINT32 S0; + UINT32 S1; + UINT32 S2; + UINT32 S3; + UINT32 S4; + UINT32 S5; + UINT32 S6; + UINT32 S7; + UINT32 S8; + UINT32 S9; + UINT32 S10; + UINT32 S11; + UINT32 S12; + UINT32 S13; + UINT32 S14; + UINT32 S15; + UINT32 FPSCR; + UINT32 NO_NAME; +#endif +} TaskContext; + +/* * + * @ingroup los_hw + * @brief: Task stack initialization. + * + * @par Description: + * This API is used to initialize the task stack. + * + * @attention: + * + * + * @param taskID [IN] Type#UINT32: TaskID. + * @param stackSize [IN] Type#UINT32: Total size of the stack. + * @param topStack [IN] Type#VOID *: Top of task's stack. + * + * @retval: context Type#TaskContext *. + * @par Dependency: + * + * @see None. + */ +extern VOID *OsTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack); + +/* * + * @ingroup los_hw + * @brief: Task scheduling Function. + * + * @par Description: + * This API is used to scheduling task. + * + * @attention: + * + * + * @param None. + * + * @retval: None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsSchedule(VOID); + +/* * + * @ingroup los_hw + * @brief: Function to determine whether task scheduling is required. + * + * @par Description: + * This API is used to Judge and entry task scheduling. + * + * @attention: + * + * + * @param None. + * + * @retval: None. + * @par Dependency: + * + * @see None. + */ +extern VOID LOS_Schedule(VOID); + +/** + * @ingroup los_hw + * @brief: Function to task exit. + * + * @par Description: + * This API is used to exit task. + * + * @attention: + * + * + * @param None. + * + * @retval: None. + * @par Dependency: + * + * @see None. + */ +LITE_OS_SEC_TEXT_MINOR VOID OsTaskExit(VOID); + +/* * + * @ingroup los_hw + * @brief: The M3 wait interrupt instruction. + * + * @par Description: + * This API is used to make CPU enter to power-save mode. + * + * @attention: + * + * + * @param None. + * + * @retval: None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsEnterSleep(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_H */ + diff --git a/arch/arm/cortex-m/include/los_hwi.h b/arch/arm/cortex-m/include/los_hwi.h new file mode 100755 index 00000000..f8fabba1 --- /dev/null +++ b/arch/arm/cortex-m/include/los_hwi.h @@ -0,0 +1,720 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_hwi Hardware interrupt + * @ingroup kernel + */ +#ifndef _LOS_HWI_H +#define _LOS_HWI_H + +#include "los_base.h" +#include "los_sys.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* * + * @ingroup los_hwi + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT +#endif + +/* * + * @ingroup los_hwi + * Highest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_HIGHEST +#define OS_HWI_PRIO_HIGHEST 0 +#endif + +/* * + * @ingroup los_hwi + * Lowest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_LOWEST +#define OS_HWI_PRIO_LOWEST 7 +#endif + +/* * + * @ingroup los_config + * Configuration item for interrupt with argument + */ +#ifndef OS_HWI_WITH_ARG +#define OS_HWI_WITH_ARG NO +#endif + +/* * + * @ingroup los_hwi + * Define the type of a hardware interrupt number. + */ +typedef UINT32 HWI_HANDLE_T; + +/* * + * @ingroup los_hwi + * Define the type of a hardware interrupt priority. + */ +typedef UINT16 HWI_PRIOR_T; + +/* * + * @ingroup los_hwi + * Define the type of hardware interrupt mode configurations. + */ +typedef UINT16 HWI_MODE_T; + +/* * + * @ingroup los_hwi + * Define the type of the parameter used for the hardware interrupt creation function. The function of this parameter varies among platforms. + */ +typedef UINT32 HWI_ARG_T; + +/* * + * @ingroup los_hwi + * Define the type of a hardware interrupt handling function. + */ +#if (OS_HWI_WITH_ARG == YES) + +typedef VOID (*HWI_PROC_FUNC)(VOID *parm); +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_SLAVE_FUNC; + +#else + +typedef VOID (*HWI_PROC_FUNC)(void); + +#endif + +/* * + * @ingroup los_hwi + * Define the type of a hardware interrupt vector table function. + */ +typedef VOID (**HWI_VECTOR_FUNC)(void); + +/* * + * @ingroup los_hwi + * Count of interrupts. + */ +extern UINT32 g_vuwIntCount; + +/* * + * @ingroup los_hwi + * An interrupt is active. + */ +#define OS_INT_ACTIVE (g_vuwIntCount > 0) + +/* * + * @ingroup los_hwi + * An interrupt is inactive. + */ +#define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) + +/* * + * @ingroup los_hwi + * Count of M-Core system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 16 + +/* * + * @ingroup los_hwi + * Count of M-Core interrupt vector. + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + +/* * + * @ingroup los_hwi + * AIRCR register priority group parameter . + */ +#define OS_NVIC_AIRCR_PRIGROUP 7 + +/* * + * @ingroup los_hwi + * Boot interrupt vector table. + */ +extern UINT32 _BootVectors[]; + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable for a Cortex-A7 platform is [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Null hardware interrupt handling function. + * + * Value: 0x02000901 + * + * Solution: Pass in a valid non-null hardware interrupt handling function. + */ +#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation. + * + * Value: 0x02000902 + * + * Solution: Increase the configured maximum number of supported hardware interrupts. + */ +#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization. + * + * Value: 0x02000903 + * + * Solution: Expand the configured memory. + */ +#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created. + * + * Value: 0x02000904 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. The value range of the interrupt priority applicable for a Cortex-A7 platform is [0,15]. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Incorrect interrupt creation mode. + * + * Value: 0x02000906 + * + * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of which the value can be 0 or 1. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created as a fast interrupt. + * + * Value: 0x02000907 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) + +/* * + * @ingroup los_hwi + * SysTick control and status register. + */ +#define OS_SYSTICK_CONTROL_REG 0xE000E010 + +/* * + * @ingroup los_hw + * SysTick current value register. + */ +#define OS_SYSTICK_CURRENT_REG 0xE000E018 + +/* * + * @ingroup los_hwi + * Interrupt Priority-Level Registers. + */ +#define OS_NVIC_PRI_BASE 0xE000E400 + +/* * + * @ingroup los_hwi + * Interrupt enable register for 0-31. + */ +#define OS_NVIC_SETENA_BASE 0xE000E100 + +/* * + * @ingroup los_hwi + * interrupt pending register. + */ +#define OS_NVIC_SETPEND_BASE 0xE000E200 + +/* * + * @ingroup los_hwi + * Interrupt active register. + */ +#define OS_NVIC_INT_ACT_BASE 0xE000E300 + +/* * + * @ingroup los_hwi + * Interrupt disable register for 0-31. + */ +#define OS_NVIC_CLRENA_BASE 0xE000E180 + +/* * + * @ingroup los_hwi + * Interrupt control and status register. + */ +#define OS_NVIC_INT_CTRL 0xE000ED04 + +/* * + * @ingroup los_hwi + * Vector table offset register. + */ +#define OS_NVIC_VTOR 0xE000ED08 + +/* * + * @ingroup los_hwi + * Application interrupt and reset control register + */ +#define OS_NVIC_AIRCR 0xE000ED0C + +/* * + * @ingroup los_hwi + * System exception priority register. + */ +#define OS_NVIC_EXCPRI_BASE 0xE000ED18 + +/* * + * @ingroup los_hwi + * Interrupt No. 1 :reset. + */ +#define OS_EXC_RESET 1 + +/* * + * @ingroup los_hwi + * Interrupt No. 2 :Non-Maskable Interrupt. + */ +#define OS_EXC_NMI 2 + +/* * + * @ingroup los_hwi + * Interrupt No. 3 :(hard)fault. + */ +#define OS_EXC_HARD_FAULT 3 + +/* * + * @ingroup los_hwi + * Interrupt No. 4 :MemManage fault. + */ +#define OS_EXC_MPU_FAULT 4 + +/* * + * @ingroup los_hwi + * Interrupt No. 5 :Bus fault. + */ +#define OS_EXC_BUS_FAULT 5 + +/* * + * @ingroup los_hwi + * Interrupt No. 6 :Usage fault. + */ +#define OS_EXC_USAGE_FAULT 6 + +/* * + * @ingroup los_hwi + * Interrupt No. 11 :SVCall. + */ +#define OS_EXC_SVC_CALL 11 + +/* * + * @ingroup los_hwi + * Interrupt No. 12 :Debug monitor. + */ +#define OS_EXC_DBG_MONITOR 12 + +/* * + * @ingroup los_hwi + * Interrupt No. 14 :PendSV. + */ +#define OS_EXC_PEND_SV 14 + +/* * + * @ingroup los_hwi + * Interrupt No. 15 :SysTick. + */ +#define OS_EXC_SYS_TICK 15 + +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT]; + +#if (OS_HWI_WITH_ARG == YES) +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVectonr(num, vector, arg) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)OsInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pParm = (VOID *)arg; \ + } while(0) +#else +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVector(num, vector) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = OsInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT] = vector; \ + } while(0) +#endif + +/* * + * @ingroup los_hwi + * @brief Create a hardware interrupt. + * + * @par Description: + * This API is used to configure a hardware interrupt and register a hardware interrupt handling function. + * + * @attention + * + * + * @param hwiNum [IN] Type#HWI_HANDLE_T: hardware interrupt number. The value range applicable for a Cortex-A7 platform is [32,95]. + * @param hwiPrio [IN] Type#HWI_PRIOR_T: hardware interrupt priority. Ignore this parameter temporarily. + * @param mode [IN] Type#HWI_MODE_T: hardware interrupt mode. Ignore this parameter temporarily. + * @param handler [IN] Type#HWI_PROC_FUNC: interrupt handler used when a hardware interrupt is triggered. + * @param arg [IN] Type#HWI_ARG_T: input parameter of the interrupt handler used when a hardware interrupt is triggered. + * + * @retval #OS_ERRNO_HWI_PROC_FUNC_NULL 0x02000901: Null hardware interrupt handling function. + * @retval #OS_ERRNO_HWI_NUM_INVALID 0x02000900: Invalid interrupt number. + * @retval #OS_ERRNO_HWI_NO_MEMORY 0x02000903: Insufficient memory for hardware interrupt creation. + * @retval #OS_ERRNO_HWI_ALREADY_CREATED 0x02000904: The interrupt handler being created has already been created. + * @retval #LOS_OK 0 : The interrupt is successfully created. + * @par Dependency: + * + * @see None. + */ +extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg); + +/* * + * @ingroup los_hwi + * @brief: Hardware interrupt entry function. + * + * @par Description: + * This API is used as all hardware interrupt handling function entry. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsInterrupt(VOID); + +/* * + * @ingroup los_hwi + * @brief: Get a interrupt number. + * + * @par Description: + * This API is used to get the current interrupt number. + * + * @attention: + * + * + * @param: None. + * + * @retval: Interrupt Indexes number. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsIntNumGet(VOID); + +/* * + * @ingroup los_hwi + * @brief: Default vector handling function. + * + * @par Description: + * This API is used to configure interrupt for null function. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsHwiDefaultHandler(VOID); + +/* * + * @ingroup los_hwi + * @brief: Reset the vector table. + * + * @par Description: + * This API is used to reset the vector table. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID Reset_Handler(VOID); + +/* * + * @ingroup los_hwi + * @brief: Pended System Call. + * + * @par Description: + * PendSV can be pended and is useful for an OS to pend an exception + * so that an action can be performed after other important tasks are completed. + * + * @attention: + * + * + * @param:None. + * + * @retval:None. + * @par Dependency: + * + * @see None. + */ +extern VOID osPendSV(VOID); + +/* * + * @ingroup los_hwi + * @brief Enable all interrupts. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval CPSR value obtained after all interrupts are enabled. + * @par Dependency: + * + * @see LOS_IntRestore + */ +extern UINTPTR LOS_IntUnLock(VOID); + +/* * + * @ingroup los_hwi + * @brief Disable all interrupts. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval CPSR value obtained before all interrupts are disabled. + * @par Dependency: + * + * @see LOS_IntRestore + */ +extern UINTPTR LOS_IntLock(VOID); + +/* * + * @ingroup los_hwi + * @brief Restore interrupts. + * + * @par Description: + * + * @attention + * + * + * @param intSave [IN] CPSR value obtained before all interrupts are disabled. + * + * @retval None. + * @par Dependency: + * + * @see LOS_IntLock + */ +extern VOID LOS_IntRestore(UINTPTR intSave); + +/* * + * @ingroup los_hwi + * @brief Get value from xPSR register. + * + * @par Description: + * + * @attention + * + * + * @param cntHi [IN] CpuTick High 4 byte + * @param cntLo [IN] CpuTick Low 4 byte + * + * @retval None. + * @par Dependency: + * + * @see LOS_IntRestore + */ +extern VOID LOS_GetCpuCycle(UINT32 *cntHi, UINT32 *cntLo); + +#if (LOSCFG_KERNEL_TICKLESS == YES) +/** + * @ingroup los_hwi + * @brief reconfig systick, and clear SysTick_IRQn. + * + * @par Description: + * + * @attention + * + * + * @param cyclesPerTick [IN] Cycles Per Tick + * + * @retval None. + * @par Dependency: + * + * @see LOS_IntRestore + */ +extern VOID LOS_SysTickReload(UINT32 cyclesPerTick); +#endif + +/** + * @ingroup los_hwi + * @brief Get System cycle count. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval: The value of the system cycle count. + * @par Dependency: + * + * @see LOS_IntRestore + */ +extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); +extern VOID LOS_GetSystickCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); + +extern UINT32 LOS_SysTickCurrCycleGet(VOID); + +/* * + * @ingroup los_hwi + * @brief Delete hardware interrupt. + * + * @par Description: + * This API is used to delete hardware interrupt. + * + * @attention + * + * + * @param hwiNum [IN] Type#HWI_HANDLE_T: hardware interrupt number. The value range applicable for a Cortex-A7 platform is [32,95]. + * + * @retval #OS_ERRNO_HWI_NUM_INVALID 0x02000900: Invalid interrupt number. + * @retval #LOS_OK 0 : The interrupt is successfully delete. + * @par Dependency: + * + * @see None. + */ +extern UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HWI_H */ + diff --git a/arch/arm/cortex-m/src/los_hw.c b/arch/arm/cortex-m/src/los_hw.c new file mode 100755 index 00000000..9ce1471b --- /dev/null +++ b/arch/arm/cortex-m/src/los_hw.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_base.h" +#include "los_task_pri.h" +#include "los_hw.h" +#include "los_priqueue_pri.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* **************************************************************************** + Function : OsSchedule + Description : task scheduling + Input : None + Output : None + Return : None + **************************************************************************** */ +VOID OsSchedule(VOID) +{ + osTaskSchedule(); +} + +/* **************************************************************************** + Function : LOS_Schedule + Description : Function to determine whether task scheduling is required. + Input : None + Output : None + Return : None + **************************************************************************** */ +VOID LOS_Schedule(VOID) +{ + UINTPTR intSave; + + intSave = LOS_IntLock(); + + /* Find the highest task */ + g_losTask.newTask = LOS_DL_LIST_ENTRY(OsPriqueueTop(), LosTaskCB, pendList); + + /* In case that running is not highest then reschedule */ + if (g_losTask.runTask != g_losTask.newTask) { + if (!g_losTaskLock) { + LOS_IntRestore(intSave); + + osTaskSchedule(); + + return; + } + } + + LOS_IntRestore(intSave); +} + +/* **************************************************************************** + Function : OsTaskExit + Description : Task exit function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID OsTaskExit(VOID) +{ + __disable_irq(); + while (1) {} +} + +/* **************************************************************************** + Function : OsTskStackInit + Description : Task stack initialization function + Input : taskID --- TaskID + stackSize --- Total size of the stack + topStack --- Top of task's stack + Output : None + Return : Context pointer + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID *OsTskStackInit(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)); + +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + context->S16 = 0xAA000010; + context->S17 = 0xAA000011; + context->S18 = 0xAA000012; + context->S19 = 0xAA000013; + context->S20 = 0xAA000014; + context->S21 = 0xAA000015; + context->S22 = 0xAA000016; + context->S23 = 0xAA000017; + context->S24 = 0xAA000018; + context->S25 = 0xAA000019; + context->S26 = 0xAA00001A; + context->S27 = 0xAA00001B; + context->S28 = 0xAA00001C; + context->S29 = 0xAA00001D; + context->S30 = 0xAA00001E; + context->S31 = 0xAA00001F; + context->S0 = 0xAA000000; + context->S1 = 0xAA000001; + context->S2 = 0xAA000002; + context->S3 = 0xAA000003; + context->S4 = 0xAA000004; + context->S5 = 0xAA000005; + context->S6 = 0xAA000006; + context->S7 = 0xAA000007; + context->S8 = 0xAA000008; + context->S9 = 0xAA000009; + context->S10 = 0xAA00000A; + context->S11 = 0xAA00000B; + context->S12 = 0xAA00000C; + context->S13 = 0xAA00000D; + context->S14 = 0xAA00000E; + context->S15 = 0xAA00000F; + context->FPSCR = 0x00000000; + context->NO_NAME = 0xAA000011; +#endif + + context->uwR4 = 0x04040404L; + context->uwR5 = 0x05050505L; + context->uwR6 = 0x06060606L; + context->uwR7 = 0x07070707L; + context->uwR8 = 0x08080808L; + context->uwR9 = 0x09090909L; + context->uwR10 = 0x10101010L; + context->uwR11 = 0x11111111L; + context->uwPriMask = 0; + context->uwR0 = taskID; + context->uwR1 = 0x01010101L; + context->uwR2 = 0x02020202L; + context->uwR3 = 0x03030303L; + context->uwR12 = 0x12121212L; + context->uwLR = (UINT32)(UINTPTR)OsTaskExit; + context->uwPC = (UINT32)(UINTPTR)OsTaskEntry; + context->uwxPSR = 0x01000000L; + + return (VOID *)context; +} + +LITE_OS_SEC_TEXT_INIT VOID OsEnterSleep(VOID) +{ + __DSB(); + __WFI(); + __ISB(); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + diff --git a/arch/arm/cortex-m/src/los_hw_tick.c b/arch/arm/cortex-m/src/los_hw_tick.c new file mode 100755 index 00000000..3bc85eb4 --- /dev/null +++ b/arch/arm/cortex-m/src/los_hw_tick.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_tick_pri.h" +#include "los_base.h" +#include "los_task_pri.h" +#include "los_swtmr.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define TICK_CHECK 0x4000000 +#define CYCLE_CHECK 0xFFFFFFFFU +#define SHIFT_32_BIT 32 + + +/* **************************************************************************** +Function : OsTickStart +Description : Configure Tick Interrupt Start +Input : none +output : none +return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed +**************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 OsTickStart(VOID) +{ + UINT32 ret; + + if ((OS_SYS_CLOCK == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) { + return LOS_ERRNO_TICK_CFG_INVALID; + } + +#if (OS_HWI_WITH_ARG == YES) + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)OsTickHandler, NULL); +#else + OsSetVector(SysTick_IRQn, OsTickHandler); +#endif + + g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; + g_ullTickCount = 0; + + ret = SysTick_Config(g_cyclesPerTick); + if (ret == 1) { + return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL; + } + + return LOS_OK; +} + +#if (LOSCFG_KERNEL_TICKLESS == YES) +/* **************************************************************************** +Function : LOS_SysTickReload +Description : reconfig systick, and clear SysTick_IRQn +Input : cyclesPerTick --- cycles Per Tick +output : none +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID LOS_SysTickReload(UINT32 cyclesPerTick) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + NVIC_ClearPendingIRQ(SysTick_IRQn); + SysTick->LOAD = (UINT32)(cyclesPerTick - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} +#endif + +/* **************************************************************************** +Function : LOS_SysTickCurrCycleGet +Description : Get System cycle count +Input : none +output : none +return : hwCycle --- the system cycle count +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysTickCurrCycleGet(VOID) +{ + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + hwCycle += g_cyclesPerTick; + } + + LOS_IntRestore(intSave); + + return hwCycle; +} + +/* **************************************************************************** +Function : LOS_GetCpuCycle +Description : Get System cycle count +Input : none +output : cntHi --- CpuTick High 4 byte + cntLo --- CpuTick Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + swTick++; + } + + cycle = (((swTick) * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle)); + + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +/* **************************************************************************** +Function : LOS_GetSystickCycle +Description : Get Sys tick cycle count +Input : none +output : cntHi --- SysTick count High 4 byte + cntLo --- SysTick count Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetSystickCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + UINT32 systickLoad; + UINT32 systickCur; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + + systickLoad = SysTick->LOAD; + systickCur = SysTick->VAL; + if (systickLoad < systickCur) { + LOS_IntRestore(intSave); + return; + } + hwCycle = systickLoad - systickCur; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = systickLoad - systickCur; + swTick++; + } + + cycle = hwCycle + swTick * systickLoad; + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/arch/arm/cortex-m/src/los_hwi.c b/arch/arm/cortex-m/src/los_hwi.c new file mode 100755 index 00000000..15634883 --- /dev/null +++ b/arch/arm/cortex-m/src/los_hwi.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_hwi.h" +#include "los_sr.h" + +#if (LOSCFG_KERNEL_TICKLESS == YES) +#include "los_tickless_pri.h" +#endif +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/*lint -save -e40 -e522 -e533*/ +__weak VOID SysTickHandler(VOID) +{ + return; +} + +UINT32 g_vuwIntCount = 0; +/*lint -restore*/ +#ifdef __ICCARM__ +#pragma location = ".data.vector" +#elif defined(__CC_ARM) || defined(__GNUC__) +LITE_OS_SEC_VEC +#endif + +HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = { + (HWI_PROC_FUNC)0, // [0] Top of Stack + (HWI_PROC_FUNC)Reset_Handler, // [1] reset + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [2] NMI Handler + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [3] Hard Fault Handler + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [4] MPU Fault Handler + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [5] Bus Fault Handler + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [6] Usage Fault Handler + (HWI_PROC_FUNC)0, // [7] Reserved + (HWI_PROC_FUNC)0, // [8] Reserved + (HWI_PROC_FUNC)0, // [9] Reserved + (HWI_PROC_FUNC)0, // [10] Reserved + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [11] SVCall Handler + (HWI_PROC_FUNC)OsHwiDefaultHandler, // [12] Debug Monitor Handler + (HWI_PROC_FUNC)0, // [13] Reserved + (HWI_PROC_FUNC)osPendSV, // [14] PendSV Handler + (HWI_PROC_FUNC)SysTickHandler, // [15] SysTick Handler +}; +#if (OS_HWI_WITH_ARG == YES) +HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; +#else +HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +#endif + +/* **************************************************************************** + Function : OsIntNumGet + Description : Get a interrupt number + Input : None + Output : None + Return : Interrupt Indexes number + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 OsIntNumGet(VOID) +{ + return __get_IPSR(); +} + +/* **************************************************************************** + Function : OsHwiDefaultHandler + Description : default handler of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +/*lint -e529*/ +LITE_OS_SEC_TEXT_MINOR VOID OsHwiDefaultHandler(VOID) +{ + UINT32 irqNum = OsIntNumGet(); + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); + while (1) {} +} + +/* **************************************************************************** + Function : OsInterrupt + Description : Hardware interrupt entry function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT VOID OsInterrupt(VOID) +{ + UINT32 hwiIndex; + UINT32 intSave; + +#if (LOSCFG_KERNEL_RUNSTOP == YES) + SCB->SCR &= (UINT32) ~((UINT32)SCB_SCR_SLEEPDEEP_Msk); +#endif + + intSave = LOS_IntLock(); + + g_vuwIntCount++; + + LOS_IntRestore(intSave); + + hwiIndex = OsIntNumGet(); +#if (LOSCFG_KERNEL_TICKLESS == YES) + osUpdateKernelTickCount(hwiIndex); +#endif + +#if (OS_HWI_WITH_ARG == YES) + if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { + g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + } +#else + if (g_hwiSlaveForm[hwiIndex] != 0) { + g_hwiSlaveForm[hwiIndex](); + } +#endif + intSave = LOS_IntLock(); + g_vuwIntCount--; + LOS_IntRestore(intSave); +} + +/* **************************************************************************** + Function : OsHwiInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID OsHwiInit() +{ + UINT32 index; + + for (index = OS_SYS_VECTOR_CNT; index < OS_VECTOR_CNT; index++) { + g_hwiForm[index] = (HWI_PROC_FUNC)OsHwiDefaultHandler; + } + + /* Interrupt vector table location */ + SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; +#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ + NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); +#endif + + return; +} +/* **************************************************************************** + Function : LOS_HwiCreate + Description : create hardware interrupt + Input : hwiNum --- hwi num to create + hwiPrio --- priority of the hwi + mode --- unused + handler --- hwi handler + arg --- param of the hwi handler + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) +{ + UINTPTR intSave; + + if (handler == NULL) { + return OS_ERRNO_HWI_PROC_FUNC_NULL; + } + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)OsHwiDefaultHandler) { + return OS_ERRNO_HWI_ALREADY_CREATED; + } + + if (hwiPrio > OS_HWI_PRIO_LOWEST) { + return OS_ERRNO_HWI_PRIO_INVALID; + } + + intSave = LOS_IntLock(); +#if (OS_HWI_WITH_ARG == YES) + OsSetVector(hwiNum, handler, arg); +#else + OsSetVector(hwiNum, handler); +#endif + NVIC_EnableIRQ((IRQn_Type)hwiNum); + NVIC_SetPriority((IRQn_Type)hwiNum, hwiPrio); + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/* **************************************************************************** + Function : LOS_HwiDelete + Description : Delete hardware interrupt + Input : hwiNum --- hwi num to delete + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + NVIC_DisableIRQ((IRQn_Type)hwiNum); + + intSave = LOS_IntLock(); + + g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)OsHwiDefaultHandler; + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + diff --git a/arch/risc-v/BUILD.gn b/arch/risc-v/BUILD.gn new file mode 100755 index 00000000..e69de29b diff --git a/components/BUILD.gn b/components/BUILD.gn new file mode 100755 index 00000000..3e40a6c1 --- /dev/null +++ b/components/BUILD.gn @@ -0,0 +1,83 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("//build/lite/config/component/lite_component.gni") + +source_set("sec") { + + sources = [ + "cmsis/cmsis_liteos.c", + "../../../third_party/bounds_checking_function/src/fscanf_s.c", + "../../../third_party/bounds_checking_function/src/fwscanf_s.c", + "../../../third_party/bounds_checking_function/src/gets_s.c", + "../../../third_party/bounds_checking_function/src/memcpy_s.c", + "../../../third_party/bounds_checking_function/src/memmove_s.c", + "../../../third_party/bounds_checking_function/src/memset_s.c", + "../../../third_party/bounds_checking_function/src/scanf_s.c", + "../../../third_party/bounds_checking_function/src/securecutil.c", + "../../../third_party/bounds_checking_function/src/secureinput_a.c", + "../../../third_party/bounds_checking_function/src/secureinput_w.c", + "../../../third_party/bounds_checking_function/src/secureprintoutput_a.c", + "../../../third_party/bounds_checking_function/src/secureprintoutput_w.c", + "../../../third_party/bounds_checking_function/src/snprintf_s.c", + "../../../third_party/bounds_checking_function/src/sprintf_s.c", + "../../../third_party/bounds_checking_function/src/sscanf_s.c", + "../../../third_party/bounds_checking_function/src/strcat_s.c", + "../../../third_party/bounds_checking_function/src/strcpy_s.c", + "../../../third_party/bounds_checking_function/src/strncat_s.c", + "../../../third_party/bounds_checking_function/src/strncpy_s.c", + "../../../third_party/bounds_checking_function/src/strtok_s.c", + "../../../third_party/bounds_checking_function/src/swprintf_s.c", + "../../../third_party/bounds_checking_function/src/swscanf_s.c", + "../../../third_party/bounds_checking_function/src/vfscanf_s.c", + "../../../third_party/bounds_checking_function/src/vfwscanf_s.c", + "../../../third_party/bounds_checking_function/src/vscanf_s.c", + "../../../third_party/bounds_checking_function/src/vsnprintf_s.c", + "../../../third_party/bounds_checking_function/src/vsprintf_s.c", + "../../../third_party/bounds_checking_function/src/vsscanf_s.c", + "../../../third_party/bounds_checking_function/src/vswprintf_s.c", + "../../../third_party/bounds_checking_function/src/vswscanf_s.c", + "../../../third_party/bounds_checking_function/src/vwscanf_s.c", + "../../../third_party/bounds_checking_function/src/wcscat_s.c", + "../../../third_party/bounds_checking_function/src/wcscpy_s.c", + "../../../third_party/bounds_checking_function/src/wcsncat_s.c", + "../../../third_party/bounds_checking_function/src/wcsncpy_s.c", + "../../../third_party/bounds_checking_function/src/wcstok_s.c", + "../../../third_party/bounds_checking_function/src/wmemcpy_s.c", + "../../../third_party/bounds_checking_function/src/wmemmove_s.c", + "../../../third_party/bounds_checking_function/src/wscanf_s.c", + ] +} + +lite_component("components") { + features = [ + ":sec" + ] + +} diff --git a/components/cmsis/2.0/cmsis_liteos2.c b/components/cmsis/2.0/cmsis_liteos2.c new file mode 100755 index 00000000..1e609423 --- /dev/null +++ b/components/cmsis/2.0/cmsis_liteos2.c @@ -0,0 +1,1410 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "cmsis_os.h" +#include "los_typedef.h" +#include "los_printf.h" + +#include "los_event.h" +#include "los_membox.h" +#include "los_memory.h" +#include "los_hwi.h" + +#include "los_mux_pri.h" +#include "los_queue_pri.h" +#include "los_sem_pri.h" +#include "los_swtmr_pri.h" +#include "los_sys_pri.h" +#include "los_task_pri.h" +#include "los_tick_pri.h" +#include "string.h" +#include "securec.h" +#include "system_config.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#if (CMSIS_OS_VER == 2) + +/* Kernel initialization state */ +static osKernelState_t g_kernelState; + +extern BOOL g_taskScheduled; + +#define LOS_PRIORITY_WIN 8 + +const osVersion_t g_stLosVersion = { 001, 001 }; + +#define LITEOS_VERSION_MAJOR 1 +#define LITEOS_VERSION_MINOR 0 +#define LITEOS_VERSION_BUILD 0 + +/* Kernel version and identification string definition */ +#define KERNEL_VERSION (((UINT32)LITEOS_VERSION_MAJOR * 10000000UL) | \ + ((UINT32)LITEOS_VERSION_MINOR * 10000UL) | \ + ((UINT32)LITEOS_VERSION_BUILD * 1UL)) + +#define KERNEL_ID "HUAWEI-LiteOS" +#define UNUSED(var) do { (void)var; } while(0) + +// ==== Kernel Management Functions ==== +uint32_t osTaskStackWaterMarkGet(UINT32 taskID); + + +osStatus_t osKernelInitialize(void) +{ + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (g_kernelState != osKernelInactive) { + return osError; + } + + if (LOS_OK == LOS_KernelInit()) { + g_kernelState = osKernelReady; + return osOK; + } else { + return osError; + } +} + + +osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size) +{ + uint32_t uwRet; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (version != NULL) { + version->api = g_stLosVersion.api; + version->kernel = g_stLosVersion.kernel; + } + + if ((id_buf != NULL) && (id_size != 0U)) { + if (id_size > sizeof(KERNEL_ID)) { + id_size = sizeof(KERNEL_ID); + } + uwRet = memcpy_s(id_buf, id_size, KERNEL_ID, id_size); + if (uwRet != EOK) { + PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, uwRet); + return osError; + } + } + + return osOK; +} + + +osKernelState_t osKernelGetState(void) +{ + if (OS_INT_ACTIVE) { + return osKernelError; + } + + if (!g_taskScheduled) { + if (g_kernelState == osKernelReady) { + return osKernelReady; + } else { + return osKernelInactive; + } + } else if (g_losTaskLock > 0) { + return osKernelLocked; + } else { + return osKernelRunning; + } +} + + +osStatus_t osKernelStart(void) +{ + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (g_kernelState == osKernelReady) { + if (LOS_OK == LOS_Start()) { + g_kernelState = osKernelRunning; + return osOK; + } else { + return osError; + } + } else { + return osError; + } +} + + +int32_t osKernelLock(void) +{ + int32_t lock; + + if (OS_INT_ACTIVE) { + return (int32_t)osErrorISR; + } + + if (!g_taskScheduled) { + return (int32_t)osError; + } + + if (g_losTaskLock > 0) { + lock = 1; + } else { + LOS_TaskLock(); + lock = 0; + } + + return lock; +} + + +int32_t osKernelUnlock(void) +{ + int32_t lock; + + if (OS_INT_ACTIVE) { + return (int32_t)osErrorISR; + } + + if (!g_taskScheduled) { + return (int32_t)osError; + } + + if (g_losTaskLock > 0) { + LOS_TaskUnlock(); + if (g_losTaskLock != 0) { + return (int32_t)osError; + } + lock = 1; + } else { + lock = 0; + } + + return lock; +} + + +int32_t osKernelRestoreLock(int32_t lock) +{ + if (OS_INT_ACTIVE) { + return (int32_t)osErrorISR; + } + + if (!g_taskScheduled) { + return (int32_t)osError; + } + + switch (lock) { + case 0: + LOS_TaskUnlock(); + if (g_losTaskLock != 0) { + break; + } + return 0; + case 1: + LOS_TaskLock(); + return 1; + default: + break; + } + + return (int32_t)osError; +} + + +uint32_t osKernelGetTickCount(void) +{ + uint64_t ticks; + UINTPTR uvIntSave; + + if (OS_INT_ACTIVE) { +#ifndef LITEOS_WIFI_IOT_VERSION + ticks = g_ullTickCount; +#else + ticks = g_tickCount; +#endif + } else { + uvIntSave = LOS_IntLock(); +#ifndef LITEOS_WIFI_IOT_VERSION + ticks = g_ullTickCount; +#else + ticks = g_tickCount; +#endif + LOS_IntRestore(uvIntSave); + } + + return (uint32_t)ticks; +} + +uint32_t osKernelGetTickFreq(void) +{ + uint32_t freq; + + if (OS_INT_ACTIVE) { + freq = 0U; + } else { + freq = LOSCFG_BASE_CORE_TICK_PER_SECOND; + } + + return (freq); +} + +extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); +uint32_t osKernelGetSysTimerCount(void) +{ + uint32_t countHigh = 0; + uint32_t countLow = 0; + if (OS_INT_ACTIVE) { + countLow = 0U; + } else { + LOS_GetCpuCycle((UINT32 *)&countHigh, (UINT32 *)&countLow); + } + return countLow; +} + + +uint32_t osKernelGetSysTimerFreq(void) +{ + return OS_SYS_CLOCK; +} + + +// ==== Thread Management Functions ==== + +osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) +{ + UINT32 uwTid; + UINT32 uwRet; + LosTaskCB *pstTaskCB = NULL; + TSK_INIT_PARAM_S stTskInitParam; + + if (OS_INT_ACTIVE) { + return NULL; + } + + if ((attr == NULL) || (func == NULL) || (attr->priority < osPriorityLow1) || + (attr->priority > osPriorityAboveNormal6)) { + return (osThreadId_t)NULL; + } + + (void)memset_s(&stTskInitParam, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)func; +#ifndef LITEOS_WIFI_IOT_VERSION + stTskInitParam.uwArg = (UINT32)argument; +#else + stTskInitParam.auwArgs[0] = (UINT32)argument; +#endif + stTskInitParam.uwStackSize = attr->stack_size; + stTskInitParam.pcName = (CHAR *)attr->name; + stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - ((UINT16)(attr->priority) - LOS_PRIORITY_WIN); /* 0~31 */ + + uwRet = LOS_TaskCreate(&uwTid, &stTskInitParam); + + if (LOS_OK != uwRet) { + return (osThreadId_t)NULL; + } + + pstTaskCB = OS_TCB_FROM_TID(uwTid); + + return (osThreadId_t)pstTaskCB; +} + + +const char *osThreadGetName(osThreadId_t thread_id) +{ + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE || thread_id == NULL) { + return NULL; + } + + pstTaskCB = (LosTaskCB *)thread_id; + + return pstTaskCB->taskName; +} + + +osThreadId_t osThreadGetId(void) +{ + if (OS_INT_ACTIVE) { + return NULL; + } + + return (osThreadId_t)(g_losTask.runTask); +} + +void *osThreadGetArgument(void) +{ + if (OS_INT_ACTIVE) { + return 0; + } + + LosTaskCB *taskCb = (LosTaskCB *)osThreadGetId(); + if (taskCb == NULL) { + return NULL; + } +#ifndef LITEOS_WIFI_IOT_VERSION + return (void *)(taskCb->arg); +#else + return (void *)(taskCb->args[0]); +#endif +} + +osThreadState_t osThreadGetState(osThreadId_t thread_id) +{ + UINT16 taskStatus; + osThreadState_t stState; + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE || thread_id == NULL) { + return osThreadError; + } + + pstTaskCB = (LosTaskCB *)thread_id; + taskStatus = pstTaskCB->taskStatus; + + if (taskStatus & OS_TASK_STATUS_RUNNING) { + stState = osThreadRunning; + } else if (taskStatus & OS_TASK_STATUS_READY) { + stState = osThreadReady; + } else if (taskStatus & + (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND | OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND_QUEUE)) { + stState = osThreadBlocked; + } else if (taskStatus & OS_TASK_STATUS_UNUSED) { + stState = osThreadInactive; + } else { + stState = osThreadError; + } + + return stState; +} + + +uint32_t osThreadGetStackSize(osThreadId_t thread_id) +{ + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE || thread_id == NULL) { + return 0U; + } + + pstTaskCB = (LosTaskCB *)thread_id; + + return pstTaskCB->stackSize; +} + + +uint32_t osTaskStackWaterMarkGet(UINT32 taskID) +{ + UINT32 uwCount = 0; + UINT32 *ptopOfStack; + UINTPTR uvIntSave; + LosTaskCB *pstTaskCB = NULL; + + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return 0; + } + + uvIntSave = LOS_IntLock(); + + pstTaskCB = OS_TCB_FROM_TID(taskID); + if (OS_TASK_STATUS_UNUSED & (pstTaskCB->taskStatus)) { + LOS_IntRestore(uvIntSave); + return 0; + } + + // first 4 bytes is OS_TASK_MAGIC_WORD, skip + ptopOfStack = (UINT32 *)(UINTPTR)pstTaskCB->topOfStack + 1; + + while (*ptopOfStack == (UINT32)OS_TASK_STACK_INIT) { + ++ptopOfStack; + ++uwCount; + } + + uwCount *= sizeof(UINT32); + + LOS_IntRestore(uvIntSave); + return uwCount; +} + + +uint32_t osThreadGetStackSpace(osThreadId_t thread_id) +{ + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE || thread_id == NULL) { + return 0U; + } + + pstTaskCB = (LosTaskCB *)thread_id; + + return osTaskStackWaterMarkGet(pstTaskCB->taskID); +} + + +osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority) +{ + UINT32 uwRet; + UINT16 usPriority; + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (thread_id == NULL) { + return osErrorParameter; + } + + if (priority < osPriorityLow1 || priority > osPriorityAboveNormal6) { + return osErrorParameter; + } + + pstTaskCB = (LosTaskCB *)thread_id; + usPriority = OS_TASK_PRIORITY_LOWEST - ((UINT16)priority - LOS_PRIORITY_WIN); + uwRet = LOS_TaskPriSet(pstTaskCB->taskID, usPriority); + switch (uwRet) { + case LOS_ERRNO_TSK_PRIOR_ERROR: + case LOS_ERRNO_TSK_OPERATE_IDLE: + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + + case LOS_ERRNO_TSK_NOT_CREATED: + return osErrorResource; + + default: + return osOK; + } +} + + +osPriority_t osThreadGetPriority(osThreadId_t thread_id) +{ + UINT16 usRet; + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE || thread_id == NULL) { + return osPriorityError; + } + + pstTaskCB = (LosTaskCB *)thread_id; + usRet = LOS_TaskPriGet(pstTaskCB->taskID); + + if (usRet == (UINT16)OS_INVALID) { + return osPriorityError; + } + + return (osPriority_t)(OS_TASK_PRIORITY_LOWEST - (usRet - LOS_PRIORITY_WIN)); +} + + +osStatus_t osThreadYield(void) +{ + UINT32 uwRet; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + uwRet = LOS_TaskYield(); + + if (uwRet == LOS_OK) { + return osOK; + } + + return osError; +} + + +osStatus_t osThreadSuspend(osThreadId_t thread_id) +{ + UINT32 uwRet; + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (thread_id == NULL) { + return osErrorParameter; + } + + pstTaskCB = (LosTaskCB *)thread_id; + uwRet = LOS_TaskSuspend(pstTaskCB->taskID); + switch (uwRet) { + case LOS_ERRNO_TSK_OPERATE_IDLE: + case LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED: + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + + case LOS_ERRNO_TSK_NOT_CREATED: + case LOS_ERRNO_TSK_ALREADY_SUSPENDED: + case LOS_ERRNO_TSK_SUSPEND_LOCKED: + return osErrorResource; + + default: + return osOK; + } +} + + +osStatus_t osThreadResume(osThreadId_t thread_id) +{ + UINT32 uwRet; + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (thread_id == NULL) { + return osErrorParameter; + } + + pstTaskCB = (LosTaskCB *)thread_id; + uwRet = LOS_TaskResume(pstTaskCB->taskID); + + switch (uwRet) { + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + + case LOS_ERRNO_TSK_NOT_CREATED: + case LOS_ERRNO_TSK_NOT_SUSPENDED: + return osErrorResource; + + default: + return osOK; + } +} + + +osStatus_t osThreadTerminate(osThreadId_t thread_id) +{ + UINT32 uwRet; + LosTaskCB *pstTaskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (thread_id == NULL) { + return osErrorParameter; + } + + pstTaskCB = (LosTaskCB *)thread_id; + uwRet = LOS_TaskDelete(pstTaskCB->taskID); + + switch (uwRet) { + case LOS_ERRNO_TSK_OPERATE_IDLE: + case LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED: + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + + case LOS_ERRNO_TSK_NOT_CREATED: + return osErrorResource; + + default: + return osOK; + } +} + + +uint32_t osThreadGetCount(void) +{ + uint32_t uwCount = 0; + + if (OS_INT_ACTIVE) { + return 0U; + } + + for (uint32_t index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (!((g_taskCBArray + index)->taskStatus & OS_TASK_STATUS_UNUSED)) { + uwCount++; + } + } + + return uwCount; +} + + +// ==== Generic Wait Functions ==== +WEAK UINT32 LOS_HalDelay(UINT32 ticks) +{ + UNUSED(ticks); + return LOS_ERRNO_TSK_DELAY_IN_INT; +} + + +osStatus_t osDelay(uint32_t ticks) +{ + UINT32 uwRet = 0; + if (ticks == 0) { + return osOK; + } + if (osKernelGetState() != osKernelRunning) { + uwRet = LOS_HalDelay(ticks); + } else { + uwRet = LOS_TaskDelay(ticks); + } + if (uwRet == LOS_OK) { + return osOK; + } else { + return osError; + } +} + + +osStatus_t osDelayUntil(uint32_t ticks) +{ + UINT32 uwRet; + UINT32 uwTicks; + UINT32 tickCount = osKernelGetTickCount(); + + if (ticks < tickCount) { + return osError; + } + + uwTicks = (UINT32)(ticks - tickCount); + + uwRet = LOS_TaskDelay(uwTicks); + if (uwRet == LOS_OK) { + return osOK; + } else { + return osError; + } +} + +// ==== Timer Management Functions ==== +#if (LOSCFG_BASE_CORE_SWTMR == YES) +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +osTimerId_t osTimerExtNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr, + os_timer_rouses_type ucRouses, os_timer_align_type ucSensitive) +{ + UNUSED(attr); + UINT16 usSwTmrID; + UINT8 mode; + + if ((OS_INT_ACTIVE) || (NULL == func) || ((osTimerOnce != type) && (osTimerPeriodic != type))) { + return (osTimerId_t)NULL; + } + + if (osTimerOnce == type) { + mode = LOS_SWTMR_MODE_NO_SELFDELETE; + } else { + mode = LOS_SWTMR_MODE_PERIOD; + } + if (LOS_OK != LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, &usSwTmrID, (UINT32)(UINTPTR)argument, ucRouses, ucSensitive)) { + return (osTimerId_t)NULL; + } + + return (osTimerId_t)OS_SWT_FROM_SID(usSwTmrID); +} +#endif +osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) +{ + UNUSED(attr); + UINT16 usSwTmrID; + UINT8 mode; + + if ((OS_INT_ACTIVE) || (NULL == func) || ((osTimerOnce != type) && (osTimerPeriodic != type))) { + return (osTimerId_t)NULL; + } + + if (osTimerOnce == type) { + mode = LOS_SWTMR_MODE_NO_SELFDELETE; + } else { + mode = LOS_SWTMR_MODE_PERIOD; + } +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + if (LOS_OK != LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, &usSwTmrID, (UINT32)(UINTPTR)argument, + osTimerRousesAllow, osTimerAlignIgnore)) { + return (osTimerId_t)NULL; + } +#else + if (LOS_OK != LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, &usSwTmrID, (UINT32)(UINTPTR)argument)) { + return (osTimerId_t)NULL; + } +#endif + + return (osTimerId_t)OS_SWT_FROM_SID(usSwTmrID); +} + +osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks) +{ + UINT32 uwRet; + SWTMR_CTRL_S *pstSwtmr; + + if ((0 == ticks) || (NULL == timer_id)) { + return osErrorParameter; + } + + pstSwtmr = (SWTMR_CTRL_S *)timer_id; + pstSwtmr->uwInterval = ticks; + uwRet = LOS_SwtmrStart(pstSwtmr->usTimerID); + if (LOS_OK == uwRet) { + return osOK; + } else if (LOS_ERRNO_SWTMR_ID_INVALID == uwRet) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + + +const char *osTimerGetName(osTimerId_t timer_id) +{ + UNUSED(timer_id); + return (const char *)NULL; +} + + +osStatus_t osTimerStop(osTimerId_t timer_id) +{ + UINT32 uwRet; + SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)timer_id; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (NULL == pstSwtmr) { + return osErrorParameter; + } + + uwRet = LOS_SwtmrStop(pstSwtmr->usTimerID); + if (LOS_OK == uwRet) { + return osOK; + } else if (LOS_ERRNO_SWTMR_ID_INVALID == uwRet) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + + +uint32_t osTimerIsRunning(osTimerId_t timer_id) +{ + if ((OS_INT_ACTIVE) || (NULL == timer_id)) { + return 0; + } + + return (OS_SWTMR_STATUS_TICKING == ((SWTMR_CTRL_S *)timer_id)->ucState); +} + + +osStatus_t osTimerDelete(osTimerId_t timer_id) +{ + UINT32 uwRet; + SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)timer_id; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (NULL == pstSwtmr) { + return osErrorParameter; + } + + uwRet = LOS_SwtmrDelete(pstSwtmr->usTimerID); + if (LOS_OK == uwRet) { + return osOK; + } else if (LOS_ERRNO_SWTMR_ID_INVALID == uwRet) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +#endif + +osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr) +{ + PEVENT_CB_S pstEventCB; + UINT32 uwRet; + + UNUSED(attr); + + if (OS_INT_ACTIVE) { + return (osEventFlagsId_t)NULL; + } + + pstEventCB = (PEVENT_CB_S)LOS_MemAlloc(m_aucSysMem0, sizeof(EVENT_CB_S)); + if (pstEventCB == NULL) { + return (osEventFlagsId_t)NULL; + } + + uwRet = LOS_EventInit(pstEventCB); + if (uwRet == LOS_ERRNO_EVENT_PTR_NULL) { + return (osEventFlagsId_t)NULL; + } else { + return (osEventFlagsId_t)pstEventCB; + } +} + + +const char *osEventFlagsGetName(osEventFlagsId_t ef_id) +{ + UNUSED(ef_id); + + if (OS_INT_ACTIVE) { + return (const char *)NULL; + } + + return (const char *)NULL; +} + + +uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) +{ + PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id; + UINT32 uwRet; + uint32_t rflags; + if (pstEventCB == NULL) { + return osFlagsErrorParameter; + } + uwRet = LOS_EventWrite(pstEventCB, (UINT32)flags); + if (uwRet != LOS_OK) { + return (uint32_t)osFlagsErrorParameter; + } else { + rflags = pstEventCB->uwEventID; + return rflags; + } +} + + +uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags) +{ + PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id; + UINTPTR uwIntSave; + uint32_t rflags; + UINT32 uwRet; + + if (pstEventCB == NULL) { + return (uint32_t)osFlagsErrorParameter; + } + + uwIntSave = LOS_IntLock(); + rflags = pstEventCB->uwEventID; + + uwRet = LOS_EventClear(pstEventCB, ~flags); + LOS_IntRestore(uwIntSave); + if (uwRet != LOS_OK) { + return (uint32_t)osFlagsErrorParameter; + } else { + return rflags; + } +} + + +uint32_t osEventFlagsGet(osEventFlagsId_t ef_id) +{ + PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id; + UINTPTR uwIntSave; + uint32_t rflags; + + if (pstEventCB == NULL) { + return (uint32_t)osFlagsErrorParameter; + } + + uwIntSave = LOS_IntLock(); + rflags = pstEventCB->uwEventID; + LOS_IntRestore(uwIntSave); + + return rflags; +} + +uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) +{ + PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id; + UINT32 uwMode = 0; + UINT32 uwRet; + uint32_t rflags; + + if (options > (osFlagsWaitAny | osFlagsWaitAll | osFlagsNoClear)) { + return (uint32_t)osFlagsErrorParameter; + } + + if ((options & osFlagsWaitAll) == osFlagsWaitAll) { + uwMode |= LOS_WAITMODE_AND; + } else { + uwMode |= LOS_WAITMODE_OR; + } + + if ((options & osFlagsNoClear) == osFlagsNoClear) { + uwMode &= ~LOS_WAITMODE_CLR; + } else { + uwMode |= LOS_WAITMODE_CLR; + } + + uwRet = LOS_EventRead(pstEventCB, (UINT32)flags, uwMode, (UINT32)timeout); + switch (uwRet) { + case LOS_ERRNO_EVENT_PTR_NULL: + case LOS_ERRNO_EVENT_EVENTMASK_INVALID: + case LOS_ERRNO_EVENT_SETBIT_INVALID: + return (uint32_t)osFlagsErrorParameter; + + case LOS_ERRNO_EVENT_READ_IN_INTERRUPT: + case LOS_ERRNO_EVENT_FLAGS_INVALID: + case LOS_ERRNO_EVENT_READ_IN_LOCK: + return (uint32_t)osFlagsErrorResource; + + case LOS_ERRNO_EVENT_READ_TIMEOUT: + return (uint32_t)osFlagsErrorTimeout; + + default: + rflags = (uint32_t)uwRet; + return rflags; + } +} + +osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id) +{ + PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id; + UINTPTR uwIntSave; + osStatus_t uwRet; + + uwIntSave = LOS_IntLock(); + if (LOS_EventDestroy(pstEventCB) == LOS_OK) { + uwRet = osOK; + } else { + uwRet = osErrorParameter; + } + LOS_IntRestore(uwIntSave); + + if (LOS_MemFree(m_aucSysMem0, (void *)pstEventCB) == LOS_OK) { + uwRet = osOK; + } else { + uwRet = osErrorParameter; + } + + return uwRet; +} + +// ==== Mutex Management Functions ==== +#if (LOSCFG_BASE_IPC_MUX == YES) +osMutexId_t osMutexNew(const osMutexAttr_t *attr) +{ + UINT32 uwRet; + UINT32 uwMuxId; + + UNUSED(attr); + + if (OS_INT_ACTIVE) { + return NULL; + } + + uwRet = LOS_MuxCreate(&uwMuxId); + if (uwRet == LOS_OK) { + return (osMutexId_t)(GET_MUX(uwMuxId)); + } else { + return (osMutexId_t)NULL; + } +} + + +osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) +{ + UINT32 uwRet; + + if (mutex_id == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) { + timeout = 0; + } + + uwRet = LOS_MuxPend(((LosMuxCB *)mutex_id)->muxID, timeout); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_MUX_TIMEOUT) { + return osErrorTimeout; + } else if (uwRet == LOS_ERRNO_MUX_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + + +osStatus_t osMutexRelease(osMutexId_t mutex_id) +{ + UINT32 uwRet; + + if (mutex_id == NULL) { + return osErrorParameter; + } + + uwRet = LOS_MuxPost(((LosMuxCB *)mutex_id)->muxID); + if (uwRet == LOS_OK) { + return osOK; + } else { + return osErrorResource; + } +} + + +osThreadId_t osMutexGetOwner(osMutexId_t mutex_id) +{ + UINT32 uwIntSave; + LosTaskCB *pstTaskCB; + + if (OS_INT_ACTIVE) { + return NULL; + } + + if (mutex_id == NULL) { + return NULL; + } + + uwIntSave = LOS_IntLock(); + pstTaskCB = ((LosMuxCB *)mutex_id)->owner; + LOS_IntRestore(uwIntSave); + + return (osThreadId_t)pstTaskCB; +} + + +osStatus_t osMutexDelete(osMutexId_t mutex_id) +{ + UINT32 uwRet; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (mutex_id == NULL) { + return osErrorParameter; + } + + uwRet = LOS_MuxDelete(((LosMuxCB *)mutex_id)->muxID); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_MUX_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +#endif + +// ==== Semaphore Management Functions ==== +#if (LOSCFG_BASE_IPC_SEM == YES) + +osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) +{ + UINT32 uwRet; + UINT32 uwSemId; + + UNUSED(attr); + + if (OS_INT_ACTIVE) { + return (osSemaphoreId_t)NULL; + } + + if (1 == max_count) { + uwRet = LOS_BinarySemCreate((UINT16)initial_count, &uwSemId); + } else { + uwRet = LOS_SemCreate((UINT16)initial_count, &uwSemId); + } + + if (uwRet == LOS_OK) { + return (osSemaphoreId_t)(GET_SEM(uwSemId)); + } else { + return (osSemaphoreId_t)NULL; + } +} + + +osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) +{ + UINT32 uwRet; + + if (semaphore_id == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) { + return osErrorISR; + } + + uwRet = LOS_SemPend(((LosSemCB *)semaphore_id)->semID, timeout); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_SEM_TIMEOUT) { + return osErrorTimeout; + } else if (uwRet == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else if (uwRet == LOS_ERRNO_SEM_PEND_INTERR) { + return osErrorISR; + } else { + return osErrorResource; + } +} + + +osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) +{ + UINT32 uwRet; + + if (semaphore_id == NULL) { + return osErrorParameter; + } + + uwRet = LOS_SemPost(((LosSemCB *)semaphore_id)->semID); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + + +uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id) +{ + UINT32 uwIntSave; + UINT32 uwCount; + + if (OS_INT_ACTIVE) { + return 0; + } + + if (semaphore_id == NULL) { + return 0; + } + + uwIntSave = LOS_IntLock(); + uwCount = ((LosSemCB *)semaphore_id)->semCount; + LOS_IntRestore(uwIntSave); + + return uwCount; +} + + +osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) +{ + UINT32 uwRet; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (semaphore_id == NULL) { + return osErrorParameter; + } + + uwRet = LOS_SemDelete(((LosSemCB *)semaphore_id)->semID); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +#endif + + +// ==== Message Queue Management Functions ==== +#if (LOSCFG_BASE_IPC_QUEUE == YES) +osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) +{ + UINT32 uwQueueID; + UINT32 uwRet; + UNUSED(attr); + osMessageQueueId_t handle; + + if (0 == msg_count || 0 == msg_size || OS_INT_ACTIVE) { + return (osMessageQueueId_t)NULL; + } + + uwRet = LOS_QueueCreate((char *)NULL, (UINT16)msg_count, &uwQueueID, 0, (UINT16)msg_size); + if (uwRet == LOS_OK) { + handle = (osMessageQueueId_t)(GET_QUEUE_HANDLE(uwQueueID)); + } else { + handle = (osMessageQueueId_t)NULL; + } + + return handle; +} + + +osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) +{ + UNUSED(msg_prio); + UINT32 uwRet; + UINT32 uwBufferSize; + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + + if (pstQueue == NULL || msg_ptr == NULL || ((OS_INT_ACTIVE) && (0 != timeout))) { + return osErrorParameter; + } + if (pstQueue->queueSize < sizeof(UINT32)) { + return osErrorParameter; + } + uwBufferSize = (UINT32)(pstQueue->queueSize - sizeof(UINT32)); + uwRet = LOS_QueueWriteCopy((UINT32)pstQueue->queueID, (void *)msg_ptr, uwBufferSize, timeout); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_QUEUE_INVALID || uwRet == LOS_ERRNO_QUEUE_NOT_CREATE) { + return osErrorParameter; + } else if (uwRet == LOS_ERRNO_QUEUE_TIMEOUT) { + return osErrorTimeout; + } else { + return osErrorResource; + } +} + + +osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) +{ + UNUSED(msg_prio); + UINT32 uwRet; + UINT32 uwBufferSize; + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + + if (pstQueue == NULL || msg_ptr == NULL || ((OS_INT_ACTIVE) && (0 != timeout))) { + return osErrorParameter; + } + + uwBufferSize = (UINT32)(pstQueue->queueSize - sizeof(UINT32)); + uwRet = LOS_QueueReadCopy((UINT32)pstQueue->queueID, msg_ptr, &uwBufferSize, timeout); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_QUEUE_INVALID || uwRet == LOS_ERRNO_QUEUE_NOT_CREATE) { + return osErrorParameter; + } else if (uwRet == LOS_ERRNO_QUEUE_TIMEOUT) { + return osErrorTimeout; + } else { + return osErrorResource; + } +} + +uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id) +{ + uint32_t capacity; + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + + if (pstQueue == NULL) { + capacity = 0U; + } else { + capacity = pstQueue->queueLen; + } + + return (capacity); +} + +uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id) +{ + uint32_t size; + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + + if (pstQueue == NULL) { + size = 0U; + } else { + size = pstQueue->queueSize - sizeof(UINT32); + } + + return (size); +} + + +uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id) +{ + uint32_t count; + UINTPTR uwIntSave; + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + + if (pstQueue == NULL) { + count = 0U; + } else { + uwIntSave = LOS_IntLock(); + count = (uint32_t)(pstQueue->readWriteableCnt[OS_QUEUE_READ]); + LOS_IntRestore(uwIntSave); + } + return count; +} + + +uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id) +{ + uint32_t space; + UINTPTR uwIntSave; + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + + if (pstQueue == NULL) { + space = 0U; + } else { + uwIntSave = LOS_IntLock(); + space = (uint32_t)pstQueue->readWriteableCnt[OS_QUEUE_WRITE]; + LOS_IntRestore(uwIntSave); + } + return space; +} + +osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id) +{ + LosQueueCB *pstQueue = (LosQueueCB *)mq_id; + UINT32 uwRet; + + if (pstQueue == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + uwRet = LOS_QueueDelete((UINT32)pstQueue->queueID); + if (uwRet == LOS_OK) { + return osOK; + } else if (uwRet == LOS_ERRNO_QUEUE_NOT_FOUND || uwRet == LOS_ERRNO_QUEUE_NOT_CREATE) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +void osThreadExit(void) +{ + return; +} +#endif + +#endif // (CMSIS_OS_VER == 2) +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/components/cmsis/2.0/cmsis_os2.h b/components/cmsis/2.0/cmsis_os2.h new file mode 120000 index 00000000..3c97517f --- /dev/null +++ b/components/cmsis/2.0/cmsis_os2.h @@ -0,0 +1 @@ +../../../../../third_party/cmsis/CMSIS/RTOS2/Include/cmsis_os2.h \ No newline at end of file diff --git a/components/cmsis/BUILD.gn b/components/cmsis/BUILD.gn new file mode 100755 index 00000000..1ff472ff --- /dev/null +++ b/components/cmsis/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("//build/lite/config/component/lite_component.gni") + +static_library("cmsis") { + sources = [ + "cmsis_liteos.c" + ] + + include_dirs = [ + "//kernel/liteos_m/components/cmsis", + "//third_party/bounds_checking_function/include", + ] + + defines = [ + "LITEOS_WIFI_IOT_VERSION", + ] + + cflags = [ "-Wno-error" ] +} diff --git a/components/cmsis/cmsis_liteos.c b/components/cmsis/cmsis_liteos.c new file mode 100755 index 00000000..3254b8ed --- /dev/null +++ b/components/cmsis/cmsis_liteos.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_config.h" + +#if (CMSIS_OS_VER == 1) +#include "1.0/cmsis_liteos1.c" +#elif (CMSIS_OS_VER == 2) +#include "2.0/cmsis_liteos2.c" +#endif diff --git a/components/cmsis/cmsis_os.h b/components/cmsis/cmsis_os.h new file mode 100755 index 00000000..2f8e2867 --- /dev/null +++ b/components/cmsis/cmsis_os.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_config.h" + +#if (CMSIS_OS_VER == 1) +#error "cmsis version 1.0 is not supported now!" +#elif (CMSIS_OS_VER == 2) +#include "2.0/cmsis_os2.h" +#endif + diff --git a/components/cmsis_adp/hos_cmsis_adp.h b/components/cmsis_adp/hos_cmsis_adp.h new file mode 100755 index 00000000..66260764 --- /dev/null +++ b/components/cmsis_adp/hos_cmsis_adp.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 HOS_CMSIS_ADP_H +#define HOS_CMSIS_ADP_H + +#include "cmsis_os.h" +#include "hos_types.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef struct { + osSemaphoreAttr_t attr; + uint32 maxCount; + uint32 initialCount; +} SemaphoreEx; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/components/kal/BUILD.gn b/components/kal/BUILD.gn new file mode 100755 index 00000000..f1f27443 --- /dev/null +++ b/components/kal/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("//build/lite/config/component/lite_component.gni") + +static_library("kal") { + sources = [ + "src/kal.c", + ] + + include_dirs = [ + "//kernel/liteos_m/components/kal/include", + "//third_party/bounds_checking_function/include", + ] + + defines = [ + "LITEOS_WIFI_IOT_VERSION", + ] + + cflags = [ "-Werror" ] +} diff --git a/components/kal/include/kal.h b/components/kal/include/kal.h new file mode 100755 index 00000000..142f2ee3 --- /dev/null +++ b/components/kal/include/kal.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + + /** + * @addtogroup KAL + * @{ + * + * @brief Defines the kernel adaptation layer (KAL), which provides compatible interfaces across L0 and L1 systems. + * + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef KAL_H_ +#define KAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief Indicates the maximum length of a thread name. +* +* @since 1.0 +* @version 1.0 +*/ +#define KAL_TASK_NAME_LEN 32 + +typedef void (*KalTimerProc)(void *arg); +typedef void *KalTimerId; + +typedef enum { + KAL_TIMER_ONCE = 0, // /< One-shot timer. + KAL_TIMER_PERIODIC = 1 // /< Repeating timer. +} KalTimerType; + +typedef enum { + KAL_OK = 0, + KAL_ERR_PARA = 1, + KAL_ERR_INNER = 2, + KAL_ERR_TIMER_STATE = 0x100, +} KalErrCode; + +/** +* @brief Describes a thread. +* +* @since 1.0 +* @version 1.0 +*/ +typedef struct { +/** Thread name */ +char name[KAL_TASK_NAME_LEN]; +/** Thread ID */ +unsigned int id; +/** Thread status */ +unsigned short status; +/** Thread priority */ +unsigned short priority; +/** Thread semaphore */ +void *taskSem; +/** Thread mutex */ +void *taskMutex; +/** Thread event */ +unsigned int eventStru[3]; +/** Thread event mask */ +unsigned int eventMask; +/** Thread stack size */ +unsigned int stackSize; +/** Thread stack top */ +unsigned int topOfStack; +/** Thread stack bottom */ +unsigned int bottomOfStack; +/** Thread current mstatus */ +unsigned int mstatus; +/** Thread current mepc */ +unsigned int mepc; +/** Thread current tp */ +unsigned int tp; +/** Thread current ra */ +unsigned int ra; +/** Thread stack pointer */ +unsigned int sp; +/** Current stack space usage */ +unsigned int currUsed; +/** Peak stack space usage */ +unsigned int peakUsed; +/** Thread stack overflow flag */ +unsigned int overflowFlag; +} ThreadInfo; + +typedef struct { + /**< Total space of the memory pool. */ + unsigned int total; + /**< Used space of the memory pool. */ + unsigned int used; + /**< Free space of the memory pool. */ + unsigned int free; + /**< Number of free nodes in the memory pool. */ + unsigned int freeNodeNum; + /**< Number of used nodes in the memory pool. */ + unsigned int usedNodeNum; + /**< Maximum size of the node in the free space of the memory pool. */ + unsigned int maxFreeNodeSize; + /**< Number of memory application failures. */ + unsigned int mallocFailCount; + /**< Peak memory usage of the memory pool. */ + unsigned int peekSize; + /**< Total space of the little memory pool. */ + unsigned int totalLmp; + /**< Used space of the little memory pool. */ + unsigned int usedLmp; + /**< Free space of the little memory pool. */ + unsigned int freeLmp; +} MemInfo; + +/** +* @brief Obtains thread information. +* +* @param threadId Indicates the thread ID. +* @param info Indicates the pointer to the buffer for storing the obtained thread information. +* @return Returns 0 if the thread information is obtained; returns a negative value otherwise. +* @since 1.0 +* @version 1.0 +*/ +unsigned int KalThreadGetInfo(unsigned int threadId, ThreadInfo *info); + +/** +* @brief Delays a thread. +* +* The delay unit is microsecond. The actual delay precision can reach only the tick level. +* +* @param us Indicates the number of microseconds to delay. The actual delay precision is one tick. +* @since 1.0 +* @version 1.0 +*/ +void KalDelayUs(unsigned int us); +KalTimerId KalTimerCreate(KalTimerProc func, KalTimerType type, void *arg, unsigned int ticks); +KalErrCode KalTimerStart(KalTimerId timerId); +KalErrCode KalTimerChange(KalTimerId timerId, unsigned int ticks); +KalErrCode KalTimerStop(KalTimerId timerId); +KalErrCode KalTimerDelete(KalTimerId timerId); +unsigned int KalTimerIsRunning(KalTimerId timerId); +unsigned int KalTickToMs(unsigned int ticks); +unsigned int KalMsToTick(unsigned int millisec); +KalErrCode KalGetMemInfo(MemInfo *pmemInfo); + +#ifdef __cplusplus +} +#endif + +#endif // KAL_H_ + +/* * @} */ \ No newline at end of file diff --git a/components/kal/src/kal.c b/components/kal/src/kal.c new file mode 100755 index 00000000..5c6d5006 --- /dev/null +++ b/components/kal/src/kal.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "securec.h" +#include "hi_mem.h" +#include "los_task.h" +#include "los_swtmr.h" +#include "los_swtmr_pri.h" +#include "los_hwi.h" +#include "kal.h" + + +#ifdef __cplusplus +#define NULL 0L +#else +#ifndef NULL +#define NULL ((void *)0) +#endif +#endif +#define MS_PER_SECOND 1000 + +unsigned int KalThreadGetInfo(unsigned int threadId, ThreadInfo *info) +{ + unsigned int ret; + if (info == NULL) { + return -1; + } + (void)memset_s(info, sizeof(ThreadInfo), 0, sizeof(ThreadInfo)); + TSK_INFO_S *losTaskInfo = (TSK_INFO_S *)malloc(sizeof(TSK_INFO_S)); + if (losTaskInfo == NULL) { + return -1; + } + (void)memset_s(losTaskInfo, sizeof(TSK_INFO_S), 0, sizeof(TSK_INFO_S)); + ret = LOS_TaskInfoGet(threadId, losTaskInfo); + if (ret == LOS_OK) { + info->id = losTaskInfo->uwTaskID; + info->status = losTaskInfo->usTaskStatus; + info->priority = losTaskInfo->usTaskPrio; + info->taskSem = losTaskInfo->pTaskSem; + info->taskMutex = losTaskInfo->pTaskMux; + info->eventMask = losTaskInfo->uwEventMask; + info->stackSize = losTaskInfo->uwStackSize; + info->topOfStack = losTaskInfo->uwTopOfStack; + info->bottomOfStack = losTaskInfo->uwBottomOfStack; + info->mstatus = losTaskInfo->mstatus; + info->mepc = losTaskInfo->mepc; + info->tp = losTaskInfo->tp; + info->ra = losTaskInfo->ra; + info->sp = losTaskInfo->uwSP; + info->currUsed = losTaskInfo->uwCurrUsed; + info->peakUsed = losTaskInfo->uwPeakUsed; + info->overflowFlag = losTaskInfo->bOvf; + ret = memcpy_s(info->name, sizeof(info->name), losTaskInfo->acName, sizeof(info->name) - 1); + } + free(losTaskInfo); + return ret; +} + +void KalDelayUs(unsigned int us) +{ + unsigned int ticks; + if (us == 0) { + return; + } + ticks = LOS_MS2Tick(us / MS_PER_SECOND); + (void)LOS_TaskDelay(ticks); +} + +KalTimerId KalTimerCreate(KalTimerProc func, KalTimerType type, void *arg, unsigned int ticks) +{ + UINT16 swtmrId; + UINT8 mode; + if ((OS_INT_ACTIVE) || (NULL == func) || ((KAL_TIMER_ONCE != type) && (KAL_TIMER_PERIODIC != type))) { + return (KalTimerId)NULL; + } + if (KAL_TIMER_ONCE == type) { + mode = LOS_SWTMR_MODE_NO_SELFDELETE; + } else { + mode = LOS_SWTMR_MODE_PERIOD; + } +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + if (LOS_OK != LOS_SwtmrCreate(ticks, mode, (SWTMR_PROC_FUNC)func, &swtmrId, (UINT32)(UINTPTR)arg, + osTimerRousesAllow, osTimerAlignIgnore)) { + return (KalTimerId)NULL; + } +#else + if (LOS_OK != LOS_SwtmrCreate(ticks, mode, (SWTMR_PROC_FUNC)func, &swtmrId, (UINT32)(UINTPTR)arg)) { + return (KalTimerId)NULL; + } +#endif + return (KalTimerId)OS_SWT_FROM_SID(swtmrId); +} +KalErrCode KalTransRetCode(unsigned int ret) +{ + if (LOS_OK == ret) { + return KAL_OK; + } else if (LOS_ERRNO_SWTMR_ID_INVALID == ret) { + return KAL_ERR_PARA; + } else { + return KAL_ERR_INNER; + } +} +KalErrCode KalTimerStart(KalTimerId timerId) +{ + UINT32 ret; + SWTMR_CTRL_S *swtmr = NULL; + if (NULL == timerId) { + return KAL_ERR_PARA; + } + swtmr = (SWTMR_CTRL_S *)timerId; + + ret = LOS_SwtmrStart(swtmr->usTimerID); + return KalTransRetCode(ret); +} +// support change while not running. +KalErrCode KalTimerChange(KalTimerId timerId, unsigned int ticks) +{ + SWTMR_CTRL_S *swtmr = NULL; + if ((0 == ticks) || (NULL == timerId)) { + return KAL_ERR_PARA; + } + swtmr = (SWTMR_CTRL_S *)timerId; + if (OS_SWTMR_STATUS_TICKING == swtmr->ucState) { + return KAL_ERR_TIMER_STATE; + } + swtmr->uwInterval = ticks; + return KAL_OK; +} +KalErrCode KalTimerStop(KalTimerId timerId) +{ + UINT32 ret; + SWTMR_CTRL_S *swtmr = NULL; + if (NULL == timerId) { + return KAL_ERR_PARA; + } + swtmr = (SWTMR_CTRL_S *)timerId; + ret = LOS_SwtmrStop(swtmr->usTimerID); + return KalTransRetCode(ret); +} + +KalErrCode KalTimerDelete(KalTimerId timerId) +{ + UINT32 ret; + SWTMR_CTRL_S *swtmr = NULL; + if (NULL == timerId) { + return KAL_ERR_PARA; + } + swtmr = (SWTMR_CTRL_S *)timerId; + ret = LOS_SwtmrDelete(swtmr->usTimerID); + return KalTransRetCode(ret); +} +unsigned int KalTimerIsRunning(KalTimerId timerId) +{ + if ((OS_INT_ACTIVE) || (NULL == timerId)) { + return 0; + } + return (OS_SWTMR_STATUS_TICKING == ((SWTMR_CTRL_S *)timerId)->ucState); +} + +unsigned int KalTickToMs(unsigned int ticks) +{ + return LOS_Tick2MS(ticks); +} +unsigned int KalMsToTick(unsigned int millisec) +{ + return LOS_MS2Tick(millisec); +} + +KalErrCode KalGetMemInfo(MemInfo *pmemInfo) +{ + hi_mdm_mem_info hiMemInfo; + hi_u32 hiRet; + if (NULL == pmemInfo) { + return KAL_ERR_PARA; + } + hiRet = hi_mem_get_sys_info(&hiMemInfo); + if (hiRet != 0) { + return KAL_ERR_INNER; + } + pmemInfo->total = hiMemInfo.total; + pmemInfo->used = hiMemInfo.used; + pmemInfo->free = hiMemInfo.free; + pmemInfo->freeNodeNum = hiMemInfo.free_node_num; + pmemInfo->usedNodeNum = hiMemInfo.used_node_num; + pmemInfo->maxFreeNodeSize = hiMemInfo.max_free_node_size; + pmemInfo->mallocFailCount = hiMemInfo.malloc_fail_count; + pmemInfo->peekSize = hiMemInfo.peek_size; + pmemInfo->totalLmp = hiMemInfo.total_lmp; + pmemInfo->usedLmp = hiMemInfo.used_lmp; + pmemInfo->freeLmp = hiMemInfo.free_lmp; + return KAL_OK; +} diff --git a/kernel/BUILD.gn b/kernel/BUILD.gn new file mode 100755 index 00000000..2ccedd1b --- /dev/null +++ b/kernel/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("//build/lite/config/component/lite_component.gni") + +source_set("init") { + + sources = [ + "los_init.c", + ] + + include_dirs = [ + "include", + ] +} + +lite_component("kernel") { + features = [ + ":init", + "base", + "extended:cpup" + ] + +} diff --git a/kernel/base/BUILD.gn b/kernel/base/BUILD.gn new file mode 100755 index 00000000..3aba1b51 --- /dev/null +++ b/kernel/base/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("base") { + + sources = [ + "core/los_priqueue.c", + "core/los_swtmr.c", + "core/los_sys.c", + "core/los_task.c", + "core/los_tick.c", + "core/los_timeslice.c", + "ipc/los_event.c", + "ipc/los_mux.c", + "ipc/los_queue.c", + "ipc/los_sem.c", + "mem/bestfit/los_membox.c", + "mem/bestfit/los_memcheck.c", + "mem/bestfit/los_memory.c", + "mem/bestfit/los_memstat.c", + "mem/bestfit/los_multipledlinkhead.c", + "mem/common/los_slab.c", + "mem/common/los_slabmem.c", + "misc/los_misc.c", + "om/los_err.c", + ] +} diff --git a/kernel/base/core/los_priqueue.c b/kernel/base/core/los_priqueue.c new file mode 100755 index 00000000..24b4b155 --- /dev/null +++ b/kernel/base/core/los_priqueue.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_priqueue_pri.h" +#include "los_base_pri.h" +#include "los_task_pri.h" +#include "los_memory.h" +#include "los_compiler.h" + +LITE_OS_SEC_BSS LOS_DL_LIST *g_losPriorityQueueList = NULL; +static LITE_OS_SEC_BSS UINT32 g_priqueueBitmap = 0; + +#define PRIQUEUE_PRIOR0_BIT (UINT32)0x80000000 + +UINT32 OsPriqueueInit(VOID) +{ + UINT32 priority; + UINT32 size = OS_PRIORITY_QUEUE_PRIORITYNUM * sizeof(LOS_DL_LIST); + + g_losPriorityQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_losPriorityQueueList == NULL) { + return LOS_NOK; + } + + for (priority = 0; priority < OS_PRIORITY_QUEUE_PRIORITYNUM; ++priority) { + LOS_ListInit(&g_losPriorityQueueList[priority]); + } + return LOS_OK; +} + +VOID OsPriqueueEnqueue(LOS_DL_LIST *priqueueItem, UINT32 priority) +{ + if (LOS_ListEmpty(&g_losPriorityQueueList[priority])) { + g_priqueueBitmap |= (PRIQUEUE_PRIOR0_BIT >> priority); + } + + LOS_ListTailInsert(&g_losPriorityQueueList[priority], priqueueItem); +} + +VOID OsPriqueueDequeue(LOS_DL_LIST *priqueueItem) +{ + LosTaskCB *runningTask = NULL; + LOS_ListDelete(priqueueItem); + + runningTask = LOS_DL_LIST_ENTRY(priqueueItem, LosTaskCB, pendList); + if (LOS_ListEmpty(&g_losPriorityQueueList[runningTask->priority])) { + g_priqueueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> runningTask->priority); + } +} + +LOS_DL_LIST *OsPriqueueTop(VOID) +{ + UINT32 priority; + + if (g_priqueueBitmap != 0) { + priority = CLZ(g_priqueueBitmap); + return LOS_DL_LIST_FIRST(&g_losPriorityQueueList[priority]); + } + + return (LOS_DL_LIST *)NULL; +} + +UINT32 OsPriqueueSize(UINT32 priority) +{ + UINT32 itemCnt = 0; + LOS_DL_LIST *curPQNode = (LOS_DL_LIST *)NULL; + + LOS_DL_LIST_FOR_EACH(curPQNode, &g_losPriorityQueueList[priority]) { + ++itemCnt; + } + + return itemCnt; +} + +UINT32 OsPriqueueTotalSize(VOID) +{ + UINT32 priority; + UINT32 totalSize = 0; + + for (priority = 0; priority < OS_PRIORITY_QUEUE_PRIORITYNUM; ++priority) { + totalSize += OsPriqueueSize(priority); + } + + return totalSize; +} diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c new file mode 100755 index 00000000..3cbbedda --- /dev/null +++ b/kernel/base/core/los_swtmr.c @@ -0,0 +1,860 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "string.h" +#include "securec.h" +#include "los_swtmr_pri.h" +#include "los_base_pri.h" +#include "los_sys.h" +#include "los_membox_pri.h" +#include "los_memory_pri.h" +#include "los_queue_pri.h" +#include "los_task_pri.h" +#include "los_hwi.h" +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_exc.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_BASE_CORE_SWTMR == YES) + +LITE_OS_SEC_BSS UINT32 g_swtmrHandlerQueue; /* Software Timer timeout queue ID */ +LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* first address in Timer memory space */ +LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrFreeList = NULL; /* Free list of Softwaer Timer */ +LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrSortList = NULL; /* The software timer count list */ + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +typedef struct SwtmrAlignDataStr { + UINT32 times : 24; + UINT32 : 5; + UINT32 canMultiple : 1; + UINT32 canAlign : 1; + UINT32 isAligned : 1; +} SwtmrAlignData; +LITE_OS_SEC_BSS SwtmrAlignData g_swtmrAlignID[LOSCFG_BASE_CORE_SWTMR_LIMIT] = {0}; /* store swtmr align */ +static UINT32 g_swtimerRousesTime = 0; /* suspend time */ +static SWTMR_CTRL_S *g_swtmrRouses = NULL; /* first swtmr that can wake up */ +static SWTMR_CTRL_S *g_swtmrRousesPrev = NULL; +#endif + +#define SWTMR_MAX_RUNNING_TICKS 2 + + +/***************************************************************************** +Function : OsSwtmrTask +Description : Swtmr task main loop, handle time-out timer. +Input : None +Output : None +Return : None +*****************************************************************************/ +LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) +{ + SwtmrHandlerItem swtmrHandle; + UINT32 readSzie; + UINT32 ret; + UINT64 tick; + readSzie = sizeof(SwtmrHandlerItem); + for (;;) { + ret = LOS_QueueReadCopy(g_swtmrHandlerQueue, &swtmrHandle, &readSzie, LOS_WAIT_FOREVER); + if ((ret == LOS_OK) && (readSzie == sizeof(SwtmrHandlerItem))) { + if (swtmrHandle.handler == NULL) { + continue; + } + + tick = LOS_TickCountGet(); + swtmrHandle.handler(swtmrHandle.arg); + tick = LOS_TickCountGet() - tick; + + if (tick >= SWTMR_MAX_RUNNING_TICKS) { + PRINT_WARN("timer_handler(%p) cost too many ms(%d)\n", + swtmrHandle.handler, + (UINT32)((tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND)); + } + } + } +} + +/***************************************************************************** +Function : OsSwtmrTaskCreate +Description : Create Software Timer +Input : None +Output : None +Return : LOS_OK on success or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S swtmrTask; + + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + + swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask; + swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE; + swtmrTask.pcName = "Swt_Task"; + swtmrTask.usTaskPrio = 0; + ret = LOS_TaskCreate(&g_swtmrTaskID, &swtmrTask); + return ret; +} + +/***************************************************************************** +Function : OsSwtmrInit +Description : Initializes Software Timer +Input : None +Output : None +Return : LOS_OK on success or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) +{ + UINT32 size; + UINT16 index; + UINT32 ret; + SWTMR_CTRL_S *swtmr = NULL; + SWTMR_CTRL_S *temp = NULL; + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + // Ignore the return code when matching CSEC rule 6.6(1). + (VOID)memset_s((VOID *)g_swtmrAlignID, sizeof(SwtmrAlignData) * LOSCFG_BASE_CORE_SWTMR_LIMIT, + 0, sizeof(SwtmrAlignData) * LOSCFG_BASE_CORE_SWTMR_LIMIT); +#endif + + g_swtmrSortList = (SWTMR_CTRL_S *)NULL; + size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); + if (swtmr == NULL) { + return LOS_ERRNO_SWTMR_NO_MEMORY; + } + // Ignore the return code when matching CSEC rule 6.6(3). + (VOID)memset_s((VOID *)swtmr, size, 0, size); + g_swtmrCBArray = swtmr; + g_swtmrFreeList = swtmr; + swtmr->usTimerID = 0; + temp = swtmr; + swtmr++; + for (index = 1; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { + swtmr->usTimerID = index; + temp->pstNext = swtmr; + temp = swtmr; + } + + ret = LOS_QueueCreate((CHAR *)NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, + &g_swtmrHandlerQueue, 0, sizeof(SwtmrHandlerItem)); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem0, swtmr); + return LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; + } + + ret = OsSwtmrTaskCreate(); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem0, swtmr); + return LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; + } + + return LOS_OK; +} + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +STATIC_INLINE UINT32 OsSwtmrCalcAlignCount(UINT32 interval, UINT16 timerId) +{ + SWTMR_CTRL_S *cur = g_swtmrSortList; + UINT32 count = 0; + if (interval == 0) { + return interval; + } + while (cur != NULL) { + count += cur->uwCount; + if (cur->usTimerID == timerId) { + return (interval - (cur->uwInterval - count) % interval); + } + cur = cur->pstNext; + } + return interval; +} + +LITE_OS_SEC_TEXT SWTMR_CTRL_S* OsSwtmrFindAlignPos(SWTMR_CTRL_S *swtmr) +{ + SWTMR_CTRL_S *intPos = (SWTMR_CTRL_S *)NULL; + SWTMR_CTRL_S *cur = (SWTMR_CTRL_S *)NULL; + SWTMR_CTRL_S *minInLarge = (SWTMR_CTRL_S *)NULL; + SWTMR_CTRL_S *maxInLitte = (SWTMR_CTRL_S *)NULL; + UINT32 currSwtmrTimes, swtmrTimes; + SwtmrAlignData swtmrAlgInfo, currSwtmrAlgInfo; + UINT32 minInLargeVal = OS_NULL_INT; + UINT32 maxInLitteval = OS_NULL_INT; + + currSwtmrAlgInfo = g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT]; + currSwtmrTimes = currSwtmrAlgInfo.times; + cur = g_swtmrSortList; + while (cur != NULL) { + swtmrAlgInfo = g_swtmrAlignID[cur->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT]; + if ((swtmrAlgInfo.isAligned == 0) || (swtmrAlgInfo.canAlign == 0)) { // swtmr not start + goto CONTINUE_NEXT_NODE; + } + // find same interval timer, directly return + if (cur->uwInterval == swtmr->uwInterval) { + swtmr->uwCount = 0; + return cur; + } + + if ((currSwtmrAlgInfo.canMultiple != 1) || (swtmrAlgInfo.times == 0)) { + goto CONTINUE_NEXT_NODE; + } + swtmrTimes = swtmrAlgInfo.times; + if (currSwtmrTimes == 0) { + return NULL; + } + if ((swtmrTimes >= currSwtmrTimes) && ((swtmrTimes % currSwtmrTimes) == 0)) { + if (minInLargeVal > (swtmrTimes / currSwtmrTimes)) { + minInLargeVal = swtmrTimes / currSwtmrTimes; + minInLarge = cur; + } + } else if ((swtmrTimes < currSwtmrTimes) && ((currSwtmrTimes % swtmrTimes) == 0)) { + if (maxInLitteval > (currSwtmrTimes / swtmrTimes)) { + maxInLitteval = currSwtmrTimes / swtmrTimes; + maxInLitte = cur; + } + } + CONTINUE_NEXT_NODE: + + cur = cur->pstNext; + } + if (minInLarge != NULL) { + swtmr->uwCount = OsSwtmrCalcAlignCount(swtmr->uwInterval, minInLarge->usTimerID); + } else if (maxInLitte != NULL) { + swtmr->uwCount = 0; + intPos = maxInLitte; + } + return intPos; +} +#endif + +/***************************************************************************** +Function : OsSwtmrStart +Description : Start Software Timer +Input : swtmr ---------- Need to start Software Timer +Output : None +Return : None +*****************************************************************************/ +LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) +{ + SWTMR_CTRL_S *prev = (SWTMR_CTRL_S *)NULL; + SWTMR_CTRL_S *cur = (SWTMR_CTRL_S *)NULL; + + swtmr->uwCount = swtmr->uwInterval; + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + if ((g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].canAlign == 1) && + (g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned == 0)) { + g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned = 1; + prev = OsSwtmrFindAlignPos(swtmr); + } +#endif + + if (prev == NULL) { + cur = g_swtmrSortList; + while (cur != NULL) { + if (cur->uwCount > swtmr->uwCount) { + break; + } + + swtmr->uwCount -= cur->uwCount; + prev = cur; + cur = cur->pstNext; + } + } + + swtmr->pstNext = ((prev == NULL) ? g_swtmrSortList : prev->pstNext); + if (swtmr->pstNext != NULL) { + swtmr->pstNext->uwCount -= swtmr->uwCount; + } + (prev == NULL) ? (g_swtmrSortList = swtmr) : (prev->pstNext = swtmr); + swtmr->ucState = OS_SWTMR_STATUS_TICKING; +} + +/***************************************************************************** +Function : OsSwtmrDelete +Description : Delete Software Timer +Input : swtmr --- Need to delete Software Timer, When using, Ensure that it can't be NULL. +Output : None +Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) +{ + /* insert to free list */ + swtmr->pstNext = g_swtmrFreeList; + g_swtmrFreeList = swtmr; + swtmr->ucState = OS_SWTMR_STATUS_UNUSED; + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + (VOID)memset_s((VOID *)&g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT], + sizeof(SwtmrAlignData), 0, sizeof(SwtmrAlignData)); +#endif +} + + +LITE_OS_SEC_TEXT VOID OsSwtmrStop(const SWTMR_CTRL_S *swtmr) +{ + SWTMR_CTRL_S *prev = (SWTMR_CTRL_S *)NULL; + SWTMR_CTRL_S *cur = (SWTMR_CTRL_S *)NULL; + + if (!g_swtmrSortList) { + return; + } + + cur = g_swtmrSortList; + + while (cur != swtmr) { + prev = cur; + cur = cur->pstNext; + } + + if (cur->pstNext != NULL) { + cur->pstNext->uwCount += cur->uwCount; + } + + if (prev == NULL) { + g_swtmrSortList = cur->pstNext; + } else { + prev->pstNext = cur->pstNext; + } + + cur->pstNext = (SWTMR_CTRL_S *)NULL; + cur->ucState = OS_SWTMR_STATUS_CREATED; + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned = 0; +#endif +} + +/***************************************************************************** +Function : OsSwtmrTimeoutHandle +Description : Software Timer time out handler +Input : None +Output : None +Return : None +*****************************************************************************/ +LITE_OS_SEC_TEXT static VOID OsSwtmrTimeoutHandle(VOID) +{ + SWTMR_CTRL_S *swtmr = g_swtmrSortList; + SwtmrHandlerItem swtmrHandler; + + while ((swtmr != NULL) && (swtmr->uwCount == 0)) { + g_swtmrSortList = swtmr->pstNext; + swtmrHandler.handler = swtmr->pfnHandler; + swtmrHandler.arg = swtmr->uwArg; + (VOID)LOS_QueueWriteCopy(g_swtmrHandlerQueue, &swtmrHandler, sizeof(SwtmrHandlerItem), LOS_NO_WAIT); + if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) { + OsSwtmrDelete(swtmr); + if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { + swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; + } else { + swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; + } + } else if (swtmr->ucMode == LOS_SWTMR_MODE_PERIOD) { + OsSwtmrStart(swtmr); + } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + } + + swtmr = g_swtmrSortList; + } +} + +/***************************************************************************** +Function : OsSwtmrScan +Description : Tick interrupt interface module of Software Timer +Input : None +Output : None +Return : LOS_OK on success +*****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 OsSwtmrScan(VOID) +{ + if (g_swtmrSortList != NULL) { + if (--(g_swtmrSortList->uwCount) == 0) { + OsSwtmrTimeoutHandle(); + } + } + return LOS_OK; +} + +/***************************************************************************** +Function : OsSwtmrGetNextTimeout +Description : Get next timeout +Input : None +Output : None +Return : Count of the Timer list +*****************************************************************************/ +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) +{ + SWTMR_CTRL_S *cur = NULL; + UINT32 tmpTime = 0; + UINT32 sleepTime = OS_NULL_INT; + + cur = g_swtmrSortList; + + // find first timer can wakeup the system + while (cur != NULL) { + if (cur->ucRouses == OS_SWTMR_ROUSES_ALLOW) { + g_swtmrRouses = cur; + break; + } + + tmpTime += cur->uwCount; + g_swtmrRousesPrev = cur; + cur = cur->pstNext; + } + + if (cur != NULL) { + sleepTime = cur->uwCount + tmpTime; + g_swtimerRousesTime = sleepTime; + } + + return sleepTime; +} +#else +LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) +{ + if (g_swtmrSortList == NULL) { + return OS_NULL_INT; + } + return g_swtmrSortList->uwCount; +} +#endif + +/***************************************************************************** +Function : OsSwtimerInsert +Description : Insert a list of swtmr +Input : **head, *swtmr +Output : **head, *swtmr +Return : None +*****************************************************************************/ +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +VOID OsSwtimerInsert(SWTMR_CTRL_S **head, SWTMR_CTRL_S *swtmr) +{ + SWTMR_CTRL_S *prev = NULL; + SWTMR_CTRL_S *nextTmp = swtmr->pstNext; + SWTMR_CTRL_S *cur = *head; + + while (swtmr != NULL) { + while (cur != NULL) { + if (cur->uwCount > swtmr->uwCount) { + break; + } + + swtmr->uwCount -= cur->uwCount; + prev = cur; + cur = cur->pstNext; + } + swtmr->pstNext = cur; + + if (cur != NULL) { + cur->uwCount -= swtmr->uwCount; + } + if (prev == NULL) { + *head = swtmr; + } else { + prev->pstNext = swtmr; + } + + prev = swtmr; + swtmr = nextTmp; + nextTmp = nextTmp->pstNext; + } + + return; +} +#endif +/***************************************************************************** +Function : OsSwtmrAdjust +Description : Adjust Software Timer list +Input : sleepTime +Output : None +Return : None +*****************************************************************************/ +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +LITE_OS_SEC_TEXT VOID OsSwtmrAdjust(UINT32 sleepTime) +{ + SWTMR_CTRL_S *cur = NULL; + + if (g_swtmrRouses == NULL) { + return; + } + + if (sleepTime > g_swtimerRousesTime) { + sleepTime = g_swtimerRousesTime; + } + + if (sleepTime <= g_swtmrRouses->uwCount) { + g_swtmrRouses->uwCount -= sleepTime; + } else { + g_swtmrRouses->uwCount = g_swtimerRousesTime - sleepTime; + + if (g_swtmrRousesPrev != NULL) { + g_swtmrRousesPrev->pstNext = NULL; + cur = g_swtmrSortList; + OsSwtimerInsert(&g_swtmrRouses, cur); + g_swtmrSortList = g_swtmrRouses; + } + } + if (g_swtmrSortList->uwCount == 0) { + OsSwtmrTimeoutHandle(); + } + + g_swtmrRouses = NULL; + g_swtmrRousesPrev = NULL; +} +#else +LITE_OS_SEC_TEXT VOID OsSwtmrAdjust(UINT32 sleepTime) +{ + UINT32 tmpSleepTime = sleepTime; + + if (g_swtmrSortList == NULL) { + return; + } + + if (tmpSleepTime > g_swtmrSortList->uwCount) { + tmpSleepTime = g_swtmrSortList->uwCount; + } + + g_swtmrSortList->uwCount -= tmpSleepTime; + + if (g_swtmrSortList->uwCount == 0) { + OsSwtmrTimeoutHandle(); + } +} +#endif + +LITE_OS_SEC_TEXT UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) +{ + SWTMR_CTRL_S *cur = (SWTMR_CTRL_S *)NULL; + UINT32 tick = 0; + + cur = g_swtmrSortList; + while (1) { + if (cur == NULL) { + break; + } + tick += cur->uwCount; + if (cur == swtmr) { + break; + } + + cur = cur->pstNext; + } + + return tick; +} + +/***************************************************************************** +Function : LOS_SwtmrCreate +Description : Create software timer +Input : interval + mode + handler + arg +Output : swtmrId +Return : LOS_OK on success or error code on failure +*****************************************************************************/ +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrId, + UINT32 arg, + UINT8 rouses, + UINT8 sensitive) +#else +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrId, + UINT32 arg) +#endif +{ + SWTMR_CTRL_S *swtmr = NULL; + UINTPTR intSave; + + if (interval == 0) { + return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED; + } + + if ((mode != LOS_SWTMR_MODE_ONCE) && + (mode != LOS_SWTMR_MODE_PERIOD) && + (mode != LOS_SWTMR_MODE_NO_SELFDELETE)) { + return LOS_ERRNO_SWTMR_MODE_INVALID; + } + + if (handler == NULL) { + return LOS_ERRNO_SWTMR_PTR_NULL; + } + + if (swtmrId == NULL) { + return LOS_ERRNO_SWTMR_RET_PTR_NULL; + } + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + if ((rouses != OS_SWTMR_ROUSES_IGNORE) && (rouses != OS_SWTMR_ROUSES_ALLOW)) { + return OS_ERRNO_SWTMR_ROUSES_INVALID; + } + + if ((sensitive != OS_SWTMR_ALIGN_INSENSITIVE) && (sensitive != OS_SWTMR_ALIGN_SENSITIVE)) { + return OS_ERRNO_SWTMR_ALIGN_INVALID; + } +#endif + + intSave = LOS_IntLock(); + if (g_swtmrFreeList == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SWTMR_MAXSIZE; + } + + swtmr = g_swtmrFreeList; + g_swtmrFreeList = swtmr->pstNext; + LOS_IntRestore(intSave); + swtmr->pfnHandler = handler; + swtmr->ucMode = mode; + swtmr->uwInterval = interval; + swtmr->pstNext = (SWTMR_CTRL_S *)NULL; + swtmr->uwCount = 0; + swtmr->uwArg = arg; +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + swtmr->ucRouses = rouses; + swtmr->ucSensitive = sensitive; +#endif + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + *swtmrId = swtmr->usTimerID; + + return LOS_OK; +} + +/***************************************************************************** +Function : LOS_SwtmrStart +Description : Start software timer +Input : swtmrId ------- Software timer ID +Output : None +Return : LOS_OK on success or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrId) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINTPTR intSave; +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + UINT32 times; + UINT32 swtmrAlignIdIndex = 0; +#endif + UINT32 ret = LOS_OK; + UINT16 swtmrCbId; + + if (swtmrId >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + intSave = LOS_IntLock(); + swtmrCbId = swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCbId; + if (swtmr->usTimerID != swtmrId) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + if ((swtmr->ucSensitive == OS_SWTMR_ALIGN_INSENSITIVE) && (swtmr->ucMode == LOS_SWTMR_MODE_PERIOD)) { + swtmrAlignIdIndex = swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + g_swtmrAlignID[swtmrAlignIdIndex].canAlign = 1; + if ((swtmr->uwInterval % LOS_COMMON_DIVISOR) == 0) { + g_swtmrAlignID[swtmrAlignIdIndex].canMultiple = 1; + times = swtmr->uwInterval / (LOS_COMMON_DIVISOR); + g_swtmrAlignID[swtmrAlignIdIndex].times = times; + } + } +#endif + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_TICKING: + OsSwtmrStop(swtmr); + /* fall through */ + case OS_SWTMR_STATUS_CREATED: + OsSwtmrStart(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + LOS_IntRestore(intSave); + return ret; +} + +/***************************************************************************** +Function : LOS_SwtmrStop +Description : Stop software timer +Input : swtmrId ------- Software timer ID +Output : None +Return : LOS_OK on success or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINTPTR intSave; + UINT16 swtmrCbId; + UINT32 ret = LOS_OK; + + if (swtmrId >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + intSave = LOS_IntLock(); + swtmrCbId = swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCbId; + if (swtmr->usTimerID != swtmrId) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_CREATED: + ret = LOS_ERRNO_SWTMR_NOT_STARTED; + break; + case OS_SWTMR_STATUS_TICKING: + OsSwtmrStop(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + LOS_IntRestore(intSave); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrId, UINT32 *tick) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINTPTR intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCbId; + + if (swtmrId >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + if (tick == NULL) { + return LOS_ERRNO_SWTMR_TICK_PTR_NULL; + } + + intSave = LOS_IntLock(); + swtmrCbId = swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCbId; + + if (swtmr->usTimerID != swtmrId) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_CREATED: + ret = LOS_ERRNO_SWTMR_NOT_STARTED; + break; + case OS_SWTMR_STATUS_TICKING: + *tick = OsSwtmrTimeGet(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + LOS_IntRestore(intSave); + return ret; +} + +/***************************************************************************** +Function : LOS_SwtmrDelete +Description : Delete software timer +Input : swtmrId ------- Software timer ID +Output : None +Return : LOS_OK on success or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrId) +{ + SWTMR_CTRL_S *swtmr = NULL; + UINTPTR intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCbId; + + if (swtmrId >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + intSave = LOS_IntLock(); + swtmrCbId = swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCbId; + if (swtmr->usTimerID != swtmrId) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + case OS_SWTMR_STATUS_TICKING: + OsSwtmrStop(swtmr); + /* fall through */ + case OS_SWTMR_STATUS_CREATED: + OsSwtmrDelete(swtmr); + break; + default: + ret = LOS_ERRNO_SWTMR_STATUS_INVALID; + break; + } + + LOS_IntRestore(intSave); + return ret; +} + +#endif /* (LOSCFG_BASE_CORE_SWTMR == YES) */ + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif diff --git a/kernel/base/core/los_sys.c b/kernel/base/core/los_sys.c new file mode 100755 index 00000000..2ba64e1b --- /dev/null +++ b/kernel/base/core/los_sys.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_sys_pri.h" +#include "los_tick_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/***************************************************************************** +Function : LOS_TickCountGet +Description : get current tick +Input : None +Output : None +Return : current tick +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID) +{ + return g_ullTickCount; +} + +/***************************************************************************** +Function : LOS_CyclePerTickGet +Description : Get System cycle number corresponding to each tick +Input : None +Output : None +Return : cycle number corresponding to each tick +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID) +{ + return g_cyclesPerTick; +} + +/***************************************************************************** +Function : LOS_MS2Tick +Description : milliseconds convert to Tick +Input : millisec ---------- milliseconds +Output : None +Return : Tick +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec) +{ + if (millisec == OS_NULL_INT) { + return OS_NULL_INT; + } + + return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND; +} + +/***************************************************************************** +Function : LOS_Tick2MS +Description : Tick convert to milliseconds +Input : ticks ---------- ticks +Output : None +Return : milliseconds +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 ticks) +{ + return ((UINT64)ticks * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND; +} + +/***************************************************************************** +Function : OsCpuTick2MS +Description : cycle convert to milliseconds +Input : cpuTick ---------- cycle +Output : msHi ---------- High 32 milliseconds + msLo ---------- Low 32 milliseconds +Return : LOS_OK on success ,or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsCpuTick2MS(CpuTick *cpuTick, UINT32 *msHi, UINT32 *msLo) +{ + UINT64 tmpCpuTick; + DOUBLE temp; + + if ((cpuTick == NULL) || (msHi == NULL) || (msLo == NULL)) { + return LOS_ERRNO_SYS_PTR_NULL; + } + + if (g_sysClock == 0) { + return LOS_ERRNO_SYS_CLOCK_INVALID; + } + tmpCpuTick = ((UINT64)cpuTick->cntHi << OS_SYS_MV_32_BIT) | cpuTick->cntLo; + temp = tmpCpuTick / ((DOUBLE)g_sysClock / OS_SYS_MS_PER_SECOND); + + tmpCpuTick = (UINT64)temp; + + *msLo = (UINT32)tmpCpuTick; + *msHi = (UINT32)(tmpCpuTick >> OS_SYS_MV_32_BIT); + + return LOS_OK; +} + +/***************************************************************************** +Function : OsCpuTick2US +Description : cycle convert to Microsecond +Input : cpuTick ---------- cycle +Output : usHi ---------- High 32 Microsecond + usLo ---------- Low 32 Microsecond +Return : LOS_OK on success ,or error code on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsCpuTick2US(CpuTick *cpuTick, UINT32 *usHi, UINT32 *usLo) +{ + UINT64 tmpCpuTick; + DOUBLE temp; + + if ((cpuTick == NULL) || (usHi == NULL) || (usLo == NULL)) { + return LOS_ERRNO_SYS_PTR_NULL; + } + + if (g_sysClock == 0) { + return LOS_ERRNO_SYS_CLOCK_INVALID; + } + tmpCpuTick = ((UINT64)cpuTick->cntHi << OS_SYS_MV_32_BIT) | cpuTick->cntLo; + temp = tmpCpuTick / ((DOUBLE)g_sysClock / OS_SYS_US_PER_SECOND); + + tmpCpuTick = (UINT64)temp; + + *usLo = (UINT32)tmpCpuTick; + *usHi = (UINT32)(tmpCpuTick >> OS_SYS_MV_32_BIT); + + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c new file mode 100755 index 00000000..3bddd8e4 --- /dev/null +++ b/kernel/base/core/los_task.c @@ -0,0 +1,1539 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_task_pri.h" +#include "string.h" +#include "securec.h" +#include "los_base_pri.h" +#include "los_memory_pri.h" +#include "los_memstat_pri.h" +#include "los_priqueue_pri.h" +#include "los_sem_pri.h" +#include "los_mux_pri.h" +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_exc_pri.h" +#endif +#if (LOSCFG_KERNEL_TICKLESS == YES) +#include "los_tickless_pri.h" +#endif +#if (LOSCFG_BASE_CORE_CPUP == YES) +#include "los_cpup_pri.h" +#endif +#include "los_hw.h" + +#if (LOSCFG_KERNEL_TRACE == YES) +#include "los_trace.h" +#endif +#include "los_sleep.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_task + * @brief Convinence macro for bitwise operation of task module + */ +#define EVALUATE_L(NUMBER, VALUE) \ + ((NUMBER) = (((NUMBER) & 0xf8000000) | (VALUE))) + +#define EVALUATE_H(NUMBER, VALUE) \ + ((NUMBER) = (((NUMBER) & 0x07ffffff) | ((VALUE) << 27))) + +#define UWROLLNUMSUB(NUMBER1, NUMBER2) \ + ((NUMBER1) = (((NUMBER1) & 0xf8000000) | (UWROLLNUM(NUMBER1) - UWROLLNUM(NUMBER2)))) + +#define UWROLLNUMADD(NUMBER1, NUMBER2) \ + ((NUMBER1) = (((NUMBER1) & 0xf8000000) | (UWROLLNUM(NUMBER1) + UWROLLNUM(NUMBER2)))) + +#define UWROLLNUM(NUMBER) ((NUMBER) & 0x07ffffff) + +#define UWSORTINDEX(NUMBER) ((NUMBER) >> 27) + +#define UWROLLNUMDEC(NUMBER) \ + ((NUMBER) = ((NUMBER) - 1)) + + +#define OS_CHECK_TASK_BLOCK (OS_TASK_STATUS_DELAY | \ + OS_TASK_STATUS_PEND | \ + OS_TASK_STATUS_SUSPEND | \ + OS_TASK_STATUS_EVENT | \ + OS_TASK_STATUS_PEND_QUEUE) + +/** + * @ingroup los_task + * @brief check taks id's validation + */ +#define OS_TASK_ID_CHECK(taskID) LOS_ASSERT_COND(OS_TSK_GET_INDEX(taskID) < g_taskMaxNum) + +/** + * @ingroup los_task + * @brief check taks id's invalidation + */ +#define OS_CHECK_TSK_PID_NOIDLE(taskID) (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) + +/** + * @ingroup los_task + * @brief the offset of task stack's top for skipping the magic word + */ +#define OS_TASK_STACK_TOP_OFFSET 4 + +LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray = NULL; +LITE_OS_SEC_BSS LosTask g_losTask; +LITE_OS_SEC_BSS UINT16 g_losTaskLock; +LITE_OS_SEC_BSS UINT32 g_taskMaxNum; +LITE_OS_SEC_BSS UINT32 g_idleTaskID; +LITE_OS_SEC_BSS UINT32 g_swtmrTaskID; +LITE_OS_SEC_DATA_INIT LOS_DL_LIST g_losFreeTask; +LITE_OS_SEC_DATA_INIT LOS_DL_LIST g_taskRecyleList; +LITE_OS_SEC_BSS TaskSortLinkAttr g_taskSortLink; +LITE_OS_SEC_BSS BOOL g_taskScheduled = FALSE; + +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) + +TSKSWITCHHOOK g_taskSwitchHook = NULL; +TSKSWITCHHOOK g_pfnUsrTskSwitchHook = NULL; +#endif /* LOSCFG_BASE_CORE_TSK_MONITOR == YES */ + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) + +TaskSwitchInfo g_taskSwitchInfo; +#endif + +STATIC_INLINE UINT32 OsCheckTaskIDValid(UINT32 taskID) +{ + UINT32 ret = LOS_OK; + if (taskID == g_idleTaskID) { + ret = LOS_ERRNO_TSK_OPERATE_IDLE; + } else if (taskID == g_swtmrTaskID) { + ret = LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED; + } else if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) { + ret = LOS_ERRNO_TSK_ID_INVALID; + } + return ret; +} + +#if (LOSCFG_KERNEL_TICKLESS == YES) +UINT32 OsTaskNextSwitchTimeGet(VOID) +{ + LosTaskCB *taskCB = NULL; + UINT32 taskSortLinkTick = 0; + LOS_DL_LIST *listObject = NULL; + UINT32 tempTicks = 0; + UINT32 index; + + for (index = 0; index < OS_TSK_SORTLINK_LEN; index++) { + listObject = g_taskSortLink.sortLink + ((g_taskSortLink.cursor + index) % OS_TSK_SORTLINK_LEN); + if (listObject->pstNext != listObject) { + taskCB = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList); + tempTicks = (index == 0) ? OS_TSK_SORTLINK_LEN : index; + tempTicks += (UINT32)(UWROLLNUM(taskCB->idxRollNum) * OS_TSK_SORTLINK_LEN); + if ((taskSortLinkTick == 0) || (taskSortLinkTick > tempTicks)) { + taskSortLinkTick = tempTicks; + } + } + } + + return taskSortLinkTick; +} +#endif + +/***************************************************************************** + Function : OsIdleTask + Description : Idle task. + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) +{ + while (1) { +#if (LOSCFG_KERNEL_TICKLESS == YES) + if (g_tickIrqFlag) { + g_tickIrqFlag = 0; + OsTicklessStart(); + } +#endif +#if (LOSCFG_KERNEL_RUNSTOP == YES) + LOS_EnterSleep(OS_SYS_NORMAL_SLEEP); +#endif + } +} + +/***************************************************************************** + Function : OsTaskPriModify + Description : Change task priority. + Input : taskCB --- task control block + priority --- priority + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority) +{ + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + OsPriqueueDequeue(&taskCB->pendList); + taskCB->taskStatus &= (~OS_TASK_STATUS_READY); + taskCB->priority = priority; + taskCB->taskStatus |= OS_TASK_STATUS_READY; + OsPriqueueEnqueue(&taskCB->pendList, taskCB->priority); + } else { + taskCB->priority = priority; + } +} + +/***************************************************************************** + Function : OsTaskAdd2TimerList + Description : Add task to sorted delay list. + Input : taskCB --- task control block + timeout --- wait time, ticks + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT VOID OsTaskAdd2TimerList(LosTaskCB *taskCB, UINT32 timeout) +{ + LosTaskCB *taskDelay = NULL; + LOS_DL_LIST *listObject = NULL; + UINT32 sortIndex; + UINT32 rollNum; + + sortIndex = timeout & OS_TSK_SORTLINK_MASK; + rollNum = (timeout >> OS_TSK_SORTLINK_LOGLEN); + (sortIndex > 0) ? 0 : (rollNum--); + EVALUATE_L(taskCB->idxRollNum, rollNum); + sortIndex = (sortIndex + g_taskSortLink.cursor); + sortIndex = sortIndex & OS_TSK_SORTLINK_MASK; + EVALUATE_H(taskCB->idxRollNum, sortIndex); + listObject = g_taskSortLink.sortLink + sortIndex; + if (listObject->pstNext == listObject) { + LOS_ListTailInsert(listObject, &taskCB->timerList); + } else { + taskDelay = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList); + do { + if (UWROLLNUM(taskDelay->idxRollNum) <= UWROLLNUM(taskCB->idxRollNum)) { + UWROLLNUMSUB(taskCB->idxRollNum, taskDelay->idxRollNum); + } else { + UWROLLNUMSUB(taskDelay->idxRollNum, taskCB->idxRollNum); + break; + } + + taskDelay = LOS_DL_LIST_ENTRY(taskDelay->timerList.pstNext, LosTaskCB, timerList); + } while (&taskDelay->timerList != (listObject)); + + LOS_ListTailInsert(&taskDelay->timerList, &taskCB->timerList); + } +} + + +LITE_OS_SEC_TEXT VOID OsTimerListDelete(LosTaskCB *taskCB) +{ + LOS_DL_LIST *listObject = NULL; + LosTaskCB *nextTask = NULL; + UINT32 sortIndex; + + sortIndex = UWSORTINDEX(taskCB->idxRollNum); + listObject = g_taskSortLink.sortLink + sortIndex; + + if (listObject != taskCB->timerList.pstNext) { + nextTask = LOS_DL_LIST_ENTRY(taskCB->timerList.pstNext, LosTaskCB, timerList); + UWROLLNUMADD(nextTask->idxRollNum, taskCB->idxRollNum); + } + + LOS_ListDelete(&taskCB->timerList); +} + +LITE_OS_SEC_TEXT VOID OsTaskScan(VOID) +{ + LosTaskCB *taskCB = NULL; + BOOL needSchedule = FALSE; + LOS_DL_LIST *listObject = NULL; + UINT16 tempStatus; + UINTPTR intSave; + intSave = LOS_IntLock(); + + g_taskSortLink.cursor = (g_taskSortLink.cursor + 1) % OS_TSK_SORTLINK_LEN; + listObject = g_taskSortLink.sortLink + g_taskSortLink.cursor; + if (listObject->pstNext == listObject) { + LOS_IntRestore(intSave); + return; + } + + for (taskCB = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList); + &taskCB->timerList != (listObject);) { + tempStatus = taskCB->taskStatus; + if (UWROLLNUM(taskCB->idxRollNum) > 0) { + UWROLLNUMDEC(taskCB->idxRollNum); + break; + } + + LOS_ListDelete(&taskCB->timerList); + if (tempStatus & OS_TASK_STATUS_PEND) { + taskCB->taskStatus &= ~(OS_TASK_STATUS_PEND); + LOS_ListDelete(&taskCB->pendList); + taskCB->taskSem = NULL; + taskCB->taskMux = NULL; + } + else if (tempStatus & OS_TASK_STATUS_EVENT) { + taskCB->taskStatus &= ~(OS_TASK_STATUS_EVENT); + } + else if (tempStatus & OS_TASK_STATUS_PEND_QUEUE) { + LOS_ListDelete(&taskCB->pendList); + taskCB->taskStatus &= ~(OS_TASK_STATUS_PEND_QUEUE); + } else { + taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY); + } + + if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) { + taskCB->taskStatus |= OS_TASK_STATUS_READY; + OsPriqueueEnqueue(&taskCB->pendList, taskCB->priority); + needSchedule = TRUE; + } + + if (listObject->pstNext == listObject) { + break; + } + + taskCB = LOS_DL_LIST_ENTRY(listObject->pstNext, LosTaskCB, timerList); + } + + LOS_IntRestore(intSave); + + if (needSchedule) { + LOS_Schedule(); + } +} + +/***************************************************************************** + Function : OsConvertTskStatus + Description : Convert task status to string. + Input : taskStatus --- task status + Output : None + Return : string + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT8 *OsConvertTskStatus(UINT16 taskStatus) +{ + if (taskStatus & OS_TASK_STATUS_RUNNING) { + return (UINT8 *)"Running"; + } else if (taskStatus & OS_TASK_STATUS_READY) { + return (UINT8 *)"Ready"; + } else if (taskStatus & OS_TASK_STATUS_DELAY) { + return (UINT8 *)"Delay"; + } else if (taskStatus & OS_TASK_STATUS_PEND) { + if (taskStatus & OS_TASK_STATUS_TIMEOUT) { + return (UINT8 *)"PendTimeOut"; + } + + return (UINT8 *)"Pend"; + } else if (taskStatus & OS_TASK_STATUS_SUSPEND) { + return (UINT8 *)"Suspend"; + } else if (taskStatus & OS_TASK_STATUS_PEND_QUEUE) { + if (taskStatus & OS_TASK_STATUS_TIMEOUT) { + return (UINT8 *)"QueuePendTimeOut"; + } + + return (UINT8 *)"QueuePend"; + } + + return (UINT8 *)"Impossible"; +} + +UINT32 OsGetTaskWaterLine(UINT32 taskID) +{ + UINT32 *stackPtr = NULL; + UINT32 peakUsed; + + if (*(UINT32 *)(UINTPTR)OS_TCB_FROM_TID(taskID)->topOfStack == OS_TASK_MAGIC_WORD) { + stackPtr = (UINT32 *)(UINTPTR)(OS_TCB_FROM_TID(taskID)->topOfStack + OS_TASK_STACK_TOP_OFFSET); + while ((stackPtr < (UINT32 *)(OS_TCB_FROM_TID(taskID)->stackPointer)) && (*stackPtr == OS_TASK_STACK_INIT)) { + stackPtr += 1; + } + peakUsed = OS_TCB_FROM_TID(taskID)->stackSize - + ((UINT32)(UINTPTR)stackPtr - OS_TCB_FROM_TID(taskID)->topOfStack); + } else { + PRINT_ERR("CURRENT task %s stack overflow!\n", OS_TCB_FROM_TID(taskID)->taskName); + peakUsed = OS_NULL_INT; + } + return peakUsed; +} + +#if (LOSCFG_BASE_CORE_CPUP == YES) +LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskCpupInfo(CPUP_INFO_S **cpuLessOneSec, + CPUP_INFO_S **cpuTenSec, + CPUP_INFO_S **cpuOneSec) +{ + if ((cpuLessOneSec == NULL) || (cpuTenSec == NULL) || (cpuOneSec == NULL)) { + return OS_ERROR; + } + *cpuLessOneSec = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_taskMaxNum); + if (*cpuLessOneSec == NULL) { + PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__); + return OS_ERROR; + } + // Ignore the return code when matching CSEC rule 6.6(3). + (VOID)memset_s((VOID *)(*cpuLessOneSec), sizeof(CPUP_INFO_S) * g_taskMaxNum, + (INT32)0, sizeof(CPUP_INFO_S) * g_taskMaxNum); + + *cpuTenSec = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_taskMaxNum); + if (*cpuTenSec == NULL) { + PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, *cpuLessOneSec); + *cpuLessOneSec = NULL; + return OS_ERROR; + } + // Ignore the return code when matching CSEC rule 6.6(3). + (VOID)memset_s((VOID *)(*cpuTenSec), sizeof(CPUP_INFO_S) * g_taskMaxNum, + (INT32)0, sizeof(CPUP_INFO_S) * g_taskMaxNum); + + *cpuOneSec = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_taskMaxNum); + if (*cpuOneSec == NULL) { + PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, *cpuLessOneSec); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, *cpuTenSec); + return OS_ERROR; + } + // Ignore the return code when matching CSEC rule 6.6(3). + (VOID)memset_s((VOID *)(*cpuOneSec), sizeof(CPUP_INFO_S) * g_taskMaxNum, + (INT32)0, sizeof(CPUP_INFO_S) * g_taskMaxNum); + + LOS_TaskLock(); + (VOID)LOS_AllTaskCpuUsage(*cpuLessOneSec, CPUP_LESS_THAN_1S); + (VOID)LOS_AllTaskCpuUsage(*cpuTenSec, CPUP_IN_10S); + (VOID)LOS_AllTaskCpuUsage(*cpuOneSec, CPUP_IN_1S); + LOS_TaskUnlock(); + + return LOS_OK; +} +#endif + +LITE_OS_SEC_TEXT_MINOR VOID OsPrintAllTskInfoHeader() +{ + PRINT_ERR("\r\nName TID Priority Status " + "StackSize WaterLine StackPoint TopOfStack EventMask SemID"); +#if (LOSCFG_BASE_CORE_CPUP == YES) + PRINT_ERR(" CPUUSE CPUUSE10s CPUUSE1s "); +#endif /* LOSCFG_BASE_CORE_CPUP */ + PRINT_ERR("\n"); + PRINT_ERR("---- --- -------- -------- "); + PRINT_ERR("--------- ---------- ---------- ---------- --------- -----"); +#if (LOSCFG_BASE_CORE_CPUP == YES) + PRINT_ERR(" ------- --------- ---------"); +#endif /* LOSCFG_BASE_CORE_CPUP */ + PRINT_ERR("\n"); +} + +/***************************************************************************** + Function : OsGetAllTskInfo + Description : Get all task info. + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID) +{ + LosTaskCB *taskCB = (LosTaskCB *)NULL; + UINT32 loopNum; + UINT32 semID; +#if (LOSCFG_BASE_CORE_CPUP == YES) + CPUP_INFO_S *cpuLessOneSec = (CPUP_INFO_S *)NULL; + CPUP_INFO_S *cpuTenSec = (CPUP_INFO_S *)NULL; + CPUP_INFO_S *cpuOneSec = (CPUP_INFO_S *)NULL; +#endif + +#if (LOSCFG_BASE_CORE_CPUP == YES) + if (OsGetAllTskCpupInfo(&cpuLessOneSec, &cpuTenSec, &cpuOneSec) != LOS_OK) { + return OS_ERROR; + } +#endif + + OsPrintAllTskInfoHeader(); + +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == YES) + UINT32 flag = osStackProtDisable(); +#endif + + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + taskCB = (((LosTaskCB *)g_taskCBArray) + loopNum); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + + PRINT_ERR("%-30s, 0x%-5x, %-11d, %-13s, 0x%-11x, 0x%-11x, 0x%-10x, 0x%-11x, 0x%-9x", + taskCB->taskName, taskCB->taskID, taskCB->priority, OsConvertTskStatus(taskCB->taskStatus), + taskCB->stackSize, OsGetTaskWaterLine(taskCB->taskID), + (UINT32)(UINTPTR)taskCB->stackPointer, taskCB->topOfStack, taskCB->eventMask); + + semID = (taskCB->taskSem == NULL) ? OS_NULL_SHORT : (((LosSemCB *)taskCB->taskSem)->semID); + PRINT_ERR("0x%-7x", semID); + +#if (LOSCFG_BASE_CORE_CPUP == YES) + PRINT_ERR("%2d.%-7d%2d.%-9d%2d.%-6d", + cpuLessOneSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT, + cpuLessOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT, + cpuTenSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT, + cpuTenSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT, + cpuOneSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT, + cpuOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT); +#endif /* LOSCFG_BASE_CORE_CPUP */ + PRINT_ERR("\n"); + } + +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == YES) + osStackProtRestore(flag); +#endif + +#if (LOSCFG_BASE_CORE_CPUP == YES) + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuLessOneSec); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuTenSec); + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuOneSec); +#endif + + return LOS_OK; +} + +/***************************************************************************** + Function : OsTaskInit + Description : Task init function. + Input : None + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID) +{ + UINT32 size; + UINT32 index; + LOS_DL_LIST *listObject = NULL; + UINT32 queueResult; + + size = (g_taskMaxNum + 1) * sizeof(LosTaskCB); + g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_taskCBArray == NULL) { + return LOS_ERRNO_TSK_NO_MEMORY; + } + + // Ignore the return code when matching CSEC rule 6.6(1). + (VOID)memset_s(g_taskCBArray, size, 0, size); + LOS_ListInit(&g_losFreeTask); + LOS_ListInit(&g_taskRecyleList); + for (index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED; + g_taskCBArray[index].taskID = index; + LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList); + } + + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)memset_s((VOID *)(&g_losTask), sizeof(g_losTask), 0, sizeof(g_losTask)); + g_losTask.runTask = &g_taskCBArray[g_taskMaxNum]; + g_losTask.runTask->taskID = index; + g_losTask.runTask->taskStatus = (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_RUNNING); + g_losTask.runTask->priority = OS_TASK_PRIORITY_LOWEST + 1; + queueResult = OsPriqueueInit(); + if (queueResult == LOS_NOK) { + (VOID)LOS_MemFree(m_aucSysMem0, g_taskCBArray); + return LOS_ERRNO_TSK_NO_MEMORY; + } + + size = sizeof(LOS_DL_LIST) * OS_TSK_SORTLINK_LEN; + listObject = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size); + if (listObject == NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, g_taskCBArray); + return LOS_ERRNO_TSK_NO_MEMORY; + } + + // Ignore the return code when matching CSEC rule 6.6(3). + (VOID)memset_s((VOID *)listObject, size, 0, size); + g_taskSortLink.sortLink = listObject; + g_taskSortLink.cursor = 0; + for (index = 0; index < OS_TSK_SORTLINK_LEN; index++, listObject++) { + LOS_ListInit(listObject); + } + +#if (LOSCFG_PLATFORM_EXC == YES) + OsExcRegister((ExcInfoType)OS_EXC_TYPE_TSK, (EXC_INFO_SAVE_CALLBACK)LOS_TaskInfoGet, &g_taskMaxNum); +#endif + return LOS_OK; +} + + +/***************************************************************************** + Function : OsIdleTaskCreate + Description : Create idle task. + Input : None + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) +{ + UINT32 retVal; + TSK_INIT_PARAM_S taskInitParam; + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask; + taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; + taskInitParam.pcName = "IdleCore000"; + taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; + retVal = LOS_TaskCreate(&g_idleTaskID, &taskInitParam); + + if (retVal != LOS_OK) { + return retVal; + } + + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_CurTaskIDGet + Description : get id of current running task. + Input : None + Output : None + Return : task id + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) +{ + if (g_losTask.runTask == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + return g_losTask.runTask->taskID; +} + +/***************************************************************************** + Function : LOS_NextTaskIDGet + Description : get id of next running task. + Input : None + Output : None + Return : task id + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_NextTaskIDGet(VOID) +{ + if (g_losTask.newTask == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + return g_losTask.newTask->taskID; +} + +/***************************************************************************** + Function : LOS_CurTaskNameGet + Description : get name of current running task. + Input : None + Output : None + Return : task name + *****************************************************************************/ +LITE_OS_SEC_TEXT CHAR *LOS_CurTaskNameGet(VOID) +{ + CHAR *taskName = NULL; + + if (g_losTask.runTask != NULL) { + taskName = g_losTask.runTask->taskName; + } + + return taskName; +} + +/***************************************************************************** + Function : OsTaskSwitchCheck + Description : Check task switch + Input : Node + Output : None + Return : None + *****************************************************************************/ +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) +LITE_OS_SEC_TEXT VOID OsTaskSwitchCheck(VOID) +{ +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == NO) + UINT32 endOfStack = g_losTask.newTask->topOfStack + g_losTask.newTask->stackSize; + + if ((*(UINT32 *)(UINTPTR)(g_losTask.runTask->topOfStack)) != OS_TASK_MAGIC_WORD) { + PRINT_ERR("CURRENT task ID: %s:%d stack overflow!\n", + g_losTask.runTask->taskName, g_losTask.runTask->taskID); + } + if (((UINT32)(UINTPTR)(g_losTask.newTask->stackPointer) <= (g_losTask.newTask->topOfStack)) || + ((UINT32)(UINTPTR)(g_losTask.newTask->stackPointer) > endOfStack)) { + PRINT_ERR("HIGHEST task ID: %s:%d SP error!\n", + g_losTask.newTask->taskName, g_losTask.newTask->taskID); + PRINT_ERR("HIGHEST task StackPointer: 0x%x TopOfStack: 0x%x\n", + (UINT32)(UINTPTR)(g_losTask.newTask->stackPointer), g_losTask.newTask->topOfStack); + } +#endif + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) + /* record task switch info */ + g_taskSwitchInfo.pid[g_taskSwitchInfo.idx] = (UINT16)(g_losTask.newTask->taskID); + + errno_t ret = memcpy_s(g_taskSwitchInfo.name[g_taskSwitchInfo.idx], LOS_TASK_NAMELEN, + g_losTask.newTask->taskName, LOS_TASK_NAMELEN); + if (ret != EOK) { + PRINT_ERR("exc task switch copy file name failed!\n"); + } + g_taskSwitchInfo.name[g_taskSwitchInfo.idx][LOS_TASK_NAMELEN - 1] = '\0'; + + if (++g_taskSwitchInfo.idx == OS_TASK_SWITCH_INFO_COUNT) { + g_taskSwitchInfo.idx = 0; + g_taskSwitchInfo.cntInfo.isFull = TRUE; + } +#endif + + if (g_pfnUsrTskSwitchHook != NULL) { + g_pfnUsrTskSwitchHook(); + } + +#if (LOSCFG_KERNEL_TRACE == YES) + LOS_Trace(LOS_TRACE_SWITCH, 0); +#endif + +#if (LOSCFG_BASE_CORE_CPUP == YES) + OsTskCycleEndStart(); +#endif /* LOSCFG_BASE_CORE_CPUP */ +} + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMonInit(VOID) +{ +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)memset_s(&g_taskSwitchInfo, sizeof(TaskSwitchInfo), 0, sizeof(TaskSwitchInfo)); + g_taskSwitchInfo.cntInfo.maxCnt = OS_TASK_SWITCH_INFO_COUNT; +#if (LOSCFG_PLATFORM_EXC == YES) + OsExcRegister((ExcInfoType)OS_EXC_TYPE_TSK_SWITCH, + (EXC_INFO_SAVE_CALLBACK)LOS_TaskSwitchInfoGet, + &g_taskSwitchInfo); +#endif +#endif + g_taskSwitchHook = OsTaskSwitchCheck; + g_pfnUsrTskSwitchHook = NULL; + return; +} +#endif + +/***************************************************************************** + Function : OsTaskEntry + Description : All task entry + Input : taskID --- The ID of the task to be run + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) +{ + UINT32 retVal; + LosTaskCB *taskCB = NULL; + + OS_TASK_ID_CHECK(taskID); + + taskCB = OS_TCB_FROM_TID(taskID); + + (VOID)taskCB->taskEntry(taskCB->arg); + + retVal = LOS_TaskDelete(taskCB->taskID); + if (retVal != LOS_OK) { + PRINT_ERR("Delete Task[TID: %d] Failed!\n", taskCB->taskID); + } +} + +LITE_OS_SEC_TEXT_INIT STATIC_INLINE UINT32 OsTaskInitParamCheck(TSK_INIT_PARAM_S *taskInitParam) +{ + if (taskInitParam == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + if (taskInitParam->pcName == NULL) { + return LOS_ERRNO_TSK_NAME_EMPTY; + } + + if (taskInitParam->pfnTaskEntry == NULL) { + return LOS_ERRNO_TSK_ENTRY_NULL; + } + + if ((taskInitParam->usTaskPrio) > OS_TASK_PRIORITY_LOWEST) { + return LOS_ERRNO_TSK_PRIOR_ERROR; + } + + if (((taskInitParam->usTaskPrio) == OS_TASK_PRIORITY_LOWEST) + && (taskInitParam->pfnTaskEntry != OS_IDLE_TASK_ENTRY)) { + return LOS_ERRNO_TSK_PRIOR_ERROR; + } + + if (taskInitParam->uwStackSize > OS_SYS_MEM_SIZE) { + return LOS_ERRNO_TSK_STKSZ_TOO_LARGE; + } + + if (taskInitParam->uwStackSize == 0) { + taskInitParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + } + taskInitParam->uwStackSize = ALIGN(taskInitParam->uwStackSize, OS_TASK_STACK_ADDR_ALIGN); + + if (taskInitParam->uwStackSize < LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE) { + return LOS_ERRNO_TSK_STKSZ_TOO_SMALL; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S *taskInitParam, VOID *topOfStack) +{ + VOID *stackPtr = NULL; + + stackPtr = OsTskStackInit(taskCB->taskID, taskInitParam->uwStackSize, topOfStack); + taskCB->stackPointer = stackPtr; + taskCB->arg = taskInitParam->uwArg; + taskCB->topOfStack = (UINT32)(UINTPTR)topOfStack; + taskCB->stackSize = taskInitParam->uwStackSize; + taskCB->taskSem = NULL; + taskCB->taskMux = NULL; + taskCB->taskStatus = OS_TASK_STATUS_SUSPEND; + taskCB->priority = taskInitParam->usTaskPrio; + taskCB->taskEntry = taskInitParam->pfnTaskEntry; + taskCB->event.uwEventID = OS_NULL_INT; + taskCB->eventMask = 0; + taskCB->taskName = taskInitParam->pcName; + taskCB->msg = NULL; + + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_TaskCreateOnly + Description : Create a task and suspend + Input : taskInitParam --- Task init parameters + Output : taskID --- Save task ID + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam) +{ + UINTPTR intSave; + VOID *topOfStack = NULL; + LosTaskCB *taskCB = NULL; + UINT32 retVal; + + if (taskID == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + retVal = OsTaskInitParamCheck(taskInitParam); + if (retVal != LOS_OK) { + return retVal; + } + + intSave = LOS_IntLock(); + while (!LOS_ListEmpty(&g_taskRecyleList)) { + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecyleList)); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_taskRecyleList)); + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); + (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)(UINTPTR)taskCB->topOfStack); + taskCB->topOfStack = (UINT32)NULL; + } + + if (LOS_ListEmpty(&g_losFreeTask)) { + retVal = LOS_ERRNO_TSK_TCB_UNAVAILABLE; + OS_GOTO_ERREND(); + } + + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask)); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask)); + + LOS_IntRestore(intSave); + + topOfStack = (VOID *)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, taskInitParam->uwStackSize, + LOSCFG_STACK_POINT_ALIGN_SIZE); + if (topOfStack == NULL) { + intSave = LOS_IntLock(); + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_NO_MEMORY; + } + + retVal = OsNewTaskInit(taskCB, taskInitParam, topOfStack); + if (retVal != LOS_OK) { + return retVal; + } + + *taskID = taskCB->taskID; + return retVal; +} + + +/***************************************************************************** + Function : LOS_TaskCreate + Description : Create a task + Input : taskInitParam --- Task init parameters + Output : taskID --- Save task ID + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam) +{ + UINT32 retVal; + UINTPTR intSave; + LosTaskCB *taskCB = NULL; + + retVal = LOS_TaskCreateOnly(taskID, taskInitParam); + if (retVal != LOS_OK) { + return retVal; + } + taskCB = OS_TCB_FROM_TID(*taskID); + + intSave = LOS_IntLock(); + taskCB->taskStatus &= (~OS_TASK_STATUS_SUSPEND); + taskCB->taskStatus |= OS_TASK_STATUS_READY; + +#if (LOSCFG_BASE_CORE_CPUP == YES) + g_cpup[taskCB->taskID].cpupID = taskCB->taskID; + g_cpup[taskCB->taskID].status = taskCB->taskStatus; +#endif + + OsPriqueueEnqueue(&taskCB->pendList, taskCB->priority); + g_losTask.newTask = LOS_DL_LIST_ENTRY(OsPriqueueTop(), LosTaskCB, pendList); + + if ((g_taskScheduled) && (g_losTaskLock == 0)) { + if (g_losTask.runTask != g_losTask.newTask) { + if (LOS_CHECK_SCHEDULE) { + LOS_IntRestore(intSave); + OsSchedule(); + return LOS_OK; + } + } + } + + LOS_IntRestore(intSave); + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_TaskResume + Description : Resume suspend task + Input : taskID --- Task ID + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) +{ + UINTPTR intSave; + LosTaskCB *taskCB = NULL; + UINT16 tempStatus; + UINT32 retErr = OS_ERROR; + + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + intSave = LOS_IntLock(); + tempStatus = taskCB->taskStatus; + + if (tempStatus & OS_TASK_STATUS_UNUSED) { + retErr = LOS_ERRNO_TSK_NOT_CREATED; + OS_GOTO_ERREND(); + } else if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) { + retErr = LOS_ERRNO_TSK_NOT_SUSPENDED; + OS_GOTO_ERREND(); + } + + taskCB->taskStatus &= (~OS_TASK_STATUS_SUSPEND); + if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) { + taskCB->taskStatus |= OS_TASK_STATUS_READY; + OsPriqueueEnqueue(&taskCB->pendList, taskCB->priority); + if (g_taskScheduled) { + LOS_IntRestore(intSave); + LOS_Schedule(); + return LOS_OK; + } + g_losTask.newTask = LOS_DL_LIST_ENTRY(OsPriqueueTop(), LosTaskCB, pendList); + } + + LOS_IntRestore(intSave); + return LOS_OK; + +LOS_ERREND: + LOS_IntRestore(intSave); + return retErr; +} + +/***************************************************************************** + Function : LOS_TaskSuspend + Description : Suspend task + Input : taskID --- Task ID + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) +{ + UINTPTR intSave; + LosTaskCB *taskCB = NULL; + UINT16 tempStatus; + UINT32 retErr; + + retErr = OsCheckTaskIDValid(taskID); + if (retErr != LOS_OK) { + return retErr; + } + + taskCB = OS_TCB_FROM_TID(taskID); + intSave = LOS_IntLock(); + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + retErr = LOS_ERRNO_TSK_NOT_CREATED; + OS_GOTO_ERREND(); + } + + if (tempStatus & OS_TASK_STATUS_SUSPEND) { + retErr = LOS_ERRNO_TSK_ALREADY_SUSPENDED; + OS_GOTO_ERREND(); + } + + if ((tempStatus & OS_TASK_STATUS_RUNNING) && (g_losTaskLock != 0)) { + retErr = LOS_ERRNO_TSK_SUSPEND_LOCKED; + OS_GOTO_ERREND(); + } + + if (tempStatus & OS_TASK_STATUS_READY) { + OsPriqueueDequeue(&taskCB->pendList); + taskCB->taskStatus &= (~OS_TASK_STATUS_READY); + } + + taskCB->taskStatus |= OS_TASK_STATUS_SUSPEND; + if (taskID == g_losTask.runTask->taskID) { + LOS_IntRestore(intSave); + LOS_Schedule(); + return LOS_OK; + } + + LOS_IntRestore(intSave); + return LOS_OK; + +LOS_ERREND: + LOS_IntRestore(intSave); + return retErr; +} + +LITE_OS_SEC_TEXT_INIT STATIC_INLINE VOID OsRunningTaskDelete(UINT32 taskID, LosTaskCB *taskCB) +{ + LOS_ListTailInsert(&g_taskRecyleList, &taskCB->pendList); + g_losTask.runTask = &g_taskCBArray[g_taskMaxNum]; + g_losTask.runTask->taskID = taskID; + g_losTask.runTask->taskStatus = taskCB->taskStatus; + g_losTask.runTask->topOfStack = taskCB->topOfStack; + g_losTask.runTask->taskName = taskCB->taskName; +} +/***************************************************************************** + Function : LOS_TaskDelete + Description : Delete a task + Input : taskID --- Task ID + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) +{ + UINTPTR intSave; + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + + UINT32 ret = OsCheckTaskIDValid(taskID); + if (ret != LOS_OK) { + return ret; + } + + intSave = LOS_IntLock(); + + if ((taskCB->taskStatus) & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + + /* 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"); + g_losTaskLock = 0; + } + + if ((taskCB->taskStatus) & OS_TASK_STATUS_READY) { + OsPriqueueDequeue(&taskCB->pendList); + taskCB->taskStatus &= (~OS_TASK_STATUS_READY); + } else if (((taskCB->taskStatus) & (OS_TASK_STATUS_PEND | OS_TASK_STATUS_PEND_QUEUE))) { + LOS_ListDelete(&taskCB->pendList); + } + + if ((taskCB->taskStatus) & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_TIMEOUT)) { + OsTimerListDelete(taskCB); + } + + taskCB->taskStatus &= (~(OS_TASK_STATUS_SUSPEND)); + taskCB->taskStatus |= OS_TASK_STATUS_UNUSED; + taskCB->event.uwEventID = OS_NULL_INT; + taskCB->eventMask = 0; +#if (LOSCFG_BASE_CORE_CPUP == YES) + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)memset_s((VOID *)&g_cpup[taskCB->taskID], sizeof(OsCpupCB), 0, sizeof(OsCpupCB)); +#endif + g_losTask.newTask = LOS_DL_LIST_ENTRY(OsPriqueueTop(), LosTaskCB, pendList); + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { + OsRunningTaskDelete(taskID, taskCB); + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + LOS_IntRestore(intSave); + OsSchedule(); + return LOS_OK; + } else { + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); + (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)(UINTPTR)taskCB->topOfStack); + taskCB->topOfStack = (UINT32)NULL; + } + + LOS_IntRestore(intSave); + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_TaskDelay + Description : delay the current task + Input : tick --- time + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) +{ + UINTPTR intSave; + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_TSK_DELAY_IN_INT; + } + + if (g_losTaskLock != 0) { + return LOS_ERRNO_TSK_DELAY_IN_LOCK; + } + + if (tick == 0) { + return LOS_TaskYield(); + } else { + intSave = LOS_IntLock(); + OsPriqueueDequeue(&(g_losTask.runTask->pendList)); + g_losTask.runTask->taskStatus &= (~OS_TASK_STATUS_READY); + OsTaskAdd2TimerList((LosTaskCB *)g_losTask.runTask, tick); + g_losTask.runTask->taskStatus |= OS_TASK_STATUS_DELAY; + LOS_IntRestore(intSave); + LOS_Schedule(); + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) +{ + UINTPTR intSave; + LosTaskCB *taskCB = NULL; + UINT16 priority; + + if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { + return (UINT16)OS_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + + intSave = LOS_IntLock(); + + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return (UINT16)OS_INVALID; + } + + priority = taskCB->priority; + LOS_IntRestore(intSave); + return priority; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) +{ + BOOL isReady = FALSE; + UINTPTR intSave; + LosTaskCB *taskCB = NULL; + UINT16 tempStatus; + + if (taskPrio > OS_TASK_PRIORITY_LOWEST) { + return LOS_ERRNO_TSK_PRIOR_ERROR; + } + + if (taskID == g_idleTaskID) { + return LOS_ERRNO_TSK_OPERATE_IDLE; + } + + if (taskID == g_swtmrTaskID) { + return LOS_ERRNO_TSK_OPERATE_SWTMR; + } + + if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + intSave = LOS_IntLock(); + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + /* delete the task and insert with right priority into ready queue */ + isReady = (tempStatus & OS_TASK_STATUS_READY); + if (isReady) { + OsPriqueueDequeue(&taskCB->pendList); + taskCB->taskStatus &= (~OS_TASK_STATUS_READY); + taskCB->priority = taskPrio; + taskCB->taskStatus |= OS_TASK_STATUS_READY; + OsPriqueueEnqueue(&taskCB->pendList, taskCB->priority); + } else { + taskCB->priority = taskPrio; + } + + LOS_IntRestore(intSave); + /* delete the task and insert with right priority into ready queue */ + if (isReady) { + LOS_Schedule(); + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio) +{ + UINT32 retVal; + retVal = LOS_TaskPriSet(g_losTask.runTask->taskID, taskPrio); + return retVal; +} + +/************************************************************************** + Function : OsTaskWait + Description : pend the running task in a list + Input : pendingList -- The pending list + taskStatus -- The status need to be converted to + timeout -- Expiry time + Output : None + Return : None +**************************************************************************/ +VOID OsTaskWait(LOS_DL_LIST *pendingList, UINT32 taskStatus, UINT32 timeout) +{ + LosTaskCB *runTask = NULL; + LOS_DL_LIST *pendObj = NULL; + + runTask = g_losTask.runTask; + OsPriqueueDequeue(&runTask->pendList); + runTask->taskStatus &= (~OS_TASK_STATUS_READY); + pendObj = &runTask->pendList; + runTask->taskStatus |= taskStatus; + LOS_ListTailInsert(pendingList, pendObj); + if (timeout != LOS_WAIT_FOREVER) { + runTask->taskStatus |= OS_TASK_STATUS_TIMEOUT; + OsTaskAdd2TimerList((LosTaskCB *)runTask, timeout); + } +} + +/************************************************************************** + Function : OsTaskWake + Description : delete the task from pendlist and also add to the priqueue + Input : resumedTask -- resumed task + : taskStatus -- the status to be unset + Output : resumedTask -- resumed task + Return : None +**************************************************************************/ +VOID OsTaskWake(LosTaskCB *resumedTask, UINT32 taskStatus) +{ + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= (~taskStatus); + if (resumedTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + OsTimerListDelete(resumedTask); + resumedTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); + } + if (!(resumedTask->taskStatus & OS_TASK_STATUS_SUSPEND)) { + resumedTask->taskStatus |= OS_TASK_STATUS_READY; + OsPriqueueEnqueue(&resumedTask->pendList, resumedTask->priority); + } +} + +/***************************************************************************** + Function : LOS_TaskYield + Description : Adjust the procedure order of specified task + Input : None + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) +{ + UINT32 taskCount; + UINTPTR intSave; + + if (g_losTask.runTask->taskID >= g_taskMaxNum) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + if (!(g_losTask.runTask->taskStatus & OS_TASK_STATUS_READY)) { + return LOS_OK; + } + + intSave = LOS_IntLock(); + taskCount = OsPriqueueSize(g_losTask.runTask->priority); + if (taskCount > 1) { + LOS_ListDelete(&(g_losTask.runTask->pendList)); + g_losTask.runTask->taskStatus |= OS_TASK_STATUS_READY; + OsPriqueueEnqueue(&(g_losTask.runTask->pendList), g_losTask.runTask->priority); + } else { + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK; + } + + LOS_IntRestore(intSave); + LOS_Schedule(); + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_TaskLock + Description : Task lock + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID) +{ + UINTPTR intSave; + + intSave = LOS_IntLock(); + g_losTaskLock++; + LOS_IntRestore(intSave); +} + +/***************************************************************************** + Function : LOS_TaskUnlock + Description : Task unlock + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) +{ + UINTPTR intSave; + + intSave = LOS_IntLock(); + if (g_losTaskLock > 0) { + g_losTaskLock--; + if (g_losTaskLock == 0) { + LOS_IntRestore(intSave); + LOS_Schedule(); + return; + } + } + + LOS_IntRestore(intSave); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) +{ + UINT32 intSave; + LosTaskCB *taskCB = NULL; +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == YES) + UINT32 flag; +#endif + + if (taskInfo == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + intSave = LOS_IntLock(); + + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + + taskInfo->uwSP = (UINT32)(UINTPTR)taskCB->stackPointer; + taskInfo->usTaskStatus = taskCB->taskStatus; + taskInfo->usTaskPrio = taskCB->priority; + taskInfo->uwStackSize = taskCB->stackSize; + taskInfo->uwTopOfStack = taskCB->topOfStack; + taskInfo->uwEvent = taskCB->event; + taskInfo->uwEventMask = taskCB->eventMask; + taskInfo->uwSemID = (taskCB->taskSem != NULL) ? ((LosSemCB *)(taskCB->taskSem))->semID : + LOSCFG_BASE_IPC_SEM_LIMIT; + taskInfo->uwMuxID = (taskCB->taskMux != NULL) ? ((LosMuxCB *)(taskCB->taskMux))->muxID : + LOSCFG_BASE_IPC_MUX_LIMIT; + taskInfo->pTaskSem = taskCB->taskSem; + taskInfo->pTaskMux = taskCB->taskMux; + taskInfo->uwTaskID = taskID; + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)strncpy_s(taskInfo->acName, LOS_TASK_NAMELEN, taskCB->taskName, LOS_TASK_NAMELEN - 1); + taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0'; + + taskInfo->uwBottomOfStack = TRUNCATE(((UINT32)(taskCB->topOfStack) + (taskCB->stackSize)), + OS_TASK_STACK_ADDR_ALIGN); + taskInfo->uwCurrUsed = taskInfo->uwBottomOfStack - taskInfo->uwSP; + +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == YES) + flag = osStackProtDisable(); +#endif + + taskInfo->uwPeakUsed = OsGetTaskWaterLine(taskID); + taskInfo->bOvf = (taskInfo->uwPeakUsed == OS_NULL_INT) ? TRUE : FALSE; + +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == YES) + osStackProtRestore(flag); +#endif + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskStatusGet(UINT32 taskID, UINT32 *taskStatus) +{ + UINT32 intSave; + LosTaskCB *taskCB = NULL; + + if (taskStatus == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + intSave = LOS_IntLock(); + + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return LOS_ERRNO_TSK_NOT_CREATED; + } + + *taskStatus = taskCB->taskStatus; + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskSwitchInfoGet(UINT32 index, UINT32 *taskSwitchInfo) +{ + UINTPTR intSave; + UINT32 curIndex; + + curIndex = index; + if (curIndex >= OS_TASK_SWITCH_INFO_COUNT) { + curIndex %= OS_TASK_SWITCH_INFO_COUNT; + } + + if (taskSwitchInfo == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } + + intSave = LOS_IntLock(); + + (*taskSwitchInfo) = g_taskSwitchInfo.pid[curIndex]; + + if (memcpy_s((VOID *)(taskSwitchInfo + 1), LOS_TASK_NAMELEN, + g_taskSwitchInfo.name[curIndex], LOS_TASK_NAMELEN) != EOK) { + PRINT_ERR("LOS_TaskSwitchInfoGet copy task name failed\n"); + } + + LOS_IntRestore(intSave); + return LOS_OK; +} +#endif + +/***************************************************************************** +Function : LOS_TaskInfoMonitor +Description : Get all task info +Input : None +Return : LOS_OK on success ,or OS_ERROR on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoMonitor(VOID) +{ + UINT32 retVal; + + retVal = OsGetAllTskInfo(); + + return retVal; +} + +/***************************************************************************** + Function : LOS_TaskIsRunning + Description : Check if LiteOS has been started. + Input : VOID + Output : VOID + Return : TRUE means LiteOS was started, FALSE means not. + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR BOOL LOS_TaskIsRunning(VOID) +{ + return g_taskScheduled; +} + +/***************************************************************************** + Function : LOS_NewTaskIDGet + Description : get id of current new task. + Input : None + Output : None + Return : task id + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_NewTaskIDGet(VOID) +{ + if (g_losTask.newTask == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + return g_losTask.newTask->taskID; +} + +/***************************************************************************** + Function : LOS_TaskNameGet + Description : get Name of current new task. + Input : taskID -----task id + Output : None + Return : task name + *****************************************************************************/ +LITE_OS_SEC_TEXT CHAR* LOS_TaskNameGet(UINT32 taskID) +{ + UINT32 intSave; + LosTaskCB *taskCB = NULL; + + if (OS_CHECK_TSK_PID_NOIDLE(taskID)) { + return NULL; + } + + taskCB = OS_TCB_FROM_TID(taskID); + + intSave = LOS_IntLock(); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return NULL; + } + LOS_IntRestore(intSave); + + return taskCB->taskName; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/core/los_tick.c b/kernel/base/core/los_tick.c new file mode 100755 index 00000000..90a98718 --- /dev/null +++ b/kernel/base/core/los_tick.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_tick_pri.h" +#include "los_base_pri.h" +#include "los_swtmr_pri.h" +#include "los_task_pri.h" +#include "los_timeslice_pri.h" +#if (LOSCFG_KERNEL_TICKLESS == YES) +#include "los_tickless_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +LITE_OS_SEC_BSS UINT64 g_ullTickCount; +LITE_OS_SEC_BSS UINT32 g_ticksPerSec; +LITE_OS_SEC_BSS UINT32 g_uwCyclePerSec; +LITE_OS_SEC_BSS UINT32 g_cyclesPerTick; +LITE_OS_SEC_BSS UINT32 g_sysClock; + +#if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES) +extern VOID platform_tick_handler(VOID); +#endif + +#if (LOSCFG_KERNEL_TICKLESS == YES) +LITE_OS_SEC_TEXT VOID OsTickHandlerLoop(UINT32 elapseTicks) +{ + UINT32 index; + + for (index = 0; index < elapseTicks; index++) { +#if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES) + platform_tick_handler(); +#endif + + g_ullTickCount++; + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + OsTimesliceCheck(); +#endif + OsTaskScan(); // task timeout scan +#if (LOSCFG_BASE_CORE_SWTMR == YES) + (VOID)OsSwtmrScan(); +#endif + } +} + +#endif + +LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) +{ +#if (LOSCFG_KERNEL_TICKLESS == YES) + if (g_reloadSysTickFlag) { + LOS_SysTickReload(g_cyclesPerTick); + g_reloadSysTickFlag = 0; + } + g_tickIrqFlag = g_ticklessFlag; +#endif + +#if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES) + platform_tick_handler(); +#endif + + g_ullTickCount++; + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + OsTimesliceCheck(); +#endif + + OsTaskScan(); // task timeout scan + +#if (LOSCFG_BASE_CORE_SWTMR == YES) + (VOID)OsSwtmrScan(); +#endif +} + +UINT32 LOS_SysClockGet(VOID) +{ + return g_sysClock; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/core/los_timeslice.c b/kernel/base/core/los_timeslice.c new file mode 100755 index 00000000..10683395 --- /dev/null +++ b/kernel/base/core/los_timeslice.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_sys_pri.h" +#include "los_task_pri.h" +#include "los_tick_pri.h" +#include "los_typedef_pri.h" +#include "los_timeslice_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) +LITE_OS_SEC_BSS OsTaskRobin g_taskTimeSlice; + +/***************************************************************************** + Function : OsTimesliceInit + Description : Initialztion Timeslice + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT VOID OsTimesliceInit(VOID) +{ + g_taskTimeSlice.task = (LosTaskCB *)NULL; + g_taskTimeSlice.tout = LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT; +} + +/***************************************************************************** + Function : OsTimesliceCheck + Description : check Timeslice + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT VOID OsTimesliceCheck(VOID) +{ + if (g_taskTimeSlice.task != g_losTask.runTask) { + g_taskTimeSlice.task = g_losTask.runTask; + g_taskTimeSlice.time = ((UINT16)g_ullTickCount + g_taskTimeSlice.tout) - 1; + } + + if (g_taskTimeSlice.time == (UINT16)g_ullTickCount) { + g_taskTimeSlice.task = (LosTaskCB *)NULL; + if (LOS_TaskYield() != LOS_OK) { + PRINT_INFO("%s, %d\n", __FUNCTION__, __LINE__); + } + } +} + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + diff --git a/kernel/base/include/los_base_pri.h b/kernel/base/include/los_base_pri.h new file mode 100755 index 00000000..8b712311 --- /dev/null +++ b/kernel/base/include/los_base_pri.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_BASE_PRI_H +#define _LOS_BASE_PRI_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_base + * Define the CPU Tick structure. + */ +typedef struct tagCpuTick { + UINT32 cntHi; /* < Upper 32 bits of the tick value */ + UINT32 cntLo; /* < Lower 32 bits of the tick value */ +} CpuTick; + +#define OS_GOTO_ERREND() \ + do { \ + goto LOS_ERREND; \ + } while (0) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BASE_PRI_H */ diff --git a/kernel/base/include/los_err_pri.h b/kernel/base/include/los_err_pri.h new file mode 100755 index 00000000..84c16ec8 --- /dev/null +++ b/kernel/base/include/los_err_pri.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_ERR_PRI_H +#define _LOS_ERR_PRI_H + +#include "los_err.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** + * @ingroup los_err + * Define the error magic word. + */ +#define OS_ERR_MAGIC_WORD 0xa1b2c3f8 + +/** + * @ingroup los_err + * @brief Error handling macro capable of returning error codes. + * + * @par Description: + * This API is used to call the error handling function by using an error code and return the same error code. + * @attention + * + * + * @param errNo [IN] Error code. + * + * @retval errNo + * @par Dependency: + * + * @see None. + */ +#define OS_RETURN_ERROR(errNo) \ + do { \ + (VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \ + return (errNo); \ + } while (0) + +/** + * @ingroup los_err + * @brief Error handling macro capable of returning error codes. + * + * @par Description: + * This API is used to call the error handling function by using an error code and the line number of the erroneous line, + and return the same error code. + * @attention + * + * + * @param errLine [IN] Line number of the erroneous line. + * @param errNo [IN] Error code. + * + * @retval errNo + * @par Dependency: + * + * @see None. + */ +#define OS_RETURN_ERROR_P2(errLine, errNo) \ + do { \ + (VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \ + return (errNo); \ + } while (0) + +/** + * @ingroup los_err + * @brief Macro for jumping to error handler. + * + * @par Description: + * This API is used to call the error handling function by using an error code. + * @attention + * + * + * @param errorNo [IN] Error code. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +#define OS_GOTO_ERR_HANDLER(errorNo) \ + do { \ + errNo = (errorNo); \ + errLine = OS_ERR_MAGIC_WORD; \ + goto ERR_HANDLER; \ + } while (0) + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ERR_PRI_H */ diff --git a/kernel/base/include/los_event_pri.h b/kernel/base/include/los_event_pri.h new file mode 100755 index 00000000..7a437a10 --- /dev/null +++ b/kernel/base/include/los_event_pri.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_EVENT_PRI_H +#define _LOS_EVENT_PRI_H + +#include "los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut); +extern UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EVENT_PRI_H */ diff --git a/kernel/base/include/los_heap_pri.h b/kernel/base/include/los_heap_pri.h new file mode 100755 index 00000000..c4c39614 --- /dev/null +++ b/kernel/base/include/los_heap_pri.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_heap Heap + * @ingroup kernel + */ + +#ifndef _LOS_HEAP_PRI_H +#define _LOS_HEAP_PRI_H + +#include "los_heap.h" +#include "los_slab_pri.h" +#include "los_memstat_pri.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct tagLosHeapStatus { + UINT32 totalSize; + UINT32 usedSize; + UINT32 freeSize; + UINT32 allocCount; + UINT32 freeCount; +} LosHeapStatus; + +struct LosHeapManager { + struct LOS_HEAP_NODE *head; + struct LOS_HEAP_NODE *tail; + UINT32 size; +#if (LOSCFG_MEM_MUL_POOL == YES) + VOID *nextPool; +#endif +#if (LOSCFG_KERNEL_MEM_SLAB == YES) + struct LosSlabControlHeader slabCtrlHdr; +#endif +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + TaskMemUsedInfo memStats[LOSCFG_BASE_CORE_TSK_LIMIT + 2]; +#endif +}; + +/** + * @ingroup los_heap + * @brief Look up the next memory node according to one memory node in the memory block list. + * + * @par Description: + * This API is used to look up the next memory node according to one memory node in the memory block list. + * @attention + * + * @param heapMan [IN] Type #LosHeapManager * Pointer to the manager,to distinguish heap. + * @param node [IN] Type #LOS_HEAP_NODE * Size of memory in bytes to allocate. + * + * @retval LOS_HEAP_NODE * Pointer to next memory node. + * + * @par Dependency: + * + * @see None. + */ +extern struct LOS_HEAP_NODE* OsHeapPrvGetNext(struct LosHeapManager *heapMan, struct LOS_HEAP_NODE* node); + +/** + * @ingroup los_heap + * @brief Obtain the heap information. + * + * @par Description: + * This API is used to obtain the heap information. + * @attention + * + * @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool. + * + * @retval None. + * + * @par Dependency: + * + * @see None. + */ +extern VOID OsAlarmHeapInfo(VOID *pool); + +/** + * @ingroup los_heap + * @brief Obtain the heap status. + * + * @par Description: + * This API is used to obtain the heap status. + * @attention + * + * @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool. + * @param status [OUT] Type #LosHeapStatus * Heap status. + * + * @retval UINT32 Get status result. + * + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status); + +/** + * @ingroup los_heap + * @brief Get the max free block size. + * + * @par Description: + * This API is used to Get the max free block size. + * @attention + * + * @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool. + * + * @retval UINT32 Max free block size. + * + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/kernel/base/include/los_membox_pri.h b/kernel/base/include/los_membox_pri.h new file mode 100755 index 00000000..f89d2f7c --- /dev/null +++ b/kernel/base/include/los_membox_pri.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMBOX_PRI_H +#define _LOS_MEMBOX_PRI_H + +#include "los_membox.h" + +#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)((UINT8 *)(addr) + (blkSize)) + +#ifdef LOS_MEMBOX_CHECK +#define OS_MEMBOX_MAGIC 0xa55a5aa5 +#define OS_MEMBOX_SET_MAGIC(addr) (*((UINT32 *)(addr)) = OS_MEMBOX_MAGIC) +#define OS_MEMBOX_CHECK_MAGIC(addr) ((*((UINT32 *)(addr)) == OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) +#else +#define OS_MEMBOX_SET_MAGIC(addr) +#define OS_MEMBOX_CHECK_MAGIC(addr) LOS_OK +#endif + +#define OS_MEMBOX_USER_ADDR(addr) ((VOID *)((UINT8 *)(addr) + LOS_MEMBOX_MAGIC_SIZE)) +#define OS_MEMBOX_NODE_ADDR(addr) ((LOS_MEMBOX_NODE *)((UINT8 *)(addr) - LOS_MEMBOX_MAGIC_SIZE)) + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMBOX_PRI_H */ diff --git a/kernel/base/include/los_memcheck_pri.h b/kernel/base/include/los_memcheck_pri.h new file mode 100755 index 00000000..48e304a1 --- /dev/null +++ b/kernel/base/include/los_memcheck_pri.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMCHECK_PRI_H +#define _LOS_MEMCHECK_PRI_H + +#include "los_memcheck.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +/** + * @ingroup los_memboxcheck + * @brief Update the information of the memory. + * + * @par Description: + * + * @attention + * + * + * @param pool [IN/OUT] Type #VOID * Memory pool number. + * @param size [IN] Type #UINT32 Memory size. + * @param type [IN] Type #UINT32 Memory mang type. + * + * @retval UINT32 Updateinformation result. + * @par Dependency: + * + * @see None. + */ +UINT32 OsMemInfoUpdate(VOID *pool, UINT32 size, UINT32 type); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_MEMCHECK_PRI_H */ diff --git a/kernel/base/include/los_memory_pri.h b/kernel/base/include/los_memory_pri.h new file mode 100755 index 00000000..3e6f1c65 --- /dev/null +++ b/kernel/base/include/los_memory_pri.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMORY_PRI_H +#define _LOS_MEMORY_PRI_H + +#include "los_memory.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MEM_ENABLE_MEM_STATISTICS + +/* + * memcheck error code: the stack have not inited + * Value: 0x02000100 + * Solution: do memcheck must after stack mem init + */ +#define OS_ERRNO_MEMCHECK_NOT_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x0) + +/* + * memcheck error code: the pPtr is NULL + * Value: 0x02000101 + * Solution: don't give a NULL parameter + */ +#define OS_ERRNO_MEMCHECK_PARA_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x1) + +/* + * memcheck error code: the pPtr addr not in the suit range + * Value: 0x02000102 + * Solution: check pPtr and comfirm it included by stack + */ +#define OS_ERRNO_MEMCHECK_OUTSIDE LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x2) + +/* + * memcheck error code: can't find the ctrl node + * Value: 0x02000103 + * Solution: confirm the pPtr if this node has been freed or has not been alloced + */ +#define OS_ERRNO_MEMCHECK_NO_HEAD LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x3) + +/* + * memcheck error code: the para level is wrong + * Value: 0x02000104 + * Solution: checkout the memcheck level by the func "OS_GetMemCheck_Level" + */ +#define OS_ERRNO_MEMCHECK_WRONG_LEVEL LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x4) + +/* + * memcheck error code: memcheck func not open + * Value: 0x02000105 + * Solution: enable memcheck by the func "OS_SetMemCheck_Level" + */ +#define OS_ERRNO_MEMCHECK_DISABLED LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x5) + +/** + * @ingroup los_memory + * @brief Initialization the memory system. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval UINT32 Initialization result. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsMemSystemInit(VOID); + +/** + * @ingroup los_memory + * Memory linked list node structure + */ +typedef struct tagLosMemDynNode { + LOS_DL_LIST freeNodeInfo; /**< Free memory node */ + struct tagLosMemDynNode *preNode; /**< Pointer to the previous memory node */ + UINT32 sizeAndFlag; /**< Size and flag of the current node(the highest bit + represents a flag, and the rest bits specify the size) */ +} LosMemDynNode; + +#define OS_MEM_TASKID_SET(node, ID) \ + do { \ + UINTPTR tmp = (UINTPTR)(((LosMemDynNode *)(node))->freeNodeInfo.pstNext); \ + tmp = tmp & 0xffff0000; \ + tmp |= (ID); \ + ((LosMemDynNode *)(node))->freeNodeInfo.pstNext = (LOS_DL_LIST *)(tmp); \ + } while (0) + +#define OS_MEM_TASKID_GET(node) ((UINT32)(UINTPTR)(((LosMemDynNode *)(node))->freeNodeInfo.pstNext) & 0xffff) + +#define OS_MEM_MODID_SET(node, ID) \ + do { \ + UINTPTR tmp = (UINTPTR)(((LosMemDynNode *)(node))->freeNodeInfo.pstNext); \ + tmp = tmp & 0xffff; \ + tmp |= (ID) << 16; \ + ((LosMemDynNode *)(node))->freeNodeInfo.pstNext = (LOS_DL_LIST *)(tmp); \ + } while (0) + +#define OS_MEM_MODID_GET(node) ((UINT32)(((LosMemDynNode *)(node))->freeNodeInfo.pstNext) >> 16) + +#define OS_MEM_NODE_HEAD_SIZE sizeof(LosMemDynNode) +#define OS_MEM_MIN_POOL_SIZE (OS_DLNK_HEAD_SIZE + (2 * OS_MEM_NODE_HEAD_SIZE) + sizeof(LOS_MEM_POOL_INFO)) +#define OS_MEM_ALIGN_SIZE 4 +#define OS_MEM_NODE_USED_FLAG 0x80000000 +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000 +#define OS_MEM_NODE_ALIGN_SIZE 64 +#define OS_MEM_NODE_NUM 2 +#define OS_MEM_NODE_DATA_SIZE 4 +#define OS_MEM_NODE_COUNT_NUM 8 +#define OS_MULTI_DLNK_SIZE (OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2) + +#define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) ((sizeAndFlag) & OS_MEM_NODE_ALIGNED_FLAG) +#define OS_MEM_NODE_SET_ALIGNED_FLAG(sizeAndFlag) ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_ALIGNED_FLAG)) +#define OS_MEM_NODE_GET_ALIGNED_GAPSIZE(sizeAndFlag) ((sizeAndFlag) & (~OS_MEM_NODE_ALIGNED_FLAG)) +#define OS_MEM_NODE_GET_USED_FLAG(sizeAndFlag) ((sizeAndFlag) & OS_MEM_NODE_USED_FLAG) +#define OS_MEM_NODE_SET_USED_FLAG(sizeAndFlag) ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_USED_FLAG)) +#define OS_MEM_NODE_GET_SIZE(sizeAndFlag) ((sizeAndFlag) & (~OS_MEM_NODE_USED_FLAG)) +#define OS_MEM_IS_NODE_NEXT_EXIST(node, poolInfo) (((UINT32)(node) + (node)->sizeAndFlag) < \ + ((UINT32)(poolInfo) + (poolInfo)->uwPoolSize)) +#define OS_MEM_HEAD(pool, size) OS_DLNK_HEAD(OS_MEM_HEAD_ADDR(pool), size) +#define OS_MEM_HEAD_ADDR(pool) ((VOID *)((UINT32)(UINTPTR)(pool) + sizeof(LOS_MEM_POOL_INFO))) +#define OS_MEM_NEXT_NODE(node) ((LosMemDynNode *)((UINT8 *)(node) + \ + OS_MEM_NODE_GET_SIZE((node)->sizeAndFlag))) +#define OS_MEM_FIRST_NODE(pool) ((LosMemDynNode *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE)) +#define OS_MEM_END_NODE(pool, size) ((LosMemDynNode *)(((UINT8 *)(pool) + (size)) - OS_MEM_NODE_HEAD_SIZE)) +#define OS_MEM_MIDDLE_ADDR_OPEN_END(startAddr, middleAddr, endAddr) \ + (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) < (UINT8 *)(endAddr))) +#define OS_MEM_MIDDLE_ADDR(startAddr, middleAddr, endAddr) (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && \ + ((UINT8 *)(middleAddr) <= (UINT8 *)(endAddr))) +#define OS_MEM_SET_MAGIC(value) (value) = (LOS_DL_LIST *)(UINTPTR)((UINT32)(UINTPTR)(&(value)) ^ 0xffffffff) +#define OS_MEM_MAGIC_VALID(value) ((((UINT32)(UINTPTR)(value)) ^ ((UINT32)(UINTPTR)(&(value)))) == 0xffffffff) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMORY_PRI_H */ diff --git a/kernel/base/include/los_memstat_pri.h b/kernel/base/include/los_memstat_pri.h new file mode 100755 index 00000000..a3628b62 --- /dev/null +++ b/kernel/base/include/los_memstat_pri.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMSTAT_PRI_H +#define _LOS_MEMSTAT_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_MEMORY_BESTFIT == YES) + +extern VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID); +extern VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID); +extern UINT32 OsTaskMemUsage(UINT32 taskID); +extern VOID OsTaskMemClear(UINT32 taskID); + +#ifdef OS_MEM_ENABLE_MEM_STATISTICS +#define OS_MEM_ADD_USED(usedSize, taskID) OsTaskMemUsedInc(usedSize, taskID) +#define OS_MEM_REDUCE_USED(usedSize, taskID) OsTaskMemUsedDec(usedSize, taskID) +#define OS_MEM_CLEAR(taskID) OsTaskMemClear(taskID) +#else +#define OS_MEM_ADD_USED(usedSize, taskID) +#define OS_MEM_REDUCE_USED(usedSize, taskID) +#define OS_MEM_CLEAR(taskID) +#endif + +#else + +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +typedef struct { + UINT32 memUsed; + UINT32 memPeak; +} TaskMemUsedInfo; + +extern VOID OsTaskMemStatInit(TaskMemUsedInfo *memStats); +extern VOID OsTaskMemUsedInc(TaskMemUsedInfo *memStats, UINT32 usedSize, UINT32 taskID); +extern VOID OsTaskMemUsedDec(TaskMemUsedInfo *memStats, UINT32 usedSize, UINT32 taskID); +extern UINT32 OsTaskMemUsage(TaskMemUsedInfo *memStats, UINT32 taskID); +extern VOID OsTaskMemClear(TaskMemUsedInfo *memStats, UINT32 taskID); +#endif +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMSTAT_PRI_H */ diff --git a/kernel/base/include/los_multipledlinkhead_pri.h b/kernel/base/include/los_multipledlinkhead_pri.h new file mode 100755 index 00000000..dbf46499 --- /dev/null +++ b/kernel/base/include/los_multipledlinkhead_pri.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MULTIPLE_DLINK_HEAD_PRI_H +#define _LOS_MULTIPLE_DLINK_HEAD_PRI_H + +#include "los_list.h" + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MAX_MULTI_DLNK_LOG2 30 +#define OS_MIN_MULTI_DLNK_LOG2 4 +#define OS_MULTI_DLNK_NUM ((OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2) + 1) +#define OS_DLNK_HEAD_SIZE OS_MULTI_DLNK_HEAD_SIZE +#define OS_DLNK_INIT_HEAD OsDLnkInitMultiHead +#define OS_DLNK_HEAD OsDLnkMultiHead +#define OS_DLNK_NEXT_HEAD OsDLnkNextMultiHead +#define OS_DLNK_FIRST_HEAD OsDLnkFirstMultiHead +#define OS_MULTI_DLNK_HEAD_SIZE sizeof(LosMultipleDlinkHead) + +typedef struct { + LOS_DL_LIST listHead[OS_MULTI_DLNK_NUM]; +} LosMultipleDlinkHead; + +STATIC_INLINE LOS_DL_LIST *OsDLnkNextMultiHead(VOID *headAddr, LOS_DL_LIST *listHead) +{ + LosMultipleDlinkHead *head = (LosMultipleDlinkHead *)headAddr; + + return (&(head->listHead[OS_MULTI_DLNK_NUM - 1]) == listHead) ? NULL : (listHead + 1); +} + +STATIC_INLINE LOS_DL_LIST *OsDLnkFirstMultiHead(VOID *headAddr) +{ + return (LOS_DL_LIST *)headAddr; +} + +extern VOID OsDLnkInitMultiHead(VOID *headAddr); +extern LOS_DL_LIST *OsDLnkMultiHead(VOID *headAddr, UINT32 size); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MULTIPLE_DLINK_HEAD_PRI_H */ diff --git a/kernel/base/include/los_mux_pri.h b/kernel/base/include/los_mux_pri.h new file mode 100755 index 00000000..99c1f5a5 --- /dev/null +++ b/kernel/base/include/los_mux_pri.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MUX_PRI_H +#define _LOS_MUX_PRI_H + +#include "los_task_pri.h" + +#include "los_mux.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_mux + * Mutex object. + */ +typedef struct { + UINT8 muxStat; /**< State OS_MUX_UNUSED,OS_MUX_USED */ + UINT16 muxCount; /**< Times of locking a mutex */ + UINT32 muxID; /**< Handle ID */ + LOS_DL_LIST muxList; /**< Mutex linked list */ + LosTaskCB *owner; /**< The current thread that is locking a mutex */ + UINT16 priority; /**< Priority of the thread that is locking a mutex */ +} LosMuxCB; + +/** + * @ingroup los_mux + * Mutex state: not in use. + */ +#define OS_MUX_UNUSED 0 + +/** + * @ingroup los_mux + * Mutex state: in use. + */ +#define OS_MUX_USED 1 + +extern LosMuxCB *g_allMux; + +/** + * @ingroup los_mux + * Obtain the pointer to a mutex object of the mutex that has a specified handle. + */ +#define GET_MUX(muxid) (((LosMuxCB *)g_allMux) + (muxid)) + +/** + * @ingroup los_mux + * @brief Initializes the mutex. + * + * @par Description: + * This API is used to initializes the mutex. + * @attention + * + * + * @param None. + * + * @retval UINT32 Initialization result. + * @par Dependency: + * + * @see LOS_MuxDelete + */ +extern UINT32 OsMuxInit(VOID); + +/** + * @ingroup los_mux + * Obtain the pointer to the linked list in the mutex pointed to by a specified pointer. + */ +#define GET_MUX_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosMuxCB, muxList) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_PRI_H */ diff --git a/kernel/base/include/los_printf_pri.h b/kernel/base/include/los_printf_pri.h new file mode 100755 index 00000000..e0406522 --- /dev/null +++ b/kernel/base/include/los_printf_pri.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_PRINTF_PRI_H +#define _LOS_PRINTF_PRI_H + +#include "los_printf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +VOID _dprintf(const CHAR *fmt, va_list ap); +INT32 __dprintf(const CHAR *fmt, va_list ap, VOID (*uart_fputc)(UINT32 n, VOID *cookie), CHAR *cookie); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PRINTF_PRI_H */ diff --git a/kernel/base/include/los_priqueue_pri.h b/kernel/base/include/los_priqueue_pri.h new file mode 100755 index 00000000..9a7c59af --- /dev/null +++ b/kernel/base/include/los_priqueue_pri.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_PRIQUEUE_PRI_H +#define _LOS_PRIQUEUE_PRI_H + +#include "los_list.h" +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_PRIORITY_QUEUE_PRIORITYNUM 32 + +/** + * @ingroup los_priqueue + * @brief Initialize the priority queue. + * + * @par Description: + * This API is used to initialize the priority queue. + * @attention + * + * @param none. + * + * @retval LOS_OK on success . + * @retval LOS_NOK on failure. + * @par Dependency: + * + * @see none. + */ +extern UINT32 OsPriqueueInit(VOID); + +/** + * @ingroup los_priqueue + * @brief Insert a item to the priority queue. + * + * @par Description: + * This API is used to insert a item to the priority queue according to the priority of this item. + * @attention + * + * @param priqueueItem [IN] The node of item to be inserted. + * @param priority [IN] Priority of the item be inserted. + * + * @retval none. + * @par Dependency: + * + * @see OsPriqueueDequeue. + */ +extern VOID OsPriqueueEnqueue(LOS_DL_LIST *priqueueItem, UINT32 priority); + +/** + * @ingroup los_priqueue + * @brief Delete a item from the priority queue. + * + * @par Description: + * This API is used to delete a item from the priority queue. + * @attention + * + * @param priqueueItem [IN] The node of item to be deleted. + * + * @retval none. + * @par Dependency: + * + * @see OsPriqueueEnqueue. + */ +extern VOID OsPriqueueDequeue(LOS_DL_LIST *priqueueItem); + +/** + * @ingroup los_priqueue + * @brief Obtain the item with highest priority. + * + * @par Description: + * This API is used to obtain the item with highest priority in the priority queue. + * @attention + * + * @param none. + * + * @retval NULL : The priority queue is empty. + * @retval item node : The node of the item with highest priority. + * @par Dependency: + * + * @see none. + */ +extern LOS_DL_LIST *OsPriqueueTop(VOID); + +/** + * @ingroup los_priqueue + * @brief Obtain the number of items with the specified priority. + * + * @par Description: + * This API is used to obtain the number of items with the specified priority. + * @attention + * + * @param priority [IN] Obtain the number of items with the specified priority of priority. + * + * @retval The number of items :The number of items with the specified priority. + * @par Dependency: + * + * @see none. + */ +extern UINT32 OsPriqueueSize(UINT32 priority); + +/** + * @ingroup los_priqueue + * @brief Obtain the total number of items in the priority queue. + * + * @par Description: + * This API is used to obtain the number of items in the priority queue. + * @attention + * + * + * @retval The number of items: The total number of items in the priority queue. + * @par Dependency: + * + * @see none. + */ +extern UINT32 OsPriqueueTotalSize(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PRIQUEUE_PRI_H */ diff --git a/kernel/base/include/los_queue_pri.h b/kernel/base/include/los_queue_pri.h new file mode 100755 index 00000000..8ad5a145 --- /dev/null +++ b/kernel/base/include/los_queue_pri.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_QUEUE_PRI_H +#define _LOS_QUEUE_PRI_H + +#include "los_queue.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + OS_QUEUE_READ, + OS_QUEUE_WRITE +} QueueReadWrite; + +typedef enum { + OS_QUEUE_HEAD, + OS_QUEUE_TAIL +} QueueHeadTail; + +typedef enum { + OS_QUEUE_NOT_POINT, + OS_QUEUE_POINT +} QueuePointOrNot; + +#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail, PointOrNot) \ + (((UINT32)(PointOrNot) << 2) | ((UINT32)(HeadOrTail) << 1) | (ReadOrWrite)) +#define OS_QUEUE_READ_WRITE_GET(type) ((type) & (0x01)) +#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1)) +#define OS_QUEUE_READ_TAIL (OS_QUEUE_READ | (OS_QUEUE_TAIL << 1)) +#define OS_QUEUE_WRITE_HEAD (OS_QUEUE_WRITE | (OS_QUEUE_HEAD << 1)) +#define OS_QUEUE_WRITE_TAIL (OS_QUEUE_WRITE | (OS_QUEUE_TAIL << 1)) +#define OS_QUEUE_OPERATE_GET(type) ((type) & (0x03)) +#define OS_QUEUE_IS_POINT(type) ((type) & (0x04)) +#define OS_QUEUE_IS_READ(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_READ) +#define OS_QUEUE_IS_WRITE(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_WRITE) +#define OS_READWRITE_LEN 2 + +/** + * @ingroup los_queue + * Queue information block structure + */ +typedef struct { + UINT8 *queue; /**< Pointer to a queue handle */ + UINT16 queueState; /**< Queue state */ + UINT16 queueLen; /**< Queue length */ + UINT16 queueSize; /**< Node size */ + UINT16 queueID; /**< queueID */ + UINT16 queueHead; /**< Node head */ + UINT16 queueTail; /**< Node tail */ + UINT16 readWriteableCnt[OS_READWRITE_LEN]; /**< Count of readable or writable resources, 0:readable, 1:writable */ + LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /**< Pointer to the linked list to be read or written, + 0:readlist, 1:writelist */ + LOS_DL_LIST memList; /**< Pointer to the memory linked list */ +} LosQueueCB; + +/* queue state */ +/** + * @ingroup los_queue + * Message queue state: not in use. + */ +#define OS_QUEUE_UNUSED 0 + +/** + * @ingroup los_queue + * Message queue state: used. + */ +#define OS_QUEUE_INUSED 1 + +/** + * @ingroup los_queue + * Not in use. + */ +#define OS_QUEUE_WAIT_FOR_POOL 1 + +/** + * @ingroup los_queue + * Normal message queue. + */ +#define OS_QUEUE_NORMAL 0 + +/** + * @ingroup los_queue + * Queue information control block + */ +extern LosQueueCB *g_allQueue; + +/** + * @ingroup los_queue + * Obtain a handle of the queue that has a specified ID. + */ +#define GET_QUEUE_HANDLE(QueueID) (((LosQueueCB *)g_allQueue) + (QueueID)) + +/** + * @ingroup los_queue + * Obtain the head node in a queue doubly linked list. + */ +#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE]) + +/** + * @ingroup los_queue + * @brief Alloc a stationary memory for a mail. + * + * @par Description: + * This API is used to alloc a stationary memory for a mail according to queueID. + * @attention + * + * + * @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param mailPool [IN] The memory poll that stores the mail. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER]. + * + * @retval #NULL The memory allocation is failed. + * @retval #mem The address of alloc memory. + * @par Dependency: + * + * @see OsQueueMailFree + */ +extern VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Free a stationary memory of a mail. + * + * @par Description: + * This API is used to free a stationary memory for a mail according to queueID. + * @attention + * + * + * @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param mailPool [IN] The mail memory poll address. + * @param mailMem [IN] The mail memory block address. + * + * @retval #LOS_OK 0x00000000: The memory free successfully. + * @retval #OS_ERRNO_QUEUE_MAIL_HANDLE_INVALID 0x02000619: The handle of the queue passed-in when the memory for + the queue is being freed is invalid. + * @retval #OS_ERRNO_QUEUE_MAIL_PTR_INVALID 0x0200061a: The pointer to the memory to be freed is null. + * @retval #OS_ERRNO_QUEUE_MAIL_FREE_ERROR 0x0200061b: The memory for the queue fails to be freed. + * @par Dependency: + * + * @see OsQueueMailAlloc + */ +extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem); + +/** + * @ingroup los_queue + * @brief Initialization queue. + * + * @par Description: + * This API is used to initialization queue. + * @attention + * + * + * @param None. + * + * @retval UINT32 Initialization result. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsQueueInit(VOID); + +/** + * @ingroup los_queue + * @brief Handle when read or write queue. + * + * @par Description: + * This API is used to handle when read or write queue. + * @attention + * + * + * @param queueID [IN] Queue id. + * @param operateType [IN] Operate type + * @param bufferAddr [IN] Buffer address. + * @param bufferSize [IN] Buffer size. + * @param timeOut [IN] Timeout. + * + * @retval UINT32 Handle result. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, + UINT32 timeOut); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_PRI_H */ diff --git a/kernel/base/include/los_sem_pri.h b/kernel/base/include/los_sem_pri.h new file mode 100755 index 00000000..a17e14ba --- /dev/null +++ b/kernel/base/include/los_sem_pri.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_SEM_PRI_H +#define _LOS_SEM_PRI_H + +#include "los_sem.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +enum LosSemMaxCount { + OS_SEM_COUNTING_MAX_COUNT = 0xFFFF, /**< Max count of counting semaphores */ + OS_SEM_BINARY_MAX_COUNT = 1 /**< Max count of binary semaphores */ +}; + +/** + * @ingroup los_sem + * Semaphore control structure. + */ +typedef struct { + UINT16 semStat; /**< Semaphore state */ + UINT16 semCount; /**< Number of available semaphores */ + UINT16 maxSemCount; /**< Max number of available semaphores */ + UINT16 semID; /**< Semaphore control structure ID */ + LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore */ +} LosSemCB; + +/** + * @ingroup los_sem + * The semaphore is not in use. + * + */ +#define OS_SEM_UNUSED 0 +/** + * @ingroup los_sem + * The semaphore is used. + * + */ +#define OS_SEM_USED 1 +/** + * @ingroup los_sem + * Obtain the head node in a semaphore doubly linked list. + * + */ +#define GET_SEM_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosSemCB, semList) +extern LosSemCB *g_allSem; +/** + * @ingroup los_sem + * Obtain a semaphore ID. + * + */ +#define GET_SEM(semid) (((LosSemCB *)g_allSem) + (semid)) + +/** + * @ingroup los_sem + * @brief Initialize the Semaphore doubly linked list. + * + * @par Description: + * This API is used to initialize the Semaphore doubly linked list. + * @attention + * + * + * @param None. + * + * @retval UINT32 Initialization result. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsSemInit(VOID); + +/** + * @ingroup los_sem + * @brief Create Semaphore. + * + * @par Description: + * This API is used to create Semaphore. + * @attention + * + * + * @param count [IN]Type #UINT16 Semaphore count. + * @param maxCount [IN]Type #UINT16 Max semaphore count. + * @param semHandle [OUT]Type #UINT32 * Index of semaphore. + * + * @retval UINT32 Create result. + * @par Dependency: + * + * @see None. + */ +UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SEM_PRI_H */ diff --git a/kernel/base/include/los_slab_pri.h b/kernel/base/include/los_slab_pri.h new file mode 100755 index 00000000..4cef0bad --- /dev/null +++ b/kernel/base/include/los_slab_pri.h @@ -0,0 +1,687 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_slab Slab + * @ingroup kernel + */ + +#ifndef _LOS_SLAB_PRI_H +#define _LOS_SLAB_PRI_H + +#include "los_base.h" +#include "los_slab.h" +#include + +typedef struct tagLosSlabStatus { + UINT32 totalSize; + UINT32 usedSize; + UINT32 freeSize; + UINT32 allocCount; + UINT32 freeCount; +} LosSlabStatus; + +typedef struct tagOsSlabBlockNode { + UINT16 magic; + UINT8 blkSz; + UINT8 recordId; +} OsSlabBlockNode; + +struct AtomicBitset { + UINT32 numBits; + UINT32 words[0]; +}; + +typedef struct tagOsSlabAllocator { + UINT32 itemSz; + UINT8 *dataChunks; + struct AtomicBitset *bitset; +} OsSlabAllocator; + +typedef struct tagOsSlabMem { + UINT32 blkSz; + UINT32 blkCnt; + UINT32 blkUsedCnt; + OsSlabAllocator *alloc; +} OsSlabMem; + +struct LosSlabControlHeader { + OsSlabMem slabClass[SLAB_MEM_COUNT]; +}; + +#define OS_SLAB_MAGIC 0xdede +#define OS_SLAB_BLOCK_HEAD_GET(ptr) ((OsSlabBlockNode *)(VOID *)((UINT8 *)(ptr) - \ + sizeof(OsSlabBlockNode))) +#define OS_SLAB_BLOCK_MAGIC_SET(slabNode) (((OsSlabBlockNode *)(slabNode))->magic = (UINT16)OS_SLAB_MAGIC) +#define OS_SLAB_BLOCK_MAGIC_GET(slabNode) (((OsSlabBlockNode *)(slabNode))->magic) +#define OS_SLAB_BLOCK_SIZE_SET(slabNode, size) (((OsSlabBlockNode *)(slabNode))->blkSz = (size)) +#define OS_SLAB_BLOCK_SIZE_GET(slabNode) (((OsSlabBlockNode *)(slabNode))->blkSz) +#define OS_SLAB_BLOCK_ID_SET(slabNode, id) (((OsSlabBlockNode *)(slabNode))->recordId = (id)) +#define OS_SLAB_BLOCK_ID_GET(slabNode) (((OsSlabBlockNode *)(slabNode))->recordId) +#define OS_ALLOC_FROM_SLAB_CHECK(slabNode) (((OsSlabBlockNode *)(slabNode))->magic == (UINT16)OS_SLAB_MAGIC) + +#define ATOMIC_BITSET_SZ(numbits) (sizeof(struct AtomicBitset) + ((numbits) + 31) / 8) + +/** + * @ingroup los_slab + * @brief Initialization atomic bitset. + * + * @par Description: + * This API is used to initialization atomic bitset. + * + * @attention + * + * + * @param set [IN/OUT] Type #AtomicBitset * Atomic bitset. + * @param numBits [IN] Type #UINT32 Bits number. + * + * @retval None. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +VOID OsAtomicBitsetInit(struct AtomicBitset *set, UINT32 numBits); + +/** + * @ingroup los_slab + * @brief Get atomic bitset number. + * + * @par Description: + * This API is used to get atomic bitset number. + * + * @attention + * + * + * @param set [IN] Type #AtomicBitset * Atomic bitset. + * + * @retval UINT32 Atomic bitset number. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +UINT32 OsAtomicBitsetGetNumBits(const struct AtomicBitset *set); + +/** + * @ingroup los_slab + * @brief Get atomic bitset bit. + * + * @par Description: + * This API is used to get atomic bitset bit. + * + * @attention + * + * + * @param set [IN] Type #AtomicBitset * Atomic bitset. + * @param num [IN] Type #UINT32 Bit number. + * + * @retval BOOL success or failed + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +BOOL OsAtomicBitsetGetBit(const struct AtomicBitset *set, UINT32 num); + +/** + * @ingroup los_slab + * @brief Clear the atomic bitset bit. + * + * @par Description: + * This API is used to clear the atomic bitset bit. + * + * @attention + * + * + * @param set [IN] Type #AtomicBitset * Atomic bitset. + * @param num [IN] Type #UINT32 Bit number. + * + * @retval None. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +VOID OsAtomicBitsetClearBit(struct AtomicBitset *set, UINT32 num); + +/** + * @ingroup los_slab + * @brief Clear and set the atomic bitset bit. + * + * @par Description: + * This API is used to clear and set the atomic bitset bit. + * + * @attention + * + * + * @param set [IN] Type #AtomicBitset * Atomic bitset. + * + * @retval INT32 The address of the first available bit. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +INT32 OsAtomicBitsetFindClearAndSet(struct AtomicBitset *set); + +/** + * @ingroup los_slab + * @brief Change the order of the output idx of OsAtomicBitsetFindClearAndSet to order of natural numbers. + * + * @par Description: + * This API is used to change the order of the output idx of OsAtomicBitsetFindClearAndSet to order of natural numbers. + * + * @attention + * + * + * @param bitset [IN] Type #AtomicBitset * Atomic bitset. + * @param index [IN] Type #INT32 index. + * + * @retval INT32 Index to natural numbers. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +INT32 OsAtomicBitsetIdxChgToNatural(struct AtomicBitset *bitset, INT32 index); + +/** + * @ingroup los_slab + * @brief Judgment the atomic bitset is empty. + * + * @par Description: + * This API is used to judgment the atomic bitset is empty. + * + * @attention + * + * + * @param bitset [IN] Type #AtomicBitset * Atomic bitset. + * + * @retval BOOL Judgment result. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +BOOL OsAtomicBitsetEmpty(struct AtomicBitset *bitset); + +// thread/interrupt safe. allocations will not fail if space exists. even in interrupts. +// itemAlign over 4 will not be guaranteed since the heap does not hand out chunks with that kind of alignment +/** + * @ingroup los_slab + * @brief create a new slab allocator. + * + * @par Description: + * This API is used to create a new slab allocator. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param itemSz [IN] The size of one slab page. + * @param itemAlign [IN] Type alignment, 4 byte-aligned, 8 byte-aligned, etc. + * @param numItems [IN] The number of slab page. + * + * @retval #OS_SLAB_ALLOCATOR* The address of slab allocator. + * @par Dependency: + * + * @see OsSlabAllocatorDestroy + */ +OsSlabAllocator *OsSlabAllocatorNew(VOID *pool, UINT32 itemSz, UINT32 itemAlign, UINT32 numItems); + +/** + * @ingroup los_slab + * @brief Destroy a slab allocator. + * + * @par Description: + * This API is used to Destroy a slab allocator. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param allocator [IN] a slab allocator. + * + * @retval #VOID + * @par Dependency: + * + * @see OsSlabAllocatorNew + */ +VOID OsSlabAllocatorDestroy(VOID *pool, OsSlabAllocator *allocator); + +/** + * @ingroup los_slab + * @brief Allocate a slab page form allocator. + * + * @par Description: + * This API is used to allocate a slab page form allocator. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * + * @retval #VOID* return a slab page. + * @par Dependency: + * + * @see OsSlabAllocatorFree + */ +VOID* OsSlabAllocatorAlloc(OsSlabAllocator *allocator); + +/** + * @ingroup los_slab + * @brief Free a slab page. + * + * @par Description: + * This API is used to free a slab page. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * @param ptr [IN] a slab page. + * + * @retval #FALSE Failed to free a slab page. + * @retval #TRUE Succees to free a slab page. + * @par Dependency: + * + * @see LOS_SlabAllocatorAlloc + */ +BOOL OsSlabAllocatorFree(OsSlabAllocator *allocator, VOID* ptr); + +/** + * @ingroup los_slab + * @brief Get a slab page index with judgment. + * + * @par Description: + * This API is used to get a slab page index with judgment. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * @param idx [IN] index + * + * @retval VOID * + * @par Dependency: + * + * @see None. + */ +/* -> pointer or NULL if that slot is empty may be not int-safe. YMMV */ +VOID* OsSlabAllocatorGetNth(OsSlabAllocator *allocator, UINT32 idx); + +/** + * @ingroup los_slab + * @brief Get a slab page index without judgment. + * + * @par Description: + * This API is used to get a slab page index without judgment. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * @param idx [IN] index + * + * @retval VOID * + * @par Dependency: + * + * @see None. + */ +VOID* OsSlabAllocatorGetIdxP(OsSlabAllocator *allocator, UINT32 idx); + +/** + * @ingroup los_slab + * @brief Get the index of slab page in slab allocator. + * + * @par Description: + * This API is used to get the index of slab page in slab allocator. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * @param ptr [IN] a slab page. + * + * @retval #-1 Illegal index . + * @retval #UINT32 Succees to get index. + * @par Dependency: + * + * @see + */ +UINT32 OsSlabAllocatorGetIndex(OsSlabAllocator *allocator, VOID *ptr); + +/** + * @ingroup los_slab + * @brief Get the number of slab page. + * + * @par Description: + * This API is used to get the number of slab page. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * + * @retval #UINT32 Succees to get the number of slab page. + * @par Dependency: + * + * @see + */ +UINT32 OsSlabAllocatorGetNumItems(OsSlabAllocator *allocator); + +/** + * @ingroup los_slab + * @brief Check the slab allocator. + * + * @par Description: + * This API is used to check the slab allocator. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * + * @retval #FALSE The slab allocator is already used. + * @retval #TRUE The slab allocator is not used. + * @par Dependency: + * + * @see + */ +BOOL OsSlabAllocatorEmpty(OsSlabAllocator *allocator); + +/** + * @ingroup los_slab + * @brief Get the used number of slab page in slab allocator. + * + * @par Description: + * This API is used to get the used number of slab page in slab allocator. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * + * @retval #UINT32 The used number of slab page in slab allocator. + * @par Dependency: + * + * @see + */ +UINT32 OsSlabAllocatorGetUsedItemCnt(OsSlabAllocator *allocator); + +/** + * @ingroup los_slab + * @brief Get the info of slab allocator. + * + * @par Description: + * This API is used to get the info of slab allocator. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * @param itemSize [OUT] a slab page size. + * @param itemCnt [OUT] a slab page num. + * @param curUsage [OUT] a used number of slab page. + * + * @retval #VOID + * @par Dependency: + * + * @see + */ +VOID OsSlabAllocatorGetSlabInfo(OsSlabAllocator *allocator, UINT32 *itemSize, UINT32 *itemCnt, UINT32 *curUsage); + +/** + * @ingroup los_slab + * @brief init slab allocator. + * + * @par Description: + * This API is used to init slab allocator. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * + * @retval BOOL + * @par Dependency: + * + * @see + */ +extern BOOL OsSlabMemInit(VOID *pool); + +/** + * @ingroup los_slab + * @brief alloc mem by slab allocator. + * + * @par Description: + * This API is used to alloc mem by slab allocator. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param sz [IN] Size of mem to alloc + * + * @retval VOID * The address of alloced mem or NULL. + * @par Dependency: + * + * @see + */ +extern VOID *OsSlabMemAlloc(VOID *pool, UINT32 sz); + +/** + * @ingroup los_slab + * @brief free mem by slab allocator. + * + * @par Description: + * This API is used to free mem by slab allocator. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param ptr [IN] Pointer to the memory that to be free + * + * @retval BOOL success or failed + * @par Dependency: + * + * @see + */ +extern BOOL OsSlabMemFree(VOID *pool, VOID *ptr); + +/** + * @ingroup los_slab + * @brief deinit slab allocator. + * + * @par Description: + * This API is used to deinit slab allocator. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * + * @retval VOID + * @par Dependency: + * + * @see + */ +extern VOID OsSlabMemDeinit(VOID *pool); + +/** + * @ingroup los_slab + * @brief Check slab allocator. + * + * @par Description: + * This API is used to check slab allocator. + * + * @attention + * + * + * @param allocator [IN] a slab allocator. + * @param ptr [IN] Slab node. + * + * @retval VOID + * @par Dependency: + * + * @see None. + */ +extern BOOL OsSlabAllocatorCheck(OsSlabAllocator *allocator, VOID *ptr); + +/** + * @ingroup los_slab + * @brief Get SlabCtrlHdr. + * + * @par Description: + * This API is used to get SlabCtrlHdr. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * + * @retval VOID + * @par Dependency: + * + * @see None. + */ +extern VOID *OsSlabCtrlHdrGet(const VOID *pool); + +/** + * @ingroup los_slab + * @brief Check the slab memory. + * + * @par Description: + * This API is used to check the slab memory. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param ptr [IN] Slab block head. + * + * @retval UINT32 block size. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsSlabMemCheck(VOID *pool, VOID *ptr); + +/** + * @ingroup los_slab + * @brief Get the slab status. + * + * @par Description: + * This API is used to get the slab status. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param status [IN/OUT] Slab block status. + * + * @retval UINT32 Get status result. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsSlabStatisticsGet(VOID *pool, LosSlabStatus *status); + +/** + * @ingroup los_slab + * @brief Get the max free block size. + * + * @par Description: + * This API is used to get the max free block size. + * + * @attention + * + * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * + * @retval UINT32 Max free block size. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsSlabGetMaxFreeBlkSize(VOID *pool); + +#endif + diff --git a/kernel/base/include/los_swtmr_pri.h b/kernel/base/include/los_swtmr_pri.h new file mode 100755 index 00000000..a61dbcd3 --- /dev/null +++ b/kernel/base/include/los_swtmr_pri.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_SWTMR_PRI_H +#define _LOS_SWTMR_PRI_H + +#include "los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** + * @ingroup los_swtmr + * Software timer state + */ +enum SwtmrState { + OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */ + OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */ + OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */ +}; + +/** + * @ingroup los_swtmr + * Structure of the callback function that handles software timer timeout + */ +typedef struct { + SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */ + UINT32 arg; /**< Parameter passed in when the callback function + that handles software timer timeout is called */ +} SwtmrHandlerItem; + +extern SWTMR_CTRL_S *g_swtmrCBArray; + +#define OS_SWT_FROM_SID(swtmrId) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrId) % LOSCFG_BASE_CORE_SWTMR_LIMIT)) + +/** + * @ingroup los_swtmr + * @brief Scan a software timer. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see LOS_SwtmrStop + */ +extern UINT32 OsSwtmrScan(VOID); + +/** + * @ingroup los_swtmr + * @brief Initialization software timer. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsSwtmrInit(VOID); + +/** + * @ingroup los_swtmr + * @brief Get next timeout. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsSwtmrGetNextTimeout(VOID); + +/** + * @ingroup los_swtmr + * @brief Adjust software timer list. + * + * @par Description: + * + * @attention + * + * + * @param sleepTime [IN] UINT32 Sleep time. + * + * @retval UINT32 Sleep time. + * @par Dependency: + * + * @see None. + */ +extern VOID OsSwtmrAdjust(UINT32 sleepTime); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SWTMR_PRI_H */ diff --git a/kernel/base/include/los_sys_pri.h b/kernel/base/include/los_sys_pri.h new file mode 100755 index 00000000..27b85e5d --- /dev/null +++ b/kernel/base/include/los_sys_pri.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_SYS_PRI_H +#define _LOS_SYS_PRI_H + +#include "los_base_pri.h" +#include "los_tick_pri.h" +#include "los_sys.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sys + * Number of operable bits of a 32-bit operand + */ +#define OS_SYS_MV_32_BIT 32 + +/** + * @ingroup los_sys + * Number of milliseconds in one second. + */ +#define OS_SYS_MS_PER_SECOND 1000 + +/** + * @ingroup los_sys + * Number of microseconds in one second. + */ +#define OS_SYS_US_PER_SECOND 1000000 + +/** + * @ingroup los_sys + * The maximum length of name. + */ +#define OS_SYS_APPVER_NAME_MAX 64 + +/** + * @ingroup los_sys + * The magic word. + */ +#define OS_SYS_MAGIC_WORD 0xAAAAAAAA + +/** + * @ingroup los_sys + * The initialization value of stack space. + */ +#define OS_SYS_EMPTY_STACK 0xCACACACA + +/** + * @ingroup los_sys + * @brief Convert cycles to milliseconds. + * + * @par Description: + * This API is used to convert cycles to milliseconds. + * @attention + * + * + * @param cpuTick [IN] Number of CPU cycles. + * @param msHi [OUT] Upper 32 bits of the number of milliseconds. + * @param msLo [OUT] Lower 32 bits of the number of milliseconds. + * + * @retval #LOS_ERRNO_SYS_PTR_NULL 0x02000011: Invalid parameter. + * @retval #LOS_OK 0: Cycles are successfully converted to microseconds. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsCpuTick2MS(CpuTick *cpuTick, UINT32 *msHi, UINT32 *msLo); + +/** + * @ingroup los_sys + * @brief Convert cycles to microseconds. + * + * @par Description: + * This API is used to convert cycles to microseconds. + * @attention + * + * + * @param cpuTick [IN] Number of CPU cycles. + * @param usHi [OUT] Upper 32 bits of the number of microseconds. + * @param usLo [OUT] Lower 32 bits of the number of microseconds. + * + * @retval #LOS_ERRNO_SYS_PTR_NULL 0x02000011: Invalid parameter. + * @retval #LOS_OK 0: Cycles are successfully converted to microseconds. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsCpuTick2US(CpuTick *cpuTick, UINT32 *usHi, UINT32 *usLo); + +/** + * @ingroup los_sys + * @brief Convert cycles to milliseconds. + * + * @par Description: + * This API is used to convert cycles to milliseconds. + * @attention + * + * + * @param cycle [IN] Number of cycles. + * + * @retval Number of milliseconds obtained through the conversion. Cycles are successfully converted to milliseconds. + * @par Dependency: + * + * @see None. + */ +STATIC_INLINE UINT64 OsCycle2MS(UINT64 cycle) +{ + return (UINT64)((cycle / (g_sysClock / OS_SYS_MS_PER_SECOND))); +} + +/** + * @ingroup los_sys + * @brief Convert cycles to microseconds. + * + * @par Description: + * This API is used to convert cycles to microseconds. + * @attention + * + * + * @param cycle [IN] Number of cycles. + * + * @retval Number of microseconds obtained through the conversion. Cycles are successfully converted to microseconds. + * @par Dependency: + * + * @see None. + */ +STATIC_INLINE UINT64 OsCycle2US(UINT64 cycle) +{ + UINT64 tmp = g_sysClock / OS_SYS_US_PER_SECOND; + if (tmp == 0) { + return 0; + } + return (UINT64)(cycle / tmp); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SYS_PRI_H */ diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h new file mode 100755 index 00000000..b3f9b106 --- /dev/null +++ b/kernel/base/include/los_task_pri.h @@ -0,0 +1,711 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_TASK_PRI_H +#define _LOS_TASK_PRI_H + +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** + * @ingroup los_task + * Null task ID + * + */ +#define OS_TASK_ERRORID 0xFFFFFFFF + +/** + * @ingroup los_task + * Define a usable task priority. + * + * Highest task priority. + */ +#define OS_TASK_PRIORITY_HIGHEST 0 + +/** + * @ingroup los_task + * Define a usable task priority. + * + * Lowest task priority. + */ +#define OS_TASK_PRIORITY_LOWEST 31 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task control block is unused. + */ +#define OS_TASK_STATUS_UNUSED 0x0001 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is suspended. + */ +#define OS_TASK_STATUS_SUSPEND 0x0002 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is ready. + */ +#define OS_TASK_STATUS_READY 0x0004 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is blocked. + */ +#define OS_TASK_STATUS_PEND 0x0008 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is running. + */ +#define OS_TASK_STATUS_RUNNING 0x0010 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is delayed. + */ +#define OS_TASK_STATUS_DELAY 0x0020 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The time for waiting for an event to occur expires. + */ +#define OS_TASK_STATUS_TIMEOUT 0x0040 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is waiting for an event to occur. + */ +#define OS_TASK_STATUS_EVENT 0x0400 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is reading an event. + */ +#define OS_TASK_STATUS_EVENT_READ 0x0800 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * A software timer is waiting for an event to occur. + */ +#define OS_TASK_STATUS_SWTMR_WAIT 0x1000 + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is blocked on a queue. + */ +#define OS_TASK_STATUS_PEND_QUEUE 0x2000 + +/** + * @ingroup los_task + * Flag that indicates the task is in userspace. + * + * The task is a user task. + */ +#define OS_TASK_STATUS_USERSPACE 0x8000 + +/** + * @ingroup los_task + * Boundary on which the stack size is aligned. + * + */ +#define OS_TASK_STACK_SIZE_ALIGN 16 + +/** + * @ingroup los_task + * Boundary on which the stack address is aligned. + * + */ +#define OS_TASK_STACK_ADDR_ALIGN 8 + +/** + * @ingroup los_task + * Task stack top magic number. + * + */ +#define OS_TASK_MAGIC_WORD 0xCCCCCCCC + +/** + * @ingroup los_task + * Initial task stack value. + * + */ +#define OS_TASK_STACK_INIT 0xCACACACA + +/** + * @ingroup los_task + * Number of usable task priorities. + */ +#define OS_TSK_PRINUM ((OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST) + 1) + +/** + * @ingroup los_task + * @brief the num of delayed tasks bucket + */ +#define OS_TSK_SORTLINK_LEN 32 + +/** + * @ingroup los_task + * @brief the bit width occupied by the delayed ticks of task + */ +#define OS_TSK_SORTLINK_LOGLEN 5 + +/** + * @ingroup los_task + * @brief the mask of delayed tasks bucket id. + */ +#define OS_TSK_SORTLINK_MASK (OS_TSK_SORTLINK_LEN - 1) + +/** + * @ingroup los_task + * @brief the max task count for switch. + */ +#define OS_TASK_SWITCH_INFO_COUNT 0xA + +/** + * @ingroup los_task + * @brief Check whether a task ID is valid. + * + * @par Description: + * This API is used to check whether a task ID, excluding the idle task ID, is valid. + * @attention None. + * + * @param taskID [IN] Task ID. + * + * @retval 0 or 1. One indicates that the task ID is invalid, whereas zero indicates that the task ID is valid. + * @par Dependency: + * + * @see + */ +#define OS_TSK_GET_INDEX(taskID) (taskID) + +/** + * @ingroup los_task + * @brief Obtain the pointer to a task control block. + * + * @par Description: + * This API is used to obtain the pointer to a task control block using a corresponding parameter. + * @attention None. + * + * @param ptr [IN] Parameter used for obtaining the task control block. + * + * @retval Pointer to the task control block. + * @par Dependency: + * + * @see + */ +#define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosTaskCB, pendList) + +/** + * @ingroup los_task + * @brief Obtain the pointer to a task control block. + * + * @par Description: + * This API is used to obtain the pointer to a task control block that has a specified task ID. + * @attention None. + * + * @param taskID [IN] task ID. + * + * @retval Pointer to the task control block. + * @par Dependency: + * + * @see + */ +#define OS_TCB_FROM_TID(taskID) (((LosTaskCB *)g_taskCBArray) + (taskID)) +#define OS_IDLE_TASK_ENTRY ((TSK_ENTRY_FUNC)OsIdleTask) + + +/** + * @ingroup los_task + * Define the task control block structure. + */ +typedef struct { + VOID *stackPointer; /**< Task stack pointer */ + UINT16 taskStatus; + UINT16 priority; + UINT32 stackSize; /**< Task stack size */ + UINT32 topOfStack; /**< Task stack top */ + UINT32 taskID; /**< Task ID */ + TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ + VOID *taskSem; /**< Task-held semaphore */ + VOID *taskMux; /**< Task-held mutex */ + UINT32 arg; /**< Parameter */ + CHAR *taskName; /**< Task name */ + LOS_DL_LIST pendList; + LOS_DL_LIST timerList; + UINT32 idxRollNum; + EVENT_CB_S event; + UINT32 eventMask; /**< Event mask */ + UINT32 eventMode; /**< Event mode */ + VOID *msg; /**< Memory allocated to queues */ +} LosTaskCB; + +typedef struct { + LosTaskCB *runTask; + LosTaskCB *newTask; +} LosTask; + +typedef struct { + LOS_DL_LIST *sortLink; + UINT16 cursor; + UINT16 unused; +} TaskSortLinkAttr; + +/** + * @ingroup los_task + * Time slice structure. + */ +typedef struct TaskTimeSlice { + LosTaskCB *task; /**< Current running task */ + UINT16 time; /**< Expiration time point */ + UINT16 tout; /**< Expiration duration */ +} OsTaskRobin; + +typedef struct { + UINT8 maxCnt : 7; // bits [6:0] store count of task switch info + UINT8 isFull : 1; // bit [7] store isfull status +} TaskCountInfo; + +/** + * @ingroup los_task + * Task switch information structure. + * + */ +typedef struct { + UINT8 idx; + TaskCountInfo cntInfo; + UINT16 pid[OS_TASK_SWITCH_INFO_COUNT]; + CHAR name[OS_TASK_SWITCH_INFO_COUNT][LOS_TASK_NAMELEN]; +}TaskSwitchInfo; + + +extern LosTask g_losTask; + +/** + * @ingroup los_task + * Task lock flag. + * + */ +extern UINT16 g_losTaskLock; + +/** + * @ingroup los_task + * Maximum number of tasks. + * + */ +extern UINT32 g_taskMaxNum; + +/** + * @ingroup los_task + * Idle task ID. + * + */ +extern UINT32 g_idleTaskID; + +/** + * @ingroup los_task + * Software timer task ID. + * + */ +extern UINT32 g_swtmrTaskID; + +/** + * @ingroup los_task + * Starting address of a task. + * + */ +extern LosTaskCB *g_taskCBArray; + +/** + * @ingroup los_task + * Free task linked list. + * + */ +extern LOS_DL_LIST g_losFreeTask; + +/** + * @ingroup los_task + * Circular linked list that stores tasks that are deleted automatically. + * + */ +extern LOS_DL_LIST g_taskRecyleList; + +/** + * @ingroup los_task + * @brief the block status of task + */ +extern VOID OsTaskSchedule(VOID); + +/** + * @ingroup los_task + * @brief Modify the priority of task. + * + * @par Description: + * This API is used to modify the priority of task. + * + * @attention + * + * + * @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure. + * @param priority [IN] Type #UINT16 the priority of task. + * + * @retval None. + * @par Dependency: + * + * @see + */ +extern VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority); + +/** + * @ingroup los_task + * @brief Scan a task. + * + * @par Description: + * This API is used to scan a task. + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see + */ +extern VOID OsTaskScan(VOID); + +/** + * @ingroup los_task + * @brief Initialization a task. + * + * @par Description: + * This API is used to initialization a task. + * + * @attention + * + * + * @param None. + * + * @retval UINT32 Initialization result. + * @par Dependency: + * + * @see + */ +extern UINT32 OsTaskInit(VOID); + +/** + * @ingroup los_task + * @brief Create idle task. + * + * @par Description: + * This API is used to create idle task. + * + * @attention + * + * + * @param None. + * + * @retval UINT32 Create result. + * @par Dependency: + * + * @see + */ +extern UINT32 OsIdleTaskCreate(VOID); + +/** + * @ingroup los_task + * @brief Check task switch. + * + * @par Description: + * This API is used to check task switch. + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see + */ +extern VOID OsTaskSwitchCheck(VOID); + +/** + * @ingroup los_task + * @brief TaskMonInit. + * + * @par Description: + * This API is used to taskMonInit. + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see + */ +extern VOID OsTaskMonInit(VOID); + +/** + * @ingroup los_task + * @brief Task entry. + * + * @par Description: + * This API is used to task entry. + * + * @attention + * + * + * @param taskID [IN] Type #UINT32 task id. + * + * @retval None. + * @par Dependency: + * + * @see + */ +extern VOID OsTaskEntry(UINT32 taskID); + +/** + * @ingroup los_task + * @brief pend running task to pendlist + * + * @par Description: + * This API is used to pend task to pendlist and add to sorted delay list. + * + * @attention + * + * + * @param list [IN] Type #LOS_DL_LIST * pointer to list which running task will be pended. + * @param taskStatus [IN] Type #UINT32 Task Status. + * @param timeOut [IN] Type #UINT32 Expiry time. The value range is [0,LOS_WAIT_FOREVER]. + * + * @retval LOS_OK wait success + * @retval LOS_NOK pend out + * @par Dependency: + * + * @see OsTaskWake + */ +extern VOID OsTaskWait(LOS_DL_LIST *list, UINT32 taskStatus, UINT32 timeOut); + +/** + * @ingroup los_task + * @brief delete task from pendlist. + * + * @par Description: + * This API is used to delete task from pendlist and also add to the priqueue. + * + * @attention + * + * + * @param resumedTask [IN] Type #LosTaskCB * pointer to the task which will be add to priqueue. + * @param taskStatus [IN] Type #UINT32 Task Status. + * + * @retval None. + * @par Dependency: + * + * @see OsTaskWait + */ +extern VOID OsTaskWake(LosTaskCB *resumedTask, UINT32 taskStatus); + +/** + * @ingroup los_task + * @brief Get the task water line. + * + * @par Description: + * This API is used to get the task water line. + * + * @attention + * + * + * @param taskID [IN] Type #UINT32 task id. + * + * @retval UINT32 Task water line. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsGetTaskWaterLine(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Convert task status to string. + * + * @par Description: + * This API is used to convert task status to string. + * + * @attention + * + * + * @param taskStatus [IN] Type #UINT16 task status. + * + * @retval UINT8 * String. + * @par Dependency: + * + * @see None. + */ +extern UINT8 *OsConvertTskStatus(UINT16 taskStatus); + +/** + * @ingroup los_task + * @brief Add task to sorted delay list. + * + * @par Description: + * This API is used to add task to sorted delay list. + * + * @attention + * + * + * @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure. + * @param timeout [IN] Type #UINT32 wait time, ticks. + * + * @retval None. + * @par Dependency: + * + * @see OsTimerListDelete + */ +extern VOID OsTaskAdd2TimerList(LosTaskCB *taskCB, UINT32 timeout); + +/** + * @ingroup los_task + * @brief delete task from sorted delay list. + * + * @par Description: + * This API is used to delete task from sorted delay list. + * + * @attention + * + * + * @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure. + * + * @retval None. + * @par Dependency: + * + * @see OsTaskAdd2TimerList + */ +extern VOID OsTimerListDelete(LosTaskCB *taskCB); + +/** + * @ingroup los_task + * @brief Get all task information. + * + * @par Description: + * This API is used to get all task information. + * + * @attention + * + * + * @param None. + * + * @retval UINT32 All task information. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsGetAllTskInfo(VOID); + + +extern VOID *OsTskUserStackInit(VOID* stackPtr, VOID* userSP, UINT32 userStackSize); + +extern VOID *OsTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack); + +extern VOID OsSchedule(VOID); + +extern VOID osTaskSchedule(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TASK_PRI_H */ diff --git a/kernel/base/include/los_tick_pri.h b/kernel/base/include/los_tick_pri.h new file mode 100755 index 00000000..eceec947 --- /dev/null +++ b/kernel/base/include/los_tick_pri.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_TICK_PRI_H +#define _LOS_TICK_PRI_H + +#include "los_tick.h" +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_tick + * Count of Ticks + */ +extern UINT64 g_ullTickCount; + +/** + * @ingroup los_tick + * Ticks per second + */ +extern UINT32 g_ticksPerSec; + +/** + * @ingroup los_tick + * Cycles per Second + */ +extern UINT32 g_uwCyclePerSec; + +/** + * @ingroup los_tick + * Cycles per Tick + */ +extern UINT32 g_cyclesPerTick; + +/** + * @ingroup los_tick + * System Clock + */ +extern UINT32 g_sysClock; +/** + * @ingroup los_tick + * @brief Handle the system tick timeout. + * + * @par Description: + * This API is called when the system tick timeout and triggers the interrupt. + * + * @attention + * + * + * @param none. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsTickHandler(VOID); + +#if (LOSCFG_KERNEL_TICKLESS == YES) +LITE_OS_SEC_TEXT VOID OsTickHandlerLoop(UINT32 elapseTicks); +#endif + +/** + * @ingroup los_tick + * @brief tick modul init. + * + * @par Description: + * This API is called when the system initializating. + * + * @attention + * + * + * @param systemClock [IN] Type #UINT32 SystemClock. + * @param tickPerSecond [IN] Type #UINT32 TickPerSecond. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +extern UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TICK_PRI_H */ diff --git a/kernel/base/include/los_timeslice_pri.h b/kernel/base/include/los_timeslice_pri.h new file mode 100755 index 00000000..8d18eb1a --- /dev/null +++ b/kernel/base/include/los_timeslice_pri.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_timeslice Timeslice + * @ingroup kernel + */ + +#ifndef _LOS_TIMESLICE_PRI_H +#define _LOS_TIMESLICE_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_timeslice + * @brief Initialize time slices. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsTimesliceInit(VOID); + +/** + * @ingroup los_timeslice + * @brief Check time slices. + * + * @par Description: + * + * @attention + * + * + * @param None. + * + * @retval None. + * @par Dependency: + * + * @see None. + */ +extern VOID OsTimesliceCheck(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TIMESLICE_PRI_H */ diff --git a/kernel/base/include/los_typedef_pri.h b/kernel/base/include/los_typedef_pri.h new file mode 100755 index 00000000..19fbdaef --- /dev/null +++ b/kernel/base/include/los_typedef_pri.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_TYPEDEF_PRI_H +#define _LOS_TYPEDEF_PRI_H + +#include "los_typedef.h" + +#endif /* _LOS_TYPEDEF_PRI_H */ diff --git a/kernel/base/ipc/los_event.c b/kernel/base/ipc/los_event.c new file mode 100755 index 00000000..ac8163e3 --- /dev/null +++ b/kernel/base/ipc/los_event.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_event_pri.h" +#include "los_priqueue_pri.h" +#include "los_task_pri.h" +#include "los_hw.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) +{ + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + eventCB->uwEventID = 0; + LOS_ListInit(&eventCB->stEventList); + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) +{ + UINT32 ret = 0; + UINTPTR intSave; + + intSave = LOS_IntLock(); + if (mode & LOS_WAITMODE_OR) { + if ((*eventID & eventMask) != 0) { + ret = *eventID & eventMask; + } + } else { + if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) { + ret = *eventID & eventMask; + } + } + if (ret && (mode & LOS_WAITMODE_CLR)) { + *eventID = *eventID & ~(ret); + } + LOS_IntRestore(intSave); + return ret; +} + +LITE_OS_SEC_TEXT STATIC_INLINE UINT32 OsEventReadParamCheck(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode) +{ + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + if ((eventCB->stEventList.pstNext == NULL) || (eventCB->stEventList.pstPrev == NULL)) { + return LOS_ERRNO_EVENT_NOT_INITIALIZED; + } + if (eventMask == 0) { + return LOS_ERRNO_EVENT_EVENTMASK_INVALID; + } + if (eventMask & LOS_ERRTYPE_ERROR) { + return LOS_ERRNO_EVENT_SETBIT_INVALID; + } + if (((mode & LOS_WAITMODE_OR) && (mode & LOS_WAITMODE_AND)) || + (mode & ~(LOS_WAITMODE_OR | LOS_WAITMODE_AND | LOS_WAITMODE_CLR)) || + !(mode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) { + return LOS_ERRNO_EVENT_FLAGS_INVALID; + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut) +{ + UINT32 ret; + UINTPTR intSave; + LosTaskCB *runTsk = NULL; + + ret = OsEventReadParamCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_EVENT_READ_IN_INTERRUPT; + } + intSave = LOS_IntLock(); + ret = LOS_EventPoll(&(eventCB->uwEventID), eventMask, mode); + if (ret == 0) { + if (timeOut == 0) { + LOS_IntRestore(intSave); + return ret; + } + + if (g_losTaskLock) { + LOS_IntRestore(intSave); + return LOS_ERRNO_EVENT_READ_IN_LOCK; + } + runTsk = g_losTask.runTask; + runTsk->eventMask = eventMask; + runTsk->eventMode = mode; + OsTaskWait(&eventCB->stEventList, OS_TASK_STATUS_PEND, timeOut); + LOS_IntRestore(intSave); + LOS_Schedule(); + + if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) { + intSave = LOS_IntLock(); + runTsk->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); + LOS_IntRestore(intSave); + return LOS_ERRNO_EVENT_READ_TIMEOUT; + } + intSave = LOS_IntLock(); + ret = LOS_EventPoll(&eventCB->uwEventID, eventMask, mode); + LOS_IntRestore(intSave); + } else { + LOS_IntRestore(intSave); + } + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) +{ + LosTaskCB *resumedTask = NULL; + LosTaskCB *nextTask = (LosTaskCB *)NULL; + UINTPTR intSave; + UINT8 exitFlag = 0; + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + if ((eventCB->stEventList.pstNext == NULL) || (eventCB->stEventList.pstPrev == NULL)) { + return LOS_ERRNO_EVENT_NOT_INITIALIZED; + } + if (events & LOS_ERRTYPE_ERROR) { + return LOS_ERRNO_EVENT_SETBIT_INVALID; + } + intSave = LOS_IntLock(); + eventCB->uwEventID |= events; + if (!LOS_ListEmpty(&eventCB->stEventList)) { + for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList); + &resumedTask->pendList != (&eventCB->stEventList);) { + nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList); + + if (((resumedTask->eventMode & LOS_WAITMODE_OR) && (resumedTask->eventMask & events) != 0) || + ((resumedTask->eventMode & LOS_WAITMODE_AND) && + ((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) { + exitFlag = 1; + + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND); + } + resumedTask = nextTask; + } + + if (exitFlag == 1) { + LOS_IntRestore(intSave); + LOS_Schedule(); + return LOS_OK; + } + } + + LOS_IntRestore(intSave); + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) +{ + UINTPTR intSave; + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + intSave = LOS_IntLock(); + + if (!LOS_ListEmpty(&eventCB->stEventList)) { + LOS_IntRestore(intSave); + return LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY; + } + eventCB->stEventList.pstNext = (LOS_DL_LIST *)NULL; + eventCB->stEventList.pstPrev = (LOS_DL_LIST *)NULL; + LOS_IntRestore(intSave); + return LOS_OK; +} +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events) +{ + UINTPTR intSave; + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + intSave = LOS_IntLock(); + eventCB->uwEventID &= events; + LOS_IntRestore(intSave); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + diff --git a/kernel/base/ipc/los_mux.c b/kernel/base/ipc/los_mux.c new file mode 100755 index 00000000..37424b1b --- /dev/null +++ b/kernel/base/ipc/los_mux.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_mux_pri.h" +#include "los_err_pri.h" +#include "los_memory_pri.h" +#include "los_priqueue_pri.h" +#include "los_task_pri.h" +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_exc.h" +#endif +#include "los_hw.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#if (LOSCFG_BASE_IPC_MUX == YES) + +LITE_OS_SEC_BSS LosMuxCB* g_allMux = NULL; +LITE_OS_SEC_DATA_INIT LOS_DL_LIST g_unusedMuxList; + +/***************************************************************************** + Funtion : OsMuxInit + Description : Initializes the mutex + Input : None + Output : None + Return : LOS_OK on success ,or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsMuxInit(VOID) +{ + LosMuxCB *muxNode = NULL; + UINT32 index; + + LOS_ListInit(&g_unusedMuxList); + + if (LOSCFG_BASE_IPC_MUX_LIMIT == 0) { + return LOS_ERRNO_MUX_MAXNUM_ZERO; + } + + g_allMux = (LosMuxCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(LosMuxCB))); + if (g_allMux == NULL) { + return LOS_ERRNO_MUX_NO_MEMORY; + } + + for (index = 0; index < LOSCFG_BASE_IPC_MUX_LIMIT; index++) { + muxNode = ((LosMuxCB *)g_allMux) + index; + muxNode->muxID = index; + muxNode->muxStat = OS_MUX_UNUSED; + LOS_ListTailInsert(&g_unusedMuxList, &muxNode->muxList); + } + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_MuxCreate + Description : Create a mutex + Input : None + Output : muxHandle ------ Mutex operation handle + Return : LOS_OK on success ,or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MuxCreate(UINT32 *muxHandle) +{ + UINT32 intSave; + LosMuxCB *muxCreated = NULL; + LOS_DL_LIST *unusedMux = NULL; + UINT32 errNo; + UINT32 errLine; + + if (muxHandle == NULL) { + return LOS_ERRNO_MUX_PTR_NULL; + } + + intSave = LOS_IntLock(); + if (LOS_ListEmpty(&g_unusedMuxList)) { + LOS_IntRestore(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_ALL_BUSY); + } + + unusedMux = LOS_DL_LIST_FIRST(&(g_unusedMuxList)); + LOS_ListDelete(unusedMux); + muxCreated = (GET_MUX_LIST(unusedMux)); + muxCreated->muxCount = 0; + muxCreated->muxStat = OS_MUX_USED; + muxCreated->priority = 0; + muxCreated->owner = (LosTaskCB *)NULL; + LOS_ListInit(&muxCreated->muxList); + *muxHandle = (UINT32)muxCreated->muxID; + LOS_IntRestore(intSave); + return LOS_OK; +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); +} + +/***************************************************************************** + Function : LOS_MuxDelete + Description : Delete a mutex + Input : muxHandle ------Mutex operation handle + Output : None + Return : LOS_OK on success ,or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MuxDelete(UINT32 muxHandle) +{ + UINT32 intSave; + LosMuxCB *muxDeleted = NULL; + UINT32 errNo; + UINT32 errLine; + + if (muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) { + OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_INVALID); + } + + muxDeleted = GET_MUX(muxHandle); + intSave = LOS_IntLock(); + if (muxDeleted->muxStat == OS_MUX_UNUSED) { + LOS_IntRestore(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_INVALID); + } + + if ((!LOS_ListEmpty(&muxDeleted->muxList)) || muxDeleted->muxCount) { + LOS_IntRestore(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_PENDED); + } + + LOS_ListAdd(&g_unusedMuxList, &muxDeleted->muxList); + muxDeleted->muxStat = OS_MUX_UNUSED; + + LOS_IntRestore(intSave); + + return LOS_OK; +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); +} + +STATIC_INLINE UINT32 OsMuxValidCheck(LosMuxCB *muxPended) +{ + if (muxPended->muxStat == OS_MUX_UNUSED) { + return LOS_ERRNO_MUX_INVALID; + } + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_MUX_PEND_INTERR; + } + + if (g_losTaskLock) { + PRINT_ERR("!!!LOS_ERRNO_MUX_PEND_IN_LOCK!!!\n"); +#if (LOSCFG_PLATFORM_EXC == YES) + OsBackTrace(); +#endif + return LOS_ERRNO_MUX_PEND_IN_LOCK; + } + + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_MuxPend + Description : Specify the mutex P operation + Input : muxHandle ------ Mutex operation handleone + : timeOut ------- waiting time + Output : None + Return : LOS_OK on success ,or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout) +{ + UINT32 intSave; + LosMuxCB *muxPended = NULL; + UINT32 retErr; + LosTaskCB *runningTask = NULL; + + if (muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) { + OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); + } + + muxPended = GET_MUX(muxHandle); + intSave = LOS_IntLock(); + retErr = OsMuxValidCheck(muxPended); + if (retErr) { + goto ERROR_MUX_PEND; + } + + runningTask = (LosTaskCB *)g_losTask.runTask; + if (muxPended->muxCount == 0) { + muxPended->muxCount++; + muxPended->owner = runningTask; + muxPended->priority = runningTask->priority; + LOS_IntRestore(intSave); + return LOS_OK; + } + + if (muxPended->owner == runningTask) { + muxPended->muxCount++; + LOS_IntRestore(intSave); + return LOS_OK; + } + + if (!timeout) { + retErr = LOS_ERRNO_MUX_UNAVAILABLE; + goto ERROR_MUX_PEND; + } + + runningTask->taskMux = (VOID *)muxPended; + + if (muxPended->owner->priority > runningTask->priority) { + OsTaskPriModify(muxPended->owner, runningTask->priority); + } + + OsTaskWait(&muxPended->muxList, OS_TASK_STATUS_PEND, timeout); + + LOS_IntRestore(intSave); + LOS_Schedule(); + + if (runningTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + intSave = LOS_IntLock(); + runningTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); + retErr = LOS_ERRNO_MUX_TIMEOUT; + goto ERROR_MUX_PEND; + } + + return LOS_OK; + +ERROR_MUX_PEND: + LOS_IntRestore(intSave); + OS_RETURN_ERROR(retErr); +} + +/***************************************************************************** + Function : LOS_MuxPost + Description : Specify the mutex V operation, + Input : muxHandle ------ Mutex operation handle + Output : None + Return : LOS_OK on success ,or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 muxHandle) +{ + UINT32 intSave; + LosMuxCB *muxPosted = GET_MUX(muxHandle); + LosTaskCB *resumedTask = NULL; + LosTaskCB *runningTask = NULL; + + intSave = LOS_IntLock(); + + if ((muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) || + (muxPosted->muxStat == OS_MUX_UNUSED)) { + LOS_IntRestore(intSave); + OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); + } + + runningTask = (LosTaskCB *)g_losTask.runTask; + if ((muxPosted->muxCount == 0) || (muxPosted->owner != runningTask)) { + LOS_IntRestore(intSave); + OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); + } + + if (--(muxPosted->muxCount) != 0) { + LOS_IntRestore(intSave); + return LOS_OK; + } + + if ((muxPosted->owner->priority) != muxPosted->priority) { + OsTaskPriModify(muxPosted->owner, muxPosted->priority); + } + + if (!LOS_ListEmpty(&muxPosted->muxList)) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(muxPosted->muxList))); + + muxPosted->muxCount = 1; + muxPosted->owner = resumedTask; + muxPosted->priority = resumedTask->priority; + resumedTask->taskMux = NULL; + + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND); + + LOS_IntRestore(intSave); + LOS_Schedule(); + } else { + LOS_IntRestore(intSave); + } + + return LOS_OK; +} +#endif /* (LOSCFG_BASE_IPC_MUX == YES) */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/ipc/los_queue.c b/kernel/base/ipc/los_queue.c new file mode 100755 index 00000000..cc558335 --- /dev/null +++ b/kernel/base/ipc/los_queue.c @@ -0,0 +1,680 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "string.h" +#include "securec.h" +#include "los_queue_pri.h" +#include "los_membox_pri.h" +#include "los_memory_pri.h" +#include "los_priqueue_pri.h" +#include "los_task_pri.h" +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_exc_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#if (LOSCFG_BASE_IPC_QUEUE == YES) + +LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL ; +LITE_OS_SEC_BSS LOS_DL_LIST g_freeQueueList; +#if (LOSCFG_PLATFORM_EXC == YES) +LITE_OS_SEC_BSS UINT32 g_excQueueMaxNum; +#endif + +/************************************************************************** + Function : OsQueueInit + Description : queue initial + Input : None + Output : None + Return : LOS_OK on success or error code on failure +**************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) +{ + LosQueueCB *queueNode = NULL; + UINT16 index; + + if (LOSCFG_BASE_IPC_QUEUE_LIMIT == 0) { + return LOS_ERRNO_QUEUE_MAXNUM_ZERO; + } + + g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB)); + if (g_allQueue == NULL) { + return LOS_ERRNO_QUEUE_NO_MEMORY; + } + + (VOID)memset_s(g_allQueue, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB), + 0, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB)); + + LOS_ListInit(&g_freeQueueList); + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + queueNode = ((LosQueueCB *)g_allQueue) + index; + queueNode->queueID = index; + LOS_ListTailInsert(&g_freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]); + } + +#if (LOSCFG_PLATFORM_EXC == YES) + g_excQueueMaxNum = LOSCFG_BASE_IPC_QUEUE_LIMIT; + OsExcRegister(OS_EXC_TYPE_QUE, (EXC_INFO_SAVE_CALLBACK)LOS_QueueInfoGet, &g_excQueueMaxNum); +#endif + + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_QueueCreate + Description : Create a queue + Input : queueName --- Queue name, less than 4 characters + : len --- Queue lenth + : flags --- Queue type, FIFO or PRIO + : maxMsgSize --- Maximum message size in byte + Output : queueID --- Queue ID + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, + UINT16 len, + UINT32 *queueID, + UINT32 flags, + UINT16 maxMsgSize) +{ + LosQueueCB *queueCB = NULL; + UINTPTR intSave; + LOS_DL_LIST *unusedQueue = NULL; + UINT8 *queue = NULL; + UINT16 msgSize; + + (VOID)queueName; + (VOID)flags; + + if (queueID == NULL) { + return LOS_ERRNO_QUEUE_CREAT_PTR_NULL; + } + + if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) { + return LOS_ERRNO_QUEUE_SIZE_TOO_BIG; + } + + if ((len == 0) || (maxMsgSize == 0)) { + return LOS_ERRNO_QUEUE_PARA_ISZERO; + } + msgSize = maxMsgSize + sizeof(UINT32); + + /* Memory allocation is time-consuming, to shorten the time of disable interrupt, + move the memory allocation to here. */ + queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, len * msgSize); + if (queue == NULL) { + return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY; + } + + intSave = LOS_IntLock(); + if (LOS_ListEmpty(&g_freeQueueList)) { + LOS_IntRestore(intSave); + (VOID)LOS_MemFree(m_aucSysMem0, queue); + return LOS_ERRNO_QUEUE_CB_UNAVAILABLE; + } + + unusedQueue = LOS_DL_LIST_FIRST(&(g_freeQueueList)); + LOS_ListDelete(unusedQueue); + queueCB = (GET_QUEUE_LIST(unusedQueue)); + queueCB->queueLen = len; + queueCB->queueSize = msgSize; + queueCB->queue = queue; + queueCB->queueState = OS_QUEUE_INUSED; + queueCB->readWriteableCnt[OS_QUEUE_READ] = 0; + queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len; + queueCB->queueHead = 0; + queueCB->queueTail = 0; + LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]); + LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]); + LOS_ListInit(&queueCB->memList); + LOS_IntRestore(intSave); + + *queueID = queueCB->queueID; + + return LOS_OK; +} + +static INLINE LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, VOID *bufferAddr, + UINT32 *bufferSize, UINT32 timeOut) +{ + if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_INVALID; + } + if ((bufferAddr == NULL) || (bufferSize == NULL)) { + return LOS_ERRNO_QUEUE_READ_PTR_NULL; + } + + if (*bufferSize == 0) { + return LOS_ERRNO_QUEUE_READSIZE_ISZERO; + } + + if (timeOut != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { + return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT; + } + } + return LOS_OK; +} + +static INLINE LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, VOID *bufferAddr, + UINT32 *bufferSize, UINT32 timeOut) +{ + if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_INVALID; + } + + if (bufferAddr == NULL) { + return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; + } + + if (*bufferSize == 0) { + return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO; + } + + if (timeOut != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { + return LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT; + } + } + return LOS_OK; +} + +static INLINE VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, + VOID *bufferAddr, UINT32 *bufferSize) +{ + UINT8 *queueNode = NULL; + UINT32 msgDataSize; + UINT16 queuePosion; + errno_t rc; + + /* get the queue position */ + switch (OS_QUEUE_OPERATE_GET(operateType)) { + case OS_QUEUE_READ_HEAD: + queuePosion = queueCB->queueHead; + ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++); + break; + + case OS_QUEUE_WRITE_HEAD: + (queueCB->queueHead == 0) ? (queueCB->queueHead = (queueCB->queueLen - 1)) : (--queueCB->queueHead); + queuePosion = queueCB->queueHead; + break; + + case OS_QUEUE_WRITE_TAIL: + queuePosion = queueCB->queueTail; + ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++); + break; + + default: + PRINT_ERR("invalid queue operate type!\n"); + return; + } + + queueNode = &(queueCB->queue[(queuePosion * (queueCB->queueSize))]); + + if (OS_QUEUE_IS_POINT(operateType)) { + if (OS_QUEUE_IS_READ(operateType)) { + *(UINT32 *)bufferAddr = *(UINT32 *)(VOID *)queueNode; + } else { + *(UINT32 *)(VOID *)queueNode = *(UINT32 *)bufferAddr; // change to pp when calling OsQueueOperate + } + } else { + if (OS_QUEUE_IS_READ(operateType)) { + msgDataSize = *((UINT32 *)(UINTPTR)((queueNode + queueCB->queueSize) - sizeof(UINT32))); + rc = memcpy_s((VOID *)bufferAddr, *bufferSize, (VOID *)queueNode, msgDataSize); + if (rc != EOK) { + PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, rc); + return; + } + + *bufferSize = msgDataSize; + } else { + *((UINT32 *)(UINTPTR)((queueNode + queueCB->queueSize) - sizeof(UINT32))) = *bufferSize; + rc = memcpy_s((VOID *)queueNode, queueCB->queueSize, (VOID *)bufferAddr, *bufferSize); + if (rc != EOK) { + PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, rc); + return; + } + } + } +} + +static INLINE UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 operateType, const UINT32 *bufferSize) +{ + if (queueCB->queueState == OS_QUEUE_UNUSED) { + return LOS_ERRNO_QUEUE_NOT_CREATE; + } + + if (OS_QUEUE_IS_READ(operateType) && (*bufferSize < (queueCB->queueSize - sizeof(UINT32)))) { + return LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL; + } else if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) { + return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG; + } + + return LOS_OK; +} + +UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeOut) +{ + LosQueueCB *queueCB = NULL; + LosTaskCB *runTsk = NULL; + LosTaskCB *resumedTask = NULL; + UINT32 ret; + UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType); + UINT32 readWriteTmp = !readWrite; + + UINTPTR intSave = LOS_IntLock(); + + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + ret = OsQueueOperateParamCheck(queueCB, operateType, bufferSize); + if (ret != LOS_OK) { + goto QUEUE_END; + } + + if (queueCB->readWriteableCnt[readWrite] == 0) { + if (timeOut == LOS_NO_WAIT) { + ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL; + goto QUEUE_END; + } + + if (g_losTaskLock) { + ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK; + goto QUEUE_END; + } + + runTsk = (LosTaskCB *)g_losTask.runTask; + OsTaskWait(&queueCB->readWriteList[readWrite], OS_TASK_STATUS_PEND_QUEUE, timeOut); + LOS_IntRestore(intSave); + LOS_Schedule(); + + intSave = LOS_IntLock(); + if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTsk->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); + ret = LOS_ERRNO_QUEUE_TIMEOUT; + goto QUEUE_END; + } + } else { + queueCB->readWriteableCnt[readWrite]--; + } + + OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize); + + + if (!LOS_ListEmpty(&queueCB->readWriteList[readWriteTmp])) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[readWriteTmp])); + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND_QUEUE); + LOS_IntRestore(intSave); + LOS_Schedule(); + return LOS_OK; + } else { + queueCB->readWriteableCnt[readWriteTmp]++; + } + +QUEUE_END: + LOS_IntRestore(intSave); + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 *bufferSize, + UINT32 timeOut) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeOut); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD, OS_QUEUE_NOT_POINT); + return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeOut); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeOut); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD, OS_QUEUE_NOT_POINT); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeOut); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeOut); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL, OS_QUEUE_NOT_POINT); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeOut); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut) +{ + UINT32 ret; + UINT32 operateType; + + ret = OsQueueReadParameterCheck(queueID, bufferAddr, &bufferSize, timeOut); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD, OS_QUEUE_POINT); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeOut); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeOut) +{ + UINT32 ret; + UINT32 operateType; + UINT32 size = sizeof(UINT32 *); + (VOID)bufferSize; + + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &size, timeOut); + if (ret != LOS_OK) { + return ret; + } + + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL, OS_QUEUE_POINT); + return OsQueueOperate(queueID, operateType, &bufferAddr, &size, timeOut); +} + +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut) +{ + UINT32 size = sizeof(UINT32 *); + (VOID)bufferSize; + + if (bufferAddr == NULL) { + return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; + } + + return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, size, timeOut); +} + +/***************************************************************************** + Function : OsQueueMailAlloc + Description : Mail allocate memory + Input : queueID --- QueueID + : mailPool --- MailPool + : timeOut --- TimeOut + Output : None + Return : mem:pointer if success otherwise NULL + *****************************************************************************/ +LITE_OS_SEC_TEXT VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeOut) +{ + VOID *mem = (VOID *)NULL; + UINTPTR intSave; + LosQueueCB *queueCB = (LosQueueCB *)NULL; + LosTaskCB *runTsk = (LosTaskCB *)NULL; + + if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return NULL; + } + + if (mailPool == NULL) { + return NULL; + } + + if (timeOut != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { + return NULL; + } + } + + intSave = LOS_IntLock(); + queueCB = GET_QUEUE_HANDLE(queueID); + if (queueCB->queueState == OS_QUEUE_UNUSED) { + goto END; + } + + mem = LOS_MemboxAlloc(mailPool); + if (mem == NULL) { + if (timeOut == LOS_NO_WAIT) { + goto END; + } + + runTsk = (LosTaskCB *)g_losTask.runTask; + OsTaskWait(&queueCB->memList, OS_TASK_STATUS_PEND_QUEUE, timeOut); + LOS_IntRestore(intSave); + LOS_Schedule(); + + intSave = LOS_IntLock(); + if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTsk->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); + goto END; + } else { + /* When enters the current branch, means the current task already got a available membox, + * so the runTsk->msg can not be NULL. + */ + mem = runTsk->msg; + runTsk->msg = NULL; + } + } + +END: + LOS_IntRestore(intSave); + return mem; +} + +/***************************************************************************** + Function : OsQueueMailFree + Description : Mail free memory + Input : queueID --- QueueID + : mailPool --- MailPool + : mailMem --- MailMem + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem) +{ + VOID *mem = (VOID *)NULL; + UINTPTR intSave; + LosQueueCB *queueCB = (LosQueueCB *)NULL; + LosTaskCB *resumedTask = (LosTaskCB *)NULL; + + if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID; + } + + if (mailPool == NULL) { + return LOS_ERRNO_QUEUE_MAIL_PTR_INVALID; + } + + intSave = LOS_IntLock(); + + if (LOS_MemboxFree(mailPool, mailMem)) { + LOS_IntRestore(intSave); + return LOS_ERRNO_QUEUE_MAIL_FREE_ERROR; + } + + queueCB = GET_QUEUE_HANDLE(queueID); + if (queueCB->queueState == OS_QUEUE_UNUSED) { + LOS_IntRestore(intSave); + return LOS_ERRNO_QUEUE_NOT_CREATE; + } + + if (!LOS_ListEmpty(&queueCB->memList)) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->memList)); + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND_QUEUE); + mem = LOS_MemboxAlloc(mailPool); + if (mem == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_QUEUE_NO_MEMORY; + } + resumedTask->msg = mem; + LOS_IntRestore(intSave); + LOS_Schedule(); + } else { + LOS_IntRestore(intSave); + } + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_QueueDelete + Description : Delete a queue + Input : queueID --- QueueID + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) +{ + LosQueueCB *queueCB = NULL; + UINT8 *queue = NULL; + UINTPTR intSave; + UINT32 ret; + + if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_NOT_FOUND; + } + + intSave = LOS_IntLock(); + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + if (queueCB->queueState == OS_QUEUE_UNUSED) { + ret = LOS_ERRNO_QUEUE_NOT_CREATE; + goto QUEUE_END; + } + + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; + goto QUEUE_END; + } + + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; + goto QUEUE_END; + } + + if (!LOS_ListEmpty(&queueCB->memList)) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; + goto QUEUE_END; + } + + if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) != + queueCB->queueLen) { + ret = LOS_ERRNO_QUEUE_IN_TSKWRITE; + goto QUEUE_END; + } + + queue = queueCB->queue; + queueCB->queue = (UINT8 *)NULL; + queueCB->queueState = OS_QUEUE_UNUSED; + LOS_ListAdd(&g_freeQueueList, &queueCB->readWriteList[OS_QUEUE_WRITE]); + LOS_IntRestore(intSave); + + ret = LOS_MemFree(m_aucSysMem0, (VOID *)queue); + return ret; + +QUEUE_END: + LOS_IntRestore(intSave); + return ret; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo) +{ + UINTPTR intSave; + UINT32 ret = LOS_OK; + LosQueueCB *queueCB = NULL; + LosTaskCB *tskCB = NULL; + + if (queueInfo == NULL) { + return LOS_ERRNO_QUEUE_PTR_NULL; + } + + if (queueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { + return LOS_ERRNO_QUEUE_INVALID; + } + + (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S)); + intSave = LOS_IntLock(); + + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + + if (queueCB->queueState == OS_QUEUE_UNUSED) { + ret = LOS_ERRNO_QUEUE_NOT_CREATE; + goto QUEUE_END; + } + + queueInfo->queueID = queueID; + queueInfo->queueLen = queueCB->queueLen; + queueInfo->queueSize = queueCB->queueSize; + queueInfo->queueHead = queueCB->queueHead; + queueInfo->queueTail = queueCB->queueTail; + queueInfo->readableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ]; + queueInfo->writableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE]; + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) { + queueInfo->waitReadTask |= (1 << tskCB->taskID); + } + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) { + queueInfo->waitWriteTask |= (1 << tskCB->taskID); + } + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) { + queueInfo->waitMemTask |= (1 << tskCB->taskID); + } + +QUEUE_END: + LOS_IntRestore(intSave); + return ret; +} + +#endif /* (LOSCFG_BASE_IPC_QUEUE == YES) */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/ipc/los_sem.c b/kernel/base/ipc/los_sem.c new file mode 100755 index 00000000..18e96811 --- /dev/null +++ b/kernel/base/ipc/los_sem.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_sem_pri.h" +#include "los_base_pri.h" +#include "los_err_pri.h" +#include "los_memory_pri.h" +#include "los_priqueue_pri.h" +#include "los_sys_pri.h" +#include "los_task_pri.h" +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_exc.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#if (LOSCFG_BASE_IPC_SEM == YES) + +LITE_OS_SEC_DATA_INIT LOS_DL_LIST g_unusedSemList; +LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL; + +/***************************************************************************** + Function : OsSemInit + Description : Initialize the Semaphore doubly linked list + Input : None + Output : None + Return : LOS_OK on success, or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) +{ + LosSemCB *semNode = NULL; + UINT16 index; + + LOS_ListInit(&g_unusedSemList); + + if (LOSCFG_BASE_IPC_SEM_LIMIT == 0) { + return LOS_ERRNO_SEM_MAXNUM_ZERO; + } + + g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB))); + if (g_allSem == NULL) { + return LOS_ERRNO_SEM_NO_MEMORY; + } + + /* Connect all the ECBs in a doubly linked list. */ + for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) { + semNode = ((LosSemCB *)g_allSem) + index; + semNode->semID = index; + semNode->semStat = OS_SEM_UNUSED; + LOS_ListTailInsert(&g_unusedSemList, &semNode->semList); + } + return LOS_OK; +} + +/***************************************************************************** + Function : OsSemCreate + Description : create the Semaphore + Input : count --- Semaphore count + : maxCount --- Max semaphore count for check + Output : semHandle --- Index of semaphore + Return : LOS_OK on success, or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle) +{ + UINT32 intSave; + LosSemCB *semCreated = NULL; + LOS_DL_LIST *unusedSem = NULL; + UINT32 errNo; + UINT32 errLine; + + if (semHandle == NULL) { + return LOS_ERRNO_SEM_PTR_NULL; + } + + if (count > maxCount) { + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW); + } + + intSave = LOS_IntLock(); + + if (LOS_ListEmpty(&g_unusedSemList)) { + LOS_IntRestore(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY); + } + + unusedSem = LOS_DL_LIST_FIRST(&(g_unusedSemList)); + LOS_ListDelete(unusedSem); + semCreated = (GET_SEM_LIST(unusedSem)); + semCreated->semCount = count; + semCreated->semStat = OS_SEM_USED; + semCreated->maxSemCount = maxCount; + LOS_ListInit(&semCreated->semList); + *semHandle = (UINT32)semCreated->semID; + LOS_IntRestore(intSave); + return LOS_OK; + +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); +} + +/***************************************************************************** + Function : LOS_SemCreate + Description : Create a semaphore + Input : count--------- semaphore count + Output : semHandle-----Index of semaphore + Return : LOS_OK on success, or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle) +{ + return OsSemCreate(count, OS_SEM_COUNTING_MAX_COUNT, semHandle); +} + +/***************************************************************************** + Function : LOS_BinarySemCreate + Description : Create a binary semaphore + Input : count--------- semaphore count + Output : semHandle-----Index of semaphore + Return : LOS_OK on success, or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle) +{ + return OsSemCreate(count, OS_SEM_BINARY_MAX_COUNT, semHandle); +} + +/***************************************************************************** + Function : LOS_SemDelete + Description : Delete a semaphore + Input : semHandle--------- semaphore operation handle + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) +{ + UINT32 intSave; + LosSemCB *semDeleted = NULL; + UINT32 errNo; + UINT32 errLine; + + if (semHandle >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); + } + + semDeleted = GET_SEM(semHandle); + intSave = LOS_IntLock(); + if (semDeleted->semStat == OS_SEM_UNUSED) { + LOS_IntRestore(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); + } + + if (!LOS_ListEmpty(&semDeleted->semList)) { + LOS_IntRestore(intSave); + OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED); + } + + LOS_ListAdd(&g_unusedSemList, &semDeleted->semList); + semDeleted->semStat = OS_SEM_UNUSED; + LOS_IntRestore(intSave); + return LOS_OK; +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); +} + +STATIC_INLINE UINT32 OsSemValidCheck(LosSemCB *semPended) +{ + if (semPended->semStat == OS_SEM_UNUSED) { + return LOS_ERRNO_SEM_INVALID; + } + + if (OS_INT_ACTIVE) { + PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n"); +#if (LOSCFG_PLATFORM_EXC == YES) + OsBackTrace(); +#endif + return LOS_ERRNO_SEM_PEND_INTERR; + } + + if (g_losTaskLock) { + PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); +#if (LOSCFG_PLATFORM_EXC == YES) + OsBackTrace(); +#endif + return LOS_ERRNO_SEM_PEND_IN_LOCK; + } + + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_SemPend + Description : Specified semaphore P operation + Input : semHandle --------- semaphore operation handle + : timeout --------- waitting time + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) +{ + UINT32 intSave; + LosSemCB *semPended = NULL; + UINT32 retErr; + LosTaskCB *runningTask = NULL; + + if (semHandle >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { + OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); + } + + semPended = GET_SEM(semHandle); + intSave = LOS_IntLock(); + + retErr = OsSemValidCheck(semPended); + if (retErr) { + goto ERROR_SEM_PEND; + } + + if (semPended->semCount > 0) { + semPended->semCount--; + LOS_IntRestore(intSave); + return LOS_OK; + } + + if (!timeout) { + retErr = LOS_ERRNO_SEM_UNAVAILABLE; + goto ERROR_SEM_PEND; + } + + runningTask = (LosTaskCB *)g_losTask.runTask; + runningTask->taskSem = (VOID *)semPended; + OsTaskWait(&semPended->semList, OS_TASK_STATUS_PEND, timeout); + LOS_IntRestore(intSave); + LOS_Schedule(); + + if (runningTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + intSave = LOS_IntLock(); + runningTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); + retErr = LOS_ERRNO_SEM_TIMEOUT; + goto ERROR_SEM_PEND; + } + + return LOS_OK; + +ERROR_SEM_PEND: + LOS_IntRestore(intSave); + OS_RETURN_ERROR(retErr); +} + +/***************************************************************************** + Function : LOS_SemPost + Description : Specified semaphore V operation + Input : semHandle--------- semaphore operation handle + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) +{ + UINT32 intSave; + LosSemCB *semPosted = GET_SEM(semHandle); + LosTaskCB *resumedTask = NULL; + + if (semHandle >= LOSCFG_BASE_IPC_SEM_LIMIT) { + return LOS_ERRNO_SEM_INVALID; + } + + intSave = LOS_IntLock(); + + if (semPosted->semStat == OS_SEM_UNUSED) { + LOS_IntRestore(intSave); + OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); + } + + if (semPosted->maxSemCount == semPosted->semCount) { + LOS_IntRestore(intSave); + OS_RETURN_ERROR(LOS_ERRNO_SEM_OVERFLOW); + } + if (!LOS_ListEmpty(&semPosted->semList)) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList))); + resumedTask->taskSem = NULL; + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND); + + LOS_IntRestore(intSave); + LOS_Schedule(); + } else { + semPosted->semCount++; + LOS_IntRestore(intSave); + } + + return LOS_OK; +} + +#endif /* (LOSCFG_BASE_IPC_SEM == YES) */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/mem/bestfit/los_membox.c b/kernel/base/mem/bestfit/los_membox.c new file mode 100755 index 00000000..217fafa1 --- /dev/null +++ b/kernel/base/mem/bestfit/los_membox.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "securec.h" +#include "los_hwi.h" +#include "los_typedef.h" +#include "los_membox.h" +#include "los_memory.h" +#include "los_memcheck_pri.h" + +#if (LOSCFG_PLATFORM_EXC == YES) || (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) +UINT8 g_memMang[MEM_INFO_SIZE]; +#endif + +UINT32 LOS_MemboxInit(VOID *boxMem, UINT32 boxSize, UINT32 blkSize) +{ + UINTPTR intSave; +#ifdef LOS_MEMBOX_CHECK + UINT32 *memCount = (UINT32 *)g_memMang; + MEM_INFO *memInfo = (MEM_INFO *)(g_memMang + sizeof(UINT32)); + UINT8 loop; +#endif + + if (boxMem == NULL) { + return OS_ERROR; + } + + /* Initialize memory block system, returns 0 if OK, 1 if fails. */ + if (blkSize == 0) { + return OS_ERROR; + } + if (boxSize == 0) { + return OS_ERROR; + } + +#ifdef LOS_MEMBOX_CHECK + intSave = LOS_IntLock(); + for (loop = 0; loop < *memCount; loop++) { + if (memInfo->uwStartAddr == (UINTPTR)boxMem) { + (*memCount)--; + break; + } + memInfo++; + } + if (*memCount < OS_SYS_MEM_NUM) { + memInfo->uwType = MEM_MANG_MEMBOX; + memInfo->uwStartAddr = (UINTPTR)boxMem; + memInfo->uwSize = boxSize; + UINT32 allocSize = boxSize / blkSize * sizeof(VOID *); + VOID *ptr = LOS_MemAlloc(m_aucSysMem0, allocSize); + if (ptr == NULL) { + PRINT_ERR("LOS_MemAlloc return fail!\n"); + return LOS_NOK; + } else { + UINT32 ret = memset_s(ptr, allocSize, 0, allocSize); + if (ret != LOS_OK) { + (VOID)LOS_MemFree(m_aucSysMem0, ptr); + PRINT_ERR("memset return fail!\n"); + return LOS_NOK; + } + } + memInfo->blkAddrArray = ptr; + (*memCount)++; + } + LOS_IntRestore(intSave); +#endif + + /* Create a Memory structure. */ + intSave = LOS_IntLock(); + ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk = boxSize / blkSize; + ((OS_MEMBOX_S_P)boxMem)->uwBlkSize = blkSize; + ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt = 0; + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/* --------------------------- LOS_MemboxAlloc ---------------------------------- */ +VOID *LOS_MemboxAlloc(VOID *boxMem) +{ + VOID *ret = NULL; + UINTPTR intSave; + + intSave = LOS_IntLock(); + if (((OS_MEMBOX_S_P)boxMem)->uwBlkCnt < ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk) { + ret = LOS_MemAlloc(m_aucSysMem0, ((OS_MEMBOX_S_P)boxMem)->uwBlkSize); + if (ret != NULL) { + ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt++; +#ifdef LOS_MEMBOX_CHECK + UINT32 *memCount = (UINT32 *)g_memMang; + MEM_INFO *memInfo = (MEM_INFO *)(VOID *)(g_memMang + sizeof(UINT32)); + UINT8 loop; + UINT8 idx; + for (loop = 0; loop < *memCount; loop++) { + if (memInfo->uwStartAddr == (UINTPTR)boxMem) { + if (memInfo->blkAddrArray != NULL) { + for (idx = 0; idx < ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk; idx++) { + if (((VOID **)(memInfo->blkAddrArray))[idx] == NULL) { + ((VOID **)(memInfo->blkAddrArray))[idx] = ret; + break; + } + } + } + break; + } + memInfo++; + } +#endif + } else { + PRINT_ERR("LOS_AllocMem return fail!\n"); + } + } + LOS_IntRestore(intSave); + return ret; +} + +/* --------------------------- LOS_MemboxFree ---------------------------------- */ +UINT32 LOS_MemboxFree(const VOID *boxMem, VOID *box) +{ + UINT32 freeRes; + UINTPTR intSave; + + freeRes = LOS_MemFree(m_aucSysMem0, box); + if (freeRes == LOS_OK) { + intSave = LOS_IntLock(); + if (((OS_MEMBOX_S_P)boxMem)->uwBlkCnt) { + ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt--; +#ifdef LOS_MEMBOX_CHECK + UINT32 *memCount = (UINT32 *)g_memMang; + MEM_INFO *memInfo = (MEM_INFO *)(VOID *)(g_memMang + sizeof(UINT32)); + UINT8 loop; + UINT8 idx; + for (loop = 0; loop < *memCount; loop++) { + if (memInfo->uwStartAddr == (UINTPTR)boxMem) { + if (memInfo->blkAddrArray != NULL) { + for (idx = 0; idx < ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk; idx++) { + if (((VOID **)(memInfo->blkAddrArray))[idx] == box) { + ((VOID **)(memInfo->blkAddrArray))[idx] = NULL; + break; + } + } + } + break; + } + memInfo++; + } +#endif + } + LOS_IntRestore(intSave); + } + return freeRes; +} + +/* --------------------------- LOS_MemboxClr ---------------------------------- */ +VOID LOS_MemboxClr(const VOID *boxMem, VOID *box) +{ + // Ignore the return code when matching CSEC rule 6.6(2). + (VOID)memset_s(box, ((OS_MEMBOX_S_P)boxMem)->uwBlkSize, 0, ((OS_MEMBOX_S_P)boxMem)->uwBlkSize); +} + +UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize) +{ + if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { + return LOS_NOK; + } + + *maxBlk = ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk; + *blkCnt = ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt; + *blkSize = ((OS_MEMBOX_S_P)boxMem)->uwBlkSize; + + return LOS_OK; +} + diff --git a/kernel/base/mem/bestfit/los_memcheck.c b/kernel/base/mem/bestfit/los_memcheck.c new file mode 100755 index 00000000..c3094028 --- /dev/null +++ b/kernel/base/mem/bestfit/los_memcheck.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_memcheck.h" +#include "los_memory_pri.h" +#include "los_membox_pri.h" +#include "los_multipledlinkhead_pri.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#if LOSCFG_PLATFORM_EXC == YES +extern UINT8 g_memMang[MEM_INFO_SIZE]; +/***************************************************************************** + Function : LOS_MemExcInfoGet + Description : Get the information of the exc memory + Input : uwMemNum + Output : pstMemExcInfo + Return : return 0 + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemExcInfoGet(UINT32 memNum, MEM_INFO_S *memExcInfo) +{ + UINT32 idx = 0; + UINT32 maxBlk = 0; + UINT32 blkCnt = 0; + UINT32 blkSize = 0; + MEM_INFO *memInfo = NULL; + LosMemDynNode *pstTmpNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *pPool = (LOS_MEM_POOL_INFO *)NULL; + LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)NULL; + UINT8 *pEndPool = NULL; + + if (memNum >= *(UINT32 *)g_memMang || memExcInfo == NULL) { + return LOS_NOK; + } + memInfo = (MEM_INFO *)(VOID *)(g_memMang + sizeof(UINT32)) + memNum; + memExcInfo->uwType = memInfo->uwType; + memExcInfo->uwStartAddr = memInfo->uwStartAddr; + memExcInfo->uwSize = memInfo->uwSize; + memExcInfo->uwFree = 0; + memExcInfo->uwBlockSize = 0; + memExcInfo->uwErrorAddr = 0; + memExcInfo->uwErrorLen = 0; + memExcInfo->uwErrorOwner = 0; + + if (memInfo->uwType == MEM_MANG_MEMBOX) { + (VOID)LOS_MemboxStatisticsGet((VOID *)(memInfo->uwStartAddr), &maxBlk, &blkCnt, &blkSize); + memExcInfo->uwBlockSize = blkSize; + memExcInfo->uwSize = maxBlk; // Block num + memExcInfo->uwFree = maxBlk - blkCnt; + pPool = (LOS_MEM_POOL_INFO *)m_aucSysMem0; + pstPoolInfo = pPool; + pEndPool = (UINT8 *)pPool + pstPoolInfo->uwPoolSize; + while (memInfo->blkAddrArray != NULL && idx < maxBlk) { + char *tmpPtr = ((char **)(memInfo->blkAddrArray))[idx]; + if (tmpPtr != NULL) { + pstTmpNode = (LosMemDynNode *)(tmpPtr - OS_MEM_NODE_HEAD_SIZE); + if (!OS_MEM_MAGIC_VALID(pstTmpNode->freeNodeInfo.pstPrev)) { + goto errout; + } + } + idx++; + } + } else if (memInfo->uwType == MEM_MANG_MEMORY) { + memExcInfo->uwFree = memInfo->uwSize - LOS_MemTotalUsedGet((VOID *)(memInfo->uwStartAddr)) - OS_DLNK_HEAD_SIZE + - LOS_MemFreeBlksGet((VOID *)(memInfo->uwStartAddr)) * OS_MEM_NODE_HEAD_SIZE - sizeof(LOS_MEM_POOL_INFO); + + memExcInfo->uwBlockSize = 0; + pPool = (LOS_MEM_POOL_INFO *)memInfo->uwStartAddr; + if (pPool == NULL) { + return LOS_OK; + } + pstPoolInfo = pPool; + pEndPool = (UINT8 *)pPool + pstPoolInfo->uwPoolSize; + + for (pstTmpNode = (LosMemDynNode *)OS_MEM_FIRST_NODE(pPool); pstTmpNode < (LosMemDynNode *)OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); + pstTmpNode = (LosMemDynNode *)OS_MEM_NEXT_NODE(pstTmpNode)) { + memExcInfo->uwBlockSize++; + if (OS_MEM_NODE_GET_USED_FLAG(pstTmpNode->sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID(pstTmpNode->freeNodeInfo.pstPrev)) { + goto errout; + } + } + else { //is free node, check free node range + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pPool, pstTmpNode->freeNodeInfo.pstPrev, pEndPool)) { + goto errout; + } + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pPool, pstTmpNode->freeNodeInfo.pstNext, pEndPool)) { + goto errout; + } + } + + } + } + return LOS_OK; +errout: + memExcInfo->uwErrorAddr = (UINT32)(UINTPTR)((char*)pstTmpNode + OS_MEM_NODE_HEAD_SIZE); + memExcInfo->uwErrorLen = (UINT32)OS_MEM_NODE_GET_SIZE(pstTmpNode->sizeAndFlag) - OS_MEM_NODE_HEAD_SIZE; + memExcInfo->uwErrorOwner = (UINT32)(UINTPTR)(pstTmpNode->freeNodeInfo.pstNext); + return LOS_OK; +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/kernel/base/mem/bestfit/los_memory.c b/kernel/base/mem/bestfit/los_memory.c new file mode 100755 index 00000000..8fb7555c --- /dev/null +++ b/kernel/base/mem/bestfit/los_memory.c @@ -0,0 +1,1790 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "securec.h" +#include "los_memory_pri.h" +#include "los_memstat_pri.h" +#include "los_multipledlinkhead_pri.h" +#include "los_task_pri.h" +#include "los_exc.h" +#include "los_printf.h" +#ifdef LOS_MEM_LEAK_CHECK +#include "los_membox_pri.h" +#endif +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) +#include "los_memcheck_pri.h" +#endif +#ifdef LOSCFG_LIB_LIBC +#include "string.h" +#endif +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_MEM_MUL_POOL == YES) +VOID *g_memPoolHead = NULL; +#endif + +#if (LOSCFG_BASE_CORE_TASKSTACK_INDEPENDENT == YES) +__attribute__((section(".data"))) UINT32 g_sysStackAddrEnd; +#endif + +UINT8 *g_sysNoCacheMem0 = (UINT8 *)NULL; +__attribute__((section(".data.init"))) UINT32 g_sysMemAddrEnd; +#ifdef OS_MEM_CHECK_DEBUG +static UINT8 g_checkMemLevel = (UINT8)LOS_MEM_CHECK_LEVEL_DEFAULT; +#endif + +#ifdef LOS_MEM_LEAK_CHECK +MEM_CHECK_INFO g_checkInfo[CHECK_MAXCOUNT] = {0}; +int g_memCount = 0; +int g_memPeakCount = 0; +int g_memCheckFlag = 0; +#endif + +#ifdef LOSCFG_MEM_MUL_MODULE +UINT32 g_memInfo[MEM_MODULE_MAX + 1] = {0}; +#endif + +MALLOC_HOOK g_mallocHook = (MALLOC_HOOK)(UINTPTR)NULL; +LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit() +{ + UINT32 ret; + UINT32 memSize; + m_aucSysMem0 = (UINT8 *)(UINTPTR)(((UINT32)(UINTPTR)m_aucSysMem0 + (OS_MEM_NODE_ALIGN_SIZE - 1)) & + ~(OS_MEM_NODE_ALIGN_SIZE - 1)); + memSize = ((UINT32)g_sysMemAddrEnd) - OS_SYS_NOCACHEMEM_SIZE - (UINT32)(UINTPTR)m_aucSysMem0; + ret = LOS_MemInit(m_aucSysMem0, memSize); + PRINT_INFO("LiteOS heap memory address:0x%x,size:0x%x\n", m_aucSysMem0, memSize); + return ret; +} +#if (LOSCFG_BASE_CORE_TASKSTACK_INDEPENDENT == YES) +LITE_OS_SEC_TEXT_INIT UINT32 OsSysStackInit(UINT32 memStart) +{ + UINT32 ret; + UINT32 memSize; + UINT8 *sysStackAddr = NULL; + sysStackAddr = (UINT8 *)((memStart + (OS_MEM_NODE_ALIGN_SIZE - 1)) & ~(OS_MEM_NODE_ALIGN_SIZE - 1)); + memSize = ((UINTPTR)g_sysStackAddrEnd) - (UINTPTR)sysStackAddr; + ret = LOS_MemInit(sysStackAddr, memSize); + PRINT_INFO("LiteOS stack memory address:0x%x,size:0x%x\n", sysStackAddr, memSize); + return ret; +} +#endif + +#if OS_SYS_NOCACHEMEM_SIZE +UINT32 OsNocacheMemSystemInit(VOID) +{ + UINT32 ret; + g_sysNoCacheMem0 = (g_sysMemAddrEnd - OS_SYS_NOCACHEMEM_SIZE); + ret = LOS_MemInit(g_sysNoCacheMem0, OS_SYS_NOCACHEMEM_SIZE); + return ret; +} +#endif + +VOID OsMemInfoPrint(VOID *pool); +VOID *OsMemFindNodeCtrl(VOID *headPtr); + +/***************************************************************************** + Function : OsMemFindSuitableFreeBlock + Description : find suitable free block use "best fit" algorithm + Input : pool --- Pointer to memory pool + allocSize --- Size of memory in bytes which note need allocate + Output : None + Return : NULL --- no suitable block found + tmpNode --- pointer a suitable free block +*****************************************************************************/ +STATIC_INLINE LosMemDynNode *OsMemFindSuitableFreeBlock(VOID *pool, UINT32 allocSize) +{ + LOS_DL_LIST *listHead = (LOS_DL_LIST *)NULL; + + for (listHead = OS_MEM_HEAD(pool, allocSize); listHead != NULL; + listHead = OS_DLNK_NEXT_HEAD(OS_MEM_HEAD_ADDR(pool), listHead)) { + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(tmpNode, listHead, LosMemDynNode, freeNodeInfo) { + if (tmpNode->sizeAndFlag >= allocSize) { + return tmpNode; + } + } + } + + return (LosMemDynNode *)NULL; +} + +/***************************************************************************** + Function : OsMemClearNode + Description : clear a mem Node , set every member to NULL + Input : node --- Pointer to the mem node which will be cleared up + Output : None + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemClearNode(LosMemDynNode *node) +{ + node->freeNodeInfo.pstPrev = (LOS_DL_LIST *)NULL; + node->freeNodeInfo.pstNext = (LOS_DL_LIST *)NULL; + node->preNode = (LosMemDynNode *)NULL; +} + +/***************************************************************************** + Function : OsMemMergeNode + Description : merge this node and pre node ,then clear this node info + Input : node --- Pointer to node which will be merged + Output : None + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemMergeNode(LosMemDynNode *node) +{ + LosMemDynNode *nextNode = (LosMemDynNode *)NULL; + + node->preNode->sizeAndFlag += node->sizeAndFlag; + nextNode = (LosMemDynNode *)((UINTPTR)node + node->sizeAndFlag); + nextNode->preNode = node->preNode; + OsMemClearNode(node); +} + +/***************************************************************************** + Function : OsMemSpitNode + Description : spit new node from allocNode, and merge remainder mem if necessary + Input : pool --- Pointer to memory pool + allocNode --- the source node which new node be spit from to. + After pick up it's node info, change to point the new node + allocSize --- the size of new node + Output : allocNode --- save new node addr + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemSpitNode(VOID *pool, LosMemDynNode *allocNode, UINT32 allocSize) +{ + LosMemDynNode *newFreeNode = (LosMemDynNode *)NULL; + LosMemDynNode *nextNode = (LosMemDynNode *)NULL; + LOS_DL_LIST *listHead = (LOS_DL_LIST *)NULL; + + newFreeNode = (LosMemDynNode *)((UINT8 *)allocNode + allocSize); + newFreeNode->preNode = allocNode; + newFreeNode->sizeAndFlag = allocNode->sizeAndFlag - allocSize; + allocNode->sizeAndFlag = allocSize; + nextNode = OS_MEM_NEXT_NODE(newFreeNode); + nextNode->preNode = newFreeNode; + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + LOS_ListDelete(&(nextNode->freeNodeInfo)); + OsMemMergeNode(nextNode); + } + + listHead = OS_MEM_HEAD(pool, newFreeNode->sizeAndFlag); + if (listHead == NULL) { + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + return; + } + + LOS_ListAdd(listHead, &(newFreeNode->freeNodeInfo)); +} + +/***************************************************************************** + Function : OsMemFreeNode + Description : free the node from memory & if there are free node beside, merger them. + at last update "listHead' which saved all free node control head + Input : node --- the node which need be freed + pool --- Pointer to memory pool + Output : None + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemFreeNode(LosMemDynNode *node, VOID *pool) +{ + LosMemDynNode *nextNode = (LosMemDynNode *)NULL; + LOS_DL_LIST *listHead = (LOS_DL_LIST *)NULL; + +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + poolInfo->uwPoolCurUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); +#endif + if (pool == (VOID *)OS_SYS_MEM_ADDR) { + OS_MEM_REDUCE_USED(OS_MEM_NODE_GET_SIZE(node->sizeAndFlag), OS_MEM_TASKID_GET(node)); + } + + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + if ((node->preNode != NULL) && + (!OS_MEM_NODE_GET_USED_FLAG(node->preNode->sizeAndFlag))) { + LosMemDynNode *preNode = node->preNode; + OsMemMergeNode(node); + nextNode = OS_MEM_NEXT_NODE(preNode); + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + LOS_ListDelete(&(nextNode->freeNodeInfo)); + OsMemMergeNode(nextNode); + } + + LOS_ListDelete(&(preNode->freeNodeInfo)); + listHead = OS_MEM_HEAD(pool, preNode->sizeAndFlag); + if (listHead == NULL) { + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + return; + } + + LOS_ListAdd(listHead, &(preNode->freeNodeInfo)); + } else { + nextNode = OS_MEM_NEXT_NODE(node); + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) { + LOS_ListDelete(&(nextNode->freeNodeInfo)); + OsMemMergeNode(nextNode); + } + + listHead = OS_MEM_HEAD(pool, node->sizeAndFlag); + if (listHead == NULL) { + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + return; + } + + LOS_ListAdd(listHead, &(node->freeNodeInfo)); + } +} + +STATIC_INLINE LosMemDynNode *OsMemGetNodeFromPtr(VOID *ptr) +{ + UINT32 gapSize; + gapSize = *((UINT32 *)((UINTPTR)ptr - OS_MEM_NODE_DATA_SIZE)); + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + ptr = (VOID *)((UINTPTR)ptr - gapSize); + } + return (LosMemDynNode *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); +} + +/***************************************************************************** + Function : OsMemCheckUsedNode + Description : check the result if pointer memory node belongs to pointer memory pool + Input : pool --- Pointer to memory pool + node --- the node which need be checked + Output : None + Return : LOS_OK or LOS_NOK +*****************************************************************************/ +#ifdef LOS_DLNK_SAFE_CHECK +STATIC_INLINE UINT32 OsMemCheckUsedNode(VOID *pool, LosMemDynNode *node) +{ + LosMemDynNode *tmpNode = NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LosMemDynNode *end = OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < end; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if ((tmpNode == node) && OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + return LOS_OK; + } else if (tmpNode > node) { + return LOS_NOK; + } + } + + return LOS_NOK; +} + +#elif defined(LOS_DLNK_SIMPLE_CHECK) +STATIC_INLINE UINT32 OsMemCheckUsedNode(VOID *pool, LosMemDynNode *node) +{ + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LosMemDynNode *startNode = OS_MEM_FIRST_NODE(pool); + LosMemDynNode *endNode = OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(startNode, node, endNode)) { + return LOS_NOK; + } + + if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + return LOS_NOK; + } + + if (!OS_MEM_MAGIC_VALID(node->freeNodeInfo.pstPrev)) { + return LOS_NOK; + } + + return LOS_OK; +} + +#else +STATIC_INLINE BOOL OsMemIsNodeValid(const LosMemDynNode *node, const LosMemDynNode *startNode, + const LosMemDynNode *endNode, const UINT8 *startPool, const UINT8 *endPool) +{ + if (!OS_MEM_MIDDLE_ADDR(startNode, node, endNode)) { + return FALSE; + } + + if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID(node->freeNodeInfo.pstPrev)) { + return FALSE; + } + return TRUE; + } + + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(startPool, node->freeNodeInfo.pstPrev, endPool)) { + return FALSE; + } + + return TRUE; +} + +STATIC_INLINE UINT32 OsMemCheckUsedNode(VOID *pool, LosMemDynNode *node) +{ + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LosMemDynNode *startNode = OS_MEM_FIRST_NODE(pool); + LosMemDynNode *endNode = OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + UINT8 *endPool = (UINT8 *)pool + poolInfo->uwPoolSize; + const LosMemDynNode *nextNode = (const LosMemDynNode *)NULL; + if (OsMemIsNodeValid(node, startNode, endNode, (UINT8 *)pool, endPool) != TRUE) { + return LOS_NOK; + } + + if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + return LOS_NOK; + } + + nextNode = OS_MEM_NEXT_NODE(node); + if (OsMemIsNodeValid(nextNode, startNode, endNode, (UINT8 *)pool, endPool) != TRUE) { + return LOS_NOK; + } + + if (nextNode->preNode != node) { + return LOS_NOK; + } + + if (node != startNode) { + if (OsMemIsNodeValid(node->preNode, startNode, endNode, (UINT8 *)pool, endPool) != TRUE) { + return LOS_NOK; + } + + if (OS_MEM_NEXT_NODE(node->preNode) != node) { + return LOS_NOK; + } + } + + return LOS_OK; +} + +#endif + +/***************************************************************************** + Function : OsMemSetMagicNumAndTaskid + Description : set magic & taskid + Input : node --- the node which will be set magic & taskid + Output : None + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemSetMagicNumAndTaskid(LosMemDynNode *node) +{ + OS_MEM_SET_MAGIC(node->freeNodeInfo.pstPrev); + + /* In the process of dynamic memory initialization, direct use of uninitialized global variable which + * initialized in task initialization. Need to exclude this scene, make the value of + * node->freeNodeInfo.pstNext to 0xffffffff */ + if ((g_losTask.runTask != NULL) && OS_INT_INACTIVE) { + OS_MEM_TASKID_SET(node, g_losTask.runTask->taskID); + } else { + node->freeNodeInfo.pstNext = (LOS_DL_LIST *)0xffffffff; /* If the task mode does not initialize, + * the field is the 0xffffffff */ + } +} + +STATIC_INLINE VOID OsMemIntegrityCheckErrout(LosMemDynNode *curNode, LosMemDynNode *prevNode) +{ + UINT32 taskID; + LosTaskCB *taskCB = NULL; + + /* print the 4 UINT32 of the current memory node head */ + PRINTK("broken node head: 0x%x 0x%x 0x%x 0x%x\n", + *(UINT32 *)curNode, *((UINT32 *)curNode + 1), *((UINT32 *)curNode + 2), *((UINT32 *)curNode + 3)); + + taskID = OS_MEM_TASKID_GET(prevNode); + do { + if (taskID >= g_taskMaxNum) { + LOS_Panic("Task ID %d in pre node is invalid!\n", taskID); + break; + } + taskCB = OS_TCB_FROM_TID(taskID); + + if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) || + (taskCB->taskEntry == NULL) || + (taskCB->taskName == NULL)) { + LOS_Panic("\r\nTask ID %d in pre node is not created!\n", taskID); + break; + } + LOS_Panic("cur node: 0x%x\n" + "pre node: 0x%x\n" + "pre node was allocated by task:%s\n", + (UINTPTR)curNode, (UINTPTR)prevNode, taskCB->taskName); + } while (0); +} + +/***************************************************************************** + Function : LOS_MemIntegrityCheck + Description : memory pool integrity checking + Input : pool --- Pointer to memory pool + Output : None + Return : LOS_OK --- memory pool integrate or LOS_NOK --- memory pool impaired +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) +{ + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + LosMemDynNode *prevNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + UINT8 *endPool = NULL; + UINTPTR intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + endPool = (UINT8 *)pool + poolInfo->uwPoolSize; + + intSave = LOS_IntLock(); + prevNode = OS_MEM_FIRST_NODE(pool); + for (tmpNode = OS_MEM_FIRST_NODE(pool); + tmpNode < OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID(tmpNode->freeNodeInfo.pstPrev)) { + PRINT_ERR("[%s], %d, memory check error!\n" + "memory used but magic num wrong, freeNodeInfo.pstPrev(magic num):0x%x \n", + __FUNCTION__, __LINE__, (UINT32)(UINTPTR)(tmpNode->freeNodeInfo.pstPrev)); + goto ERROUT; + } + } else { /* is free node, check free node range */ + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pool, tmpNode->freeNodeInfo.pstPrev, endPool)) { + PRINT_ERR("[%s], %d, memory check error!\n" + "freeNodeInfo.pstPrev:0x%x is out of legal mem range[0x%x, 0x%x]\n", + __FUNCTION__, __LINE__, + (UINT32)(UINTPTR)(tmpNode->freeNodeInfo.pstPrev), (UINTPTR)pool, (UINTPTR)endPool); + goto ERROUT; + } + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pool, + (UINT32)(UINTPTR)(tmpNode->freeNodeInfo.pstNext), + (UINTPTR)endPool)) { + PRINT_ERR("[%s], %d, memory check error!\n" + "freeNodeInfo.pstNext:0x%x is out of legal mem range[0x%x, 0x%x]\n", + __FUNCTION__, __LINE__, + (UINT32)(UINTPTR)(tmpNode->freeNodeInfo.pstNext), (UINTPTR)pool, (UINTPTR)endPool); + goto ERROUT; + } + } + + prevNode = tmpNode; + } + LOS_IntRestore(intSave); + return LOS_OK; + +ERROUT: + OsMemIntegrityCheckErrout(tmpNode, prevNode); + LOS_IntRestore(intSave); + return LOS_NOK; +} + +/***************************************************************************** + Function : OsMemAllocWithCheck + Description : Allocate node from Memory pool + Input : pool --- Pointer to memory pool + size --- Size of memory in bytes to allocate + Output : None + Return : Pointer to allocated memory +*****************************************************************************/ +STATIC_INLINE VOID *OsMemAllocWithCheck(VOID *pool, UINT32 size) +{ + LosMemDynNode *allocNode = (LosMemDynNode *)NULL; + UINT32 allocSize; +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; +#endif + if (g_mallocHook != NULL) { + g_mallocHook(); + } + +#ifdef OS_MEM_ENABLE_ALLOC_CHECK + if (LOS_MemIntegrityCheck(pool) != LOS_OK) { + PRINT_ERR("Memory Pool Integrity Checking Failed!\n"); + } +#endif + + allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); + allocNode = OsMemFindSuitableFreeBlock(pool, allocSize); + if (allocNode == NULL) { + PRINT_ERR("--------------------------------------------------------------------------------------\n"); + OsMemInfoPrint(pool); + PRINT_ERR("[%s] No suitable free block, require free node size: 0x%x\n", __FUNCTION__, allocSize); + PRINT_ERR("--------------------------------------------------------------------------------------\n"); + return NULL; + } + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= allocNode->sizeAndFlag) { + OsMemSpitNode(pool, allocNode, allocSize); + } + LOS_ListDelete(&(allocNode->freeNodeInfo)); + OsMemSetMagicNumAndTaskid(allocNode); + OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); + if (pool == (VOID *)OS_SYS_MEM_ADDR) { + OS_MEM_ADD_USED(OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag), OS_MEM_TASKID_GET(allocNode)); + } +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->uwPoolCurUsedSize += OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag); + if (poolInfo->uwPoolCurUsedSize > poolInfo->uwPoolWaterLine) { + poolInfo->uwPoolWaterLine = poolInfo->uwPoolCurUsedSize; + } +#endif + return (allocNode + 1); +} + +/***************************************************************************** + Function : OsMemReAllocSmaller + Description : reAlloc a smaller memory node + Input : pool --- Pointer to memory pool + allocSize --- the size of new node which will be alloced + node --- the node which wille be realloced + nodeSize --- the size of old node + Output : node --- pointer to the new node after realloc + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, LosMemDynNode *node, UINT32 nodeSize) +{ +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; +#endif + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= nodeSize) { + node->sizeAndFlag = nodeSize; + OsMemSpitNode(pool, node, allocSize); + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); + if (pool == (VOID *)OS_SYS_MEM_ADDR) { + OS_MEM_REDUCE_USED(nodeSize - allocSize, OS_MEM_TASKID_GET(node)); + } +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->uwPoolCurUsedSize -= (nodeSize - allocSize); +#endif + } +} + +/***************************************************************************** + Function : OsMemMergeNodeForReAllocBigger + Description : reAlloc a Bigger memory node after merge node and nextNode + Input : pool --- Pointer to memory pool + allocSize --- the size of new node which will be alloced + node --- the node which wille be realloced + nodeSize --- the size of old node + nextNode --- pointer next node which will be merged + Output : node --- pointer to the new node after realloc + Return : None +*****************************************************************************/ +STATIC_INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, + LosMemDynNode *node, UINT32 nodeSize, LosMemDynNode *nextNode) +{ +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; +#endif + node->sizeAndFlag = nodeSize; + LOS_ListDelete(&(nextNode->freeNodeInfo)); + OsMemMergeNode(nextNode); + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= node->sizeAndFlag) { + OsMemSpitNode(pool, node, allocSize); + } +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->uwPoolCurUsedSize += (node->sizeAndFlag - nodeSize); + if (poolInfo->uwPoolCurUsedSize > poolInfo->uwPoolWaterLine) { + poolInfo->uwPoolWaterLine = poolInfo->uwPoolCurUsedSize; + } +#endif + if (pool == (VOID *)OS_SYS_MEM_ADDR) { + OS_MEM_ADD_USED(node->sizeAndFlag - nodeSize, OS_MEM_TASKID_GET(node)); + } + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); +} + +STATIC_INLINE VOID *OsMemReallocMem(VOID *pool, const VOID *ptr, UINT32 size, LosMemDynNode *node) +{ + errno_t rc; + VOID *newPtr = NULL; + UINT32 allocSize, nodeSize; + LosMemDynNode *nextNode = NULL; + + allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); + nodeSize = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); + if (nodeSize >= allocSize) { + OsMemReAllocSmaller(pool, allocSize, node, nodeSize); + return (VOID *)ptr; + } + + nextNode = OS_MEM_NEXT_NODE(node); + if ((!OS_MEM_NODE_GET_USED_FLAG(nextNode->sizeAndFlag)) && + ((nextNode->sizeAndFlag + nodeSize) >= allocSize)) { + OsMemMergeNodeForReAllocBigger(pool, allocSize, node, nodeSize, nextNode); + return (VOID *)ptr; + } + + newPtr = OsMemAllocWithCheck(pool, size); + if (newPtr != NULL) { + rc = memcpy_s(newPtr, size, ptr, nodeSize - OS_MEM_NODE_HEAD_SIZE); + if (rc != EOK) { + PRINT_ERR("%s[%d] memcpy_s failed, error type = %d\n", __FUNCTION__, __LINE__, rc); + } + OsMemFreeNode(node, pool); + } + return newPtr; + +} +/***************************************************************************** + Function : LOS_MemPoolSizeGet + Description : get the memory pool's size + Input : pool --- Pointer to memory pool + Output : LOS_NOK & Other value --- The size of the memory pool. + Return : the size of the memory pool +*****************************************************************************/ +UINT32 LOS_MemPoolSizeGet(const VOID *pool) +{ + if (pool == NULL) { + return LOS_NOK; + } + return ((LOS_MEM_POOL_INFO *)pool)->uwPoolSize; +} + +STATIC_INLINE UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size) +{ + VOID *next = g_memPoolHead; + VOID *cur = NULL; + UINT32 poolEnd; + + while (next != NULL) { + poolEnd = (UINTPTR)next + LOS_MemPoolSizeGet(next); + if ((((pool <= next) && ((UINTPTR)pool + size)) > (UINTPTR)next) || + (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { + PRINT_ERR("pool [0x%x, 0x%x) conflict with pool [0x%x, 0x%x)\n", + (UINT32)(UINTPTR)pool, (UINT32)(UINTPTR)pool + size, + (UINT32)(UINTPTR)next, (UINT32)(UINTPTR)next + LOS_MemPoolSizeGet(next)); + return OS_ERROR; + } + cur = next; + next = ((LOS_MEM_POOL_INFO *)next)->pNextPool; + } + + if (g_memPoolHead == NULL) { + g_memPoolHead = pool; + } else { + ((LOS_MEM_POOL_INFO *)cur)->pNextPool = pool; + } + + ((LOS_MEM_POOL_INFO *)pool)->pNextPool = NULL; + return LOS_OK; +} +/***************************************************************************** + Function : LOS_MemInit + Description : Initialize Dynamic Memory pool + Input : pool --- Pointer to memory pool + size --- Size of memory in bytes to allocate + Output : None + Return : LOS_OK --- Ok, OS_ERROR --- Error +*****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size) +{ + LosMemDynNode *newNode = (LosMemDynNode *)NULL; + LosMemDynNode *endNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)NULL; + UINTPTR intSave; + LOS_DL_LIST *listHead = (LOS_DL_LIST *)NULL; +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) + UINT32 *memCount = (UINT32 *)g_memMang; + MEM_INFO *memInfo = (MEM_INFO *)(g_memMang + sizeof(UINT32)); + UINT8 loop; +#endif + + if ((pool == NULL) || (size < OS_MEM_MIN_POOL_SIZE)) { + return OS_ERROR; + } + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) + intSave = LOS_IntLock(); + for (loop = 0; loop < *memCount; loop++) { + if (memInfo->uwStartAddr == (UINT32)(UINTPTR)pool) { + (*memCount)--; + break; + } + memInfo++; + } + if (*memCount < OS_SYS_MEM_NUM) { + memInfo->uwType = MEM_MANG_MEMORY; + memInfo->uwStartAddr = (UINT32)(UINTPTR)pool; + memInfo->uwSize = size; + (*memCount)++; + } + LOS_IntRestore(intSave); +#endif + intSave = LOS_IntLock(); + + poolInfo = (LOS_MEM_POOL_INFO *)pool; + poolInfo->pPoolAddr = pool; + poolInfo->uwPoolSize = size; + OS_DLNK_INIT_HEAD(OS_MEM_HEAD_ADDR(pool)); + newNode = OS_MEM_FIRST_NODE(pool); + newNode->sizeAndFlag = ((size - ((UINTPTR)newNode - (UINTPTR)pool)) - OS_MEM_NODE_HEAD_SIZE); + newNode->preNode = (LosMemDynNode *)NULL; + listHead = OS_MEM_HEAD(pool, newNode->sizeAndFlag); + if (listHead == NULL) { + LOS_IntRestore(intSave); + return OS_ERROR; + } + + LOS_ListTailInsert(listHead, &(newNode->freeNodeInfo)); + endNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, size); + // Ignore the return code when matching CSEC rule 6.6(4). + (VOID)memset_s(endNode, sizeof(*endNode), 0, sizeof(*endNode)); + endNode->preNode = newNode; + endNode->sizeAndFlag = OS_MEM_NODE_HEAD_SIZE; + OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); + OsMemSetMagicNumAndTaskid(endNode); +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->uwPoolCurUsedSize = sizeof(LOS_MEM_POOL_INFO) + + OS_MULTI_DLNK_HEAD_SIZE + OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + poolInfo->uwPoolWaterLine = poolInfo->uwPoolCurUsedSize; +#endif + +#if (LOSCFG_MEM_MUL_POOL == YES) + UINT32 ret = OsMemMulPoolInit(pool, size); + if (ret != LOS_OK) { + LOS_IntRestore(intSave); + return ret; + } +#endif + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +#if (LOSCFG_MEM_MUL_POOL == YES) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(const VOID *pool) +{ + UINTPTR intSave; + UINTPTR ret = LOS_NOK; + VOID *next = NULL; + VOID *cur = NULL; + + intSave = LOS_IntLock(); + do { + if (pool == NULL) { + break; + } + + if (pool == g_memPoolHead) { + g_memPoolHead = ((LOS_MEM_POOL_INFO *)g_memPoolHead)->pNextPool; + ret = LOS_OK; + break; + } + + cur = g_memPoolHead; + next = g_memPoolHead; + + while (next != NULL) { + if (pool == next) { + ((LOS_MEM_POOL_INFO *)cur)->pNextPool = ((LOS_MEM_POOL_INFO *)next)->pNextPool; + ret = LOS_OK; + break; + } + cur = next; + next = ((LOS_MEM_POOL_INFO *)next)->pNextPool; + } + } while (0); + + LOS_IntRestore(intSave); + return ret; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemPoolList(VOID) +{ + VOID *next = g_memPoolHead; + UINT32 index = 0; + while (next != NULL) { + PRINTK("pool%u :\n", index); + index++; + OsMemInfoPrint(next); + next = ((LOS_MEM_POOL_INFO *)next)->pNextPool; + } + return index; +} +#endif + +#ifdef LOS_MEM_LEAK_CHECK +LITE_OS_SEC_TEXT VOID LOS_CheckMaxcount(VOID) +{ + if (g_memCheckFlag == 1) { + PRINTK("\nIt's checking the maxcount now, please waiting!\n"); + return; + } + PRINTK("\nthe max malloc count :%d\nplease set the CHECK_MAXCOUNT bigger than %d!\n", + g_memPeakCount, g_memPeakCount); +} + +LITE_OS_SEC_TEXT VOID LOS_MemLeakCheckStart(VOID) +{ + UINT32 ret; + UINTPTR intSave; + errno_t rc; + + intSave = LOS_IntLock(); + rc = memset_s(g_checkInfo, CHECK_MAXCOUNT, 0, MEM_CHECK_MAX_SIZE); + if (rc != EOK) { + PRINT_ERR("%s[%d] memset_s failed, error type = %d\n", __FUNCTION__, __LINE__, rc); + LOS_IntRestore(intSave); + return; + } + ret = LOS_MemboxInit(g_checkInfo, MEM_CHECK_MAX_SIZE, MEM_CHECK_SIZE); + if (ret != LOS_OK) { + PRINT_ERR("\nLOS_MemboxInit failed!\n"); + LOS_IntRestore(intSave); + return; + } + g_memCount = 0; + g_memPeakCount = 0; + g_memCheckFlag = 1; + LOS_IntRestore(intSave); +} + +INLINE VOID OsMemCheckinfoCreate(VOID *ptr, UINT32 size) +{ + UINT32 fp; + UINT32 i = 0; + UINT32 tmpFp; + UINT32 backLR; + MEM_CHECK_INFO *check = NULL; + UINTPTR intSave; + + fp = Get_Fp(); + intSave = LOS_IntLock(); + g_memCount++; + if (g_memCount > g_memPeakCount) { + g_memPeakCount = g_memCount; + } + LOS_IntRestore(intSave); + + check = (MEM_CHECK_INFO *)LOS_MemboxAlloc(g_checkInfo); + if (check == NULL) { + PRINTK("memboxalloc is failure:%s[%d]\r\n", __FUNCTION__, __LINE__); + return; + } + + (void)memset_s(check, sizeof(MEM_CHECK_INFO), 0, sizeof(MEM_CHECK_INFO)); + check->pPoolAddr = ptr; + while ((fp > OS_SYS_FUNC_ADDR_START) && (fp < OS_SYS_FUNC_ADDR_END)) { + tmpFp = fp; + backLR = *((UINT32 *)(fp)); + fp = *((UINT32 *)(tmpFp - OS_MEM_NODE_DATA_SIZE)); + if (i > 0) { + check->fp[i - 1] = backLR; + } + i++; + if (i == (OS_MEM_NODE_DATA_SIZE + 1)) { + break; + } + } + check->flag = 1; + check->uwAddrSize = size; + return; +} + +INLINE VOID OsMemCheckinfoDel(VOID *nodePtr) +{ + UINT32 i; + UINT32 ret; + UINTPTR intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)g_checkInfo; + LOS_MEMBOX_NODE *node = (LOS_MEMBOX_NODE *)NULL; + + intSave = LOS_IntLock(); + g_memCount--; + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + for (i = 0; i < boxInfo->uwBlkNum; ++i, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { + if (*(UINT32 *)((UINTPTR)node + OS_CHECK_FLAG) != 1) { + continue; + } + + if ((UINTPTR)nodePtr == *((UINT32 *)node)) { + ret = LOS_MemboxFree(g_checkInfo, node); + if (ret != LOS_OK) { + PRINTK("free membox failed!\n"); + } + *(UINT32 *)((UINTPTR)node + OS_CHECK_FLAG) = 0; + LOS_IntRestore(intSave); + return; + } + } + LOS_IntRestore(intSave); +} + +LITE_OS_SEC_TEXT VOID LOS_MemLeakCheckEnd(VOID) +{ + UINTPTR intSave; + + intSave = LOS_IntLock(); + g_memCheckFlag = 0; + LOS_IntRestore(intSave); +} + +LITE_OS_SEC_TEXT VOID LOS_MemLeakCheckShow(VOID) +{ + UINT32 i; + UINT32 j; + UINTPTR intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)g_checkInfo; + LOS_MEMBOX_NODE *node = (LOS_MEMBOX_NODE *)NULL; + + intSave = LOS_IntLock(); + + if (g_memCheckFlag == 1) { + PRINTK("\nIt's checking mem used now, please waiting!\n"); + LOS_IntRestore(intSave); + return; + } + + PRINTK("\n\n **********************all mem used list**********************\r\n"); + PRINTK(" ID lr0 lr1 lr2 lr3 MemSize MemAddr\n"); + PRINTK("---------------------------------------------------------------------------------\n"); + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + for (i = 0, j = 0; i < boxInfo->uwBlkNum; ++i, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { + if ((*(UINT32 *)((UINTPTR)node + OS_CHECK_FLAG)) == 1) { + PRINTK(" %-3d 0x%-11x0x%-11x0x%-11x0x%-11x0x%-11x0x%-11x\n", j, + *(UINT32 *)((UINTPTR)node + OS_CHECK_FP0), *(UINT32 *)((UINTPTR)node + OS_CHECK_FP1), + *(UINT32 *)((UINTPTR)node + OS_CHECK_FP2), *(UINT32 *)((UINTPTR)node + OS_CHECK_FP3), + *(UINT32 *)((UINTPTR)node + OS_ADDR_SIZE), *(UINT32 *)(UINTPTR)node); + j++; + } + } + LOS_IntRestore(intSave); + if (j == 0) { + PRINTK("************************no mem leak!!!************************\n"); + return; + } + PRINTK("---------------------------------------------------------------------------------\n"); +} + +#endif + +/***************************************************************************** + Function : LOS_MemAlloc + Description : Allocate node from Memory pool + Input : pool --- Pointer to memory pool + size --- Size of memory in bytes to allocate + Output : None + Return : Pointer to allocated memory node +*****************************************************************************/ +LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) +{ + VOID *ptr = NULL; + UINTPTR intSave = LOS_IntLock(); + + do { + if ((pool == NULL) || (size == 0)) { + break; + } + + if (OS_MEM_NODE_GET_USED_FLAG(size)) { + break; + } + + ptr = OsMemAllocWithCheck(pool, size); + +#ifdef LOS_MEM_LEAK_CHECK + if (g_memCheckFlag == 1) { + OsMemCheckinfoCreate(ptr, size); + } +#endif + } while (0); + + LOS_IntRestore(intSave); + return ptr; +} + +/***************************************************************************** + Function : LOS_MemAllocAlign + Description : align size then allocate node from Memory pool + Input : pool --- Pointer to memory pool + size --- Size of memory in bytes to allocate + boundary --- align form + Output : None + Return : Pointer to allocated memory node +*****************************************************************************/ +LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) +{ + UINT32 useSize; + UINT32 gapSize; + VOID *ptr = NULL; + VOID *alignedPtr = NULL; + UINTPTR intSave = LOS_IntLock(); + + do { + if ((pool == NULL) || (size == 0) || (boundary < sizeof(VOID *)) || !IS_ALIGNED(boundary)) { + break; + } + + useSize = size + boundary + 4; /* 4bytes stores offset between alignedPtr and ptr */ + + if ((useSize < size) || OS_MEM_NODE_GET_USED_FLAG(useSize)) { + break; + } + + ptr = OsMemAllocWithCheck(pool, useSize); + + alignedPtr = (VOID *)(UINTPTR)OS_MEM_ALIGN(ptr, boundary); + + if (ptr == alignedPtr) { + break; + } + + gapSize = (UINTPTR)alignedPtr - (UINTPTR)ptr; /* store gapSize in address (ptr -4), + it will be checked while free */ + OS_MEM_NODE_SET_ALIGNED_FLAG(gapSize); + *((UINT32 *)((UINTPTR)alignedPtr - OS_MEM_NODE_DATA_SIZE)) = gapSize; + + ptr = alignedPtr; + +#ifdef LOS_MEM_LEAK_CHECK + if (g_memCheckFlag == 1) { + OsMemCheckinfoCreate(ptr, size); + } +#endif + } while (0); + + LOS_IntRestore(intSave); + + return ptr; +} + +/***************************************************************************** + Function : LOS_MemFree + Description : free the node from memory & if there are free node beside, merger them. + at last update "listHead" which saved all free node control head + Input : pool --- Pointer to memory pool + ptr --- the node which need be freed + Output : None + Return : LOS_OK --- OK, LOS_NOK --- failed +*****************************************************************************/ +LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *ptr) +{ + UINT32 ret = LOS_NOK; + UINTPTR intSave = LOS_IntLock(); +#ifdef LOS_MEM_LEAK_CHECK + VOID *p = ptr; +#endif + do { + LosMemDynNode *node = (LosMemDynNode *)NULL; + + if ((pool == NULL) || (ptr == NULL)) { + break; + } + + node = OsMemGetNodeFromPtr(ptr); + + ret = OsMemCheckUsedNode(pool, node); + if (ret == LOS_OK) { + OsMemFreeNode(node, pool); +#ifdef LOS_MEM_LEAK_CHECK + if (g_memCheckFlag == 1) { + OsMemCheckinfoDel(p); + } +#endif + } + + } while (0); + + LOS_IntRestore(intSave); + return ret; +} + +/***************************************************************************** + Function : LOS_MemRealloc + Description : reAlloc memory node + Input : pool --- Pointer to memory pool + ptr --- pointer to memory node which will be realloced + size --- the size of new node + Output : None + Return : Pointer to allocated memory +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) +{ + VOID *newPtr = NULL; + + if ((INT32)size < 0) { + return NULL; + } + + UINTPTR intSave = LOS_IntLock(); + + do { + LosMemDynNode *node = (LosMemDynNode *)NULL; + UINT32 ret; + + if (size == 0) { + (VOID)LOS_MemFree((VOID *)pool, (VOID *)ptr); + break; + } + + if (ptr == NULL) { + newPtr = LOS_MemAlloc((VOID *)pool, (UINT32)size); + if (newPtr == NULL) { + break; + } + (VOID)memset_s(newPtr, (UINT32)size, 0, (UINT32)size); + break; + } + + node = OsMemGetNodeFromPtr(ptr); + + ret = OsMemCheckUsedNode(pool, node); + if (ret != LOS_OK) { + break; + } + newPtr = OsMemReallocMem(pool, ptr, size, node); + + } while (0); + + LOS_IntRestore(intSave); + return newPtr; +} + +/***************************************************************************** + Function : LOS_MemTotalUsedGet + Description : figure the pointer memory pool for it's total mem used + Input : pool --- Pointer to memory pool + Output : None + Return : the size of the pool has been used +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) +{ + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + UINT32 memUsed = 0; + UINTPTR intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + intSave = LOS_IntLock(); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); + } + } + + LOS_IntRestore(intSave); + + return memUsed; +} + +/***************************************************************************** + Function : LOS_MemUsedBlksGet + Description : get the number of used node + Input : pool --- Pointer to memory pool + Output : None + Return : the number of used node +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemUsedBlksGet(VOID *pool) +{ + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + UINT32 blkNums = 0; + UINTPTR intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + intSave = LOS_IntLock(); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + blkNums++; + } + } + + LOS_IntRestore(intSave); + + return blkNums; +} + +/***************************************************************************** + Function : LOS_MemTaskIdGet + Description : get a memory node's taskID if pointer node is "used node" + Input : ptr --- pointer to aim node + Output : None + Return : taskID --- Ok or OS_INVALID --- pointer node is illegal or free node +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTaskIdGet(const VOID *ptr) +{ + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)OS_SYS_MEM_ADDR; + UINTPTR intSave; + + if ((ptr == NULL) || + (ptr < (VOID *)OS_MEM_FIRST_NODE(OS_SYS_MEM_ADDR)) || + (ptr > (VOID *)OS_MEM_END_NODE(OS_SYS_MEM_ADDR, poolInfo->uwPoolSize))) { + PRINT_ERR("input ptr 0x%x is out of system memory range[0x%x, 0x%x]\n", + (UINTPTR)ptr, + (UINTPTR)(OS_MEM_FIRST_NODE(OS_SYS_MEM_ADDR)), + (UINTPTR)(OS_MEM_END_NODE(OS_SYS_MEM_ADDR, poolInfo->uwPoolSize))); + return OS_INVALID; + } + + intSave = LOS_IntLock(); + + for (tmpNode = OS_MEM_FIRST_NODE(OS_SYS_MEM_ADDR); + tmpNode <= OS_MEM_END_NODE(OS_SYS_MEM_ADDR, poolInfo->uwPoolSize); tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if ((UINTPTR)ptr < (UINTPTR)tmpNode) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->preNode->sizeAndFlag)) { + UINTPTR tmpValue = (UINTPTR)(tmpNode->preNode->freeNodeInfo.pstNext); + LOS_IntRestore(intSave); + return tmpValue; + } else { + LOS_IntRestore(intSave); + PRINT_ERR("input ptr 0x%x is belong to a free mem node\n", (UINTPTR)ptr); + return OS_INVALID; + } + } + } + + LOS_IntRestore(intSave); + return OS_INVALID; +} + +/***************************************************************************** + Function : LOS_MemFreeBlksGet + Description : get the number of free node + Input : pool --- Pointer to memory pool + Output : None + Return : the number of free node +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeBlksGet(VOID *pool) +{ + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + UINT32 blkNum = 0; + UINTPTR intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + intSave = LOS_IntLock(); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + blkNum++; + } + } + + LOS_IntRestore(intSave); + + return blkNum; +} + +/***************************************************************************** + Function : LOS_MemLastUsedGet + Description : get the address of last used node(except end node) + Input : pool --- Pointer to memory pool + Output : None + Return : address of last node offset sizeof(LosMemDynNode), if last node is freeNode + address of the end node, if last node is usedNode +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemLastUsedGet(VOID *pool) +{ + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LosMemDynNode *node = NULL; + + if (pool == NULL) { + return LOS_NOK; + } + + node = OS_MEM_END_NODE(pool, poolInfo->uwPoolSize)->preNode; + + if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + return (UINTPTR)node + OS_MEM_NODE_GET_SIZE(node->sizeAndFlag) + sizeof(LosMemDynNode); + } else { + return (UINTPTR)node + sizeof(LosMemDynNode); + } +} + +/***************************************************************************** + Function : OsMemResetEndNode + Description : reset "end node" + Input : None + Output : endNode --- pointer to "end node" + Return : the number of free node +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID OsMemResetEndNode(UINT32 preAddr) +{ + LosMemDynNode *endNode = (LosMemDynNode *)OS_MEM_END_NODE(OS_SYS_MEM_ADDR, OS_SYS_MEM_SIZE); + endNode->sizeAndFlag = OS_MEM_NODE_HEAD_SIZE; + if (preAddr != (UINT32)NULL) { + endNode->preNode = (LosMemDynNode *)(UINTPTR)(preAddr - sizeof(LosMemDynNode)); + } + OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); + OsMemSetMagicNumAndTaskid(endNode); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_STATUS *status) +{ + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + UINT32 totalUsedSize = 0; + UINT32 totalFreeSize = 0; + UINT32 maxFreeNodeSize = 0; + UINT32 usedNodeNum = 0; + UINT32 freeNodeNum = 0; + UINTPTR intSave; + + if ((poolInfo == NULL) || ((UINTPTR)pool != (UINTPTR)poolInfo->pPoolAddr)) { + PRINT_ERR("wrong mem pool addr: 0x%x, line:%d\n", (UINTPTR)poolInfo, __LINE__); + return LOS_NOK; + } + + if (status == NULL) { + PRINT_ERR("wrong status addr: 0x%x, line:%d\n", (UINTPTR)status, __LINE__); + return LOS_NOK; + } + + tmpNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = (LosMemDynNode *)(UINTPTR)OS_MEM_ALIGN(tmpNode, OS_MEM_ALIGN_SIZE); + + if (!OS_MEM_MAGIC_VALID(tmpNode->freeNodeInfo.pstPrev)) { + PRINT_ERR("wrong mem pool addr: 0x%x, line:%d\n", (UINTPTR)poolInfo, __LINE__); + return LOS_NOK; + } + + intSave = LOS_IntLock(); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + ++freeNodeNum; + totalFreeSize += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); + if (maxFreeNodeSize < OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag)) { + maxFreeNodeSize = OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); + } + } else { + ++usedNodeNum; + totalUsedSize += OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag); + } + } + + LOS_IntRestore(intSave); + + status->usedSize = totalUsedSize; + status->freeSize = totalFreeSize; + status->totalSize = maxFreeNodeSize; + status->allocCount = usedNodeNum; + status->freeCount = freeNodeNum; +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + status->uwUsageWaterLine = poolInfo->uwPoolWaterLine; +#endif + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsMemInfoPrint(VOID *pool) +{ + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LOS_MEM_STATUS status = {0}; + + if (LOS_NOK == LOS_MemInfoGet(pool, &status)) { + return; + } + +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + PRINTK("pool addr pool size used size free size" + " max free node size used node num free node num UsageWaterLine\n" + "--------- -------- ------- --------" + " -------------- ------------- ------------ ------------\n" + "0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x 0x%-13x\n", + poolInfo->pPoolAddr, poolInfo->uwPoolSize, status.usedSize, status.freeSize, + status.totalSize, status.allocCount, status.freeCount, status.uwUsageWaterLine); + +#else + PRINTK("pool addr pool size used size free size" + " max free node size used node num free node num\n" + "--------- -------- ------- --------" + " -------------- ------------- ------------\n" + "0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n", + (UINT32)(UINTPTR)(poolInfo->pPoolAddr), poolInfo->uwPoolSize, status.usedSize, status.freeSize, + status.totalSize, status.allocCount, status.freeCount); +#endif + return; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeNodeShow(VOID *pool) +{ + LOS_DL_LIST *listHead = (LOS_DL_LIST *)NULL; + LosMultipleDlinkHead *headAddr = (LosMultipleDlinkHead *)((UINTPTR)pool + sizeof(LOS_MEM_POOL_INFO)); + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + LosMemDynNode *tmpNode = (LosMemDynNode *)NULL; + UINT32 count, idx; + UINT32 countNum[OS_MEM_NODE_COUNT_NUM] = {0}; + UINTPTR intSave; + INT32 i, j; + + if ((poolInfo == NULL) || ((UINTPTR)pool != (UINTPTR)poolInfo->pPoolAddr)) { + PRINT_ERR("wrong mem pool addr: 0x%x, line:%d\n", (UINTPTR)poolInfo, __LINE__); + return LOS_NOK; + } + + tmpNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, poolInfo->uwPoolSize); + tmpNode = (LosMemDynNode *)(UINTPTR)OS_MEM_ALIGN(tmpNode, OS_MEM_ALIGN_SIZE); + + if (!OS_MEM_MAGIC_VALID(tmpNode->freeNodeInfo.pstPrev)) { + PRINT_ERR("wrong mem pool addr: 0x%x\n, line:%d", (UINTPTR)poolInfo, __LINE__); + return LOS_NOK; + } + PRINTK("\n ************************ left free node number**********************\n block size: "); + intSave = LOS_IntLock(); + + for (idx = 0, j = 0; idx <= (OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2); idx++, j++) { + for (count = 0, listHead = headAddr->listHead[idx].pstNext; listHead != &(headAddr->listHead[idx]); + listHead = listHead->pstNext) { + ++count; + } + PRINTK("2^%-5d", idx + OS_MEM_NODE_DATA_SIZE); + if ((idx == 0) || ((((idx + 1) % OS_MEM_NODE_COUNT_NUM) != 0) && (idx != OS_MULTI_DLNK_SIZE))) { + goto NEXT; + } + PRINTK("\n node number:"); + for (i = 0; i < OS_MEM_NODE_COUNT_NUM; i++) { + PRINTK(" %-5u", countNum[i]); + if ((i == OS_MEM_NODE_NUM) && (idx == (OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2))) { + break; + } + } + if (idx != (OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2)) { + PRINTK("\n\n block size: "); + } +NEXT: + j = idx % OS_MEM_NODE_COUNT_NUM; + countNum[j] = count; + } + LOS_IntRestore(intSave); + PRINTK("\n ********************************************************************\n\n"); + + return LOS_OK; +} + +#ifdef OS_MEM_CHECK_DEBUG + +/***************************************************************************** + Function : LOS_MemNodeSizeCheck + Description: get a pNode's(ptr) size ,include total size and available size + Input : pool --- which pool doesn't your ptr belong to + ptr --- point to source node + Output : totalSize --- save total size + availSize --- save availabe size + Return : errorID or LOS_OK +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemNodeSizeCheck(VOID *pool, VOID *ptr, UINT32 *totalSize, UINT32 *availSize) +{ + VOID *head = NULL; + LOS_MEM_POOL_INFO *poolInfo = (LOS_MEM_POOL_INFO *)pool; + UINT8 *endPool = NULL; + + if (g_checkMemLevel == LOS_MEM_CHECK_LEVEL_DISABLE) { + return OS_ERRNO_MEMCHECK_DISABLED; + } + + if ((pool == NULL) || (ptr == NULL)) { + return OS_ERRNO_MEMCHECK_PARA_NULL; + } + + endPool = (UINT8 *)pool + poolInfo->uwPoolSize; + if (!(OS_MEM_MIDDLE_ADDR_OPEN_END(pool, (UINT8 *)ptr, endPool))) { + return OS_ERRNO_MEMCHECK_OUTSIDE; + } + + if (g_checkMemLevel == LOS_MEM_CHECK_LEVEL_HIGH) { + head = OsMemFindNodeCtrl(ptr); + if ((head == NULL) || ((((LosMemDynNode *)head)->sizeAndFlag & (~OS_MEM_NODE_USED_FLAG)) < + ((UINTPTR)ptr - (UINTPTR)head))) { + return OS_ERRNO_MEMCHECK_NO_HEAD; + } + *totalSize = (((LosMemDynNode *)head)->sizeAndFlag - sizeof(LosMemDynNode)) & (~OS_MEM_NODE_USED_FLAG); + *availSize = (((LosMemDynNode *)head)->sizeAndFlag - ((UINTPTR)ptr - (UINTPTR)head)) & + (~OS_MEM_NODE_USED_FLAG); + return LOS_OK; + } + if (g_checkMemLevel == LOS_MEM_CHECK_LEVEL_LOW) { + if (ptr != (VOID *)OS_MEM_ALIGN(ptr, OS_MEM_ALIGN_SIZE)) { + return OS_ERRNO_MEMCHECK_NO_HEAD; + } + head = (VOID *)((UINTPTR)ptr - sizeof(LosMemDynNode)); + if (OS_MEM_MAGIC_VALID(((LosMemDynNode *)head)->freeNodeInfo.pstPrev)) { + *totalSize = (((LosMemDynNode *)head)->sizeAndFlag - sizeof(LosMemDynNode)) & (~OS_MEM_NODE_USED_FLAG); + *availSize = (((LosMemDynNode *)head)->sizeAndFlag - sizeof(LosMemDynNode)) & (~OS_MEM_NODE_USED_FLAG); + return LOS_OK; + } else { + return OS_ERRNO_MEMCHECK_NO_HEAD; + } + } + + return OS_ERRNO_MEMCHECK_WRONG_LEVEL; +} + +/***************************************************************************** +Function : OsMemFindNodeCtrl +Description : get a pool's memCtrl +Input : headPtr --- point to source ptr +Output : None +Return : search forward for headPtr's memCtrl or "NULL" +@attention : this func couldn't ensure the return memCtrl belongs to ptr + it just find forward the most nearly one +*******************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID *OsMemFindNodeCtrl(VOID *headPtr) +{ + UINT8 *head = (UINT8 *)headPtr; + + if (headPtr == NULL) { + return NULL; + } + + head = (UINT8 *)OS_MEM_ALIGN((VOID *)head, OS_MEM_ALIGN_SIZE); + while (!OS_MEM_MAGIC_VALID(((LosMemDynNode *)head)->freeNodeInfo.pstPrev)) { + head -= OS_MEM_NODE_DATA_SIZE; + } + return head; +} + +/***************************************************************************** + Function : LOS_MemCheckLevelSet + Description : setting g_checkMemLevel which decide the manner of memcheck + Input : level --- waht level want to set + Output : None + Return : LOS_OK --- setting succeed + OS_ERRNO_MEMCHECK_WRONG_LEVEL --- setting failed due to illegal parameter +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemCheckLevelSet(UINT8 level) +{ + if (level == LOS_MEM_CHECK_LEVEL_LOW) { + PRINTK("%s: LOS_MEM_CHECK_LEVEL_LOW \n", __FUNCTION__); + } else if (level == LOS_MEM_CHECK_LEVEL_HIGH) { + PRINTK("%s: LOS_MEM_CHECK_LEVEL_HIGH \n", __FUNCTION__); + } else if (level == LOS_MEM_CHECK_LEVEL_DISABLE) { + PRINTK("%s: LOS_MEM_CHECK_LEVEL_DISABLE \n", __FUNCTION__); + } else { + PRINTK("%s: wrong para, setting failed !! \n", __FUNCTION__); + return OS_ERRNO_MEMCHECK_WRONG_LEVEL; + } + g_checkMemLevel = level; + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT8 LOS_MemCheckLevelGet(VOID) +{ + return g_checkMemLevel; +} + +#endif /* OS_MEM_CHECK_DEBUG */ + +UINT32 OsMemSysNodeCheck(VOID *dst, VOID *src, UINT32 length, UINT8 pos) +{ +#ifdef OS_MEM_CHECK_DEBUG + UINT32 ret; + UINT32 totalSize = 0; + UINT32 availSize = 0; + + if (pos == 0) { /* if this func was called by memset */ + ret = LOS_MemNodeSizeCheck(m_aucSysMem0, dst, &totalSize, &availSize); + if ((ret == LOS_OK) && (length > availSize)) { + PRINT_ERR("---------------------------------------------\n"); + PRINT_ERR("memset: dst inode availSize is not enough" + " availSize = 0x%x length = 0x%x\n", + availSize, length); + OsBackTrace(); + PRINT_ERR("---------------------------------------------\n"); + return LOS_NOK; + } + } else if (pos == 1) { /* if this func was called by memcpy */ + ret = LOS_MemNodeSizeCheck(m_aucSysMem0, dst, &totalSize, &availSize); + if ((ret == LOS_OK) && (length > availSize)) { + PRINT_ERR("---------------------------------------------\n"); + PRINT_ERR("memcpy: dst inode availSize is not enough availSize = 0x%x length = 0x%x\n", + availSize, length); + OsBackTrace(); + PRINT_ERR("---------------------------------------------\n"); + return LOS_NOK; + } + ret = LOS_MemNodeSizeCheck(m_aucSysMem0, src, &totalSize, &availSize); + if ((ret == LOS_OK) && (length > availSize)) { + PRINT_ERR("---------------------------------------------\n"); + PRINT_ERR("memcpy: src inode availSize is not enough availSize = 0x%x length = 0x%x\n", + availSize, length); + OsBackTrace(); + PRINT_ERR("---------------------------------------------\n"); + return LOS_NOK; + } + } +#endif + return LOS_OK; +} + +#ifdef LOSCFG_MEM_MUL_MODULE +INLINE UINT32 OsMemModCheck(UINT32 module) +{ + if (module > MEM_MODULE_MAX) { + PRINT_ERR("error module ID input!\n"); + return LOS_NOK; + } + return LOS_OK; +} + +INLINE VOID *OsMemPtrToNode(VOID *ptr) +{ + UINT32 gapSize; + LosMemDynNode *node = NULL; + gapSize = *((UINT32 *)((UINTPTR)ptr - OS_MEM_NODE_DATA_SIZE)); + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + ptr = (VOID *)((UINTPTR)ptr - gapSize); + } + + return (VOID *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); +} + +INLINE UINT32 OsMemNodeSizeGet(VOID *ptr) +{ + LosMemDynNode *node; + node = (LosMemDynNode *)OsMemPtrToNode(ptr); + + return ((node->sizeAndFlag) & (~OS_MEM_NODE_USED_FLAG)); +} + +VOID *LOS_MemMalloc(VOID *pool, UINT32 size, UINT32 module) +{ + UINTPTR intSave; + VOID *ptr = NULL; + if (OsMemModCheck(module) == LOS_NOK) { + return NULL; + } + ptr = LOS_MemAlloc(pool, size); + if (ptr != NULL) { + intSave = LOS_IntLock(); + g_memInfo[module] += OsMemNodeSizeGet(ptr); + OS_MEM_MODID_SET(OsMemPtrToNode(ptr), module); + LOS_IntRestore(intSave); + } + return ptr; +} + +VOID *LOS_MemMallocAlign(VOID *pool, UINT32 size, UINT32 boundary, UINT32 module) +{ + UINTPTR intSave; + VOID *ptr = NULL; + if (OsMemModCheck(module) == LOS_NOK) { + return NULL; + } + ptr = LOS_MemAllocAlign(pool, size, boundary); + if (ptr != NULL) { + intSave = LOS_IntLock(); + g_memInfo[module] += OsMemNodeSizeGet(ptr); + OS_MEM_MODID_SET(OsMemPtrToNode(ptr), module); + LOS_IntRestore(intSave); + } + return ptr; +} + +UINT32 LOS_MemMfree(VOID *pool, VOID *ptr, UINT32 module) +{ + UINTPTR intSave; + UINT32 ret; + UINT32 size; + + if ((OsMemModCheck(module) == LOS_NOK) || (ptr == NULL)) { + return LOS_NOK; + } + + size = OsMemNodeSizeGet(ptr); + + if (module != OS_MEM_MODID_GET(OsMemPtrToNode(ptr))) { + PRINT_ERR("node[%p] alloced in module %d, but free in module %d\n node's taskID: 0x%x\n", + ptr, OS_MEM_MODID_GET(OsMemPtrToNode(ptr)), module, OS_MEM_TASKID_GET(OsMemPtrToNode(ptr))); + } + + ret = LOS_MemFree(pool, ptr); + if (ret == LOS_OK) { + intSave = LOS_IntLock(); + g_memInfo[module] -= size; + LOS_IntRestore(intSave); + } + return ret; +} + +VOID *LOS_MemMrealloc(VOID *pool, VOID *ptr, UINT32 size, UINT32 module) +{ + VOID *newPtr = NULL; + UINT32 oldSize; + UINTPTR intSave; + + if (OsMemModCheck(module) == LOS_NOK) { + return NULL; + } + + if (ptr == NULL) { + return LOS_MemMalloc(pool, size, module); + } + + if (module != OS_MEM_MODID_GET(OsMemPtrToNode(ptr))) { + PRINT_ERR("a node[%p] alloced in module %d, but realloc in module %d\n node's taskID: %d\n", + ptr, OS_MEM_MODID_GET(OsMemPtrToNode(ptr)), module, OS_MEM_TASKID_GET(OsMemPtrToNode(ptr))); + } + + if (size == 0) { + if (LOS_MemMfree(pool, ptr, module) != LOS_OK) { + PRINT_ERR("Mem Free Failed!\n"); + } + return NULL; + } + + oldSize = OsMemNodeSizeGet(ptr); + newPtr = LOS_MemRealloc(pool, ptr, size); + if (newPtr != NULL) { + intSave = LOS_IntLock(); + g_memInfo[module] += OsMemNodeSizeGet(newPtr); + g_memInfo[module] -= oldSize; + OS_MEM_MODID_SET(OsMemPtrToNode(newPtr), module); + LOS_IntRestore(intSave); + } + return newPtr; +} + +UINT32 LOS_MemMusedGet(UINT32 module) +{ + if (OsMemModCheck(module) == LOS_NOK) { + return LOS_NOK; + } + return g_memInfo[module]; +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/mem/bestfit/los_memstat.c b/kernel/base/mem/bestfit/los_memstat.c new file mode 100755 index 00000000..af1ff74a --- /dev/null +++ b/kernel/base/mem/bestfit/los_memstat.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_memstat_pri.h" +#include "los_task_pri.h" +#include "los_config.h" + +typedef struct { + UINT32 memUsed; +} TskMemUsedInfo; + +LITE_OS_SEC_BSS_MINOR TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID) +{ + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + if (OS_INT_ACTIVE) { + return; + } + g_tskMemUsedInfo[taskID].memUsed += usedSize; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID) +{ + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + if (OS_INT_ACTIVE) { + return; + } + + if (g_tskMemUsedInfo[taskID].memUsed < usedSize) { + PRINT_INFO("mem used of current task '%s':0x%x, decrease size:0x%x\n", + g_losTask.runTask->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize); + return; + } + + g_tskMemUsedInfo[taskID].memUsed -= usedSize; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskId) +{ + if ((UINT32)taskId > LOSCFG_BASE_CORE_TSK_LIMIT) { + return LOS_NOK; + } + + return g_tskMemUsedInfo[(UINT32)taskId].memUsed; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) +{ + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + if (g_tskMemUsedInfo[taskID].memUsed != 0) { + PRINT_INFO("mem used of task '%s' is:0x%x, not zero when task being deleted\n", + g_losTask.runTask->taskName, g_tskMemUsedInfo[taskID].memUsed); + } + g_tskMemUsedInfo[taskID].memUsed = 0; + return; +} diff --git a/kernel/base/mem/bestfit/los_multipledlinkhead.c b/kernel/base/mem/bestfit/los_multipledlinkhead.c new file mode 100755 index 00000000..7c03c77f --- /dev/null +++ b/kernel/base/mem/bestfit/los_multipledlinkhead.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_multipledlinkhead_pri.h" +#include "los_compiler.h" + +#define OS_BITS_PER_BYTE 8 +STATIC_INLINE UINT32 OsLog2(UINT32 size) +{ + return size ? ((sizeof(size) * OS_BITS_PER_BYTE) - CLZ(size) - 1) : 0; +} + +LITE_OS_SEC_TEXT_INIT VOID OsDLnkInitMultiHead(VOID *headAddr) +{ + LosMultipleDlinkHead *head = (LosMultipleDlinkHead *)headAddr; + LOS_DL_LIST *listHead = head->listHead; + UINT32 idx; + + for (idx = 0; idx < OS_MULTI_DLNK_NUM; ++idx, ++listHead) { + LOS_ListInit(listHead); + } +} + +LITE_OS_SEC_TEXT_MINOR LOS_DL_LIST *OsDLnkMultiHead(VOID *headAddr, UINT32 size) +{ + LosMultipleDlinkHead *head = (LosMultipleDlinkHead *)headAddr; + UINT32 idx = OsLog2(size); + + if (idx > OS_MAX_MULTI_DLNK_LOG2) { + return (LOS_DL_LIST *)NULL; + } + + if (idx <= OS_MIN_MULTI_DLNK_LOG2) { + idx = OS_MIN_MULTI_DLNK_LOG2; + } + + return head->listHead + (idx - OS_MIN_MULTI_DLNK_LOG2); +} diff --git a/kernel/base/mem/common/los_slab.c b/kernel/base/mem/common/los_slab.c new file mode 100755 index 00000000..6ee33c95 --- /dev/null +++ b/kernel/base/mem/common/los_slab.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "securec.h" +#include "los_slab_pri.h" +#include "los_heap_pri.h" + +#define LOW_BITS_MASK 31 +#define NUM_BITS_IN_ONE_BYTE 32 +#define NUMBITS_TO_NUMBYTES(numBits) (((numBits) + LOW_BITS_MASK) / 8) + +VOID OsAtomicBitsetInit(struct AtomicBitset *set, UINT32 numBits) +{ + set->numBits = numBits; + // Ignore the return code when matching CSEC rule 6.6(2). + (VOID)memset_s(set->words, NUMBITS_TO_NUMBYTES(numBits), 0, NUMBITS_TO_NUMBYTES(numBits)); + // mark all high bits so that OsAtomicBitsetFindClearAndSet() is simpler + if (numBits & LOW_BITS_MASK) { + set->words[numBits / NUM_BITS_IN_ONE_BYTE] = + ((UINT32)((INT32) - 1LL)) << (numBits & LOW_BITS_MASK); + } +} + +inline UINT32 OsAtomicBitsetGetNumBits(const struct AtomicBitset *set) +{ + return set->numBits; +} + +/************************************************************************** + Function : OsAtomicBitsetGetBit + Description : get the specified bit in set + Input : set --- pointer to the bitset + num --- the num to fetch + Output : None + Return : LOS_OK on success or error code on failure +**************************************************************************/ +BOOL OsAtomicBitsetGetBit(const struct AtomicBitset *set, UINT32 num) +{ + /* any value is as good as the next */ + if (num >= set->numBits) { + return FALSE; + } + return !!((set->words[num / NUM_BITS_IN_ONE_BYTE]) & (1UL << (num & LOW_BITS_MASK))); +} + +/************************************************************************** + Function : OsAtomicBitsetClearBit + Description : clear the specified bit in set + Input : set --- pointer to the bitset + num --- the num to clear + Output : None + Return : None +**************************************************************************/ +VOID OsAtomicBitsetClearBit(struct AtomicBitset *set, UINT32 num) +{ + UINT32 *wordPtr = set->words + (num / NUM_BITS_IN_ONE_BYTE); + + if (num >= set->numBits) { + return; + } + (*wordPtr) &= ~(1UL << (num & LOW_BITS_MASK)); +} + +/* find from the high bit to high bit return the address of the first available bit */ +INT32 OsAtomicBitsetFindClearAndSet(struct AtomicBitset *set) +{ + UINT32 idx; + UINT32 numWords = (set->numBits + LOW_BITS_MASK) / NUM_BITS_IN_ONE_BYTE; + UINT32 *wordPtr = set->words; + UINT32 tmpWord; + INT32 count = 0; + + for (idx = 0; idx < numWords; idx++, wordPtr++) { + if (*wordPtr == 0xFFFFFFFF) { + continue; + } + + tmpWord = ~(*wordPtr); + + while (tmpWord) { + tmpWord = tmpWord >> 1UL; + count++; + } + + *wordPtr |= (1UL << (count - 1)); + + return (INT32)(idx * NUM_BITS_IN_ONE_BYTE + count - 1); + } + + return -1; +} + +/* change the order of the output idx of OsAtomicBitsetFindClearAndSet to order of natural numbers */ +INT32 OsAtomicBitsetIdxChgToNatural(struct AtomicBitset *bitset, INT32 index) +{ + UINT32 ret; + UINT32 bit; + if (index < 0) { + return index; + } + bit = LOW_BITS_MASK + (index & ~LOW_BITS_MASK); + if (bit > bitset->numBits - 1) { + bit = bitset->numBits - 1; + } + ret = bit - (index & LOW_BITS_MASK); + return ret; +} + +/************************************************************************** + Function : OsAtomicBitsetEmpty + Description : check whether bitset is empty + Input : bitset --- pointer to the bitset + Output : None + Return : LOS_OK on success or error code on failure +**************************************************************************/ +BOOL OsAtomicBitsetEmpty(struct AtomicBitset *bitset) +{ + UINT32 idx = 0; + for (idx = 0; idx < (bitset->numBits / NUM_BITS_IN_ONE_BYTE);) { + if (bitset->words[idx] != 0) { + return FALSE; + } + idx++; + } + if (bitset->numBits & LOW_BITS_MASK) { + if (bitset->words[idx] & ~(0xFFFFFFFF << (bitset->numBits & LOW_BITS_MASK))) { + return FALSE; + } + } + return TRUE; +} + +/************************************************************************** + Function : OsSlabAllocatorNew + Description : create a new allocator + Input : pool --- pointer to the pool + itemSz --- alloc size + itemAlign --- aligned size + numItems --- item num + Output : None + Return : the pointer to a new allocator +**************************************************************************/ +OsSlabAllocator* OsSlabAllocatorNew(VOID *pool, UINT32 itemSz, UINT32 itemAlign, UINT32 numItems) +{ + OsSlabAllocator *allocator = NULL; + UINT32 bitSetSz; + UINT32 dataSz; + UINT32 itemSize; + + /* calculate size */ + bitSetSz = ATOMIC_BITSET_SZ(numItems); + + bitSetSz = (bitSetSz + itemAlign - 1) & (~(itemAlign - 1)); + itemSize = (itemSz + itemAlign - 1) & (~(itemAlign - 1)); + dataSz = itemSize * numItems; + + allocator = (OsSlabAllocator*)LOS_HeapAlloc(pool, sizeof(OsSlabAllocator) + bitSetSz + dataSz); + + if (allocator != NULL) { + allocator->itemSz = itemSize; + + allocator->bitset = (struct AtomicBitset *)(VOID *)((UINT8*)allocator + sizeof(OsSlabAllocator)); + allocator->dataChunks = ((UINT8*)allocator->bitset) + bitSetSz; + OsAtomicBitsetInit(allocator->bitset, numItems); + } + + return allocator; +} + + +/************************************************************************** + Function : OsSlabAllocatorDestroy + Description : free the specified allocator + Input : pool --- pointer to the pool + allocator --- pointer to the allocator + Output : None + Return : None +**************************************************************************/ +VOID OsSlabAllocatorDestroy(VOID *pool, OsSlabAllocator *allocator) +{ + (VOID)LOS_HeapFree(pool, allocator); +} + +/************************************************************************** + Function : OsSlabAllocatorAlloc + Description : alloc one bit from the specified allocator + Input : allocator --- pointer to the allocator + Output : None + Return : NULL on failure or one bit from the specified allocator +**************************************************************************/ +VOID* OsSlabAllocatorAlloc(OsSlabAllocator *allocator) +{ + INT32 itemIdx = OsAtomicBitsetFindClearAndSet(allocator->bitset); + if (itemIdx < 0) { + return NULL; + } + + return allocator->dataChunks + allocator->itemSz * itemIdx; +} + +/************************************************************************** + Function : OsSlabAllocatorFree + Description : free the specified bit in the specified allocator + Input : allocator --- pointer to the allocator + ptr --- pointer to the mem chunk to be freed + Output : None + Return : TRUE or FALSE +**************************************************************************/ +BOOL OsSlabAllocatorFree(OsSlabAllocator *allocator, VOID* ptr) +{ + UINT8 *ptrTmp = (UINT8*)ptr; + UINT32 itemOffset = ptrTmp - allocator->dataChunks; + UINT32 itemIdx = itemOffset / allocator->itemSz; + + // check for invalid inputs + if ((itemOffset % allocator->itemSz) || (itemIdx >= OsAtomicBitsetGetNumBits(allocator->bitset)) || + !(OsAtomicBitsetGetBit(allocator->bitset, itemIdx))) { + return FALSE; + } + + OsAtomicBitsetClearBit(allocator->bitset, itemIdx); + return TRUE; +} + +/************************************************************************** + Function : OsSlabAllocatorGetNth + Description : get the specified data chunk from the allocator + Input : allocator --- pointer to the allocator + idx --- chunk num + Output : None + Return : NULL on failure or specified data chunk on success +**************************************************************************/ +VOID* OsSlabAllocatorGetNth(OsSlabAllocator *allocator, UINT32 idx) +{ + if (!OsAtomicBitsetGetBit(allocator->bitset, idx)) { + return NULL; + } + + return allocator->dataChunks + allocator->itemSz * idx; +} + +/************************************************************************** + Function : OsSlabAllocatorGetIdxP + Description : get the specified dataChunk from the specified allocator + Input : allocator --- pointer to the allocator + idx --- chunk num + Output : None + Return : the specified data Chunk from the specified allocator +**************************************************************************/ +VOID* OsSlabAllocatorGetIdxP(OsSlabAllocator *allocator, UINT32 idx) +{ + return allocator->dataChunks + allocator->itemSz * idx; +} + +/************************************************************************** + Function : OsSlabAllocatorGetIndex + Description : get item index from the specified allocator + Input : allocator --- pointer to the allocator + ptr --- pointer to the mem chunk to get index + Output : None + Return : the item index from the specified allocator +**************************************************************************/ +UINT32 OsSlabAllocatorGetIndex(OsSlabAllocator *allocator, VOID* ptr) +{ + UINT8 *ptrTmp = (UINT8*)ptr; + UINT32 itemOffset = ptrTmp - allocator->dataChunks; + UINT32 itemIdx = itemOffset / allocator->itemSz; + + if ((itemOffset % allocator->itemSz) || + (itemIdx >= OsAtomicBitsetGetNumBits(allocator->bitset)) || + !(OsAtomicBitsetGetBit(allocator->bitset, itemIdx))) { + return (UINT32)(-1); + } + + return itemIdx; +} + +/************************************************************************** + Function : OsSlabAllocatorGetNumItems + Description : get num bits of the specified allocator + Input : allocator --- pointer to the allocator + Output : None + Return : LOS_OK on success or error code on failure +**************************************************************************/ +UINT32 OsSlabAllocatorGetNumItems(OsSlabAllocator *allocator) +{ + return OsAtomicBitsetGetNumBits(allocator->bitset); +} + +/************************************************************************** + Function : OsSlabAllocatorEmpty + Description : check whether the allocator is empty + Input : allocator --- pointer to the allocator + Output : None + Return : LOS_OK on success or error code on failure +**************************************************************************/ +BOOL OsSlabAllocatorEmpty(OsSlabAllocator *allocator) +{ + return OsAtomicBitsetEmpty(allocator->bitset); +} + +/************************************************************************** + Function : OsSlabAllocatorGetUsedItemCnt + Description : get used num of the specified allocator + Input : allocator --- pointer to the allocator + Output : None + Return : used num of the specifiedd allocator +**************************************************************************/ +UINT32 OsSlabAllocatorGetUsedItemCnt(OsSlabAllocator *allocator) +{ + UINT32 used; + UINT32 idx; + struct AtomicBitset *bitset = allocator->bitset; + for (used = 0, idx = 0; idx < bitset->numBits; idx++) { + if (OsAtomicBitsetGetBit(bitset, idx)) { + used++; + } + } + return used; +} + +/************************************************************************** + Function : OsSlabAllocatorGetSlabInfo + Description : get slab info from the specified allocator + Input : allocator --- pointer to the allocator + Output : pitemSz --- item size + itemCnt --- item count + curUsage --- current usage + Return : None +**************************************************************************/ +VOID OsSlabAllocatorGetSlabInfo(OsSlabAllocator *allocator, UINT32 *pitemSz, UINT32 *itemCnt, UINT32 *curUsage) +{ + *pitemSz = allocator->itemSz; + *itemCnt = OsAtomicBitsetGetNumBits(allocator->bitset); + *curUsage = OsSlabAllocatorGetUsedItemCnt(allocator); +} + +/************************************************************************** + Function : OsSlabAllocatorCheck + Description : check whether ptr is in allocator + Input : allocator --- pointer to the allocator + ptr --- pointer to the mem chunk to check + Output : None + Return : TRUE or FALSE +**************************************************************************/ +BOOL OsSlabAllocatorCheck(OsSlabAllocator *allocator, VOID* ptr) +{ + UINT8 *ptrTmp = (UINT8*)ptr; + UINT32 itemOffset = ptrTmp - allocator->dataChunks; + UINT32 itemIdx = itemOffset / allocator->itemSz; + + // check for invalid inputs + if ((itemOffset % allocator->itemSz) || (itemIdx >= OsAtomicBitsetGetNumBits(allocator->bitset)) || + !(OsAtomicBitsetGetBit(allocator->bitset, itemIdx))) { + return FALSE; + } + + return TRUE; +} + diff --git a/kernel/base/mem/common/los_slabmem.c b/kernel/base/mem/common/los_slabmem.c new file mode 100755 index 00000000..c37e9b91 --- /dev/null +++ b/kernel/base/mem/common/los_slabmem.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +#define _LOS_SLAB_MEM_C_ +#include +#include +#include + +VOID *OsSlabBlockHeadFill(OsSlabBlockNode *slabNode, UINT32 blkSz) +{ + OS_SLAB_BLOCK_MAGIC_SET(slabNode); + OS_SLAB_BLOCK_SIZE_SET(slabNode, blkSz); + OS_SLAB_BLOCK_ID_SET(slabNode, 0); // now undefine how to use ID + return (VOID *)(slabNode + 1); +} + +/***************************************************************************** + Function : OsSlabMemInit + Description : To initialize the slab memory management + Input : None + Output : None + Return : TRUE --- initialize OK, FALSE --- initialize false +*****************************************************************************/ +BOOL OsSlabMemInit(VOID *pool) +{ + struct LosSlabControlHeader *slabMemHead = OsSlabCtrlHdrGet(pool); + UINT32 idx = 0; + UINT32 tmp = 0; + UINT32 blkSz = 0; + UINT32 blkCnt = 0; + + for (idx = 0; idx < SLAB_MEM_COUNT; idx++) { + blkSz = (SLAB_MEM_CALSS_STEP_SIZE << idx); + blkCnt = SLAB_MEM_ALLOCATOR_SIZE / blkSz; + slabMemHead->slabClass[idx].blkSz = blkSz; + slabMemHead->slabClass[idx].blkCnt = blkCnt; + slabMemHead->slabClass[idx].blkUsedCnt = 0; + if (slabMemHead->slabClass[idx].alloc != NULL) { + PRINT_WARN("SlabMemAllocator[%d] inited before\n", idx); + tmp++; + } else { + slabMemHead->slabClass[idx].alloc = + OsSlabAllocatorNew(pool, blkSz + sizeof(OsSlabBlockNode), (UINT32)sizeof(VOID *), blkCnt); + } + } + + return ((tmp == 0) ? TRUE : FALSE); +} + +/***************************************************************************** + Function : OsSlabMemAlloc + Description : To alloc memory block + Input : pool --- pointer to the memory pool + size --- size of the memory we want to alloc + Output : None + Return : pointer :the address of the memory we alloced +*****************************************************************************/ +VOID *OsSlabMemAlloc(VOID *pool, UINT32 size) +{ + VOID *ret = NULL; + UINTPTR intSave; + struct LosSlabControlHeader *slabMem = OsSlabCtrlHdrGet(pool); + OsSlabMem *slabAlloc = NULL; + UINT32 idx; + + if (size > (SLAB_MEM_CALSS_STEP_SIZE << (SLAB_MEM_COUNT - 1))) { + return NULL; + } + + for (idx = 0; idx < SLAB_MEM_COUNT; idx++) { + if (size <= slabMem->slabClass[idx].blkSz) { + intSave = LOS_IntLock(); + + if (slabMem->slabClass[idx].blkUsedCnt >= slabMem->slabClass[idx].blkCnt) { + LOS_IntRestore(intSave); + return NULL; + } + + if (slabMem->slabClass[idx].alloc == NULL) { + LOS_IntRestore(intSave); + return NULL; + } + + slabAlloc = &(slabMem->slabClass[idx]); + ret = OsSlabAllocatorAlloc(slabAlloc->alloc); + if (ret != NULL) { + /* alloc success */ + ret = OsSlabBlockHeadFill((OsSlabBlockNode *)ret, slabMem->slabClass[idx].blkSz); + slabMem->slabClass[idx].blkUsedCnt++; + } + + LOS_IntRestore(intSave); + return ret; + } + } + + return NULL; +} + +/***************************************************************************** + Function : OsSlabMemFree + Description : To free the memory block + Input : pool --- Pointer to the memory pool that contains the memory block to be allocated + ptr --- the pointer of heap memory we want to free + Output : None + Return : TRUE:success FALSE:error +*****************************************************************************/ +BOOL OsSlabMemFree(VOID *pool, VOID* ptr) +{ + UINTPTR intSave; + struct LosSlabControlHeader *slabMem = OsSlabCtrlHdrGet(pool); + BOOL ret = FALSE; + OsSlabMem *slabAlloc = NULL; + UINT32 idx; + OsSlabBlockNode *slabNode = OS_SLAB_BLOCK_HEAD_GET(ptr); + + if (!OS_ALLOC_FROM_SLAB_CHECK(slabNode)) { + return FALSE; + } + for (idx = 0; idx < SLAB_MEM_COUNT; idx++) { + if (slabMem->slabClass[idx].blkSz >= OS_SLAB_BLOCK_SIZE_GET(slabNode)) { + intSave = LOS_IntLock(); + + slabAlloc = &(slabMem->slabClass[idx]); + if (TRUE == OsSlabAllocatorFree(slabAlloc->alloc, slabNode)) { + ret = TRUE; + slabMem->slabClass[idx].blkUsedCnt--; + } + + LOS_IntRestore(intSave); + return ret; + } + } + return FALSE; +} + +/***************************************************************************** + Function : OsSlabMemDeinit + Description : deinitialize the slab memory ,set back to the original status + Input : pool --- Pointer to the memory pool + Output : None + Return : None +*****************************************************************************/ +VOID OsSlabMemDeinit(VOID *pool) +{ + UINT32 idx; + struct LosSlabControlHeader *slabMem = NULL; + OsSlabMem *slabAlloc = NULL; + UINT32 blkSz; + UINT32 blkCnt; + + if (pool == NULL) { + return ; + } + slabMem = OsSlabCtrlHdrGet(pool); + + for (idx = 0; idx < SLAB_MEM_COUNT; idx++) { + blkSz = (SLAB_MEM_CALSS_STEP_SIZE << idx); + blkCnt = SLAB_MEM_ALLOCATOR_SIZE / blkSz; + slabMem->slabClass[idx].blkSz = blkSz; + slabMem->slabClass[idx].blkCnt = blkCnt; + if (slabMem->slabClass[idx].alloc != NULL) { + slabAlloc = &(slabMem->slabClass[idx]); + OsSlabAllocatorDestroy(pool, slabAlloc->alloc); + slabMem->slabClass[idx].alloc = NULL; + } + } + return ; +} + +/************************************************************************** + Function : OsSlabMemCheck + Description : check slab memory + Input : pool --- pointer to the memory pool + ptr --- pointer to the memory chunk + Output : None + Return : LOS_OK on success or error code on failure +**************************************************************************/ +UINT32 OsSlabMemCheck(VOID *pool, VOID* ptr) +{ + UINTPTR intSave; + struct LosSlabControlHeader *slabMem = OsSlabCtrlHdrGet(pool); + UINT32 retBlkSz = (UINT32)-1; + OsSlabMem *slabAlloc = NULL; + UINT32 idx; + OsSlabBlockNode *slabNode = OS_SLAB_BLOCK_HEAD_GET(ptr); + + if ((!OS_ALLOC_FROM_SLAB_CHECK(slabNode)) || + slabMem->slabClass[SLAB_MEM_COUNT - 1].blkSz > (OS_SLAB_BLOCK_SIZE_GET(slabNode))) { + return retBlkSz; + } + + intSave = LOS_IntLock(); + for (idx = 0; idx < SLAB_MEM_COUNT; idx++) { + slabAlloc = &(slabMem->slabClass[idx]); + if (OsSlabAllocatorCheck(slabAlloc->alloc, slabNode) == TRUE) { + retBlkSz = slabMem->slabClass[idx].blkSz; + } + } + LOS_IntRestore(intSave); + + return retBlkSz; +} + +/************************************************************************** + Function : OsSlabStatisticsGet + Description : collect slab statistics + Input : pool --- pointer to the memory pool + Output : status --- memory pool statistics + Return : LOS_OK on success or error code on failure +**************************************************************************/ +UINT32 OsSlabStatisticsGet(VOID *pool, LosSlabStatus *status) +{ + struct LosSlabControlHeader *slabMem = NULL; + OsSlabMem *slabAlloc = NULL; + UINT32 itemSz = 0; + UINT32 itemCnt = 0; + UINT32 curUsage = 0; + UINT32 totalUsage = 0; + UINT32 totalMem = 0; + UINT32 totalAllocCount = 0; + UINT32 totalFreeCount = 0; + UINT32 idx; + + if ((status == NULL) || (pool == NULL)) { + return LOS_NOK; + } + slabMem = OsSlabCtrlHdrGet(pool); + + for (idx = 0; idx < SLAB_MEM_COUNT; idx++) { + slabAlloc = &(slabMem->slabClass[idx]); + + OsSlabAllocatorGetSlabInfo(slabAlloc->alloc, &itemSz, &itemCnt, &curUsage); + totalUsage += (curUsage * itemSz); + totalMem += (itemCnt * itemSz); + totalAllocCount += slabMem->slabClass[idx].blkUsedCnt; + totalFreeCount += slabMem->slabClass[idx].blkCnt - slabMem->slabClass[idx].blkUsedCnt; + } + + if (totalMem < totalUsage) { + return LOS_NOK; + } + + status->totalSize = totalMem; + status->usedSize = totalUsage; + status->freeSize = status->totalSize - status->usedSize; + status->allocCount = totalAllocCount; + status->freeCount = totalFreeCount; + return LOS_OK; +} + +/************************************************************************** + Function : OsSlabGetMaxFreeBlkSize + Description : get max free block size + Input : pool --- pointer to the memory pool + Output : None + Return : max free block size +**************************************************************************/ +UINT32 OsSlabGetMaxFreeBlkSize(VOID *pool) +{ + struct LosSlabControlHeader *slabMem = OsSlabCtrlHdrGet(pool); + OsSlabMem *slabAlloc = NULL; + UINT32 itemSz = 0; + UINT32 itemCnt = 0; + UINT32 curUsage = 0; + int idx; + + for (idx = SLAB_MEM_COUNT - 1; idx >= 0; idx--) { + slabAlloc = &(slabMem->slabClass[idx]); + if (slabAlloc->alloc) { + OsSlabAllocatorGetSlabInfo(slabAlloc->alloc, &itemSz, &itemCnt, &curUsage); + if (curUsage != itemCnt) { + return itemSz; + } + } + } + + return 0; +} diff --git a/kernel/base/misc/los_misc.c b/kernel/base/misc/los_misc.c new file mode 100755 index 00000000..8e53ac5d --- /dev/null +++ b/kernel/base/misc/los_misc.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_base_pri.h" +#include "los_sys_pri.h" +#include "los_task_pri.h" +#include "los_hwi.h" + +LITE_OS_SEC_TEXT UINT32 LOS_Align(UINT32 addr, UINT32 boundary) +{ + if ((addr + (boundary - 1)) > addr) { + return (addr + (boundary - 1)) & ~(boundary - 1); + } else { + return addr & ~(boundary - 1); + } +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 mSecs) +{ + UINT32 interval; + + if (OS_INT_ACTIVE) { + return; + } + + if (mSecs == 0) { + interval = 0; + } else { + interval = LOS_MS2Tick(mSecs); + if (interval == 0) { + interval = 1; + } + } + + (VOID)LOS_TaskDelay(interval); +} diff --git a/kernel/base/om/los_err.c b/kernel/base/om/los_err.c new file mode 100755 index 00000000..3fdfa928 --- /dev/null +++ b/kernel/base/om/los_err.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_err_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +LITE_OS_SEC_BSS UserErrFunc g_userErrFunc; + +/***************************************************************************** +Function : LOS_ErrHandle +Description : Error handle +Input : fileName -- file name + lineNo -- error line number + errorNo -- user defined error number + paraLen -- length of pPara + para -- user description of error +Output : None +Return : LOS_OK always +Other : None +*****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, + UINT32 lineNo, + UINT32 errorNo, + UINT32 paraLen, + VOID *para) +{ + + if (g_userErrFunc.pfnHook != NULL) { + g_userErrFunc.pfnHook(fileName, lineNo, errorNo, paraLen, para); + } + + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/extended/BUILD.gn b/kernel/extended/BUILD.gn new file mode 100755 index 00000000..a01fbb3c --- /dev/null +++ b/kernel/extended/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020, 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("cpup") { + + sources = [ + "cpup/los_cpup.c", + "cppsupport/los_cppsupport.c" + ] + + include_dirs = [ + "include" + ] +} \ No newline at end of file diff --git a/kernel/extended/cppsupport/los_cppsupport.c b/kernel/extended/cppsupport/los_cppsupport.c new file mode 100755 index 00000000..e0901eb6 --- /dev/null +++ b/kernel/extended/cppsupport/los_cppsupport.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_cppsupport.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef VOID (*InitFunc)(VOID); + +INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd) +{ + UINTPTR *start; + InitFunc initFunc = NULL; + + for (start = (UINTPTR *)initArrayStart; start < (UINTPTR *)initArrayEnd; start++){ + initFunc = (InitFunc)(*start); + initFunc(); + } + + return 0; +} + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/extended/cpup/los_cpup.c b/kernel/extended/cpup/los_cpup.c new file mode 100755 index 00000000..71a66f62 --- /dev/null +++ b/kernel/extended/cpup/los_cpup.c @@ -0,0 +1,541 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "string.h" +#include "securec.h" +#include "los_cpup_pri.h" +#include "los_task_pri.h" +#include "los_memory_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_BASE_CORE_CPUP == YES) + +/** + * @ingroup los_cpup + * CPU usage-type macro: used for tasks. + */ +#define OS_THREAD_TYPE_TASK 0 + +/** + * @ingroup los_cpup + * CPU usage-type macro: used for hardware interrupts. + */ +#define OS_THREAD_TYPE_HWI 1 + +LITE_OS_SEC_BSS UINT16 g_cpupInitFlg = 0; +LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL; +LITE_OS_SEC_BSS UINT64 g_lastRecordTime; +LITE_OS_SEC_BSS UINT16 g_hisPos; /* taskID; + g_cpup[taskID].cpupID = taskID; + g_cpup[taskID].startTime = OsGetCpuCycle(); + + return; +} +/***************************************************************************** +Function : OsTskCycleEnd +Description: quit task and get cycle count +Input : None +Return : None +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEnd(VOID) +{ + UINT32 taskID; + UINT64 cpuCycle; + + if (g_cpupInitFlg == 0) { + return; + } + + taskID = g_losTask.runTask->taskID; + + if (g_cpup[taskID].startTime == 0) { + return; + } + + cpuCycle = OsGetCpuCycle(); + + if (cpuCycle < g_cpup[taskID].startTime) { + cpuCycle += g_cyclesPerTick; + } + + g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime); + g_cpup[taskID].startTime = 0; + + return; +} +/***************************************************************************** +Function : OsTskCycleEndStart +Description: start task to get cycles count in current task ending +Input : None +Return : None +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEndStart(VOID) +{ + UINT32 taskID; + UINT64 cpuCycle; + UINT16 loopNum; + + if (g_cpupInitFlg == 0) { + return; + } + + taskID = g_losTask.runTask->taskID; + cpuCycle = OsGetCpuCycle(); + + if (g_cpup[taskID].startTime != 0) { + if (cpuCycle < g_cpup[taskID].startTime) { + cpuCycle += g_cyclesPerTick; + } + + g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime); + g_cpup[taskID].startTime = 0; + } + + taskID = g_losTask.newTask->taskID; + g_cpup[taskID].cpupID = taskID; + g_cpup[taskID].startTime = cpuCycle; + + if ((cpuCycle - g_lastRecordTime) > OS_CPUP_RECORD_PERIOD) { + g_lastRecordTime = cpuCycle; + + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + g_cpup[loopNum].historyTime[g_hisPos] = g_cpup[loopNum].allTime; + } + + if (g_hisPos == (OS_CPUP_HISTORY_RECORD_NUM - 1)) { + g_hisPos = 0; + } else { + g_hisPos++; + } + } + + return; +} + +LITE_OS_SEC_TEXT_MINOR static inline UINT16 OsGetPrePos(UINT16 curPos) +{ + return (curPos == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : (curPos - 1); +} + +LITE_OS_SEC_TEXT_MINOR static VOID OsGetPositions(UINT16 mode, UINT16* curPosAddr, UINT16* prePosAddr) +{ + UINT16 curPos; + UINT16 prePos = 0; + + curPos = g_hisPos; + + if (mode == CPUP_IN_1S) { + curPos = OsGetPrePos(curPos); + prePos = OsGetPrePos(curPos); + } else if (mode == CPUP_LESS_THAN_1S) { + curPos = OsGetPrePos(curPos); + } + + *curPosAddr = curPos; + *prePosAddr = prePos; +} + +/***************************************************************************** +Function : LOS_SysCpuUsage +Description: get current CPU usage +Input : None +Return : cpupRet:current CPU usage +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysCpuUsage(VOID) +{ + UINT64 cpuCycleAll = 0; + UINT32 cpupRet = 0; + UINT16 loopNum; + UINTPTR intSave; + + if (g_cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + // get end time of current task + intSave = LOS_IntLock(); + OsTskCycleEnd(); + + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + cpuCycleAll += g_cpup[loopNum].allTime; + } + + if (cpuCycleAll) { + cpupRet = LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION * + g_cpup[g_idleTaskID].allTime) / cpuCycleAll); + } + + OsTskCycleStart(); + LOS_IntRestore(intSave); + + return cpupRet; +} + +/***************************************************************************** +Function : LOS_HistorySysCpuUsage +Description: get CPU usage history +Input : mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s +Return : cpupRet:CPU usage history +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode) +{ + UINT64 cpuCycleAll = 0; + UINT64 idleCycleAll = 0; + UINT32 cpupRet = 0; + UINT16 loopNum; + UINT16 curPos; + UINT16 prePos = 0; + UINTPTR intSave; + + if (g_cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + // get end time of current task + intSave = LOS_IntLock(); + OsTskCycleEnd(); + + OsGetPositions(mode, &curPos, &prePos); + + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + if (mode == CPUP_IN_1S) { + cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos]; + } else { + cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos]; + } + } + + if (mode == CPUP_IN_1S) { + idleCycleAll += g_cpup[g_idleTaskID].historyTime[curPos] - + g_cpup[g_idleTaskID].historyTime[prePos]; + } else { + idleCycleAll += g_cpup[g_idleTaskID].allTime - g_cpup[g_idleTaskID].historyTime[curPos]; + } + + if (cpuCycleAll) { + cpupRet = (LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION * idleCycleAll) / cpuCycleAll)); + } + + OsTskCycleStart(); + LOS_IntRestore(intSave); + + return cpupRet; +} + +/***************************************************************************** +Function : LOS_TaskCpuUsage +Description: get CPU usage of certain task +Input : taskID : task ID +Return : cpupRet:CPU usage of certain task +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuUsage(UINT32 taskID) +{ + UINT64 cpuCycleAll = 0; + UINT16 loopNum; + UINTPTR intSave; + UINT32 cpupRet = 0; + + if (g_cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) { + return LOS_ERRNO_CPUP_TSK_ID_INVALID; + } + if (g_cpup[taskID].cpupID != taskID) { + return LOS_ERRNO_CPUP_THREAD_NO_CREATED; + } + if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) { + return LOS_ERRNO_CPUP_THREAD_NO_CREATED; + } + intSave = LOS_IntLock(); + OsTskCycleEnd(); + + /* get total Cycle */ + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) { + continue; + } + cpuCycleAll += g_cpup[loopNum].allTime; + } + + if (cpuCycleAll) { + cpupRet = (UINT32)((LOS_CPUP_PRECISION * g_cpup[taskID].allTime) / cpuCycleAll); + } + + OsTskCycleStart(); + LOS_IntRestore(intSave); + + return cpupRet; +} + +/***************************************************************************** +Function : LOS_HistoryTaskCpuUsage +Description: get CPU usage history of certain task +Input : taskID : task ID + : mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s +Return : cpupRet:CPU usage history of task +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode) +{ + UINT64 cpuCycleAll = 0; + UINT64 cpuCycleCurTsk = 0; + UINT16 loopNum, curPos; + UINT16 prePos = 0; + UINTPTR intSave; + UINT32 cpupRet = 0; + + if (g_cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) { + return LOS_ERRNO_CPUP_TSK_ID_INVALID; + } + if (g_cpup[taskID].cpupID != taskID) { + return LOS_ERRNO_CPUP_THREAD_NO_CREATED; + } + if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) { + return LOS_ERRNO_CPUP_THREAD_NO_CREATED; + } + intSave = LOS_IntLock(); + OsTskCycleEnd(); + + OsGetPositions(mode, &curPos, &prePos); + + /* get total Cycle in history */ + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) { + continue; + } + + if (mode == CPUP_IN_1S) { + cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos]; + } else { + cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos]; + } + } + + if (mode == CPUP_IN_1S) { + cpuCycleCurTsk += g_cpup[taskID].historyTime[curPos] - g_cpup[taskID].historyTime[prePos]; + } else { + cpuCycleCurTsk += g_cpup[taskID].allTime - g_cpup[taskID].historyTime[curPos]; + } + if (cpuCycleAll) { + cpupRet = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll); + } + + OsTskCycleStart(); + LOS_IntRestore(intSave); + + return cpupRet; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode) +{ + UINT16 loopNum; + UINT16 curPos; + UINT16 prePos = 0; + UINTPTR intSave; + UINT64 cpuCycleAll = 0; + UINT64 cpuCycleCurTsk = 0; + + if (g_cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + if (cpupInfo == NULL) { + return LOS_ERRNO_CPUP_TASK_PTR_NULL; + } + + intSave = LOS_IntLock(); + OsTskCycleEnd(); + + OsGetPositions(mode, &curPos, &prePos); + + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || + (g_cpup[loopNum].status == 0)) { + continue; + } + + if (mode == CPUP_IN_1S) { + cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos]; + } else { + cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos]; + } + } + + for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) { + if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || + (g_cpup[loopNum].status == 0)) { + continue; + } + + if (mode == CPUP_IN_1S) { + cpuCycleCurTsk += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos]; + } else { + cpuCycleCurTsk += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos]; + } + cpupInfo[loopNum].usStatus = g_cpup[loopNum].status; + if (cpuCycleAll) { + cpupInfo[loopNum].uwUsage = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll); + } + + cpuCycleCurTsk = 0; + } + + OsTskCycleStart(); + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/***************************************************************************** +Function : LOS_CpupUsageMonitor +Description: Get CPU usage history of certain task. +Input : type: cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE + : taskID: task ID, Only in SYS_CPU_USAGE type, taskID is invalid + : mode: mode, CPUP_IN_10S = usage in 10s, CPUP_IN_1S = usage in last 1s, CPUP_LESS_THAN_1S = less than 1s +Return : LOS_OK on success, or OS_ERROR on failure +*****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID) +{ + UINT32 ret; + LosTaskCB *taskCB = NULL; + + switch (type) { + case SYS_CPU_USAGE: + if (mode == CPUP_IN_10S) { + PRINTK("\nSysCpuUsage in 10s: "); + } else if (mode == CPUP_IN_1S) { + PRINTK("\nSysCpuUsage in 1s: "); + } else { + PRINTK("\nSysCpuUsage in <1s: "); + } + ret = LOS_HistorySysCpuUsage(mode); + PRINTK("%d.%d", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT); + break; + + case TASK_CPU_USAGE: + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + PRINT_ERR("\nThe taskid is invalid.\n"); + return OS_ERROR; + } + taskCB = OS_TCB_FROM_TID(taskID); + if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED)) { + PRINT_ERR("\nThe taskid is invalid.\n"); + return OS_ERROR; + } + if (mode == CPUP_IN_10S) { + PRINTK("\nCPUusage of taskID %d in 10s: ", taskID); + } else if (mode == CPUP_IN_1S) { + PRINTK("\nCPUusage of taskID %d in 1s: ", taskID); + } else { + PRINTK("\nCPUusage of taskID %d in <1s: ", taskID); + } + ret = LOS_HistoryTaskCpuUsage(taskID, mode); + PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT); + break; + + default: + PRINT_ERR("\nThe type is invalid.\n"); + return OS_ERROR; + } + + return LOS_OK; +} + +#endif /* LOSCFG_BASE_CORE_CPUP */ + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/extended/include/los_cpup_pri.h b/kernel/extended/include/los_cpup_pri.h new file mode 100755 index 00000000..b25afe42 --- /dev/null +++ b/kernel/extended/include/los_cpup_pri.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_CPUP_PRI_H +#define _LOS_CPUP_PRI_H + +#include "los_cpup.h" +#include "los_tick_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** + * @ingroup los_cpup + * Number of historical running time records + */ +#define OS_CPUP_HISTORY_RECORD_NUM 10 + +/** + * @ingroup los_cpup + * Count the CPU usage structures of a task. + */ +typedef struct { + UINT32 cpupID; /**< Task ID */ + UINT16 status; /**< Task status */ + UINT64 allTime; /**< Total running time */ + UINT64 startTime; /**< Time before a task is invoked */ + UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM]; /**< Historical running time */ +} OsCpupCB; + +extern OsCpupCB *g_cpup; + +/** + * @ingroup los_cpup + * @brief Initialization cpup. + * + * @par Description: + * This API is used to initialization cpup. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param None. + * + * @retval UINT32 Initialization result. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsCpupInit(VOID); + +/** + * @ingroup los_cpup + * @brief Start task to get cycles count in current task ending. + * + * @par Description: + * This API is used to start task to get cycles count in current task ending. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param None. + * + * @retval None. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID OsTskCycleEndStart(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CPUP_PRI_H */ diff --git a/kernel/include/los_base.h b/kernel/include/los_base.h new file mode 100755 index 00000000..3c8c84bb --- /dev/null +++ b/kernel/include/los_base.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup kernel Kernel + * @defgroup los_base Basic definitions + * @ingroup kernel + */ + +#ifndef _LOS_BASE_H +#define _LOS_BASE_H + +#include "los_builddef.h" +#include "los_typedef.h" +#include "los_config.h" +#include "los_printf.h" +#include "los_list.h" +#include "los_errno.h" +#include "los_compiler.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define SIZE(a) (a) + +#define LOS_ASSERT_COND(expression) + +/** + * @ingroup los_base + * Define the timeout interval as LOS_NO_WAIT. + */ +#define LOS_NO_WAIT 0 + +/** + * @ingroup los_base + * Define the timeout interval as LOS_WAIT_FOREVER. + */ +#define LOS_WAIT_FOREVER 0xFFFFFFFF + +/** + * @ingroup los_base + * Align the beginning of the object with the base address addr, + * with boundary bytes being the smallest unit of alignment. + */ +#ifndef ALIGN +#define ALIGN(addr, boundary) LOS_Align(addr, boundary) +#endif +/** + * @ingroup los_base + * Align the tail of the object with the base address addr, with size bytes being the smallest unit of alignment. + */ +#define TRUNCATE(addr, size) ((addr) & ~((size)-1)) + +/** + * @ingroup los_base + * Read a UINT8 value from addr and stroed in value. + */ +#define READ_UINT8(value, addr) ((value) = *((volatile UINT8 *)(addr))) +/** + * @ingroup los_base + * Read a UINT16 value from addr and stroed in addr. + */ +#define READ_UINT16(value, addr) ((value) = *((volatile UINT16 *)(addr))) +/** + * @ingroup los_base + * Read a UINT32 value from addr and stroed in value. + */ +#define READ_UINT32(value, addr) ((value) = *((volatile UINT32 *)(addr))) +/** + * @ingroup los_base + * Read a UINT64 value from addr and stroed in value. + */ +#define READ_UINT64(value, addr) ((value) = *((volatile UINT64 *)(addr))) + +/** + * @ingroup los_base + * Get a UINT8 value from addr. + */ +#define GET_UINT8(addr) (*((volatile UINT8 *)(addr))) +/** + * @ingroup los_base + * Get a UINT16 value from addr. + */ +#define GET_UINT16(addr) (*((volatile UINT16 *)(addr))) +/** + * @ingroup los_base + * Get a UINT32 value from addr. + */ +#define GET_UINT32(addr) (*((volatile UINT32 *)(addr))) +/** + * @ingroup los_base + * Get a UINT64 value from addr. + */ +#define GET_UINT64(addr) (*((volatile UINT64 *)(addr))) + +/** + * @ingroup los_base + * Write a UINT8 value to addr. + */ +#define WRITE_UINT8(value, addr) (*((volatile UINT8 *)(addr)) = (value)) +/** + * @ingroup los_base + * Write a UINT16 value to addr. + */ +#define WRITE_UINT16(value, addr) (*((volatile UINT16 *)(addr)) = (value)) +/** + * @ingroup los_base + * Write a UINT32 value to addr. + */ +#define WRITE_UINT32(value, addr) (*((volatile UINT32 *)(addr)) = (value)) +/** + * @ingroup los_base + * Write a UINT64 addr to addr. + */ +#define WRITE_UINT64(value, addr) (*((volatile UINT64 *)(addr)) = (value)) + +#if PRINT_LEVEL < LOS_ERR_LEVEL +#define LOS_ASSERT(judge) +#else +#define LOS_ASSERT(judge) \ + do { \ + if ((judge) == 0) { \ + (VOID)LOS_IntLock(); \ + PRINT_ERR("ASSERT ERROR! %s, %d, %s\n", __FILE__, __LINE__, __func__); \ + while (1) { } \ + } \ + } while (0) +#endif + +/** + * @ingroup los_base + * @brief Align the value (addr) by some bytes (boundary) you specify. + * + * @par Description: + * This API is used to align the value (addr) by some bytes (boundary) you specify. + * + * @attention + *
    + *
  • the value of boundary usually is 4,8,16,32.
  • + *
+ * + * @param addr [IN] The variable what you want to align. + * @param boundary [IN] The align size what you want to align. + * + * @retval #UINT32 The variable what have been aligned. + * @par Dependency: + *
  • los_base.h: the header file that contains the API declaration.
+ * @see + */ +extern UINT32 LOS_Align(UINT32 addr, UINT32 boundary); + +/** + * @ingroup los_base + * @brief Sleep the current task. + * + * @par Description: + * This API is used to delay the execution of the current task. The task is able to be scheduled + * after it is delayed for a specified number of Ticks. + * + * @attention + *
    + *
  • The task fails to be delayed if it is being delayed during interrupt processing or it is locked.
  • + *
  • If 0 is passed in and the task scheduling is not locked, + * execute the next task in the queue of tasks with the priority of the current task. + * If no ready task with the priority of the current task is available, + * the task scheduling will not occur, and the current task continues to be executed.
  • + *
  • The parameter passed in can not be equal to LOS_WAIT_FOREVER(0xFFFFFFFF). + * If that happens, the task will not sleep 0xFFFFFFFF milliseconds or sleep forever but sleep 0xFFFFFFFF Ticks.
  • + *
+ * + * @param mSecs [IN] Type #UINT32 Number of MS for which the task is delayed. + * + * @retval None + * @par Dependency: + *
  • los_base.h: the header file that contains the API declaration.
+ * @see None + */ +extern VOID LOS_Msleep(UINT32 mSecs); + +/** + * @ingroup los_base + * @brief System kernel initialization function. + * + * @par Description: + * This API is used to start liteOS . + * + * @attention + *
    + *
  • None.
  • + *
+ * + * @param: None. + * + * @retval #LOS_OK 0:LiteOS start success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see + */ +extern UINT32 LOS_Start(VOID); + +/** + * @ingroup los_base + * @brief System kernel initialization function. + * + * @par Description: + * This API is used to Initialize kernel ,configure all system modules. + * + * @attention + *
    + *
  • None.
  • + *
+ * + * @param: None. + * + * @retval #LOS_OK 0:System kernel initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see + */ +extern UINT32 LOS_KernelInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BASE_H */ diff --git a/kernel/include/los_compiler.h b/kernel/include/los_compiler.h new file mode 100755 index 00000000..f013c311 --- /dev/null +++ b/kernel/include/los_compiler.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_COMPILER_H +#define _LOS_COMPILER_H + +/* for IAR Compiler */ +#ifdef __ICCARM__ +#include"iccarm_builtin.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* for IAR Compiler */ +#ifdef __ICCARM__ + +#ifndef ASM +#define ASM __asm +#endif + +#ifndef INLINE +#define INLINE inline +#endif + +#ifndef STATIC_INLINE +#define STATIC_INLINE static inline +#endif + +#ifndef USED +#define USED __root +#endif + +#ifndef WEAK +#define WEAK __weak +#endif + +#ifndef CLZ +#define CLZ __iar_builtin_CLZ +#endif + +/* for ARM Compiler */ +#elif defined(__CC_ARM) + +#ifndef ASM +#define ASM __asm +#endif + +#ifndef INLINE +#define INLINE __inline +#endif + +#ifndef STATIC_INLINE +#define STATIC_INLINE static __inline +#endif + +#ifndef USED +#define USED __attribute__((used)) +#endif + +#ifndef WEAK +#define WEAK __attribute__((weak)) +#endif + +#ifndef CLZ +#define CLZ __clz +#endif + +#pragma anon_unions + +/* for GNU Compiler */ +#elif defined(__GNUC__) + +#ifndef ASM +#define ASM __asm +#endif + +#ifndef INLINE +#define INLINE inline +#endif + +#ifndef STATIC_INLINE +#define STATIC_INLINE static inline +#endif + +#ifndef USED +#define USED __attribute__((used)) +#endif + +#ifndef WEAK +#define WEAK __attribute__((weak)) +#endif + +#ifndef CLZ +#define CLZ __builtin_clz +#endif + +#else +#error Unknown compiler. +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_COMPILER_H */ diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h new file mode 100755 index 00000000..f3c73466 --- /dev/null +++ b/kernel/include/los_config.h @@ -0,0 +1,1028 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_config System configuration items + * @ingroup kernel + */ + +#ifndef _LOS_CONFIG_H +#define _LOS_CONFIG_H + +#include "los_typedef.h" +#include "target_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* ============================================================================= + System clock module configuration +============================================================================= */ +/** + * @ingroup los_config + * System clock (unit: HZ) + */ +#ifndef OS_SYS_CLOCK +#define OS_SYS_CLOCK 100000000UL +#endif + +/** + * @ingroup los_config + * timer1 clock (unit: HZ) + */ +#ifndef OS_TIME_TIMER_CLOCK +#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK +#endif + +/** + * @ingroup los_config + * Number of Ticks in one second + */ +#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND +#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000UL +#endif + +#if defined(LOSCFG_BASE_CORE_TICK_PER_SECOND) && \ + ((LOSCFG_BASE_CORE_TICK_PER_SECOND < 1UL) || (LOSCFG_BASE_CORE_TICK_PER_SECOND > 1000000000UL)) + #error "LOSCFG_BASE_CORE_TICK_PER_SECOND SHOULD big than 0, and less than 1000000000UL" +#endif + + +#if (LOSCFG_BASE_CORE_TICK_PER_SECOND <= 1000UL) +/** + * @ingroup los_config + * How much time one tick spent (unit:ms) + */ +#ifndef LOSCFG_BASE_CORE_TICK_PERIOD_MS +#define LOSCFG_BASE_CORE_TICK_PERIOD_MS (1000UL / LOSCFG_BASE_CORE_TICK_PER_SECOND) +#endif + +#elif (LOSCFG_BASE_CORE_TICK_PER_SECOND <= 1000000UL) +/** + * @ingroup los_config + * How much time one tick spent (unit:us) + */ +#ifndef LOSCFG_BASE_CORE_TICK_PERIOD_US +#define LOSCFG_BASE_CORE_TICK_PERIOD_US (1000000UL / LOSCFG_BASE_CORE_TICK_PER_SECOND) +#endif + +#else +/** + * @ingroup los_config + * How much time one tick spent (unit:ns) + */ +#ifndef LOSCFG_BASE_CORE_TICK_PERIOD_NS +#define LOSCFG_BASE_CORE_TICK_PERIOD_NS (1000000000UL / LOSCFG_BASE_CORE_TICK_PER_SECOND) +#endif +#endif + +/** + * @ingroup los_config + * External configuration item for timer tailoring + */ +#ifndef LOSCFG_BASE_CORE_TICK_HW_TIME1 +#define LOSCFG_BASE_CORE_TICK_HW_TIME1 YES +#endif + +#ifndef LOSCFG_BASE_CORE_TICK_HW_TIME +#define LOSCFG_BASE_CORE_TICK_HW_TIME NO +#endif + +/** + * @ingroup los_config + * Configuration liteos kernel tickless + */ +#ifndef LOSCFG_KERNEL_TICKLESS +#define LOSCFG_KERNEL_TICKLESS NO +#endif + +/** + * @ingroup los_config + * External configuration item for timer interrupt number + */ +#ifndef LOSCFG_BASE_TIMER_INT_NUM +#define LOSCFG_BASE_TIMER_INT_NUM 15 +#endif + + +/* ============================================================================= + Hardware interrupt module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for hardware interrupt tailoring + */ +#ifndef LOSCFG_PLATFORM_HWI +#define LOSCFG_PLATFORM_HWI YES +#endif + +/** + * @ingroup los_config + * Maximum number of used hardware interrupts, including Tick timer interrupts. + */ +#ifndef LOSCFG_PLATFORM_HWI_LIMIT +#define LOSCFG_PLATFORM_HWI_LIMIT 32 +#endif + + +/* ============================================================================= + Task module configuration +============================================================================= */ +/** + * @ingroup los_config + * Minimum stack size. + * + * 0x80 bytes, aligned on a boundary of 8. + */ +#ifndef LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE (ALIGN(0x80, 4)) +#endif + +/** + * @ingroup los_config + * Default task priority + */ +#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO +#define LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO 10 +#endif + +/** + * @ingroup los_config + * Maximum supported number of tasks except the idle task rather than the number of usable tasks + */ +#ifndef LOSCFG_BASE_CORE_TSK_LIMIT +#define LOSCFG_BASE_CORE_TSK_LIMIT 5 +#endif + +/** + * @ingroup los_config + * Size of the idle task stack + */ +#ifndef LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE 0x180UL +#endif + +/** + * @ingroup los_config + * Default task stack size + */ +#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE 0x400UL +#endif + +/** + * @ingroup los_config + * Configuration item for task Robin tailoring + */ +#ifndef LOSCFG_BASE_CORE_TIMESLICE +#define LOSCFG_BASE_CORE_TIMESLICE YES +#endif + +/** + * @ingroup los_config + * Longest execution time of tasks with the same priorities + */ +#ifndef LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT +#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 10 +#endif + +/** + * @ingroup los_config + * Configuration item for task (stack) monitoring module tailoring + */ +#ifndef LOSCFG_BASE_CORE_TSK_MONITOR +#define LOSCFG_BASE_CORE_TSK_MONITOR NO +#endif + +/** + * @ingroup los_config + * Configuration item for task perf task filter hook + */ +#ifndef LOSCFG_BASE_CORE_EXC_TSK_SWITCH +#define LOSCFG_BASE_CORE_EXC_TSK_SWITCH NO +#endif + +/** + * @ingroup los_config + * Define a usable task priority.Highest task priority. + */ +#ifndef LOS_TASK_PRIORITY_HIGHEST +#define LOS_TASK_PRIORITY_HIGHEST 0 +#endif + +/** + * @ingroup los_config + * Define a usable task priority.Lowest task priority. + */ +#ifndef LOS_TASK_PRIORITY_LOWEST +#define LOS_TASK_PRIORITY_LOWEST 31 +#endif + +/** + * @ingroup los_config + * Configuration item for task stack independent + */ +#ifndef LOSCFG_BASE_CORE_TASKSTACK_INDEPENDENT +#define LOSCFG_BASE_CORE_TASKSTACK_INDEPENDENT NO +#endif + +/** + * @ingroup los_config + * SP align size + */ +#ifndef LOSCFG_STACK_POINT_ALIGN_SIZE +#define LOSCFG_STACK_POINT_ALIGN_SIZE 8 +#endif + +/* ============================================================================= + Semaphore module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for semaphore module tailoring + */ +#ifndef LOSCFG_BASE_IPC_SEM +#define LOSCFG_BASE_IPC_SEM YES +#endif + +/** + * @ingroup los_config + * Maximum supported number of semaphores + */ +#ifndef LOSCFG_BASE_IPC_SEM_LIMIT +#define LOSCFG_BASE_IPC_SEM_LIMIT 6 +#endif + +/* ============================================================================= + Mutex module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for mutex module tailoring + */ +#ifndef LOSCFG_BASE_IPC_MUX +#define LOSCFG_BASE_IPC_MUX YES +#endif + +/** + * @ingroup los_config + * Maximum supported number of mutexes + */ +#ifndef LOSCFG_BASE_IPC_MUX_LIMIT +#define LOSCFG_BASE_IPC_MUX_LIMIT 6 +#endif + +/* ============================================================================= + Queue module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for queue module tailoring + */ +#ifndef LOSCFG_BASE_IPC_QUEUE +#define LOSCFG_BASE_IPC_QUEUE YES +#endif + +/** + * @ingroup los_config + * Maximum supported number of queues rather than the number of usable queues + */ +#ifndef LOSCFG_BASE_IPC_QUEUE_LIMIT +#define LOSCFG_BASE_IPC_QUEUE_LIMIT 6 +#endif + + +/* ============================================================================= + Software timer module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for software timer module tailoring + */ +#ifndef LOSCFG_BASE_CORE_SWTMR +#define LOSCFG_BASE_CORE_SWTMR YES +#endif + +/** + * @ingroup los_config + * Maximum supported number of software timers rather than the number of usable software timers + */ +#ifndef LOSCFG_BASE_CORE_SWTMR_LIMIT +#define LOSCFG_BASE_CORE_SWTMR_LIMIT 5 +#endif + +/** + * @ingroup los_config + * Software timer task stack size + */ +#ifndef LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE +#endif + +/** + * @ingroup los_config + * Configurate item for handling software timer interrupt in task tailoring + */ +#ifndef LOSCFG_BASE_CORE_SWTMR_TASK +#define LOSCFG_BASE_CORE_SWTMR_TASK YES +#endif + +/** + * @ingroup los_config + * Configurate item for software timer align tailoring + */ +#ifndef LOSCFG_BASE_CORE_SWTMR_ALIGN +#define LOSCFG_BASE_CORE_SWTMR_ALIGN NO +#endif + +#if((LOSCFG_BASE_CORE_SWTMR == NO) && (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES)) + #error "swtmr align first need support swmtr, should make LOSCFG_BASE_CORE_SWTMR = YES" +#endif + +/** + * @ingroup los_config + * Max number of software timers ID + */ +#ifndef OS_SWTMR_MAX_TIMERID +#define OS_SWTMR_MAX_TIMERID ((65535 / LOSCFG_BASE_CORE_SWTMR_LIMIT) * LOSCFG_BASE_CORE_SWTMR_LIMIT) +#endif + +/** + * @ingroup los_config + * Maximum size of a software timer queue + */ +#ifndef OS_SWTMR_HANDLE_QUEUE_SIZE +#define OS_SWTMR_HANDLE_QUEUE_SIZE (LOSCFG_BASE_CORE_SWTMR_LIMIT + 0) +#endif + +/** + * @ingroup los_config + * Minimum divisor of software timer multiple alignment + */ +#ifndef LOS_COMMON_DIVISOR +#define LOS_COMMON_DIVISOR 10 +#endif + +#if ((LOSCFG_BASE_IPC_QUEUE == NO) && (LOSCFG_BASE_CORE_SWTMR == YES)) +#error "queue moudle is closed, don't support swtmr" +#endif +/* ============================================================================= + Memory module configuration +============================================================================= */ +extern UINT8 *m_aucSysMem0; + +/** + * @ingroup los_config + * Starting address of the memory + */ +#ifndef OS_SYS_MEM_ADDR +#define OS_SYS_MEM_ADDR (&m_aucSysMem0[0]) +#endif + +/** + * @ingroup los_config + * Starting address of the task stack + */ +#ifndef OS_TASK_STACK_ADDR +#define OS_TASK_STACK_ADDR OS_SYS_MEM_ADDR +#endif + +/** + * @ingroup los_config + * Ending address of the memory + */ +extern UINT32 g_sysMemAddrEnd; + + +/** + * @ingroup los_config + * Memory size + */ +#ifndef OS_SYS_MEM_SIZE +#define OS_SYS_MEM_SIZE 0x10000UL +#endif + +#ifndef LOSCFG_MEMORY_BESTFIT +#define LOSCFG_MEMORY_BESTFIT YES +#endif + +/** + * @ingroup los_config + * Configuration module tailoring of more mempry pool checking + */ +#ifndef LOSCFG_MEM_MUL_POOL +#define LOSCFG_MEM_MUL_POOL NO +#endif + +/** + * @ingroup los_config + * Configuration module tailoring of slab memory + */ +#ifndef LOSCFG_KERNEL_MEM_SLAB +#define LOSCFG_KERNEL_MEM_SLAB YES +#endif + +/** + * @ingroup los_config + * Configuration module tailoring of mem node integrity checking + */ +#ifndef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK +#define LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK NO +#endif + +/** + * @ingroup los_config + * Configuration module tailoring of mem node size checking + */ +#ifndef LOSCFG_BASE_MEM_NODE_SIZE_CHECK +#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK YES +#endif + +/** + * @ingroup los_config + * Configuration of memory statistics + */ +#ifndef LOSCFG_KERNEL_MEM_STATISTICS +#define LOSCFG_KERNEL_MEM_STATISTICS NO +#endif + +/** + * @ingroup los_config + * Number of memory checking blocks + */ +#ifndef OS_SYS_MEM_NUM +#define OS_SYS_MEM_NUM 20 +#endif + +/** + * @ingroup los_config + * Configuration heap memory peak statistics + */ +#ifndef LOSCFG_HEAP_MEMORY_PEAK_STATISTICS +#define LOSCFG_HEAP_MEMORY_PEAK_STATISTICS YES +#endif + +/** + * @ingroup los_config + * Size of unaligned memory + */ +#ifndef OS_SYS_NOCACHEMEM_SIZE +#define OS_SYS_NOCACHEMEM_SIZE 0x0UL +#endif + +/** + * @ingroup los_config + * Starting address of the unaligned memory + */ +#if (OS_SYS_NOCACHEMEM_SIZE > 0) +#define OS_SYS_NOCACHEMEM_ADDR (&g_sysNoCacheMem0[0]) +#endif + + +/* ============================================================================= + Exception module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for exception tailoring + */ +#ifndef LOSCFG_PLATFORM_EXC +#define LOSCFG_PLATFORM_EXC NO +#endif + +/** + * @ingroup los_config + * Configuration of hardware stack protection + */ +#ifndef LOSCFG_EXC_HRADWARE_STACK_PROTECTION +#define LOSCFG_EXC_HRADWARE_STACK_PROTECTION NO +#endif + +/** + * @ingroup los_config + * Configuration of userspace support + */ +#ifndef LOSCFG_KERNEL_USERSPACE +#define LOSCFG_KERNEL_USERSPACE NO +#endif + +/* ============================================================================= + MPU module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for MPU + */ +#ifndef LOSCFG_BASE_CORE_MPU +#define LOSCFG_BASE_CORE_MPU NO +#endif + +/** + * @ingroup los_config + * MPU support number : MPU maximum number of region support(According to the cotex-m4 authority Guide) + */ +#ifndef LOSCFG_MPU_MAX_SUPPORT +#define LOSCFG_MPU_MAX_SUPPORT 8 +#endif + +/** + * @ingroup los_config + * MPU support address range : from LOSCFG_MPU_MIN_ADDRESS to LOSCFG_MPU_MAX_ADDRESS + */ +#ifndef LOSCFG_MPU_MIN_ADDRESS +#define LOSCFG_MPU_MIN_ADDRESS 0x0UL // Minimum protected address +#endif + +#ifndef LOSCFG_MPU_MAX_ADDRESS +#define LOSCFG_MPU_MAX_ADDRESS 0xFFFFFFFFUL // Maximum protected address +#endif + +/* ============================================================================= + Runstop module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for runstop module tailoring + */ +#ifndef LOSCFG_KERNEL_RUNSTOP +#define LOSCFG_KERNEL_RUNSTOP NO +#endif + +/* ============================================================================= + Perf module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for performance moniter unit + */ +#ifndef OS_INCLUDE_PERF +#define OS_INCLUDE_PERF NO +#endif + + +/* ============================================================================= + CPUP configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for CPU usage tailoring + */ +#ifndef LOSCFG_BASE_CORE_CPUP +#define LOSCFG_BASE_CORE_CPUP NO +#endif + + +/* ============================================================================= + fw Interface configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for the monitoring of task communication + */ +#ifndef LOSCFG_COMPAT_CMSIS_FW +#define LOSCFG_COMPAT_CMSIS_FW NO +#endif + + +/* ============================================================================= + Shell module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration item for shell module tailoring + */ +#ifndef OS_INCLUDE_SHELL +#define OS_INCLUDE_SHELL NO +#endif + + +/* ============================================================================= + Test module configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration test case to open + */ + +/** + * @ingroup los_config + * Configuration CMSIS_OS_VER + */ +#ifndef CMSIS_OS_VER +#define CMSIS_OS_VER 1 +#endif + +/* ============================================================================= + trace configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration liteos trace + */ +#ifndef LOSCFG_KERNEL_TRACE +#define LOSCFG_KERNEL_TRACE NO +#endif + + +/* ============================================================================= + Declaration of Huawei LiteOS module initialization functions +============================================================================= */ +/** + * @ingroup los_config + * @brief: Task init function. + * + * @par Description: + * This API is used to initialize task module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_ERRNO_TSK_NO_MEMORY 0x03000200:Insufficient memory for task creation. + * @retval #LOS_OK 0:Task initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsTaskInit(VOID); + + +/** + * @ingroup los_config + * @brief: hardware interrupt init function. + * + * @par Description: + * This API is used to initialize hardware interrupt module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_OK 0:Hardware interrupt initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID OsHwiInit(VOID); + + +/** + * @ingroup los_config + * @brief: Semaphore init function. + * + * @par Description: + * This API is used to initialize Semaphore module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_ERRNO_SEM_NO_MEMORY 0x02000700:The memory is insufficient. + * @retval #LOS_OK 0:Semaphore initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsSemInit(VOID); + + +/** + * @ingroup los_config + * @brief: Mutex init function. + * + * @par Description: + * This API is used to initialize mutex module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_ERRNO_MUX_NO_MEMORY 0x02001d00:The memory request fails. + * @retval #LOS_OK 0:Mutex initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsMuxInit(VOID); + + +/** + * @ingroup los_config + * @brief: Queue init function. + * + * @par Description: + * This API is used to initialize Queue module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_ERRNO_QUEUE_MAXNUM_ZERO 0x02000600:The maximum number of queue resources is configured to 0. + * @retval #LOS_ERRNO_QUEUE_NO_MEMORY 0x02000601:The queue block memory fails to be initialized. + * @retval #LOS_OK 0:Queue initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsQueueInit(VOID); + + +/** + * @ingroup los_config + * @brief: Software Timers init function. + * + * @par Description: + * This API is used to initialize Software Timers module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_ERRNO_SWTMR_MAXSIZE_INVALID 0x02000308:Invalid configured number of software timers. + * @retval #LOS_ERRNO_SWTMR_NO_MEMORY 0x02000307:Insufficient memory for software timer linked list creation. + * @retval #LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM 0x0200030a:Insufficient memory allocated by membox. + * @retval #LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED 0x0200030b:The software timer queue fails to be created. + * @retval #LOS_ERRNO_SWTMR_TASK_CREATE_FAILED 0x0200030c:The software timer task fails to be created. + * @retval #LOS_OK 0:Software Timers initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsSwtmrInit(VOID); + + +/** + * @ingroup los_config + * @brief: Task start running function. + * + * @par Description: + * This API is used to start a task. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval None. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID LOS_StartToRun(VOID); + + +/** + * @ingroup los_config + * @brief: Test Task init function. + * + * @par Description: + * This API is used to initialize Test Task. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_OK 0:App_Task initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 los_TestInit(VOID); + + + +/** + * @ingroup los_config + * @brief: Task start function. + * + * @par Description: + * This API is used to start all tasks. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval None. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID OsStart(VOID); + + +/** + * @ingroup los_config + * @brief: Hardware init function. + * + * @par Description: + * This API is used to initialize Hardware module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval None. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID OsHwInit(VOID); + + +/** + * @ingroup los_config + * @brief Configure Tick Interrupt Start. + * + * @par Description: + * This API is used to configure Tick Interrupt Start while macro LOSCFG_BASE_CORE_TICK_HW_TIME is No. + * + * @attention + *
    + *
  • None.
  • + *
+ * + * @param: None. + * + * @retval #LOS_OK 0:configure Tick Interrupt success. + * @retval #LOS_ERRNO_TICK_CFG_INVALID 0x02000400:configure Tick Interrupt failed. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see + */ +extern UINT32 OsTickStart(VOID); + +/** + * @ingroup los_config + * @brief Configure Tick Interrupt Start. + * + * @par Description: + * This API is used to configure Tick Interrupt Start while macro LOSCFG_BASE_CORE_TICK_HW_TIME is Yes. + * + * @attention + *
    + *
  • None.
  • + *
+ * + * @param: None. + * + * @retval #LOS_OK 0:configure Tick Interrupt success. + * @retval #LOS_ERRNO_TICK_CFG_INVALID 0x02000400:configure Tick Interrupt failed. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see + */ +extern UINT32 os_timer_init(VOID); + +/** + * @ingroup los_config + * @brief Scheduling initialization. + * + * @par Description: + *
    + *
  • This API is used to initialize scheduling that is used for later task scheduling.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param: None. + * + * @retval: None. + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see + */ +extern VOID OsTimesliceInit(VOID); + + +/** + * @ingroup los_config + * @brief: System memory init function. + * + * @par Description: + * This API is used to initialize system memory module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_OK 0:System memory initialization success. + * @retval #OS_ERROR (UINT32)(-1):System memory initialization failed. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(VOID); + + +/** + * @ingroup los_config + * @brief: Task Monitor init function. + * + * @par Description: + * This API is used to initialize Task Monitor module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_OK 0:Task Monitor initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID OsTaskMonInit(VOID); + + +/** + * @ingroup los_config + * @brief: CPUP init function. + * + * @par Description: + * This API is used to initialize CPUP module. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval #LOS_ERRNO_CPUP_NO_MEMORY 0x02001e00:The request for memory fails. + * @retval #LOS_OK 0:CPUP initialization success. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 OsCpupInit(VOID); + + +extern LITE_OS_SEC_TEXT_INIT UINT32 LOS_Start(VOID); + +extern LITE_OS_SEC_TEXT_INIT INT32 main(VOID); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +#endif /* _LOS_CONFIG_H */ diff --git a/kernel/include/los_cppsupport.h b/kernel/include/los_cppsupport.h new file mode 100755 index 00000000..54f917fc --- /dev/null +++ b/kernel/include/los_cppsupport.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_cppsupport c++ + * @ingroup kernel + */ + +#ifndef _LOS_CPPSUPPORT_H +#define _LOS_CPPSUPPORT_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_cppsupport + * @brief System cppsupport initialization. + * + * @par Description: + * This API is used to initialize the cppsupport . + * @attention + *
    + *
  • initArrayStart is the start address of .init_array section, + * initArrayEnd is the end address of .init_array section.
  • + *
  • initArrayStart must be smaller than initArrayEnd, + * initArrayStart and initArrayEnd should be 4(32 bits platform) or 8(64 bits platform) bytes alignment.
  • + *
+ * + * + * @retval 0 always return 0. + * @par Dependency: + *
  • los_cppsupport.h: the header file that contains the API declaration.
+ * @see None. + */ +extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CPPSUPPORT_H */ diff --git a/kernel/include/los_cpup.h b/kernel/include/los_cpup.h new file mode 100755 index 00000000..27826b89 --- /dev/null +++ b/kernel/include/los_cpup.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_cpup CPU usage + * @ingroup kernel + */ + +#ifndef _LOS_CPUP_H +#define _LOS_CPUP_H + +#include "los_hwi.h" +#include "los_base.h" +#include "los_sys.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** +* @ingroup los_cpup +* CPU usage error code: The request for memory fails. +* +* Value: 0x02001e00 +* +* Solution: Decrease the maximum number of tasks. +*/ +#define LOS_ERRNO_CPUP_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00) + +/** +* @ingroup los_cpup +* CPU usage error code: The pointer to an input parameter is NULL. +* +* Value: 0x02001e01 +* +* Solution: Check whether the pointer to the input parameter is usable. +*/ +#define LOS_ERRNO_CPUP_TASK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x01) + +/** +* @ingroup los_cpup +* CPU usage error code: The CPU usage is not initialized. +* +* Value: 0x02001e02 +* +* Solution: Check whether the CPU usage is initialized. +*/ +#define LOS_ERRNO_CPUP_NO_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x02) + +/** +* @ingroup los_cpup +* CPU usage error code: The number of threads is invalid. +* +* Value: 0x02001e03 +* +* Solution: Check whether the number of threads is applicable for the current operation. +*/ +#define LOS_ERRNO_CPUP_MAXNUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x03) + +/** +* @ingroup los_cpup +* CPU usage error code: The target thread is not created. +* +* Value: 0x02001e04 +* +* Solution: Check whether the target thread is created. +*/ +#define LOS_ERRNO_CPUP_THREAD_NO_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x04) + +/** +* @ingroup los_cpup +* CPU usage error code: The target task ID is invalid. +* +* Value: 0x02001e05 +* +* Solution: Check whether the target task ID is applicable for the current operation. +*/ +#define LOS_ERRNO_CPUP_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x05) + +/** +* @ingroup los_cpup +* Sum of cpup with all tasks. It means the value of cpup is a permillage. +*/ +#define LOS_CPUP_PRECISION 1000 + +/** +* @ingroup los_cpup +* Multiple of current cpup precision change to percent. +*/ +#define LOS_CPUP_PRECISION_MULT (LOS_CPUP_PRECISION / 100) + +/** + * @ingroup los_cpup + * Count the CPU usage structures of all tasks. + */ +typedef struct tagCpupInfo { + UINT16 usStatus; /**< save the cur task status */ + UINT32 uwUsage; /**< Usage. The value range is [0,1000]. */ +} CPUP_INFO_S; + +/** + * @ingroup los_monitor + * Type of the CPU usage query. + */ +typedef enum { + SYS_CPU_USAGE = 0, /* system cpu occupancy rate */ + TASK_CPU_USAGE, /* task cpu occupancy rate */ +} CPUP_TYPE_E; + +/** + * @ingroup los_monitor + * Mode of the CPU usage query. + */ +typedef enum { + CPUP_IN_10S = 0, /* cpu occupancy rate in 10s */ + CPUP_IN_1S, /* cpu occupancy rate in 1s */ + CPUP_LESS_THAN_1S, /* cpu occupancy rate less than 1s, if the input mode is none of them, it will be this. */ +} CPUP_MODE_E; + +/** + * @ingroup los_cpup + * @brief Obtain the current CPU usage. + * + * @par Description: + * This API is used to obtain the current CPU usage. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, error codes will be returned.
  • + *
  • The precision of the CPU usage can be adjusted by changing the value of the CPUP_PRECISION macro.
  • + *
+ * + * @param None. + * + * @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized. + * @retval #cpup [0,100], current CPU usage, of which the precision is adjustable. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see LOS_SysCpuUsage + */ +extern UINT32 LOS_SysCpuUsage(VOID); + +/** + * @ingroup los_cpup + * @brief Obtain the historical CPU usage. + * + * @par Description: + * This API is used to obtain the historical CPU usage. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.
  • + *
+ * + * @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s will be + * obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained. Other values + * indicate that the CPU usage in the period that is less than 1s will be obtained. + * + * @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized. + * @retval #cpup [0,100], historical CPU usage, of which the precision is adjustable. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see LOS_HistoryTaskCpuUsage + */ +extern UINT32 LOS_HistorySysCpuUsage(UINT16 mode); + +/** + * @ingroup los_cpup + * @brief Obtain the CPU usage of a specified task. + * + * @par Description: + * This API is used to obtain the CPU usage of a task specified by a passed-in task ID. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.
  • + *
  • The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise, + * the CPU usage fails to be obtained.
  • + *
+ * + * @param taskID [IN] UINT32. Task ID. + * + * @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized. + * @retval #OS_ERRNO_CPUP_TSK_ID_INVALID 0x02001e05: The target task ID is invalid. + * @retval #OS_ERRNO_CPUP_THREAD_NO_CREATED 0x02001e04: The target thread is not created. + * @retval #cpup [0,100], CPU usage of the specified task. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see LOS_HistoryTaskCpuUsage + */ +extern UINT32 LOS_TaskCpuUsage(UINT32 taskID); + +/** + * @ingroup los_cpup + * @brief Obtain the historical CPU usage of a specified task. + * + * @par Description: + * This API is used to obtain the historical CPU usage of a task specified by a passed-in task ID. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, + * the CPU usage fails to be obtained.
  • + *
  • The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise, + * the CPU usage fails to be obtained.
  • + *
+ * + * @param taskID [IN] UINT32. Task ID. + * @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s + * will be obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained. + * Other values indicate that the CPU usage in the period that is less than 1s will be obtained. + * + * @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized. + * @retval #OS_ERRNO_CPUP_TSK_ID_INVALID 0x02001e05: The target task ID is invalid. + * @retval #OS_ERRNO_CPUP_THREAD_NO_CREATED 0x02001e04: The target thread is not created. + * @retval #cpup [0,100], CPU usage of the specified task. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see LOS_HistorySysCpuUsage + */ +extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode); + +/** + * @ingroup los_cpup + * @brief Obtain the CPU usage of all tasks. + * + * @par Description: + * This API is used to obtain the CPU usage of all tasks according to maximum number of threads. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.
  • + *
  • The input parameter pointer must not be NULL, Otherwise, the CPU usage fails to be obtained.
  • + *
+ * + * @param cpupInfo [OUT]Type. CPUP_INFO_S* Pointer to the task CPUP information structure to be obtained. + * @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s + * will be obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained. + * Other values indicate that the CPU usage in the period that is less than 1s will be obtained. + * + * @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized. + * @retval #OS_ERRNO_CPUP_TASK_PTR_NULL 0x02001e01: The input parameter pointer is NULL. + * @retval #LOS_OK 0x00000000: The CPU usage of all tasks is successfully obtained. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see LOS_SysCpuUsage + */ +extern UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode); + +/** + * @ingroup los_monitor + * @brief Obtain CPU usage history of certain task. + * + * @par Description: + * This API is used to obtain CPU usage history of certain task. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, -1 will be returned.
  • + *
  • Only in SYS_CPU_USAGE type, uwTaskID is invalid.
  • + *
+ * + * @param type [IN] cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE + * @param mode [IN] mode,CPUP_IN_10S = usage in 10s,CPUP_IN_1S = usage in last 1s, + * CPUP_LESS_THAN_1S = less than 1s, if the inpuit mode is none of them, it will be as CPUP_LESS_THAN_1S. + * @param taskID [IN] task ID, Only in SYS_CPU_USAGE type, taskID is invalid + * + * @retval #OS_ERROR -1:CPU usage info obtain failed. + * @retval #LOS_OK 0:CPU usage info is successfully obtained. + * @par Dependency: + *
  • los_monitor.h: the header file that contains the API declaration.
+ * @see LOS_CpupUsageMonitor + */ +extern UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CPUP_H */ diff --git a/kernel/include/los_err.h b/kernel/include/los_err.h new file mode 100755 index 00000000..6e8b3a65 --- /dev/null +++ b/kernel/include/los_err.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_err Error handling + * @ingroup kernel + */ + +#ifndef _LOS_ERR_H +#define _LOS_ERR_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** + * @ingroup los_err + * @brief Define the pointer to the error handling function. + * + * @par Description: + * This API is used to define the pointer to the error handling function. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param fileName [IN] Log file that stores error information. + * @param lineNo [IN] Line number of the erroneous line. + * @param errorNo [IN] Error code. + * @param paraLen [IN] Length of the input parameter pPara. + * @param para [IN] User label of the error. + * + * @retval None. + * @par Dependency: + *
  • los_err.h: the header file that contains the API declaration.
+ * @see None. + */ +typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName, + UINT32 lineNo, /**< Line number of the erroneous line. */ + UINT32 errorNo, /**< Error code. */ + UINT32 paraLen, /**< Length of the input parameter pPara. */ + VOID *para); + +/** + * @ingroup los_err + * @brief Error handling function. + * + * @par Description: + * This API is used to perform different operations according to error types. + * @attention + *
    + *
  • None
  • + *
+ * + * @param fileName [IN] Log file that stores error information. + * @param lineNo [IN] Line number of the erroneous line which should not be OS_ERR_MAGIC_WORD. + * @param errorNo [IN] Error code. + * @param paraLen [IN] Length of the input parameter pPara. + * @param para [IN] User label of the error. + * + * @retval LOS_OK The error is successfully processed. + * @par Dependency: + *
  • los_err.h: the header file that contains the API declaration.
+ * @see None + */ +extern UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, + UINT32 errorNo, UINT32 paraLen, + VOID *para); + +/** + * @ingroup los_err + * Error handling function structure. + */ +typedef struct tagUserErrFunc { + LOS_ERRORHANDLE_FUNC pfnHook; /**< Hook function for error handling. */ +} UserErrFunc; + + +enum LOS_MOUDLE_ID { + LOS_MOD_SYS = 0x0, + LOS_MOD_MEM = 0x1, + LOS_MOD_TSK = 0x2, + LOS_MOD_SWTMR = 0x3, + LOS_MOD_TICK = 0x4, + LOS_MOD_MSG = 0x5, + LOS_MOD_QUE = 0x6, + LOS_MOD_SEM = 0x7, + LOS_MOD_MBOX = 0x8, + LOS_MOD_HWI = 0x9, + LOS_MOD_HWWDG = 0xa, + LOS_MOD_CACHE = 0xb, + LOS_MOD_HWTMR = 0xc, + LOS_MOD_MMU = 0xd, + + LOS_MOD_LOG = 0xe, + LOS_MOD_ERR = 0xf, + + LOS_MOD_EXC = 0x10, + LOS_MOD_CSTK = 0x11, + + LOS_MOD_MPU = 0x12, + LOS_MOD_NMHWI = 0x13, + LOS_MOD_TRACE = 0x14, + LOS_MOD_KNLSTAT = 0x15, + LOS_MOD_EVTTIME = 0x16, + LOS_MOD_THRDCPUP = 0x17, + LOS_MOD_IPC = 0x18, + LOS_MOD_STKMON = 0x19, + LOS_MOD_TIMER = 0x1a, + LOS_MOD_RESLEAKMON = 0x1b, + LOS_MOD_EVENT = 0x1c, + LOS_MOD_MUX = 0X1d, + LOS_MOD_CPUP = 0x1e, + LOS_MOD_SHELL = 0x31, + LOS_MOD_BUTT +}; + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ERR_H */ diff --git a/kernel/include/los_errno.h b/kernel/include/los_errno.h new file mode 100755 index 00000000..7a964733 --- /dev/null +++ b/kernel/include/los_errno.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_errno Error code + * @ingroup kernel + */ + +#ifndef _LOS_ERRNO_H +#define _LOS_ERRNO_H + +#include "los_typedef.h" +#include "los_err.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + +/** + * @ingroup los_errno + * OS error code flag. + */ +#define LOS_ERRNO_OS_ID ((UINT32)0x00 << 16) + +/** + * @ingroup los_errno + * Define the error level as informative. + */ +#define LOS_ERRTYPE_NORMAL ((UINT32)0x00 << 24) + +/** + * @ingroup los_errno + * Define the error level as warning. + */ +#define LOS_ERRTYPE_WARN ((UINT32)0x01 << 24) + +/** + * @ingroup los_errno + * Define the error level as critical. + */ +#define LOS_ERRTYPE_ERROR ((UINT32)0x02 << 24) + +/** + * @ingroup los_errno + * Define the error level as fatal. + */ +#define LOS_ERRTYPE_FATAL ((UINT32)0x03 << 24) + +/** + * @ingroup los_errno + * Define fatal OS errors. + */ +#define LOS_ERRNO_OS_FATAL(moduleID, errno) \ + (LOS_ERRTYPE_FATAL | LOS_ERRNO_OS_ID | ((UINT32)(moduleID) << 8) | (errno)) + +/** + * @ingroup los_errno + * Define critical OS errors. + */ +#define LOS_ERRNO_OS_ERROR(moduleID, errno) \ + (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(moduleID) << 8) | (errno)) + +/** + * @ingroup los_errno + * Define warning OS errors. + */ +#define LOS_ERRNO_OS_WARN(moduleID, errno) \ + (LOS_ERRTYPE_WARN | LOS_ERRNO_OS_ID | ((UINT32)(moduleID) << 8) | (errno)) + +/** + * @ingroup los_errno + * Define informative OS errors. + */ +#define LOS_ERRNO_OS_NORMAL(moduleID, errno) \ + (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(moduleID) << 8) | (errno)) + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_ERRNO_H */ diff --git a/kernel/include/los_event.h b/kernel/include/los_event.h new file mode 100755 index 00000000..77dc0ce8 --- /dev/null +++ b/kernel/include/los_event.h @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_event Event + * @ingroup kernel + */ + +#ifndef _LOS_EVENT_H +#define _LOS_EVENT_H + +#include "los_base.h" +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_event + * Event reading mode: The task waits for all its expected events to occur. + */ +#define LOS_WAITMODE_AND (4) /* all bits must be set */ + +/** + * @ingroup los_event + * Event reading mode: The task waits for any of its expected events to occur. + */ +#define LOS_WAITMODE_OR (2) /* any bit must be set */ + +/** + * @ingroup los_event + * Event reading mode: The event flag is immediately cleared after the event is read. + */ +#define LOS_WAITMODE_CLR (1) /* clear when satisfied */ + +/** + * @ingroup los_event + * Bit 25 of the event mask cannot be set to an event because it is set to an error code. + * + * Value: 0x02001c00 + * + * Solution: Set bits excluding bit 25 of the event mask to events. + */ +#define LOS_ERRNO_EVENT_SETBIT_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x00) +/** + * @ingroup los_event + * Event reading error code: Event reading times out. + * + * Value: 0x02001c01 + * + * Solution: Increase the waiting time for event reading, or make another task write a mask for the event. + */ +#define LOS_ERRNO_EVENT_READ_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x01) + +/** + * @ingroup los_event + * Event reading error code: The EVENTMASK input parameter value is valid. The input parameter value must not be 0. + * + * Value: 0x02001c02 + * + * Solution: Pass in a valid EVENTMASK value. + */ +#define LOS_ERRNO_EVENT_EVENTMASK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x02) + +/** + * @ingroup los_event + * Event reading error code: The event is being read during an interrupt. + * + * Value: 0x02001c03 + * + * Solution: Read the event in a task. + */ +#define LOS_ERRNO_EVENT_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x03) + +/** + * @ingroup los_event + * Event reading error code: The uwFlags input parameter value used in the event reading API is invalid. + * This input parameter value is obtained by performing an OR operation on corresponding bits of either OS_EVENT_ANY or + * OS_EVENT_ANY and corresponding bits of either OS_EVENT_WAIT or OS_EVENT_NOWAIT. The waiting time must be set to + * a nonzero value when an event is read in the mode of OS_EVENT_WAIT. + * + * Value: 0x02001c04 + * + * Solution: Pass in a valid uwFlags value. + */ +#define LOS_ERRNO_EVENT_FLAGS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x04) + +/** + * @ingroup los_event + * Event reading error code: The task is locked and is unable to read the event. + * + * Value: 0x02001c05 + * + * Solution: Unlock the task and read the event. + */ +#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) + +/** + * @ingroup los_event + * Event reading error code: Null pointer. + * + * Value: 0x02001c06 + * + * Solution: Check whether the input parameter is null. + */ +#define LOS_ERRNO_EVENT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x06) + +/** + * @ingroup los_event + * Event reading error code: no initialized. + * + * Value: 0x02001c07 + * + * Solution: Check whether the event is initialized. + */ +#define LOS_ERRNO_EVENT_NOT_INITIALIZED LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x07) + +/** + * @ingroup los_event + * Event reading error code: should not be distory. + * + * Value: 0x02001c08 + * + * Solution: Check whether the event list is not empty. + */ +#define LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x08) + +/** + * @ingroup los_event + * Event control structure + */ +typedef struct tagEvent { + UINT32 uwEventID; /**< Event mask in the event control block, + indicating the event that has been logically processed. */ + LOS_DL_LIST stEventList; /**< Event control block linked list */ +} EVENT_CB_S, *PEVENT_CB_S; +/** + * @ingroup los_event + * @brief Initialize an event control block. + * + * @par Description: + * This API is used to initialize the event control block pointed to by eventCB. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param eventCB [IN/OUT] Pointer to the event control block to be initialized. + * + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event control block is successfully initialized. + * @par Dependency: + *
  • los_event.h: the header file that contains the API declaration.
+ * @see LOS_EventClear + */ +extern UINT32 LOS_EventInit(PEVENT_CB_S eventCB); + +/** + * @ingroup los_event + * @brief Obtain an event specified by the event ID. + * + * @par Description: + * This API is used to check whether an event expected by the user occurs according to the event ID, event mask, + * and event reading mode, and process the event based on the event reading mode. The event ID must point to valid memory. + * @attention + *
    + *
  • When the mode is LOS_WAITMODE_CLR, the eventID is passed-out.
  • + *
  • Otherwise the eventID is passed-in.
  • + *
+ * + * @param eventID [IN/OUT] Pointer to the ID of the event to be checked. + * @param eventMask [IN] Mask of the event expected to occur by the user, indicating the event obtained after + * it is logically processed that matches the ID pointed to by mode. + * @param mode [IN] Event reading mode. The modes include LOS_WAITMODE_AND, LOS_WAITMODE_OR, LOS_WAITMODE_CLR. + * + * @retval 0 The event expected by the user does not occur. + * @retval #UINT32 The event expected by the user occurs. + * @par Dependency: + *
  • los_event.h: the header file that contains the API declaration.
+ * @see LOS_EventRead | LOS_EventWrite + */ +extern UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode); + +/** + * @ingroup los_event + * @brief Read an event. + * + * @par Description: + * This API is used to block or schedule a task that reads an event of which the event control block, event mask, reading mode, + * and timeout information are specified. + * + * @attention + *
    + *
  • An error code and an event return value can be same. To differentiate the error code and return value, bit 25 of + * the event mask is forbidden to be used.
  • + *
+ * + * @param eventCB [IN/OUT] Pointer to the event control block to be checked. This parameter must point to valid memory. + * @param eventMask [IN] Mask of the event expected to occur by the user, indicating the event obtained after + * it is logically processed that matches the ID pointed to by eventID. + * @param mode [IN] Event reading mode. + * @param timeOut [IN] Timeout interval of event reading (unit: Tick). + * + * @retval #LOS_ERRNO_EVENT_SETBIT_INVALID Bit 25 of the event mask cannot be set because it is set to an error number. + * @retval #LOS_ERRNO_EVENT_EVENTMASK_INVALID The passed-in event reading mode is incorrect. + * @retval #LOS_ERRNO_EVENT_READ_IN_INTERRUPT The event is being read during an interrupt. + * @retval #LOS_ERRNO_EVENT_FLAGS_INVALID The event mode is invalid. + * @retval #LOS_ERRNO_EVENT_READ_IN_LOCK The event reading task is locked. + * @retval #LOS_ERRNO_EVENT_PTR_NULL The passed-in pointer is null. + * @retval 0 The event expected by the user does not occur. + * @retval #UINT32 The event expected by the user occurs. + * @par Dependency: + *
  • los_event.h: the header file that contains the API declaration.
+ * @see LOS_EventPoll | LOS_EventWrite + */ +extern UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut); + +/** + * @ingroup los_event + * @brief Write an event. + * + * @par Description: + * This API is used to write an event specified by the passed-in event mask into an event control block + * pointed to by eventCB. + * @attention + *
    + *
  • To determine whether the LOS_EventRead API returns an event or an error code, bit 25 of the event mask + * is forbidden to be used.
  • + *
+ * + * @param eventCB [IN/OUT] Pointer to the event control block into which an event is to be written. + * This parameter must point to valid memory. + * @param events [IN] Event mask to be written. + * + * @retval #LOS_ERRNO_EVENT_SETBIT_INVALID Bit 25 of the event mask cannot be set to an event + * because it is set to an error code. + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event is successfully written. + * @par Dependency: + *
  • los_event.h: the header file that contains the API declaration.
+ * @see LOS_EventPoll | LOS_EventRead + */ +extern UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events); + +/** + * @ingroup los_event + * @brief Clear the event occurring in a specified task. + * + * @par Description: + *
    + *
  • This API is used to set the ID of an event that has a specified mask and of which the information is stored in + * an event control block pointed to by eventCB to 0. eventCB must point to valid memory.
  • + *
+ * @attention + *
    + *
  • The value of events needs to be reversed when it is passed-in.
  • + *
+ * + * @param eventCB [IN/OUT] Pointer to the event control block to be cleared. + * @param events [IN] Mask of the event to be cleared. + * + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event is successfully cleared. + * @par Dependency: + *
  • los_event.h: the header file that contains the API declaration.
+ * @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite + */ +extern UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events); + +/** + * @ingroup los_event + * @brief Destroy a event. + * + * @par Description: + *
    + *
  • This API is used to Destroy a event.
  • + *
+ * @attention + *
    + *
  • The specific event should be a valid one.
  • + *
+ * + * @param eventCB [IN/OUT] Pointer to the event control block to be Destroyed. + * + * @retval #LOS_ERRNO_EVENT_PTR_NULL Null pointer. + * @retval #LOS_OK The event is successfully cleared. + * @par Dependency: + *
  • los_event.h: the header file that contains the API declaration.
+ * @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite + */ +extern UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EVENT_H */ diff --git a/kernel/include/los_heap.h b/kernel/include/los_heap.h new file mode 100755 index 00000000..06d9d16d --- /dev/null +++ b/kernel/include/los_heap.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_heap Heap + * @ingroup kernel + */ + +#ifndef _LOS_HEAP_H +#define _LOS_HEAP_H + +#include +#include "los_base.h" +#if (LOSCFG_KERNEL_MEM_SLAB == YES) +#include "los_slab.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define IS_ALIGNED(value) ((((UINT32)(value)) & ((UINT32)((value) - 1))) == 0) +#define OS_MEM_ALIGN(value, align) (((UINT32)(UINTPTR)(value) + (UINT32)((align) - 1)) & \ + (~(UINT32)((align) - 1))) +#define OS_MEM_ALIGN_FLAG 0x80000000 +#define OS_MEM_SET_ALIGN_FLAG(align) ((align) = ((align) | OS_MEM_ALIGN_FLAG)) +#define OS_MEM_GET_ALIGN_FLAG(align) ((align) & OS_MEM_ALIGN_FLAG) +#define OS_MEM_GET_ALIGN_GAPSIZE(align) ((align) & (~OS_MEM_ALIGN_FLAG)) + +#define RAM_HEAP_SIZE ((OS_SYS_MEM_SIZE) & (~7)) +#define RAM_HEAP_START (OS_SYS_MEM_ADDR) + +#ifdef CONFIG_DDR_HEAP +#define DDR_HEAP_INIT() LOS_HeapInit((VOID *)DDR_HEAP_START, DDR_HEAP_SIZE) +#define DDR_HEAP_ALLOC(sz) LOS_HeapAllocAlign((VOID *)DDR_HEAP_START, \ + OS_MEM_ALIGN(sz, DCACHE_LINE_SIZE), DCACHE_LINE_SIZE) +#define DDR_HEAP_FREE(p) LOS_HeapFree((VOID *)DDR_HEAP_START, p) +#endif + +/* extra 2 blocks is for idle and extra temparary task */ +#define TASK_BLOCK_NUM (LOSCFG_BASE_CORE_TSK_LIMIT + 2) + +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +#define TASKID_BITS 7 +/* 2 bits for used and align flag, 30 bits left */ +#define SIZE_BITS (30 - TASKID_BITS) +#if (SIZE_BITS <= 0) +#error task id bits too big! +#endif +#if (TASK_BLOCK_NUM > ((1 << TASKID_BITS) - 1)) +#error task id bits too small! +#endif +#endif + +struct LOS_HEAP_NODE { + struct LOS_HEAP_NODE* pstPrev; +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + UINT32 uwSize : SIZE_BITS; + UINT32 taskID : TASKID_BITS; +#else + UINT32 uwSize : 30; +#endif + UINT32 uwUsed : 1; + UINT32 uwAlign : 1; + UINT8 ucData[0]; /*lint !e43*/ +}; + +/** + * @ingroup los_heap + * @brief Initialization heap memory. + * + * @par Description: + * This API is used to initialization heap memory. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param pool [IN/OUT] A pointer pointed to the memory pool. + * @param size [IN] Size of heap memory. + * + * @retval TRUE Initialization success. + * @retval FALSE Initialization failed. + * @par Dependency: + *
  • los_heap.h: the header file that contains the API declaration.
+ * @see None. + */ +extern BOOL LOS_HeapInit(VOID *pool, UINT32 size); + +/** + * @ingroup los_heap + * @brief Alloc memory block from heap memory. + * + * @par Description: + * This API is used to alloc memory block from heap memory. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param pool [IN/OUT] A pointer pointed to the memory pool. + * @param size [IN] Size of heap memory. + * + * @retval VOID* + * @par Dependency: + *
  • los_heap.h: the header file that contains the API declaration.
+ * @see LOS_HeapFree + */ +extern VOID* LOS_HeapAlloc(VOID *pool, UINT32 size); + +/** + * @ingroup los_heap + * @brief Alloc aligned memory block from heap memory. + * + * @par Description: + * This API is used to alloc aligned memory block from heap memory. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param pool [IN/OUT] A pointer pointed to the memory pool. + * @param size [IN] Size of heap memory. + * @param boundary [IN] Boundary the heap needs align + * + * @retval VOID* + * @par Dependency: + *
  • los_heap.h: the header file that contains the API declaration.
+ * @see LOS_HeapFree + */ +extern VOID* LOS_HeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary); + +/** + * @ingroup los_heap + * @brief Free memory block from heap memory. + * + * @par Description: + * This API is used to free memory block from heap memory. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param pool [IN/OUT] A pointer pointed to the memory pool. + * @param ptr [IN] Point to be freed. + * + * @retval BOOL TRUE free success FALSE free failed + * @par Dependency: + *
  • los_heap.h: the header file that contains the API declaration.
+ * @see LOS_HeapAlloc + */ +extern BOOL LOS_HeapFree(VOID *pool, VOID* ptr); + +/** + * @ingroup los_memory + * @brief Get the memory info from Heap. + * + * @par Description: + * This API is used to get the memory info from Heap. + * @attention + *
    + *
  • None.
  • + *
+ * @param None. + * + * @retval UINT32 Max size of heap memory being used. + * + * @par Dependency: + *
  • los_heap.h: the header file that contains the API declaration.
+ * @see None. + */ +#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) +extern UINT32 LOS_HeapGetHeapMemoryPeak(VOID); +#endif + +/** + * @ingroup los_memory + * @brief Get the memory statistics from Heap. + * + * @par Description: + * This API is used to get the memory statistics from Heap. + * @attention + *
    + *
  • None.
  • + *
+ * @param None. + * + * @retval None. + * + * @par Dependency: + *
  • los_heap.h: the header file that contains the API declaration.
+ * @see None. + */ +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +VOID LOS_HeapDumpMemoryStats(VOID *pool); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/kernel/include/los_list.h b/kernel/include/los_list.h new file mode 100755 index 00000000..ee8e4099 --- /dev/null +++ b/kernel/include/los_list.h @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_list Doubly linked list + * @ingroup kernel + */ + +#ifndef _LOS_LIST_H +#define _LOS_LIST_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_list + * Structure of a node in a doubly linked list. + */ +typedef struct LOS_DL_LIST { + struct LOS_DL_LIST *pstPrev; /**< Current node's pointer to the previous node */ + struct LOS_DL_LIST *pstNext; /**< Current node's pointer to the next node */ +} LOS_DL_LIST; + +/** + * @ingroup los_list + * @brief Initialize a doubly linked list. + * + * @par Description: + * This API is used to initialize a doubly linked list. + * @attention + *
    + *
  • The parameter passed in should be ensured to be a legal pointer.
  • + *
+ * + * @param list [IN] Node in a doubly linked list. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListInit(LOS_DL_LIST *list) +{ + list->pstNext = list; + list->pstPrev = list; +} + +/** + * @ingroup los_list + * @brief Point to the next node pointed to by the current node. + * + * @par Description: + *
    + *
  • This API is used to point to the next node pointed to by the current node.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param object [IN] Node in the doubly linked list. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_FIRST(object) ((object)->pstNext) + +/** + * @ingroup los_list + * @brief Insert a new node to a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to a doubly linked list. + * @attention + *
    + *
  • The parameters passed in should be ensured to be legal pointers.
  • + *
+ * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see LOS_ListDelete + */ +LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node) +{ + node->pstNext = list->pstNext; + node->pstPrev = list; + list->pstNext->pstPrev = node; + list->pstNext = node; +} + +/** + * @ingroup los_list + * @brief Insert a node to the tail of a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to the tail of a doubly linked list. + * @attention + *
    + *
  • The parameters passed in should be ensured to be legal pointers.
  • + *
+ * + * @param list [IN] Doubly linked list where the new node is inserted. + * @param node [IN] New node to be inserted. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see LOS_ListAdd | LOS_ListHeadInsert + */ +LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node) +{ + LOS_ListAdd(list->pstPrev, node); +} + +/** + * @ingroup los_list + * @brief Delete a specified node from a doubly linked list. + * + * @par Description: + *
    + *
  • This API is used to delete a specified node from a doubly linked list.
  • + *
+ * @attention + *
    + *
  • The parameter passed in should be ensured to be a legal pointer.
  • + *
+ * + * @param node [IN] Node to be deleted. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see LOS_ListAdd + */ +LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListDelete(LOS_DL_LIST *node) +{ + node->pstNext->pstPrev = node->pstPrev; + node->pstPrev->pstNext = node->pstNext; + node->pstNext = (LOS_DL_LIST *)NULL; + node->pstPrev = (LOS_DL_LIST *)NULL; +} + +/** + * @ingroup los_list + * @brief Identify whether a specified doubly linked list is empty. + * + * @par Description: + *
    + *
  • This API is used to return whether a doubly linked list is empty.
  • + *
+ * @attention + *
    + *
  • The parameter passed in should be ensured to be a legal pointer.
  • + *
+ * + * @param list [IN] Doubly linked node. + * + * @retval TRUE The doubly linked list is empty. + * @retval FALSE The doubly linked list is not empty. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +LITE_OS_SEC_ALW_INLINE STATIC_INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *node) +{ + return (BOOL)(node->pstNext == node); +} + +/** + * @ingroup los_list + * @brief Obtain the offset of a field to a structure address. + * + * @par Description: + * This API is used to obtain the offset of a field to a structure address. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param type [IN] Structure name. + * @param field [IN] Name of the field of which the offset is to be measured. + * + * @retval Offset of the field to the structure address. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define OFFSET_OF_FIELD(type, field) ((UINT32)&(((type *)0)->field)) + +/** + * @ingroup los_list + * @brief Obtain the pointer to a doubly linked list in a structure. + * + * @par Description: + * This API is used to obtain the pointer to a doubly linked list in a structure. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval Pointer to the doubly linked list in the structure. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_OFF_SET_OF(type, member) ((UINT32)&(((type *)0)->member)) /*lint -e(413) */ + +/** + * @ingroup los_list + * @brief Obtain the pointer to a structure that contains a doubly linked list. + * + * @par Description: + * This API is used to obtain the pointer to a structure that contains a doubly linked list. + *
    + *
  • None.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param item [IN] Current node's pointer to the next node. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval Pointer to the structure that contains the doubly linked list. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_ENTRY(item, type, member) \ + ((type *)(VOID *)((CHAR *)(item) - LOS_OFF_SET_OF(type, member))) \ + +/** + * @ingroup los_list + * @brief Iterate over a doubly linked list of given type. + * + * @par Description: + * This API is used to iterate over a doubly linked list of given type. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_FOR_EACH_ENTRY(item, list, type, member) \ + for ((item) = LOS_DL_LIST_ENTRY((list)->pstNext, type, member); \ + &(item)->member != (list); \ + (item) = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member)) + +/** + * @ingroup los_list + * @brief iterate over a doubly linked list safe against removal of list entry. + * + * @par Description: + * This API is used to iterate over a doubly linked list safe against removal of list entry. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param next [IN] Save the next node. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * @param type [IN] Structure name. + * @param member [IN] Member name of the doubly linked list in the structure. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, next, list, type, member) \ + for ((item) = LOS_DL_LIST_ENTRY((list)->pstNext, type, member), \ + (next) = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member); \ + &((item)->member) != (list); \ + (item) = (next), (next) = LOS_DL_LIST_ENTRY((item)->member.pstNext, type, member)) + +/** + * @ingroup los_list + * @brief Delete initialize a doubly linked list. + * + * @par Description: + * This API is used to delete initialize a doubly linked list. + * @attention + *
    + *
  • The parameter passed in should be ensured to be s legal pointer.
  • + *
+ * + * @param list [IN] Doubly linked list. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListDelInit(LOS_DL_LIST *list) +{ + list->pstNext->pstPrev = list->pstPrev; + list->pstPrev->pstNext = list->pstNext; + LOS_ListInit(list); +} + +/** + * @ingroup los_list + * @brief iterate over a doubly linked list. + * + * @par Description: + * This API is used to iterate over a doubly linked list. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_FOR_EACH(item, list) \ + for ((item) = (list)->pstNext; (item) != (list); (item) = (item)->pstNext) + +/** + * @ingroup los_list + * @brief Iterate over a doubly linked list safe against removal of list entry. + * + * @par Description: + * This API is used to iterate over a doubly linked list safe against removal of list entry. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param item [IN] Pointer to the structure that contains the doubly linked list that is to be traversed. + * @param next [IN] Save the next node. + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_FOR_EACH_SAFE(item, next, list) \ + for ((item) = (list)->pstNext, (next) = (item)->pstNext; (item) != (list); \ + (item) = (next), (next) = (item)->pstNext) + +/** + * @ingroup los_list + * @brief Initialize a double linked list. + * + * @par Description: + * This API is used to initialize a double linked list. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param list [IN] Pointer to the doubly linked list to be traversed. + * + * @retval None. + * @par Dependency: + *
  • los_list.h: the header file that contains the API declaration.
+ * @see + */ +#define LOS_DL_LIST_HEAD(list) \ + LOS_DL_LIST list = { &(list), &(list) } + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LIST_H */ diff --git a/kernel/include/los_membox.h b/kernel/include/los_membox.h new file mode 100755 index 00000000..b09cc281 --- /dev/null +++ b/kernel/include/los_membox.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMBOX_H +#define _LOS_MEMBOX_H + +#include "los_config.h" +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_memcheck.h" +#endif + +#define BOX_ALIGN_8 0x80000000 +/* ---------------------------------------------------------------------------- + * Global Functions + * --------------------------------------------------------------------------- */ +/** + * @ingroup los_membox + * Define whether to check the address validity + */ +#if (LOSCFG_PLATFORM_EXC == YES) +#define LOS_MEMBOX_CHECK +extern UINT8 g_memMang[]; +#endif + +typedef struct tagMemBoxCB { + UINT32 uwMaxBlk; + UINT32 uwBlkCnt; + UINT32 uwBlkSize; /* Memory block size */ +}OS_MEMBOX_S; + +typedef OS_MEMBOX_S *OS_MEMBOX_S_P; + +#ifdef LOS_MEMBOX_CHECK +#define LOS_MEMBOX_MAGIC_SIZE 4 +#else +#define LOS_MEMBOX_MAGIC_SIZE 0 +#endif + +/** + * @ingroup los_membox + * @brief Initialize a memory pool. + * + * @par Description: + *
    + *
  • This API is used to initialize a memory pool.
  • + *
+ * @attention + *
    + *
  • The boxSize parameter value should match the following two conditions :
  • + *
  • 1) Be less than or equal to the Memory pool size; 2) Be greater than the size of LOS_MEMBOX_INFO.
  • + *
+ * + * @param boxMem [IN] Memory pool address. + * @param boxSize [IN] Memory pool size. + * @param blkSize [IN] Memory block size. + * + * @retval #LOS_NOK The memory pool fails to be initialized. + * @retval #LOS_OK The memory pool is successfully initialized. + * @par Dependency: + *
    + *
  • los_membox.h: the header file that contains the API declaration.
  • + *
+ * @see None. + */ +extern UINT32 LOS_MemboxInit(VOID *boxMem, UINT32 boxSize, UINT32 blkSize); + +/** + * @ingroup los_membox + * @brief Request a memory block. + * + * @par Description: + *
    + *
  • This API is used to request a memory block.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemboxInit.
  • + *
+ * + * @param boxMem [IN] Memory pool address. + * + * @retval #VOID* The request is accepted, and return a memory block address. + * @retval #NULL The request fails. + * @par Dependency: + *
    + *
  • los_membox.h: the header file that contains the API declaration.
  • + *
+ * @see LOS_MemboxFree + */ +extern VOID *LOS_MemboxAlloc(VOID *boxMem); + +/** + * @ingroup los_membox + * @brief Free a memory block. + * + * @par Description: + *
    + *
  • This API is used to free a memory block.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemboxInit.
  • + *
  • The input pBox parameter must be allocated by LOS_MemboxAlloc.
  • + *
+ * + * @param boxMem [IN] Memory pool address. + * @param box [IN] Memory block address. + * + * @retval #LOS_NOK This memory block fails to be freed. + * @retval #LOS_OK This memory block is successfully freed. + * @par Dependency: + *
    + *
  • los_membox.h: the header file that contains the API declaration.
  • + *
+ * @see LOS_MemboxAlloc + */ +extern UINT32 LOS_MemboxFree(const VOID *boxMem, VOID *box); + +/** + * @ingroup los_membox + * @brief Clear a memory block. + * + * @par Description: + *
    + *
  • This API is used to set the memory block value to be 0.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemboxInit.
  • + *
  • The input pBox parameter must be allocated by LOS_MemboxAlloc.
  • + *
+ * + * @param boxMem [IN] Memory pool address. + * @param box [IN] Memory block address. + * + * @retval VOID + * @par Dependency: + *
    + *
  • los_membox.h: the header file that contains the API declaration.
  • + *
+ * @see None. + */ +extern VOID LOS_MemboxClr(const VOID *boxMem, VOID *box); + + +/** + * @ingroup los_membox + * @brief calculate membox information. + * + * @par Description: + *
    + *
  • This API is used to calculate membox information.
  • + *
+ * @attention + *
    + *
  • One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may be + * abnormal.
  • + *
+ * + * @param boxMem [IN] Type #VOID* Pointer to the calculate membox. + * @param maxBlk [OUT] Type #UINT32* Record membox max block. + * @param blkCnt [OUT] Type #UINT32* Record membox block count alreay allocated. + * @param blkSize [OUT] Type #UINT32* Record membox block size. + * + * @retval #LOS_OK The heap status calculate success. + * @retval #LOS_NOK The membox status calculate with some error. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree + */ +extern UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize); + +#endif diff --git a/kernel/include/los_memcheck.h b/kernel/include/los_memcheck.h new file mode 100755 index 00000000..e3b51e7b --- /dev/null +++ b/kernel/include/los_memcheck.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMCHECK_H +#define _LOS_MEMCHECK_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define MEM_INFO_SIZE ((sizeof(MEM_INFO) * OS_SYS_MEM_NUM) + 4) +extern UINT8 g_memMang[]; + +enum _MEM_MANG_TYPE { + MEM_MANG_MEMBOX, + MEM_MANG_MEMORY, + MEM_MANG_EMPTY, +}; + +enum _MEM_MANG_SOUCE { + MEM_MANG_UNUSED, + MEM_MANG_INIT, + MEM_MANG_INT, + MEM_MANG_TASK, +}; + +typedef struct _MEM_INFO { + UINT32 uwType; + UINT32 uwStartAddr; + UINT32 uwSize; + VOID * blkAddrArray; +}MEM_INFO; + +typedef struct _SLAB_INFO { + UINT32 item_sz; + UINT32 item_cnt; + UINT32 cur_usage; +}SLAB_INFO; + +#define SLAB_CLASS_NUM (4U) +typedef struct _MEM_INFO_S { + UINT32 uwType; + UINT32 uwStartAddr; + UINT32 uwSize; + UINT32 uwFree; + UINT32 uwBlockSize; + UINT32 uwErrorAddr; + UINT32 uwErrorLen; + UINT32 uwErrorOwner; + SLAB_INFO stSlabInfo[SLAB_CLASS_NUM]; +}MEM_INFO_S; + +/** + * @ingroup los_memboxcheck + * @brief Get the information of the exc memory. + * + * @par Description: + *
    + *
  • This API is used to get the information of the exc memory.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param memNum [IN] Type #UINT32 Memory pool number. + * @param memExcInfo [IN/OUT] Type #MEM_INFO_S * information of the exc memory. + * + * @retval UINT32 Get information result. + * @par Dependency: + *
    + *
  • los_memboxcheck.h: the header file that contains the API declaration.
  • + *
+ * @see None. + */ +UINT32 LOS_MemExcInfoGet(UINT32 memNum, MEM_INFO_S *memExcInfo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_MEMCHECK_H */ \ No newline at end of file diff --git a/kernel/include/los_memory.h b/kernel/include/los_memory.h new file mode 100755 index 00000000..ae0d78a5 --- /dev/null +++ b/kernel/include/los_memory.h @@ -0,0 +1,610 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_MEMORY_H +#define _LOS_MEMORY_H +#include "los_base.h" +#if (LOSCFG_KERNEL_MEM_SLAB == YES) +#include +#endif +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct __s_LOS_MEM_STATUS { + UINT32 totalSize; + UINT32 usedSize; + UINT32 freeSize; + UINT32 allocCount; + UINT32 freeCount; +} LOS_MEM_STATUS; + +#if (LOSCFG_MEMORY_BESTFIT == YES) + +/** + * @ingroup los_memory + * Memory pool information structure + */ +typedef struct { + VOID *pPoolAddr; /**< Starting address of a memory pool */ + UINT32 uwPoolSize; /**< Memory pool size */ +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + UINT32 uwPoolWaterLine; /**< Maximum usage size in a memory pool */ + UINT32 uwPoolCurUsedSize; /**< Current usage size in a memory pool */ +#endif +#ifdef LOSCFG_MEM_MUL_POOL + VOID *pNextPool; +#endif +} LOS_MEM_POOL_INFO; + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) +extern UINT8 g_memMang[]; +#endif +#if (LOSCFG_PLATFORM_EXC == YES) +#define OS_MEM_ENABLE_ALLOC_CHECK +#endif +#if (LOSCFG_BASE_MEM_NODE_SIZE_CHECK == YES) +#define OS_MEM_CHECK_DEBUG +#endif + +#ifdef LOSCFG_MEM_MUL_POOL +extern VOID *g_memPoolHead; +#endif +typedef VOID (*MALLOC_HOOK)(VOID); + +extern MALLOC_HOOK g_mallocHook; + +/** + * @ingroup los_memory + * @brief Get the size of memory totally used. + * + * @par Description: + *
    + *
  • This API is used to get the size of memory totally used in memory pool.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The size of the memory pool used. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 LOS_MemTotalUsedGet(VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the number of free memory nodes. + * + * @par Description: + *
    + *
  • This API is used to get the number of free memory nodes in memory pool.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The number of free memory nodes. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 LOS_MemFreeBlksGet(VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the number of used memory nodes. + * + * @par Description: + *
    + *
  • This API is used to get the number of used memory nodes in memory pool.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The number of used memory nodes. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 LOS_MemUsedBlksGet(VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the task ID of a used memory node. + * + * @par Description: + *
    + *
  • This API is used to get the task ID of a used memory node.
  • + *
+ * @attention + *
    + *
  • The input ptr parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign.
  • + *
  • This interface only support obtain the task ID of a used memory node which is allocated from + * the system memory pool (OS_SYS_MEM_ADDR) at present.
  • + *
+ * + * @param pool [IN] A used memory node. + * + * @retval #OS_INVALID The incoming parameter ptr is illegal. + * @retval #UINT32 The task ID of used memory node ptr. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 LOS_MemTaskIdGet(const VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the address of last node. + * + * @par Description: + *
    + *
  • This API is used to get the address of last node.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
  • The last node of memory pool is not the end node.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The incoming parameter pool is NULL. + * @retval #UINT32 The address of the last used node that casts to UINT32. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 LOS_MemLastUsedGet(VOID *pool); + +/** + * @ingroup los_memory + * @brief Check the memory pool Integrity. + * + * @par Description: + *
    + *
  • This API is used to check the memory pool Integrity.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
  • LOS_MemIntegrityCheck will be called by malloc function when the macro of LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK + * is defined in LiteOS.
  • + *
  • LOS_MemIntegrityCheck function can be called by user anytime.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * + * @retval #LOS_NOK The memory pool (pool) is impaired. + * @retval #LOS_OK The memory pool (pool) is integrated. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see None. + */ +extern UINT32 LOS_MemIntegrityCheck(VOID *pool); + +/** + * @ingroup los_memory + * Define a mem size check intensity + * + * Lowest mem check. + */ +#define LOS_MEM_CHECK_LEVEL_LOW 0 + +/** + * @ingroup los_memory + * Define a mem size check intensity + * + * Highest mem check. + */ +#define LOS_MEM_CHECK_LEVEL_HIGH 1 + +/** + * @ingroup los_memory + * Define a mem size check intensity + * + * disable mem check. + */ +#define LOS_MEM_CHECK_LEVEL_DISABLE 0xff + +/** + * @ingroup los_memory + * Define a mem size check intensity + * + * default intensity set mem check. + */ +#define LOS_MEM_CHECK_LEVEL_DEFAULT LOS_MEM_CHECK_LEVEL_DISABLE + +/** + * @ingroup los_memory + * @brief Check the size of memory node specified. + * + * @par Description: + *
    + *
  • This API is used to check the size of memory node.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
  • The input ptr parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign.
  • + *
  • The function will be called by function specified, such as memset or memcpy.
  • + *
  • The feature can be enabled when you set the macro value of LOSCFG_BASE_MEM_NODE_SIZE_CHECK as YES.
  • + *
  • You had better set memory check level as LOS_MEM_CHECK_LEVEL_DISABLE when copy bin file.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * @param ptr [IN] A pointer pointed to the source node. + * @param totalSize [OUT] A pointer to save total size, must point to valid memory. + * @param availSize [OUT] A pointer to save available size, must point to valid memory. + * + * @retval #OS_ERRNO_MEMCHECK_DISABLED Memcheck function does not open. + * @retval #OS_ERRNO_MEMCHECK_NOT_INIT Memcheck function does not init. + * @retval #OS_ERRNO_MEMCHECK_PARA_NULL The pool or ptr is NULL. + * @retval #OS_ERRNO_MEMCHECK_OUTSIDE The ptr address is not in the reasonable range. + * @retval #OS_ERRNO_MEMCHECK_NO_HEAD Can't find the control head node from ptr. + * @retval #OS_ERRNO_MEMCHECK_WRONG_LEVEL The memory check level is illegal. + * @retval #LOS_OK Success to get total size and available + * size of the memory node (ptr). + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemCheckLevelSet | LOS_MemCheckLevelGet + */ +extern UINT32 LOS_MemNodeSizeCheck(VOID *pool, VOID *ptr, UINT32 *totalSize, UINT32 *availSize); + +/** + * @ingroup los_memory + * @brief Set the memory check level. + * + * @par Description: + *
    + *
  • This API is used to set the memory check level.
  • + *
+ * @attention + *
    + *
  • There are three level you can set.
  • + *
  • The legal level are LOS_MEM_CHECK_LEVEL_LOW, LOS_MEM_CHECK_LEVEL_HIGH, LOS_MEM_CHECK_LEVEL_DISABLE.
  • + *
+ * + * @param level [IN] The level what you want to set. + * + * @retval #LOS_ERRNO_MEMCHECK_WRONG_LEVEL The memory check level what you want to set is illegal. + * @retval #LOS_OK Success to set the memory check level. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemNodeSizeCheck | LOS_MemCheckLevelGet + */ +extern UINT32 LOS_MemCheckLevelSet(UINT8 level); + +/** + * @ingroup los_memory + * @brief Get the memory check level. + * + * @par Description: + *
    + *
  • This API is used to get the current memory check level.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param None + * + * @retval #UINT8 The current memory check level. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemNodeSizeCheck | LOS_MemCheckLevelSet + */ +extern UINT8 LOS_MemCheckLevelGet(VOID); +/** + * @ingroup los_memory + * @brief Get the memory pool information. + * + * @par Description: + *
    + *
  • This API is used to get the current memory pool used information.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param pool [IN] A pointer pointed to the memory pool. + * @param status [IN] A pointer for storage the pool status. + * + * @retval #LOS_OK Success to get the memory pool information. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ */ +extern UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_STATUS *status); +#else + +/** + * @ingroup los_memory + * @brief calculate heap information. + * + * @par Description: + *
    + *
  • This API is used to calculate heap information.
  • + *
+ * @attention + *
    + *
  • One parameter of this interface is a pointer, it should be a correct value, otherwise, + * the system may be abnormal.
  • + *
+ * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param status [OUT] Type #LOS_MEM_STATUS* Pointer to the heap status structure to be obtained. + * + * @retval #LOS_OK The heap status calculate success. + * @retval #LOS_NOK The heap status calculate with some error. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree + */ +extern UINT32 LOS_MemStatisticsGet(VOID *pool, LOS_MEM_STATUS *status); + +/** + * @ingroup los_memory + * @brief calculate heap max free block size. + * + * @par Description: + *
    + *
  • This API is used to calculate heap max free block size.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param pool [IN] Pointer to memory pool. + * + * @retval #UINT32 The max free block size. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree + */ +extern UINT32 LOS_MemGetMaxFreeBlkSize(VOID *pool); +#endif + +/** + * @ingroup los_memory + * @brief Initialize dynamic memory. + * + * @par Description: + *
    + *
  • This API is used to initialize the dynamic memory of a doubly linked list.
  • + *
+ * @attention + *
    + *
  • The size parameter value should match the following two conditions : 1) Be less than or equal to + * the Memory pool size; 2) Be greater than the size of OS_MEM_MIN_POOL_SIZE.
  • + *
  • Call this API when dynamic memory needs to be initialized during the startup of Huawei LiteOS.
  • + *
  • The parameter input must be four byte-aligned.
  • + *
  • The init area [pool, pool + size] should not conflict with other pools.
  • + *
+ * + * @param pool [IN] Starting address of memory. + * @param size [IN] Memory size. + * + * @retval #LOS_NOK The dynamic memory fails to be initialized. + * @retval #LOS_OK The dynamic memory is successfully initialized. + * @par Dependency: + *
    + *
  • los_memory.h: the header file that contains the API declaration.
  • + *
+ * @see None. + */ +extern UINT32 LOS_MemInit(VOID *pool, UINT32 size); + +/** + * @ingroup los_memory + * @brief Allocate dynamic memory. + * + * @par Description: + *
    + *
  • This API is used to allocate a memory block of which the size is specified.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemInit.
  • + *
  • The size of the input parameter size can not be greater than the memory pool size + * that specified at the second input parameter of LOS_MemInit.
  • + *
  • The size of the input parameter size must be four byte-aligned.
  • + *
+ * + * @param pool [IN] Pointer to the memory pool that contains the memory block to be allocated. + * @param size [IN] Size of the memory block to be allocated (unit: byte). + * + * @retval #NULL The memory fails to be allocated. + * @retval #VOID* The memory is successfully allocated with the starting address of + * the allocated memory block returned. + * @par Dependency: + *
  • los_memory.h: the header file that contains the API declaration.
+ * @see LOS_MemRealloc | LOS_MemAllocAlign | LOS_MemFree + */ +extern VOID *LOS_MemAlloc(VOID *pool, UINT32 size); + +/** + * @ingroup los_memory + * @brief Free dynamic memory. + * + * @par Description: + *
  • This API is used to free specified dynamic memory that has been allocated.
  • + * @attention + *
      + *
    • The input pool parameter must be initialized via func LOS_MemInit.
    • + *
    • The input mem parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign or LOS_MemRealloc.
    • + *
    + * + * @param pool [IN] Pointer to the memory pool that contains the dynamic memory block to be freed. + * @param mem [IN] Starting address of the memory block to be freed. + * + * @retval #LOS_NOK The memory block fails to be freed + * @retval #LOS_OK The memory block is successfully freed. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemAllocAlign + */ +extern UINT32 LOS_MemFree(VOID *pool, VOID *mem); + +/** + * @ingroup los_memory + * @brief Re-allocate a memory block. + * + * @par Description: + *
      + *
    • This API is used to allocate a new memory block of which the size is specified by size if the original + * memory block size is insufficient. The new memory block will copy the data in the original memory block of + * which the address is specified by ptr. The size of the new memory block determines the maximum size of data + * to be copied. After the new memory block is created, the original one is freed.
    • + *
    + * @attention + *
      + *
    • The input pool parameter must be initialized via func LOS_MemInit.
    • + *
    • The input ptr parameter must be allocated by LOS_MemAlloc.
    • + *
    • The size of the input parameter size can not be greater than the memory pool size that specified at the + * second input parameter of LOS_MemInit.
    • + *
    • The size of the input parameter size must be aligned as follows: 1) if the ptr is allocated by LOS_MemAlloc, + * it must be four byte-aligned; 2) if the ptr is allocated by LOS_MemAllocAlign, it must be aligned with the size + * of the input parameter uwBoundary of LOS_MemAllocAlign.
    • + *
    + * + * @param pool [IN] Pointer to the memory pool that contains the original and new memory blocks. + * @param ptr [IN] Address of the original memory block. + * @param size [IN] Size of the new memory block. + * + * @retval #NULL The memory fails to be re-allocated. + * @retval #VOID* The memory is successfully re-allocated with the starting address of the new memory block + * returned. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see LOS_MemAlloc | LOS_MemAllocAlign | LOS_MemFree + */ +extern VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size); + +/** + * @ingroup los_memory + * @brief Allocate aligned memory. + * + * @par Description: + *
      + *
    • This API is used to allocate memory blocks of specified size and of which the starting addresses are aligned + * on a specified boundary.
    • + *
    + * @attention + *
      + *
    • The input pool parameter must be initialized via func LOS_MemInit.
    • + *
    • The size of the input parameter size can not be greater than the memory pool size that specified at the second + * input parameter of LOS_MemInit.
    • + *
    • The alignment parameter value must be a power of 2 with the minimum value being 4.
    • + *
    + * + * @param pool [IN] Pointer to the memory pool that contains the memory blocks to be allocated. + * @param size [IN] Size of the memory to be allocated. + * @param boundary [IN] Boundary on which the memory is aligned. + * + * @retval #NULL The memory fails to be allocated. + * @retval #VOID* The memory is successfully allocated with the starting address of the allocated memory + * returned. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree + */ +extern VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary); + +#if (LOSCFG_MEM_MUL_POOL == YES) +/** + * @ingroup los_memory + * @brief Deinitialize dynamic memory. + * + * @par Description: + *
      + *
    • This API is used to deinitialize the dynamic memory of a doubly linked list.
    • + *
    + * + * @param pool [IN] Starting address of memory. + * + * @retval #LOS_NOK The dynamic memory fails to be deinitialized. + * @retval #LOS_OK The dynamic memory is successfully deinitialized. + * @par Dependency: + *
      + *
    • los_memory.h: the header file that contains the API declaration.
    • + *
    + * @see None. + */ +extern UINT32 LOS_MemDeInit(const VOID *pool); + +/** + * @ingroup los_memory + * @brief Print infomation about all pools. + * + * @par Description: + *
      + *
    • This API is used to print infomation about all pools.
    • + *
    + * + * @retval #UINT32 The pool number. + * @par Dependency: + *
      + *
    • los_memory.h: the header file that contains the API declaration.
    • + *
    + * @see None. + */ +extern UINT32 LOS_MemPoolList(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMORY_H */ diff --git a/kernel/include/los_mux.h b/kernel/include/los_mux.h new file mode 100755 index 00000000..bd644938 --- /dev/null +++ b/kernel/include/los_mux.h @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_mux Mutex + * @ingroup kernel + */ + +#ifndef _LOS_MUX_H +#define _LOS_MUX_H + +#include "los_base.h" +#include "los_sys.h" +#include "los_list.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_mux + * Mutex error code: The memory request fails. + * + * Value: 0x02001d00 + * + * Solution: Decrease the number of mutexes defined by LOSCFG_BASE_IPC_MUX_LIMIT. + */ +#define LOS_ERRNO_MUX_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x00) + +/** + * @ingroup los_mux + * Mutex error code: The mutex is not usable. + * + * Value: 0x02001d01 + * + * Solution: Check whether the mutex ID and the mutex state are applicable for the current operation. + */ +#define LOS_ERRNO_MUX_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x01) + +/** +* @ingroup los_mux +* Mutex error code: Null pointer. +* +* Value: 0x02001d02 +* +* Solution: Check whether the input parameter is usable. +*/ +#define LOS_ERRNO_MUX_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x02) + +/** +* @ingroup los_mux +* Mutex error code: No mutex is available and the mutex request fails. +* +* Value: 0x02001d03 +* +* Solution: Increase the number of mutexes defined by LOSCFG_BASE_IPC_MUX_LIMIT. +*/ +#define LOS_ERRNO_MUX_ALL_BUSY LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x03) + +/** +* @ingroup los_mux +* Mutex error code: The mutex fails to be locked in non-blocking mode because it is locked by another thread. +* +* Value: 0x02001d04 +* +* Solution: Lock the mutex after it is unlocked by the thread that owns it, or set a waiting time. +*/ +#define LOS_ERRNO_MUX_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x04) + +/** +* @ingroup los_mux +* Mutex error code: The mutex is being locked during an interrupt. +* +* Value: 0x02001d05 +* +* Solution: Check whether the mutex is being locked during an interrupt. +*/ +#define LOS_ERRNO_MUX_PEND_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x05) + +/** +* @ingroup los_mux +* Mutex error code: A thread locks a mutex after waiting for the mutex to be unlocked by another thread +* when the task scheduling is disabled. +* +* Value: 0x02001d06 +* +* Solution: Check whether the task scheduling is disabled, or set uwtimeout to 0, which means that the +* thread will not wait for the mutex to become available. +*/ +#define LOS_ERRNO_MUX_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x06) + +/** +* @ingroup los_mux +* Mutex error code: The mutex locking times out. +* +* Value: 0x02001d07 +* +* Solution: Increase the waiting time or set the waiting time to LOS_WAIT_FOREVER (forever-blocking mode). +*/ +#define LOS_ERRNO_MUX_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x07) + +/** + * @ingroup los_mux + * + * Value: 0x02001d08 + * Not in use temporarily. + */ +#define LOS_ERRNO_MUX_OVERFLOW LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x08) + +/** +* @ingroup los_mux +* Mutex error code: The mutex to be deleted is being locked. +* +* Value: 0x02001d09 +* +* Solution: Delete the mutex after it is unlocked. +*/ +#define LOS_ERRNO_MUX_PENDED LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x09) + +/** + * @ingroup los_mux + * + * Value: 0x02001d0A + * Not in use temporarily. + */ +#define LOS_ERRNO_MUX_GET_COUNT_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0A) + +/** + * @ingroup los_mux + * + * Value: 0x02001d0B + * Not in use temporarily. + */ +#define LOS_ERRNO_MUX_REG_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0B) + +/** + * @ingroup los_mux + * + * Mutex error code: LOS_ERRNO_MUX_MAXNUM_ZERO is zero. + * Value: 0x02001d0C + * + * Solution: LOS_ERRNO_MUX_MAXNUM_ZERO should not be zero. + */ +#define LOS_ERRNO_MUX_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0C) + +/** + * @ingroup los_mux + * @brief Create a mutex. + * + * @par Description: + * This API is used to create a mutex. A mutex handle is assigned to muxHandle when the mutex is created successfully. + * Return LOS_OK on creating successful, return specific error code otherwise. + * @attention + *
      + *
    • The total number of mutexes is pre-configured. If there are no available mutexes, the mutex creation fails.
    • + *
    + * + * @param muxHandle [OUT] Handle pointer of the successfully created mutex. The value of handle should be in + * [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. + * + * @retval #LOS_ERRNO_MUX_PTR_NULL The muxHandle pointer is NULL. + * @retval #LOS_ERRNO_MUX_ALL_BUSY No available mutex. + * @retval #LOS_OK The mutex is successfully created. + * @par Dependency: + *
    • los_mux.h: the header file that contains the API declaration.
    + * @see LOS_MuxDelete + */ +extern UINT32 LOS_MuxCreate(UINT32 *muxHandle); + +/** + * @ingroup los_mux + * @brief Delete a mutex. + * + * @par Description: + * This API is used to delete a specified mutex. Return LOS_OK on deleting successfully, return specific error code + * otherwise. + * @attention + *
      + *
    • The specific mutex should be created firstly.
    • + *
    • The mutex can be deleted successfully only if no other tasks pend on it.
    • + *
    + * + * @param muxHandle [IN] Handle of the mutex to be deleted. The value of handle should be in + * [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. + * + * @retval #LOS_ERRNO_MUX_INVALID Invalid handle or mutex in use. + * @retval #LOS_ERRNO_MUX_PENDED Tasks pended on this mutex. + * @retval #LOS_OK The mutex is successfully deleted. + * @par Dependency: + *
    • los_mux.h: the header file that contains the API declaration.
    + * @see LOS_MuxCreate + */ +extern UINT32 LOS_MuxDelete(UINT32 muxHandle); + +/** + * @ingroup los_mux + * @brief Wait to lock a mutex. + * + * @par Description: + * This API is used to wait for a specified period of time to lock a mutex. + * @attention + *
      + *
    • The specific mutex should be created firstly.
    • + *
    • The function fails if the mutex that is waited on is already locked by another thread when the task scheduling + * is disabled.
    • + *
    • Do not wait on a mutex during an interrupt.
    • + *
    • The priority inheritance protocol is supported. If a higher-priority thread is waiting on a mutex, it changes + * the priority of the thread that owns the mutex to avoid priority inversion.
    • + *
    • A recursive mutex can be locked more than once by the same thread.
    • + *
    + * + * @param muxHandle [IN] Handle of the mutex to be waited on. The value of handle should be + * in [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. + * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_ERRNO_MUX_INVALID The mutex state (for example, the mutex does not exist or is not in use) + * is not applicable for the current operation. + * @retval #LOS_ERRNO_MUX_UNAVAILABLE The mutex fails to be locked because it is locked by another thread and + * a period of time is not set for waiting for the mutex to become available. + * @retval #LOS_ERRNO_MUX_PEND_INTERR The mutex is being locked during an interrupt. + * @retval #LOS_ERRNO_MUX_PEND_IN_LOCK The mutex is waited on when the task scheduling is disabled. + * @retval #LOS_ERRNO_MUX_TIMEOUT The mutex waiting times out. + * @retval #LOS_OK The mutex is successfully locked. + * @par Dependency: + *
    • los_mux.h: the header file that contains the API declaration.
    + * @see LOS_MuxCreate | LOS_MuxPost + */ +extern UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout); + +/** + * @ingroup los_mux + * @brief Release a mutex. + * + * @par Description: + * This API is used to release a specified mutex. + * @attention + *
      + *
    • The specific mutex should be created firstly.
    • + *
    • Do not release a mutex during an interrupt.
    • + *
    • If a recursive mutex is locked for many times, it must be unlocked for the same times to be released.
    • + *
    + * + * @param muxHandle [IN] Handle of the mutex to be released. The value of handle should be in + * [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. + * + * @retval #LOS_ERRNO_MUX_INVALID The mutex state (for example, the mutex does not exist or is not in use + * or owned by other thread) is not applicable for the current operation. + * @retval #LOS_ERRNO_MUX_PEND_INTERR The mutex is being released during an interrupt. + * @retval #LOS_OK The mutex is successfully released. + * @par Dependency: + *
    • los_mux.h: the header file that contains the API declaration.
    + * @see LOS_MuxCreate | LOS_MuxPend + */ +extern UINT32 LOS_MuxPost(UINT32 muxHandle); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_H */ diff --git a/kernel/include/los_queue.h b/kernel/include/los_queue.h new file mode 100755 index 00000000..f6c47348 --- /dev/null +++ b/kernel/include/los_queue.h @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_queue Queue + * @ingroup kernel + */ + +#ifndef _LOS_QUEUE_H +#define _LOS_QUEUE_H + +#include "los_base.h" +#include "los_list.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_queue + * Queue error code: The maximum number of queue resources is configured to 0. + * + * Value: 0x02000600 + * + * Solution: Configure the maximum number of queue resources to be greater than 0. If queue modules are not used, + * set the configuration item for the tailoring of the maximum number of queue resources to NO. + */ +#define LOS_ERRNO_QUEUE_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x00) + +/** + * @ingroup los_queue + * Queue error code: The queue block memory fails to be initialized. + * + * Value: 0x02000601 + * + * Solution: Allocate the queue block bigger memory partition, or decrease the maximum number of queue resources. + */ +#define LOS_ERRNO_QUEUE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x01) + +/** + * @ingroup los_queue + * Queue error code: The memory for queue creation fails to be requested. + * + * Value: 0x02000602 + * + * Solution: Allocate more memory for queue creation, or decrease the queue length and the number of nodes + * in the queue to be created. + */ +#define LOS_ERRNO_QUEUE_CREATE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x02) + +/** + * @ingroup los_queue + * Queue error code: The size of the biggest message in the created queue is too big. + * + * Value: 0x02000603 + * + * Solution: Change the size of the biggest message in the created queue. + */ +#define LOS_ERRNO_QUEUE_SIZE_TOO_BIG LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x03) + +/** + * @ingroup los_queue + * Queue error code: The upper limit of the number of created queues is exceeded. + * + * Value: 0x02000604 + * + * Solution: Increase the configured number of resources for queues. + */ +#define LOS_ERRNO_QUEUE_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x04) + +/** + * @ingroup los_queue + * Queue error code: Invalid queue. + * + * Value: 0x02000605 + * + * Solution: Ensure that the passed-in queue ID is valid. + */ +#define LOS_ERRNO_QUEUE_NOT_FOUND LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x05) + +/** + * @ingroup los_queue + * Queue error code: The task is forbidden to be blocked on a queue when the task is locked. + * + * Value: 0x02000606 + * + * Solution: Unlock the task before using a queue. + */ +#define LOS_ERRNO_QUEUE_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x06) + +/** + * @ingroup los_queue + * Queue error code: The time set for waiting to processing the queue expires. + * + * Value: 0x02000607 + * + * Solution: Check whether the expiry time setting is appropriate. + */ +#define LOS_ERRNO_QUEUE_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x07) + +/** + * @ingroup los_queue + * Queue error code: The queue that blocks a task cannot be deleted. + * + * Value: 0x02000608 + * + * Solution: Enable the task to obtain resources rather than be blocked on the queue. + */ +#define LOS_ERRNO_QUEUE_IN_TSKUSE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x08) + +/** + * @ingroup los_queue + * Queue error code: The queue cannot be written during an interrupt when the time for waiting to + * processing the queue expires. + * + * Value: 0x02000609 + * + * Solution: Set the expiry time to the never-waiting mode, or use asynchronous queues. + */ +#define LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x09) + +/** + * @ingroup los_queue + * Queue error code: The queue is not created. + * + * Value: 0x0200060a + * + * Solution: Check whether the passed-in queue handle value is valid. + */ +#define LOS_ERRNO_QUEUE_NOT_CREATE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0a) + +/** + * @ingroup los_queue + * Queue error code: Queue reading and writing are not synchronous. + * + * Value: 0x0200060b + * + * Solution: Synchronize queue reading with queue writing. + */ +#define LOS_ERRNO_QUEUE_IN_TSKWRITE LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0b) + +/** + * @ingroup los_queue + * Queue error code: Parameters passed in during queue creation are null pointers. + * + * Value: 0x0200060c + * + * Solution: Ensure the passed-in parameters are not null pointers. + */ +#define LOS_ERRNO_QUEUE_CREAT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0c) + +/** + * @ingroup los_queue + * Queue error code: The queue length or message node size passed in during queue creation is 0. + * + * Value: 0x0200060d + * + * Solution: Pass in correct queue length and message node size. + */ +#define LOS_ERRNO_QUEUE_PARA_ISZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0d) + +/** + * @ingroup los_queue + * Queue error code: The handle of the queue is invalid. + * + * Value: 0x0200060e + * + * Solution: Check whether the passed-in queue handle value is valid. + */ +#define LOS_ERRNO_QUEUE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0e) + +/** + * @ingroup los_queue + * Queue error code: The pointer passed in during queue reading is null. + * + * Value: 0x0200060f + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_READ_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x0f) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue reading is 0. + * + * Value: 0x02000610 + * + * Solution: Pass in a correct buffer size. + */ +#define LOS_ERRNO_QUEUE_READSIZE_ISZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x10) + +/** + * @ingroup los_queue + * Queue error code: The pointer passed in during queue writing is null. + * + * Value: 0x02000612 + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_WRITE_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x12) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue writing is 0. + * + * Value: 0x02000613 + * + * Solution: Pass in a correct buffer size. + */ +#define LOS_ERRNO_QUEUE_WRITESIZE_ISZERO LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x13) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue writing is bigger than the queue size. + * + * Value: 0x02000615 + * + * Solution: Decrease the buffer size, or use a queue in which nodes are bigger. + */ +#define LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x15) + +/** + * @ingroup los_queue + * Queue error code: No free node is available during queue writing. + * + * Value: 0x02000616 + * + * Solution: Ensure that free nodes are available before queue writing. + */ +#define LOS_ERRNO_QUEUE_ISFULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x16) + +/** + * @ingroup los_queue + * Queue error code: The pointer passed in when the queue information is being obtained is null. + * + * Value: 0x02000617 + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x17) + +/** + * @ingroup los_queue + * Queue error code: The queue cannot be read during an interrupt + * when the time for waiting to processing the queue expires. + * + * Value: 0x02000618 + * + * Solution: Set the expiry time to the never-waiting mode, or use asynchronous queues. + */ +#define LOS_ERRNO_QUEUE_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x18) + +/** + * @ingroup los_queue + * Queue error code: The handle of the queue passed-in when the memory for the queue is being freed is invalid. + * + * Value: 0x02000619 + * + * Solution: Check whether the passed-in queue handle value is valid. + */ +#define LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x19) + +/** + * @ingroup los_queue + * Queue error code: The pointer to the memory to be freed is null. + * + * Value: 0x0200061a + * + * Solution: Check whether the passed-in pointer is null. + */ +#define LOS_ERRNO_QUEUE_MAIL_PTR_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1a) + +/** + * @ingroup los_queue + * Queue error code: The memory for the queue fails to be freed. + * + * Value: 0x0200061b + * + * Solution: Pass in correct input parameters. + */ +#define LOS_ERRNO_QUEUE_MAIL_FREE_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1b) + +/** + * @ingroup los_queue + * Queue error code: No resource is in the queue that is being read when the + * time for waiting to processing the queue expires. + * + * Value: 0x0200061d + * + * Solution: Ensure that the queue contains messages when it is being read. + */ +#define LOS_ERRNO_QUEUE_ISEMPTY LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1d) + +/** + * @ingroup los_queue + * Queue error code: The buffer size passed in during queue readding is smaller than the queue size. + * + * Value: 0x0200061f + * + * Solution: Increase the buffer size, or use a queue in which nodes are smaller. + */ +#define LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_QUE, 0x1f) + +/** + * @ingroup los_queue + * Structure of the block for queue information query + */ +typedef struct tagQueueInfo { + UINT32 queueID; /**< Queue ID */ + UINT16 queueLen; /**< Queue length */ + UINT16 queueSize; /**< Node size */ + UINT16 queueHead; /**< Node head */ + UINT16 queueTail; /**< Node tail */ + UINT16 writableCnt; /**< Count of writable resources */ + UINT16 readableCnt; /**< Count of readable resources */ + UINT32 waitReadTask; /**< Resource reading task */ + UINT32 waitWriteTask; /**< Resource writing task */ + UINT32 waitMemTask; /**< Memory task */ +} QUEUE_INFO_S; + +/** + * @ingroup los_queue + * @brief Create a message queue. + * + * @par Description: + * This API is used to create a message queue. + * @attention + *
      + *
    • Threre are LOSCFG_BASE_IPC_QUEUE_LIMIT queues available, change it's value when necessory.
    • + *
    + * @param queueName [IN] Message queue name. Reserved parameter, not used for now. + * @param len [IN] Queue length. The value range is [1,0xffff]. + * @param queueID [OUT] ID of the queue control structure that is successfully created. + * @param flags [IN] Queue mode. Reserved parameter, not used for now. + * @param maxMsgSize [IN] Node size. The value range is [1,0xffff-4]. + * + * @retval #LOS_OK The message queue is successfully created. + * @retval #LOS_ERRNO_QUEUE_CB_UNAVAILABLE The upper limit of the number of created queues is exceeded. + * @retval #LOS_ERRNO_QUEUE_CREATE_NO_MEMORY Insufficient memory for queue creation. + * @retval #LOS_ERRNO_QUEUE_CREAT_PTR_NULL Null pointer, queueID is NULL. + * @retval #LOS_ERRNO_QUEUE_PARA_ISZERO The queue length or message node size passed in during queue + * creation is 0. + * @retval #LOS_ERRNO_QUEUE_SIZE_TOO_BIG The parameter maxMsgSize is larger than 0xffff - 4. + * @par Dependency: + *
    • los_queue.h: the header file that contains the API declaration.
    + * @see LOS_QueueDelete + */ +extern UINT32 LOS_QueueCreate(CHAR *queueName, + UINT16 len, + UINT32 *queueID, + UINT32 flags, + UINT16 maxMsgSize); + +/** + * @ingroup los_queue + * @brief Read a queue. + * + * @par Description: + * This API is used to read data in a specified queue, and store the obtained data to the address specified + * by bufferAddr. The address and the size of the data to be read are defined by users. + * @attention + *
      + *
    • The specific queue should be created firstly.
    • + *
    • Queue reading adopts the fist in first out (FIFO) mode. The data that is first stored in the queue is read + * first.
    • + *
    • bufferAddr stores the obtained data.
    • + *
    • Do not read or write a queue in unblocking modes such as an interrupt.
    • + *
    • This API cannot be called before the Huawei LiteOS is initialized.
    • + *
    • The argument timeOut is a relative time.
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the obtained data. The starting address must not be + * null. + * @param bufferSize [IN/OUT] Where to maintain the buffer wantted-size before read, and the real-size after read. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The queue is successfully read. + * @retval #LOS_ERRNO_QUEUE_INVALID The handle of the queue that is being read is invalid. + * @retval #LOS_ERRNO_QUEUE_READ_PTR_NULL The pointer passed in during queue reading is null. + * @retval #LOS_ERRNO_QUEUE_READSIZE_ISZERO The buffer size passed in during queue reading is 0. + * @retval #LOS_ERRNO_QUEUE_READ_IN_INTERRUPT The queue cannot be read during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue to be read is not created. + * @retval #LOS_ERRNO_QUEUE_ISEMPTY No resource is in the queue that is being read when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL The buffer size passed in during queue reading is less than + * the queue size. + * @par Dependency: + *
    • los_queue.h: the header file that contains the API declaration.
    + * @see LOS_QueueWriteCopy | LOS_QueueCreate + */ +extern UINT32 LOS_QueueReadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 *bufferSize, + UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Write data into a queue. + * + * @par Description: + * This API is used to write the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr into a queue. + * @attention + *
      + *
    • The specific queue should be created firstly.
    • + *
    • Do not read or write a queue in unblocking modes such as interrupt.
    • + *
    • This API cannot be called before the Huawei LiteOS is initialized.
    • + *
    • The data to be written is of the size specified by bufferSize and is stored at the address specified by + * BufferAddr.
    • + *
    • The argument timeOut is a relative time.
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [IN] Starting address that stores the data to be written.The starting address must + * not be null. + * @param bufferSize [IN] Passed-in buffer size. The value range is [1,USHRT_MAX - sizeof(UINT32)]. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time + * for waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when + * the task is locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
    • los_queue.h: the header file that contains the API declaration.
    + * @see LOS_QueueReadCopy | LOS_QueueCreate + */ +extern UINT32 LOS_QueueWriteCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Read a queue. + * + * @par Description: + * This API is used to read the address of data in a specified queue, and store it to the address specified by + * bufferAddr. + * @attention + *
      + *
    • The specific queue should be created firstly.
    • + *
    • Queue reading adopts the fist in first out (FIFO) mode. The data that is first stored in the queue is + * read first.
    • + *
    • bufferAddr stores the obtained data address.
    • + *
    • Do not read or write a queue in unblocking modes such as an interrupt.
    • + *
    • This API cannot be called before the Huawei LiteOS is initialized.
    • + *
    • The argument timeOut is a relative time.
    • + *
    • The bufferSize is not really used in LOS_QueueRead, because the interface is only used to + * obtain the address of data.
    • + *
    • The buffer which the bufferAddr pointing to must be greater than or equal to 4 bytes.
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the obtained data. The starting address must + * not be null. + * @param bufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The queue is successfully read. + * @retval #LOS_ERRNO_QUEUE_INVALID The handle of the queue that is being read is invalid. + * @retval #LOS_ERRNO_QUEUE_READ_PTR_NULL The pointer passed in during queue reading is null. + * @retval #LOS_ERRNO_QUEUE_READSIZE_ISZERO The buffer size passed in during queue reading is 0. + * @retval #LOS_ERRNO_QUEUE_READ_IN_INTERRUPT The queue cannot be read during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue to be read is not created. + * @retval #LOS_ERRNO_QUEUE_ISEMPTY No resource is in the queue that is being read when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
    • los_queue.h: The header file that contains the API declaration.
    + * @see LOS_QueueWrite | LOS_QueueCreate + */ +extern UINT32 LOS_QueueRead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Write data into a queue. + * + * @par Description: + * This API is used to write the address of data specified by bufferAddr into a queue. + * @attention + *
      + *
    • The specific queue should be created firstly.
    • + *
    • Do not read or write a queue in unblocking modes such as an interrupt.
    • + *
    • This API cannot be called before the Huawei LiteOS is initialized.
    • + *
    • The address of the data of the size specified by bufferSize and stored at the address specified by + * BufferAddr is to be written.
    • + *
    • The argument timeOut is a relative time.
    • + *
    • The bufferSize is not really used in LOS_QueueWrite, because the interface is only used to write the address + * of data specified by bufferAddr into a queue.
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [IN] Starting address that stores the data to be written. The starting address + * must not be null. + * @param bufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
    • los_queue.h: The header file that contains the API declaration.
    + * @see LOS_QueueRead | LOS_QueueCreate + */ +extern UINT32 LOS_QueueWrite(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Write data into a queue header. + * + * @par Description: + * This API is used to write the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr into a queue header. + * @attention + *
      + *
    • Do not read or write a queue in unblocking modes such as an interrupt.
    • + *
    • This API cannot be called before the Huawei LiteOS is initialized.
    • + *
    • The address of the data of the size specified by bufferSize and stored at the address specified by + * BufferAddr is to be written.
    • + *
    • The argument timeOut is a relative time.
    • + *
    • LOS_QueueRead and LOS_QueueWriteHead are a set of interfaces, and the two groups of interfaces need to be used. + *
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the data to be written. The starting address + * must not be null. + * @param bufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
    • los_queue.h: The header file that contains the API declaration.
    + * @see LOS_QueueRead | LOS_QueueCreate + */ +extern UINT32 LOS_QueueWriteHead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Write data into a queue header. + * + * @par Description: + * This API is used to write the data of the size specified by bufferSize and stored at the address specified by + * bufferAddr into a queue header. + * @attention + *
      + *
    • Do not read or write a queue in unblocking modes such as an interrupt.
    • + *
    • This API cannot be called before the Huawei LiteOS is initialized.
    • + *
    • The address of the data of the size specified by bufferSize and stored at the address specified by + * BufferAddr is to be written.
    • + *
    • The argument timeOut is a relative time.
    • + *
    • LOS_QueueRead and LOS_QueueWriteHead are a set of interfaces, and the two groups of interfaces need to be + * used.
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param bufferAddr [OUT] Starting address that stores the data to be written. + * The starting address must not be null. + * @param bufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. + * @param timeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER](unit: Tick). + * + * @retval #LOS_OK The data is successfully written into the queue. + * @retval #LOS_ERRNO_QUEUE_INVALID The queue handle passed in during queue writing is invalid. + * @retval #LOS_ERRNO_QUEUE_WRITE_PTR_NULL The pointer passed in during queue writing is null. + * @retval #LOS_ERRNO_QUEUE_WRITESIZE_ISZERO The buffer size passed in during queue writing is 0. + * @retval #LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT The queue cannot be written during an interrupt when the time for + * waiting to processing the queue expires. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue into which the data is written is not created. + * @retval #LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG The buffer size passed in during queue writing is bigger than + * the queue size. + * @retval #LOS_ERRNO_QUEUE_ISFULL No free node is available during queue writing. + * @retval #LOS_ERRNO_QUEUE_PEND_IN_LOCK The task is forbidden to be blocked on a queue when the task is + * locked. + * @retval #LOS_ERRNO_QUEUE_TIMEOUT The time set for waiting to processing the queue expires. + * @par Dependency: + *
    • los_queue.h: The header file that contains the API declaration.
    + * @see LOS_QueueWrite | LOS_QueueWriteHead + */ +extern UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeOut); + +/** + * @ingroup los_queue + * @brief Delete a queue. + * + * @par Description: + * This API is used to delete a queue. + * @attention + *
      + *
    • This API cannot be used to delete a queue that is not created.
    • + *
    • A synchronous queue fails to be deleted if any tasks are blocked on it, or some queues are being read or + * written.
    • + *
    + * + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * + * @retval #LOS_OK The queue is successfully deleted. + * @retval #LOS_ERRNO_QUEUE_NOT_FOUND The queue cannot be found. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue handle passed in when the queue is being deleted is + * incorrect. + * @retval #LOS_ERRNO_QUEUE_IN_TSKUSE The queue that blocks a task cannot be deleted. + * @retval #LOS_ERRNO_QUEUE_IN_TSKWRITE Queue reading and writing are not synchronous. + * @par Dependency: + *
    • los_queue.h: the header file that contains the API declaration.
    + * @see LOS_QueueCreate | LOS_QueueCreate + */ +extern UINT32 LOS_QueueDelete(UINT32 queueID); + +/** + * @ingroup los_queue + * @brief Obtain queue information. + * + * @par Description: + * This API is used to obtain queue information. + * @attention + *
      + *
    • The specific queue should be created firstly.
    • + *
    + * @param queueID [IN] Queue ID created by LOS_QueueCreate. The value range is + * [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. + * @param queueInfo [OUT] The queue information to be read must not be null. + * + * @retval #LOS_OK The queue information is successfully obtained. + * @retval #LOS_ERRNO_QUEUE_PTR_NULL The pointer to the queue information to be obtained is null. + * @retval #LOS_ERRNO_QUEUE_INVALID The handle of the queue that is being read is invalid. + * @retval #LOS_ERRNO_QUEUE_NOT_CREATE The queue in which the information to be obtained is stored is + * not created. + * + * @par Dependency: + *
    • los_queue.h: the header file that contains the API declaration.
    + * @see LOS_QueueCreate + */ +extern UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_H */ diff --git a/kernel/include/los_sem.h b/kernel/include/los_sem.h new file mode 100755 index 00000000..57f912fa --- /dev/null +++ b/kernel/include/los_sem.h @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_sem Semaphore + * @ingroup kernel + */ + +#ifndef _LOS_SEM_H +#define _LOS_SEM_H + +#include "los_base.h" +#include "los_err.h" +#include "los_list.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sem + * Semaphore error code: The memory is insufficient. + * + * Value: 0x02000700 + * + * Solution: Allocate more memory. + */ +#define LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00) + +/** + * @ingroup los_sem + * Semaphore error code: Invalid parameter. + * + * Value: 0x02000701 + * + * Solution: Change the passed-in invalid parameter value to a valid value. + */ +#define LOS_ERRNO_SEM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x01) + +/** + * @ingroup los_sem + * Semaphore error code: Null pointer. + * + * Value: 0x02000702 + * + * Solution: Change the passed-in null pointer to a valid non-null pointer. + */ +#define LOS_ERRNO_SEM_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x02) + +/** + * @ingroup los_sem + * Semaphore error code: No semaphore control structure is available. + * + * Value: 0x02000703 + * + * Solution: Perform corresponding operations based on the requirements in the code context. + */ +#define LOS_ERRNO_SEM_ALL_BUSY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x03) + +/** +* @ingroup los_sem +* Semaphore error code: Invalid parameter that specifies the timeout interval. +* +* Value: 0x02000704 +* +* +* Solution: Change the passed-in parameter value to a valid nonzero value. +*/ +#define LOS_ERRNO_SEM_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x04) + +/** +* @ingroup los_sem +* Semaphore error code: The API is called during an interrupt, which is forbidden. +* +* Value: 0x02000705 +* +* Solution: Do not call the API during an interrupt. +*/ +#define LOS_ERRNO_SEM_PEND_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x05) + +/** +* @ingroup los_sem +* Semaphore error code: The task is unable to request a semaphore because task scheduling is locked. +* +* Value: 0x02000706 +* +* Solution: Do not call LOS_SemPend when task scheduling is locked. +*/ +#define LOS_ERRNO_SEM_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x06) + +/** + * @ingroup los_sem + * Semaphore error code: The request for a semaphore times out. + * + * Value: 0x02000707 + * + * Solution: Change the passed-in parameter value to the value within the valid range. + */ +#define LOS_ERRNO_SEM_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x07) + +/** + * @ingroup los_sem + * Semaphore error code: The times of semaphore release exceed the maximum times permitted. + * + * Value: 0x02000708 + * + * Solution: Perform corresponding operations based on the requirements in the code context. + */ +#define LOS_ERRNO_SEM_OVERFLOW LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x08) + +/** + * @ingroup los_sem + * Semaphore error code: The queue of the tasks that are waiting on the semaphore control structure is not null. + * + * Value: 0x02000709 + * + * Solution: Delete the semaphore after awaking all tasks that are waiting on the semaphore. + */ +#define LOS_ERRNO_SEM_PENDED LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x09) + +/** + * @ingroup los_sem + * Semaphore error code: LOS_ERRNO_SEM_MAXNUM_ZERO is error. + * + * Value: 0x0200070A + * + * Solution: LOS_ERRNO_SEM_MAXNUM_ZERO should not be error. + */ +#define LOS_ERRNO_SEM_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x0A) + +/** + * @ingroup los_sem + * @brief Create a Counting semaphore. + * + * @par Description: + * This API is used to create a semaphore control structure according to the initial number of available semaphores + * specified by count and return the ID of this semaphore control structure. + * @attention + *
      + *
    • None.
    • + *
    + * + * @param count [IN] Initial number of available semaphores. The value range is [0, OS_SEM_COUNTING_MAX_COUNT). + * @param semHandle [OUT] ID of the semaphore control structure that is initialized. + * + * @retval #LOS_ERRNO_SEM_PTR_NULL The passed-in semHandle value is NULL. + * @retval #LOS_ERRNO_SEM_OVERFLOW The passed-in count value is greater than the maximum number of available + * semaphores. + * @retval #LOS_ERRNO_SEM_ALL_BUSY No semaphore control structure is available. + * @retval #LOS_OK The semaphore is successfully created. + * @par Dependency: + *
    • los_sem.h: the header file that contains the API declaration.
    + * @see LOS_SemDelete + */ +extern UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle); + +/** + * @ingroup los_sem + * @brief Create a binary semaphore. + * + * @par Description: + * This API is used to create a binary semaphore control structure according to the initial number of available + * semaphores specified by count and return the ID of this semaphore control structure. + * @attention + *
      + *
    • None.
    • + *
    + * + * @param count [IN] Initial number of available semaphores. The value range is [0, 1]. + * @param semHandle [OUT] ID of the semaphore control structure that is initialized. + * + * @retval #LOS_ERRNO_SEM_PTR_NULL The passed-in semHandle value is NULL. + * @retval #LOS_ERRNO_SEM_OVERFLOW The passed-in count value is greater than the maximum number of available + * semaphores. + * @retval #LOS_ERRNO_SEM_ALL_BUSY No semaphore control structure is available. + * @retval #LOS_OK The semaphore is successfully created. + * @par Dependency: + *
    • los_sem.h: the header file that contains the API declaration.
    + * @see LOS_SemDelete + */ +extern UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle); + +/** + * @ingroup los_sem + * @brief Delete a semaphore. + * + * @par Description: + * This API is used to delete a semaphore control structure that has an ID specified by semHandle. + * @attention + *
      + *
    • The specified sem id must be created first.
    • + *
    + * + * @param semHandle [IN] ID of the semaphore control structure to be deleted. The ID of the semaphore + * control structure is obtained from semaphore creation. + * + * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. + * @retval #LOS_ERRNO_SEM_PENDED The queue of the tasks that are waiting on the semaphore control structure is + * not null. + * @retval #LOS_OK The semaphore control structure is successfully deleted. + * @par Dependency: + *
    • los_sem.h: the header file that contains the API declaration.
    + * @see LOS_SemCreate + */ +extern UINT32 LOS_SemDelete(UINT32 semHandle); + +/** + * @ingroup los_sem + * @brief Request a semaphore. + * + * @par Description: + * This API is used to request a semaphore based on the semaphore control structure ID specified by semHandle and the + * parameter that specifies the timeout period. + * @attention + *
      + *
    • The specified sem id must be created first.
    • + *
    + * + * @param semHandle [IN] ID of the semaphore control structure to be requested. The ID of the semaphore control + * structure is obtained from semaphore creation. + * @param timeout [IN] Timeout interval for waiting on the semaphore. The value range is [0, 0xFFFFFFFF]. + * If the value is set to 0, the semaphore is not waited on. If the value is set to 0xFFFFFFFF, + * the semaphore is waited on forever(unit: Tick). + * + * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. + * @retval #LOS_ERRNO_SEM_UNAVAILABLE There is no available semaphore resource. + * @retval #LOS_ERRNO_SEM_PEND_INTERR The API is called during an interrupt, which is forbidden. + * @retval #LOS_ERRNO_SEM_PEND_IN_LOCK The task is unable to request a semaphore because task scheduling is locked. + * @retval #LOS_ERRNO_SEM_TIMEOUT The request for the semaphore times out. + * @retval #LOS_OK The semaphore request succeeds. + * @par Dependency: + *
    • los_sem.h: the header file that contains the API declaration.
    + * @see LOS_SemPost | LOS_SemCreate + */ +extern UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout); + +/** + * @ingroup los_sem + * @brief Release a semaphore. + * + * @par Description: + * This API is used to release a semaphore that has a semaphore control structure ID specified by semHandle. + * @attention + *
      + *
    • The specified sem id must be created first.
    • + *
    + * + * @param semHandle [IN] ID of the semaphore control structure to be released.The ID of the semaphore control + * structure is obtained from semaphore creation. + * + * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. + * @retval #LOS_ERRNO_SEM_OVERFLOW The times of semaphore release exceed the maximum times permitted. + * @retval #LOS_OK The semaphore is successfully released. + * @par Dependency: + *
    • los_sem.h: the header file that contains the API declaration.
    + * @see LOS_SemPend | LOS_SemCreate + */ +extern UINT32 LOS_SemPost(UINT32 semHandle); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SEM_H */ diff --git a/kernel/include/los_slab.h b/kernel/include/los_slab.h new file mode 100755 index 00000000..4bdedbc8 --- /dev/null +++ b/kernel/include/los_slab.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_slab Slab + * @ingroup kernel + */ + +#ifndef _LOS_SLAB_H +#define _LOS_SLAB_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +// number of slab class +#define SLAB_MEM_COUNT 4 + +// step size of each class +#define SLAB_MEM_CALSS_STEP_SIZE 0x10 + +// max size of each class +#define SLAB_MEM_ALLOCATOR_SIZE 512 + +#define SLAB_BASIC_NEED_SIZE 0x1000 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif + diff --git a/kernel/include/los_swtmr.h b/kernel/include/los_swtmr.h new file mode 100755 index 00000000..bcf5ccbb --- /dev/null +++ b/kernel/include/los_swtmr.h @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_swtmr Software timer + * @ingroup kernel + */ + +#ifndef _LOS_SWTMR_H +#define _LOS_SWTMR_H + +#include "los_base.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_swtmr + * Software timer error code: The timeout handling function is NULL. + * + * Value: 0x02000300 + * + * Solution: Define the timeout handling function. + */ +#define LOS_ERRNO_SWTMR_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00) + +/** + * @ingroup los_swtmr + * Software timer error code: The expiration time is 0. + * + * Value: 0x02000301 + * + * Solution: Re-define the expiration time. + */ +#define LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x01) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid software timer mode. + * + * Value: 0x02000302 + * + * Solution: Check the mode value. The value range is [0,3]. + */ +#define LOS_ERRNO_SWTMR_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x02) + +/** + * @ingroup los_swtmr + * Software timer error code: The passed-in software timer ID is NULL. + * + * Value: 0x02000303 + * + * Solution: Define the software timer ID before passing it in. + */ +#define LOS_ERRNO_SWTMR_RET_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x03) + +/** + * @ingroup los_swtmr + * Software timer error code: The number of software timers exceeds the configured permitted maximum number. + * + * Value: 0x02000304 + * + * Solution: Re-configure the permitted maximum number of software timers, or wait for a software timer to become + * available. + */ +#define LOS_ERRNO_SWTMR_MAXSIZE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x04) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid software timer ID. + * + * Value: 0x02000305 + * + * Solution: Pass in a valid software timer ID. + */ +#define LOS_ERRNO_SWTMR_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x05) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer is not created. + * + * Value: 0x02000306 + * + * Solution: Create a software timer. + */ +#define LOS_ERRNO_SWTMR_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x06) + +/** + * @ingroup los_swtmr + * Software timer error code: Insufficient memory for software timer linked list creation. + * + * Value: 0x02000307 + * + * Solution: Allocate bigger memory partition to software timer linked list creation. + */ +#define LOS_ERRNO_SWTMR_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x07) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid configured number of software timers. + * + * Value: 0x02000308 + * + * Solution: Re-configure the number of software timers. + */ +#define LOS_ERRNO_SWTMR_MAXSIZE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x08) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer is being used during an interrupt. + * + * Value: 0x02000309 + * + * Solution: Change the source code and do not use the software timer during an interrupt. + */ +#define LOS_ERRNO_SWTMR_HWI_ACTIVE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x09) + +/** + * @ingroup los_swtmr + * Software timer error code: Insufficient memory allocated by membox. + * + * Value: 0x0200030a + * + * Solution: Expand the memory allocated by membox. + */ +#define LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0a) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer queue fails to be created. + * + * Value: 0x0200030b + * + * Solution: Check whether more memory can be allocated to the queue to be created. + */ +#define LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0b) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer task fails to be created. + * + * Value: 0x0200030c + * + * Solution: Check whether the memory is sufficient and re-create the task. + */ +#define LOS_ERRNO_SWTMR_TASK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0c) + +/** + * @ingroup los_swtmr + * Software timer error code: The software timer is not started. + * + * Value: 0x0200030d + * + * Solution: Start the software timer. + */ +#define LOS_ERRNO_SWTMR_NOT_STARTED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0d) + +/** + * @ingroup los_swtmr + * Software timer error code: Invalid software timer state. + * + * Value: 0x0200030e + * + * Solution: Check the software timer state. + */ +#define LOS_ERRNO_SWTMR_STATUS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0e) + +/** + * @ingroup los_swtmr + * This error code is not in use temporarily. + */ +#define LOS_ERRNO_SWTMR_SORTLIST_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0f) + +/** + * @ingroup los_swtmr + * Software timer error code: The passed-in number of remaining Ticks configured on the software timer is NULL. + * + * Value: 0x02000310 + * + * Solution: Define a variable of the number of remaining Ticks before passing in the number of remaining Ticks. + */ +#define LOS_ERRNO_SWTMR_TICK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x10) + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +#define OS_ERRNO_SWTMR_ROUSES_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x11) +#define OS_ERRNO_SWTMR_ALIGN_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x12) + +enum enSwTmrRousesType { + OS_SWTMR_ROUSES_IGNORE, /* timer don't need to wake up system */ + OS_SWTMR_ROUSES_ALLOW, /* timer can wake up system */ +}; + +enum enSwTmrAlignSensitive { + OS_SWTMR_ALIGN_SENSITIVE, /* timer don't need to align */ + OS_SWTMR_ALIGN_INSENSITIVE, /* timer need to align */ +}; +#endif + +/** + * @ingroup los_swtmr + * Software timer mode + */ +enum EnSwTmrType { + LOS_SWTMR_MODE_ONCE, /* One-off software timer */ + LOS_SWTMR_MODE_PERIOD, /* Periodic software timer */ + LOS_SWTMR_MODE_NO_SELFDELETE, /* One-off software timer, but not self-delete */ + LOS_SWTMR_MODE_OPP, /* After the one-off timer finishes timing, + the periodic software timer is enabled. + This mode is not supported temporarily. */ +}; + +/** +* @ingroup los_swtmr +* @brief Define the type of a callback function that handles software timer timeout. +* +* @par Description: +* This API is used to define the type of a callback function that handles software timer timeout, so that it can be +* called when software timer timeout. +* +* @attention +*
      +*
    • None.
    • +*
    +* +* @param para [IN] the parameter of the callback function that handles software timer timeout. +* +* @retval None. +* @par Dependency: +*
    • los_swtmr.h: the header file that contains the API declaration.
    +* @see None. +*/ +typedef VOID (*SWTMR_PROC_FUNC)(UINT32 para); + +/** + * @ingroup los_swtmr + * Software timer control structure + */ +typedef struct tagSwTmrCtrl { + struct tagSwTmrCtrl *pstNext; /* Pointer to the next software timer */ + UINT8 ucState; /* Software timer state */ + UINT8 ucMode; /* Software timer mode */ +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + UINT8 ucRouses; /* wake up enable */ + UINT8 ucSensitive; /* align enable */ +#endif + UINT16 usTimerID; /* Software timer ID */ + UINT32 uwCount; /* Times that a software timer works */ + UINT32 uwInterval; /* Timeout interval of a periodic software timer */ + UINT32 uwArg; /* Parameter passed in when the callback function + that handles software timer timeout is called */ + SWTMR_PROC_FUNC pfnHandler; /* Callback function that handles software timer timeout */ +} SWTMR_CTRL_S; + + +/** + * @ingroup los_swtmr + * @brief Start a software timer. + * + * @par Description: + * This API is used to start a software timer that has a specified ID. + * @attention + *
      + *
    • The specific timer must be created first
    • + *
    + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The software timer is successfully started. + * @par Dependency: + *
    • los_swtmr.h: the header file that contains the API declaration.
    + * @see LOS_SwtmrStop | LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrStart(UINT16 swtmrID); + +/** + * @ingroup los_swtmr + * @brief Stop a software timer. + * + * @par Description: + * This API is used to stop a software timer that has a specified ID. + * @attention + *
      + *
    • The specific timer should be created and started firstly.
    • + *
    + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_NOT_STARTED The software timer is not started. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The software timer is successfully stopped. + * @par Dependency: + *
    • los_swtmr.h: the header file that contains the API declaration.
    + * @see LOS_SwtmrStart | LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrStop(UINT16 swtmrID); + +/** + * @ingroup los_swtmr + * @brief Obtain the number of remaining Ticks configured on a software timer. + * + * @par Description: + * This API is used to obtain the number of remaining Ticks configured on the software timer of which the ID is + * specified by usSwTmrID. + * @attention + *
      + *
    • The specific timer should be created and started successfully, error happends otherwise.
    • + *
    + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * @param tick [OUT] Number of remaining Ticks configured on the software timer. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_NOT_STARTED The software timer is not started. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The number of remaining Ticks is successfully obtained. + * @par Dependency: + *
    • los_swtmr.h: the header file that contains the API declaration.
    + * @see LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick); + +/** + * @ingroup los_swtmr + * @brief Create a software timer. + * + * @par Description: + * This API is used to create a software timer that has specified timing duration, timeout handling function, + * and trigger mode, and to return a handle by which the software timer can be referenced. + * @attention + *
      + *
    • Do not use the delay interface in the callback function that handles software timer timeout.
    • + *
    • Threre are LOSCFG_BASE_CORE_SWTMR_LIMIT timers available, change it's value when necessory.
    • + *
    + * + * @param interval [IN] Timing duration of the software timer to be created (unit: ms). + * @param mode [IN] Software timer mode. Pass in one of the modes specified by EnSwTmrType. There are three + * types of modes, one-off, periodic, and continuously periodic after one-off, of which the third mode is not + * supported temporarily. + * @param handler [IN] Callback function that handles software timer timeout. + * @param swtmrID [OUT] Software timer ID created by LOS_SwtmrCreate. + * @param arg [IN] Parameter passed in when the callback function that handles software timer timeout is + * called. + * + * @retval #LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED The software timer timeout interval is 0. + * @retval #LOS_ERRNO_SWTMR_MODE_INVALID Invalid software timer mode. + * @retval #LOS_ERRNO_SWTMR_PTR_NULL The callback function that handles software timer timeout is NULL. + * @retval #LOS_ERRNO_SWTMR_RET_PTR_NULL The passed-in software timer ID is NULL. + * @retval #LOS_ERRNO_SWTMR_MAXSIZE The number of software timers exceeds the configured permitted + * maximum number. + * @retval #LOS_OK The software timer is successfully created. + * @par Dependency: + *
    • los_swtmr.h: the header file that contains the API declaration.
    + * @see LOS_SwtmrDelete + */ +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +extern UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrID, + UINT32 arg, + UINT8 rouses, + UINT8 sensitive); +#else +extern UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrID, + UINT32 arg); +#endif + +/** + * @ingroup los_swtmr + * @brief Delete a software timer. + * + * @par Description: + * This API is used to delete a software timer. + * @attention + *
      + *
    • The specific timer should be created and then stopped firstly.
    • + *
    + * + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in + * [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. + * + * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. + * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. + * @retval #LOS_ERRNO_SWTMR_STATUS_INVALID Invalid software timer state. + * @retval #LOS_OK The software timer is successfully deleted. + * @par Dependency: + *
    • los_swtmr.h: the header file that contains the API declaration.
    + * @see LOS_SwtmrCreate + */ +extern UINT32 LOS_SwtmrDelete(UINT16 swtmrID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SWTMR_H */ diff --git a/kernel/include/los_sys.h b/kernel/include/los_sys.h new file mode 100755 index 00000000..5ede80f1 --- /dev/null +++ b/kernel/include/los_sys.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_sys System time + * @ingroup kernel + */ + +#ifndef _LOS_SYS_H +#define _LOS_SYS_H + +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sys + * Number of milliseconds in one second. + */ +#define OS_SYS_MS_PER_SECOND 1000 + +/** + * @ingroup los_sys + * Number of microseconds in one second. + */ +#define OS_SYS_US_PER_SECOND 1000000 + +/** + * @ingroup los_sys + * System time basic function error code: Null pointer. + * + * Value: 0x02000010 + * + * Solution: Check whether the input parameter is null. + */ +#define LOS_ERRNO_SYS_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x10) + +/** + * @ingroup los_sys + * System time basic function error code: Invalid system clock configuration. + * + * Value: 0x02000011 + * + * Solution: Configure a valid system clock in los_config.h. + */ +#define LOS_ERRNO_SYS_CLOCK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x11) + +/** + * @ingroup los_sys + * System time basic function error code: This error code is not in use temporarily. + * + * Value: 0x02000012 + * + * Solution: None. + */ +#define LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x12) + +/** + * @ingroup los_sys + * System time error code: This error code is not in use temporarily. + * + * Value: 0x02000013 + * + * Solution: None. + */ +#define LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x13) + +/** + * @ingroup los_sys + * System time error code: This error code is not in use temporarily. + * + * Value: 0x02000014 + * + * Solution: None. + */ +#define LOS_ERRNO_SYS_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x14) + +/** + * @ingroup los_typedef + * system time structure. + */ +typedef struct tagSysTime { + UINT16 uwYear; /**< value 1970 ~ 2038 or 1970 ~ 2100 */ + UINT8 ucMonth; /**< value 1 - 12 */ + UINT8 ucDay; /**< value 1 - 31 */ + UINT8 ucHour; /**< value 0 - 23 */ + UINT8 ucMinute; /**< value 0 - 59 */ + UINT8 ucSecond; /**< value 0 - 59 */ + UINT8 ucWeek; /**< value 0 - 6 */ +} SYS_TIME_S; + +/** + * @ingroup los_sys + * @brief Obtain the number of Ticks. + * + * @par Description: + * This API is used to obtain the number of Ticks. + * @attention + *
      + *
    • None
    • + *
    + * + * @param None + * + * @retval UINT64 The number of Ticks. + * @par Dependency: + *
    • los_sys.h: the header file that contains the API declaration.
    + * @see None + */ +extern UINT64 LOS_TickCountGet(VOID); + +/** + * @ingroup los_sys + * @brief Obtain the number of cycles in one second. + * + * @par Description: + * This API is used to obtain the number of cycles in one second. + * @attention + *
      + *
    • None
    • + *
    + * + * @param None + * + * @retval UINT32 Number of cycles obtained in one second. + * @par Dependency: + *
    • los_sys.h: the header file that contains the API declaration.
    + * @see None + */ +extern UINT32 LOS_CyclePerTickGet(VOID); + +/** + * @ingroup los_sys + * @brief Convert Ticks to milliseconds. + * + * @par Description: + * This API is used to convert Ticks to milliseconds. + * @attention + *
      + *
    • The number of milliseconds obtained through the conversion is 32-bit.
    • + *
    + * + * @param ticks [IN] Number of Ticks. The value range is (0,OS_SYS_CLOCK). + * + * @retval UINT32 Number of milliseconds obtained through the conversion. Ticks are successfully converted to + * milliseconds. + * @par Dependency: + *
    • los_sys.h: the header file that contains the API declaration.
    + * @see LOS_MS2Tick + */ +extern UINT32 LOS_Tick2MS(UINT32 ticks); + +/** + * @ingroup los_sys + * @brief Convert milliseconds to Ticks. + * + * @par Description: + * This API is used to convert milliseconds to Ticks. + * @attention + *
      + *
    • If the parameter passed in is equal to 0xFFFFFFFF, the retval is 0xFFFFFFFF. Pay attention to the value to be + * converted because data possibly overflows.
    • + *
    + * + * @param millisec [IN] Number of milliseconds. + * + * @retval UINT32 Number of Ticks obtained through the conversion. + * @par Dependency: + *
    • los_sys.h: the header file that contains the API declaration.
    + * @see LOS_Tick2MS + */ +extern UINT32 LOS_MS2Tick(UINT32 millisec); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SYS_H */ diff --git a/kernel/include/los_tables.h b/kernel/include/los_tables.h new file mode 100755 index 00000000..0d90ab0e --- /dev/null +++ b/kernel/include/los_tables.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_TABLES_H +#define _LOS_TABLES_H + +#include "los_typedef.h" + +#define TO_STRING(x) #x +#define X_TO_STRING(x) TO_STRING(x) + +#ifndef LOS_HAL_TABLE_WOW_BEGIN +#define LOS_HAL_TABLE_WOW_BEGIN(label, name) \ + __asm__(".section \".liteos.table." X_TO_STRING(name) ".wow.begin\",\"aw\"\n" \ + ".globl " X_TO_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_TO_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_TO_STRING(LOSARC_P2ALIGNMENT) "\n" X_TO_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n") +#endif + +#ifndef LOS_HAL_TABLE_WOW_END +#define LOS_HAL_TABLE_WOW_END(label, name) \ + __asm__(".section \".liteos.table." X_TO_STRING(name) ".wow.finish\",\"aw\"\n" \ + ".globl " X_TO_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_TO_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_TO_STRING(LOSARC_P2ALIGNMENT) "\n" X_TO_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n") +#endif + +#ifndef LOS_HAL_TABLE_SCATTER_BEGIN +#define LOS_HAL_TABLE_SCATTER_BEGIN(label, name) \ + __asm__(".section \".liteos.table." X_TO_STRING(name) ".scatter.begin\",\"aw\"\n" \ + ".globl " X_TO_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_TO_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_TO_STRING(LOSARC_P2ALIGNMENT) "\n" X_TO_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n") +#endif + +#ifndef LOS_HAL_TABLE_SCATTER_END +#define LOS_HAL_TABLE_SCATTER_END(label, name) \ + __asm__(".section \".liteos.table." X_TO_STRING(name) ".scatter.finish\",\"aw\"\n" \ + ".globl " X_TO_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_TO_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_TO_STRING(LOSARC_P2ALIGNMENT) "\n" X_TO_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n") +#endif + +#ifndef LOS_HAL_TABLE_BEGIN +#define LOS_HAL_TABLE_BEGIN(label, name) \ + __asm__(".section \".liteos.table." X_TO_STRING(name) ".begin\",\"aw\"\n" \ + ".globl " X_TO_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_TO_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_TO_STRING(LOSARC_P2ALIGNMENT) "\n" X_TO_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n") +#endif + +#ifndef LOS_HAL_TABLE_END +#define LOS_HAL_TABLE_END(label, name) \ + __asm__(".section \".liteos.table." X_TO_STRING(name) ".finish\",\"aw\"\n" \ + ".globl " X_TO_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_TO_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_TO_STRING(LOSARC_P2ALIGNMENT) "\n" X_TO_STRING(LOS_LABEL_DEFN(label)) ":\n" \ + ".previous\n") +#endif + +// This macro must be applied to any types whose objects are to be placed in tables +#ifndef LOS_HAL_TABLE_TYPE +#define LOS_HAL_TABLE_TYPE LOSBLD_ATTRIB_ALIGN(LOSARC_ALIGNMENT) +#endif + +#ifndef LOS_HAL_TABLE_EXTRA +#define LOS_HAL_TABLE_EXTRA(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_TO_STRING(name) ".extra") +#endif + +#ifndef LOS_HAL_TABLE_WOW_ENTRY +#define LOS_HAL_TABLE_WOW_ENTRY(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_TO_STRING(name) ".wow.data") \ + LOSBLD_ATTRIB_USED +#endif + +#ifndef LOS_HAL_TABLE_SCATTER_ENTRY +#define LOS_HAL_TABLE_SCATTER_ENTRY(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_TO_STRING(name) ".scatter.data") \ + LOSBLD_ATTRIB_USED +#endif + +#ifndef LOS_HAL_TABLE_ENTRY +#define LOS_HAL_TABLE_ENTRY(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_TO_STRING(name) ".data") \ + LOSBLD_ATTRIB_USED +#endif + +#ifndef LOS_HAL_TABLE_QUALIFIED_ENTRY +#define LOS_HAL_TABLE_QUALIFIED_ENTRY(name, qual) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_TO_STRING(name) ".data." X_TO_STRING(qual)) \ + LOSBLD_ATTRIB_USED +#endif + +#endif /* _LOS_TABLES_H */ diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h new file mode 100755 index 00000000..8485b772 --- /dev/null +++ b/kernel/include/los_task.h @@ -0,0 +1,1007 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_task Task + * @ingroup kernel + */ + +#ifndef _LOS_TASK_H +#define _LOS_TASK_H + +#include "los_base.h" +#include "los_list.h" +#include "los_sys.h" +#include "los_hw.h" +#include "los_tick.h" +#include "los_event.h" +#include "los_err.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_task + * Task error code: Insufficient memory for task creation. + * + * Value: 0x03000200 + * + * Solution: Allocate bigger memory partition to task creation. + */ +#define LOS_ERRNO_TSK_NO_MEMORY LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x00) + +/** + * @ingroup los_task + * Task error code: Null parameter. + * + * Value: 0x02000201 + * + * Solution: Check the parameter. + */ +#define LOS_ERRNO_TSK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x01) + +/** + * @ingroup los_task + * Task error code: The task stack is not aligned. + * + * Value: 0x02000202 + * + * Solution: Align the task stack. + */ +#define LOS_ERRNO_TSK_STKSZ_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x02) + +/** + * @ingroup los_task + * Task error code: Incorrect task priority. + * + * Value: 0x02000203 + * + * Solution: Re-configure the task priority by referring to the priority range. + */ +#define LOS_ERRNO_TSK_PRIOR_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x03) + +/** + * @ingroup los_task + * Task error code: The task entrance is NULL. + * + * Value: 0x02000204 + * + * Solution: Define the task entrance function. + */ +#define LOS_ERRNO_TSK_ENTRY_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x04) + +/** + * @ingroup los_task + * Task error code: The task name is NULL. + * + * Value: 0x02000205 + * + * Solution: Set the task name. + */ +#define LOS_ERRNO_TSK_NAME_EMPTY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x05) + +/** + * @ingroup los_task + * Task error code: The task stack size is too small. + * + * Value: 0x02000206 + * + * Solution: Expand the task stack. + */ +#define LOS_ERRNO_TSK_STKSZ_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x06) + +/** + * @ingroup los_task + * Task error code: Invalid task ID. + * + * Value: 0x02000207 + * + * Solution: Check the task ID. + */ +#define LOS_ERRNO_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x07) + +/** + * @ingroup los_task + * Task error code: The task is already suspended. + * + * Value: 0x02000208 + * + * Solution: Suspend the task after it is resumed. + */ +#define LOS_ERRNO_TSK_ALREADY_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x08) + +/** + * @ingroup los_task + * Task error code: The task is not suspended. + * + * Value: 0x02000209 + * + * Solution: Suspend the task. + */ +#define LOS_ERRNO_TSK_NOT_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x09) + +/** + * @ingroup los_task + * Task error code: The task is not created. + * + * Value: 0x0200020a + * + * Solution: Create the task. + */ +#define LOS_ERRNO_TSK_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0a) + +/** + * @ingroup los_task + * Task error code: The task message is nonzero. + * + * Value: 0x0200020c + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_MSG_NONZERO LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0c) + +/** + * @ingroup los_task + * Task error code: The task delay occurs during an interrupt. + * + * Value: 0x0300020d + * + * Solution: Perform this operation after exiting from the interrupt. + */ +#define LOS_ERRNO_TSK_DELAY_IN_INT LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x0d) + +/** + * @ingroup los_task + * Task error code: The task delay occurs when the task is locked. + * + * Value: 0x0200020e + * + * Solution: Perform this operation after unlocking the task. + */ +#define LOS_ERRNO_TSK_DELAY_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0e) + +/** + * @ingroup los_task + * Task error code: The task that is being scheduled is invalid. + * + * Value: 0x0200020f + * + * Solution: Check the task. + */ +#define LOS_ERRNO_TSK_YIELD_INVALID_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0f) + +/** + * @ingroup los_task + * Task error code: Only one task or no task is available for scheduling. + * + * Value: 0x02000210 + * + * Solution: Increase the number of tasks. + */ +#define LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x10) + +/** + * @ingroup los_task + * Task error code: No free task control block is available. + * + * Value: 0x02000211 + * + * Solution: Increase the number of task control blocks. + */ +#define LOS_ERRNO_TSK_TCB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x11) + +/** + * @ingroup los_task + * Task error code: The task hook function is not matchable. + * + * Value: 0x02000212 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_HOOK_NOT_MATCH LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x12) + +/** + * @ingroup los_task + * Task error code: The number of task hook functions exceeds the permitted upper limit. + * + * Value: 0x02000213 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x13) + +/** + * @ingroup los_task + * Task error code: The operation is performed on the idle task. + * + * Value: 0x02000214 + * + * Solution: Check the task ID and do not operate on the idle task. + */ +#define LOS_ERRNO_TSK_OPERATE_IDLE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x14) + +/** + * @ingroup los_task + * Task error code: The task that is being suspended is locked. + * + * Value: 0x03000215 + * + * Solution: Suspend the task after unlocking the task. + */ +#define LOS_ERRNO_TSK_SUSPEND_LOCKED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x15) + +/** + * @ingroup los_task + * Task error code: The task stack fails to be freed. + * + * Value: 0x02000217 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_FREE_STACK_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x17) + +/** + * @ingroup los_task + * Task error code: The task stack area is too small. + * + * Value: 0x02000218 + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_STKAREA_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x18) + +/** + * @ingroup los_task + * Task error code: The task fails to be activated. + * + * Value: 0x03000219 + * + * Solution: Perform task switching after creating an idle task. + */ +#define LOS_ERRNO_TSK_ACTIVE_FAILED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x19) + +/** + * @ingroup los_task + * Task error code: Too many task configuration items. + * + * Value: 0x0200021a + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_CONFIG_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1a) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021b + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_CP_SAVE_AREA_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1b) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021d + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_MSG_Q_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1d) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021e + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_CP_SAVE_AREA_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1e) + +/** + * @ingroup los_task + * Task error code: + * + * Value: 0x0200021f + * + * Solution: This error code is not in use temporarily. + */ +#define LOS_ERRNO_TSK_SELF_DELETE_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1f) + +/** + * @ingroup los_task + * Task error code: The task stack size is too large. + * + * Value: 0x02000220 + * + * Solution: shrink the task stack size parameter. + */ +#define LOS_ERRNO_TSK_STKSZ_TOO_LARGE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x20) + +/** + * @ingroup los_task + * Task error code: Suspending software timer task is not allowed. + * + * Value: 0x02000221 + * + * Solution: Check the task ID and do not suspend software timer task. + */ +#define LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x21) + +/** + * @ingroup los_task + * Task error code: The operation is performed on the software timer task. + * + * Value: 0x02000222 + * + * Solution: Check the task ID and do not operate on the software timer task. + */ +#define LOS_ERRNO_TSK_OPERATE_SWTMR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x22) + +/** + * @ingroup los_task + * Define the type of the task switching hook function. + * + */ +typedef VOID (*TSKSWITCHHOOK)(VOID); + +/** + * @ingroup los_task + * User task switching hook function. + * + */ +extern TSKSWITCHHOOK g_pfnUsrTskSwitchHook; + +/** + * @ingroup los_task + * Define the type of the task entry function. + * + */ +typedef VOID *(*TSK_ENTRY_FUNC)(UINT32 arg); + +/** + * @ingroup los_task + * Define the structure of the parameters used for task creation. + * + * Information of specified parameters passed in during task creation. + */ +typedef struct tagTskInitParam { + TSK_ENTRY_FUNC pfnTaskEntry; /**< Task entrance function */ + UINT16 usTaskPrio; /**< Task priority */ + UINT32 uwArg; /**< Task parameters */ + UINT32 uwStackSize; /**< Task stack size */ + CHAR *pcName; /**< Task name */ + UINT32 uwResved; /**< Reserved */ +} TSK_INIT_PARAM_S; + +/** + * @ingroup los_task + * Task name length + * + */ +#define LOS_TASK_NAMELEN 32 + +/** + * @ingroup los_task + * Task information structure. + * + */ +typedef struct tagTskInfo { + CHAR acName[LOS_TASK_NAMELEN]; /**< Task entrance function */ + UINT32 uwTaskID; /**< Task ID */ + UINT16 usTaskStatus; /**< Task status */ + UINT16 usTaskPrio; /**< Task priority */ + VOID *pTaskSem; /**< Semaphore pointer */ + VOID *pTaskMux; /**< Mutex pointer */ + UINT32 uwSemID; /**< Sem ID */ + UINT32 uwMuxID; /**< Mux ID */ + EVENT_CB_S uwEvent; /**< Event */ + UINT32 uwEventMask; /**< Event mask */ + UINT32 uwStackSize; /**< Task stack size */ + UINT32 uwTopOfStack; /**< Task stack top */ + UINT32 uwBottomOfStack; /**< Task stack bottom */ + UINT32 uwSP; /**< Task SP pointer */ + UINT32 uwCurrUsed; /**< Current task stack usage */ + UINT32 uwPeakUsed; /**< Task stack usage peak */ + BOOL bOvf; /**< Flag that indicates whether a task stack overflow occurs */ +} TSK_INFO_S; + +/** + * @ingroup los_task + * @brief Create a task and suspend. + * + * @par Description: + * This API is used to create a task and suspend it. This task will not be added to the queue of ready tasks before + * resume it. + * + * @attention + *
      + *
    • During task creation, the task control block and task stack of the task that is previously automatically deleted + * are deallocated.
    • + *
    • The task name is a pointer and is not allocated memory.
    • + *
    • If the size of the task stack of the task to be created is 0, configure #LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE + * to specify the default task stack size. The stack size should be a reasonable value, if the size is too large, may + * cause memory exhaustion.
    • + *
    • The task stack size must be aligned on the boundary of 8 bytes. The size is determined by whether it is big + * enough to avoid task stack overflow.
    • + *
    • Less parameter value indicates higher task priority.
    • + *
    • The task name cannot be null.
    • + *
    • The pointer to the task executing function cannot be null.
    • + *
    • The two parameters of this interface is pointer, it should be a correct value, otherwise, the system may be + * abnormal.
    • + *
    • If user mode is enabled, user should input user stack pointer and size, the size must fit the stack pointer, + * uwStackSize remain as the kernel stack size.
    • + *
    + * + * @param taskID [OUT] Type #UINT32 * Task ID. + * @param taskInitParam [IN] Type #TSK_INIT_PARAM_S * Parameter for task creation. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID, param puwTaskID is NULL. + * @retval #LOS_ERRNO_TSK_PTR_NULL Param pstInitParam is NULL. + * @retval #LOS_ERRNO_TSK_NAME_EMPTY The task name is NULL. + * @retval #LOS_ERRNO_TSK_ENTRY_NULL The task entrance is NULL. + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_LARGE The task stack size is too large. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_SMALL The task stack size is too small. + * @retval #LOS_ERRNO_TSK_TCB_UNAVAILABLE No free task control block is available. + * @retval #LOS_ERRNO_TSK_NO_MEMORY Insufficient memory for task creation. + * @retval #LOS_OK The task is successfully created. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + *
    • los_config.h: the header file that contains system configuration items.
    + * @see LOS_TaskDelete + */ +extern UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam); + +/** + * @ingroup los_task + * @brief Create a task. + * + * @par Description: + * This API is used to create a task. If the priority of the task created after system initialized is higher than + * the current task and task scheduling is not locked, it is scheduled for running. + * If not, the created task is added to the queue of ready tasks. + * + * @attention + *
      + *
    • During task creation, the task control block and task stack of the task that is previously automatically + * deleted are deallocated.
    • + *
    • The task name is a pointer and is not allocated memory.
    • + *
    • If the size of the task stack of the task to be created is 0, configure #LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE + * to specify the default task stack size.
    • + *
    • The task stack size must be aligned on the boundary of 8 bytes. The size is determined by whether it is big + * enough to avoid task stack overflow.
    • + *
    • Less parameter value indicates higher task priority.
    • + *
    • The task name cannot be null.
    • + *
    • The pointer to the task executing function cannot be null.
    • + *
    • The two parameters of this interface is pointer, it should be a correct value, otherwise, the system may be + * abnormal.
    • + *
    • If user mode is enabled, user should input user stack pointer and size, the size must fit the stack pointer, + * uwStackSize remain as the kernel stack size.
    • + *
    + * + * @param taskID [OUT] Type #UINT32 * Task ID. + * @param taskInitParam [IN] Type #TSK_INIT_PARAM_S * Parameter for task creation. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID, param puwTaskID is NULL. + * @retval #LOS_ERRNO_TSK_PTR_NULL Param pstInitParam is NULL. + * @retval #LOS_ERRNO_TSK_NAME_EMPTY The task name is NULL. + * @retval #LOS_ERRNO_TSK_ENTRY_NULL The task entrance is NULL. + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_LARGE The task stack size is too large. + * @retval #LOS_ERRNO_TSK_STKSZ_TOO_SMALL The task stack size is too small. + * @retval #LOS_ERRNO_TSK_TCB_UNAVAILABLE No free task control block is available. + * @retval #LOS_ERRNO_TSK_NO_MEMORY Insufficient memory for task creation. + * @retval #LOS_OK The task is successfully created. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + *
    • los_config.h: the header file that contains system configuration items.
    + * @see LOS_TaskDelete + */ +extern UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam); + +/** + * @ingroup los_task + * @brief Resume a task. + * + * @par Description: + * This API is used to resume a suspended task. + * + * @attention + *
      + *
    • If the task is delayed or blocked, resume the task without adding it to the queue of ready tasks.
    • + *
    • If the priority of the task resumed after system initialized is higher than the current task and task scheduling + * is not locked, it is scheduled for running.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_NOT_SUSPENDED The task is not suspended. + * @retval #LOS_OK The task is successfully resumed. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskSuspend + */ +extern UINT32 LOS_TaskResume(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Suspend a task. + * + * @par Description: + * This API is used to suspend a specified task, and the task will be removed from the queue of ready tasks. + * + * @attention + *
      + *
    • The task that is running and locked cannot be suspended.
    • + *
    • The idle task and swtmr task cannot be suspended.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED Check the task ID and do not operate on the swtmr task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_ALREADY_SUSPENDED The task is already suspended. + * @retval #LOS_ERRNO_TSK_SUSPEND_LOCKED The task being suspended is current task and task scheduling + * is locked. + * @retval #LOS_OK The task is successfully suspended. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskResume + */ +extern UINT32 LOS_TaskSuspend(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Delete a task. + * + * @par Description: + * This API is used to delete a specified task and release the resources for its task stack and task control block. + * + * @attention + *
      + *
    • The idle task and swtmr task cannot be deleted.
    • + *
    • If delete current task maybe cause unexpected error.
    • + *
    • If a task get a mutex is deleted or automatically deleted before release this mutex, other tasks pended + * this mutex maybe never be shchduled.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED Check the task ID and do not operate on the swtmr task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The task is successfully deleted. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskCreate | LOS_TaskCreateOnly + */ +extern UINT32 LOS_TaskDelete(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Delay a task. + * + * @par Description: + * This API is used to delay the execution of the current task. The task is able to be scheduled after it is delayed + * for a specified number of Ticks. + * + * @attention + *
      + *
    • The task fails to be delayed if it is being delayed during interrupt processing or it is locked.
    • + *
    • If 0 is passed in and the task scheduling is not locked, execute the next task in the queue of tasks with + * the same priority of the current task. + * If no ready task with the priority of the current task is available, the task scheduling will not occur, and the + * current task continues to be executed.
    • + *
    • Using the interface before system initialized is not allowed.
    • + *
    + * + * @param tick [IN] Type #UINT32 Number of Ticks for which the task is delayed. + * + * @retval #LOS_ERRNO_TSK_DELAY_IN_INT The task delay occurs during an interrupt. + * @retval #LOS_ERRNO_TSK_DELAY_IN_LOCK The task delay occurs when the task scheduling is locked. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK No tasks with the same priority is available for scheduling. + * @retval #LOS_OK The task is successfully delayed. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_TaskDelay(UINT32 tick); + +/** + * @ingroup los_task + * @brief Lock the task scheduling. + * + * @par Description: + * This API is used to lock the task scheduling. Task switching will not occur if the task scheduling is locked. + * + * @attention + *
      + *
    • If the task scheduling is locked, but interrupts are not disabled, tasks are still able to be interrupted.
    • + *
    • One is added to the number of task scheduling locks if this API is called. The number of locks is decreased by + * one if the task scheduling is unlocked. Therefore, this API should be used together with LOS_TaskUnlock.
    • + *
    + * + * @param None. + * + * @retval None. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskUnlock + */ +extern VOID LOS_TaskLock(VOID); + +/** + * @ingroup los_task + * @brief Unlock the task scheduling. + * + * @par Description: + * This API is used to unlock the task scheduling. Calling this API will decrease the number of task locks by one. + * If a task is locked more than once, the task scheduling will be unlocked only when the number of locks becomes zero. + * + * @attention + *
      + *
    • The number of locks is decreased by one if this API is called. One is added to the number of task scheduling + * locks if the task scheduling is locked. Therefore, this API should be used together with LOS_TaskLock.
    • + *
    + * + * @param None. + * + * @retval None. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskLock + */ +extern VOID LOS_TaskUnlock(VOID); + +/** + * @ingroup los_task + * @brief Set a task priority. + * + * @par Description: + * This API is used to set the priority of a specified task. + * + * @attention + *
      + *
    • If the set priority is higher than the priority of the current running task, task scheduling probably occurs. + *
    • + *
    • Changing the priority of the current running task also probably causes task scheduling.
    • + *
    • Using the interface to change the priority of software timer task and idle task is not allowed.
    • + *
    • Using the interface in the interrupt is not allowed.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param taskPrio [IN] Type #UINT16 Task priority. + * + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority.Re-configure the task priority + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The task priority is successfully set to a specified priority. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskPriSet + */ +extern UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio); + +/** + * @ingroup los_task + * @brief Set the priority of the current running task to a specified priority. + * + * @par Description: + * This API is used to set the priority of the current running task to a specified priority. + * + * @attention + *
      + *
    • Changing the priority of the current running task probably causes task scheduling.
    • + *
    • Using the interface to change the priority of software timer task and idle task is not allowed.
    • + *
    • Using the interface in the interrupt is not allowed.
    • + *
    + * + * @param taskPrio [IN] Type #UINT16 Task priority. + * + * @retval #LOS_ERRNO_TSK_PRIOR_ERROR Incorrect task priority.Re-configure the task priority + * @retval #LOS_ERRNO_TSK_OPERATE_IDLE Check the task ID and do not operate on the idle task. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The priority of the current running task is successfully set to a specified + * priority. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskPriGet + */ +extern UINT32 LOS_CurTaskPriSet(UINT16 taskPrio); + +/** + * @ingroup los_task + * @brief Change the scheduling sequence of tasks with the same priority. + * + * @par Description: + * This API is used to move current task in a queue of tasks with the same priority to the tail of the queue of ready + * tasks. + * + * @attention + *
      + *
    • At least two ready tasks need to be included in the queue of ready tasks with the same priority. If the + * less than two ready tasks are included in the queue, an error is reported.
    • + *
    + * + * @param None. + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID + * @retval #LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK No tasks with the same priority is available for scheduling. + * @retval #LOS_OK The scheduling sequence of tasks with same priority is + * successfully changed. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_TaskYield(VOID); + +/** + * @ingroup los_task + * @brief Obtain a task priority. + * + * @par Description: + * This API is used to obtain the priority of a specified task. + * + * @attention None. + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * + * @retval #OS_INVALID The task priority fails to be obtained. + * @retval #UINT16 The task priority. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see LOS_TaskPriSet + */ +extern UINT16 LOS_TaskPriGet(UINT32 taskID); + +/** + * @ingroup los_task + * @brief Obtain current running task ID. + * + * @par Description: + * This API is used to obtain the ID of current running task. + * + * @attention + *
      + *
    • This interface should not be called before system initialized.
    • + *
    + * + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid Task ID. + * @retval #UINT32 Task ID. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_CurTaskIDGet(VOID); + +/** + * @ingroup los_task + * @brief Obtain next running task ID. + * + * @par Description: + * This API is used to obtain the ID of next running task. + * + * @attention None. + * + * + * @retval #LOS_ERRNO_TSK_ID_INVALID invalid Task ID. + * @retval #UINT32 task id. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_NextTaskIDGet(VOID); + +/** + * @ingroup los_task + * @brief Obtain next running task ID. + * + * @par Description: + * This API is used to obtain the ID of next running task. + * + * @attention None. + * + * + * @retval #NULL invalid Task name. + * @retval #CHAR* task name. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern CHAR *LOS_CurTaskNameGet(VOID); + +/** + * @ingroup los_task + * @brief Obtain a task information structure. + * + * @par Description: + * This API is used to obtain a task information structure. + * + * @attention + *
      + *
    • One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may be + * abnormal.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param taskInfo [OUT] Type #TSK_INFO_S* Pointer to the task information structure to be obtained. + * + * @retval #LOS_ERRNO_TSK_PTR_NULL Null parameter. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid task ID. + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_OK The task information structure is successfully obtained. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo); + +/** + * @ingroup los_task + * @brief Obtain the task status. + * + * @par Description: + * This API is used to obtain the task status. + * + * @attention None. + * + * @param taskID [IN] Type #TSK_HANDLE_T Task ID. + * @param taskStatus [OUT] Type #UINT32 Pointer to the task status to be obtained. + * + * @retval #LOS_ERRNO_TSK_PTR_NULL 0x02000201: Null parameter. + * @retval #LOS_ERRNO_TSK_ID_INVALID 0x02000207: Invalid task ID. + * @retval #LOS_ERRNO_TSK_NOT_CREATED 0x0200020a: The task is not created. + * @retval #LOS_OK 0: The task information structure is successfully obtained. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_TaskStatusGet(UINT32 taskID, UINT32* taskStatus); + +/** + * @ingroup los_monitor + * @brief Obtain all tasks info. + * + * @par Description: + * This API is used to obtain all tasks info. + * @attention + *
      + *
    • This API can be called only after the CPU usage is initialized. Otherwise, -1 will be returned.
    • + *
    + * + * @param None. + * + * @retval #OS_ERROR -1:all tasks info obtain failed. + * @retval #LOS_OK 0:all tasks info is successfully obtained. + * @par Dependency: + *
    • los_monitor.h: the header file that contains the API declaration.
    + * @see LOS_TaskInfoMonitor + */ +extern UINT32 LOS_TaskInfoMonitor(VOID); + +/** + * @ingroup los_task + * @brief Obtain tasks switch info. + * + * @par Description: + * This API is used to obtain tasks switch info. + * + * @attention None. + * + * @param index [IN] Type #UINT32 Switch info array index. + * @param taskSwitchInfo [OUT] Type #UINT32* First 4 bytes is task id, and then is task name, name len is + * OS_TSK_NAME_LEN. + * + * @retval #LOS_ERRNO_TSK_PTR_NULL 0x02000201: Null parameter. + * @retval #LOS_OK 0: The task switch information is successfully obtained. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_TaskSwitchInfoGet(UINT32 index, UINT32 *taskSwitchInfo); + +/** + * @ingroup los_task + * @brief Obtain tasks schduling info. + * + * @par Description: + * This API is used to obtain task is scheduled. + * + * @attention None. + * + * @param None. + * + * @retval #TRUE Tasks is scheduled. + * @retval #FALSE Tasks not scheduling yet. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern BOOL LOS_TaskIsRunning(VOID); + +/** + * @ingroup los_task + * @brief Obtain current new task ID. + * + * @par Description: + * This API is used to obtain the ID of new task. + * + * @attention None. + * + * + * @retval #LOS_ERRNO_TSK_ID_INVALID 0x02000207: invalid Task ID. + * @retval # Task ID. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern UINT32 LOS_NewTaskIDGet(VOID); + /** + * @ingroup los_task + * @brief Obtain current new task name. + * + * @par Description: + * This API is used to obtain the name of new task. + * + * @attention None. + * + * @param taskID [IN] Task ID. + * + * @retval #NULL: invalid Task name. + * @retval # Task name. + * @par Dependency: + *
    • los_task.h: the header file that contains the API declaration.
    + * @see + */ +extern CHAR* LOS_TaskNameGet(UINT32 taskID); + +extern UINT32 OsTaskNextSwitchTimeGet(VOID); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TASK_H */ diff --git a/kernel/include/los_tick.h b/kernel/include/los_tick.h new file mode 100755 index 00000000..60c5d3e2 --- /dev/null +++ b/kernel/include/los_tick.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_tick Tick + * @ingroup kernel + */ + +#ifndef _LOS_TICK_H +#define _LOS_TICK_H + +#include "los_errno.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_tick + * Tick error code: The Tick configuration is incorrect. + * + * Value: 0x02000400 + * + * Solution: Change values of the OS_SYS_CLOCK and LOSCFG_BASE_CORE_TICK_PER_SECOND + * system time configuration modules in Los_config.h. + */ +#define LOS_ERRNO_TICK_CFG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x00) + +/** + * @ingroup los_tick + * Tick error code: This error code is not in use temporarily. + * + * Value: 0x02000401 + * + * Solution: None. + */ +#define LOS_ERRNO_TICK_NO_HWTIMER LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x01) + +/** + * @ingroup los_tick + * Tick error code: The number of Ticks is too small. + * + * Value: 0x02000402 + * + * Solution: Change values of the OS_SYS_CLOCK and LOSCFG_BASE_CORE_TICK_PER_SECOND + * system time configuration modules according to the SysTick_Config function. + */ +#define LOS_ERRNO_TICK_PER_SEC_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x02) + +/** + * @ingroup los_tick + * @brief: System clock get function. + * + * @par Description: + * This API is used to get system clock. + * + * @attention: + *
    • None.
    + * + * @param: None. + * + * @retval: system clock. + * + * @par Dependency: + *
    • los_tick.h: the header file that contains the API declaration.
    + * @see None. + * + * */ +extern UINT32 LOS_SysClockGet(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TICK_H */ diff --git a/kernel/include/los_tickless.h b/kernel/include/los_tickless.h new file mode 100755 index 00000000..a73e1345 --- /dev/null +++ b/kernel/include/los_tickless.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_tickless Tickless + * @ingroup kernel + */ + +#ifndef _LOS_TICKLESS_H +#define _LOS_TICKLESS_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_tickless + * @brief enable the tickless mode. + * + * @par Description: + * This API is used to enable the tickless mode. System can change from periodic clock mode to dynamic clock mode. + * + * @attention + *
      + *
    + * + * @param None. + * + * @retval None. + * @par Dependency: + *
    • los_tickless.h: the header file that contains the API declaration.
    + * @see LOS_TicklessDisable + */ +extern VOID LOS_TicklessEnable(VOID); +/** + * @ingroup los_tickless + * @brief disable the tickless mode. + * + * @par Description: + * This API is used to diable the tickless mode. System will not change from periodic clock mode to dynamic clock mode. + * + * @attention + *
      + *
    + * + * @param None. + * + * @retval None. + * @par Dependency: + *
    • los_tickless.h: the header file that contains the API declaration.
    + * @see LOS_TicklessEnable + */ +extern VOID LOS_TicklessDisable(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/kernel/include/los_trace.h b/kernel/include/los_trace.h new file mode 100755 index 00000000..60c5f192 --- /dev/null +++ b/kernel/include/los_trace.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_trace Trace + * @ingroup kernel + */ + +#ifndef _LOS_TRACE_H +#define _LOS_TRACE_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_trace + * Task error code: Insufficient memory for trace struct. + * + * Value: 0x02001400 + * + * Solution: Decrease the maximum number of tasks. + */ +#define LOS_ERRNO_TRACE_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x00) + +/** + * @ingroup los_trace + * Task error code: User type is invalid when register new trace. + * + * Value: 0x02001401 + * + * Solution: Use valid type to regeister the new trace. + */ +#define LOS_ERRNO_TRACE_TYPE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x01) + + +/** + * @ingroup los_trace + * Task error code: The callback function is null when register new trace. + * + * Value: 0x02001402 + * + * Solution: Use valid callback function to regeister the new trace. + */ +#define LOS_ERRNO_TRACE_FUNCTION_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x02) + +/** + * @ingroup los_trace + * Task error code: The filled size is 0 when register new trace. + * + * Value: 0x02001403 + * + * Solution: Use valid filled size to regeister the new trace. + */ +#define LOS_ERRNO_TRACE_MAX_SIZE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TRACE, 0x03) + +/** + * @ingroup los_trace + * It's the total size of trace buffer. It's in the unit of char + */ +#define LOS_TRACE_BUFFER_SIZE 1024 + +/** + * @ingroup los_trace + * It's the legth of tag, filled by los_trace system + */ +#define LOS_TRACE_TAG_LENGTH sizeof(UINT32) + +/** + * @ingroup los_trace + * Stands for the trace type can be registered. + */ +typedef enum enTraceType { + LOS_TRACE_SWITCH = 0, /**< trace for task switch, 0 is reserved for taskswitch */ + LOS_TRACE_INTERRUPT = 1, /**< trace for Interrrupt, 1 is reserved for interrupt */ + LOS_TRACE_TYPE_NUM = 10, /**< num for the register type, user can use 2~ LOS_TRACE_TYPE_NUM-1 */ +} TRACE_TYPE_E; + + +/** + * @ingroup los_trace + * struct to store the task switch infomation + */ +typedef struct tagTraceTaskSwitch { + UINT8 ucSrcTaskId; /**< source taskid */ + UINT8 ucDestTaskId; /**< destination taskid */ + UINT32 uwSwitchTick; /**< Time at which the task switch happens */ +} TRACE_TASKSWITCH_S; + +/** + * @ingroup los_trace + * struct to store the interrupt infomation + */ +typedef struct tagTraceInterrupt { + UINT8 ucIRQEntryExit; /**< 1 stands for that the trace is happend before interrupt function */ + /**< 0 stands for that the trace is after before interrupt function */ + UINT16 usIRQNo; /**< IRQ number which trigger the interrupt */ + UINT32 uwTick; /**< Time at which the the trace is called */ +} TRACE_INTERRUPT_S; + +/** + * @ingroup los_trace + * union struct to store the interrupt and task switch infomation + */ +typedef struct tagTrace { + union { + TRACE_TASKSWITCH_S stTraceTask; /**< It used for trace the task */ + TRACE_INTERRUPT_S stTraceInterrupt; /**< It used for trace the interrrupt */ + }; +} TRACE_S; + +/** + * @ingroup los_trace + * Main struct to store the interrupt and task swithc infomation + */ +typedef struct tagTraceBuffer { + UINT16 usTracePos; + UINT16 usTraceWrapPos; + UINT8 ucBuffer[LOS_TRACE_BUFFER_SIZE]; +} TRACE_BUFFER_S; + + +/** + * @ingroup los_trace + * Struct to store the trace infomaion for each trace type + */ +typedef struct tagTraceInfo { + TRACE_TYPE_E eType; /**< trace type, selected from TRACE_TYPE_E */ + UINT16 (*pfnHook)(UINT8 *outBuffer, VOID *pInfo); /**< callback function for the specific trace type. + * This function is used to store the infomation + * which want to be traced */ +} TRACE_INFO_S; + +/** + * @ingroup los_trace + * @brief Intialize the trace when the system startup. + * + * @par Description: + * This API is used to intilize the trace for system level. + * @attention + *
      + *
    • This API can be called only after the memory is initialized. Otherwise, the CPU usage fails to be obtained.
    • + *
    + * + * @param None. + * + * @retval #LOS_ERRNO_TRACE_NO_MEMORY 0x02001400: The memory is not enough for initilize. + * @retval #LOS_OK 0x00000000: The intialization is successful. + * @par Dependency: + *
    • los_trace.h: the header file that contains the API declaration.
    + * @see LOS_TraceInit + */ +extern UINT32 LOS_TraceInit(VOID); + + +/** + * @ingroup los_trace + * @brief main trace function is called by user to logger the information. + * + * @par Description: + * This API is used to trace the infomation. + * @attention + *
      + *
    • This API can be called only after trace type is intialized. Otherwise, the trace will be failed.
    • + *
    + * + * @param traceType [IN] TRACE_TYPE_E. Type of trace information. + * @param traceInfo [IN] VOID*. It's a input buffer to store trace infomation + * + * @retval NONE. + * + * @par Dependency: + *
    • los_trace.h: the header file that contains the API declaration.
    + * @see LOS_Trace + */ +extern VOID LOS_Trace(TRACE_TYPE_E traceType, VOID *traceInfo); + + + +/** + * @ingroup los_trace + * @brief register the hook for specific trace type. + * + * @par Description: + * This API is used to register the hook for specific trace type. + * @attention + *
      + *
    • This API can be called only after trace type is called. therwise, the trace will be failed.
    • + *
    + * + * @param traceType [IN] TRACE_TYPE_E. Type of trace information. + * @param hook [IN] UINT16 (*)(UINT8*, VOID*). It's an callback function to store the useful trace + * information + * @param size [IN] UINT16. The maximum size the trace will use for the specific trace type. + * + * @retval #LOS_ERRNO_TRACE_NO_MEMORY 0x02001400: The memory is not enough for initilize. + * @retval #LOS_ERRNO_TRACE_TYPE_INVALID 0x02001401: The trace type is invalid. Valid type is from + * LOS_TRACE_TYPE_NUM-1 + * @retval #LOS_ERRNO_TRACE_FUNCTION_NULL 0x02001402: The input callback function is NULL + * @retval #LOS_ERRNO_TRACE_MAX_SIZE_INVALID 0x02001403: The information maxmum size is 0 to store. + * @retval #LOS_OK 0x00000000: The registeration is successful. + * + * @par Dependency: + *
    • los_trace.h: the header file that contains the API declaration.
    + * @see LOS_TraceUserReg + */ +extern UINT32 LOS_TraceUserReg(TRACE_TYPE_E traceType, UINT16 (*hook)(UINT8 *, VOID *), UINT16 size); + + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TRACE_H */ diff --git a/kernel/include/los_typedef.h b/kernel/include/los_typedef.h new file mode 100755 index 00000000..96bacbae --- /dev/null +++ b/kernel/include/los_typedef.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/** + * @defgroup los_typedef Type define + * @ingroup kernel + */ + +#ifndef _LOS_TYPEDEF_H +#define _LOS_TYPEDEF_H + +#include "los_builddef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef LOS_TYPE_DEF +#define LOS_TYPE_DEF + +/* type definitions */ +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef float FLOAT; +typedef double DOUBLE; +typedef char CHAR; + +typedef unsigned int BOOL; +typedef unsigned long long UINT64; +typedef signed long long INT64; +typedef unsigned int UINTPTR; +typedef signed int INTPTR; + +#define VOID void +#endif /* end of #ifndef LOS_TYPE_DEF */ + +#ifndef FALSE +#define FALSE ((BOOL)0) +#endif + +#ifndef TRUE +#define TRUE ((BOOL)1) +#endif + +#ifndef NULL +#define NULL ((VOID *)0) +#endif + +#ifdef YES +#undef YES +#endif +#define YES 1 + +#ifdef NO +#undef NO +#endif +#define NO 0 + +#define OS_NULL_BYTE ((UINT8)0xFF) +#define OS_NULL_SHORT ((UINT16)0xFFFF) +#define OS_NULL_INT ((UINT32)0xFFFFFFFF) + +#ifndef LOS_OK +#define LOS_OK 0U +#endif + +#ifndef LOS_NOK +#define LOS_NOK 1U +#endif + +#define OS_FAIL 1 +#define OS_ERROR (UINT32)(-1) +#define OS_INVALID (UINT32)(-1) + +#define asm __asm +#ifdef typeof +#undef typeof +#endif +#define typeof __typeof__ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TYPEDEF_H */ diff --git a/kernel/los_init.c b/kernel/los_init.c new file mode 100755 index 00000000..be92a92d --- /dev/null +++ b/kernel/los_init.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_sys.h" +#include "los_tick.h" +#include "los_task_pri.h" +#include "los_tick_pri.h" +#include "los_config.h" +#if (LOSCFG_KERNEL_RUNSTOP == YES) +#include "los_sr.h" +#endif + +#if (LOSCFG_PLATFORM_EXC == YES) +#include "los_exc_pri.h" +#endif + +#if (LOSCFG_KERNEL_TRACE == YES) +#include "los_trace.h" +#endif + +#if (LOSCFG_KERNEL_CPPSUPPORT == YES) +#include "los_cppsupport.h" +#endif + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT8 *m_aucSysMem0; + +#if (LOSCFG_PLATFORM_EXC == YES) +UINT8 g_aucTaskArray[MAX_EXC_MEM_SIZE]; +#endif +#define FPU_ENABLE ((3UL << 20) | (3UL << 22)) + +VOID OsEnableFPU(VOID) +{ + *(volatile UINT32 *)0xE000ED88 |= FPU_ENABLE; /* CPACR is located at address 0xE000ED88. */ +} + +/***************************************************************************** + Function : LOS_Reboot + Description : system exception, die in here, wait for watchdog. + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT VOID LOS_Reboot(VOID) +{ + (VOID)LOS_IntLock(); + while (1) { + } +} +/***************************************************************************** + Function : OsRegister + Description : Configuring the maximum number of tasks + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT static VOID OsRegister(VOID) +{ + g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT + 1; /* Reserved 1 for IDLE */ + + return; +} + +/***************************************************************************** + Function : LOS_Start + Description : Task start function. + Input : None + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_Start(VOID) +{ + UINT32 ret; +#if (LOSCFG_BASE_CORE_TICK_HW_TIME == NO) + ret = OsTickStart(); + + if (ret != LOS_OK) { + PRINT_ERR("OsTickStart error\n"); + return ret; + } +#else + ret = os_timer_init(); + if (ret != LOS_OK) { + PRINT_ERR("os_timer_init error\n"); + return ret; + } +#endif + LOS_StartToRun(); + + return ret; +} + +/***************************************************************************** + Function : LOS_KernelInit + Description : System kernel initialization function, configure all system modules + Input : None + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID) +{ + UINT32 ret; + + OsRegister(); + + m_aucSysMem0 = (UINT8 *)OS_SYS_MEM_ADDR; + g_sysMemAddrEnd = ((UINT32)OS_SYS_MEM_ADDR + OS_SYS_MEM_SIZE); + ret = OsMemSystemInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsMemSystemInit error %d\n", ret); + return ret; + } + +#if (LOSCFG_PLATFORM_HWI == YES) + OsHwiInit(); +#endif + +#if (LOSCFG_PLATFORM_EXC == YES) + OsExcInit(MAX_EXC_MEM_SIZE); +#endif + + ret = OsTaskInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsTaskInit error\n"); + return ret; + } + +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) + OsTaskMonInit(); +#endif + +#if (LOSCFG_BASE_CORE_CPUP == YES) + ret = OsCpupInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsCpupInit error\n"); + return ret; + } +#endif + +#if (LOSCFG_BASE_IPC_SEM == YES) + ret = OsSemInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + +#if (LOSCFG_BASE_IPC_MUX == YES) + ret = OsMuxInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + +#if (LOSCFG_BASE_IPC_QUEUE == YES) + ret = OsQueueInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsQueueInit error\n"); + return ret; + } +#endif + +#if (LOSCFG_BASE_CORE_SWTMR == YES) + ret = OsSwtmrInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsSwtmrInit error\n"); + return ret; + } +#endif + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + OsTimesliceInit(); +#endif + + ret = OsIdleTaskCreate(); + if (ret != LOS_OK) { + return ret; + } + +#if (LOSCFG_KERNEL_TRACE == YES) + ret = LOS_TraceInit(); + if (ret != LOS_OK) { + PRINT_ERR("LOS_TraceInit error\n"); + return ret; + } +#endif + +#if (LOSCFG_KERNEL_CPPSUPPORT == YES) + extern char __init_array_start,__init_array_end; + LOS_CppSystemInit((UINTPTR)&__init_array_start,(UINTPTR)&__init_array_end); +#endif +#ifdef LOSCFG_TEST + ret = los_TestInit(); + if (ret != LOS_OK) { + PRINT_ERR("los_TestInit error\n"); + return ret; + } +#endif + + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/platform/cpu/arm/cortex-m4/src/los_sr.c b/platform/cpu/arm/cortex-m4/src/los_sr.c new file mode 100755 index 00000000..d484d09b --- /dev/null +++ b/platform/cpu/arm/cortex-m4/src/los_sr.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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 "los_sr.h" +#include "los_task.inc" +#include "los_exc.h" +#include "securec.h" +#include +#include "los_tick.ph" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 uwGetSleepTick = 0; +#define OS_SYSTICK_CONTROL_REG 0xE000E010 +#if(LOSCFG_BASE_CORE_TIMESLICE == YES) +extern OS_TASK_ROBIN_S g_stTaskTimeSlice; +#endif + +extern TSK_SORTLINK_ATTRIBUTE_S g_stTskSortLink; + +extern void set_mcu_status(UINT8 status); + +UINT32 g_auwSaveSRContext[30]; +UINT32 g_auwSaveAR[3]; + +UINT32 g_uwSrStateFlag = SENSORHUB_COLDBOOT; +#if (OS_SR_WAKEUP_INFO == YES) +OS_WAKEUP_INFO g_astWakeupInfo; +#endif + +VOID osSetBasePri(UINT32 value) +{ + +} +void osTickLock(void) +{ +#if (LOSCFG_BASE_CORE_TICK_HW_TIME == NO) + *(volatile UINT32 *)OS_SYSTICK_CONTROL_REG = 0x5; +#else + +#endif +} + +void osTickUnlock(void) +{ +#if (LOSCFG_BASE_CORE_TICK_HW_TIME == NO) + *(volatile UINT32 *)OS_SYSTICK_CONTROL_REG = 0x7; +#else + +#endif +} + +UINT32 osDelayTskSuspend() +{ + LOS_TASK_CB *pstTaskCB = NULL; + UINT64 delta = (UINT64)-1; + UINT16 usCursor = (UINT16)-1; + LOS_DL_LIST *pstListObject = NULL; + UINT32 min = 0x07ffffff; + UINT32 min_record = (UINT32)-1; + UINT32 i; + + usCursor = (g_stTskSortLink.usCursor + 1) % OS_TSK_SORTLINK_LEN; + + for(i = 0; i < OS_TSK_SORTLINK_LEN; i++) + { + pstListObject = g_stTskSortLink.pstSortLink + (usCursor + i) % OS_TSK_SORTLINK_LEN; + if(pstListObject->pstNext != pstListObject) + { + pstTaskCB = LOS_DL_LIST_ENTRY((pstListObject)->pstNext, LOS_TASK_CB, stTimerList);/*lint !e413*/ + if(UWROLLNUM(pstTaskCB->uwIdxRollNum) < min) + { + min = UWROLLNUM(pstTaskCB->uwIdxRollNum); + min_record = (usCursor + i) % OS_TSK_SORTLINK_LEN; + } + } + } + + if(min == 0x07ffffff) + { + return 0xFFFFFFFF; + } + else + { + pstTaskCB = LOS_DL_LIST_ENTRY(((LOS_DL_LIST *)(g_stTskSortLink.pstSortLink + min_record))->pstNext, LOS_TASK_CB, stTimerList);/*lint !e413*/ + + if(min_record >= usCursor) + { + delta = (UINT64)((min_record-(UINT32)usCursor) + UWROLLNUM(pstTaskCB->uwIdxRollNum) * OS_TSK_SORTLINK_LEN + 1); + } + else + { + delta = (UINT64)((OS_TSK_SORTLINK_LEN - (UINT32)usCursor) + min_record + UWROLLNUM(pstTaskCB->uwIdxRollNum) * OS_TSK_SORTLINK_LEN +1); + } + } + + if (delta & (((UINT64)-1) << 32)) /* lint !e648 */ + { + return 0xFFFFFFFF; + } + + return (UINT32)delta; +} + +VOID osDelayTskResume(UINT32 sleep_time) +{ + int i; + +#if(LOSCFG_BASE_CORE_TIMESLICE == YES) + g_stTaskTimeSlice.pstTask = (LOS_TASK_CB *)NULL; +#endif + + g_ullTickCount += sleep_time; + if(sleep_time == 0) + return; + + if(sleep_time > uwGetSleepTick) + { + sleep_time = uwGetSleepTick; + } + + for(i = sleep_time; i > 0; i--) + { + osTaskScan(); + } +} + +#if (LOSCFG_BASE_CORE_SWTMR == YES) +UINT32 osSwtimerSuspend() +{ + return osSwTmrGetNextTimeout(); +} +#endif +VOID osSwtimerResume(UINT32 sleep_time) +{ + osSwTmrAdjust(sleep_time); +} + + UINT32 osGetSleepTime() +{ + UINT32 task = 0xFFFFFFFF; + UINT32 timer = 0xFFFFFFFF; + + task = osDelayTskSuspend(); + #if (LOSCFG_BASE_CORE_SWTMR == YES) + timer = osSwtimerSuspend(); + #endif + PRINT_DEBUG("Ta:%d,Ti=%d\n",task,timer); + + return task < timer ? task : timer; +} + + +VOID LOS_SystemWakeup(); + +extern MC_BOOL MC_SYS_CheckSuspendCondition(MC_VOID); +extern int sys_suspend(void); +VOID LOS_SrIdleTaskProcess() +{ + __disable_irq(); + osTickLock(); + uwGetSleepTick = osGetSleepTime(); + + if (uwGetSleepTick > 10) + { + if(!sys_suspend() || (FALSE == MC_SYS_CheckSuspendCondition())) + { + osTickUnlock(); + __enable_irq(); + return; + } + g_uwSrStateFlag = SENSORHUB_SLEEP; + if(g_uwSrStateFlag == SENSORHUB_SLEEP) // if any irq before or after __enable_irq, that is befor this condition + { +#ifdef CHIP_APOLLO + enterSleepMode(uwGetSleepTick); + __enable_irq(); +#else + enterStopMode(uwGetSleepTick); + osTickUnlock(); + __enable_irq(); +#endif + } + else + { + osTickUnlock(); + __enable_irq(); + } + } + else + { + osTickUnlock(); + __enable_irq(); + } +} + +/***************************************************************************** + Function : LOS_SystemWakeup + Description : System Wakeup function + Input : uwHwiIndex --- Make sure it comes from a valid interrupt number. + Output : None + Return : None + *****************************************************************************/ +VOID LOS_SystemWakeup(UINT32 uwHwiIndex) +{ + UINT32 uwWakeupTick = 0; + osTickLock(); + uwWakeupTick = getSleepTime(); + if(uwWakeupTick > uwGetSleepTick) + { + uwWakeupTick = uwGetSleepTick; + } + // modify delay task list + osDelayTskResume(uwWakeupTick); + // modify timer list + #if (LOSCFG_BASE_CORE_SWTMR == YES) + osSwtimerResume(uwWakeupTick); + #endif + #if (OS_SR_WAKEUP_INFO == YES) + g_astWakeupInfo.uwSleepTimeTotal += uwWakeupTick; + g_astWakeupInfo.auwPID[g_astWakeupInfo.ucIdx] = uwHwiIndex; + if (++g_astWakeupInfo.ucIdx == OS_WAKEUP_INFO_COUNT) + { + g_astWakeupInfo.ucIdx = 0; + g_astWakeupInfo.ucIsFull = 1; + } + #endif + osTickUnlock(); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/platform/cpu/arm/cortex-m4/src/los_sr.h b/platform/cpu/arm/cortex-m4/src/los_sr.h new file mode 100755 index 00000000..76ccbe11 --- /dev/null +++ b/platform/cpu/arm/cortex-m4/src/los_sr.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_SR_H__ +#define __LOS_SR_H__ + +#include "los_typedef.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define SENSORHUB_COLDBOOT 0x1 +#define SENSORHUB_SLEEP 0x2 + + +#define OS_WAKEUP_INFO_COUNT 32 +typedef struct tagWakeupInfo +{ + UINT64 uwSleepTimeTotal; + UINT8 ucIdx; + UINT8 ucIsFull; + UINT8 auwPID[OS_WAKEUP_INFO_COUNT]; +}OS_WAKEUP_INFO; + + +extern unsigned int g_uwSrStateFlag; +extern unsigned int g_uwOneshotLoadValue; + +extern unsigned int osDelayTskSuspend(); +extern void osDelayTskResume(unsigned int sleep_time); + +extern unsigned int osSwTmrGetNextTimeout(void); +extern void osSwTmrAdjust(unsigned int sleep_time); + +extern void osTickLock(void); +extern void osTickUnlock(void); +extern int osSRSuspend(void); +extern void osSRResume(void); + +extern unsigned int getSleepTime(); +extern void DisableWakeUpTimer(void); +extern void enterSleepMode(unsigned int SleepTime); +extern void enterStopMode(unsigned int SleepTime); +extern void StopMode_Measure(unsigned int sleepTime, unsigned int WakeUpClock); + +extern void LOS_SrIdleTaskProcess(void); + +extern void LOS_SystemWakeup(unsigned int uwHwiIndex); +extern void osSRSaveRegister(); +extern void osSRRestoreRegister(); +extern int GetMCURunAndSleepTime(unsigned int *runningTime, unsigned int *sleepTime); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#endif diff --git a/platform/cpu/arm/cortex-m4/src/los_vendor.s b/platform/cpu/arm/cortex-m4/src/los_vendor.s new file mode 100755 index 00000000..14166ce4 --- /dev/null +++ b/platform/cpu/arm/cortex-m4/src/los_vendor.s @@ -0,0 +1,62 @@ +; +; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020, 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. +; + + PRESERVE8 + + AREA RESET, CODE, READONLY + THUMB + + IMPORT ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit|| + IMPORT PendSV_Handler + + EXPORT _BootVectors + EXPORT osResetVector + +_BootVectors + DCD ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit|| + DCD osResetVector + + +osResetVector + CPSID I + + IMPORT LOS_HardBootInit + LDR R0, =LOS_HardBootInit + BLX R0 + + IMPORT __main + LDR R0, =__main + BX R0 + + + ALIGN + END + diff --git a/platform/cpu/arm/cortex-m7/src/los_sr.h b/platform/cpu/arm/cortex-m7/src/los_sr.h new file mode 100755 index 00000000..e2fc6537 --- /dev/null +++ b/platform/cpu/arm/cortex-m7/src/los_sr.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 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_SR_H__ +#define __LOS_SR_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define SENSORHUB_COLDBOOT 0x1 +#define SENSORHUB_SLEEP 0x2 + + +#define OS_WAKEUP_INFO_COUNT 32 +typedef struct tagWakeupInfo +{ + UINT64 uwSleepTimeTotal; + UINT8 ucIdx; + UINT8 ucIsFull; + UINT8 auwPID[OS_WAKEUP_INFO_COUNT]; +}OS_WAKEUP_INFO; + + +extern unsigned int g_uwSrStateFlag; +extern unsigned int g_uwOneshotLoadValue; + +extern unsigned int osDelayTskSuspend(); +extern void osDelayTskResume(unsigned int sleep_time); + +extern unsigned int osSwTmrGetNextTimeout(void); +extern void osSwTmrAdjust(unsigned int sleep_time); + +extern void osTickLock(void); +extern void osTickUnlock(void); +extern int osSRSuspend(void); +extern void osSRResume(void); + +extern unsigned int getSleepTime(); +extern void DisableWakeUpTimer(void); +extern void enterSleepMode(unsigned int SleepTime); +extern void enterStopMode(unsigned int SleepTime); +extern void StopMode_Measure(unsigned int sleepTime, unsigned int WakeUpClock); + +extern void LOS_SrIdleTaskProcess(void); + +extern void LOS_SystemWakeup(UINT32 uwHwiIndex); +extern void osSRSaveRegister(); +extern void osSRRestoreRegister(); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ +#endif diff --git a/readme.md b/readme.md new file mode 100755 index 00000000..0ac8a864 --- /dev/null +++ b/readme.md @@ -0,0 +1 @@ +详见:https://gitee.com/openharmony/docs/blob/master/readme/内核子系统README.md