diff --git a/arch/arm/arm-m/cortex-m0/gcc/los_dispatch_gcc.S b/arch/arm/arm-m/cortex-m0/gcc/los_dispatch_gcc.S deleted file mode 100644 index 4fd7dd1eb..000000000 --- a/arch/arm/arm-m/cortex-m0/gcc/los_dispatch_gcc.S +++ /dev/null @@ -1,380 +0,0 @@ -/** ---------------------------------------------------------------------------- - * Copyright (c) <2016-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/** ---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**************************************************************************************** -* EXPORT FUNCTIONS -****************************************************************************************/ - - .global LOS_IntLock - .global LOS_IntUnLock - .global LOS_IntRestore - .global LOS_StartToRun - .global osTaskSchedule - .global PendSV_Handler - -/**************************************************************************************** -* EXTERN PARAMETERS -****************************************************************************************/ - - .extern g_stLosTask - .extern g_pfnTskSwitchHook - .extern g_bTaskScheduled - -/**************************************************************************************** -* EQU -****************************************************************************************/ - -.equ OS_NVIC_INT_CTRL, 0xE000ED04 /* Interrupt Control and State Register. */ -.equ OS_NVIC_PENDSVSET, 0x10000000 /* Value to trigger PendSV exception. */ - -.equ OS_NVIC_SYSPRI2, 0xE000ED20 /* System Handler Priority Register 2. */ -.equ OS_NVIC_PENDSV_SYSTICK_PRI, 0xC0C00000 /* SysTick + PendSV priority level (lowest). */ - -.equ OS_TASK_STATUS_RUNNING, 0x0010 /* Task Status Flag (RUNNING). */ - -/**************************************************************************************** -* CODE GENERATION DIRECTIVES -****************************************************************************************/ - - .section .text - .thumb - .syntax unified - .arch armv6-m - -/**************************************************************************************** -* Function: -* VOID LOS_StartToRun(VOID); -* Description: -* Start the first task, which is the highest priority task in the priority queue. -* Other tasks are started by task scheduling. -****************************************************************************************/ - .type LOS_StartToRun, %function -LOS_StartToRun: - CPSID I - - /** - * Set PendSV and SysTick prority to the lowest. - * read ---> modify ---> write-back. - */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORRS R1, R1, R2 - STR R1, [R0] - - /** - * Set g_bTaskScheduled = 1. - */ - LDR R0, =g_bTaskScheduled - MOVS R1, #1 - STR R1, [R0] - - /** - * Now PSP is an invalid value, R13 uses MSP as the stack pointer. - * After setting the control register, R13 will switch to PSP. - * To ensure that R13 is valid, set PSP = MSP. - */ - MRS R0, MSP - MSR PSP, R0 - - /** - * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - */ - MOVS R0, #2 - MSR CONTROL, R0 - - /** - * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - /** - * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOVS R3, #OS_TASK_STATUS_RUNNING - ORRS R2, R2, R3 - STRH R2, [R1, #4] - - /** - * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - * Return by setting the CONTROL register. - * - * The initial stack of the current running task is as follows: - * - * POP: Restore the context of the current running task ===>| - * High addr--->| - * Bottom of the stack--->| - * ----------+-----------------------+--------------------------------------+ - * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - * ----------+-----------------------+--------------------------------------+ - * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - * |<--- skip --->|<--- copy to R0-R7 --->| - * R3 to PSP--->| - * Stack pointer after LOS_StartToRun--->| - */ - LDR R3, [R1] - ADDS R3, R3, #36 /* skip R4-R11, PRIMASK. */ - - LDMFD R3!, {R0-R2} /* restore R0-R2. */ - ADDS R3, R3, #4 /* skip R3. */ - LDMFD R3!, {R4-R7} /* restore R12,LR,PC,xPSR. */ - - /** - * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - */ - MSR PSP, R3 - - SUBS R3, R3, #20 - LDR R3, [R3] /* restore R3. */ - - /** - * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - */ - MOV LR, R5 - CPSIE I - - /** - * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - * of the main function will be destroyed and will never be returned. - */ - BX R6 - -/**************************************************************************************** -* Function: -* UINTPTR LOS_IntLock(VOID); -* Description: -* Disable all interrupts except Reset,NMI and HardFault. -* The value of currnet interruption state will be returned to the caller to save. -* -* Function: -* VOID LOS_IntRestore(UINTPTR uvIntSave); -* Description: -* Restore the locked interruption of LOS_IntLock. -* The caller must pass in the value of interruption state previously saved. -****************************************************************************************/ - .type LOS_IntLock, %function -LOS_IntLock: - MRS R0, PRIMASK - CPSID I - BX LR - - .type LOS_IntUnLock, %function -LOS_IntUnLock: - MRS R0, PRIMASK - CPSIE I - BX LR - - .type LOS_IntRestore, %function -LOS_IntRestore: - MSR PRIMASK, R0 - BX LR - -/**************************************************************************************** -* Function: -* VOID osTaskSchedule(VOID); -* Description: -* Start the task swtich process by software trigger PendSV interrupt. -****************************************************************************************/ - .type osTaskSchedule, %function -osTaskSchedule: - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -/**************************************************************************************** -* Function: -* VOID PendSV_Handler(VOID); -* Description: -* PendSV interrupt handler, switch the context of the task. -* First: Save the context of the current running task(g_stLosTask.pstRunTask) -* to its own stack. -* Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -* from its own stack. -****************************************************************************************/ - .type PendSV_Handler, %function -PendSV_Handler: - /** - * R12: Save the interruption state of the current running task. - * Disable all interrupts except Reset,NMI and HardFault - */ - MRS R12, PRIMASK - CPSID I - - /** - * Call task switch hook. - */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CMP R2, #0 - BEQ TaskSwitch - MOV R1, LR - PUSH {R0, R1} - BLX R2 - POP {R0, R1} - MOV LR, R1 - -TaskSwitch: - /** - * R0 = now stack pointer of the current running task. - */ - MRS R0, PSP - - /** - * Save the stack frame(R4-R11) of the current running task. - * R12 save the PRIMASK value of the current running task. - * NOTE: Before entering the exception handler function, these registers - * (xPSR,PC,LR,R12,R3-R0) have been automatically - * saved by the CPU in the stack of the current running task. - * - * The stack of the current running task is as follows: - * - * |<=== PUSH: Save the context of the current running task - * | High addr--->| - * ----------+-----------------------+--------------------------------------+----- - * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - * ----------+-----------------------+--------------------------------------+----- - * Stack pointer before entering exception--->| - * |<--- cpu auto saved --->| - * |<---PSP to R0 - * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - */ - SUBS R0, #36 - STMIA R0!, {R4-R7} /* save R4-R7. */ - MOV R3, R8 /* copy R8-r12 to R3-r7. */ - MOV R4, R9 - MOV R5, R10 - MOV R6, R11 - MOV R7, R12 - STMIA R0!, {R3-R7} /* save R8-R12. */ - SUBS R0, #36 - - /** - * R5,R3. - */ - LDR R5, =g_stLosTask - MOVS R3, #OS_TASK_STATUS_RUNNING - - /** - * Save the stack pointer of the current running task to TCB. - * (g_stLosTask.pstRunTask->pStackPointer = R0) - */ - LDR R6, [R5] - STR R0, [R6] - - /** - * Clear the RUNNING state of the current running task. - * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - */ - LDRH R7, [R6, #4] - BICS R7, R7, R3 - STRH R7, [R6, #4] - - /** - * Switch the current running task to the next running task. - * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - */ - LDR R0, [R5, #4] - STR R0, [R5] - - /** - * Set the RUNNING state of the next running task. - * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - */ - LDRH R7, [R0, #4] - ORRS R7, R7, R3 - STRH R7, [R0, #4] - - /** - * Restore the stack pointer of the next running task from TCB. - * (R1 = g_stLosTask.pstNewTask->pStackPointer) - */ - LDR R1, [R0] - - /** - * Restore the stack frame(R4-R11) of the next running task. - * R12 restore the PRIMASK value of the next running task. - * NOTE: After exiting the exception handler function, these registers - * (xPSR,R0-R3,R12,LR,PC) will be automatically - * restored by the CPU from the stack of the next running task. - * - * 1. The stack of the next running task is as follows: - * - * POP: Restore the context of the next running task ===>| - * High addr--->| - * ----------+-----------------------+--------------------------------------+----- - * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - * ----------+-----------------------+--------------------------------------+----- - * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - * R1 to PSP--->| - * |<--- cpu auto restoring --->| - * Stack pointer after exiting exception--->| - * - * 2. If the next running task is run for the first time, the stack is as follows: - * - * POP: Restore the context of the next running task ===>| - * High addr--->| - * Bottom of the stack--->| - * ----------+-----------------------+--------------------------------------+ - * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - * ----------+-----------------------+--------------------------------------+ - * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - * R1 to PSP--->| - * |<--- cpu auto restoring --->| - * Stack pointer after exiting exception--->| - */ - ADDS R1, #16 - LDMFD R1!, {R3-R7} /* restore R8-R12 to R3-R7. */ - MOV R8, R3 /* copy R3-R7 to R8-R12. */ - MOV R9, R4 - MOV R10, R5 - MOV R11, R6 - MOV R12, R7 - /** - * Set the stack pointer of the next running task to PSP. - */ - MSR PSP, R1 - SUBS R1, #36 - LDMFD R1!, {R4-R7} /* restore R4-R7. */ - - /** - * Restore the interruption state of the next running task. - */ - MSR PRIMASK, R12 - BX LR - diff --git a/arch/arm/arm-m/cortex-m0/gcc/los_hw_exc_gcc.S b/arch/arm/arm-m/cortex-m0/gcc/los_hw_exc_gcc.S deleted file mode 100644 index a08965bd8..000000000 --- a/arch/arm/arm-m/cortex-m0/gcc/los_hw_exc_gcc.S +++ /dev/null @@ -1,286 +0,0 @@ -/*---------------------------------------------------------------------------- - Copyright (c) <2013-2015>, - 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. ----------------------------------------------------------------------------- - Notice of Export Control Law - =============================================== - Huawei LiteOS may be subject to applicable export control laws and regulations, which might - include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - applicable export control laws and regulations. - ---------------------------------------------------------------------------*/ - -/**************************************************************************************** - CODE GENERATION DIRECTIVES -****************************************************************************************/ - - .section .text - .thumb - .syntax unified - .arch armv6-m - -/**************************************************************************************** - EXPORT FUNCTIONS -****************************************************************************************/ - - .global NMI_Handler - .global HardFault_Handler - .global MemManage_Handler - .global BusFault_Handler - .global UsageFault_Handler - - - -/**************************************************************************************** - EXTERN PARAMETERS -****************************************************************************************/ - - .extern osExcHandleEntry - .extern g_uwExcTbl - .extern g_bTaskScheduled - .extern it_is_memManangeFault - .extern it_is_busFault - .extern it_is_usageFault - -/**************************************************************************************** - EQU -****************************************************************************************/ - -.equ OS_EXC_CAUSE_NMI, 18 -.equ OS_EXC_CAUSE_HARDFAULT, 19 -.equ OS_EXC_CAUSE_MEMFAULT, 20 -.equ OS_EXC_CAUSE_BUSFAULT, 21 -.equ OS_EXC_CAUSE_USAGEFAULT, 22 -.equ OS_EXC_CAUSE_SVC, 23 - -.equ HF_DEBUGEVT, 24 -.equ HF_VECTBL, 25 - -.equ FLAG_ADDR_VALID, 0x10000 /*bit 16*/ -.equ FLAG_HWI_ACTIVE, 0x20000 /*bit 17*/ -.equ FLAG_NO_FLOAT, 0x10000000 /*bit 28*/ - -.equ OS_NVIC_CFSR, 0xE000ED28 /*include BusFault/MemFault/UsageFault State Regeister*/ -.equ OS_NVIC_HFSR, 0xE000ED2C /*HardFault State Regeister*/ -.equ OS_NVIC_BFAR, 0xE000ED38 -.equ OS_NVIC_MMFAR, 0xE000ED34 -.equ OS_NVIC_ACT_BASE, 0xE000E300 -.equ OS_NVIC_SHCSRS, 0xE000ED24 -.equ OS_NVIC_SHCSR_MASK, 0xC00 /*SYSTICKACT and PENDSVACT*/ - -.equ ADDR_SETPEND, 0XE000E200 /*the addr of setpend register*/ -.equ ADDR_CLRPEND, 0XE000E280 /*the addr of clrpend register*/ -.equ ADDR_SETENA, 0XE000E100 -.equ EXC_RETURN_NEST, 0XFFFFFFF1 /*return to some irq_handler*/ -/**************************************************************************************** - Function: - VOID NMI_Handler(VOID) - Description: - NMI Handler. -****************************************************************************************/ - .type NMI_Handler, %function -NMI_Handler: - /** - * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +------------------------------------------------------+------------------------+ - * | 31-8 | 7-0 | - * +------------------------------------------------------+------------------------+ - * | --- | OS_EXC_CAUSE_NMI | - * +------------------------------------------------------+------------------------+ - * < R1 >: invalid - */ - MOVS R0, #OS_EXC_CAUSE_NMI - MOVS R1, #0 - B osExcDispatch - -/**************************************************************************************** - Function: - VOID HardFault_Handler(VOID) - Description: - HardFault Handler. -****************************************************************************************/ - .type HardFault_Handler, %function -HardFault_Handler: - /** - * save fault type to R0 - */ - MOVS R0, #OS_EXC_CAUSE_HARDFAULT - B osExcDispatch - - - /** - * When executing osExcDispatch, R2 will be used. - */ -osExcDispatch: - - LDR R2, =ADDR_SETPEND - LDR R2, [R2] - LDR R3,=0X40 - LSLS R3,R3,#0X18 - SUBS R3,R3,#1 /*R3 =0011 1111 1111 1111 1111 1111 1111 1111 filter the highest active 2 bits error*/ - ANDS R2,R2,R3 - LDR R3,=ADDR_SETENA - LDR R3,[R3] - ANDS R2,R2,R3 /*if an interrupt is enabled and active ,it is a nomal exception ,otherwise,it should be ignored*/ - - MOV R1,LR - LDR R3, =EXC_RETURN_NEST - CMP R1,R3 - BEQ __in_interrupt /*jump when they are equal,if LR equals it,they are in some interrupt*/ - B __second_judge -__in_interrupt: - CMP R2,#0 - BEQ __set_R2_33 - B _NoFloatInMsp - -__set_R2_33: - MOVS R2,#0x21 /*if in interrupt,but the setpendAddr is 0,sth wrong happened, set id to 33*/ - B _NoFloatInMsp - -__second_judge: - CMP R2,#0 - BEQ _whether_in_initialization /*jump when no external interrupt occurred*/ - - /** - * Interrupts and initialization phase always use MSP. - */ -_ExcInMSP: - /** - * Before executing instruction 'B _handleEntry', MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR | - * +--------------------------------------------------------------------------------+--------- - * R13--->| Initial R13--->|<--- #32 --->|<---SAVED_SP - * | (CPU auto saved) | - * - */ -_NoFloatInMsp: - CMP R2,#0 /*check r2 ,find the phase interrupts occurred*/ - BEQ __11 - MOVS R1,#0x2f /*in interrupt phase ,r1=47*/ - LSLS R0,R0,#8 - ORRS R0,R0,R1 /*make r1 available*/ - B __12 -__11: - MOVS R1,#0 /*in initialization phase r1=0*/ - LSLS R0,R0,#8 - ORRS R0,R0,R1 /* make r1 available */ -__12: - ADD R3, R13, #32 /*#32: skip [R0-R3,R12,LR,PC,xPSR]*/ - PUSH {R3} /*push [SAVED_SP]: MSP+32 = Stack pointer in MSP before entering the exception*/ - MRS R12, PRIMASK - MOV R3,R12 - PUSH {R3} - MOV R3,R11 - PUSH {R3} - MOV R3,R10 - PUSH {R3} - MOV R3,R9 - PUSH {R3} - MOV R3,R8 - PUSH {R3} - PUSH {R7} - PUSH {R6} - PUSH {R5} - PUSH {R4} /*push R4-R11,PRIMASK to MSP in certain order*/ - - B _handleEntry - - /** - * Check whether during the initialization phase. - * If g_bTaskScheduled == 0, it is in the initialization phase. - */ -_whether_in_initialization: - LDR R1, =g_bTaskScheduled - LDR R1, [R1] - MOVS R3,#1 - TST R1,R3 - BEQ _ExcInMSP /*initialization phase use MSP*/ - - /** - * Before executing _handleEntry, MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR | - * +--------------------------------------------------------------------------------+--------- - * R13--->| |<--- #32 --->|<---Initial R13 - * | (copied from PSP) | - * |<---R2(no use) - * - * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR. - */ -_NoFloatInPsp: - MOVS R1,#1 /*in task ,r1 = 1 */ - LSLS R0,R0,#8 - ORRS R0,R0,R1 /*make r1 available*/ - - MOV R1, R13 - SUB R13, #32 /*#32: MSP reserved, used to store stack frame in PSP*/ - - MRS R3, PSP - - ADDS R3, R3, #32 /*PSP+32 = Stack pointer of the task before entering the exception*/ - - PUSH {R3} /*push task SP to MSP*/ - MRS R3,PRIMASK - PUSH {R3} - MOV R3,R11 - PUSH {R3} - MOV R3,R10 - PUSH {R3} - MOV R3,R9 - PUSH {R3} - MOV R3,R8 - PUSH {R3} - PUSH {R7} - PUSH {R6} - PUSH {R5} - PUSH {R4} - - MRS R3,PSP - /* Copy stack frame from the stack of the current running task to MSP */ - LDMIA R3!, {R4-R7} - SUBS R1,#0X20 - STMIA R1!, {R4-R7} - LDMIA R3!, {R4-R7} - STMIA R1!, {R4-R7} - - /** - * _handleEntry: Call osExcHandleEntry - * param1: R0 --- type num and phase - * param2: R1 --- the sp being used(in Cortex-M0,it is only for debug ) - * param3: R2 --- external interrupt ID - * param4: R3 --- Point to the top of the stack(R4 or S16) that the exception stack frame in MSP. - */ -_handleEntry: - MOV R3, R13 - MOV R1,R13 - CPSID I - LDR R4,=osExcHandleEntry - MOV PC,R4 - NOP diff --git a/arch/arm/arm-m/cortex-m0/iar/los_dispatch_iar.S b/arch/arm/arm-m/cortex-m0/iar/los_dispatch_iar.S deleted file mode 100644 index 16eacfcc3..000000000 --- a/arch/arm/arm-m/cortex-m0/iar/los_dispatch_iar.S +++ /dev/null @@ -1,376 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2016-2018>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT LOS_IntLock - EXPORT LOS_IntUnLock - EXPORT LOS_IntRestore - EXPORT LOS_StartToRun - EXPORT osTaskSchedule - EXPORT PendSV_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT g_stLosTask - IMPORT g_pfnTskSwitchHook - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt Control and State Register. -OS_NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. - -OS_NVIC_SYSPRI2 EQU 0xE000ED20 ; System Handler Priority Register 2. -OS_NVIC_PENDSV_SYSTICK_PRI EQU 0xC0C00000 ; SysTick + PendSV priority level (lowest). - -OS_TASK_STATUS_RUNNING EQU 0x0010 ; Task Status Flag (RUNNING). - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - SECTION .text:CODE(2) - THUMB - REQUIRE8 - PRESERVE8 - -;**************************************************************************************** -; Function: -; VOID LOS_StartToRun(VOID); -; Description: -; Start the first task, which is the highest priority task in the priority queue. -; Other tasks are started by task scheduling. -;**************************************************************************************** -LOS_StartToRun - CPSID I - - ;/** - ; * Set PendSV and SysTick prority to the lowest. - ; * read ---> modify ---> write-back. - ; */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORRS R1, R1, R2 - STR R1, [R0] - - ;/** - ; * Set g_bTaskScheduled = 1. - ; */ - LDR R0, =g_bTaskScheduled - MOVS R1, #1 - STR R1, [R0] - - ;/** - ; * Now PSP is an invalid value, R13 uses MSP as the stack pointer. - ; * After setting the control register, R13 will switch to PSP. - ; * To ensure that R13 is valid, set PSP = MSP. - ; */ - MRS R0, MSP - MSR PSP, R0 - - ;/** - ; * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - ; */ - MOVS R0, #2 - MSR CONTROL, R0 - - ;/** - ; * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - ; */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - ; */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOVS R3, #OS_TASK_STATUS_RUNNING - ORRS R2, R2, R3 - STRH R2, [R1, #4] - - ;/** - ; * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - ; * Return by setting the CONTROL register. - ; * - ; * The initial stack of the current running task is as follows: - ; * - ; * POP: Restore the context of the current running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+-----------------------+--------------------------------------+ - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - ; * |<--- skip --->|<--- copy to R0-R7 --->| - ; * R3 to PSP--->| - ; * Stack pointer after LOS_StartToRun--->| - ; */ - LDR R3, [R1] - ADDS R3, R3, #36 ; skip R4-R11, PRIMASK. - - LDMFD R3!, {R0-R2} ; restore R0-R2. - ADDS R3, R3, #4 ; skip R3. - LDMFD R3!, {R4-R7} ; restore R12,LR,PC,xPSR. - - ;/** - ; * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - ; */ - MSR PSP, R3 - - SUBS R3, R3, #20 - LDR R3, [R3] ; restore R3. - - ;/** - ; * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - ; */ - MOV LR, R5 - CPSIE I - - ;/** - ; * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - ; * of the main function will be destroyed and will never be returned. - ; */ - BX R6 - -;**************************************************************************************** -; Function: -; UINTPTR LOS_IntLock(VOID); -; Description: -; Disable all interrupts except Reset,NMI and HardFault. -; The value of currnet interruption state will be returned to the caller to save. -; -; Function: -; VOID LOS_IntRestore(UINTPTR uvIntSave); -; Description: -; Restore the locked interruption of LOS_IntLock. -; The caller must pass in the value of interruption state previously saved. -;**************************************************************************************** -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 - -;**************************************************************************************** -; Function: -; VOID osTaskSchedule(VOID); -; Description: -; Start the task swtich process by software trigger PendSV interrupt. -;**************************************************************************************** -osTaskSchedule - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -;**************************************************************************************** -; Function: -; VOID PendSV_Handler(VOID); -; Description: -; PendSV interrupt handler, switch the context of the task. -; First: Save the context of the current running task(g_stLosTask.pstRunTask) -; to its own stack. -; Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -; from its own stack. -;**************************************************************************************** -PendSV_Handler - ;/** - ; * R12: Save the interruption state of the current running task. - ; * Disable all interrupts except Reset,NMI and HardFault - ; */ - MRS R12, PRIMASK - CPSID I - - ;/** - ; * Call task switch hook. - ; */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CMP R2, #0 - BEQ TaskSwitch - MOV R1, LR - PUSH {R0, R1} - BLX R2 - POP {R0, R1} - MOV LR, R1 - -TaskSwitch - ;/** - ; * R0 = now stack pointer of the current running task. - ; */ - MRS R0, PSP - - ;/** - ; * Save the stack frame(R4-R11) of the current running task. - ; * R12 save the PRIMASK value of the current running task. - ; * NOTE: Before entering the exception handler function, these registers - ; * (xPSR,PC,LR,R12,R3-R0) have been automatically - ; * saved by the CPU in the stack of the current running task. - ; * - ; * The stack of the current running task is as follows: - ; * - ; * |<=== PUSH: Save the context of the current running task - ; * | High addr--->| - ; * ----------+-----------------------+--------------------------------------+----- - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+----- - ; * Stack pointer before entering exception--->| - ; * |<--- cpu auto saved --->| - ; * |<---PSP to R0 - ; * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - ; */ - SUBS R0, #36 - STMIA R0!, {R4-R7} ; save R4-R7. - MOV R3, R8 ; copy R8-r12 to R3-r7. - MOV R4, R9 - MOV R5, R10 - MOV R6, R11 - MOV R7, R12 - STMIA R0!, {R3-R7} ; save R8-R12. - SUBS R0, #36 - - ;/** - ; * R5,R3. - ; */ - LDR R5, =g_stLosTask - MOVS R3, #OS_TASK_STATUS_RUNNING - - ;/** - ; * Save the stack pointer of the current running task to TCB. - ; * (g_stLosTask.pstRunTask->pStackPointer = R0) - ; */ - LDR R6, [R5] - STR R0, [R6] - - ;/** - ; * Clear the RUNNING state of the current running task. - ; * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R6, #4] - BICS R7, R7, R3 - STRH R7, [R6, #4] - - ;/** - ; * Switch the current running task to the next running task. - ; * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - ; */ - LDR R0, [R5, #4] - STR R0, [R5] - - ;/** - ; * Set the RUNNING state of the next running task. - ; * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R0, #4] - ORRS R7, R7, R3 - STRH R7, [R0, #4] - - ;/** - ; * Restore the stack pointer of the next running task from TCB. - ; * (R1 = g_stLosTask.pstNewTask->pStackPointer) - ; */ - LDR R1, [R0] - - ;/** - ; * Restore the stack frame(R4-R11) of the next running task. - ; * R12 restore the PRIMASK value of the next running task. - ; * NOTE: After exiting the exception handler function, these registers - ; * (xPSR,R0-R3,R12,LR,PC) will be automatically - ; * restored by the CPU from the stack of the next running task. - ; * - ; * 1. The stack of the next running task is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * ----------+-----------------------+--------------------------------------+----- - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+----- - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; * - ; * 2. If the next running task is run for the first time, the stack is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+-----------------------+--------------------------------------+ - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; */ - ADDS R1, #16 - LDMFD R1!, {R3-R7} ; restore R8-R12 to R3-R7. - MOV R8, R3 ; copy R3-R7 to R8-R12. - MOV R9, R4 - MOV R10, R5 - MOV R11, R6 - MOV R12, R7 - ;/** - ; * Set the stack pointer of the next running task to PSP. - ; */ - MSR PSP, R1 - SUBS R1, #36 - LDMFD R1!, {R4-R7} ; restore R4-R7. - - ;/** - ; * Restore the interruption state of the next running task. - ; */ - MSR PRIMASK, R12 - BX LR - - END - diff --git a/arch/arm/arm-m/cortex-m0/keil/los_dispatch_keil.S b/arch/arm/arm-m/cortex-m0/keil/los_dispatch_keil.S deleted file mode 100644 index 4289aea7e..000000000 --- a/arch/arm/arm-m/cortex-m0/keil/los_dispatch_keil.S +++ /dev/null @@ -1,377 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2016-2018>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT LOS_IntLock - EXPORT LOS_IntUnLock - EXPORT LOS_IntRestore - EXPORT LOS_StartToRun - EXPORT osTaskSchedule - EXPORT PendSV_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT g_stLosTask - IMPORT g_pfnTskSwitchHook - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt Control and State Register. -OS_NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. - -OS_NVIC_SYSPRI2 EQU 0xE000ED20 ; System Handler Priority Register 2. -OS_NVIC_PENDSV_SYSTICK_PRI EQU 0xC0C00000 ; SysTick + PendSV priority level (lowest). - -OS_TASK_STATUS_RUNNING EQU 0x0010 ; Task Status Flag (RUNNING). - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - AREA |.text|, CODE, READONLY - THUMB - REQUIRE8 - PRESERVE8 - -;**************************************************************************************** -; Function: -; VOID LOS_StartToRun(VOID); -; Description: -; Start the first task, which is the highest priority task in the priority queue. -; Other tasks are started by task scheduling. -;**************************************************************************************** -LOS_StartToRun - CPSID I - - ;/** - ; * Set PendSV and SysTick prority to the lowest. - ; * read ---> modify ---> write-back. - ; */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORRS R1, R1, R2 - STR R1, [R0] - - ;/** - ; * Set g_bTaskScheduled = 1. - ; */ - LDR R0, =g_bTaskScheduled - MOVS R1, #1 - STR R1, [R0] - - ;/** - ; * Now PSP is an invalid value, R13 uses MSP as the stack pointer. - ; * After setting the control register, R13 will switch to PSP. - ; * To ensure that R13 is valid, set PSP = MSP. - ; */ - MRS R0, MSP - MSR PSP, R0 - - ;/** - ; * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - ; */ - MOVS R0, #2 - MSR CONTROL, R0 - - ;/** - ; * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - ; */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - ; */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOVS R3, #OS_TASK_STATUS_RUNNING - ORRS R2, R2, R3 - STRH R2, [R1, #4] - - ;/** - ; * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - ; * Return by setting the CONTROL register. - ; * - ; * The initial stack of the current running task is as follows: - ; * - ; * POP: Restore the context of the current running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+-----------------------+--------------------------------------+ - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - ; * |<--- skip --->|<--- copy to R0-R7 --->| - ; * R3 to PSP--->| - ; * Stack pointer after LOS_StartToRun--->| - ; */ - LDR R3, [R1] - ADDS R3, R3, #36 ; skip R4-R11, PRIMASK. - - LDMFD R3!, {R0-R2} ; restore R0-R2. - ADDS R3, R3, #4 ; skip R3. - LDMFD R3!, {R4-R7} ; restore R12,LR,PC,xPSR. - - ;/** - ; * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - ; */ - MSR PSP, R3 - - SUBS R3, R3, #20 - LDR R3, [R3] ; restore R3. - - ;/** - ; * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - ; */ - MOV LR, R5 - CPSIE I - - ;/** - ; * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - ; * of the main function will be destroyed and will never be returned. - ; */ - BX R6 - -;**************************************************************************************** -; Function: -; UINTPTR LOS_IntLock(VOID); -; Description: -; Disable all interrupts except Reset,NMI and HardFault. -; The value of currnet interruption state will be returned to the caller to save. -; -; Function: -; VOID LOS_IntRestore(UINTPTR uvIntSave); -; Description: -; Restore the locked interruption of LOS_IntLock. -; The caller must pass in the value of interruption state previously saved. -;**************************************************************************************** -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 - -;**************************************************************************************** -; Function: -; VOID osTaskSchedule(VOID); -; Description: -; Start the task swtich process by software trigger PendSV interrupt. -;**************************************************************************************** -osTaskSchedule - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -;**************************************************************************************** -; Function: -; VOID PendSV_Handler(VOID); -; Description: -; PendSV interrupt handler, switch the context of the task. -; First: Save the context of the current running task(g_stLosTask.pstRunTask) -; to its own stack. -; Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -; from its own stack. -;**************************************************************************************** -PendSV_Handler - ;/** - ; * R12: Save the interruption state of the current running task. - ; * Disable all interrupts except Reset,NMI and HardFault - ; */ - MRS R12, PRIMASK - CPSID I - - ;/** - ; * Call task switch hook. - ; */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CMP R2, #0 - BEQ TaskSwitch - MOV R1, LR - PUSH {R0, R1} - BLX R2 - POP {R0, R1} - MOV LR, R1 - -TaskSwitch - ;/** - ; * R0 = now stack pointer of the current running task. - ; */ - MRS R0, PSP - - ;/** - ; * Save the stack frame(R4-R11) of the current running task. - ; * R12 save the PRIMASK value of the current running task. - ; * NOTE: Before entering the exception handler function, these registers - ; * (xPSR,PC,LR,R12,R3-R0) have been automatically - ; * saved by the CPU in the stack of the current running task. - ; * - ; * The stack of the current running task is as follows: - ; * - ; * |<=== PUSH: Save the context of the current running task - ; * | High addr--->| - ; * ----------+-----------------------+--------------------------------------+----- - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+----- - ; * Stack pointer before entering exception--->| - ; * |<--- cpu auto saved --->| - ; * |<---PSP to R0 - ; * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - ; */ - SUBS R0, #36 - STMIA R0!, {R4-R7} ; save R4-R7. - MOV R3, R8 ; copy R8-r12 to R3-r7. - MOV R4, R9 - MOV R5, R10 - MOV R6, R11 - MOV R7, R12 - STMIA R0!, {R3-R7} ; save R8-R12. - SUBS R0, #36 - - ;/** - ; * R5,R3. - ; */ - LDR R5, =g_stLosTask - MOVS R3, #OS_TASK_STATUS_RUNNING - - ;/** - ; * Save the stack pointer of the current running task to TCB. - ; * (g_stLosTask.pstRunTask->pStackPointer = R0) - ; */ - LDR R6, [R5] - STR R0, [R6] - - ;/** - ; * Clear the RUNNING state of the current running task. - ; * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R6, #4] - BICS R7, R7, R3 - STRH R7, [R6, #4] - - ;/** - ; * Switch the current running task to the next running task. - ; * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - ; */ - LDR R0, [R5, #4] - STR R0, [R5] - - ;/** - ; * Set the RUNNING state of the next running task. - ; * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R0, #4] - ORRS R7, R7, R3 - STRH R7, [R0, #4] - - ;/** - ; * Restore the stack pointer of the next running task from TCB. - ; * (R1 = g_stLosTask.pstNewTask->pStackPointer) - ; */ - LDR R1, [R0] - - ;/** - ; * Restore the stack frame(R4-R11) of the next running task. - ; * R12 restore the PRIMASK value of the next running task. - ; * NOTE: After exiting the exception handler function, these registers - ; * (xPSR,R0-R3,R12,LR,PC) will be automatically - ; * restored by the CPU from the stack of the next running task. - ; * - ; * 1. The stack of the next running task is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * ----------+-----------------------+--------------------------------------+----- - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+----- - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; * - ; * 2. If the next running task is run for the first time, the stack is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+-----------------------+--------------------------------------+ - ; * | R4-R11, PRIMASK | R0-R3, R12, LR, PC, xPSR | - ; * ----------+-----------------------+--------------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; */ - ADDS R1, #16 - LDMFD R1!, {R3-R7} ; restore R8-R12 to R3-R7. - MOV R8, R3 ; copy R3-R7 to R8-R12. - MOV R9, R4 - MOV R10, R5 - MOV R11, R6 - MOV R12, R7 - ;/** - ; * Set the stack pointer of the next running task to PSP. - ; */ - MSR PSP, R1 - SUBS R1, #36 - LDMFD R1!, {R4-R7} ; restore R4-R7. - - ;/** - ; * Restore the interruption state of the next running task. - ; */ - MSR PRIMASK, R12 - BX LR - - ALIGN - END - diff --git a/arch/arm/arm-m/cortex-m0/keil/los_hw_exc_keil.S b/arch/arm/arm-m/cortex-m0/keil/los_hw_exc_keil.S deleted file mode 100644 index dfa48eb8e..000000000 --- a/arch/arm/arm-m/cortex-m0/keil/los_hw_exc_keil.S +++ /dev/null @@ -1,284 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2013-2015>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - PRESERVE8 - AREA |.text|, CODE, READONLY - THUMB - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT NMI_Handler - EXPORT HardFault_Handler - EXPORT MemManage_Handler - EXPORT BusFault_Handler - EXPORT UsageFault_Handler -; EXPORT SVC_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT osExcHandleEntry - IMPORT g_uwExcTbl - IMPORT g_bTaskScheduled - IMPORT it_is_memManangeFault - IMPORT it_is_busFault - IMPORT it_is_usageFault - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_EXC_CAUSE_NMI EQU 18 -OS_EXC_CAUSE_HARDFAULT EQU 19 -OS_EXC_CAUSE_MEMFAULT EQU 20 -OS_EXC_CAUSE_BUSFAULT EQU 21 -OS_EXC_CAUSE_USAGEFAULT EQU 22 -OS_EXC_CAUSE_SVC EQU 23 - -HF_DEBUGEVT EQU 24 -HF_VECTBL EQU 25 - -FLAG_ADDR_VALID EQU 0x10000 ; bit 16 -FLAG_HWI_ACTIVE EQU 0x20000 ; bit 17 -FLAG_NO_FLOAT EQU 0x10000000 ; bit 28 - -OS_NVIC_CFSR EQU 0xE000ED28 ; include BusFault/MemFault/UsageFault State Regeister -OS_NVIC_HFSR EQU 0xE000ED2C ; HardFault State Regeister -OS_NVIC_BFAR EQU 0xE000ED38 -OS_NVIC_MMFAR EQU 0xE000ED34 -OS_NVIC_ACT_BASE EQU 0xE000E300 -OS_NVIC_SHCSRS EQU 0xE000ED24 -OS_NVIC_SHCSR_MASK EQU 0xC00 ; SYSTICKACT and PENDSVACT - -ADDR_SETPEND EQU 0XE000E200 ;the addr of setpend register -ADDR_CLRPEND EQU 0XE000E280 ;the addr of clrpend register -;**************************************************************************************** -; Function: -; VOID NMI_Handler(VOID); -; Description: -; NMI Handler. -;**************************************************************************************** -NMI_Handler - ;/** - ; * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - ; * < R0 >: - ; * +------------------------------------------------------+------------------------+ - ; * | 31-8 | 7-0 | - ; * +------------------------------------------------------+------------------------+ - ; * | --- | OS_EXC_CAUSE_NMI | - ; * +------------------------------------------------------+------------------------+ - ; * < R1 >: invalid - ; */ - MOVS R0, #OS_EXC_CAUSE_NMI - MOVS R1, #0 - B osExcDispatch - -;**************************************************************************************** -; Function: -; VOID HardFault_Handler(VOID); -; Description: -; HardFault Handler. -;**************************************************************************************** -HardFault_Handler - ;/** - ; * save fault type to R0 - ; */ - MOVS R0, #OS_EXC_CAUSE_HARDFAULT - B osExcDispatch - -;**************************************************************************************** -; Function: -; VOID BusFault_Handler(VOID); -; Description: -; BusFault Handler. -;**************************************************************************************** -BusFault_Handler - BL it_is_busFault -;**************************************************************************************** -; Function: -; VOID MemManage_Handler(VOID); -; Description: -; MemManage Handler. -;**************************************************************************************** -MemManage_Handler - BL it_is_memManangeFault -;**************************************************************************************** -; Function: -; VOID UsageFault_Handler(VOID); -; Description: -; UsageFault Handler. -;**************************************************************************************** -UsageFault_Handler - BL it_is_usageFault - - ;/** - ; * When executing osExcDispatch, R2 will be used. - ; */ -osExcDispatch - LDR R2, =ADDR_SETPEND - LDR R2, [R2] - - CMP R2,#0 - BEQ _whether_in_initialization ;NO external interrupt occurred - - ;/** - ; * Interrupts and initialization phase always use MSP. - ; */ -_ExcInMSP - ;/** - ; * Before executing instruction 'B _handleEntry', MSP is as follows. - ; * MSP: - ; * High addr--->| - ; * +--------------------------------------------------------------------------------+--------- - ; * | R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR | - ; * +--------------------------------------------------------------------------------+--------- - ; * R13--->| Initial R13--->|<--- #32 --->|<---SAVED_SP - ; * | (CPU auto saved) | - ; * - ; */ -_NoFloatInMsp - CMP R2,#0 ;check r2 ,find the phase interrupts occurred - BEQ __11 - MOVS R1,#0x2f ;in interrupt phase ,r1=47 - LSLS R0,R0,#8 - ORRS R0,R0,R1 ;make r1 available - B __12 -__11 - MOVS R1,#0 ;in initialization phase r1=0 - LSLS R0,R0,#8 - ORRS R0,R0,R1 ;make r1 available -__12 - ADD R3, R13, #32 ; #32: skip [R0-R3,R12,LR,PC,xPSR] - PUSH {R3} ; push [SAVED_SP]: MSP+32 = Stack pointer in MSP before entering the exception - MRS R12, PRIMASK - MOV R3,R12 - PUSH {R3} - MOV R3,R11 - PUSH {R3} - MOV R3,R10 - PUSH {R3} - MOV R3,R9 - PUSH {R3} - MOV R3,R8 - PUSH {R3} - PUSH {R7} - PUSH {R6} - PUSH {R5} - PUSH {R4} ; push R4-R11,PRIMASK to MSP in certain order - - B _handleEntry - - ;/** - ; * Check whether during the initialization phase. - ; * If g_bTaskScheduled == 0, it is in the initialization phase. - ; */ -_whether_in_initialization - LDR R1, =g_bTaskScheduled - LDR R1, [R1] - MOVS R3,#1 - TST R1,R3 - BEQ _ExcInMSP ; initialization phase use MSP - - ;/** - ; * Before executing _handleEntry, MSP is as follows. - ; * MSP: - ; * High addr--->| - ; * +--------------------------------------------------------------------------------+--------- - ; * | R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR | - ; * +--------------------------------------------------------------------------------+--------- - ; * R13--->| |<--- #32 --->|<---Initial R13 - ; * | (copied from PSP) | - ; * |<---R2(no use) - ; * - ; * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR. - ; */ -_NoFloatInPsp - MOVS R1,#1 ;in task ,r1 = 1 - LSLS R0,R0,#8 - ORRS R0,R0,R1 ;make r1 available - - MOV R1, R13 - SUB R13, #32 ; #32: MSP reserved, used to store stack frame in PSP - - MRS R3, PSP - - ADDS R3, R3, #32 ; PSP+32 = Stack pointer of the task before entering the exception - - PUSH {R3} ; push task SP to MSP - MRS R3,PRIMASK - PUSH {R3} - MOV R3,R11 - PUSH {R3} - MOV R3,R10 - PUSH {R3} - MOV R3,R9 - PUSH {R3} - MOV R3,R8 - PUSH {R3} - PUSH {R7} - PUSH {R6} - PUSH {R5} - PUSH {R4} - - MRS R3,PSP - ;/* Copy stack frame from the stack of the current running task to MSP */ - LDMIA R3!, {R4-R7} - SUBS R1,#0X20 - STMIA R1!, {R4-R7} - LDMIA R3!, {R4-R7} - STMIA R1!, {R4-R7} - - ;/** - ; * _handleEntry: Call osExcHandleEntry - ; * param1: R0 --- type num and phase - ; * param2: R1 --- the sp being used(in Cortex-M0,it is only for debug ) - ; * param3: R2 --- external interrupt ID - ; * param4: R3 --- Point to the top of the stack(R4 or S16) that the exception stack frame in MSP. - ; */ -_handleEntry - MOV R3, R13 - MOV R1,R13 - CPSID I - LDR R4,=osExcHandleEntry - MOV PC,R4 - NOP - ALIGN - END \ No newline at end of file diff --git a/arch/arm/arm-m/cortex-m0/los_exc.c b/arch/arm/arm-m/cortex-m0/los_exc.c deleted file mode 100644 index 3e64826b3..000000000 --- a/arch/arm/arm-m/cortex-m0/los_exc.c +++ /dev/null @@ -1,578 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - - -#include "los_exc.inc" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#if (LOSCFG_PLATFORM_EXC == YES) - -UINT32 g_uwCurNestCount = 0; -EXC_INFO_S m_stExcInfo; -/* - * CFSR register, include UFSR,BFSR and MFSR. - * - * +----------------------------------------------------------------------------------+ - * | UFSR | - * |-----------+-----------+-----------+-------+------+-------+----------+------------| - * | 31 - 26 | 25 | 24 | 23-20 | 19 | 18 | 17 | 16 | - * |-----------+-----------+-----------+-------+------+-------+----------+------------| - * | --- | DIVBYZERO | UNALIGNED | --- | NOCP | INVPC | INVSTATE | UNDEFINSTR | - * +----------------------------------------------------------------------------------+ - * - * +----------------------------------------------------------------------------------+ - * | BFSR | - * |-----------+-----+--------+--------+----------+-------------+-----------+---------| - * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | - * |-----------+-----+--------+--------+----------+-------------+-----------+---------| - * | BFARVALID | --- | LSPERR | STKERR | UNSTKERR | IMPRECISERR | PRECISERR | IBUSERR | - * +----------------------------------------------------------------------------------+ - * - * +----------------------------------------------------------------------------------+ - * | MFSR | - * |-----------+-------+---------+---------+-----------+-------+----------+-----------| - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - * |-----------+-------+---------+---------+-----------+-------+----------+-----------| - * | MMARVALID | --- | MLSPERR | MSTKERR | MUNSTKERR | --- | DACCVIOL | ICACCVIOL | - * +----------------------------------------------------------------------------------+ - */ -UINT8 g_uwExcTbl[32] = -{ - 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 -}; - -#if (LOSCFG_SAVE_EXC_INFO == YES) -VOID *m_puwExcContent; -UINT32 g_uwArraySize = 0; -EXC_INFO_ARRAY_S m_stExcArray[OS_EXC_TYPE_MAX - 1]; -static VOID osExcSave2DDR(VOID); -#endif - -extern VOID LOS_Reboot(VOID); - -/***************************************************************************** - Function : osExcInfoDisplay - Description : EXC info display - Input : pstExc --- Pointer to the EXC data - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcInfoDisplay(EXC_INFO_S *pstExc) -{ - - //in gcc env - PRINT_ERR("Phase = 0x%8x\n", pstExc->usPhase); - PRINT_ERR("ThrdPid = 0x%8x\n", pstExc->uwThrdPid); - PRINT_ERR("R0 = 0x%8x\t%16u\n", pstExc->pstContext->uwR0,pstExc->pstContext->uwR0); - PRINT_ERR("R1 = 0x%8x\t%16u\n", pstExc->pstContext->uwR1,pstExc->pstContext->uwR1); - PRINT_ERR("R2 = 0x%8x\t%16u\n", pstExc->pstContext->uwR2,pstExc->pstContext->uwR2); - PRINT_ERR("R3 = 0x%8x\t%16u\n", pstExc->pstContext->uwR3,pstExc->pstContext->uwR3); - PRINT_ERR("R4 = 0x%8x\t%16u\n", pstExc->pstContext->uwR4,pstExc->pstContext->uwR4); - PRINT_ERR("R5 = 0x%8x\t%16u\n", pstExc->pstContext->uwR5,pstExc->pstContext->uwR5); - PRINT_ERR("R6 = 0x%8x\t%16u\n", pstExc->pstContext->uwR6,pstExc->pstContext->uwR6); - PRINT_ERR("R7 = 0x%8x\t%16u\n", pstExc->pstContext->uwR7,pstExc->pstContext->uwR7); - PRINT_ERR("R8 = 0x%8x\t%16u\n", pstExc->pstContext->uwR8,pstExc->pstContext->uwR8); - PRINT_ERR("R9 = 0x%8x\t%16u\n", pstExc->pstContext->uwR9,pstExc->pstContext->uwR9); - PRINT_ERR("R10 = 0x%8x\t%16u\n", pstExc->pstContext->uwR10,pstExc->pstContext->uwR10); - PRINT_ERR("R11 = 0x%8x\t%16u\n", pstExc->pstContext->uwR11,pstExc->pstContext->uwR11); - PRINT_ERR("R12 = 0x%8x\t%16u\n", pstExc->pstContext->uwR12,pstExc->pstContext->uwR12); - PRINT_ERR("PriMask = 0x%8x\t%16u\n", pstExc->pstContext->uwPriMask,pstExc->pstContext->uwPriMask); - PRINT_ERR("SP = 0x%8x\t%16u\n", pstExc->pstContext->uwSP,pstExc->pstContext->uwSP); - PRINT_ERR("LR = 0x%8x\t%16u\n", pstExc->pstContext->uwLR,pstExc->pstContext->uwLR); - PRINT_ERR("PC = 0x%8x\t%16u\n", pstExc->pstContext->uwPC,pstExc->pstContext->uwPC); - PRINT_ERR("xPSR = 0x%8x\t%16u\n", pstExc->pstContext->uwxPSR,pstExc->pstContext->uwxPSR); - PRINT_ERR("\nplease use the addr2line tool to analyze the call stack on PC:\n"); - PRINT_ERR("addr2line -e (xxx.axf/xxx.elf/xxx.out) -a -f "); - - for (UINT32 i = 0; i < pstExc->uwCallStackDepth; i++) - { - printf("%8x", pstExc->uwCallStack[i]); - } - printf("\n"); - return; -} - -/***************************************************************************** - Function : osExcCallStackAnalysis - Description : Call stack analysis - Input : pstExc --- point to exception info - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcCallStackAnalysis(EXC_INFO_S *pstExc) -{ - UINT32 uwSP; - UINT32 uwLR; - UINT32 uwPC; - UINT32 uwStackStartAddr; - UINT32 uwStackSize; - UINT32 uwDepth = 0; - BOOL bFirstLrValid = FALSE; - - uwSP = pstExc->pstContext->uwSP; /* sp pointer before entering exception */ - - /* - * save first and second depth - * first: PC before entering exception - * second: (LR - 4) before entering exception - * NOTE: If an exception occurs in the interrupt, LR may be EXC_RETURN, so we must make sure - * that LR is valid, exclude EXC_RETURN. - */ - - pstExc->uwCallStack[uwDepth++] = pstExc->pstContext->uwPC; - - if ((pstExc->pstContext->uwLR >= LOSCFG_EXC_CODE_START_ADDR) && \ - (pstExc->pstContext->uwLR <= LOSCFG_EXC_CODE_START_ADDR + LOSCFG_EXC_CODE_SIZE)) - { - pstExc->uwCallStack[uwDepth++] = pstExc->pstContext->uwLR - sizeof(VOID *); /* lr = pc + 4 */ - bFirstLrValid = TRUE; - int tmp = uwDepth - 1; - } - - - /* - * get the start address and size of the stack before entering the exception - */ - if (pstExc->usPhase == OS_EXC_IN_TASK) /* task use PSP */ - { - uwStackStartAddr = g_stLosTask.pstRunTask->uwTopOfStack; - uwStackSize = g_stLosTask.pstRunTask->uwStackSize; - } - else /* init and interrupt use MSP */ - { - uwStackStartAddr = LOSCFG_EXC_MSP_START_ADDR; - uwStackSize = LOSCFG_EXC_MSP_SIZE; - } - - /* - * check stack overflow, if so, compensate for overflow, readjust stack start address and size. - */ - if (uwSP < uwStackStartAddr) /* stack top overflow */ - { - if (pstExc->usPhase == OS_EXC_IN_TASK) - { - PRINT_ERR("task %s stack top overflow\n", g_stLosTask.pstRunTask->pcTaskName); - } - else - { - PRINT_ERR("MSP top overflow\n"); - } - uwStackSize += (uwStackStartAddr - uwSP); /* compensate overflow size */ - uwStackStartAddr = uwSP; /* readjust stack start address */ - } - - /* - * Traverses the entire stack from the top of the stack to the bottom of the stack, - * find all LR. - */ - for (; uwSP < uwStackStartAddr + uwStackSize; uwSP += sizeof(UINT32*)) - { - uwLR = *(UINT32 *)uwSP; - - if (uwLR % 2 == 0) /* Thumb instruction, LR bit0 == 1 */ - { - continue; - } - - /* - * It may be LR, which must be further determined based on the start address - * and end address of the code segment. - */ - if ((uwLR >= LOSCFG_EXC_CODE_START_ADDR) && (uwLR <= LOSCFG_EXC_CODE_START_ADDR + LOSCFG_EXC_CODE_SIZE) \ - && (uwDepth < LOSCFG_EXC_CALL_STACK_ANALYSIS_MAX_DEPTH)) - { - uwPC = uwLR - sizeof(VOID *); /* lr = pc + 4 */ - /* the second depth(first LR) has been saved */ - if ((uwDepth == 2) && (uwPC == pstExc->uwCallStack[1]) && (bFirstLrValid == TRUE)) - { - continue; - } - pstExc->uwCallStack[uwDepth++] = uwPC; - } - } - pstExc->uwCallStackDepth = uwDepth; /* save call stack depth */ - - return; -} - -/***************************************************************************** - Function : osExcHandleEntry - Description : EXC handler entry - Input : uwExcType --- EXC type - : uwFaultAddr --- The address of an accurate address access error - : uwPid --- Interrupt number - : puwExcBufAddr --- Point to the stack frame without FPU - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcHandleEntry(UINT32 uwExcType, UINT32 uwUsingSp, UINT32 uwID, EXC_CONTEXT_S *pstExcBufAddr) -{ - g_uwCurNestCount++; -#if (LOSCFG_PLATFORM_HWI == YES) - extern UINT32 g_vuwIntCount; - g_vuwIntCount++; -#endif - int tmp_type = uwExcType & 0x0000ff00; - tmp_type = tmp_type >> 8; - /* Save interrupt nesting times */ - m_stExcInfo.usNestCnt = (UINT16)g_uwCurNestCount; - /* uwExcType 8-15 bits: exc type */ - m_stExcInfo.usType = (UINT16)tmp_type; -#if (LOSCFG_SAVE_EXC_INFO == YES) - /* Initializing a pointer to save an exception context */ - m_puwExcContent = (UINT32 *)m_aucTaskArray; -#endif - - /* Save the fault address when an exception occurs if it is valid */ - /* Save the phase of the exception */ - extern BOOL g_bTaskScheduled; - int tmp_phase = uwExcType; - tmp_phase = uwExcType & 0x000000ff; - m_stExcInfo.usPhase = (UINT16)tmp_phase; - m_stExcInfo.uwThrdPid = uwID; /* interrupt number */ - m_stExcInfo.usFpuContext = 0; - m_stExcInfo.pstContext = pstExcBufAddr; /* point to r3 */ - - osExcCallStackAnalysis(&m_stExcInfo); - osExcInfoDisplay(&m_stExcInfo); - LOS_Reboot(); -} - -#if (LOSCFG_SAVE_EXC_INFO == YES) -/***************************************************************************** - Function : osExcSaveIntStatus - Description : Save NVIC register group - Input : None - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSaveIntStatus(VOID) -{ - /* Save exc type */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_NVIC; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save total size of NVIC */ - *((UINT32 *)m_puwExcContent) = 0x164; // = OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + OS_NVIC_INT_ACT_SIZE + OS_NVIC_INT_PRI_SIZE + 12 + 4 + 4 - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save interrupt enable register group (start addr: 0xE000E100, size: 32bytes, CMSIS-Core: NVIC->ISER[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SETENA_BASE, OS_NVIC_INT_ENABLE_SIZE); - m_puwExcContent =(UINT8 *)m_puwExcContent + OS_NVIC_INT_ENABLE_SIZE; - - /* Save interrupt pend register group (start addr: 0xE000E200, size: 32bytes, CMSIS-Core: NVIC->ISPR[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SETPEND_BASE, OS_NVIC_INT_PEND_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_PEND_SIZE; - - /* Save interrupt active status register group (start addr: 0xE000E300, size: 32bytes, CMSIS-Core: NVIC->IABR[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_INT_ACT_BASE, OS_NVIC_INT_ACT_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_ACT_SIZE; - - /* Save interrupt priority register group (start addr: 0xE000E400, size: 240bytes), CMSIS-Core: NVIC->IP[0 - 239] */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_PRI_BASE, OS_NVIC_INT_PRI_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_PRI_SIZE; - - /* Save system exception priority register group (start addr: 0xE000ED18, size: 12bytes, CMSIS-Core: SCB->SHP[0 - 11]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_EXCPRI_BASE, 12); - m_puwExcContent = (UINT8 *)m_puwExcContent + 12; - - /* Save system processing control and state register group (start addr: 0xE000ED24, size: 4bytes, CMSIS-Core: SCB->SHCSR) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SHCSR, 4); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save interrupt control and status register group (start addr: 0xE000ED04, size: 4bytes, CMSIS-Core: SCB->ICSR) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_INT_CTRL, 4); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - return; -} - -/***************************************************************************** - Function : osExcRegister - Description : Register exception - Input : uwType --- exception type - : pFunc --- exception callback function - : pArg --- exception save info arg, not pFunc - Output : None - Return : None - *****************************************************************************/ -VOID osExcRegister(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg) -{ - EXC_INFO_ARRAY_S *pstExcInfo; - - if (uwType == 0 || uwType >= OS_EXC_TYPE_MAX || pFunc == NULL) - { - PRINT_ERR("osExcRegister ERROR!\n"); - return; - } - - pstExcInfo = &(m_stExcArray[uwType - 1]); - pstExcInfo->uwType = uwType; - pstExcInfo->pFnExcInfoCb = pFunc; - pstExcInfo->pArg = pArg; - pstExcInfo->uwValid = TRUE; -} - -/***************************************************************************** - Function : osExcSaveSysInfo - Description : Saving exception information by calling callback function recursively - Input : uwType --- exception type(OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1) - : pFunc --- callback function - : uwLoop --- loop total count - : uwLen --- The size of the data saved each time - : uwIdx --- loop index - Output : None - Return : None - *****************************************************************************/ -VOID osExcSaveSysInfo(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, UINT32 uwLoop, UINT32 uwLen, UINT32 uwIdx) -{ - UINT32 uwRet; - UINT32 uwBuffer[OS_EXC_MAX_BUF_LEN]; - - /* Save exception type and size */ - *((UINT32 *)m_puwExcContent) = uwType; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - *((UINT32 *)m_puwExcContent) = uwLen * (uwLoop - uwIdx); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - for (; uwIdx < uwLoop; uwIdx++) - { - memset((VOID *)uwBuffer, 0, sizeof(UINT32) * OS_EXC_MAX_BUF_LEN); - uwRet = pFunc(uwIdx, (VOID *)uwBuffer); - if (LOS_OK == uwRet) - { - memcpy(m_puwExcContent, (VOID *)uwBuffer, uwLen); - } - m_puwExcContent =(UINT8 *)m_puwExcContent + uwLen; - } -} - -/***************************************************************************** - Function : osExcSaveInfo - Description : save exception info - Input : uwType --- exception type(OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1) - : pFunc --- exception callback - : pArg --- register arg, used to generate the arg passed to the callback - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSaveInfo(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg) -{ - UINT32 uwLen; - UINT32 uwIdx; - UINT32 uwLoop; - UINT32 uwTaskSwitchCount = 0; - OS_TASK_SWITCH_INFO *pstTaskSwitchInfo; - - switch(uwType) - { - case OS_EXC_TYPE_TSK: /* save task info */ - uwLen = sizeof(TSK_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - case OS_EXC_TYPE_QUE: /* save queue info */ - uwLen = sizeof(QUEUE_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - case OS_EXC_TYPE_NVIC: /* save NVIC info */ - (VOID)pFunc(0, 0); - goto END; - - case OS_EXC_TYPE_TSK_SWITCH: /* save task switch info */ - pstTaskSwitchInfo = pArg; - uwTaskSwitchCount = pstTaskSwitchInfo->ucIsFull & 0x7F; - uwLen = sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN; /* auwPID + acName */ - if (pstTaskSwitchInfo->ucIsFull & 0x80) - { - uwIdx = pstTaskSwitchInfo->ucIdx; - uwLoop = uwIdx + uwTaskSwitchCount; - } - else - { - uwIdx = 0; - uwLoop = pstTaskSwitchInfo->ucIdx; - } - break; - - case OS_EXC_TYPE_MEM: /* save mem info */ - uwLen = sizeof(MEM_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - default: - goto END; - } - osExcSaveSysInfo(uwType, (EXC_INFO_SAVE_CALLBACK)pFunc, uwLoop, uwLen, uwIdx); -END: - return; -} - -/***************************************************************************** - Function : osExcSave2DDR - Description : Save exception info to RAM - Input : None - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSave2DDR(VOID) -{ - UINT32 uwIdx = 0; - UINT32 uwExcContextSize; - - if (m_stExcInfo.usFpuContext == 1) - { - uwExcContextSize = sizeof(EXC_CONTEXT_S); - } - else - { - uwExcContextSize = sizeof(EXC_CONTEXT_S) - 136; /* except FPU register */ - } - - memset(m_puwExcContent, 0xff, g_uwArraySize); - - /* Cortex-M type */ - *((UINT32 *)m_puwExcContent) = 4; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* - * Save exception type: OS_EXC_TYPE_CONTEXT - */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_CONTEXT; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* The size of struct EXC_INFO_S(except member EXC_CONTEXT_S*) and exception context size */ - *((UINT32 *)m_puwExcContent) = sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *) + uwExcContextSize; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save struct m_stExcInfo except m_stExcInfo.pstContext */ - memcpy((VOID *)m_puwExcContent, (VOID *)&m_stExcInfo, sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *)); - m_puwExcContent = (UINT8 *)m_puwExcContent + sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *); - - /* Save struct EXC_CONTEXT_S */ - if (m_stExcInfo.usFpuContext == 0) - { - #if FPU_EXIST - /* m_stExcInfo.pstContext: init --- point to S16, S16->S31 invalid - * + 64 --- point to uwR4 - * copy uwR4 -> uwxPSR */ - memcpy((VOID *)m_puwExcContent, (UINT8 *)m_stExcInfo.pstContext + 64, uwExcContextSize); - #else - memcpy((VOID *)m_puwExcContent, m_stExcInfo.pstContext, uwExcContextSize); - #endif - } - else - { - memcpy((VOID *)m_puwExcContent, m_stExcInfo.pstContext, uwExcContextSize); - } - m_puwExcContent = (UINT8 *)m_puwExcContent + uwExcContextSize; - - /* - * Save exception type: OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1 - */ - for (uwIdx = 0; uwIdx < OS_EXC_TYPE_MAX - 1; uwIdx++) - { - if (m_stExcArray[uwIdx].uwValid == FALSE) - { - continue; - } - osExcSaveInfo(m_stExcArray[uwIdx].uwType, m_stExcArray[uwIdx].pFnExcInfoCb, m_stExcArray[uwIdx].pArg); - } - - /* - * Save exception type: OS_EXC_TYPE_MAX - */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_MAX; - m_puwExcContent = (UINT8*)m_puwExcContent + 4; - - return; -} -#endif /*(LOSCFG_SAVE_EXC_INFO == YES)*/ - -/***************************************************************************** - Function : osExcInit - Description : Initializes the EXC - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID osExcInit(UINT32 uwArraySize) -{ -#if (LOSCFG_PLATFORM_HWI == YES) - /* Register exception handler to interrupt vector table in RAM */ - m_pstHwiForm[-14 + OS_SYS_VECTOR_CNT] = NMI_Handler; - m_pstHwiForm[-13 + OS_SYS_VECTOR_CNT] = HardFault_Handler; - m_pstHwiForm[-12 + OS_SYS_VECTOR_CNT] = MemManage_Handler; - m_pstHwiForm[-11 + OS_SYS_VECTOR_CNT] = BusFault_Handler; - m_pstHwiForm[-10 + OS_SYS_VECTOR_CNT] = UsageFault_Handler; - m_pstHwiForm[-5 + OS_SYS_VECTOR_CNT] = SVC_Handler; -#endif - - /* Enable USGFAULT(BIT_18), BUSFAULT(BIT_17), MEMFAULT(BIT_16) */ - *(volatile UINT32 *)OS_NVIC_SHCSR |= 0x70000; - - /* Enable DIV 0(BIT_4) exception, unaligned(BIT_3) disable */ - *(volatile UINT32 *)OS_NVIC_CCR |= 0x10; - -#if (LOSCFG_SAVE_EXC_INFO == YES) - g_uwArraySize = uwArraySize; - osExcRegister((EXC_INFO_TYPE)OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)osExcSaveIntStatus, NULL); -#endif -} - -VOID osBackTrace(VOID) -{ - return; -} - -#endif /*(LOSCFG_PLATFORM_EXC == YES)*/ - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - diff --git a/arch/arm/arm-m/cortex-m4/Makefile b/arch/arm/arm-m/cortex-m4/Makefile deleted file mode 100644 index c3e5342f2..000000000 --- a/arch/arm/arm-m/cortex-m4/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -objs-y += los_exc.o - diff --git a/arch/arm/arm-m/cortex-m4/gcc/los_dispatch_gcc.S b/arch/arm/arm-m/cortex-m4/gcc/los_dispatch_gcc.S deleted file mode 100644 index 71d893802..000000000 --- a/arch/arm/arm-m/cortex-m4/gcc/los_dispatch_gcc.S +++ /dev/null @@ -1,370 +0,0 @@ -/** ---------------------------------------------------------------------------- - * Copyright (c) <2016-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/** ---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**************************************************************************************** -* EXPORT FUNCTIONS -****************************************************************************************/ - - .global LOS_IntLock - .global LOS_IntUnLock - .global LOS_IntRestore - .global LOS_StartToRun - .global osTaskSchedule - .global PendSV_Handler - -/**************************************************************************************** -* EXTERN PARAMETERS -****************************************************************************************/ - - .extern g_stLosTask - .extern g_pfnTskSwitchHook - .extern g_bTaskScheduled - -/**************************************************************************************** -* EQU -****************************************************************************************/ - -.equ OS_NVIC_INT_CTRL, 0xE000ED04 /* Interrupt Control and State Register. */ -.equ OS_NVIC_PENDSVSET, 0x10000000 /* Value to trigger PendSV exception. */ - -.equ OS_NVIC_SYSPRI2, 0xE000ED20 /* System Handler Priority Register 2. */ -.equ OS_NVIC_PENDSV_SYSTICK_PRI, 0xFFFF0000 /* SysTick + PendSV priority level (lowest). */ - -.equ OS_TASK_STATUS_RUNNING, 0x0010 /* Task Status Flag (RUNNING). */ - -/**************************************************************************************** -* CODE GENERATION DIRECTIVES -****************************************************************************************/ - - .section .text - .thumb - .syntax unified - .arch armv7e-m - -/**************************************************************************************** -* Function: -* VOID LOS_StartToRun(VOID); -* Description: -* Start the first task, which is the highest priority task in the priority queue. -* Other tasks are started by task scheduling. -****************************************************************************************/ - .type LOS_StartToRun, %function -LOS_StartToRun: - CPSID I - - /** - * Set PendSV and SysTick prority to the lowest. - * read ---> modify ---> write-back. - */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORR R1, R1, R2 - STR R1, [R0] - - /** - * Set g_bTaskScheduled = 1. - */ - LDR R0, =g_bTaskScheduled - MOV R1, #1 - STR R1, [R0] - - /** - * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - /** - * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOV R3, #OS_TASK_STATUS_RUNNING - ORR R2, R2, R3 - STRH R2, [R1, #4] - - /** - * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - * [Initial EXC_RETURN ignore,] return by setting the CONTROL register. - * - * The initial stack of the current running task is as follows: - * - * POP: Restore the context of the current running task ===>| - * High addr--->| - * Bottom of the stack--->| - * ----------+---------------------------------+--------------------------------+ - * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - * ----------+---------------------------------+--------------------------------+ - * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - * |<--- skip --->|<--- copy to R0-R7 --->| - * R12 to PSP--->| - * Stack pointer after LOS_StartToRun--->| - */ - LDR R12, [R1] - ADD R12, R12, #36 /* skip R4-R11, PRIMASK. */ -#if defined (__VFP_FP__) && !defined(__SOFTFP__) - ADD R12, R12, #4 /* if FPU exist, skip EXC_RETURN. */ -#endif - LDMFD R12!, {R0-R7} - - /** - * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - */ - MSR PSP, R12 - - /** - * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - */ - MOV R12, #2 - MSR CONTROL, R12 - - /** - * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - */ - MOV LR, R5 - CPSIE I - - /** - * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - * of the main function will be destroyed and will never be returned. - */ - BX R6 - -/**************************************************************************************** -* Function: -* UINTPTR LOS_IntLock(VOID); -* Description: -* Disable all interrupts except Reset,NMI and HardFault. -* The value of currnet interruption state will be returned to the caller to save. -* -* Function: -* VOID LOS_IntRestore(UINTPTR uvIntSave); -* Description: -* Restore the locked interruption of LOS_IntLock. -* The caller must pass in the value of interruption state previously saved. -****************************************************************************************/ - .type LOS_IntLock, %function -LOS_IntLock: - MRS R0, PRIMASK - CPSID I - BX LR - - .type LOS_IntUnLock, %function -LOS_IntUnLock: - MRS R0, PRIMASK - CPSIE I - BX LR - - .type LOS_IntRestore, %function -LOS_IntRestore: - MSR PRIMASK, R0 - BX LR - -/**************************************************************************************** -* Function: -* VOID osTaskSchedule(VOID); -* Description: -* Start the task swtich process by software trigger PendSV interrupt. -****************************************************************************************/ - .type osTaskSchedule, %function -osTaskSchedule: - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -/**************************************************************************************** -* Function: -* VOID PendSV_Handler(VOID); -* Description: -* PendSV interrupt handler, switch the context of the task. -* First: Save the context of the current running task(g_stLosTask.pstRunTask) -* to its own stack. -* Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -* from its own stack. -****************************************************************************************/ - .type PendSV_Handler, %function -PendSV_Handler: - /** - * R12: Save the interruption state of the current running task. - * Disable all interrupts except Reset,NMI and HardFault - */ - MRS R12, PRIMASK - CPSID I - - /** - * Call task switch hook. - */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CBZ R2, TaskSwitch - PUSH {R12, LR} - BLX R2 - POP {R12, LR} - -TaskSwitch: - /** - * R0 = now stack pointer of the current running task. - */ - MRS R0, PSP - - /** - * Save the stack frame([S16-S31],R4-R11) of the current running task. - * R12 save the PRIMASK value of the current running task. - * NOTE: 1. Before entering the exception handler function, these registers - * ([NO_NAME,FPSCR,S15-S0],xPSR,PC,LR,R12,R3-R0) have been automatically - * saved by the CPU in the stack of the current running task. - * 2. If lazy stacking is enabled, space is reserved on the stack for - * the floating-point context(FPSCR,S15-S0), but the floating-point state - * is not saved. when the floating-point instruction(VSTMDBEQ R0!, {D8-D15}) - * is executed, the floating-point context(FPSCR,S15-S0) is first saved into - * the space reserved on the stack. In other words, the instruction - * 'VSTMDBEQ R0!, {D8-D15}' will trigger the CPU to save 'FPSCR,S15-S0' first. - * - * The stack of the current running task is as follows: - * - * |<=== PUSH: Save the context of the current running task - * | High addr--->| - * --+-----------------------------------+-------------------------------------------+--- - * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * | [ lazy stacking ]| - * --+-----------------------------------+-------------------------------------------+--- - * Stack pointer before entering exception--->| - * |<--- cpu auto saved --->| - * |<---PSP to R0 - * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - */ -#if defined (__VFP_FP__) && !defined(__SOFTFP__) /* if FPU exist. */ - TST R14, #0x10 /* if the task using the FPU context, push s16-s31. */ - IT EQ - VSTMDBEQ R0!, {D8-D15} - STMFD R0!, {R14} /* save EXC_RETURN. */ -#endif - STMFD R0!, {R4-R12} /* save the core registers and PRIMASK. */ - - /** - * R5,R8. - */ - LDR R5, =g_stLosTask - MOV R8, #OS_TASK_STATUS_RUNNING - - /** - * Save the stack pointer of the current running task to TCB. - * (g_stLosTask.pstRunTask->pStackPointer = R0) - */ - LDR R6, [R5] - STR R0, [R6] - - /** - * Clear the RUNNING state of the current running task. - * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - */ - LDRH R7, [R6, #4] - BIC R7, R7, R8 - STRH R7, [R6, #4] - - /** - * Switch the current running task to the next running task. - * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - */ - LDR R0, [R5, #4] - STR R0, [R5] - - /** - * Set the RUNNING state of the next running task. - * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - */ - LDRH R7, [R0, #4] - ORR R7, R7, R8 - STRH R7, [R0, #4] - - /** - * Restore the stack pointer of the next running task from TCB. - * (R1 = g_stLosTask.pstNewTask->pStackPointer) - */ - LDR R1, [R0] - - /** - * Restore the stack frame(R4-R11,[S16-S31]) of the next running task. - * R12 restore the PRIMASK value of the next running task. - * NOTE: After exiting the exception handler function, these registers - * (PC,xPSR,R0-R3,R12,LR,[S0-S15,FPSCR,NO_NAME]) will be automatically - * restored by the CPU from the stack of the next running task. - * - * 1. The stack of the next running task is as follows: - * - * POP: Restore the context of the next running task ===>| - * High addr--->| - * --+-----------------------------------+-------------------------------------------+--- - * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * --+-----------------------------------+-------------------------------------------+--- - * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - * R1 to PSP--->| - * |<--- cpu auto restoring --->| - * Stack pointer after exiting exception--->| - * - * 2. If the next running task is run for the first time, the stack is as follows: - * - * POP: Restore the context of the next running task ===>| - * High addr--->| - * Bottom of the stack--->| - * ----------+---------------------------------+--------------------------------+ - * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - * ----------+---------------------------------+--------------------------------+ - * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - * R1 to PSP--->| - * |<--- cpu auto restoring --->| - * Stack pointer after exiting exception--->| - */ - LDMFD R1!, {R4-R12} /* restore the core registers and PRIMASK. */ -#if defined (__VFP_FP__) && !defined(__SOFTFP__) /* if FPU exist. */ - LDMFD R1!, {R14} /* restore EXC_RETURN. */ - TST R14, #0x10 /* if the task using the FPU context, pop s16-s31. */ - IT EQ - VLDMIAEQ R1!, {D8-D15} -#endif - - /** - * Set the stack pointer of the next running task to PSP. - */ - MSR PSP, R1 - - /** - * Restore the interruption state of the next running task. - */ - MSR PRIMASK, R12 - BX LR - diff --git a/arch/arm/arm-m/cortex-m4/gcc/los_hw_exc_gcc.S b/arch/arm/arm-m/cortex-m4/gcc/los_hw_exc_gcc.S deleted file mode 100644 index 2fccb579a..000000000 --- a/arch/arm/arm-m/cortex-m4/gcc/los_hw_exc_gcc.S +++ /dev/null @@ -1,553 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ - /*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**************************************************************************************** -* CODE GENERATION DIRECTIVES -****************************************************************************************/ - - .syntax unified - .arch armv7e-m - .thumb - .section .text - -/**************************************************************************************** -* EXPORT FUNCTIONS -****************************************************************************************/ - - .global NMI_Handler - .global HardFault_Handler - .global MemManage_Handler - .global BusFault_Handler - .global UsageFault_Handler - .global SVC_Handler - -/**************************************************************************************** -* EXTERN PARAMETERS -****************************************************************************************/ - - .extern osExcHandleEntry - .extern g_uwExcTbl - .extern g_bTaskScheduled - -/**************************************************************************************** -* EQU -****************************************************************************************/ - -.equ OS_EXC_CAUSE_NMI, 18 -.equ OS_EXC_CAUSE_HARDFAULT, 19 -.equ OS_EXC_CAUSE_MEMFAULT, 20 -.equ OS_EXC_CAUSE_BUSFAULT, 21 -.equ OS_EXC_CAUSE_USAGEFAULT, 22 -.equ OS_EXC_CAUSE_SVC, 23 - -.equ HF_DEBUGEVT, 24 -.equ HF_VECTBL, 25 - -.equ FLAG_ADDR_VALID, 0x10000 /* bit 16 */ -.equ FLAG_HWI_ACTIVE, 0x20000 /* bit 17 */ -.equ FLAG_NO_FLOAT, 0x10000000 /* bit 28 */ - -.equ OS_NVIC_CFSR, 0xE000ED28 /* include BusFault/MemFault/UsageFault State Regeister */ -.equ OS_NVIC_HFSR, 0xE000ED2C /* HardFault State Regeister */ -.equ OS_NVIC_BFAR, 0xE000ED38 -.equ OS_NVIC_MMFAR, 0xE000ED34 -.equ OS_NVIC_ACT_BASE, 0xE000E300 -.equ OS_NVIC_SHCSRS, 0xE000ED24 -.equ OS_NVIC_SHCSR_MASK, 0xC00 /* SYSTICKACT and PENDSVACT */ - -/**************************************************************************************** -* Function: -* VOID NMI_Handler(VOID); -* Description: -* NMI Handler. -****************************************************************************************/ - .type NMI_Handler, %function -NMI_Handler: - /** - * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +------------------------------------------------------+------------------------+ - * | 31-8 | 7-0 | - * +------------------------------------------------------+------------------------+ - * | --- | OS_EXC_CAUSE_NMI | - * +------------------------------------------------------+------------------------+ - * < R1 >: invalid - */ - MOV R0, #OS_EXC_CAUSE_NMI - MOV R1, #0 - B osExcDispatch - -/**************************************************************************************** -* Function: -* VOID HardFault_Handler(VOID); -* Description: -* HardFault Handler. -****************************************************************************************/ - .type HardFault_Handler, %function -HardFault_Handler: - /** - * Check HardFault state register. - * - * HFSR: - * +----------+--------+--------+--------+-------+ - * | 31 | 30 | 29 - 2 | 1 | 0 | - * +----------+--------+--------+--------+-------+ - * | DEBUGEVT | FORCED | -- | VECTBL | -- | - * +----------+--------+--------+--------+-------+ - */ - MOV R0, #OS_EXC_CAUSE_HARDFAULT - LDR R2, =OS_NVIC_HFSR - LDR R2, [R2] - - /** - * Check whether HardFault are triggered by debugging events. - * Before executing instruction 'BNE osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +----------------------------------------+-------------+------------------------+ - * | 31-16 | 15-8 | 7-0 | - * +----------------------------------------+-------------+------------------------+ - * | --- | HF_DEBUGEVT | OS_EXC_CAUSE_HARDFAULT | - * +----------------------------------------+-------------+------------------------+ - * < R1 >: invalid - */ - MOV R1, #HF_DEBUGEVT - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x80000000 - BNE osExcDispatch /* DEBUGEVT */ - - /** - * Check whether HardFault is caused by the failure of the fetch vector. - * Before executing instruction 'BNE osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +----------------------------------------+-------------+------------------------+ - * | 31-16 | 15-8 | 7-0 | - * +----------------------------------------+-------------+------------------------+ - * | --- | HF_VECTBL | OS_EXC_CAUSE_HARDFAULT | - * +----------------------------------------+-------------+------------------------+ - * < R1 >: invalid - */ - AND R0, R0, #0x000000FF - MOV R1, #HF_VECTBL - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x00000002 - BNE osExcDispatch /* VECTBL */ - - /** - * If it`s not DEBUGEVT and VECTBL, that is FORCED, then read the CFSR register to - * check BusFault, MemFault and UsageFault. - * R0: OS_EXC_CAUSE_HARDFAULT - * - * CFSR: - * +----------------+--------+--------+ - * | 31-16 | 15-8 | 7-0 | - * +----------------+--------+--------+ - * | UFSR | BFSR | MFSR | - * +----------------+--------+--------+ - */ - AND R0, R0, #0x000000FF - - LDR R2, =OS_NVIC_CFSR - LDR R2, [R2] - - TST R2, #0x8000 /* BFSR->BFARVALID */ - BNE _HFBusFault /* BusFault */ - - TST R2, #0x80 /* MFSR->MMARVALID */ - BNE _HFMemFault /* MemFault */ - - /** - * BFARVALID and MMARVALID flag both invalid. - * R12: 0 --- The error address is invalid. - */ - MOV R12, #0 - B osHFExcCommonBMU - - /** - * BFARVALID flag valid, read BFAR register. - * R1 : BFAR value --- The address value of a bus error. - * R12: The error address is valid. - */ -_HFBusFault: - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - B osHFExcCommonBMU - - /** - * MMARVALID flag valid, read MMFAR register. - * R1 : MMFAR value --- The address value of memory management error. - * R12: The error address is valid. - */ -_HFMemFault: - LDR R1, =OS_NVIC_MMFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - - /** - * osHFExcCommonBMU: --- Get specific error status from table g_uwExcTbl, stored in R0. - * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +-------------------+-----------------+------------------+------------------------+ - * | 31-17 | 16 | 15-8 | 7-0 | - * +-------------------+-----------------+------------------+------------------------+ - * | --- | FLAG_ADDR_VALID | Error state code | OS_EXC_CAUSE_HARDFAULT | - * | | or | in | | - * | | 0(invalid) | table g_uwExcTbl | | - * +-------------------+-----------------+------------------+------------------------+ - * < R1 >: The value of BFAR or MMFAR if the bit16(FLAG_ADDR_VALID) of R0 is set to 1, - * else invalid. - */ -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 - -/**************************************************************************************** -* Function: -* VOID SVC_Handler(VOID); -* Description: -* SVC Handler. -****************************************************************************************/ - .type SVC_Handler, %function -SVC_Handler: - TST LR, #0x4 /* EXC_RETURN[b2] --- PSP or MSP */ - ITE EQ - MRSEQ R0, MSP - MRSNE R0, PSP - LDR R1, [R0, #24] /* The PC value in the stack frame */ - LDRB R0, [R1, #-2] /* R0: The number of SVC (0 - 255) */ - MOV R1, #0 - /* B osExcDispatch */ -_SvcLoop: - B _SvcLoop - -/**************************************************************************************** -* Function: -* VOID BusFault_Handler(VOID); -* Description: -* BusFault Handler. -****************************************************************************************/ - .type BusFault_Handler, %function -BusFault_Handler: - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_BUSFAULT - - TST R0, #0x8000 /* BFSR->BFARVALID */ - BEQ _ExcBusNoADDR - - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] /* R1: The value of BFAR */ - MOV R12, #FLAG_ADDR_VALID /* R12: BusFault addr valid */ - AND R0, R0, #0x3F00 /* R0: Reserved the b13-b8 of the BFSR */ - B osExcCommonBMU - -_ExcBusNoADDR: - MOV R12, #0 /* R12: BusFault addr invalid */ - AND R0, R0, #0x3F00 /* R0: Reserved the b13-b8 of the BFSR */ - B osExcCommonBMU - -/**************************************************************************************** -* Function: -* VOID MemManage_Handler(VOID); -* Description: -* MemManage Handler. -****************************************************************************************/ - .type MemManage_Handler, %function -MemManage_Handler: - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_MEMFAULT - - TST R0, #0x80 /* MFSR->MMARVALID */ - BEQ _ExcMemNoADDR - - LDR R1, =OS_NVIC_MMFAR - LDR R1, [R1] /* R1: The value of MMFAR */ - MOV R12, #FLAG_ADDR_VALID /* R12: MemFault addr valid */ - AND R0, R0, #0x3B /* R0: Reserved the b5-b0 of the MFSR */ - B osExcCommonBMU - -_ExcMemNoADDR: - MOV R12, #0 /* R12: MemFault addr invalid */ - AND R0, R0, #0x3B /* R0: Reserved the b5-b0 of the MFSR */ - B osExcCommonBMU - -/**************************************************************************************** -* Function: -* VOID UsageFault_Handler(VOID); -* Description: -* UsageFault Handler. -****************************************************************************************/ - .type UsageFault_Handler, %function -UsageFault_Handler: - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_USAGEFAULT - - LDR R1, =#0x030F - LSL R1, R1, #16 - AND R0, R0, R1 /* R0: reserved UFSR */ - MOV R12, #0 /* R12: Fault addr invalid */ - - /** - * osExcCommonBMU: BusFault_Handler,MemManage_Handler and UsageFault_Handler share. - * Get specific error status from table g_uwExcTbl, stored in R0. - * Before executing osExcDispatch, the value of R0 is as follows. - * < R0 >: - * +-------------------+-----------------+------------------+------------------------+ - * | 31-17 | 16 | 15-8 | 7-0 | - * +-------------------+-----------------+------------------+------------------------+ - * | --- | FLAG_ADDR_VALID | Error state code |OS_EXC_CAUSE_BUSFAULT or| - * | | or | in |OS_EXC_CAUSE_MEMFAULT or| - * | | 0(invalid) | table g_uwExcTbl |OS_EXC_CAUSE_USAGEFAULT | - * +-------------------+-----------------+------------------+------------------------+ - * < R1 >: The value of BFAR or MMFAR if the bit16(FLAG_ADDR_VALID) of R0 is set to 1, - * else invalid. - */ -osExcCommonBMU: - CLZ R0, R0 - LDR R3, =g_uwExcTbl - ADD R3, R3, R0 - LDRB R0, [R3] - LSL R0, R0, #0x8 - ORR R0, R0, R2 - ORR R0, R0, R12 - - /**************************************************************************************** - * osExcDispatch: NMI_Handler, HardFault_Handler, SVC_Handler, BusFault_Handler, MemManage_Handler, - * UsageFault_Handler sharing. - ****************************************************************************************/ - - /** - * When executing osExcDispatch, R0, R1 will be used. - * The possible values of R0 and R1 are as follows. - * - * < R0 >: - * +----------------+-----------------+---------------------+------------------------+ - * | 31-17 | 16 | 15-8 | 7-0 | - * +----------------+-----------------+---------------------+------------------------+ - * | | FLAG_ADDR_VALID | Error state code in | OS_EXC_CAUSE_HARDFAULT | - * | --- | or | table g_uwExcTbl |or OS_EXC_CAUSE_MEMFAULT| - * | | 0(invalid) | or HF_DEBUGEVT |or OS_EXC_CAUSE_BUSFAULT| - * | | | or HF_VECTBL |or OS_EXC_CAUSE_NMI or | - * | | | | OS_EXC_CAUSE_USAGEFAULT| - * +----------------+-----------------+---------------------+------------------------+ - * b17: FLAG_HWI_ACTIVE - * b28: FLAG_NO_FLOAT - * NOTE: b17 and b28 will be set later. - * - * < R1 >: - * If the bit16 of R0 is 1, then R1 is the value of BFAR or MMFAR, otherwise the - * value in R1 is invalid. - * - */ -osExcDispatch: - LDR R2, =OS_NVIC_ACT_BASE - MOV R12, #8 /* #8: externel interrupt active check loop counter(#0 - #239) */ - -_hwiActiveCheck: - LDR R3, [R2] /* R3 store the value of externel interrupt active status */ - CMP R3, #0 - BEQ _hwiActiveCheckNext - - /** - * Exception occured in external interrupt. - */ - ORR R0, R0, #FLAG_HWI_ACTIVE /* R0[b17] = 1, externel interrupt active valid &&&&&&&&&& */ - RBIT R2, R3 /* bit reversal */ - CLZ R2, R2 - RSB R12, R12, #8 /* R12 = 8 - R12 */ - ADD R2, R2, R12, LSL #5 /* R2: external interrupt number as uwPid */ - - /** - * Interrupts and initialization phase always use MSP. - */ -_ExcInMSP: - TST LR, #0x10 /* EXC_RETURN[b4] --- FPU(0) or without FPU(1) */ - BNE _NoFloatInMsp - - /** - * Before executing instruction 'B _handleEntry', MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | S16-S31,R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * +--------------------------------------------------------------------------------+--------- - * |<---R13 Initial R13--->|<--- #104 --->|<---SAVED_SP - * | (CPU auto saved) | - * - */ - ADD R3, R13, #104 /* #104: skip [R0-xPSR,D0-D7,FPSCR,NO_NAME] */ - PUSH {R3} /* push [SAVED_SP]: MSP+104 = Stack pointer in MSP before entering the exception */ - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK to MSP */ - VPUSH {D8-D15} /* push D8-D15 to MSP */ - B _handleEntry - - /** - * Before executing instruction 'B _handleEntry', MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR | - * +--------------------------------------------------------------------------------+--------- - * R13--->| Initial R13--->|<--- #32 --->|<---SAVED_SP - * | (CPU auto saved) | - * - */ -_NoFloatInMsp: - ADD R3, R13, #32 /* #32: skip [R0-R3,R12,LR,PC,xPSR] */ - PUSH {R3} /* push [SAVED_SP]: MSP+32 = Stack pointer in MSP before entering the exception */ - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK to MSP */ - ORR R0, R0, #FLAG_NO_FLOAT /* R0[b28] = 1, no FPU &&&&&&&&&& */ - B _handleEntry - -_hwiActiveCheckNext: - ADD R2, R2, #4 /* next NVIC ACT ADDR */ - SUBS R12, R12, #1 - BNE _hwiActiveCheck - - /** - * Not in externel interrupt, check whether it is SysTick or PendSV. - */ - LDR R2, =OS_NVIC_SHCSRS - LDRH R2,[R2] - LDR R3,=OS_NVIC_SHCSR_MASK - AND R2, R2, R3 - CMP R2, #0 - BNE _ExcInMSP /* SysTick or PendSV active */ - - /** - * Check whether an exception occurs during the initialization phase. - * If g_bTaskScheduled == 0, it is in the initialization phase. - */ - LDR R2, =g_bTaskScheduled - LDR R2, [R2] - TST R2, #1 - BEQ _ExcInMSP /* initialization phase use MSP */ - - /** - * Exception occured in Task. - */ - TST LR, #0x10 - BNE _NoFloatInPsp - - /** - * Before executing _handleEntry, MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | S16-S31,R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * +--------------------------------------------------------------------------------+--------- - * |<---R13 |<--- #104 --->|<---Initial R13 - * | (copied from PSP) | - * R2(no use)--->| - * - * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME. - */ - MOV R2, R13 - SUB R2, R2, #8 /* #8: reserved for [FPSCR,NO_NAME] */ - SUB R13, #104 /* #104: MSP reserved, used to store stack frame in PSP */ - - MRS R3, PSP - ADD R12, R3, #104 /* PSP+104 = Stack pointer of the task before entering the exception */ - PUSH {R12} /* push task SP to MSP */ - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK of the current running task to MSP */ - VPUSH {D8-D15} /* push D8-D15 of the currnent running task to MSP */ - - /* Copy stack frame from the stack of the current running task to MSP */ - LDMFD R3!, {R4-R11} /* restore stack frame[R0-xPSR] of PSP to R4-R11 */ - VLDMIA R3!, {D8-D15} /* restore stack frame[D0-D7] of PSP to D8-D15 */ - VSTMDB R2!, {D8-D15} /* save stack frame[D0-D7] to MSP */ - STMFD R2!, {R4-R11} /* save stack frame[R0-xPSR] to MSP */ - LDMFD R3, {R4-R5} /* restore stack frame[FPSCR,NO_NAME] to R4-R5 */ - ADD R2, R2, #104 /* skip stack frame */ - STMFD R2, {R4-R5} /* save stack frame[FPSCR,NO_NAME] to MSP */ - B _handleEntry - - /** - * Before executing _handleEntry, MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR | - * +--------------------------------------------------------------------------------+--------- - * R13--->| |<--- #32 --->|<---Initial R13 - * | (copied from PSP) | - * |<---R2(no use) - * - * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR. - */ -_NoFloatInPsp: - MOV R2, R13 - SUB R13, #32 /* #32: MSP reserved, used to store stack frame in PSP */ - - MRS R3, PSP - ADD R12, R3, #32 /* PSP+32 = Stack pointer of the task before entering the exception */ - PUSH {R12} /* push task SP to MSP */ - - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK of the current running task to MSP */ - - /* Copy stack frame from the stack of the current running task to MSP */ - LDMFD R3, {R4-R11} /* restore stack frame of PSP to R4-R11 */ - STMFD R2!, {R4-R11} /* save stack frame to MSP */ - ORR R0, R0, #FLAG_NO_FLOAT /* R0[b28] = 1, no FPU &&&&&&&&&& */ - - /** - * _handleEntry: Call osExcHandleEntry - * param1: R0 --- b28: FLAG_NO_FLOAT. - * b17: FLAG_HWI_ACTIVE. - * b16: FLAG_ADDR_VALID. - * b15-b8: Error state code in table g_uwExcTbl or HF_DEBUGEVT or HF_VECTBL. - * b7-b0: OS_EXC_CAUSE_HARDFAULT or OS_EXC_CAUSE_NMI or OS_EXC_CAUSE_MEMFAULT - * or OS_EXC_CAUSE_BUSFAULT or OS_EXC_CAUSE_USAGEFAULT. - * param2: R1 --- The value of BFAR or MMFAR if R0[b16] = 1, otherwise invalid. - * param3: R2 --- external interrupt number(0-239) if R0[b17] = 1, otherwise invalid. - * param4: R3 --- Point to the top of the stack(R4 or S16) that the exception stack frame in MSP. - */ -_handleEntry: - MOV R3, R13 - CPSID I - CPSID F - B osExcHandleEntry - - NOP diff --git a/arch/arm/arm-m/cortex-m4/iar/los_dispatch_iar.S b/arch/arm/arm-m/cortex-m4/iar/los_dispatch_iar.S deleted file mode 100644 index 402973aad..000000000 --- a/arch/arm/arm-m/cortex-m4/iar/los_dispatch_iar.S +++ /dev/null @@ -1,366 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2016-2018>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT LOS_IntLock - EXPORT LOS_IntUnLock - EXPORT LOS_IntRestore - EXPORT LOS_StartToRun - EXPORT osTaskSchedule - EXPORT PendSV_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT g_stLosTask - IMPORT g_pfnTskSwitchHook - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt Control and State Register. -OS_NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. - -OS_NVIC_SYSPRI2 EQU 0xE000ED20 ; System Handler Priority Register 2. -OS_NVIC_PENDSV_SYSTICK_PRI EQU 0xFFFF0000 ; SysTick + PendSV priority level (lowest). - -OS_TASK_STATUS_RUNNING EQU 0x0010 ; Task Status Flag (RUNNING). - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - SECTION .text:CODE(2) - THUMB - REQUIRE8 - PRESERVE8 - -;**************************************************************************************** -; Function: -; VOID LOS_StartToRun(VOID); -; Description: -; Start the first task, which is the highest priority task in the priority queue. -; Other tasks are started by task scheduling. -;**************************************************************************************** -LOS_StartToRun - CPSID I - - ;/** - ; * Set PendSV and SysTick prority to the lowest. - ; * read ---> modify ---> write-back. - ; */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORR R1, R1, R2 - STR R1, [R0] - - ;/** - ; * Set g_bTaskScheduled = 1. - ; */ - LDR R0, =g_bTaskScheduled - MOV R1, #1 - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - ; */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - ; */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOV R3, #OS_TASK_STATUS_RUNNING - ORR R2, R2, R3 - STRH R2, [R1, #4] - - ;/** - ; * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - ; * [Initial EXC_RETURN ignore,] return by setting the CONTROL register. - ; * - ; * The initial stack of the current running task is as follows: - ; * - ; * POP: Restore the context of the current running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - ; * |<--- skip --->|<--- copy to R0-R7 --->| - ; * R12 to PSP--->| - ; * Stack pointer after LOS_StartToRun--->| - ; */ - LDR R12, [R1] - ADD R12, R12, #36 ; skip R4-R11, PRIMASK. -#if defined (__ARMVFP__) - ADD R12, R12, #4 ; if FPU exist, skip EXC_RETURN. -#endif - LDMFD R12!, {R0-R7} - - ;/** - ; * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - ; */ - MSR PSP, R12 - - ;/** - ; * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - ; */ - MOV R12, #2 - MSR CONTROL, R12 - - ;/** - ; * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - ; */ - MOV LR, R5 - CPSIE I - - ;/** - ; * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - ; * of the main function will be destroyed and will never be returned. - ; */ - BX R6 - -;**************************************************************************************** -; Function: -; UINTPTR LOS_IntLock(VOID); -; Description: -; Disable all interrupts except Reset,NMI and HardFault. -; The value of currnet interruption state will be returned to the caller to save. -; -; Function: -; VOID LOS_IntRestore(UINTPTR uvIntSave); -; Description: -; Restore the locked interruption of LOS_IntLock. -; The caller must pass in the value of interruption state previously saved. -;**************************************************************************************** -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 - -;**************************************************************************************** -; Function: -; VOID osTaskSchedule(VOID); -; Description: -; Start the task swtich process by software trigger PendSV interrupt. -;**************************************************************************************** -osTaskSchedule - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -;**************************************************************************************** -; Function: -; VOID PendSV_Handler(VOID); -; Description: -; PendSV interrupt handler, switch the context of the task. -; First: Save the context of the current running task(g_stLosTask.pstRunTask) -; to its own stack. -; Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -; from its own stack. -;**************************************************************************************** -PendSV_Handler - ;/** - ; * R12: Save the interruption state of the current running task. - ; * Disable all interrupts except Reset,NMI and HardFault - ; */ - MRS R12, PRIMASK - CPSID I - - ;/** - ; * Call task switch hook. - ; */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CBZ R2, TaskSwitch - PUSH {R12, LR} - BLX R2 - POP {R12, LR} - -TaskSwitch - ;/** - ; * R0 = now stack pointer of the current running task. - ; */ - MRS R0, PSP - - ;/** - ; * Save the stack frame([S16-S31],R4-R11) of the current running task. - ; * R12 save the PRIMASK value of the current running task. - ; * NOTE: 1. Before entering the exception handler function, these registers - ; * ([NO_NAME,FPSCR,S15-S0],xPSR,PC,LR,R12,R3-R0) have been automatically - ; * saved by the CPU in the stack of the current running task. - ; * 2. If lazy stacking is enabled, space is reserved on the stack for - ; * the floating-point context(FPSCR,S15-S0), but the floating-point state - ; * is not saved. when the floating-point instruction(VSTMDBEQ R0!, {D8-D15}) - ; * is executed, the floating-point context(FPSCR,S15-S0) is first saved into - ; * the space reserved on the stack. In other words, the instruction - ; * 'VSTMDBEQ R0!, {D8-D15}' will trigger the CPU to save 'FPSCR,S15-S0' first. - ; * - ; * The stack of the current running task is as follows: - ; * - ; * |<=== PUSH: Save the context of the current running task - ; * | High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * | [ lazy stacking ]| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * Stack pointer before entering exception--->| - ; * |<--- cpu auto saved --->| - ; * |<---PSP to R0 - ; * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - ; */ -#if defined (__ARMVFP__) ; if FPU exist. - TST R14, #0x10 ; if the task using the FPU context, push s16-s31. - IT EQ - VSTMDBEQ R0!, {D8-D15} - STMFD R0!, {R14} ; save EXC_RETURN. -#endif - STMFD R0!, {R4-R12} ; save the core registers and PRIMASK. - - ;/** - ; * R5,R8. - ; */ - LDR R5, =g_stLosTask - MOV R8, #OS_TASK_STATUS_RUNNING - - ;/** - ; * Save the stack pointer of the current running task to TCB. - ; * (g_stLosTask.pstRunTask->pStackPointer = R0) - ; */ - LDR R6, [R5] - STR R0, [R6] - - ;/** - ; * Clear the RUNNING state of the current running task. - ; * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R6, #4] - BIC R7, R7, R8 - STRH R7, [R6, #4] - - ;/** - ; * Switch the current running task to the next running task. - ; * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - ; */ - LDR R0, [R5, #4] - STR R0, [R5] - - ;/** - ; * Set the RUNNING state of the next running task. - ; * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R0, #4] - ORR R7, R7, R8 - STRH R7, [R0, #4] - - ;/** - ; * Restore the stack pointer of the next running task from TCB. - ; * (R1 = g_stLosTask.pstNewTask->pStackPointer) - ; */ - LDR R1, [R0] - - ;/** - ; * Restore the stack frame(R4-R11,[S16-S31]) of the next running task. - ; * R12 restore the PRIMASK value of the next running task. - ; * NOTE: After exiting the exception handler function, these registers - ; * (PC,xPSR,R0-R3,R12,LR,[S0-S15,FPSCR,NO_NAME]) will be automatically - ; * restored by the CPU from the stack of the next running task. - ; * - ; * 1. The stack of the next running task is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * --+-----------------------------------+-------------------------------------------+--- - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; * - ; * 2. If the next running task is run for the first time, the stack is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; */ - LDMFD R1!, {R4-R12} ; restore the core registers and PRIMASK. -#if defined (__ARMVFP__) ; if FPU exist. - LDMFD R1!, {R14} ; restore EXC_RETURN. - TST R14, #0x10 ; if the task using the FPU context, pop s16-s31. - IT EQ - VLDMIAEQ R1!, {D8-D15} -#endif - - ;/** - ; * Set the stack pointer of the next running task to PSP. - ; */ - MSR PSP, R1 - - ;/** - ; * Restore the interruption state of the next running task. - ; */ - MSR PRIMASK, R12 - BX LR - - END - diff --git a/arch/arm/arm-m/cortex-m4/keil/los_dispatch_keil.S b/arch/arm/arm-m/cortex-m4/keil/los_dispatch_keil.S deleted file mode 100644 index 81ac8a61c..000000000 --- a/arch/arm/arm-m/cortex-m4/keil/los_dispatch_keil.S +++ /dev/null @@ -1,367 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2016-2018>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT LOS_IntLock - EXPORT LOS_IntUnLock - EXPORT LOS_IntRestore - EXPORT LOS_StartToRun - EXPORT osTaskSchedule - EXPORT PendSV_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT g_stLosTask - IMPORT g_pfnTskSwitchHook - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt Control and State Register. -OS_NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. - -OS_NVIC_SYSPRI2 EQU 0xE000ED20 ; System Handler Priority Register 2. -OS_NVIC_PENDSV_SYSTICK_PRI EQU 0xFFFF0000 ; SysTick + PendSV priority level (lowest). - -OS_TASK_STATUS_RUNNING EQU 0x0010 ; Task Status Flag (RUNNING). - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - AREA |.text|, CODE, READONLY - THUMB - REQUIRE8 - PRESERVE8 - -;**************************************************************************************** -; Function: -; VOID LOS_StartToRun(VOID); -; Description: -; Start the first task, which is the highest priority task in the priority queue. -; Other tasks are started by task scheduling. -;**************************************************************************************** -LOS_StartToRun - CPSID I - - ;/** - ; * Set PendSV and SysTick prority to the lowest. - ; * read ---> modify ---> write-back. - ; */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORR R1, R1, R2 - STR R1, [R0] - - ;/** - ; * Set g_bTaskScheduled = 1. - ; */ - LDR R0, =g_bTaskScheduled - MOV R1, #1 - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - ; */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - ; */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOV R3, #OS_TASK_STATUS_RUNNING - ORR R2, R2, R3 - STRH R2, [R1, #4] - - ;/** - ; * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - ; * [Initial EXC_RETURN ignore,] return by setting the CONTROL register. - ; * - ; * The initial stack of the current running task is as follows: - ; * - ; * POP: Restore the context of the current running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - ; * |<--- skip --->|<--- copy to R0-R7 --->| - ; * R12 to PSP--->| - ; * Stack pointer after LOS_StartToRun--->| - ; */ - LDR R12, [R1] - ADD R12, R12, #36 ; skip R4-R11, PRIMASK. - IF {FPU} != "SoftVFP" - ADD R12, R12, #4 ; if FPU exist, skip EXC_RETURN. - ENDIF - LDMFD R12!, {R0-R7} - - ;/** - ; * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - ; */ - MSR PSP, R12 - - ;/** - ; * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - ; */ - MOV R12, #2 - MSR CONTROL, R12 - - ;/** - ; * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - ; */ - MOV LR, R5 - CPSIE I - - ;/** - ; * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - ; * of the main function will be destroyed and will never be returned. - ; */ - BX R6 - -;**************************************************************************************** -; Function: -; UINTPTR LOS_IntLock(VOID); -; Description: -; Disable all interrupts except Reset,NMI and HardFault. -; The value of currnet interruption state will be returned to the caller to save. -; -; Function: -; VOID LOS_IntRestore(UINTPTR uvIntSave); -; Description: -; Restore the locked interruption of LOS_IntLock. -; The caller must pass in the value of interruption state previously saved. -;**************************************************************************************** -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 - -;**************************************************************************************** -; Function: -; VOID osTaskSchedule(VOID); -; Description: -; Start the task swtich process by software trigger PendSV interrupt. -;**************************************************************************************** -osTaskSchedule - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -;**************************************************************************************** -; Function: -; VOID PendSV_Handler(VOID); -; Description: -; PendSV interrupt handler, switch the context of the task. -; First: Save the context of the current running task(g_stLosTask.pstRunTask) -; to its own stack. -; Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -; from its own stack. -;**************************************************************************************** -PendSV_Handler - ;/** - ; * R12: Save the interruption state of the current running task. - ; * Disable all interrupts except Reset,NMI and HardFault - ; */ - MRS R12, PRIMASK - CPSID I - - ;/** - ; * Call task switch hook. - ; */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CBZ R2, TaskSwitch - PUSH {R12, LR} - BLX R2 - POP {R12, LR} - -TaskSwitch - ;/** - ; * R0 = now stack pointer of the current running task. - ; */ - MRS R0, PSP - - ;/** - ; * Save the stack frame([S16-S31],R4-R11) of the current running task. - ; * R12 save the PRIMASK value of the current running task. - ; * NOTE: 1. Before entering the exception handler function, these registers - ; * ([NO_NAME,FPSCR,S15-S0],xPSR,PC,LR,R12,R3-R0) have been automatically - ; * saved by the CPU in the stack of the current running task. - ; * 2. If lazy stacking is enabled, space is reserved on the stack for - ; * the floating-point context(FPSCR,S15-S0), but the floating-point state - ; * is not saved. when the floating-point instruction(VSTMDBEQ R0!, {D8-D15}) - ; * is executed, the floating-point context(FPSCR,S15-S0) is first saved into - ; * the space reserved on the stack. In other words, the instruction - ; * 'VSTMDBEQ R0!, {D8-D15}' will trigger the CPU to save 'FPSCR,S15-S0' first. - ; * - ; * The stack of the current running task is as follows: - ; * - ; * |<=== PUSH: Save the context of the current running task - ; * | High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * | [ lazy stacking ]| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * Stack pointer before entering exception--->| - ; * |<--- cpu auto saved --->| - ; * |<---PSP to R0 - ; * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - ; */ - IF {FPU} != "SoftVFP" ; if FPU exist. - TST R14, #0x10 ; if the task using the FPU context, push s16-s31. - IT EQ - VSTMDBEQ R0!, {D8-D15} - STMFD R0!, {R14} ; save EXC_RETURN. - ENDIF - STMFD R0!, {R4-R12} ; save the core registers and PRIMASK. - - ;/** - ; * R5,R8. - ; */ - LDR R5, =g_stLosTask - MOV R8, #OS_TASK_STATUS_RUNNING - - ;/** - ; * Save the stack pointer of the current running task to TCB. - ; * (g_stLosTask.pstRunTask->pStackPointer = R0) - ; */ - LDR R6, [R5] - STR R0, [R6] - - ;/** - ; * Clear the RUNNING state of the current running task. - ; * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R6, #4] - BIC R7, R7, R8 - STRH R7, [R6, #4] - - ;/** - ; * Switch the current running task to the next running task. - ; * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - ; */ - LDR R0, [R5, #4] - STR R0, [R5] - - ;/** - ; * Set the RUNNING state of the next running task. - ; * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R0, #4] - ORR R7, R7, R8 - STRH R7, [R0, #4] - - ;/** - ; * Restore the stack pointer of the next running task from TCB. - ; * (R1 = g_stLosTask.pstNewTask->pStackPointer) - ; */ - LDR R1, [R0] - - ;/** - ; * Restore the stack frame(R4-R11,[S16-S31]) of the next running task. - ; * R12 restore the PRIMASK value of the next running task. - ; * NOTE: After exiting the exception handler function, these registers - ; * (PC,xPSR,R0-R3,R12,LR,[S0-S15,FPSCR,NO_NAME]) will be automatically - ; * restored by the CPU from the stack of the next running task. - ; * - ; * 1. The stack of the next running task is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * --+-----------------------------------+-------------------------------------------+--- - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; * - ; * 2. If the next running task is run for the first time, the stack is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; */ - LDMFD R1!, {R4-R12} ; restore the core registers and PRIMASK. - IF {FPU} != "SoftVFP" ; if FPU exist. - LDMFD R1!, {R14} ; restore EXC_RETURN. - TST R14, #0x10 ; if the task using the FPU context, pop s16-s31. - IT EQ - VLDMIAEQ R1!, {D8-D15} - ENDIF - - ;/** - ; * Set the stack pointer of the next running task to PSP. - ; */ - MSR PSP, R1 - - ;/** - ; * Restore the interruption state of the next running task. - ; */ - MSR PRIMASK, R12 - BX LR - - ALIGN - END - diff --git a/arch/arm/arm-m/cortex-m4/los_exc.c b/arch/arm/arm-m/cortex-m4/los_exc.c deleted file mode 100644 index e3f5e43ce..000000000 --- a/arch/arm/arm-m/cortex-m4/los_exc.c +++ /dev/null @@ -1,619 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - - -#include "los_exc.inc" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#if (LOSCFG_PLATFORM_EXC == YES) - -UINT32 g_uwCurNestCount = 0; -EXC_INFO_S m_stExcInfo; -/* - * CFSR register, include UFSR,BFSR and MFSR. - * - * +----------------------------------------------------------------------------------+ - * | UFSR | - * |-----------+-----------+-----------+-------+------+-------+----------+------------| - * | 31 - 26 | 25 | 24 | 23-20 | 19 | 18 | 17 | 16 | - * |-----------+-----------+-----------+-------+------+-------+----------+------------| - * | --- | DIVBYZERO | UNALIGNED | --- | NOCP | INVPC | INVSTATE | UNDEFINSTR | - * +----------------------------------------------------------------------------------+ - * - * +----------------------------------------------------------------------------------+ - * | BFSR | - * |-----------+-----+--------+--------+----------+-------------+-----------+---------| - * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | - * |-----------+-----+--------+--------+----------+-------------+-----------+---------| - * | BFARVALID | --- | LSPERR | STKERR | UNSTKERR | IMPRECISERR | PRECISERR | IBUSERR | - * +----------------------------------------------------------------------------------+ - * - * +----------------------------------------------------------------------------------+ - * | MFSR | - * |-----------+-------+---------+---------+-----------+-------+----------+-----------| - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - * |-----------+-------+---------+---------+-----------+-------+----------+-----------| - * | MMARVALID | --- | MLSPERR | MSTKERR | MUNSTKERR | --- | DACCVIOL | ICACCVIOL | - * +----------------------------------------------------------------------------------+ - */ -UINT8 g_uwExcTbl[32] = -{ - 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, OS_EXC_BF_LSPERR, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, - 0, 0, OS_EXC_MF_MLSPERR, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL -}; - -#if (LOSCFG_SAVE_EXC_INFO == YES) -VOID *m_puwExcContent; -UINT32 g_uwArraySize = 0; -EXC_INFO_ARRAY_S m_stExcArray[OS_EXC_TYPE_MAX - 1]; -static VOID osExcSave2DDR(VOID); -#endif - -extern VOID LOS_Reboot(VOID); - -/***************************************************************************** - Function : osExcInfoDisplay - Description : EXC info display - Input : pstExc --- Pointer to the EXC data - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcInfoDisplay(EXC_INFO_S *pstExc) -{ - PRINT_ERR("Phase = 0x%x\n", pstExc->usPhase); - PRINT_ERR("Type = 0x%x\n", pstExc->usType); - PRINT_ERR("FaultAddr = 0x%x\n", pstExc->uwFaultAddr); - PRINT_ERR("ThrdPid = 0x%x\n", pstExc->uwThrdPid); - PRINT_ERR("R0 = 0x%x\n", pstExc->pstContext->uwR0); - PRINT_ERR("R1 = 0x%x\n", pstExc->pstContext->uwR1); - PRINT_ERR("R2 = 0x%x\n", pstExc->pstContext->uwR2); - PRINT_ERR("R3 = 0x%x\n", pstExc->pstContext->uwR3); - PRINT_ERR("R4 = 0x%x\n", pstExc->pstContext->uwR4); - PRINT_ERR("R5 = 0x%x\n", pstExc->pstContext->uwR5); - PRINT_ERR("R6 = 0x%x\n", pstExc->pstContext->uwR6); - PRINT_ERR("R7 = 0x%x\n", pstExc->pstContext->uwR7); - PRINT_ERR("R8 = 0x%x\n", pstExc->pstContext->uwR8); - PRINT_ERR("R9 = 0x%x\n", pstExc->pstContext->uwR9); - PRINT_ERR("R10 = 0x%x\n", pstExc->pstContext->uwR10); - PRINT_ERR("R11 = 0x%x\n", pstExc->pstContext->uwR11); - PRINT_ERR("R12 = 0x%x\n", pstExc->pstContext->uwR12); - PRINT_ERR("PriMask = 0x%x\n", pstExc->pstContext->uwPriMask); - PRINT_ERR("SP = 0x%x\n", pstExc->pstContext->uwSP); - PRINT_ERR("LR = 0x%x\n", pstExc->pstContext->uwLR); - PRINT_ERR("PC = 0x%x\n", pstExc->pstContext->uwPC); - PRINT_ERR("xPSR = 0x%x\n", pstExc->pstContext->uwxPSR); - - PRINT_ERR("\nplease use the addr2line tool to analyze the call stack on PC:\n"); - PRINT_ERR("addr2line -e (xxx.axf/xxx.elf/xxx.out) -a -f "); - for (UINT32 i = 0; i < pstExc->uwCallStackDepth; i++) - { - PRINT_ERR("%#x ", pstExc->uwCallStack[i]); - } - - return; -} - -/***************************************************************************** - Function : osExcCallStackAnalysis - Description : Call stack analysis - Input : pstExc --- point to exception info - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcCallStackAnalysis(EXC_INFO_S *pstExc) -{ - UINT32 uwSP; - UINT32 uwLR; - UINT32 uwPC; - UINT32 uwStackStartAddr; - UINT32 uwStackSize; - UINT32 uwDepth = 0; - BOOL bFirstLrValid = FALSE; - - uwSP = pstExc->pstContext->uwSP; /* sp pointer before entering exception */ - - /* - * save first and second depth - * first: PC before entering exception - * second: (LR - 4) before entering exception - * NOTE: If an exception occurs in the interrupt, LR may be EXC_RETURN, so we must make sure - * that LR is valid, exclude EXC_RETURN. - */ - pstExc->uwCallStack[uwDepth++] = pstExc->pstContext->uwPC; - if ((pstExc->pstContext->uwLR >= LOSCFG_EXC_CODE_START_ADDR) && \ - (pstExc->pstContext->uwLR <= LOSCFG_EXC_CODE_START_ADDR + LOSCFG_EXC_CODE_SIZE)) - { - pstExc->uwCallStack[uwDepth++] = pstExc->pstContext->uwLR - sizeof(VOID *); /* lr = pc + 4 */ - bFirstLrValid = TRUE; - } - - /* - * get the start address and size of the stack before entering the exception - */ - if (pstExc->usPhase == OS_EXC_IN_TASK) /* task use PSP */ - { - uwStackStartAddr = g_stLosTask.pstRunTask->uwTopOfStack; - uwStackSize = g_stLosTask.pstRunTask->uwStackSize; - } - else /* init and interrupt use MSP */ - { - uwStackStartAddr = LOSCFG_EXC_MSP_START_ADDR; - uwStackSize = LOSCFG_EXC_MSP_SIZE; - } - - /* - * check stack overflow, if so, compensate for overflow, readjust stack start address and size. - */ - if (uwSP < uwStackStartAddr) /* stack top overflow */ - { - if (pstExc->usPhase == OS_EXC_IN_TASK) - { - PRINT_ERR("task %s stack top overflow\n", g_stLosTask.pstRunTask->pcTaskName); - } - else - { - PRINT_ERR("MSP top overflow\n"); - } - uwStackSize += (uwStackStartAddr - uwSP); /* compensate overflow size */ - uwStackStartAddr = uwSP; /* readjust stack start address */ - } - - /* - * Traverses the entire stack from the top of the stack to the bottom of the stack, - * find all LR. - */ - for (; uwSP < uwStackStartAddr + uwStackSize; uwSP += sizeof(UINT32)) - { - uwLR = *(UINT32 *)uwSP; - if (uwLR % 2 == 0) /* Thumb instruction, LR bit0 == 1 */ - { - continue; - } - - /* - * It may be LR, which must be further determined based on the start address - * and end address of the code segment. - */ - if ((uwLR >= LOSCFG_EXC_CODE_START_ADDR) && (uwLR <= LOSCFG_EXC_CODE_START_ADDR + LOSCFG_EXC_CODE_SIZE) \ - && (uwDepth < LOSCFG_EXC_CALL_STACK_ANALYSIS_MAX_DEPTH)) - { - uwPC = uwLR - sizeof(VOID *); /* lr = pc + 4 */ - /* the second depth(first LR) has been saved */ - if ((uwDepth == 2) && (uwPC == pstExc->uwCallStack[1]) && (bFirstLrValid == TRUE)) - { - continue; - } - pstExc->uwCallStack[uwDepth++] = uwPC; - } - } - pstExc->uwCallStackDepth = uwDepth; /* save call stack depth */ - - return; -} - -/***************************************************************************** - Function : osExcHandleEntry - Description : EXC handler entry - Input : uwExcType --- EXC type - : uwFaultAddr --- The address of an accurate address access error - : uwPid --- Interrupt number - : puwExcBufAddr --- Point to the stack frame without FPU - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcHandleEntry(UINT32 uwExcType, UINT32 uwFaultAddr, UINT32 uwPid, EXC_CONTEXT_S *pstExcBufAddr) -{ - /* uwExcType high 16 bits: 0x01 - uwFaultAddr valid, 0x02 - in hwi */ - UINT16 usTmpFlag = (uwExcType >> 16) & 0xFFFF; - - g_uwCurNestCount++; -#if (LOSCFG_PLATFORM_HWI == YES) - extern UINT32 g_vuwIntCount; - g_vuwIntCount++; -#endif - - /* Save interrupt nesting times */ - m_stExcInfo.usNestCnt = (UINT16)g_uwCurNestCount; - /* uwExcType low 16 bits: exc type */ - m_stExcInfo.usType = (UINT16)uwExcType & 0xFFFF; -#if (LOSCFG_SAVE_EXC_INFO == YES) - /* Initializing a pointer to save an exception context */ - m_puwExcContent = (UINT32 *)m_aucTaskArray; -#endif - - /* Save the fault address when an exception occurs if it is valid */ - if (usTmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) - { - m_stExcInfo.uwFaultAddr = uwFaultAddr; - } - else - { - m_stExcInfo.uwFaultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; - } - - /* Save the phase of the exception */ - extern BOOL g_bTaskScheduled; - if (g_bTaskScheduled && (NULL != g_stLosTask.pstRunTask)) - { - if (usTmpFlag & OS_EXC_FLAG_IN_HWI) - { - m_stExcInfo.usPhase = OS_EXC_IN_HWI; - m_stExcInfo.uwThrdPid = uwPid; /* interrupt number */ - } - else - { - m_stExcInfo.usPhase = OS_EXC_IN_TASK; - m_stExcInfo.uwThrdPid = g_stLosTask.pstRunTask->uwTaskID; /* task id */ - } - } - else - { - m_stExcInfo.usPhase = OS_EXC_IN_INIT; - m_stExcInfo.uwThrdPid = 0xffffffff; - } - - /* uwExcType BIT_28: Wether or not to use FPU */ - if(uwExcType & OS_EXC_FLAG_NO_FLOAT) - { - m_stExcInfo.usFpuContext = 0; - #if FPU_EXIST - /* NOTE: S16-S31, S0-S15,FPSCR,NO_NAME invalid */ - m_stExcInfo.pstContext = (EXC_CONTEXT_S *)((UINT8 *)pstExcBufAddr - 64); /* point to S16 */ - #else - m_stExcInfo.pstContext = pstExcBufAddr; /* point to uwR4 */ - #endif - } - else - { - m_stExcInfo.usFpuContext = 1; - m_stExcInfo.pstContext = pstExcBufAddr; /* point to S16 */ - } - - osExcCallStackAnalysis(&m_stExcInfo); - -#if (LOSCFG_SAVE_EXC_INFO == YES) - osExcSave2DDR(); -#endif - - osExcInfoDisplay(&m_stExcInfo); - - LOS_Reboot(); -} - -#if (LOSCFG_SAVE_EXC_INFO == YES) -/***************************************************************************** - Function : osExcSaveIntStatus - Description : Save NVIC register group - Input : None - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSaveIntStatus(VOID) -{ - /* Save exc type */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_NVIC; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save total size of NVIC */ - *((UINT32 *)m_puwExcContent) = 0x164; // = OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + OS_NVIC_INT_ACT_SIZE + OS_NVIC_INT_PRI_SIZE + 12 + 4 + 4 - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save interrupt enable register group (start addr: 0xE000E100, size: 32bytes, CMSIS-Core: NVIC->ISER[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SETENA_BASE, OS_NVIC_INT_ENABLE_SIZE); - m_puwExcContent =(UINT8 *)m_puwExcContent + OS_NVIC_INT_ENABLE_SIZE; - - /* Save interrupt pend register group (start addr: 0xE000E200, size: 32bytes, CMSIS-Core: NVIC->ISPR[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SETPEND_BASE, OS_NVIC_INT_PEND_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_PEND_SIZE; - - /* Save interrupt active status register group (start addr: 0xE000E300, size: 32bytes, CMSIS-Core: NVIC->IABR[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_INT_ACT_BASE, OS_NVIC_INT_ACT_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_ACT_SIZE; - - /* Save interrupt priority register group (start addr: 0xE000E400, size: 240bytes), CMSIS-Core: NVIC->IP[0 - 239] */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_PRI_BASE, OS_NVIC_INT_PRI_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_PRI_SIZE; - - /* Save system exception priority register group (start addr: 0xE000ED18, size: 12bytes, CMSIS-Core: SCB->SHP[0 - 11]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_EXCPRI_BASE, 12); - m_puwExcContent = (UINT8 *)m_puwExcContent + 12; - - /* Save system processing control and state register group (start addr: 0xE000ED24, size: 4bytes, CMSIS-Core: SCB->SHCSR) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SHCSR, 4); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save interrupt control and status register group (start addr: 0xE000ED04, size: 4bytes, CMSIS-Core: SCB->ICSR) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_INT_CTRL, 4); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - return; -} - -/***************************************************************************** - Function : osExcRegister - Description : Register exception - Input : uwType --- exception type - : pFunc --- exception callback function - : pArg --- exception save info arg, not pFunc - Output : None - Return : None - *****************************************************************************/ -VOID osExcRegister(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg) -{ - EXC_INFO_ARRAY_S *pstExcInfo; - - if (uwType == 0 || uwType >= OS_EXC_TYPE_MAX || pFunc == NULL) - { - PRINT_ERR("osExcRegister ERROR!\n"); - return; - } - - pstExcInfo = &(m_stExcArray[uwType - 1]); - pstExcInfo->uwType = uwType; - pstExcInfo->pFnExcInfoCb = pFunc; - pstExcInfo->pArg = pArg; - pstExcInfo->uwValid = TRUE; -} - -/***************************************************************************** - Function : osExcSaveSysInfo - Description : Saving exception information by calling callback function recursively - Input : uwType --- exception type(OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1) - : pFunc --- callback function - : uwLoop --- loop total count - : uwLen --- The size of the data saved each time - : uwIdx --- loop index - Output : None - Return : None - *****************************************************************************/ -VOID osExcSaveSysInfo(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, UINT32 uwLoop, UINT32 uwLen, UINT32 uwIdx) -{ - UINT32 uwRet; - UINT32 uwBuffer[OS_EXC_MAX_BUF_LEN]; - - /* Save exception type and size */ - *((UINT32 *)m_puwExcContent) = uwType; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - *((UINT32 *)m_puwExcContent) = uwLen * (uwLoop - uwIdx); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - for (; uwIdx < uwLoop; uwIdx++) - { - memset((VOID *)uwBuffer, 0, sizeof(UINT32) * OS_EXC_MAX_BUF_LEN); - uwRet = pFunc(uwIdx, (VOID *)uwBuffer); - if (LOS_OK == uwRet) - { - memcpy(m_puwExcContent, (VOID *)uwBuffer, uwLen); - } - m_puwExcContent =(UINT8 *)m_puwExcContent + uwLen; - } -} - -/***************************************************************************** - Function : osExcSaveInfo - Description : save exception info - Input : uwType --- exception type(OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1) - : pFunc --- exception callback - : pArg --- register arg, used to generate the arg passed to the callback - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSaveInfo(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg) -{ - UINT32 uwLen; - UINT32 uwIdx; - UINT32 uwLoop; - UINT32 uwTaskSwitchCount = 0; - OS_TASK_SWITCH_INFO *pstTaskSwitchInfo; - - switch(uwType) - { - case OS_EXC_TYPE_TSK: /* save task info */ - uwLen = sizeof(TSK_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - case OS_EXC_TYPE_QUE: /* save queue info */ - uwLen = sizeof(QUEUE_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - case OS_EXC_TYPE_NVIC: /* save NVIC info */ - (VOID)pFunc(0, 0); - goto END; - - case OS_EXC_TYPE_TSK_SWITCH: /* save task switch info */ - pstTaskSwitchInfo = pArg; - uwTaskSwitchCount = pstTaskSwitchInfo->ucIsFull & 0x7F; - uwLen = sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN; /* auwPID + acName */ - if (pstTaskSwitchInfo->ucIsFull & 0x80) - { - uwIdx = pstTaskSwitchInfo->ucIdx; - uwLoop = uwIdx + uwTaskSwitchCount; - } - else - { - uwIdx = 0; - uwLoop = pstTaskSwitchInfo->ucIdx; - } - break; - - case OS_EXC_TYPE_MEM: /* save mem info */ - uwLen = sizeof(MEM_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - default: - goto END; - } - osExcSaveSysInfo(uwType, (EXC_INFO_SAVE_CALLBACK)pFunc, uwLoop, uwLen, uwIdx); -END: - return; -} - -/***************************************************************************** - Function : osExcSave2DDR - Description : Save exception info to RAM - Input : None - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSave2DDR(VOID) -{ - UINT32 uwIdx = 0; - UINT32 uwExcContextSize; - - if (m_stExcInfo.usFpuContext == 1) - { - uwExcContextSize = sizeof(EXC_CONTEXT_S); - } - else - { - uwExcContextSize = sizeof(EXC_CONTEXT_S) - 136; /* except FPU register */ - } - - memset(m_puwExcContent, 0xff, g_uwArraySize); - - /* Cortex-M type */ - *((UINT32 *)m_puwExcContent) = 4; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* - * Save exception type: OS_EXC_TYPE_CONTEXT - */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_CONTEXT; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* The size of struct EXC_INFO_S(except member EXC_CONTEXT_S*) and exception context size */ - *((UINT32 *)m_puwExcContent) = sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *) + uwExcContextSize; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save struct m_stExcInfo except m_stExcInfo.pstContext */ - memcpy((VOID *)m_puwExcContent, (VOID *)&m_stExcInfo, sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *)); - m_puwExcContent = (UINT8 *)m_puwExcContent + sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *); - - /* Save struct EXC_CONTEXT_S */ - if (m_stExcInfo.usFpuContext == 0) - { - #if FPU_EXIST - /* m_stExcInfo.pstContext: init --- point to S16, S16->S31 invalid - * + 64 --- point to uwR4 - * copy uwR4 -> uwxPSR */ - memcpy((VOID *)m_puwExcContent, (UINT8 *)m_stExcInfo.pstContext + 64, uwExcContextSize); - #else - memcpy((VOID *)m_puwExcContent, m_stExcInfo.pstContext, uwExcContextSize); - #endif - } - else - { - memcpy((VOID *)m_puwExcContent, m_stExcInfo.pstContext, uwExcContextSize); - } - m_puwExcContent = (UINT8 *)m_puwExcContent + uwExcContextSize; - - /* - * Save exception type: OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1 - */ - for (uwIdx = 0; uwIdx < OS_EXC_TYPE_MAX - 1; uwIdx++) - { - if (m_stExcArray[uwIdx].uwValid == FALSE) - { - continue; - } - osExcSaveInfo(m_stExcArray[uwIdx].uwType, m_stExcArray[uwIdx].pFnExcInfoCb, m_stExcArray[uwIdx].pArg); - } - - /* - * Save exception type: OS_EXC_TYPE_MAX - */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_MAX; - m_puwExcContent = (UINT8*)m_puwExcContent + 4; - - return; -} -#endif /*(LOSCFG_SAVE_EXC_INFO == YES)*/ - -/***************************************************************************** - Function : osExcInit - Description : Initializes the EXC - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID osExcInit(UINT32 uwArraySize) -{ -#if (LOSCFG_PLATFORM_HWI == YES) - /* Register exception handler to interrupt vector table in RAM */ - m_pstHwiForm[-14 + OS_SYS_VECTOR_CNT] = NMI_Handler; - m_pstHwiForm[-13 + OS_SYS_VECTOR_CNT] = HardFault_Handler; - m_pstHwiForm[-12 + OS_SYS_VECTOR_CNT] = MemManage_Handler; - m_pstHwiForm[-11 + OS_SYS_VECTOR_CNT] = BusFault_Handler; - m_pstHwiForm[-10 + OS_SYS_VECTOR_CNT] = UsageFault_Handler; - m_pstHwiForm[-5 + OS_SYS_VECTOR_CNT] = SVC_Handler; -#endif - - /* Enable USGFAULT(BIT_18), BUSFAULT(BIT_17), MEMFAULT(BIT_16) */ - *(volatile UINT32 *)OS_NVIC_SHCSR |= 0x70000; - - /* Enable DIV 0(BIT_4) exception, unaligned(BIT_3) disable */ - *(volatile UINT32 *)OS_NVIC_CCR |= 0x10; - -#if (LOSCFG_SAVE_EXC_INFO == YES) - g_uwArraySize = uwArraySize; - osExcRegister((EXC_INFO_TYPE)OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)osExcSaveIntStatus, NULL); -#endif -} - -VOID osBackTrace(VOID) -{ - return; -} - -#endif /*(LOSCFG_PLATFORM_EXC == YES)*/ - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - diff --git a/arch/arm/arm-m/cortex-m7/gcc/los_dispatch_gcc.S b/arch/arm/arm-m/cortex-m7/gcc/los_dispatch_gcc.S deleted file mode 100644 index 71d893802..000000000 --- a/arch/arm/arm-m/cortex-m7/gcc/los_dispatch_gcc.S +++ /dev/null @@ -1,370 +0,0 @@ -/** ---------------------------------------------------------------------------- - * Copyright (c) <2016-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/** ---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**************************************************************************************** -* EXPORT FUNCTIONS -****************************************************************************************/ - - .global LOS_IntLock - .global LOS_IntUnLock - .global LOS_IntRestore - .global LOS_StartToRun - .global osTaskSchedule - .global PendSV_Handler - -/**************************************************************************************** -* EXTERN PARAMETERS -****************************************************************************************/ - - .extern g_stLosTask - .extern g_pfnTskSwitchHook - .extern g_bTaskScheduled - -/**************************************************************************************** -* EQU -****************************************************************************************/ - -.equ OS_NVIC_INT_CTRL, 0xE000ED04 /* Interrupt Control and State Register. */ -.equ OS_NVIC_PENDSVSET, 0x10000000 /* Value to trigger PendSV exception. */ - -.equ OS_NVIC_SYSPRI2, 0xE000ED20 /* System Handler Priority Register 2. */ -.equ OS_NVIC_PENDSV_SYSTICK_PRI, 0xFFFF0000 /* SysTick + PendSV priority level (lowest). */ - -.equ OS_TASK_STATUS_RUNNING, 0x0010 /* Task Status Flag (RUNNING). */ - -/**************************************************************************************** -* CODE GENERATION DIRECTIVES -****************************************************************************************/ - - .section .text - .thumb - .syntax unified - .arch armv7e-m - -/**************************************************************************************** -* Function: -* VOID LOS_StartToRun(VOID); -* Description: -* Start the first task, which is the highest priority task in the priority queue. -* Other tasks are started by task scheduling. -****************************************************************************************/ - .type LOS_StartToRun, %function -LOS_StartToRun: - CPSID I - - /** - * Set PendSV and SysTick prority to the lowest. - * read ---> modify ---> write-back. - */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORR R1, R1, R2 - STR R1, [R0] - - /** - * Set g_bTaskScheduled = 1. - */ - LDR R0, =g_bTaskScheduled - MOV R1, #1 - STR R1, [R0] - - /** - * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - /** - * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOV R3, #OS_TASK_STATUS_RUNNING - ORR R2, R2, R3 - STRH R2, [R1, #4] - - /** - * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - * [Initial EXC_RETURN ignore,] return by setting the CONTROL register. - * - * The initial stack of the current running task is as follows: - * - * POP: Restore the context of the current running task ===>| - * High addr--->| - * Bottom of the stack--->| - * ----------+---------------------------------+--------------------------------+ - * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - * ----------+---------------------------------+--------------------------------+ - * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - * |<--- skip --->|<--- copy to R0-R7 --->| - * R12 to PSP--->| - * Stack pointer after LOS_StartToRun--->| - */ - LDR R12, [R1] - ADD R12, R12, #36 /* skip R4-R11, PRIMASK. */ -#if defined (__VFP_FP__) && !defined(__SOFTFP__) - ADD R12, R12, #4 /* if FPU exist, skip EXC_RETURN. */ -#endif - LDMFD R12!, {R0-R7} - - /** - * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - */ - MSR PSP, R12 - - /** - * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - */ - MOV R12, #2 - MSR CONTROL, R12 - - /** - * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - */ - MOV LR, R5 - CPSIE I - - /** - * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - * of the main function will be destroyed and will never be returned. - */ - BX R6 - -/**************************************************************************************** -* Function: -* UINTPTR LOS_IntLock(VOID); -* Description: -* Disable all interrupts except Reset,NMI and HardFault. -* The value of currnet interruption state will be returned to the caller to save. -* -* Function: -* VOID LOS_IntRestore(UINTPTR uvIntSave); -* Description: -* Restore the locked interruption of LOS_IntLock. -* The caller must pass in the value of interruption state previously saved. -****************************************************************************************/ - .type LOS_IntLock, %function -LOS_IntLock: - MRS R0, PRIMASK - CPSID I - BX LR - - .type LOS_IntUnLock, %function -LOS_IntUnLock: - MRS R0, PRIMASK - CPSIE I - BX LR - - .type LOS_IntRestore, %function -LOS_IntRestore: - MSR PRIMASK, R0 - BX LR - -/**************************************************************************************** -* Function: -* VOID osTaskSchedule(VOID); -* Description: -* Start the task swtich process by software trigger PendSV interrupt. -****************************************************************************************/ - .type osTaskSchedule, %function -osTaskSchedule: - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -/**************************************************************************************** -* Function: -* VOID PendSV_Handler(VOID); -* Description: -* PendSV interrupt handler, switch the context of the task. -* First: Save the context of the current running task(g_stLosTask.pstRunTask) -* to its own stack. -* Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -* from its own stack. -****************************************************************************************/ - .type PendSV_Handler, %function -PendSV_Handler: - /** - * R12: Save the interruption state of the current running task. - * Disable all interrupts except Reset,NMI and HardFault - */ - MRS R12, PRIMASK - CPSID I - - /** - * Call task switch hook. - */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CBZ R2, TaskSwitch - PUSH {R12, LR} - BLX R2 - POP {R12, LR} - -TaskSwitch: - /** - * R0 = now stack pointer of the current running task. - */ - MRS R0, PSP - - /** - * Save the stack frame([S16-S31],R4-R11) of the current running task. - * R12 save the PRIMASK value of the current running task. - * NOTE: 1. Before entering the exception handler function, these registers - * ([NO_NAME,FPSCR,S15-S0],xPSR,PC,LR,R12,R3-R0) have been automatically - * saved by the CPU in the stack of the current running task. - * 2. If lazy stacking is enabled, space is reserved on the stack for - * the floating-point context(FPSCR,S15-S0), but the floating-point state - * is not saved. when the floating-point instruction(VSTMDBEQ R0!, {D8-D15}) - * is executed, the floating-point context(FPSCR,S15-S0) is first saved into - * the space reserved on the stack. In other words, the instruction - * 'VSTMDBEQ R0!, {D8-D15}' will trigger the CPU to save 'FPSCR,S15-S0' first. - * - * The stack of the current running task is as follows: - * - * |<=== PUSH: Save the context of the current running task - * | High addr--->| - * --+-----------------------------------+-------------------------------------------+--- - * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * | [ lazy stacking ]| - * --+-----------------------------------+-------------------------------------------+--- - * Stack pointer before entering exception--->| - * |<--- cpu auto saved --->| - * |<---PSP to R0 - * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - */ -#if defined (__VFP_FP__) && !defined(__SOFTFP__) /* if FPU exist. */ - TST R14, #0x10 /* if the task using the FPU context, push s16-s31. */ - IT EQ - VSTMDBEQ R0!, {D8-D15} - STMFD R0!, {R14} /* save EXC_RETURN. */ -#endif - STMFD R0!, {R4-R12} /* save the core registers and PRIMASK. */ - - /** - * R5,R8. - */ - LDR R5, =g_stLosTask - MOV R8, #OS_TASK_STATUS_RUNNING - - /** - * Save the stack pointer of the current running task to TCB. - * (g_stLosTask.pstRunTask->pStackPointer = R0) - */ - LDR R6, [R5] - STR R0, [R6] - - /** - * Clear the RUNNING state of the current running task. - * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - */ - LDRH R7, [R6, #4] - BIC R7, R7, R8 - STRH R7, [R6, #4] - - /** - * Switch the current running task to the next running task. - * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - */ - LDR R0, [R5, #4] - STR R0, [R5] - - /** - * Set the RUNNING state of the next running task. - * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - */ - LDRH R7, [R0, #4] - ORR R7, R7, R8 - STRH R7, [R0, #4] - - /** - * Restore the stack pointer of the next running task from TCB. - * (R1 = g_stLosTask.pstNewTask->pStackPointer) - */ - LDR R1, [R0] - - /** - * Restore the stack frame(R4-R11,[S16-S31]) of the next running task. - * R12 restore the PRIMASK value of the next running task. - * NOTE: After exiting the exception handler function, these registers - * (PC,xPSR,R0-R3,R12,LR,[S0-S15,FPSCR,NO_NAME]) will be automatically - * restored by the CPU from the stack of the next running task. - * - * 1. The stack of the next running task is as follows: - * - * POP: Restore the context of the next running task ===>| - * High addr--->| - * --+-----------------------------------+-------------------------------------------+--- - * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * --+-----------------------------------+-------------------------------------------+--- - * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - * R1 to PSP--->| - * |<--- cpu auto restoring --->| - * Stack pointer after exiting exception--->| - * - * 2. If the next running task is run for the first time, the stack is as follows: - * - * POP: Restore the context of the next running task ===>| - * High addr--->| - * Bottom of the stack--->| - * ----------+---------------------------------+--------------------------------+ - * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - * ----------+---------------------------------+--------------------------------+ - * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - * R1 to PSP--->| - * |<--- cpu auto restoring --->| - * Stack pointer after exiting exception--->| - */ - LDMFD R1!, {R4-R12} /* restore the core registers and PRIMASK. */ -#if defined (__VFP_FP__) && !defined(__SOFTFP__) /* if FPU exist. */ - LDMFD R1!, {R14} /* restore EXC_RETURN. */ - TST R14, #0x10 /* if the task using the FPU context, pop s16-s31. */ - IT EQ - VLDMIAEQ R1!, {D8-D15} -#endif - - /** - * Set the stack pointer of the next running task to PSP. - */ - MSR PSP, R1 - - /** - * Restore the interruption state of the next running task. - */ - MSR PRIMASK, R12 - BX LR - diff --git a/arch/arm/arm-m/cortex-m7/gcc/los_hw_exc_gcc.S b/arch/arm/arm-m/cortex-m7/gcc/los_hw_exc_gcc.S deleted file mode 100644 index 2fccb579a..000000000 --- a/arch/arm/arm-m/cortex-m7/gcc/los_hw_exc_gcc.S +++ /dev/null @@ -1,553 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ - /*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**************************************************************************************** -* CODE GENERATION DIRECTIVES -****************************************************************************************/ - - .syntax unified - .arch armv7e-m - .thumb - .section .text - -/**************************************************************************************** -* EXPORT FUNCTIONS -****************************************************************************************/ - - .global NMI_Handler - .global HardFault_Handler - .global MemManage_Handler - .global BusFault_Handler - .global UsageFault_Handler - .global SVC_Handler - -/**************************************************************************************** -* EXTERN PARAMETERS -****************************************************************************************/ - - .extern osExcHandleEntry - .extern g_uwExcTbl - .extern g_bTaskScheduled - -/**************************************************************************************** -* EQU -****************************************************************************************/ - -.equ OS_EXC_CAUSE_NMI, 18 -.equ OS_EXC_CAUSE_HARDFAULT, 19 -.equ OS_EXC_CAUSE_MEMFAULT, 20 -.equ OS_EXC_CAUSE_BUSFAULT, 21 -.equ OS_EXC_CAUSE_USAGEFAULT, 22 -.equ OS_EXC_CAUSE_SVC, 23 - -.equ HF_DEBUGEVT, 24 -.equ HF_VECTBL, 25 - -.equ FLAG_ADDR_VALID, 0x10000 /* bit 16 */ -.equ FLAG_HWI_ACTIVE, 0x20000 /* bit 17 */ -.equ FLAG_NO_FLOAT, 0x10000000 /* bit 28 */ - -.equ OS_NVIC_CFSR, 0xE000ED28 /* include BusFault/MemFault/UsageFault State Regeister */ -.equ OS_NVIC_HFSR, 0xE000ED2C /* HardFault State Regeister */ -.equ OS_NVIC_BFAR, 0xE000ED38 -.equ OS_NVIC_MMFAR, 0xE000ED34 -.equ OS_NVIC_ACT_BASE, 0xE000E300 -.equ OS_NVIC_SHCSRS, 0xE000ED24 -.equ OS_NVIC_SHCSR_MASK, 0xC00 /* SYSTICKACT and PENDSVACT */ - -/**************************************************************************************** -* Function: -* VOID NMI_Handler(VOID); -* Description: -* NMI Handler. -****************************************************************************************/ - .type NMI_Handler, %function -NMI_Handler: - /** - * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +------------------------------------------------------+------------------------+ - * | 31-8 | 7-0 | - * +------------------------------------------------------+------------------------+ - * | --- | OS_EXC_CAUSE_NMI | - * +------------------------------------------------------+------------------------+ - * < R1 >: invalid - */ - MOV R0, #OS_EXC_CAUSE_NMI - MOV R1, #0 - B osExcDispatch - -/**************************************************************************************** -* Function: -* VOID HardFault_Handler(VOID); -* Description: -* HardFault Handler. -****************************************************************************************/ - .type HardFault_Handler, %function -HardFault_Handler: - /** - * Check HardFault state register. - * - * HFSR: - * +----------+--------+--------+--------+-------+ - * | 31 | 30 | 29 - 2 | 1 | 0 | - * +----------+--------+--------+--------+-------+ - * | DEBUGEVT | FORCED | -- | VECTBL | -- | - * +----------+--------+--------+--------+-------+ - */ - MOV R0, #OS_EXC_CAUSE_HARDFAULT - LDR R2, =OS_NVIC_HFSR - LDR R2, [R2] - - /** - * Check whether HardFault are triggered by debugging events. - * Before executing instruction 'BNE osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +----------------------------------------+-------------+------------------------+ - * | 31-16 | 15-8 | 7-0 | - * +----------------------------------------+-------------+------------------------+ - * | --- | HF_DEBUGEVT | OS_EXC_CAUSE_HARDFAULT | - * +----------------------------------------+-------------+------------------------+ - * < R1 >: invalid - */ - MOV R1, #HF_DEBUGEVT - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x80000000 - BNE osExcDispatch /* DEBUGEVT */ - - /** - * Check whether HardFault is caused by the failure of the fetch vector. - * Before executing instruction 'BNE osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +----------------------------------------+-------------+------------------------+ - * | 31-16 | 15-8 | 7-0 | - * +----------------------------------------+-------------+------------------------+ - * | --- | HF_VECTBL | OS_EXC_CAUSE_HARDFAULT | - * +----------------------------------------+-------------+------------------------+ - * < R1 >: invalid - */ - AND R0, R0, #0x000000FF - MOV R1, #HF_VECTBL - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x00000002 - BNE osExcDispatch /* VECTBL */ - - /** - * If it`s not DEBUGEVT and VECTBL, that is FORCED, then read the CFSR register to - * check BusFault, MemFault and UsageFault. - * R0: OS_EXC_CAUSE_HARDFAULT - * - * CFSR: - * +----------------+--------+--------+ - * | 31-16 | 15-8 | 7-0 | - * +----------------+--------+--------+ - * | UFSR | BFSR | MFSR | - * +----------------+--------+--------+ - */ - AND R0, R0, #0x000000FF - - LDR R2, =OS_NVIC_CFSR - LDR R2, [R2] - - TST R2, #0x8000 /* BFSR->BFARVALID */ - BNE _HFBusFault /* BusFault */ - - TST R2, #0x80 /* MFSR->MMARVALID */ - BNE _HFMemFault /* MemFault */ - - /** - * BFARVALID and MMARVALID flag both invalid. - * R12: 0 --- The error address is invalid. - */ - MOV R12, #0 - B osHFExcCommonBMU - - /** - * BFARVALID flag valid, read BFAR register. - * R1 : BFAR value --- The address value of a bus error. - * R12: The error address is valid. - */ -_HFBusFault: - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - B osHFExcCommonBMU - - /** - * MMARVALID flag valid, read MMFAR register. - * R1 : MMFAR value --- The address value of memory management error. - * R12: The error address is valid. - */ -_HFMemFault: - LDR R1, =OS_NVIC_MMFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - - /** - * osHFExcCommonBMU: --- Get specific error status from table g_uwExcTbl, stored in R0. - * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - * < R0 >: - * +-------------------+-----------------+------------------+------------------------+ - * | 31-17 | 16 | 15-8 | 7-0 | - * +-------------------+-----------------+------------------+------------------------+ - * | --- | FLAG_ADDR_VALID | Error state code | OS_EXC_CAUSE_HARDFAULT | - * | | or | in | | - * | | 0(invalid) | table g_uwExcTbl | | - * +-------------------+-----------------+------------------+------------------------+ - * < R1 >: The value of BFAR or MMFAR if the bit16(FLAG_ADDR_VALID) of R0 is set to 1, - * else invalid. - */ -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 - -/**************************************************************************************** -* Function: -* VOID SVC_Handler(VOID); -* Description: -* SVC Handler. -****************************************************************************************/ - .type SVC_Handler, %function -SVC_Handler: - TST LR, #0x4 /* EXC_RETURN[b2] --- PSP or MSP */ - ITE EQ - MRSEQ R0, MSP - MRSNE R0, PSP - LDR R1, [R0, #24] /* The PC value in the stack frame */ - LDRB R0, [R1, #-2] /* R0: The number of SVC (0 - 255) */ - MOV R1, #0 - /* B osExcDispatch */ -_SvcLoop: - B _SvcLoop - -/**************************************************************************************** -* Function: -* VOID BusFault_Handler(VOID); -* Description: -* BusFault Handler. -****************************************************************************************/ - .type BusFault_Handler, %function -BusFault_Handler: - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_BUSFAULT - - TST R0, #0x8000 /* BFSR->BFARVALID */ - BEQ _ExcBusNoADDR - - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] /* R1: The value of BFAR */ - MOV R12, #FLAG_ADDR_VALID /* R12: BusFault addr valid */ - AND R0, R0, #0x3F00 /* R0: Reserved the b13-b8 of the BFSR */ - B osExcCommonBMU - -_ExcBusNoADDR: - MOV R12, #0 /* R12: BusFault addr invalid */ - AND R0, R0, #0x3F00 /* R0: Reserved the b13-b8 of the BFSR */ - B osExcCommonBMU - -/**************************************************************************************** -* Function: -* VOID MemManage_Handler(VOID); -* Description: -* MemManage Handler. -****************************************************************************************/ - .type MemManage_Handler, %function -MemManage_Handler: - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_MEMFAULT - - TST R0, #0x80 /* MFSR->MMARVALID */ - BEQ _ExcMemNoADDR - - LDR R1, =OS_NVIC_MMFAR - LDR R1, [R1] /* R1: The value of MMFAR */ - MOV R12, #FLAG_ADDR_VALID /* R12: MemFault addr valid */ - AND R0, R0, #0x3B /* R0: Reserved the b5-b0 of the MFSR */ - B osExcCommonBMU - -_ExcMemNoADDR: - MOV R12, #0 /* R12: MemFault addr invalid */ - AND R0, R0, #0x3B /* R0: Reserved the b5-b0 of the MFSR */ - B osExcCommonBMU - -/**************************************************************************************** -* Function: -* VOID UsageFault_Handler(VOID); -* Description: -* UsageFault Handler. -****************************************************************************************/ - .type UsageFault_Handler, %function -UsageFault_Handler: - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_USAGEFAULT - - LDR R1, =#0x030F - LSL R1, R1, #16 - AND R0, R0, R1 /* R0: reserved UFSR */ - MOV R12, #0 /* R12: Fault addr invalid */ - - /** - * osExcCommonBMU: BusFault_Handler,MemManage_Handler and UsageFault_Handler share. - * Get specific error status from table g_uwExcTbl, stored in R0. - * Before executing osExcDispatch, the value of R0 is as follows. - * < R0 >: - * +-------------------+-----------------+------------------+------------------------+ - * | 31-17 | 16 | 15-8 | 7-0 | - * +-------------------+-----------------+------------------+------------------------+ - * | --- | FLAG_ADDR_VALID | Error state code |OS_EXC_CAUSE_BUSFAULT or| - * | | or | in |OS_EXC_CAUSE_MEMFAULT or| - * | | 0(invalid) | table g_uwExcTbl |OS_EXC_CAUSE_USAGEFAULT | - * +-------------------+-----------------+------------------+------------------------+ - * < R1 >: The value of BFAR or MMFAR if the bit16(FLAG_ADDR_VALID) of R0 is set to 1, - * else invalid. - */ -osExcCommonBMU: - CLZ R0, R0 - LDR R3, =g_uwExcTbl - ADD R3, R3, R0 - LDRB R0, [R3] - LSL R0, R0, #0x8 - ORR R0, R0, R2 - ORR R0, R0, R12 - - /**************************************************************************************** - * osExcDispatch: NMI_Handler, HardFault_Handler, SVC_Handler, BusFault_Handler, MemManage_Handler, - * UsageFault_Handler sharing. - ****************************************************************************************/ - - /** - * When executing osExcDispatch, R0, R1 will be used. - * The possible values of R0 and R1 are as follows. - * - * < R0 >: - * +----------------+-----------------+---------------------+------------------------+ - * | 31-17 | 16 | 15-8 | 7-0 | - * +----------------+-----------------+---------------------+------------------------+ - * | | FLAG_ADDR_VALID | Error state code in | OS_EXC_CAUSE_HARDFAULT | - * | --- | or | table g_uwExcTbl |or OS_EXC_CAUSE_MEMFAULT| - * | | 0(invalid) | or HF_DEBUGEVT |or OS_EXC_CAUSE_BUSFAULT| - * | | | or HF_VECTBL |or OS_EXC_CAUSE_NMI or | - * | | | | OS_EXC_CAUSE_USAGEFAULT| - * +----------------+-----------------+---------------------+------------------------+ - * b17: FLAG_HWI_ACTIVE - * b28: FLAG_NO_FLOAT - * NOTE: b17 and b28 will be set later. - * - * < R1 >: - * If the bit16 of R0 is 1, then R1 is the value of BFAR or MMFAR, otherwise the - * value in R1 is invalid. - * - */ -osExcDispatch: - LDR R2, =OS_NVIC_ACT_BASE - MOV R12, #8 /* #8: externel interrupt active check loop counter(#0 - #239) */ - -_hwiActiveCheck: - LDR R3, [R2] /* R3 store the value of externel interrupt active status */ - CMP R3, #0 - BEQ _hwiActiveCheckNext - - /** - * Exception occured in external interrupt. - */ - ORR R0, R0, #FLAG_HWI_ACTIVE /* R0[b17] = 1, externel interrupt active valid &&&&&&&&&& */ - RBIT R2, R3 /* bit reversal */ - CLZ R2, R2 - RSB R12, R12, #8 /* R12 = 8 - R12 */ - ADD R2, R2, R12, LSL #5 /* R2: external interrupt number as uwPid */ - - /** - * Interrupts and initialization phase always use MSP. - */ -_ExcInMSP: - TST LR, #0x10 /* EXC_RETURN[b4] --- FPU(0) or without FPU(1) */ - BNE _NoFloatInMsp - - /** - * Before executing instruction 'B _handleEntry', MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | S16-S31,R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * +--------------------------------------------------------------------------------+--------- - * |<---R13 Initial R13--->|<--- #104 --->|<---SAVED_SP - * | (CPU auto saved) | - * - */ - ADD R3, R13, #104 /* #104: skip [R0-xPSR,D0-D7,FPSCR,NO_NAME] */ - PUSH {R3} /* push [SAVED_SP]: MSP+104 = Stack pointer in MSP before entering the exception */ - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK to MSP */ - VPUSH {D8-D15} /* push D8-D15 to MSP */ - B _handleEntry - - /** - * Before executing instruction 'B _handleEntry', MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR | - * +--------------------------------------------------------------------------------+--------- - * R13--->| Initial R13--->|<--- #32 --->|<---SAVED_SP - * | (CPU auto saved) | - * - */ -_NoFloatInMsp: - ADD R3, R13, #32 /* #32: skip [R0-R3,R12,LR,PC,xPSR] */ - PUSH {R3} /* push [SAVED_SP]: MSP+32 = Stack pointer in MSP before entering the exception */ - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK to MSP */ - ORR R0, R0, #FLAG_NO_FLOAT /* R0[b28] = 1, no FPU &&&&&&&&&& */ - B _handleEntry - -_hwiActiveCheckNext: - ADD R2, R2, #4 /* next NVIC ACT ADDR */ - SUBS R12, R12, #1 - BNE _hwiActiveCheck - - /** - * Not in externel interrupt, check whether it is SysTick or PendSV. - */ - LDR R2, =OS_NVIC_SHCSRS - LDRH R2,[R2] - LDR R3,=OS_NVIC_SHCSR_MASK - AND R2, R2, R3 - CMP R2, #0 - BNE _ExcInMSP /* SysTick or PendSV active */ - - /** - * Check whether an exception occurs during the initialization phase. - * If g_bTaskScheduled == 0, it is in the initialization phase. - */ - LDR R2, =g_bTaskScheduled - LDR R2, [R2] - TST R2, #1 - BEQ _ExcInMSP /* initialization phase use MSP */ - - /** - * Exception occured in Task. - */ - TST LR, #0x10 - BNE _NoFloatInPsp - - /** - * Before executing _handleEntry, MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | S16-S31,R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - * +--------------------------------------------------------------------------------+--------- - * |<---R13 |<--- #104 --->|<---Initial R13 - * | (copied from PSP) | - * R2(no use)--->| - * - * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME. - */ - MOV R2, R13 - SUB R2, R2, #8 /* #8: reserved for [FPSCR,NO_NAME] */ - SUB R13, #104 /* #104: MSP reserved, used to store stack frame in PSP */ - - MRS R3, PSP - ADD R12, R3, #104 /* PSP+104 = Stack pointer of the task before entering the exception */ - PUSH {R12} /* push task SP to MSP */ - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK of the current running task to MSP */ - VPUSH {D8-D15} /* push D8-D15 of the currnent running task to MSP */ - - /* Copy stack frame from the stack of the current running task to MSP */ - LDMFD R3!, {R4-R11} /* restore stack frame[R0-xPSR] of PSP to R4-R11 */ - VLDMIA R3!, {D8-D15} /* restore stack frame[D0-D7] of PSP to D8-D15 */ - VSTMDB R2!, {D8-D15} /* save stack frame[D0-D7] to MSP */ - STMFD R2!, {R4-R11} /* save stack frame[R0-xPSR] to MSP */ - LDMFD R3, {R4-R5} /* restore stack frame[FPSCR,NO_NAME] to R4-R5 */ - ADD R2, R2, #104 /* skip stack frame */ - STMFD R2, {R4-R5} /* save stack frame[FPSCR,NO_NAME] to MSP */ - B _handleEntry - - /** - * Before executing _handleEntry, MSP is as follows. - * MSP: - * High addr--->| - * +--------------------------------------------------------------------------------+--------- - * | R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR | - * +--------------------------------------------------------------------------------+--------- - * R13--->| |<--- #32 --->|<---Initial R13 - * | (copied from PSP) | - * |<---R2(no use) - * - * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR. - */ -_NoFloatInPsp: - MOV R2, R13 - SUB R13, #32 /* #32: MSP reserved, used to store stack frame in PSP */ - - MRS R3, PSP - ADD R12, R3, #32 /* PSP+32 = Stack pointer of the task before entering the exception */ - PUSH {R12} /* push task SP to MSP */ - - MRS R12, PRIMASK - PUSH {R4-R12} /* push R4-R11,PRIMASK of the current running task to MSP */ - - /* Copy stack frame from the stack of the current running task to MSP */ - LDMFD R3, {R4-R11} /* restore stack frame of PSP to R4-R11 */ - STMFD R2!, {R4-R11} /* save stack frame to MSP */ - ORR R0, R0, #FLAG_NO_FLOAT /* R0[b28] = 1, no FPU &&&&&&&&&& */ - - /** - * _handleEntry: Call osExcHandleEntry - * param1: R0 --- b28: FLAG_NO_FLOAT. - * b17: FLAG_HWI_ACTIVE. - * b16: FLAG_ADDR_VALID. - * b15-b8: Error state code in table g_uwExcTbl or HF_DEBUGEVT or HF_VECTBL. - * b7-b0: OS_EXC_CAUSE_HARDFAULT or OS_EXC_CAUSE_NMI or OS_EXC_CAUSE_MEMFAULT - * or OS_EXC_CAUSE_BUSFAULT or OS_EXC_CAUSE_USAGEFAULT. - * param2: R1 --- The value of BFAR or MMFAR if R0[b16] = 1, otherwise invalid. - * param3: R2 --- external interrupt number(0-239) if R0[b17] = 1, otherwise invalid. - * param4: R3 --- Point to the top of the stack(R4 or S16) that the exception stack frame in MSP. - */ -_handleEntry: - MOV R3, R13 - CPSID I - CPSID F - B osExcHandleEntry - - NOP diff --git a/arch/arm/arm-m/cortex-m7/iar/los_dispatch_iar.S b/arch/arm/arm-m/cortex-m7/iar/los_dispatch_iar.S deleted file mode 100644 index 402973aad..000000000 --- a/arch/arm/arm-m/cortex-m7/iar/los_dispatch_iar.S +++ /dev/null @@ -1,366 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2016-2018>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT LOS_IntLock - EXPORT LOS_IntUnLock - EXPORT LOS_IntRestore - EXPORT LOS_StartToRun - EXPORT osTaskSchedule - EXPORT PendSV_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT g_stLosTask - IMPORT g_pfnTskSwitchHook - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt Control and State Register. -OS_NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. - -OS_NVIC_SYSPRI2 EQU 0xE000ED20 ; System Handler Priority Register 2. -OS_NVIC_PENDSV_SYSTICK_PRI EQU 0xFFFF0000 ; SysTick + PendSV priority level (lowest). - -OS_TASK_STATUS_RUNNING EQU 0x0010 ; Task Status Flag (RUNNING). - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - SECTION .text:CODE(2) - THUMB - REQUIRE8 - PRESERVE8 - -;**************************************************************************************** -; Function: -; VOID LOS_StartToRun(VOID); -; Description: -; Start the first task, which is the highest priority task in the priority queue. -; Other tasks are started by task scheduling. -;**************************************************************************************** -LOS_StartToRun - CPSID I - - ;/** - ; * Set PendSV and SysTick prority to the lowest. - ; * read ---> modify ---> write-back. - ; */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORR R1, R1, R2 - STR R1, [R0] - - ;/** - ; * Set g_bTaskScheduled = 1. - ; */ - LDR R0, =g_bTaskScheduled - MOV R1, #1 - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - ; */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - ; */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOV R3, #OS_TASK_STATUS_RUNNING - ORR R2, R2, R3 - STRH R2, [R1, #4] - - ;/** - ; * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - ; * [Initial EXC_RETURN ignore,] return by setting the CONTROL register. - ; * - ; * The initial stack of the current running task is as follows: - ; * - ; * POP: Restore the context of the current running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - ; * |<--- skip --->|<--- copy to R0-R7 --->| - ; * R12 to PSP--->| - ; * Stack pointer after LOS_StartToRun--->| - ; */ - LDR R12, [R1] - ADD R12, R12, #36 ; skip R4-R11, PRIMASK. -#if defined (__ARMVFP__) - ADD R12, R12, #4 ; if FPU exist, skip EXC_RETURN. -#endif - LDMFD R12!, {R0-R7} - - ;/** - ; * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - ; */ - MSR PSP, R12 - - ;/** - ; * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - ; */ - MOV R12, #2 - MSR CONTROL, R12 - - ;/** - ; * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - ; */ - MOV LR, R5 - CPSIE I - - ;/** - ; * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - ; * of the main function will be destroyed and will never be returned. - ; */ - BX R6 - -;**************************************************************************************** -; Function: -; UINTPTR LOS_IntLock(VOID); -; Description: -; Disable all interrupts except Reset,NMI and HardFault. -; The value of currnet interruption state will be returned to the caller to save. -; -; Function: -; VOID LOS_IntRestore(UINTPTR uvIntSave); -; Description: -; Restore the locked interruption of LOS_IntLock. -; The caller must pass in the value of interruption state previously saved. -;**************************************************************************************** -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 - -;**************************************************************************************** -; Function: -; VOID osTaskSchedule(VOID); -; Description: -; Start the task swtich process by software trigger PendSV interrupt. -;**************************************************************************************** -osTaskSchedule - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -;**************************************************************************************** -; Function: -; VOID PendSV_Handler(VOID); -; Description: -; PendSV interrupt handler, switch the context of the task. -; First: Save the context of the current running task(g_stLosTask.pstRunTask) -; to its own stack. -; Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -; from its own stack. -;**************************************************************************************** -PendSV_Handler - ;/** - ; * R12: Save the interruption state of the current running task. - ; * Disable all interrupts except Reset,NMI and HardFault - ; */ - MRS R12, PRIMASK - CPSID I - - ;/** - ; * Call task switch hook. - ; */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CBZ R2, TaskSwitch - PUSH {R12, LR} - BLX R2 - POP {R12, LR} - -TaskSwitch - ;/** - ; * R0 = now stack pointer of the current running task. - ; */ - MRS R0, PSP - - ;/** - ; * Save the stack frame([S16-S31],R4-R11) of the current running task. - ; * R12 save the PRIMASK value of the current running task. - ; * NOTE: 1. Before entering the exception handler function, these registers - ; * ([NO_NAME,FPSCR,S15-S0],xPSR,PC,LR,R12,R3-R0) have been automatically - ; * saved by the CPU in the stack of the current running task. - ; * 2. If lazy stacking is enabled, space is reserved on the stack for - ; * the floating-point context(FPSCR,S15-S0), but the floating-point state - ; * is not saved. when the floating-point instruction(VSTMDBEQ R0!, {D8-D15}) - ; * is executed, the floating-point context(FPSCR,S15-S0) is first saved into - ; * the space reserved on the stack. In other words, the instruction - ; * 'VSTMDBEQ R0!, {D8-D15}' will trigger the CPU to save 'FPSCR,S15-S0' first. - ; * - ; * The stack of the current running task is as follows: - ; * - ; * |<=== PUSH: Save the context of the current running task - ; * | High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * | [ lazy stacking ]| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * Stack pointer before entering exception--->| - ; * |<--- cpu auto saved --->| - ; * |<---PSP to R0 - ; * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - ; */ -#if defined (__ARMVFP__) ; if FPU exist. - TST R14, #0x10 ; if the task using the FPU context, push s16-s31. - IT EQ - VSTMDBEQ R0!, {D8-D15} - STMFD R0!, {R14} ; save EXC_RETURN. -#endif - STMFD R0!, {R4-R12} ; save the core registers and PRIMASK. - - ;/** - ; * R5,R8. - ; */ - LDR R5, =g_stLosTask - MOV R8, #OS_TASK_STATUS_RUNNING - - ;/** - ; * Save the stack pointer of the current running task to TCB. - ; * (g_stLosTask.pstRunTask->pStackPointer = R0) - ; */ - LDR R6, [R5] - STR R0, [R6] - - ;/** - ; * Clear the RUNNING state of the current running task. - ; * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R6, #4] - BIC R7, R7, R8 - STRH R7, [R6, #4] - - ;/** - ; * Switch the current running task to the next running task. - ; * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - ; */ - LDR R0, [R5, #4] - STR R0, [R5] - - ;/** - ; * Set the RUNNING state of the next running task. - ; * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R0, #4] - ORR R7, R7, R8 - STRH R7, [R0, #4] - - ;/** - ; * Restore the stack pointer of the next running task from TCB. - ; * (R1 = g_stLosTask.pstNewTask->pStackPointer) - ; */ - LDR R1, [R0] - - ;/** - ; * Restore the stack frame(R4-R11,[S16-S31]) of the next running task. - ; * R12 restore the PRIMASK value of the next running task. - ; * NOTE: After exiting the exception handler function, these registers - ; * (PC,xPSR,R0-R3,R12,LR,[S0-S15,FPSCR,NO_NAME]) will be automatically - ; * restored by the CPU from the stack of the next running task. - ; * - ; * 1. The stack of the next running task is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * --+-----------------------------------+-------------------------------------------+--- - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; * - ; * 2. If the next running task is run for the first time, the stack is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; */ - LDMFD R1!, {R4-R12} ; restore the core registers and PRIMASK. -#if defined (__ARMVFP__) ; if FPU exist. - LDMFD R1!, {R14} ; restore EXC_RETURN. - TST R14, #0x10 ; if the task using the FPU context, pop s16-s31. - IT EQ - VLDMIAEQ R1!, {D8-D15} -#endif - - ;/** - ; * Set the stack pointer of the next running task to PSP. - ; */ - MSR PSP, R1 - - ;/** - ; * Restore the interruption state of the next running task. - ; */ - MSR PRIMASK, R12 - BX LR - - END - diff --git a/arch/arm/arm-m/cortex-m7/keil/los_dispatch_keil.S b/arch/arm/arm-m/cortex-m7/keil/los_dispatch_keil.S deleted file mode 100644 index 81ac8a61c..000000000 --- a/arch/arm/arm-m/cortex-m7/keil/los_dispatch_keil.S +++ /dev/null @@ -1,367 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2016-2018>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT LOS_IntLock - EXPORT LOS_IntUnLock - EXPORT LOS_IntRestore - EXPORT LOS_StartToRun - EXPORT osTaskSchedule - EXPORT PendSV_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT g_stLosTask - IMPORT g_pfnTskSwitchHook - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt Control and State Register. -OS_NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. - -OS_NVIC_SYSPRI2 EQU 0xE000ED20 ; System Handler Priority Register 2. -OS_NVIC_PENDSV_SYSTICK_PRI EQU 0xFFFF0000 ; SysTick + PendSV priority level (lowest). - -OS_TASK_STATUS_RUNNING EQU 0x0010 ; Task Status Flag (RUNNING). - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - AREA |.text|, CODE, READONLY - THUMB - REQUIRE8 - PRESERVE8 - -;**************************************************************************************** -; Function: -; VOID LOS_StartToRun(VOID); -; Description: -; Start the first task, which is the highest priority task in the priority queue. -; Other tasks are started by task scheduling. -;**************************************************************************************** -LOS_StartToRun - CPSID I - - ;/** - ; * Set PendSV and SysTick prority to the lowest. - ; * read ---> modify ---> write-back. - ; */ - LDR R0, =OS_NVIC_SYSPRI2 - LDR R1, =OS_NVIC_PENDSV_SYSTICK_PRI - LDR R2, [R0] - ORR R1, R1, R2 - STR R1, [R0] - - ;/** - ; * Set g_bTaskScheduled = 1. - ; */ - LDR R0, =g_bTaskScheduled - MOV R1, #1 - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask = g_stLosTask.pstNewTask. - ; */ - LDR R0, =g_stLosTask - LDR R1, [R0, #4] - STR R1, [R0] - - ;/** - ; * Set g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_RUNNING. - ; */ - LDR R1, [R0] - LDRH R2, [R1, #4] - MOV R3, #OS_TASK_STATUS_RUNNING - ORR R2, R2, R3 - STRH R2, [R1, #4] - - ;/** - ; * Restore the default stack frame(R0-R3,R12,LR,PC,xPSR) of g_stLosTask.pstRunTask to R0-R7. - ; * [Initial EXC_RETURN ignore,] return by setting the CONTROL register. - ; * - ; * The initial stack of the current running task is as follows: - ; * - ; * POP: Restore the context of the current running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstRunTask->pStackPointer - ; * |<--- skip --->|<--- copy to R0-R7 --->| - ; * R12 to PSP--->| - ; * Stack pointer after LOS_StartToRun--->| - ; */ - LDR R12, [R1] - ADD R12, R12, #36 ; skip R4-R11, PRIMASK. - IF {FPU} != "SoftVFP" - ADD R12, R12, #4 ; if FPU exist, skip EXC_RETURN. - ENDIF - LDMFD R12!, {R0-R7} - - ;/** - ; * Set the stack pointer of g_stLosTask.pstRunTask to PSP. - ; */ - MSR PSP, R12 - - ;/** - ; * Set the CONTROL register, after schedule start, privilege level and stack = PSP. - ; */ - MOV R12, #2 - MSR CONTROL, R12 - - ;/** - ; * Enable interrupt. (The default PRIMASK value is 0, so enable directly) - ; */ - MOV LR, R5 - CPSIE I - - ;/** - ; * Jump directly to the default PC of g_stLosTask.pstRunTask, the field information - ; * of the main function will be destroyed and will never be returned. - ; */ - BX R6 - -;**************************************************************************************** -; Function: -; UINTPTR LOS_IntLock(VOID); -; Description: -; Disable all interrupts except Reset,NMI and HardFault. -; The value of currnet interruption state will be returned to the caller to save. -; -; Function: -; VOID LOS_IntRestore(UINTPTR uvIntSave); -; Description: -; Restore the locked interruption of LOS_IntLock. -; The caller must pass in the value of interruption state previously saved. -;**************************************************************************************** -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 - -;**************************************************************************************** -; Function: -; VOID osTaskSchedule(VOID); -; Description: -; Start the task swtich process by software trigger PendSV interrupt. -;**************************************************************************************** -osTaskSchedule - LDR R0, =OS_NVIC_INT_CTRL - LDR R1, =OS_NVIC_PENDSVSET - STR R1, [R0] - BX LR - -;**************************************************************************************** -; Function: -; VOID PendSV_Handler(VOID); -; Description: -; PendSV interrupt handler, switch the context of the task. -; First: Save the context of the current running task(g_stLosTask.pstRunTask) -; to its own stack. -; Second: Restore the context of the next running task(g_stLosTask.pstNewTask) -; from its own stack. -;**************************************************************************************** -PendSV_Handler - ;/** - ; * R12: Save the interruption state of the current running task. - ; * Disable all interrupts except Reset,NMI and HardFault - ; */ - MRS R12, PRIMASK - CPSID I - - ;/** - ; * Call task switch hook. - ; */ - LDR R2, =g_pfnTskSwitchHook - LDR R2, [R2] - CBZ R2, TaskSwitch - PUSH {R12, LR} - BLX R2 - POP {R12, LR} - -TaskSwitch - ;/** - ; * R0 = now stack pointer of the current running task. - ; */ - MRS R0, PSP - - ;/** - ; * Save the stack frame([S16-S31],R4-R11) of the current running task. - ; * R12 save the PRIMASK value of the current running task. - ; * NOTE: 1. Before entering the exception handler function, these registers - ; * ([NO_NAME,FPSCR,S15-S0],xPSR,PC,LR,R12,R3-R0) have been automatically - ; * saved by the CPU in the stack of the current running task. - ; * 2. If lazy stacking is enabled, space is reserved on the stack for - ; * the floating-point context(FPSCR,S15-S0), but the floating-point state - ; * is not saved. when the floating-point instruction(VSTMDBEQ R0!, {D8-D15}) - ; * is executed, the floating-point context(FPSCR,S15-S0) is first saved into - ; * the space reserved on the stack. In other words, the instruction - ; * 'VSTMDBEQ R0!, {D8-D15}' will trigger the CPU to save 'FPSCR,S15-S0' first. - ; * - ; * The stack of the current running task is as follows: - ; * - ; * |<=== PUSH: Save the context of the current running task - ; * | High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * | [ lazy stacking ]| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * Stack pointer before entering exception--->| - ; * |<--- cpu auto saved --->| - ; * |<---PSP to R0 - ; * |<---Top of the stack, save to g_stLosTask.pstRunTask->pStackPointer - ; */ - IF {FPU} != "SoftVFP" ; if FPU exist. - TST R14, #0x10 ; if the task using the FPU context, push s16-s31. - IT EQ - VSTMDBEQ R0!, {D8-D15} - STMFD R0!, {R14} ; save EXC_RETURN. - ENDIF - STMFD R0!, {R4-R12} ; save the core registers and PRIMASK. - - ;/** - ; * R5,R8. - ; */ - LDR R5, =g_stLosTask - MOV R8, #OS_TASK_STATUS_RUNNING - - ;/** - ; * Save the stack pointer of the current running task to TCB. - ; * (g_stLosTask.pstRunTask->pStackPointer = R0) - ; */ - LDR R6, [R5] - STR R0, [R6] - - ;/** - ; * Clear the RUNNING state of the current running task. - ; * (g_stLosTask.pstRunTask->usTaskStatus &= ~OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R6, #4] - BIC R7, R7, R8 - STRH R7, [R6, #4] - - ;/** - ; * Switch the current running task to the next running task. - ; * (g_stLosTask.pstRunTask = g_stLosTask.pstNewTask) - ; */ - LDR R0, [R5, #4] - STR R0, [R5] - - ;/** - ; * Set the RUNNING state of the next running task. - ; * (g_stLosTask.pstNewTask->usTaskStatus |= OS_TASK_STATUS_RUNNING) - ; */ - LDRH R7, [R0, #4] - ORR R7, R7, R8 - STRH R7, [R0, #4] - - ;/** - ; * Restore the stack pointer of the next running task from TCB. - ; * (R1 = g_stLosTask.pstNewTask->pStackPointer) - ; */ - LDR R1, [R0] - - ;/** - ; * Restore the stack frame(R4-R11,[S16-S31]) of the next running task. - ; * R12 restore the PRIMASK value of the next running task. - ; * NOTE: After exiting the exception handler function, these registers - ; * (PC,xPSR,R0-R3,R12,LR,[S0-S15,FPSCR,NO_NAME]) will be automatically - ; * restored by the CPU from the stack of the next running task. - ; * - ; * 1. The stack of the next running task is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * --+-----------------------------------+-------------------------------------------+--- - ; * | R4-R11,PRIMASK,EXC_RETURN,S16-S31 | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * --+-----------------------------------+-------------------------------------------+--- - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; * - ; * 2. If the next running task is run for the first time, the stack is as follows: - ; * - ; * POP: Restore the context of the next running task ===>| - ; * High addr--->| - ; * Bottom of the stack--->| - ; * ----------+---------------------------------+--------------------------------+ - ; * | R4-R11, PRIMASK, EXC_RETURN | R0-R3, R12, LR, PC, xPSR | - ; * ----------+---------------------------------+--------------------------------+ - ; * |<---Top of the stack, restored from g_stLosTask.pstNewTask->pStackPointer - ; * R1 to PSP--->| - ; * |<--- cpu auto restoring --->| - ; * Stack pointer after exiting exception--->| - ; */ - LDMFD R1!, {R4-R12} ; restore the core registers and PRIMASK. - IF {FPU} != "SoftVFP" ; if FPU exist. - LDMFD R1!, {R14} ; restore EXC_RETURN. - TST R14, #0x10 ; if the task using the FPU context, pop s16-s31. - IT EQ - VLDMIAEQ R1!, {D8-D15} - ENDIF - - ;/** - ; * Set the stack pointer of the next running task to PSP. - ; */ - MSR PSP, R1 - - ;/** - ; * Restore the interruption state of the next running task. - ; */ - MSR PRIMASK, R12 - BX LR - - ALIGN - END - diff --git a/arch/arm/arm-m/cortex-m7/keil/los_hw_exc_keil.S b/arch/arm/arm-m/cortex-m7/keil/los_hw_exc_keil.S deleted file mode 100644 index 07a6acad9..000000000 --- a/arch/arm/arm-m/cortex-m7/keil/los_hw_exc_keil.S +++ /dev/null @@ -1,548 +0,0 @@ -;---------------------------------------------------------------------------- - ; Copyright (c) <2013-2015>, - ; 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. - ;---------------------------------------------------------------------------*/ -;---------------------------------------------------------------------------- - ; Notice of Export Control Law - ; =============================================== - ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might - ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - ; applicable export control laws and regulations. - ;---------------------------------------------------------------------------*/ - -;**************************************************************************************** -; CODE GENERATION DIRECTIVES -;**************************************************************************************** - - PRESERVE8 - AREA |.text|, CODE, READONLY - THUMB - -;**************************************************************************************** -; EXPORT FUNCTIONS -;**************************************************************************************** - - EXPORT NMI_Handler - EXPORT HardFault_Handler - EXPORT MemManage_Handler - EXPORT BusFault_Handler - EXPORT UsageFault_Handler - EXPORT SVC_Handler - -;**************************************************************************************** -; EXTERN PARAMETERS -;**************************************************************************************** - - IMPORT osExcHandleEntry - IMPORT g_uwExcTbl - IMPORT g_bTaskScheduled - -;**************************************************************************************** -; EQU -;**************************************************************************************** - -OS_EXC_CAUSE_NMI EQU 18 -OS_EXC_CAUSE_HARDFAULT EQU 19 -OS_EXC_CAUSE_MEMFAULT EQU 20 -OS_EXC_CAUSE_BUSFAULT EQU 21 -OS_EXC_CAUSE_USAGEFAULT EQU 22 -OS_EXC_CAUSE_SVC EQU 23 - -HF_DEBUGEVT EQU 24 -HF_VECTBL EQU 25 - -FLAG_ADDR_VALID EQU 0x10000 ; bit 16 -FLAG_HWI_ACTIVE EQU 0x20000 ; bit 17 -FLAG_NO_FLOAT EQU 0x10000000 ; bit 28 - -OS_NVIC_CFSR EQU 0xE000ED28 ; include BusFault/MemFault/UsageFault State Regeister -OS_NVIC_HFSR EQU 0xE000ED2C ; HardFault State Regeister -OS_NVIC_BFAR EQU 0xE000ED38 -OS_NVIC_MMFAR EQU 0xE000ED34 -OS_NVIC_ACT_BASE EQU 0xE000E300 -OS_NVIC_SHCSRS EQU 0xE000ED24 -OS_NVIC_SHCSR_MASK EQU 0xC00 ; SYSTICKACT and PENDSVACT - -;**************************************************************************************** -; Function: -; VOID NMI_Handler(VOID); -; Description: -; NMI Handler. -;**************************************************************************************** -NMI_Handler - ;/** - ; * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - ; * < R0 >: - ; * +------------------------------------------------------+------------------------+ - ; * | 31-8 | 7-0 | - ; * +------------------------------------------------------+------------------------+ - ; * | --- | OS_EXC_CAUSE_NMI | - ; * +------------------------------------------------------+------------------------+ - ; * < R1 >: invalid - ; */ - MOV R0, #OS_EXC_CAUSE_NMI - MOV R1, #0 - B osExcDispatch - -;**************************************************************************************** -; Function: -; VOID HardFault_Handler(VOID); -; Description: -; HardFault Handler. -;**************************************************************************************** -HardFault_Handler - ;/** - ; * Check HardFault state register. - ; * - ; * HFSR: - ; * +----------+--------+--------+--------+-------+ - ; * | 31 | 30 | 29 - 2 | 1 | 0 | - ; * +----------+--------+--------+--------+-------+ - ; * | DEBUGEVT | FORCED | -- | VECTBL | -- | - ; * +----------+--------+--------+--------+-------+ - ; */ - MOV R0, #OS_EXC_CAUSE_HARDFAULT - LDR R2, =OS_NVIC_HFSR - LDR R2, [R2] - - ;/** - ; * Check whether HardFault are triggered by debugging events. - ; * Before executing instruction 'BNE osExcDispatch', the value of R0 is as follows. - ; * < R0 >: - ; * +----------------------------------------+-------------+------------------------+ - ; * | 31-16 | 15-8 | 7-0 | - ; * +----------------------------------------+-------------+------------------------+ - ; * | --- | HF_DEBUGEVT | OS_EXC_CAUSE_HARDFAULT | - ; * +----------------------------------------+-------------+------------------------+ - ; * < R1 >: invalid - ; */ - MOV R1, #HF_DEBUGEVT - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x80000000 - BNE osExcDispatch ; DEBUGEVT - - ;/** - ; * Check whether HardFault is caused by the failure of the fetch vector. - ; * Before executing instruction 'BNE osExcDispatch', the value of R0 is as follows. - ; * < R0 >: - ; * +----------------------------------------+-------------+------------------------+ - ; * | 31-16 | 15-8 | 7-0 | - ; * +----------------------------------------+-------------+------------------------+ - ; * | --- | HF_VECTBL | OS_EXC_CAUSE_HARDFAULT | - ; * +----------------------------------------+-------------+------------------------+ - ; * < R1 >: invalid - ; */ - AND R0, R0, #0x000000FF - MOV R1, #HF_VECTBL - ORR R0, R0, R1, LSL #0x8 - TST R2, #0x00000002 - BNE osExcDispatch ; VECTBL - - ;/** - ; * If it`s not DEBUGEVT and VECTBL, that is FORCED, then read the CFSR register to - ; * check BusFault, MemFault and UsageFault. - ; * R0: OS_EXC_CAUSE_HARDFAULT - ; * - ; * CFSR: - ; * +----------------+--------+--------+ - ; * | 31-16 | 15-8 | 7-0 | - ; * +----------------+--------+--------+ - ; * | UFSR | BFSR | MFSR | - ; * +----------------+--------+--------+ - ; */ - AND R0, R0, #0x000000FF - - LDR R2, =OS_NVIC_CFSR - LDR R2, [R2] - - TST R2, #0x8000 ; BFSR->BFARVALID - BNE _HFBusFault ; BusFault - - TST R2, #0x80 ; MFSR->MMARVALID - BNE _HFMemFault ; MemFault - - ;/** - ; * BFARVALID and MMARVALID flag both invalid. - ; * R12: 0 --- The error address is invalid. - ; */ - MOV R12, #0 - B osHFExcCommonBMU - - ;/** - ; * BFARVALID flag valid, read BFAR register. - ; * R1 : BFAR value --- The address value of a bus error. - ; * R12: The error address is valid. - ; */ -_HFBusFault - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - B osHFExcCommonBMU - - ;/** - ; * MMARVALID flag valid, read MMFAR register. - ; * R1 : MMFAR value --- The address value of memory management error. - ; * R12: The error address is valid. - ; */ -_HFMemFault - LDR R1, =OS_NVIC_MMFAR - LDR R1, [R1] - MOV R12, #FLAG_ADDR_VALID - - ;/** - ; * osHFExcCommonBMU: --- Get specific error status from table g_uwExcTbl, stored in R0. - ; * Before executing instruction 'B osExcDispatch', the value of R0 is as follows. - ; * < R0 >: - ; * +-------------------+-----------------+------------------+------------------------+ - ; * | 31-17 | 16 | 15-8 | 7-0 | - ; * +-------------------+-----------------+------------------+------------------------+ - ; * | --- | FLAG_ADDR_VALID | Error state code | OS_EXC_CAUSE_HARDFAULT | - ; * | | or | in | | - ; * | | 0(invalid) | table g_uwExcTbl | | - ; * +-------------------+-----------------+------------------+------------------------+ - ; * < R1 >: The value of BFAR or MMFAR if the bit16(FLAG_ADDR_VALID) of R0 is set to 1, - ; * else invalid. - ; */ -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 - -;**************************************************************************************** -; Function: -; VOID SVC_Handler(VOID); -; Description: -; SVC Handler. -;**************************************************************************************** -SVC_Handler - TST LR, #0x4 ; EXC_RETURN[b2] --- PSP or MSP - ITE EQ - MRSEQ R0, MSP - MRSNE R0, PSP - LDR R1, [R0, #24] ; The PC value in the stack frame - LDRB R0, [R1, #-2] ; R0: The number of SVC (0 - 255) - MOV R1, #0 - ;B osExcDispatch -_SvcLoop - B _SvcLoop - -;**************************************************************************************** -; Function: -; VOID BusFault_Handler(VOID); -; Description: -; BusFault Handler. -;**************************************************************************************** -BusFault_Handler - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_BUSFAULT - - TST R0, #0x8000 ; BFSR->BFARVALID - BEQ _ExcBusNoADDR - - LDR R1, =OS_NVIC_BFAR - LDR R1, [R1] ; R1: The value of BFAR - MOV R12, #FLAG_ADDR_VALID ; R12: BusFault addr valid - AND R0, R0, #0x3F00 ; R0: Reserved the b13-b8 of the BFSR - B osExcCommonBMU - -_ExcBusNoADDR - MOV R12, #0 ; R12: BusFault addr invalid - AND R0, R0, #0x3F00 ; R0: Reserved the b13-b8 of the BFSR - B osExcCommonBMU - -;**************************************************************************************** -; Function: -; VOID MemManage_Handler(VOID); -; Description: -; MemManage Handler. -;**************************************************************************************** -MemManage_Handler - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_MEMFAULT - - TST R0, #0x80 ; MFSR->MMARVALID - BEQ _ExcMemNoADDR - - LDR R1, =OS_NVIC_MMFAR - LDR R1, [R1] ; R1: The value of MMFAR - MOV R12, #FLAG_ADDR_VALID ; R12: MemFault addr valid - AND R0, R0, #0x3B ; R0: Reserved the b5-b0 of the MFSR - B osExcCommonBMU - -_ExcMemNoADDR - MOV R12, #0 ; R12: MemFault addr invalid - AND R0, R0, #0x3B ; R0: Reserved the b5-b0 of the MFSR - B osExcCommonBMU - -;**************************************************************************************** -; Function: -; VOID UsageFault_Handler(VOID); -; Description: -; UsageFault Handler. -;**************************************************************************************** -UsageFault_Handler - LDR R0, =OS_NVIC_CFSR - LDR R0, [R0] - LDR R2, =OS_EXC_CAUSE_USAGEFAULT - - MOV R1, #0x030F - LSL R1, R1, #16 - AND R0, R0, R1 ; R0: reserved UFSR - MOV R12, #0 ; R12: Fault addr invalid - - ;/** - ; * osExcCommonBMU: BusFault_Handler,MemManage_Handler and UsageFault_Handler share. - ; * Get specific error status from table g_uwExcTbl, stored in R0. - ; * Before executing osExcDispatch, the value of R0 is as follows. - ; * < R0 >: - ; * +-------------------+-----------------+------------------+------------------------+ - ; * | 31-17 | 16 | 15-8 | 7-0 | - ; * +-------------------+-----------------+------------------+------------------------+ - ; * | --- | FLAG_ADDR_VALID | Error state code |OS_EXC_CAUSE_BUSFAULT or| - ; * | | or | in |OS_EXC_CAUSE_MEMFAULT or| - ; * | | 0(invalid) | table g_uwExcTbl |OS_EXC_CAUSE_USAGEFAULT | - ; * +-------------------+-----------------+------------------+------------------------+ - ; * < R1 >: The value of BFAR or MMFAR if the bit16(FLAG_ADDR_VALID) of R0 is set to 1, - ; * else invalid. - ; */ -osExcCommonBMU - CLZ R0, R0 - LDR R3, =g_uwExcTbl - ADD R3, R3, R0 - LDRB R0, [R3] - LSL R0, R0, #0x8 - ORR R0, R0, R2 - ORR R0, R0, R12 - - ;**************************************************************************************** - ; osExcDispatch: NMI_Handler, HardFault_Handler, SVC_Handler, BusFault_Handler, MemManage_Handler, - ; UsageFault_Handler sharing. - ;**************************************************************************************** - - ;/** - ; * When executing osExcDispatch, R0, R1 will be used. - ; * The possible values of R0 and R1 are as follows. - ; * - ; * < R0 >: - ; * +----------------+-----------------+---------------------+------------------------+ - ; * | 31-17 | 16 | 15-8 | 7-0 | - ; * +----------------+-----------------+---------------------+------------------------+ - ; * | | FLAG_ADDR_VALID | Error state code in | OS_EXC_CAUSE_HARDFAULT | - ; * | --- | or | table g_uwExcTbl |or OS_EXC_CAUSE_MEMFAULT| - ; * | | 0(invalid) | or HF_DEBUGEVT |or OS_EXC_CAUSE_BUSFAULT| - ; * | | | or HF_VECTBL |or OS_EXC_CAUSE_NMI or | - ; * | | | | OS_EXC_CAUSE_USAGEFAULT| - ; * +----------------+-----------------+---------------------+------------------------+ - ; * b17: FLAG_HWI_ACTIVE - ; * b28: FLAG_NO_FLOAT - ; * NOTE: b17 and b28 will be set later. - ; * - ; * < R1 >: - ; * If the bit16 of R0 is 1, then R1 is the value of BFAR or MMFAR, otherwise the - ; * value in R1 is invalid. - ; * - ; */ -osExcDispatch - LDR R2, =OS_NVIC_ACT_BASE - MOV R12, #8 ; #8: externel interrupt active check loop counter(#0 - #239) - -_hwiActiveCheck - LDR R3, [R2] ; R3 store the value of externel interrupt active status - CMP R3, #0 - BEQ _hwiActiveCheckNext - - ;/** - ; * Exception occured in external interrupt. - ; */ - ORR R0, R0, #FLAG_HWI_ACTIVE ; R0[b17] = 1, externel interrupt active valid &&&&&&&&&& - RBIT R2, R3 ; bit reversal - CLZ R2, R2 - RSB R12, R12, #8 ; R12 = 8 - R12 - ADD R2, R2, R12, LSL #5 ; R2: external interrupt number as uwPid - - ;/** - ; * Interrupts and initialization phase always use MSP. - ; */ -_ExcInMSP - TST LR, #0x10 ; EXC_RETURN[b4] --- FPU(0) or without FPU(1) - BNE _NoFloatInMsp - - ;/** - ; * Before executing instruction 'B _handleEntry', MSP is as follows. - ; * MSP: - ; * High addr--->| - ; * +--------------------------------------------------------------------------------+--------- - ; * | S16-S31,R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * +--------------------------------------------------------------------------------+--------- - ; * |<---R13 Initial R13--->|<--- #104 --->|<---SAVED_SP - ; * | (CPU auto saved) | - ; * - ; */ - ADD R3, R13, #104 ; #104: skip [R0-xPSR,D0-D7,FPSCR,NO_NAME] - PUSH {R3} ; push [SAVED_SP]: MSP+104 = Stack pointer in MSP before entering the exception - MRS R12, PRIMASK - PUSH {R4-R12} ; push R4-R11,PRIMASK to MSP - VPUSH {D8-D15} ; push D8-D15 to MSP - B _handleEntry - - ;/** - ; * Before executing instruction 'B _handleEntry', MSP is as follows. - ; * MSP: - ; * High addr--->| - ; * +--------------------------------------------------------------------------------+--------- - ; * | R4-R11,PRIMASK,SAVED_SP | R0-R3,R12,LR,PC,xPSR | - ; * +--------------------------------------------------------------------------------+--------- - ; * R13--->| Initial R13--->|<--- #32 --->|<---SAVED_SP - ; * | (CPU auto saved) | - ; * - ; */ -_NoFloatInMsp - ADD R3, R13, #32 ; #32: skip [R0-R3,R12,LR,PC,xPSR] - PUSH {R3} ; push [SAVED_SP]: MSP+32 = Stack pointer in MSP before entering the exception - MRS R12, PRIMASK - PUSH {R4-R12} ; push R4-R11,PRIMASK to MSP - ORR R0, R0, #FLAG_NO_FLOAT ; R0[b28] = 1, no FPU &&&&&&&&&& - B _handleEntry - -_hwiActiveCheckNext - ADD R2, R2, #4 ; next NVIC ACT ADDR - SUBS R12, R12, #1 - BNE _hwiActiveCheck - - ;/** - ; * Not in externel interrupt, check whether it is SysTick or PendSV. - ; */ - LDR R2, =OS_NVIC_SHCSRS - LDRH R2,[R2] - LDR R3,=OS_NVIC_SHCSR_MASK - AND R2, R2, R3 - CMP R2, #0 - BNE _ExcInMSP ; SysTick or PendSV active - - ;/** - ; * Check whether an exception occurs during the initialization phase. - ; * If g_bTaskScheduled == 0, it is in the initialization phase. - ; */ - LDR R2, =g_bTaskScheduled - LDR R2, [R2] - TST R2, #1 - BEQ _ExcInMSP ; initialization phase use MSP - - ;/** - ; * Exception occured in Task. - ; */ - TST LR, #0x10 - BNE _NoFloatInPsp - - ;/** - ; * Before executing _handleEntry, MSP is as follows. - ; * MSP: - ; * High addr--->| - ; * +--------------------------------------------------------------------------------+--------- - ; * | S16-S31,R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME | - ; * +--------------------------------------------------------------------------------+--------- - ; * |<---R13 |<--- #104 --->|<---Initial R13 - ; * | (copied from PSP) | - ; * R2(no use)--->| - ; * - ; * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR,NO_NAME. - ; */ - MOV R2, R13 - SUB R2, R2, #8 ; #8: reserved for [FPSCR,NO_NAME] - SUB R13, #104 ; #104: MSP reserved, used to store stack frame in PSP - - MRS R3, PSP - ADD R12, R3, #104 ; PSP+104 = Stack pointer of the task before entering the exception - PUSH {R12} ; push task SP to MSP - MRS R12, PRIMASK - PUSH {R4-R12} ; push R4-R11,PRIMASK of the current running task to MSP - VPUSH {D8-D15} ; push D8-D15 of the currnent running task to MSP - - ;/* Copy stack frame from the stack of the current running task to MSP */ - LDMFD R3!, {R4-R11} ; restore stack frame[R0-xPSR] of PSP to R4-R11 - VLDMIA R3!, {D8-D15} ; restore stack frame[D0-D7] of PSP to D8-D15 - VSTMDB R2!, {D8-D15} ; save stack frame[D0-D7] to MSP - STMFD R2!, {R4-R11} ; save stack frame[R0-xPSR] to MSP - LDMFD R3, {R4-R5} ; restore stack frame[FPSCR,NO_NAME] to R4-R5 - ADD R2, R2, #104 ; skip stack frame - STMFD R2, {R4-R5} ; save stack frame[FPSCR,NO_NAME] to MSP - B _handleEntry - - ;/** - ; * Before executing _handleEntry, MSP is as follows. - ; * MSP: - ; * High addr--->| - ; * +--------------------------------------------------------------------------------+--------- - ; * | R4-R11,PRIMASK,TASK_SP | R0-R3,R12,LR,PC,xPSR | - ; * +--------------------------------------------------------------------------------+--------- - ; * R13--->| |<--- #32 --->|<---Initial R13 - ; * | (copied from PSP) | - ; * |<---R2(no use) - ; * - ; * NOTE: stack frame: R0-R3,R12,LR,PC,xPSR. - ; */ -_NoFloatInPsp - MOV R2, R13 - SUB R13, #32 ; #32: MSP reserved, used to store stack frame in PSP - - MRS R3, PSP - ADD R12, R3, #32 ; PSP+32 = Stack pointer of the task before entering the exception - PUSH {R12} ; push task SP to MSP - - MRS R12, PRIMASK - PUSH {R4-R12} ; push R4-R11,PRIMASK of the current running task to MSP - - ;/* Copy stack frame from the stack of the current running task to MSP */ - LDMFD R3, {R4-R11} ; restore stack frame of PSP to R4-R11 - STMFD R2!, {R4-R11} ; save stack frame to MSP - ORR R0, R0, #FLAG_NO_FLOAT ; R0[b28] = 1, no FPU &&&&&&&&&& - - ;/** - ; * _handleEntry: Call osExcHandleEntry - ; * param1: R0 --- b28: FLAG_NO_FLOAT. - ; * b17: FLAG_HWI_ACTIVE. - ; * b16: FLAG_ADDR_VALID. - ; * b15-b8: Error state code in table g_uwExcTbl or HF_DEBUGEVT or HF_VECTBL. - ; * b7-b0: OS_EXC_CAUSE_HARDFAULT or OS_EXC_CAUSE_NMI or OS_EXC_CAUSE_MEMFAULT - ; * or OS_EXC_CAUSE_BUSFAULT or OS_EXC_CAUSE_USAGEFAULT. - ; * param2: R1 --- The value of BFAR or MMFAR if R0[b16] = 1, otherwise invalid. - ; * param3: R2 --- external interrupt number(0-239) if R0[b17] = 1, otherwise invalid. - ; * param4: R3 --- Point to the top of the stack(R4 or S16) that the exception stack frame in MSP. - ; */ -_handleEntry - MOV R3, R13 - CPSID I - CPSID F - B osExcHandleEntry - - NOP - ALIGN - END diff --git a/arch/arm/arm-m/cortex-m7/los_exc.c b/arch/arm/arm-m/cortex-m7/los_exc.c deleted file mode 100644 index 3e29cf9ad..000000000 --- a/arch/arm/arm-m/cortex-m7/los_exc.c +++ /dev/null @@ -1,621 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - - -#include "los_exc.inc" -#include "los_task.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ -//extern ST_LOS_TASK g_stLosTask; -#if (LOSCFG_PLATFORM_EXC == YES) - -UINT32 g_uwCurNestCount = 0; -EXC_INFO_S m_stExcInfo; -/* - * CFSR register, include UFSR,BFSR and MFSR. - * - * +----------------------------------------------------------------------------------+ - * | UFSR | - * |-----------+-----------+-----------+-------+------+-------+----------+------------| - * | 31 - 26 | 25 | 24 | 23-20 | 19 | 18 | 17 | 16 | - * |-----------+-----------+-----------+-------+------+-------+----------+------------| - * | --- | DIVBYZERO | UNALIGNED | --- | NOCP | INVPC | INVSTATE | UNDEFINSTR | - * +----------------------------------------------------------------------------------+ - * - * +----------------------------------------------------------------------------------+ - * | BFSR | - * |-----------+-----+--------+--------+----------+-------------+-----------+---------| - * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | - * |-----------+-----+--------+--------+----------+-------------+-----------+---------| - * | BFARVALID | --- | LSPERR | STKERR | UNSTKERR | IMPRECISERR | PRECISERR | IBUSERR | - * +----------------------------------------------------------------------------------+ - * - * +----------------------------------------------------------------------------------+ - * | MFSR | - * |-----------+-------+---------+---------+-----------+-------+----------+-----------| - * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - * |-----------+-------+---------+---------+-----------+-------+----------+-----------| - * | MMARVALID | --- | MLSPERR | MSTKERR | MUNSTKERR | --- | DACCVIOL | ICACCVIOL | - * +----------------------------------------------------------------------------------+ - */ -UINT8 g_uwExcTbl[32] = -{ - 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, OS_EXC_BF_LSPERR, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, - 0, 0, OS_EXC_MF_MLSPERR, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL -}; - -#if (LOSCFG_SAVE_EXC_INFO == YES) -VOID *m_puwExcContent; -UINT32 g_uwArraySize = 0; -EXC_INFO_ARRAY_S m_stExcArray[OS_EXC_TYPE_MAX - 1]; -static VOID osExcSave2DDR(VOID); -#endif - -extern VOID LOS_Reboot(VOID); - -/***************************************************************************** - Function : osExcInfoDisplay - Description : EXC info display - Input : pstExc --- Pointer to the EXC data - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcInfoDisplay(EXC_INFO_S *pstExc) -{ - PRINT_ERR("Phase = 0x%x\n", pstExc->usPhase); - PRINT_ERR("Type = 0x%x\n", pstExc->usType); - PRINT_ERR("FaultAddr = 0x%x\n", pstExc->uwFaultAddr); - PRINT_ERR("ThrdPid = 0x%x\n", pstExc->uwThrdPid); - PRINT_ERR("R0 = 0x%x\n", pstExc->pstContext->uwR0); - PRINT_ERR("R1 = 0x%x\n", pstExc->pstContext->uwR1); - PRINT_ERR("R2 = 0x%x\n", pstExc->pstContext->uwR2); - PRINT_ERR("R3 = 0x%x\n", pstExc->pstContext->uwR3); - PRINT_ERR("R4 = 0x%x\n", pstExc->pstContext->uwR4); - PRINT_ERR("R5 = 0x%x\n", pstExc->pstContext->uwR5); - PRINT_ERR("R6 = 0x%x\n", pstExc->pstContext->uwR6); - PRINT_ERR("R7 = 0x%x\n", pstExc->pstContext->uwR7); - PRINT_ERR("R8 = 0x%x\n", pstExc->pstContext->uwR8); - PRINT_ERR("R9 = 0x%x\n", pstExc->pstContext->uwR9); - PRINT_ERR("R10 = 0x%x\n", pstExc->pstContext->uwR10); - PRINT_ERR("R11 = 0x%x\n", pstExc->pstContext->uwR11); - PRINT_ERR("R12 = 0x%x\n", pstExc->pstContext->uwR12); - PRINT_ERR("PriMask = 0x%x\n", pstExc->pstContext->uwPriMask); - PRINT_ERR("SP = 0x%x\n", pstExc->pstContext->uwSP); - PRINT_ERR("LR = 0x%x\n", pstExc->pstContext->uwLR); - PRINT_ERR("PC = 0x%x\n", pstExc->pstContext->uwPC); - PRINT_ERR("xPSR = 0x%x\n", pstExc->pstContext->uwxPSR); - - PRINT_ERR("\nplease use the addr2line tool to analyze the call stack on PC:\n"); - PRINT_ERR("addr2line -e (xxx.axf/xxx.elf/xxx.out) -a -f "); - for (UINT32 i = 0; i < pstExc->uwCallStackDepth; i++) - { - printf("%#x ", pstExc->uwCallStack[i]); - } - printf("\n"); - - return; -} - -/***************************************************************************** - Function : osExcCallStackAnalysis - Description : Call stack analysis - Input : pstExc --- point to exception info - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcCallStackAnalysis(EXC_INFO_S *pstExc) -{ - UINT32 uwSP; - UINT32 uwLR; - UINT32 uwPC; - UINT32 uwStackStartAddr; - UINT32 uwStackSize; - UINT32 uwDepth = 0; - BOOL bFirstLrValid = FALSE; - - uwSP = pstExc->pstContext->uwSP; /* sp pointer before entering exception */ - - /* - * save first and second depth - * first: PC before entering exception - * second: (LR - 4) before entering exception - * NOTE: If an exception occurs in the interrupt, LR may be EXC_RETURN, so we must make sure - * that LR is valid, exclude EXC_RETURN. - */ - pstExc->uwCallStack[uwDepth++] = pstExc->pstContext->uwPC; - if ((pstExc->pstContext->uwLR >= LOSCFG_EXC_CODE_START_ADDR) && \ - (pstExc->pstContext->uwLR <= LOSCFG_EXC_CODE_START_ADDR + LOSCFG_EXC_CODE_SIZE)) - { - pstExc->uwCallStack[uwDepth++] = pstExc->pstContext->uwLR - sizeof(VOID *); /* lr = pc + 4 */ - bFirstLrValid = TRUE; - } - - /* - * get the start address and size of the stack before entering the exception - */ - if (pstExc->usPhase == OS_EXC_IN_TASK) /* task use PSP */ - { - uwStackStartAddr = g_stLosTask.pstRunTask->uwTopOfStack; - uwStackSize = g_stLosTask.pstRunTask->uwStackSize; - } - else /* init and interrupt use MSP */ - { - uwStackStartAddr = LOSCFG_EXC_MSP_START_ADDR; - uwStackSize = LOSCFG_EXC_MSP_SIZE; - } - - /* - * check stack overflow, if so, compensate for overflow, readjust stack start address and size. - */ - if (uwSP < uwStackStartAddr) /* stack top overflow */ - { - if (pstExc->usPhase == OS_EXC_IN_TASK) - { - PRINT_ERR("task %s stack top overflow\n", g_stLosTask.pstRunTask->pcTaskName); - } - else - { - PRINT_ERR("MSP top overflow\n"); - } - uwStackSize += (uwStackStartAddr - uwSP); /* compensate overflow size */ - uwStackStartAddr = uwSP; /* readjust stack start address */ - } - - /* - * Traverses the entire stack from the top of the stack to the bottom of the stack, - * find all LR. - */ - for (; uwSP < uwStackStartAddr + uwStackSize; uwSP += sizeof(UINT32)) - { - uwLR = *(UINT32 *)uwSP; - if (uwLR % 2 == 0) /* Thumb instruction, LR bit0 == 1 */ - { - continue; - } - - /* - * It may be LR, which must be further determined based on the start address - * and end address of the code segment. - */ - if ((uwLR >= LOSCFG_EXC_CODE_START_ADDR) && (uwLR <= LOSCFG_EXC_CODE_START_ADDR + LOSCFG_EXC_CODE_SIZE) \ - && (uwDepth < LOSCFG_EXC_CALL_STACK_ANALYSIS_MAX_DEPTH)) - { - uwPC = uwLR - sizeof(VOID *); /* lr = pc + 4 */ - /* the second depth(first LR) has been saved */ - if ((uwDepth == 2) && (uwPC == pstExc->uwCallStack[1]) && (bFirstLrValid == TRUE)) - { - continue; - } - pstExc->uwCallStack[uwDepth++] = uwPC; - } - } - pstExc->uwCallStackDepth = uwDepth; /* save call stack depth */ - - return; -} - -/***************************************************************************** - Function : osExcHandleEntry - Description : EXC handler entry - Input : uwExcType --- EXC type - : uwFaultAddr --- The address of an accurate address access error - : uwPid --- Interrupt number - : puwExcBufAddr --- Point to the stack frame without FPU - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osExcHandleEntry(UINT32 uwExcType, UINT32 uwFaultAddr, UINT32 uwPid, EXC_CONTEXT_S *pstExcBufAddr) -{ - /* uwExcType high 16 bits: 0x01 - uwFaultAddr valid, 0x02 - in hwi */ - UINT16 usTmpFlag = (uwExcType >> 16) & 0xFFFF; - - g_uwCurNestCount++; -#if (LOSCFG_PLATFORM_HWI == YES) - extern UINT32 g_vuwIntCount; - g_vuwIntCount++; -#endif - - /* Save interrupt nesting times */ - m_stExcInfo.usNestCnt = (UINT16)g_uwCurNestCount; - /* uwExcType low 16 bits: exc type */ - m_stExcInfo.usType = (UINT16)uwExcType & 0xFFFF; -#if (LOSCFG_SAVE_EXC_INFO == YES) - /* Initializing a pointer to save an exception context */ - m_puwExcContent = (UINT32 *)m_aucTaskArray; -#endif - - /* Save the fault address when an exception occurs if it is valid */ - if (usTmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) - { - m_stExcInfo.uwFaultAddr = uwFaultAddr; - } - else - { - m_stExcInfo.uwFaultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; - } - - /* Save the phase of the exception */ - extern BOOL g_bTaskScheduled; - if (g_bTaskScheduled && (NULL != g_stLosTask.pstRunTask)) - { - if (usTmpFlag & OS_EXC_FLAG_IN_HWI) - { - m_stExcInfo.usPhase = OS_EXC_IN_HWI; - m_stExcInfo.uwThrdPid = uwPid; /* interrupt number */ - } - else - { - m_stExcInfo.usPhase = OS_EXC_IN_TASK; - m_stExcInfo.uwThrdPid = g_stLosTask.pstRunTask->uwTaskID; /* task id */ - } - } - else - { - m_stExcInfo.usPhase = OS_EXC_IN_INIT; - m_stExcInfo.uwThrdPid = 0xffffffff; - } - - /* uwExcType BIT_28: Wether or not to use FPU */ - if(uwExcType & OS_EXC_FLAG_NO_FLOAT) - { - m_stExcInfo.usFpuContext = 0; - #if FPU_EXIST - /* NOTE: S16-S31, S0-S15,FPSCR,NO_NAME invalid */ - m_stExcInfo.pstContext = (EXC_CONTEXT_S *)((UINT8 *)pstExcBufAddr - 64); /* point to S16 */ - #else - m_stExcInfo.pstContext = pstExcBufAddr; /* point to uwR4 */ - #endif - } - else - { - m_stExcInfo.usFpuContext = 1; - m_stExcInfo.pstContext = pstExcBufAddr; /* point to S16 */ - } - - osExcCallStackAnalysis(&m_stExcInfo); - -#if (LOSCFG_SAVE_EXC_INFO == YES) - osExcSave2DDR(); -#endif - - osExcInfoDisplay(&m_stExcInfo); - - LOS_Reboot(); -} - -#if (LOSCFG_SAVE_EXC_INFO == YES) -/***************************************************************************** - Function : osExcSaveIntStatus - Description : Save NVIC register group - Input : None - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSaveIntStatus(VOID) -{ - /* Save exc type */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_NVIC; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save total size of NVIC */ - *((UINT32 *)m_puwExcContent) = 0x164; // = OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + OS_NVIC_INT_ACT_SIZE + OS_NVIC_INT_PRI_SIZE + 12 + 4 + 4 - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save interrupt enable register group (start addr: 0xE000E100, size: 32bytes, CMSIS-Core: NVIC->ISER[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SETENA_BASE, OS_NVIC_INT_ENABLE_SIZE); - m_puwExcContent =(UINT8 *)m_puwExcContent + OS_NVIC_INT_ENABLE_SIZE; - - /* Save interrupt pend register group (start addr: 0xE000E200, size: 32bytes, CMSIS-Core: NVIC->ISPR[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SETPEND_BASE, OS_NVIC_INT_PEND_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_PEND_SIZE; - - /* Save interrupt active status register group (start addr: 0xE000E300, size: 32bytes, CMSIS-Core: NVIC->IABR[0 - 7]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_INT_ACT_BASE, OS_NVIC_INT_ACT_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_ACT_SIZE; - - /* Save interrupt priority register group (start addr: 0xE000E400, size: 240bytes), CMSIS-Core: NVIC->IP[0 - 239] */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_PRI_BASE, OS_NVIC_INT_PRI_SIZE); - m_puwExcContent = (UINT8 *)m_puwExcContent + OS_NVIC_INT_PRI_SIZE; - - /* Save system exception priority register group (start addr: 0xE000ED18, size: 12bytes, CMSIS-Core: SCB->SHP[0 - 11]) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_EXCPRI_BASE, 12); - m_puwExcContent = (UINT8 *)m_puwExcContent + 12; - - /* Save system processing control and state register group (start addr: 0xE000ED24, size: 4bytes, CMSIS-Core: SCB->SHCSR) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_SHCSR, 4); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save interrupt control and status register group (start addr: 0xE000ED04, size: 4bytes, CMSIS-Core: SCB->ICSR) */ - memcpy(m_puwExcContent, (const void *)OS_NVIC_INT_CTRL, 4); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - return; -} - -/***************************************************************************** - Function : osExcRegister - Description : Register exception - Input : uwType --- exception type - : pFunc --- exception callback function - : pArg --- exception save info arg, not pFunc - Output : None - Return : None - *****************************************************************************/ -VOID osExcRegister(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg) -{ - EXC_INFO_ARRAY_S *pstExcInfo; - - if (uwType == 0 || uwType >= OS_EXC_TYPE_MAX || pFunc == NULL) - { - PRINT_ERR("osExcRegister ERROR!\n"); - return; - } - - pstExcInfo = &(m_stExcArray[uwType - 1]); - pstExcInfo->uwType = uwType; - pstExcInfo->pFnExcInfoCb = pFunc; - pstExcInfo->pArg = pArg; - pstExcInfo->uwValid = TRUE; -} - -/***************************************************************************** - Function : osExcSaveSysInfo - Description : Saving exception information by calling callback function recursively - Input : uwType --- exception type(OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1) - : pFunc --- callback function - : uwLoop --- loop total count - : uwLen --- The size of the data saved each time - : uwIdx --- loop index - Output : None - Return : None - *****************************************************************************/ -VOID osExcSaveSysInfo(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, UINT32 uwLoop, UINT32 uwLen, UINT32 uwIdx) -{ - UINT32 uwRet; - UINT32 uwBuffer[OS_EXC_MAX_BUF_LEN]; - - /* Save exception type and size */ - *((UINT32 *)m_puwExcContent) = uwType; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - *((UINT32 *)m_puwExcContent) = uwLen * (uwLoop - uwIdx); - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - for (; uwIdx < uwLoop; uwIdx++) - { - memset((VOID *)uwBuffer, 0, sizeof(UINT32) * OS_EXC_MAX_BUF_LEN); - uwRet = pFunc(uwIdx, (VOID *)uwBuffer); - if (LOS_OK == uwRet) - { - memcpy(m_puwExcContent, (VOID *)uwBuffer, uwLen); - } - m_puwExcContent =(UINT8 *)m_puwExcContent + uwLen; - } -} - -/***************************************************************************** - Function : osExcSaveInfo - Description : save exception info - Input : uwType --- exception type(OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1) - : pFunc --- exception callback - : pArg --- register arg, used to generate the arg passed to the callback - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSaveInfo(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg) -{ - UINT32 uwLen; - UINT32 uwIdx; - UINT32 uwLoop; - UINT32 uwTaskSwitchCount = 0; - OS_TASK_SWITCH_INFO *pstTaskSwitchInfo; - - switch(uwType) - { - case OS_EXC_TYPE_TSK: /* save task info */ - uwLen = sizeof(TSK_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - case OS_EXC_TYPE_QUE: /* save queue info */ - uwLen = sizeof(QUEUE_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - case OS_EXC_TYPE_NVIC: /* save NVIC info */ - (VOID)pFunc(0, 0); - goto END; - - case OS_EXC_TYPE_TSK_SWITCH: /* save task switch info */ - pstTaskSwitchInfo = pArg; - uwTaskSwitchCount = pstTaskSwitchInfo->ucIsFull & 0x7F; - uwLen = sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN; /* auwPID + acName */ - if (pstTaskSwitchInfo->ucIsFull & 0x80) - { - uwIdx = pstTaskSwitchInfo->ucIdx; - uwLoop = uwIdx + uwTaskSwitchCount; - } - else - { - uwIdx = 0; - uwLoop = pstTaskSwitchInfo->ucIdx; - } - break; - - case OS_EXC_TYPE_MEM: /* save mem info */ - uwLen = sizeof(MEM_INFO_S); - uwLoop = *(UINT32 *)pArg; - uwIdx = 0; - break; - - default: - goto END; - } - osExcSaveSysInfo(uwType, (EXC_INFO_SAVE_CALLBACK)pFunc, uwLoop, uwLen, uwIdx); -END: - return; -} - -/***************************************************************************** - Function : osExcSave2DDR - Description : Save exception info to RAM - Input : None - Output : None - Return : None - *****************************************************************************/ -static VOID osExcSave2DDR(VOID) -{ - UINT32 uwIdx = 0; - UINT32 uwExcContextSize; - - if (m_stExcInfo.usFpuContext == 1) - { - uwExcContextSize = sizeof(EXC_CONTEXT_S); - } - else - { - uwExcContextSize = sizeof(EXC_CONTEXT_S) - 136; /* except FPU register */ - } - - memset(m_puwExcContent, 0xff, g_uwArraySize); - - /* Cortex-M type */ - *((UINT32 *)m_puwExcContent) = 4; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* - * Save exception type: OS_EXC_TYPE_CONTEXT - */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_CONTEXT; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* The size of struct EXC_INFO_S(except member EXC_CONTEXT_S*) and exception context size */ - *((UINT32 *)m_puwExcContent) = sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *) + uwExcContextSize; - m_puwExcContent = (UINT8 *)m_puwExcContent + 4; - - /* Save struct m_stExcInfo except m_stExcInfo.pstContext */ - memcpy((VOID *)m_puwExcContent, (VOID *)&m_stExcInfo, sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *)); - m_puwExcContent = (UINT8 *)m_puwExcContent + sizeof(EXC_INFO_S) - sizeof(EXC_CONTEXT_S *); - - /* Save struct EXC_CONTEXT_S */ - if (m_stExcInfo.usFpuContext == 0) - { - #if FPU_EXIST - /* m_stExcInfo.pstContext: init --- point to S16, S16->S31 invalid - * + 64 --- point to uwR4 - * copy uwR4 -> uwxPSR */ - memcpy((VOID *)m_puwExcContent, (UINT8 *)m_stExcInfo.pstContext + 64, uwExcContextSize); - #else - memcpy((VOID *)m_puwExcContent, m_stExcInfo.pstContext, uwExcContextSize); - #endif - } - else - { - memcpy((VOID *)m_puwExcContent, m_stExcInfo.pstContext, uwExcContextSize); - } - m_puwExcContent = (UINT8 *)m_puwExcContent + uwExcContextSize; - - /* - * Save exception type: OS_EXC_TYPE_CONTEXT+1 ---> OS_EXC_TYPE_MAX-1 - */ - for (uwIdx = 0; uwIdx < OS_EXC_TYPE_MAX - 1; uwIdx++) - { - if (m_stExcArray[uwIdx].uwValid == FALSE) - { - continue; - } - osExcSaveInfo(m_stExcArray[uwIdx].uwType, m_stExcArray[uwIdx].pFnExcInfoCb, m_stExcArray[uwIdx].pArg); - } - - /* - * Save exception type: OS_EXC_TYPE_MAX - */ - *((UINT32 *)m_puwExcContent) = OS_EXC_TYPE_MAX; - m_puwExcContent = (UINT8*)m_puwExcContent + 4; - - return; -} -#endif /*(LOSCFG_SAVE_EXC_INFO == YES)*/ - -/***************************************************************************** - Function : osExcInit - Description : Initializes the EXC - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID osExcInit(UINT32 uwArraySize) -{ -#if (LOSCFG_PLATFORM_HWI == YES) - /* Register exception handler to interrupt vector table in RAM */ - m_pstHwiForm[-14 + OS_SYS_VECTOR_CNT] = NMI_Handler; - m_pstHwiForm[-13 + OS_SYS_VECTOR_CNT] = HardFault_Handler; - m_pstHwiForm[-12 + OS_SYS_VECTOR_CNT] = MemManage_Handler; - m_pstHwiForm[-11 + OS_SYS_VECTOR_CNT] = BusFault_Handler; - m_pstHwiForm[-10 + OS_SYS_VECTOR_CNT] = UsageFault_Handler; - m_pstHwiForm[-5 + OS_SYS_VECTOR_CNT] = SVC_Handler; -#endif - - /* Enable USGFAULT(BIT_18), BUSFAULT(BIT_17), MEMFAULT(BIT_16) */ - *(volatile UINT32 *)OS_NVIC_SHCSR |= 0x70000; - - /* Enable DIV 0(BIT_4) exception, unaligned(BIT_3) disable */ - *(volatile UINT32 *)OS_NVIC_CCR |= 0x10; - -#if (LOSCFG_SAVE_EXC_INFO == YES) - g_uwArraySize = uwArraySize; - osExcRegister((EXC_INFO_TYPE)OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)osExcSaveIntStatus, NULL); -#endif -} - -VOID osBackTrace(VOID) -{ - return; -} - -#endif /*(LOSCFG_PLATFORM_EXC == YES)*/ - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - diff --git a/arch/arm/arm-m/include/los_exc.h b/arch/arm/arm-m/include/los_exc.h deleted file mode 100644 index 80017aa05..000000000 --- a/arch/arm/arm-m/include/los_exc.h +++ /dev/null @@ -1,387 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_EXC_H -#define _LOS_EXC_H - -#include "los_hwi.h" -#include "los_task.ph" -#include "los_queue.h" -#include "los_config.h" -#include "los_memcheck.h" -#include "los_hw.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#if (LOSCFG_PLATFORM_EXC == YES) - - -#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_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 -{ -#if FPU_EXIST - 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 uwSP; - UINT32 uwR0; - UINT32 uwR1; - UINT32 uwR2; - UINT32 uwR3; - UINT32 uwR12; - UINT32 uwLR; - UINT32 uwPC; - UINT32 uwxPSR; -#if FPU_EXIST - 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 uwExcType, UINT32 uwFaultAddr, UINT32 uwPid, EXC_CONTEXT_S * pstExcBufAddr); - -/** - * @ingroup los_hwi - * @brief: Exception initialization. - * - * @par Description: - * This API is used to configure the exception function vector table. - * - * @attention: - *
  • None.
- * - *@param uwArraySize [IN] Memory size of exception. - * - * @retval: None - * @par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -VOID osExcInit(UINT32 uwArraySize); - -extern VOID NMI_Handler(VOID); -extern VOID HardFault_Handler(VOID); -extern VOID MemManage_Handler(VOID); -extern VOID BusFault_Handler(VOID); -extern VOID UsageFault_Handler(VOID); -extern VOID SVC_Handler(VOID); -extern VOID osBackTrace(VOID); -extern UINT8 m_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. - *@since Huawei LiteOS V100R001C00 -*/ -void LOS_Panic(const char * fmt, ...); - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线状æ€å¯„存器入栈时å‘生错误 - */ -#define OS_EXC_BF_STKERR 1 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线状æ€å¯„存器出栈时å‘生错误 - */ -#define OS_EXC_BF_UNSTKERR 2 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线状æ€å¯„存器ä¸ç²¾ç¡®çš„æ•°æ®è®¿é—®è¿ä¾‹ - */ -#define OS_EXC_BF_IMPRECISERR 3 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线状æ€å¯„存器精确的数æ®è®¿é—®è¿ä¾‹ - */ -#define OS_EXC_BF_PRECISERR 4 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线状æ€å¯„存器å–指时的访问è¿ä¾‹ - */ -#define OS_EXC_BF_IBUSERR 5 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线错误,浮点惰性压栈错误,具有浮点å•å…ƒçš„cortex-m4åŠcortex-m7中存在 - */ -#define OS_EXC_BF_LSPERR 6 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:存储器管ç†çŠ¶æ€å¯„存器入栈时å‘生错误 - */ -#define OS_EXC_MF_MSTKERR 7 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:存储器管ç†çŠ¶æ€å¯„存器出栈时å‘生错误 - */ -#define OS_EXC_MF_MUNSTKERR 8 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:存储器管ç†çŠ¶æ€å¯„存器数æ®è®¿é—®è¿ä¾‹ - */ -#define OS_EXC_MF_DACCVIOL 9 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:存储器管ç†çŠ¶æ€å¯„存器å–指访问è¿ä¾‹ - */ -#define OS_EXC_MF_IACCVIOL 10 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:存储器管ç†é”™è¯¯ï¼Œæµ®ç‚¹æƒ°æ€§åŽ‹æ ˆé”™è¯¯ï¼Œå…·æœ‰æµ®ç‚¹å•å…ƒçš„cortex-m4åŠcortex-m7中存在 - */ -#define OS_EXC_MF_MLSPERR 11 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:用法错误,表示除法è¿ç®—时除数为零 - */ -#define OS_EXC_UF_DIVBYZERO 12 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:用法错误,未对é½è®¿é—®å¯¼è‡´çš„错误 - */ -#define OS_EXC_UF_UNALIGNED 13 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:用法错误,试图执行å处ç†å™¨ç›¸å…³æŒ‡ä»¤ - */ -#define OS_EXC_UF_NOCP 14 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:用法错误,在异常返回时试图éžæ³•åœ°åŠ è½½EXC_RETURN到PC - */ -#define OS_EXC_UF_INVPC 15 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:用法错误,试图切入ARMçŠ¶æ€ - */ -#define OS_EXC_UF_INVSTATE 16 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:用法错误,执行的指令其编ç æ˜¯æœªå®šä¹‰çš„——解ç ä¸èƒ½ - */ -#define OS_EXC_UF_UNDEFINSTR 17 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:NMI中断 - */ -#define OS_EXC_CAUSE_NMI 18 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:硬fault - */ -#define OS_EXC_CAUSE_HARDFAULT 19 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:存储器管ç†fault - */ -#define OS_EXC_CAUSE_MEMFAULT 20 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:总线fault - */ -#define OS_EXC_CAUSE_BUSFAULT 21 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:使用fault - */ -#define OS_EXC_CAUSE_USAGEFAULT 22 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:SVC调用 - */ -#define OS_EXC_CAUSE_SVC 23 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:调试事件导致的硬fault - */ -#define OS_EXC_CAUSE_DEBUGEVT 24 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:å–å‘é‡æ—¶å‘生的硬fault - */ -#define OS_EXC_CAUSE_VECTBL 25 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:任务处ç†å‡½æ•°é€€å‡º - */ -#define OS_EXC_CAUSE_TASK_EXIT 26 - -/** - *@ingroup los_exc - *Cortex-M异常具体类型:致命错误 - */ -#define OS_EXC_CAUSE_FATAL_ERR 27 - -/** - *@ingroup los_exc - * 异常信æ¯ç»“构体 - * - * æè¿°:Cortex-Må¹³å°ä¸‹çš„异常触å‘æ—¶ä¿å­˜çš„å¼‚å¸¸ä¿¡æ¯ - * - */ -typedef struct tagExcInfo -{ - UINT16 usPhase; /**< 异常å‘生阶段: 0表示异常å‘生在åˆå§‹åŒ–中,1表示异常å‘生在任务中,2表示异常å‘生在中断中 */ - UINT16 usType; /**< 异常类型,分高低两字节,出异常时高低字节分别对照上é¢åˆ—å‡ºçš„å¼‚å¸¸ç¼–å· */ - UINT32 uwFaultAddr; /**< 若为精确地å€è®¿é—®é”™è¯¯è¡¨ç¤ºå¼‚常å‘ç”Ÿæ—¶çš„é”™è¯¯è®¿é—®åœ°å€ */ - UINT32 uwThrdPid; /**< 在中断中å‘生异常,表示中断å·ã€‚在任务中å‘生异常,表示任务id,如果å‘生在åˆå§‹åŒ–中,则为0xffffffff */ - UINT16 usNestCnt; /**< 异常嵌套个数,目å‰ä»…支æŒç¬¬ä¸€æ¬¡è¿›å…¥å¼‚常时执行注册的钩å­å‡½æ•° */ - UINT16 usFpuContext; /**< 是å¦ä¿å­˜æµ®ç‚¹å¯„存器,1表示需è¦ä¿å­˜æµ®ç‚¹å¯„存器 */ - UINT32 uwCallStackDepth; /**< 异常时调用栈分æžæ·±åº¦ */ - UINT32 uwCallStack[LOSCFG_EXC_CALL_STACK_ANALYSIS_MAX_DEPTH]; /**< å‡½æ•°è°ƒç”¨åœ°å€ */ - EXC_CONTEXT_S *pstContext; /**< 异常å‘生时的寄存器值,由usFpuContext决定寄存器中是å¦åŒ…å«æµ®ç‚¹å¯„存器的值 */ -}EXC_INFO_S; - -extern UINT32 g_uwCurNestCount; -extern UINT32 g_vuwIntCount; -extern EXC_INFO_S m_stExcInfo; - -VOID osExcInfoDisplay(EXC_INFO_S *pstExc); - -extern OS_TASK_SWITCH_INFO g_astTskSwitchInfo; -extern UINT8 g_uwExcTbl[32]; - -#endif - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#endif /* _LOS_EXC_H */ - diff --git a/arch/arm/arm-m/include/los_hw_tick.h b/arch/arm/arm-m/include/los_hw_tick.h deleted file mode 100644 index f8be29d8a..000000000 --- a/arch/arm/arm-m/include/los_hw_tick.h +++ /dev/null @@ -1,111 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - - /**@defgroup los_hw hardware - *@ingroup kernel - */ - -#ifndef _LOS_HW_TICK_H -#define _LOS_HW_TICK_H - -#include "los_base.h" -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#if (LOSCFG_KERNEL_TICKLESS == YES) -/** - * @ingroup los_hwi - * Check whether the counting direction of system tick is decreasing, it will be used to - * readjust the value of the system tick, if not decreasing, please set this macro to NO. - */ -#define LOSCFG_SYSTICK_CNT_DIR_DECREASE YES - -/** - * @ingroup los_hwi - * Max reload value of system tick. - */ -#define LOSCFG_SYSTICK_LOAD_RELOAD_MAX SysTick_LOAD_RELOAD_Msk - -/***************************************************************************** -Function : LOS_SysTickStop -Description: stop systick -Input : none -output : none -return : none -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR static inline VOID LOS_SysTickStop(VOID) -{ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; -} - -/***************************************************************************** -Function : LOS_SysTickStart -Description: start systick -Input : none -output : none -return : none -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR static inline VOID LOS_SysTickStart(VOID) -{ - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; -} - -/***************************************************************************** -Function : LOS_SysTickGetIntStatus -Description: get systick interrupt status -Input : none -output : none -return : systick interrupt status -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR static inline UINT32 LOS_SysTickGetIntStatus(VOID) -{ - return SCB->ICSR & SCB_ICSR_PENDSTSET_Msk; -} - -extern VOID LOS_SysTickReload(UINT32 uwCyclesPerTick); - -#endif - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -#endif /* _LOS_HW_H */ - diff --git a/arch/arm/arm-m/include/los_hwi.h b/arch/arm/arm-m/include/los_hwi.h deleted file mode 100644 index 977eed7b2..000000000 --- a/arch/arm/arm-m/include/los_hwi.h +++ /dev/null @@ -1,711 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - - /**@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. - */ -/*lint -e553*/ -#ifndef OS_HWI_MAX_NUM -#if (__CORTEX_M == 0U) -/* Cortex-m0 and Cortex-m0plus default 32 */ -#define OS_HWI_MAX_NUM 32 -#elif (__CORTEX_M == 3U || __CORTEX_M == 4U || __CORTEX_M == 7U) -/* Cortex-m3,Cortex-m4 and Cortex-m7 default 240 */ -#define OS_HWI_MAX_NUM 240 -#endif -#endif -/*lint +e553*/ - -/** - * @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 *pParm); -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; - -#if (LOSCFG_PLATFORM_HWI == YES) -/** - * @ingroup los_hwi - * An interrupt is active. - */ -#define OS_INT_ACTIVE (g_vuwIntCount > 0) -#else -/** - * @ingroup los_hwi - * An interrupt is active. - */ -#define OS_INT_ACTIVE (osIntNumGet()) -#endif - -/** - * @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 - * ?D??ACTIVE???????? - */ -#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 m_pstHwiForm[OS_VECTOR_CNT]; - -#if (OS_HWI_WITH_ARG == YES) -/** - * @ingroup los_hwi - * hardware interrupt Slave form mapping handling function array. - */ -extern HWI_SLAVE_FUNC m_pstHwiSlaveForm[OS_VECTOR_CNT]; - -/** - * @ingroup los_hwi - * Set interrupt vector table. - */ -#define osSetVector(uwNum, pfnVector, uwArg) \ - m_pstHwiForm[uwNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)osInterrupt;\ - m_pstHwiSlaveForm[uwNum + OS_SYS_VECTOR_CNT].pfnHandler= pfnVector; \ - m_pstHwiSlaveForm[uwNum + OS_SYS_VECTOR_CNT].pParm = (VOID*)uwArg; -#else -/** - * @ingroup los_hwi - * hardware interrupt Slave form mapping handling function array. - */ -extern HWI_PROC_FUNC m_pstHwiSlaveForm[OS_VECTOR_CNT]; - -/** - * @ingroup los_hwi - * Set interrupt vector table. - */ -#define osSetVector(uwNum, pfnVector) \ - m_pstHwiForm[uwNum + OS_SYS_VECTOR_CNT] = osInterrupt;\ - m_pstHwiSlaveForm[uwNum + OS_SYS_VECTOR_CNT] = pfnVector; -#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 - *
    - *
  • The hardware interrupt module is usable only when the configuration item for hardware interrupt tailoring is enabled.
  • - *
  • Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. The value range applicable for a Cortex-A7 platform is [32,95].
  • - *
  • OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.
  • - *
  • Before executing an interrupt on a platform, refer to the chip manual of the platform.
  • - *
- * - * @param uwHwiNum [IN] Type#HWI_HANDLE_T: hardware interrupt number. The value range applicable for a Cortex-A7 platform is [32,95]. - * @param usHwiPrio [IN] Type#HWI_PRIOR_T: hardware interrupt priority. Ignore this parameter temporarily. - * @param usMode [IN] Type#HWI_MODE_T: hardware interrupt mode. Ignore this parameter temporarily. - * @param pfnHandler [IN] Type#HWI_PROC_FUNC: interrupt handler used when a hardware interrupt is triggered. - * @param uwArg [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: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_HwiCreate( HWI_HANDLE_T uwHwiNum, - HWI_PRIOR_T usHwiPrio, - HWI_MODE_T usMode, - HWI_PROC_FUNC pfnHandler, - HWI_ARG_T uwArg - ); - -/** - * @ingroup los_hwi - * @brief: Hardware interrupt entry function. - * - * @par Description: - * This API is used as all hardware interrupt handling function entry. - * - * @attention: - *
  • None.
- * - * @param:None. - * - * @retval:None. - * @par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -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: - *
  • None.
- * - * @param: None. - * - * @retval: Interrupt Indexes number. - * @par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -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: - *
  • None.
- * - * @param:None. - * - * @retval:None. - * @par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osHwiDefaultHandler(VOID); - -/** - * @ingroup los_hwi - * @brief: Reset the vector table. - * - * @par Description: - * This API is used to reset the vector table. - * - * @attention: - *
  • None.
- * - * @param:None. - * - * @retval:None. - * @par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -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: - *
  • None.
- * - * @param:None. - * - * @retval:None. - * @par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern VOID PendSV_Handler(VOID); - - /** - *@ingroup los_hwi - *@brief Enable all interrupts. - * - *@par Description: - *
    - *
  • This API is used to enable all IRQ and FIQ interrupts in the CPSR.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval CPSR value obtained after all interrupts are enabled. - *@par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- *@see LOS_IntRestore - *@since Huawei LiteOS V100R001C00 - */ -extern UINTPTR LOS_IntUnLock(VOID); - - - - /** - *@ingroup los_hwi - *@brief Disable all interrupts. - * - *@par Description: - *
    - *
  • This API is used to disable all IRQ and FIQ interrupts in the CPSR.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval CPSR value obtained before all interrupts are disabled. - *@par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- *@see LOS_IntRestore - *@since Huawei LiteOS V100R001C00 - */ -extern UINTPTR LOS_IntLock(VOID); - - - - /** - *@ingroup los_hwi - *@brief Restore interrupts. - * - *@par Description: - *
    - *
  • This API is used to restore the CPSR value obtained before all interrupts are disabled.
  • - *
- *@attention - *
    - *
  • This API can be called only after all interrupts are disabled, and the input parameter value should be the value returned by calling the all interrupt disabling API.
  • - *
- * - *@param uvIntSave [IN] CPSR value obtained before all interrupts are disabled. - * - *@retval None. - *@par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
- *@see LOS_IntLock - *@since Huawei LiteOS V100R001C00 - */ -extern VOID LOS_IntRestore(UINTPTR uvIntSave); - - /** - *@ingroup los_hwi - *@brief Get value from xPSR register. - * - *@par Description: - *
    - *
  • This API is used to Get value from xPSR register.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval xPSR register value. - *@par Dependency: - *
  • los_hwi.h: the header file that contains the API declaration.
  • - *@see LOS_IntRestore - *@since Huawei LiteOS V100R001C00 - */ -extern VOID LOS_GetCpuCycle(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 - *
      - *
    • The hardware interrupt module is usable only when the configuration item for hardware interrupt tailoring is enabled.
    • - *
    • Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. The value range applicable for a Cortex-A7 platform is [32,95].
    • - *
    • OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.
    • - *
    • Before executing an interrupt on a platform, refer to the chip manual of the platform.
    • - *
    - * - * @param uwHwiNum [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: - *
    • los_hwi.h: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_HwiDelete(HWI_HANDLE_T uwHwiNum); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - - -#endif /* _LOS_HWI_H */ - diff --git a/arch/arm/arm-m/src/los_hw_tick.c b/arch/arm/arm-m/src/los_hw_tick.c deleted file mode 100644 index 706ea449b..000000000 --- a/arch/arm/arm-m/src/los_hw_tick.c +++ /dev/null @@ -1,212 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_tick.ph" -#include "los_base.h" -#include "los_task.ph" -#include "los_swtmr.h" -#include "los_hwi.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -/***************************************************************************** -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 uwRet; - - if ((0 == OS_SYS_CLOCK) - || (0 == LOSCFG_BASE_CORE_TICK_PER_SECOND) - || (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK))/*lint !e506*/ - { - return LOS_ERRNO_TICK_CFG_INVALID; - } - -#if (LOSCFG_PLATFORM_HWI == YES) -#if (OS_HWI_WITH_ARG == YES) - osSetVector(SysTick_IRQn, (HWI_PROC_FUNC)osTickHandler, NULL); -#else - osSetVector(SysTick_IRQn, osTickHandler); -#endif -#endif - - g_uwCyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; - g_ullTickCount = 0; - - uwRet = SysTick_Config(OS_SYS_CLOCK/LOSCFG_BASE_CORE_TICK_PER_SECOND); - if (uwRet == 1) - { - return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL; - } - - g_bSysTickStart = TRUE; - - return LOS_OK; -} - -#if (LOSCFG_KERNEL_TICKLESS == YES) -/***************************************************************************** -Function : LOS_SysTickReload -Description: reconfig systick -Input : none -output : none -return : none -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID LOS_SysTickReload(UINT32 uwCyclesPerTick) -{ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - SysTick->LOAD = (uint32_t)(uwCyclesPerTick - 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 : SysTick->VAL -return : none -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysTickCurrCycleGet(VOID) -{ - UINT32 uwHwCycle; - UINTPTR uvIntSave; - - uvIntSave = LOS_IntLock(); - uwHwCycle = SysTick->VAL; - - /*tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ - if (((SCB->ICSR & 0x4000000) != 0)) - { - uwHwCycle = SysTick->VAL; - uwHwCycle += g_uwCyclesPerTick; - } - - LOS_IntRestore(uvIntSave); - - return uwHwCycle; -} - -/***************************************************************************** -Function : LOS_GetCpuCycle -Description: Get System cycle count -Input : none -output : puwCntHi --- CpuTick High 4 byte - puwCntLo --- CpuTick Low 4 byte -return : none -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo) -{ - UINT64 ullSwTick; - UINT64 ullCycle; - UINT32 uwHwCycle; - UINTPTR uvIntSave; - - uvIntSave = LOS_IntLock(); - - ullSwTick = g_ullTickCount; - uwHwCycle = SysTick->VAL; - - /*tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ - if (((SCB->ICSR & 0x4000000) != 0)) - { - uwHwCycle = SysTick->VAL; - ullSwTick++; - } - - ullCycle = (((ullSwTick) * g_uwCyclesPerTick) + (g_uwCyclesPerTick - uwHwCycle)); - - *puwCntHi = ullCycle >> 32; - *puwCntLo = ullCycle & 0xFFFFFFFFU; - - LOS_IntRestore(uvIntSave); - - return; -} - -/***************************************************************************** -Function : LOS_GetSystickCycle -Description: Get Sys tick cycle count -Input : none -output : puwCntHi --- SysTick count High 4 byte - puwCntLo --- SysTick count Low 4 byte -return : none -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID LOS_GetSystickCycle(UINT32 *puwCntHi, UINT32 *puwCntLo) -{ - UINT64 ullSwTick; - UINT64 ullCycle; - UINT32 uwHwCycle; - UINTPTR uvIntSave; - UINT32 uwSystickLoad; - UINT32 uwSystickCur; - - uvIntSave = LOS_IntLock(); - - ullSwTick = g_ullTickCount; - - uwSystickLoad = SysTick->LOAD; - uwSystickCur = SysTick->VAL; - uwHwCycle = uwSystickLoad - uwSystickCur; - - /*tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ - if (((SCB->ICSR & 0x4000000) != 0)) - { - uwHwCycle = uwSystickLoad - uwSystickCur; - ullSwTick++; - } - - ullCycle = uwHwCycle + ullSwTick * uwSystickLoad; - *puwCntHi = ullCycle >> 32; - *puwCntLo = ullCycle & 0xFFFFFFFFU; - - LOS_IntRestore(uvIntSave); - - return; -} -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ diff --git a/arch/arm/common/cmsis/arm_common_tables.h b/arch/arm/common/cmsis/arm_common_tables.h deleted file mode 100644 index dfea7460e..000000000 --- a/arch/arm/common/cmsis/arm_common_tables.h +++ /dev/null @@ -1,121 +0,0 @@ -/* ---------------------------------------------------------------------- - * Project: CMSIS DSP Library - * Title: arm_common_tables.h - * Description: Extern declaration for common tables - * - * $Date: 27. January 2017 - * $Revision: V.1.5.1 - * - * Target Processor: Cortex-M cores - * -------------------------------------------------------------------- */ -/* - * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _ARM_COMMON_TABLES_H -#define _ARM_COMMON_TABLES_H - -#include "arm_math.h" - -extern const uint16_t armBitRevTable[1024]; -extern const q15_t armRecipTableQ15[64]; -extern const q31_t armRecipTableQ31[64]; -extern const float32_t twiddleCoef_16[32]; -extern const float32_t twiddleCoef_32[64]; -extern const float32_t twiddleCoef_64[128]; -extern const float32_t twiddleCoef_128[256]; -extern const float32_t twiddleCoef_256[512]; -extern const float32_t twiddleCoef_512[1024]; -extern const float32_t twiddleCoef_1024[2048]; -extern const float32_t twiddleCoef_2048[4096]; -extern const float32_t twiddleCoef_4096[8192]; -#define twiddleCoef twiddleCoef_4096 -extern const q31_t twiddleCoef_16_q31[24]; -extern const q31_t twiddleCoef_32_q31[48]; -extern const q31_t twiddleCoef_64_q31[96]; -extern const q31_t twiddleCoef_128_q31[192]; -extern const q31_t twiddleCoef_256_q31[384]; -extern const q31_t twiddleCoef_512_q31[768]; -extern const q31_t twiddleCoef_1024_q31[1536]; -extern const q31_t twiddleCoef_2048_q31[3072]; -extern const q31_t twiddleCoef_4096_q31[6144]; -extern const q15_t twiddleCoef_16_q15[24]; -extern const q15_t twiddleCoef_32_q15[48]; -extern const q15_t twiddleCoef_64_q15[96]; -extern const q15_t twiddleCoef_128_q15[192]; -extern const q15_t twiddleCoef_256_q15[384]; -extern const q15_t twiddleCoef_512_q15[768]; -extern const q15_t twiddleCoef_1024_q15[1536]; -extern const q15_t twiddleCoef_2048_q15[3072]; -extern const q15_t twiddleCoef_4096_q15[6144]; -extern const float32_t twiddleCoef_rfft_32[32]; -extern const float32_t twiddleCoef_rfft_64[64]; -extern const float32_t twiddleCoef_rfft_128[128]; -extern const float32_t twiddleCoef_rfft_256[256]; -extern const float32_t twiddleCoef_rfft_512[512]; -extern const float32_t twiddleCoef_rfft_1024[1024]; -extern const float32_t twiddleCoef_rfft_2048[2048]; -extern const float32_t twiddleCoef_rfft_4096[4096]; - -/* floating-point bit reversal tables */ -#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) -#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) -#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) -#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) -#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) -#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) -#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) -#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) -#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) - -extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; - -/* fixed-point bit reversal tables */ -#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) -#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) -#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) -#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) -#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) -#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) -#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) -#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) -#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) - -extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; - -/* Tables for Fast Math Sine and Cosine */ -extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; -extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; -extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; - -#endif /* ARM_COMMON_TABLES_H */ diff --git a/arch/arm/common/cmsis/arm_const_structs.h b/arch/arm/common/cmsis/arm_const_structs.h deleted file mode 100644 index 80a3e8bbe..000000000 --- a/arch/arm/common/cmsis/arm_const_structs.h +++ /dev/null @@ -1,66 +0,0 @@ -/* ---------------------------------------------------------------------- - * Project: CMSIS DSP Library - * Title: arm_const_structs.h - * Description: Constant structs that are initialized for user convenience. - * For example, some can be given as arguments to the arm_cfft_f32() function. - * - * $Date: 27. January 2017 - * $Revision: V.1.5.1 - * - * Target Processor: Cortex-M cores - * -------------------------------------------------------------------- */ -/* - * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _ARM_CONST_STRUCTS_H -#define _ARM_CONST_STRUCTS_H - -#include "arm_math.h" -#include "arm_common_tables.h" - - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; - - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; - - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; - -#endif diff --git a/arch/arm/common/cmsis/arm_math.h b/arch/arm/common/cmsis/arm_math.h deleted file mode 100644 index 1a40a50d9..000000000 --- a/arch/arm/common/cmsis/arm_math.h +++ /dev/null @@ -1,7185 +0,0 @@ -/* ---------------------------------------------------------------------- - * Project: CMSIS DSP Library - * Title: arm_math.h - * Description: Public header file for CMSIS DSP Library - * - * $Date: 27. January 2017 - * $Revision: V.1.5.1 - * - * Target Processor: Cortex-M cores - * -------------------------------------------------------------------- */ -/* - * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - \mainpage CMSIS DSP Software Library - * - * Introduction - * ------------ - * - * This user manual describes the CMSIS DSP software library, - * a suite of common signal processing functions for use on Cortex-M processor based devices. - * - * The library is divided into a number of functions each covering a specific category: - * - Basic math functions - * - Fast math functions - * - Complex math functions - * - Filters - * - Matrix functions - * - Transforms - * - Motor control functions - * - Statistical functions - * - Support functions - * - Interpolation functions - * - * The library has separate functions for operating on 8-bit integers, 16-bit integers, - * 32-bit integer and 32-bit floating-point values. - * - * Using the Library - * ------------ - * - * The library installer contains prebuilt versions of the libraries in the Lib folder. - * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) - * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) - * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) - * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) - * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) - * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) - * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) - * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) - * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) - * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) - * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) - * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) - * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) - * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) - * - arm_ARMv8MBLl_math.lib (ARMv8M Baseline, Little endian) - * - arm_ARMv8MMLl_math.lib (ARMv8M Mainline, Little endian) - * - arm_ARMv8MMLlfsp_math.lib (ARMv8M Mainline, Little endian, Single Precision Floating Point Unit) - * - arm_ARMv8MMLld_math.lib (ARMv8M Mainline, Little endian, DSP instructions) - * - arm_ARMv8MMLldfsp_math.lib (ARMv8M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) - * - * The library functions are declared in the public file arm_math.h which is placed in the Include folder. - * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single - * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. - * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or - * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. - * For ARMv8M cores define pre processor MACRO ARM_MATH_ARMV8MBL or ARM_MATH_ARMV8MML. - * Set Pre processor MACRO __DSP_PRESENT if ARMv8M Mainline core supports DSP instructions. - * - * - * Examples - * -------- - * - * The library ships with a number of examples which demonstrate how to use the library functions. - * - * Toolchain Support - * ------------ - * - * The library has been developed and tested with MDK-ARM version 5.14.0.0 - * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. - * - * Building the Library - * ------------ - * - * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. - * - arm_cortexM_math.uvprojx - * - * - * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. - * - * Pre-processor Macros - * ------------ - * - * Each library project have differant pre-processor macros. - * - * - UNALIGNED_SUPPORT_DISABLE: - * - * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access - * - * - ARM_MATH_BIG_ENDIAN: - * - * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. - * - * - ARM_MATH_MATRIX_CHECK: - * - * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices - * - * - ARM_MATH_ROUNDING: - * - * Define macro ARM_MATH_ROUNDING for rounding on support functions - * - * - ARM_MATH_CMx: - * - * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target - * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and - * ARM_MATH_CM7 for building the library on cortex-M7. - * - * - ARM_MATH_ARMV8MxL: - * - * Define macro ARM_MATH_ARMV8MBL for building the library on ARMv8M Baseline target, ARM_MATH_ARMV8MBL for building library - * on ARMv8M Mainline target. - * - * - __FPU_PRESENT: - * - * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for floating point libraries. - * - * - __DSP_PRESENT: - * - * Initialize macro __DSP_PRESENT = 1 when ARMv8M Mainline core supports DSP instructions. - * - *
    - * CMSIS-DSP in ARM::CMSIS Pack - * ----------------------------- - * - * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: - * |File/Folder |Content | - * |------------------------------|------------------------------------------------------------------------| - * |\b CMSIS\\Documentation\\DSP | This documentation | - * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | - * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | - * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | - * - *
    - * Revision History of CMSIS-DSP - * ------------ - * Please refer to \ref ChangeLog_pg. - * - * Copyright Notice - * ------------ - * - * Copyright (C) 2010-2015 ARM Limited. All rights reserved. - */ - - -/** - * @defgroup groupMath Basic Math Functions - */ - -/** - * @defgroup groupFastMath Fast Math Functions - * This set of functions provides a fast approximation to sine, cosine, and square root. - * As compared to most of the other functions in the CMSIS math library, the fast math functions - * operate on individual values and not arrays. - * There are separate functions for Q15, Q31, and floating-point data. - * - */ - -/** - * @defgroup groupCmplxMath Complex Math Functions - * This set of functions operates on complex data vectors. - * The data in the complex arrays is stored in an interleaved fashion - * (real, imag, real, imag, ...). - * In the API functions, the number of samples in a complex array refers - * to the number of complex values; the array contains twice this number of - * real values. - */ - -/** - * @defgroup groupFilters Filtering Functions - */ - -/** - * @defgroup groupMatrix Matrix Functions - * - * This set of functions provides basic matrix math operations. - * The functions operate on matrix data structures. For example, - * the type - * definition for the floating-point matrix structure is shown - * below: - *
    - *     typedef struct
    - *     {
    - *       uint16_t numRows;     // number of rows of the matrix.
    - *       uint16_t numCols;     // number of columns of the matrix.
    - *       float32_t *pData;     // points to the data of the matrix.
    - *     } arm_matrix_instance_f32;
    - * 
    - * There are similar definitions for Q15 and Q31 data types. - * - * The structure specifies the size of the matrix and then points to - * an array of data. The array is of size numRows X numCols - * and the values are arranged in row order. That is, the - * matrix element (i, j) is stored at: - *
    - *     pData[i*numCols + j]
    - * 
    - * - * \par Init Functions - * There is an associated initialization function for each type of matrix - * data structure. - * The initialization function sets the values of the internal structure fields. - * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() - * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. - * - * \par - * Use of the initialization function is optional. However, if initialization function is used - * then the instance structure cannot be placed into a const data section. - * To place the instance structure in a const data - * section, manually initialize the data structure. For example: - *
    - * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
    - * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
    - * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
    - * 
    - * where nRows specifies the number of rows, nColumns - * specifies the number of columns, and pData points to the - * data array. - * - * \par Size Checking - * By default all of the matrix functions perform size checking on the input and - * output matrices. For example, the matrix addition function verifies that the - * two input matrices and the output matrix all have the same number of rows and - * columns. If the size check fails the functions return: - *
    - *     ARM_MATH_SIZE_MISMATCH
    - * 
    - * Otherwise the functions return - *
    - *     ARM_MATH_SUCCESS
    - * 
    - * There is some overhead associated with this matrix size checking. - * The matrix size checking is enabled via the \#define - *
    - *     ARM_MATH_MATRIX_CHECK
    - * 
    - * within the library project settings. By default this macro is defined - * and size checking is enabled. By changing the project settings and - * undefining this macro size checking is eliminated and the functions - * run a bit faster. With size checking disabled the functions always - * return ARM_MATH_SUCCESS. - */ - -/** - * @defgroup groupTransforms Transform Functions - */ - -/** - * @defgroup groupController Controller Functions - */ - -/** - * @defgroup groupStats Statistics Functions - */ -/** - * @defgroup groupSupport Support Functions - */ - -/** - * @defgroup groupInterpolation Interpolation Functions - * These functions perform 1- and 2-dimensional interpolation of data. - * Linear interpolation is used for 1-dimensional data and - * bilinear interpolation is used for 2-dimensional data. - */ - -/** - * @defgroup groupExamples Examples - */ -#ifndef _ARM_MATH_H -#define _ARM_MATH_H - -/* ignore some GCC warnings */ -#if defined ( __GNUC__ ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ - -#if defined(ARM_MATH_CM7) - #include "core_cm7.h" - #define ARM_MATH_DSP -#elif defined (ARM_MATH_CM4) - #include "core_cm4.h" - #define ARM_MATH_DSP -#elif defined (ARM_MATH_CM3) - #include "core_cm3.h" -#elif defined (ARM_MATH_CM0) - #include "core_cm0.h" - #define ARM_MATH_CM0_FAMILY -#elif defined (ARM_MATH_CM0PLUS) - #include "core_cm0plus.h" - #define ARM_MATH_CM0_FAMILY -#elif defined (ARM_MATH_ARMV8MBL) - #include "core_armv8mbl.h" - #define ARM_MATH_CM0_FAMILY -#elif defined (ARM_MATH_ARMV8MML) - #include "core_armv8mml.h" - #if (defined (__DSP_PRESENT) && (__DSP_PRESENT == 1)) - #define ARM_MATH_DSP - #endif -#else - #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" -#endif - -#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ -#include "string.h" -#include "math.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - - /** - * @brief Macros required for reciprocal calculation in Normalized LMS - */ - -#define DELTA_Q31 (0x100) -#define DELTA_Q15 0x5 -#define INDEX_MASK 0x0000003F -#ifndef PI - #define PI 3.14159265358979f -#endif - - /** - * @brief Macros required for SINE and COSINE Fast math approximations - */ - -#define FAST_MATH_TABLE_SIZE 512 -#define FAST_MATH_Q31_SHIFT (32 - 10) -#define FAST_MATH_Q15_SHIFT (16 - 10) -#define CONTROLLER_Q31_SHIFT (32 - 9) -#define TABLE_SPACING_Q31 0x400000 -#define TABLE_SPACING_Q15 0x80 - - /** - * @brief Macros required for SINE and COSINE Controller functions - */ - /* 1.31(q31) Fixed value of 2/360 */ - /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ -#define INPUT_SPACING 0xB60B61 - - /** - * @brief Macro for Unaligned Support - */ -#ifndef UNALIGNED_SUPPORT_DISABLE - #define ALIGN4 -#else - #if defined (__GNUC__) - #define ALIGN4 __attribute__((aligned(4))) - #else - #define ALIGN4 __align(4) - #endif -#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ - - /** - * @brief Error status returned by some functions in the library. - */ - - typedef enum - { - ARM_MATH_SUCCESS = 0, /**< No error */ - ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ - ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ - ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ - ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ - ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ - ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ - } arm_status; - - /** - * @brief 8-bit fractional data type in 1.7 format. - */ - typedef int8_t q7_t; - - /** - * @brief 16-bit fractional data type in 1.15 format. - */ - typedef int16_t q15_t; - - /** - * @brief 32-bit fractional data type in 1.31 format. - */ - typedef int32_t q31_t; - - /** - * @brief 64-bit fractional data type in 1.63 format. - */ - typedef int64_t q63_t; - - /** - * @brief 32-bit floating-point type definition. - */ - typedef float float32_t; - - /** - * @brief 64-bit floating-point type definition. - */ - typedef double float64_t; - - -#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) -#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) -#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) -#define __SIMD64(addr) (*(int64_t **) & (addr)) - -/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#if !defined (ARM_MATH_DSP) - /** - * @brief definition to pack two 16 bit values. - */ -#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ - (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) -#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ - (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) - -/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#endif /* !defined (ARM_MATH_DSP) */ - - /** - * @brief definition to pack four 8 bit values. - */ -#ifndef ARM_MATH_BIG_ENDIAN - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) -#else - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) - -#endif - - - /** - * @brief Clips Q63 to Q31 values. - */ - CMSIS_INLINE __STATIC_INLINE q31_t clip_q63_to_q31( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; - } - - /** - * @brief Clips Q63 to Q15 values. - */ - CMSIS_INLINE __STATIC_INLINE q15_t clip_q63_to_q15( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); - } - - /** - * @brief Clips Q31 to Q7 values. - */ - CMSIS_INLINE __STATIC_INLINE q7_t clip_q31_to_q7( - q31_t x) - { - return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? - ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; - } - - /** - * @brief Clips Q31 to Q15 values. - */ - CMSIS_INLINE __STATIC_INLINE q15_t clip_q31_to_q15( - q31_t x) - { - return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? - ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; - } - - /** - * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. - */ - - CMSIS_INLINE __STATIC_INLINE q63_t mult32x64( - q63_t x, - q31_t y) - { - return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + - (((q63_t) (x >> 32) * y))); - } - -/* - #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) - #define __CLZ __clz - #endif - */ -/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ -#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) - CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( - q31_t data); - - CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( - q31_t data) - { - uint32_t count = 0; - uint32_t mask = 0x80000000; - - while ((data & mask) == 0) - { - count += 1u; - mask = mask >> 1u; - } - - return (count); - } -#endif - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. - */ - - CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q31( - q31_t in, - q31_t * dst, - q31_t * pRecipTable) - { - q31_t out; - uint32_t tempVal; - uint32_t index, i; - uint32_t signBits; - - if (in > 0) - { - signBits = ((uint32_t) (__CLZ( in) - 1)); - } - else - { - signBits = ((uint32_t) (__CLZ(-in) - 1)); - } - - /* Convert input sample to 1.31 format */ - in = (in << signBits); - - /* calculation of index for initial approximated Val */ - index = (uint32_t)(in >> 24); - index = (index & INDEX_MASK); - - /* 1.31 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (uint32_t) (((q63_t) in * out) >> 31); - tempVal = 0x7FFFFFFFu - tempVal; - /* 1.31 with exp 1 */ - /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ - out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1u); - } - - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. - */ - CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q15( - q15_t in, - q15_t * dst, - q15_t * pRecipTable) - { - q15_t out = 0; - uint32_t tempVal = 0; - uint32_t index = 0, i = 0; - uint32_t signBits = 0; - - if (in > 0) - { - signBits = ((uint32_t)(__CLZ( in) - 17)); - } - else - { - signBits = ((uint32_t)(__CLZ(-in) - 17)); - } - - /* Convert input sample to 1.15 format */ - in = (in << signBits); - - /* calculation of index for initial approximated Val */ - index = (uint32_t)(in >> 8); - index = (index & INDEX_MASK); - - /* 1.15 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (uint32_t) (((q31_t) in * out) >> 15); - tempVal = 0x7FFFu - tempVal; - /* 1.15 with exp 1 */ - out = (q15_t) (((q31_t) out * tempVal) >> 14); - /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1); - } - - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0_FAMILY) - CMSIS_INLINE __STATIC_INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if (x > 0) - { - posMax = (posMax - 1); - - if (x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if (x < negMin) - { - x = negMin; - } - } - return (x); - } -#endif /* end of ARM_MATH_CM0_FAMILY */ - - - /* - * @brief C custom defined intrinsic function for M3 and M0 processors - */ -/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#if !defined (ARM_MATH_DSP) - - /* - * @brief C custom defined QADD8 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( - uint32_t x, - uint32_t y) - { - q31_t r, s, t, u; - - r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; - s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; - t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; - u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; - - return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); - } - - - /* - * @brief C custom defined QSUB8 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( - uint32_t x, - uint32_t y) - { - q31_t r, s, t, u; - - r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; - s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; - t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; - u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; - - return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); - } - - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( - uint32_t x, - uint32_t y) - { -/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ - q31_t r = 0, s = 0; - - r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHADD16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined QSUB16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHSUB16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined QASX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHASX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined QSAX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; - s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SHSAX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( - uint32_t x, - uint32_t y) - { - q31_t r, s; - - r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; - s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; - - return ((uint32_t)((s << 16) | (r ))); - } - - - /* - * @brief C custom defined SMUSDX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); - } - - /* - * @brief C custom defined SMUADX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); - } - - - /* - * @brief C custom defined QADD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE int32_t __QADD( - int32_t x, - int32_t y) - { - return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); - } - - - /* - * @brief C custom defined QSUB for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( - int32_t x, - int32_t y) - { - return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); - } - - - /* - * @brief C custom defined SMLAD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( - uint32_t x, - uint32_t y, - uint32_t sum) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + - ( ((q31_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLADX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( - uint32_t x, - uint32_t y, - uint32_t sum) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + - ( ((q31_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLSDX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( - uint32_t x, - uint32_t y, - uint32_t sum) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + - ( ((q31_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLALD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( - uint32_t x, - uint32_t y, - uint64_t sum) - { -/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ - return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + - ( ((q63_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMLALDX for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALDX( - uint32_t x, - uint32_t y, - uint64_t sum) - { -/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ - return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + - ( ((q63_t)sum ) ) )); - } - - - /* - * @brief C custom defined SMUAD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUAD( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); - } - - - /* - * @brief C custom defined SMUSD for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSD( - uint32_t x, - uint32_t y) - { - return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - - ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); - } - - - /* - * @brief C custom defined SXTB16 for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __SXTB16( - uint32_t x) - { - return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | - ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); - } - - /* - * @brief C custom defined SMMLA for M3 and M0 processors - */ - CMSIS_INLINE __STATIC_INLINE int32_t __SMMLA( - int32_t x, - int32_t y, - int32_t sum) - { - return (sum + (int32_t) (((int64_t) x * y) >> 32)); - } - -#if 0 - /* - * @brief C custom defined PKHBT for unavailable DSP extension - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __PKHBT( - uint32_t x, - uint32_t y, - uint32_t leftshift) - { - return ( ((x ) & 0x0000FFFFUL) | - ((y << leftshift) & 0xFFFF0000UL) ); - } - - /* - * @brief C custom defined PKHTB for unavailable DSP extension - */ - CMSIS_INLINE __STATIC_INLINE uint32_t __PKHTB( - uint32_t x, - uint32_t y, - uint32_t rightshift) - { - return ( ((x ) & 0xFFFF0000UL) | - ((y >> rightshift) & 0x0000FFFFUL) ); - } -#endif - -/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ -#endif /* !defined (ARM_MATH_DSP) */ - - - /** - * @brief Instance structure for the Q7 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q7; - - /** - * @brief Instance structure for the Q15 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_f32; - - - /** - * @brief Processing function for the Q7 FIR filter. - * @param[in] S points to an instance of the Q7 FIR filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_q7( - const arm_fir_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 FIR filter. - * @param[in,out] S points to an instance of the Q7 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed. - */ - void arm_fir_init_q7( - arm_fir_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR filter. - * @param[in] S points to an instance of the Q15 FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q15 FIR filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_fast_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR filter. - * @param[in,out] S points to an instance of the Q15 FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if - * numTaps is not a supported value. - */ - arm_status arm_fir_init_q15( - arm_fir_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 FIR filter. - * @param[in] S points to an instance of the Q31 FIR filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q31 FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_fast_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR filter. - * @param[in,out] S points to an instance of the Q31 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - */ - void arm_fir_init_q31( - arm_fir_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR filter. - * @param[in] S points to an instance of the floating-point FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_f32( - const arm_fir_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR filter. - * @param[in,out] S points to an instance of the floating-point FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - */ - void arm_fir_init_f32( - arm_fir_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 Biquad cascade filter. - */ - typedef struct - { - int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - } arm_biquad_casd_df1_inst_q15; - - /** - * @brief Instance structure for the Q31 Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - } arm_biquad_casd_df1_inst_q31; - - /** - * @brief Instance structure for the floating-point Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_casd_df1_inst_f32; - - - /** - * @brief Processing function for the Q15 Biquad cascade filter. - * @param[in] S points to an instance of the Q15 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 Biquad cascade filter. - * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - */ - void arm_biquad_cascade_df1_init_q15( - arm_biquad_casd_df1_inst_q15 * S, - uint8_t numStages, - q15_t * pCoeffs, - q15_t * pState, - int8_t postShift); - - - /** - * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q15 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_fast_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 Biquad cascade filter - * @param[in] S points to an instance of the Q31 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q31 Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_fast_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 Biquad cascade filter. - * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - */ - void arm_biquad_cascade_df1_init_q31( - arm_biquad_casd_df1_inst_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q31_t * pState, - int8_t postShift); - - - /** - * @brief Processing function for the floating-point Biquad cascade filter. - * @param[in] S points to an instance of the floating-point Biquad cascade structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df1_f32( - const arm_biquad_casd_df1_inst_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point Biquad cascade filter. - * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_df1_init_f32( - arm_biquad_casd_df1_inst_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float32_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f32; - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float64_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f64; - - /** - * @brief Instance structure for the Q15 matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q15_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_q15; - - /** - * @brief Instance structure for the Q31 matrix structure. - */ - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q31_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_q31; - - - /** - * @brief Floating-point matrix addition. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_add_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix addition. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_add_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix addition. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_add_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point, complex, matrix multiplication. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_cmplx_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15, complex, matrix multiplication. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_cmplx_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pScratch); - - - /** - * @brief Q31, complex, matrix multiplication. - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_cmplx_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix transpose. - * @param[in] pSrc points to the input matrix - * @param[out] pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_trans_f32( - const arm_matrix_instance_f32 * pSrc, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix transpose. - * @param[in] pSrc points to the input matrix - * @param[out] pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_trans_q15( - const arm_matrix_instance_q15 * pSrc, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix transpose. - * @param[in] pSrc points to the input matrix - * @param[out] pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_trans_q31( - const arm_matrix_instance_q31 * pSrc, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix multiplication - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix multiplication - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @param[in] pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - - /** - * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @param[in] pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_fast_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - - /** - * @brief Q31 matrix multiplication - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_mult_fast_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix subtraction - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_sub_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix subtraction - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_sub_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix subtraction - * @param[in] pSrcA points to the first input matrix structure - * @param[in] pSrcB points to the second input matrix structure - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_sub_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix scaling. - * @param[in] pSrc points to the input matrix - * @param[in] scale scale factor - * @param[out] pDst points to the output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_scale_f32( - const arm_matrix_instance_f32 * pSrc, - float32_t scale, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix scaling. - * @param[in] pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_scale_q15( - const arm_matrix_instance_q15 * pSrc, - q15_t scaleFract, - int32_t shift, - arm_matrix_instance_q15 * pDst); - - - /** - * @brief Q31 matrix scaling. - * @param[in] pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - arm_status arm_mat_scale_q31( - const arm_matrix_instance_q31 * pSrc, - q31_t scaleFract, - int32_t shift, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix initialization. - * @param[in,out] S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] pData points to the matrix data array. - */ - void arm_mat_init_q31( - arm_matrix_instance_q31 * S, - uint16_t nRows, - uint16_t nColumns, - q31_t * pData); - - - /** - * @brief Q15 matrix initialization. - * @param[in,out] S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] pData points to the matrix data array. - */ - void arm_mat_init_q15( - arm_matrix_instance_q15 * S, - uint16_t nRows, - uint16_t nColumns, - q15_t * pData); - - - /** - * @brief Floating-point matrix initialization. - * @param[in,out] S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] pData points to the matrix data array. - */ - void arm_mat_init_f32( - arm_matrix_instance_f32 * S, - uint16_t nRows, - uint16_t nColumns, - float32_t * pData); - - - - /** - * @brief Instance structure for the Q15 PID Control. - */ - typedef struct - { - q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ -#if !defined (ARM_MATH_DSP) - q15_t A1; - q15_t A2; -#else - q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ -#endif - q15_t state[3]; /**< The state array of length 3. */ - q15_t Kp; /**< The proportional gain. */ - q15_t Ki; /**< The integral gain. */ - q15_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q15; - - /** - * @brief Instance structure for the Q31 PID Control. - */ - typedef struct - { - q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - q31_t A2; /**< The derived gain, A2 = Kd . */ - q31_t state[3]; /**< The state array of length 3. */ - q31_t Kp; /**< The proportional gain. */ - q31_t Ki; /**< The integral gain. */ - q31_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q31; - - /** - * @brief Instance structure for the floating-point PID Control. - */ - typedef struct - { - float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - float32_t A2; /**< The derived gain, A2 = Kd . */ - float32_t state[3]; /**< The state array of length 3. */ - float32_t Kp; /**< The proportional gain. */ - float32_t Ki; /**< The integral gain. */ - float32_t Kd; /**< The derivative gain. */ - } arm_pid_instance_f32; - - - - /** - * @brief Initialization function for the floating-point PID Control. - * @param[in,out] S points to an instance of the PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - */ - void arm_pid_init_f32( - arm_pid_instance_f32 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the floating-point PID Control. - * @param[in,out] S is an instance of the floating-point PID Control structure - */ - void arm_pid_reset_f32( - arm_pid_instance_f32 * S); - - - /** - * @brief Initialization function for the Q31 PID Control. - * @param[in,out] S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - */ - void arm_pid_init_q31( - arm_pid_instance_q31 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q31 PID Control. - * @param[in,out] S points to an instance of the Q31 PID Control structure - */ - - void arm_pid_reset_q31( - arm_pid_instance_q31 * S); - - - /** - * @brief Initialization function for the Q15 PID Control. - * @param[in,out] S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - */ - void arm_pid_init_q15( - arm_pid_instance_q15 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q15 PID Control. - * @param[in,out] S points to an instance of the q15 PID Control structure - */ - void arm_pid_reset_q15( - arm_pid_instance_q15 * S); - - - /** - * @brief Instance structure for the floating-point Linear Interpolate function. - */ - typedef struct - { - uint32_t nValues; /**< nValues */ - float32_t x1; /**< x1 */ - float32_t xSpacing; /**< xSpacing */ - float32_t *pYData; /**< pointer to the table of Y values */ - } arm_linear_interp_instance_f32; - - /** - * @brief Instance structure for the floating-point bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - float32_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_f32; - - /** - * @brief Instance structure for the Q31 bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q31_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q31; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q15_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q15; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q7_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q7; - - - /** - * @brief Q7 vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Floating-point vector multiplication. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_mult_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q15( - arm_cfft_radix2_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q15( - const arm_cfft_radix2_instance_q15 * S, - q15_t * pSrc); - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q15( - arm_cfft_radix4_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_q15( - const arm_cfft_radix4_instance_q15 * S, - q15_t * pSrc); - - /** - * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q31; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q31( - arm_cfft_radix2_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q31( - const arm_cfft_radix2_instance_q31 * S, - q31_t * pSrc); - - /** - * @brief Instance structure for the Q31 CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q31; - -/* Deprecated */ - void arm_cfft_radix4_q31( - const arm_cfft_radix4_instance_q31 * S, - q31_t * pSrc); - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q31( - arm_cfft_radix4_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix2_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_f32( - arm_cfft_radix2_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_f32( - const arm_cfft_radix2_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix4_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_f32( - arm_cfft_radix4_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_f32( - const arm_cfft_radix4_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q15; - -void arm_cfft_q15( - const arm_cfft_instance_q15 * S, - q15_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q31; - -void arm_cfft_q31( - const arm_cfft_instance_q31 * S, - q31_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_f32; - - void arm_cfft_f32( - const arm_cfft_instance_f32 * S, - float32_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the Q15 RFFT/RIFFT function. - */ - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q15; - - arm_status arm_rfft_init_q15( - arm_rfft_instance_q15 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q15( - const arm_rfft_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst); - - /** - * @brief Instance structure for the Q31 RFFT/RIFFT function. - */ - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q31; - - arm_status arm_rfft_init_q31( - arm_rfft_instance_q31 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q31( - const arm_rfft_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint16_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_f32; - - arm_status arm_rfft_init_f32( - arm_rfft_instance_f32 * S, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_f32( - const arm_rfft_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ -typedef struct - { - arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ - uint16_t fftLenRFFT; /**< length of the real sequence */ - float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ - } arm_rfft_fast_instance_f32 ; - -arm_status arm_rfft_fast_init_f32 ( - arm_rfft_fast_instance_f32 * S, - uint16_t fftLen); - -void arm_rfft_fast_f32( - arm_rfft_fast_instance_f32 * S, - float32_t * p, float32_t * pOut, - uint8_t ifftFlag); - - /** - * @brief Instance structure for the floating-point DCT4/IDCT4 function. - */ - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - float32_t normalize; /**< normalizing factor. */ - float32_t *pTwiddle; /**< points to the twiddle factor table. */ - float32_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_f32; - - - /** - * @brief Initialization function for the floating-point DCT4/IDCT4. - * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. - * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. - * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. - */ - arm_status arm_dct4_init_f32( - arm_dct4_instance_f32 * S, - arm_rfft_instance_f32 * S_RFFT, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint16_t N, - uint16_t Nby2, - float32_t normalize); - - - /** - * @brief Processing function for the floating-point DCT4/IDCT4. - * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. - * @param[in] pState points to state buffer. - * @param[in,out] pInlineBuffer points to the in-place input and output buffer. - */ - void arm_dct4_f32( - const arm_dct4_instance_f32 * S, - float32_t * pState, - float32_t * pInlineBuffer); - - - /** - * @brief Instance structure for the Q31 DCT4/IDCT4 function. - */ - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q31_t normalize; /**< normalizing factor. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - q31_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q31; - - - /** - * @brief Initialization function for the Q31 DCT4/IDCT4. - * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. - * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure - * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - arm_status arm_dct4_init_q31( - arm_dct4_instance_q31 * S, - arm_rfft_instance_q31 * S_RFFT, - arm_cfft_radix4_instance_q31 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q31_t normalize); - - - /** - * @brief Processing function for the Q31 DCT4/IDCT4. - * @param[in] S points to an instance of the Q31 DCT4 structure. - * @param[in] pState points to state buffer. - * @param[in,out] pInlineBuffer points to the in-place input and output buffer. - */ - void arm_dct4_q31( - const arm_dct4_instance_q31 * S, - q31_t * pState, - q31_t * pInlineBuffer); - - - /** - * @brief Instance structure for the Q15 DCT4/IDCT4 function. - */ - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q15_t normalize; /**< normalizing factor. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - q15_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q15; - - - /** - * @brief Initialization function for the Q15 DCT4/IDCT4. - * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. - * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. - * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - arm_status arm_dct4_init_q15( - arm_dct4_instance_q15 * S, - arm_rfft_instance_q15 * S_RFFT, - arm_cfft_radix4_instance_q15 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q15_t normalize); - - - /** - * @brief Processing function for the Q15 DCT4/IDCT4. - * @param[in] S points to an instance of the Q15 DCT4 structure. - * @param[in] pState points to state buffer. - * @param[in,out] pInlineBuffer points to the in-place input and output buffer. - */ - void arm_dct4_q15( - const arm_dct4_instance_q15 * S, - q15_t * pState, - q15_t * pInlineBuffer); - - - /** - * @brief Floating-point vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q7 vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector addition. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_add_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Floating-point vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q7 vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector subtraction. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in each vector - */ - void arm_sub_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a floating-point vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scale scale factor to be applied - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_f32( - float32_t * pSrc, - float32_t scale, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a Q7 vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_q7( - q7_t * pSrc, - q7_t scaleFract, - int8_t shift, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a Q15 vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_q15( - q15_t * pSrc, - q15_t scaleFract, - int8_t shift, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Multiplies a Q31 vector by a scalar. - * @param[in] pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_scale_q31( - q31_t * pSrc, - q31_t scaleFract, - int8_t shift, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q7 vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Floating-point vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q15 vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Q31 vector absolute value. - * @param[in] pSrc points to the input buffer - * @param[out] pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - */ - void arm_abs_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Dot product of floating-point vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t blockSize, - float32_t * result); - - - /** - * @brief Dot product of Q7 vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_q7( - q7_t * pSrcA, - q7_t * pSrcB, - uint32_t blockSize, - q31_t * result); - - - /** - * @brief Dot product of Q15 vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - - /** - * @brief Dot product of Q31 vectors. - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] result output result returned here - */ - void arm_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - - /** - * @brief Shifts the elements of a Q7 vector a specified number of bits. - * @param[in] pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_shift_q7( - q7_t * pSrc, - int8_t shiftBits, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Shifts the elements of a Q15 vector a specified number of bits. - * @param[in] pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_shift_q15( - q15_t * pSrc, - int8_t shiftBits, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Shifts the elements of a Q31 vector a specified number of bits. - * @param[in] pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_shift_q31( - q31_t * pSrc, - int8_t shiftBits, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a floating-point vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_f32( - float32_t * pSrc, - float32_t offset, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a Q7 vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_q7( - q7_t * pSrc, - q7_t offset, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a Q15 vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_q15( - q15_t * pSrc, - q15_t offset, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Adds a constant offset to a Q31 vector. - * @param[in] pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_offset_q31( - q31_t * pSrc, - q31_t offset, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a floating-point vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a Q7 vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a Q15 vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Negates the elements of a Q31 vector. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] blockSize number of samples in the vector - */ - void arm_negate_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a floating-point vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a Q7 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a Q15 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Copies the elements of a Q31 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_copy_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a floating-point vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_f32( - float32_t value, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a Q7 vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_q7( - q7_t value, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a Q15 vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_q15( - q15_t value, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Fills a constant value into a Q31 vector. - * @param[in] value input value to be filled - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_fill_q31( - q31_t value, - q31_t * pDst, - uint32_t blockSize); - - -/** - * @brief Convolution of floating-point sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - */ - void arm_conv_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - */ - void arm_conv_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - */ - void arm_conv_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - */ - void arm_conv_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Convolution of Q31 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - */ - void arm_conv_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. - */ - void arm_conv_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Partial convolution of floating-point sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Partial convolution of Q31 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q7 sequences - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Partial convolution of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - arm_status arm_conv_partial_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Instance structure for the Q15 FIR decimator. - */ - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR decimator. - */ - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR decimator. - */ - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_f32; - - - /** - * @brief Processing function for the floating-point FIR decimator. - * @param[in] S points to an instance of the floating-point FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_f32( - const arm_fir_decimate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR decimator. - * @param[in,out] S points to an instance of the floating-point FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - arm_status arm_fir_decimate_init_f32( - arm_fir_decimate_instance_f32 * S, - uint16_t numTaps, - uint8_t M, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR decimator. - * @param[in] S points to an instance of the Q15 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q15 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_fast_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR decimator. - * @param[in,out] S points to an instance of the Q15 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - arm_status arm_fir_decimate_init_q15( - arm_fir_decimate_instance_q15 * S, - uint16_t numTaps, - uint8_t M, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 FIR decimator. - * @param[in] S points to an instance of the Q31 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_q31( - const arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] S points to an instance of the Q31 FIR decimator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_decimate_fast_q31( - arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR decimator. - * @param[in,out] S points to an instance of the Q31 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - arm_status arm_fir_decimate_init_q31( - arm_fir_decimate_instance_q31 * S, - uint16_t numTaps, - uint8_t M, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 FIR interpolator. - */ - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR interpolator. - */ - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR interpolator. - */ - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ - } arm_fir_interpolate_instance_f32; - - - /** - * @brief Processing function for the Q15 FIR interpolator. - * @param[in] S points to an instance of the Q15 FIR interpolator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_interpolate_q15( - const arm_fir_interpolate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR interpolator. - * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - arm_status arm_fir_interpolate_init_q15( - arm_fir_interpolate_instance_q15 * S, - uint8_t L, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 FIR interpolator. - * @param[in] S points to an instance of the Q15 FIR interpolator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_interpolate_q31( - const arm_fir_interpolate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR interpolator. - * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - arm_status arm_fir_interpolate_init_q31( - arm_fir_interpolate_instance_q31 * S, - uint8_t L, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR interpolator. - * @param[in] S points to an instance of the floating-point FIR interpolator structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_interpolate_f32( - const arm_fir_interpolate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR interpolator. - * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] pCoeffs points to the filter coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - arm_status arm_fir_interpolate_init_f32( - arm_fir_interpolate_instance_f32 * S, - uint8_t L, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the high precision Q31 Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ - } arm_biquad_cas_df1_32x64_ins_q31; - - - /** - * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cas_df1_32x64_q31( - const arm_biquad_cas_df1_32x64_ins_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format - */ - void arm_biquad_cas_df1_32x64_init_q31( - arm_biquad_cas_df1_32x64_ins_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q63_t * pState, - uint8_t postShift); - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f32; - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_stereo_df2T_instance_f32; - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f64; - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] S points to an instance of the filter data structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df2T_f32( - const arm_biquad_cascade_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels - * @param[in] S points to an instance of the filter data structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_stereo_df2T_f32( - const arm_biquad_cascade_stereo_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] S points to an instance of the filter data structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_biquad_cascade_df2T_f64( - const arm_biquad_cascade_df2T_instance_f64 * S, - float64_t * pSrc, - float64_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_df2T_init_f32( - arm_biquad_cascade_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_stereo_df2T_init_f32( - arm_biquad_cascade_stereo_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] pCoeffs points to the filter coefficients. - * @param[in] pState points to the state buffer. - */ - void arm_biquad_cascade_df2T_init_f64( - arm_biquad_cascade_df2T_instance_f64 * S, - uint8_t numStages, - float64_t * pCoeffs, - float64_t * pState); - - - /** - * @brief Instance structure for the Q15 FIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_f32; - - - /** - * @brief Initialization function for the Q15 FIR lattice filter. - * @param[in] S points to an instance of the Q15 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] pState points to the state buffer. The array is of length numStages. - */ - void arm_fir_lattice_init_q15( - arm_fir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pCoeffs, - q15_t * pState); - - - /** - * @brief Processing function for the Q15 FIR lattice filter. - * @param[in] S points to an instance of the Q15 FIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_fir_lattice_q15( - const arm_fir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR lattice filter. - * @param[in] S points to an instance of the Q31 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] pState points to the state buffer. The array is of length numStages. - */ - void arm_fir_lattice_init_q31( - arm_fir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pCoeffs, - q31_t * pState); - - - /** - * @brief Processing function for the Q31 FIR lattice filter. - * @param[in] S points to an instance of the Q31 FIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_fir_lattice_q31( - const arm_fir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the floating-point FIR lattice filter. - * @param[in] S points to an instance of the floating-point FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] pState points to the state buffer. The array is of length numStages. - */ - void arm_fir_lattice_init_f32( - arm_fir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Processing function for the floating-point FIR lattice filter. - * @param[in] S points to an instance of the floating-point FIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] blockSize number of samples to process. - */ - void arm_fir_lattice_f32( - const arm_fir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_f32; - - - /** - * @brief Processing function for the floating-point IIR lattice filter. - * @param[in] S points to an instance of the floating-point IIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_f32( - const arm_iir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point IIR lattice filter. - * @param[in] S points to an instance of the floating-point IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_init_f32( - arm_iir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pkCoeffs, - float32_t * pvCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 IIR lattice filter. - * @param[in] S points to an instance of the Q31 IIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_q31( - const arm_iir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 IIR lattice filter. - * @param[in] S points to an instance of the Q31 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_init_q31( - arm_iir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pkCoeffs, - q31_t * pvCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 IIR lattice filter. - * @param[in] S points to an instance of the Q15 IIR lattice structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - */ - void arm_iir_lattice_q15( - const arm_iir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the Q15 IIR lattice filter. - * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process per call. - */ - void arm_iir_lattice_init_q15( - arm_iir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pkCoeffs, - q15_t * pvCoeffs, - q15_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the floating-point LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that controls filter coefficient updates. */ - } arm_lms_instance_f32; - - - /** - * @brief Processing function for floating-point LMS filter. - * @param[in] S points to an instance of the floating-point LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_f32( - const arm_lms_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for floating-point LMS filter. - * @param[in] S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to the coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_init_f32( - arm_lms_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q15; - - - /** - * @brief Initialization function for the Q15 LMS filter. - * @param[in] S points to an instance of the Q15 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to the coefficient buffer. - * @param[in] pState points to the state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_init_q15( - arm_lms_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint32_t postShift); - - - /** - * @brief Processing function for Q15 LMS filter. - * @param[in] S points to an instance of the Q15 LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_q15( - const arm_lms_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q31; - - - /** - * @brief Processing function for Q31 LMS filter. - * @param[in] S points to an instance of the Q15 LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_q31( - const arm_lms_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q31 LMS filter. - * @param[in] S points to an instance of the Q31 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_init_q31( - arm_lms_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint32_t postShift); - - - /** - * @brief Instance structure for the floating-point normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that control filter coefficient updates. */ - float32_t energy; /**< saves previous frame energy. */ - float32_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_f32; - - - /** - * @brief Processing function for floating-point normalized LMS filter. - * @param[in] S points to an instance of the floating-point normalized LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_f32( - arm_lms_norm_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for floating-point normalized LMS filter. - * @param[in] S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_init_f32( - arm_lms_norm_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q31_t *recipTable; /**< points to the reciprocal initial value table. */ - q31_t energy; /**< saves previous frame energy. */ - q31_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q31; - - - /** - * @brief Processing function for Q31 normalized LMS filter. - * @param[in] S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_q31( - arm_lms_norm_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q31 normalized LMS filter. - * @param[in] S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_norm_init_q31( - arm_lms_norm_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint8_t postShift); - - - /** - * @brief Instance structure for the Q15 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< Number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q15_t *recipTable; /**< Points to the reciprocal initial value table. */ - q15_t energy; /**< saves previous frame energy. */ - q15_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q15; - - - /** - * @brief Processing function for Q15 normalized LMS filter. - * @param[in] S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] pSrc points to the block of input data. - * @param[in] pRef points to the block of reference data. - * @param[out] pOut points to the block of output data. - * @param[out] pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - */ - void arm_lms_norm_q15( - arm_lms_norm_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q15 normalized LMS filter. - * @param[in] S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] pCoeffs points to coefficient buffer. - * @param[in] pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - */ - void arm_lms_norm_init_q15( - arm_lms_norm_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint8_t postShift); - - - /** - * @brief Correlation of floating-point sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Correlation of Q15 sequences - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - */ - void arm_correlate_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - - /** - * @brief Correlation of Q15 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - - void arm_correlate_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - - void arm_correlate_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - */ - void arm_correlate_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - - /** - * @brief Correlation of Q31 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - */ - void arm_correlate_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - */ - void arm_correlate_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Instance structure for the floating-point sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_f32; - - /** - * @brief Instance structure for the Q31 sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q31; - - /** - * @brief Instance structure for the Q15 sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q15; - - /** - * @brief Instance structure for the Q7 sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q7; - - - /** - * @brief Processing function for the floating-point sparse FIR filter. - * @param[in] S points to an instance of the floating-point sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_f32( - arm_fir_sparse_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - float32_t * pScratchIn, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point sparse FIR filter. - * @param[in,out] S points to an instance of the floating-point sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_f32( - arm_fir_sparse_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 sparse FIR filter. - * @param[in] S points to an instance of the Q31 sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_q31( - arm_fir_sparse_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - q31_t * pScratchIn, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 sparse FIR filter. - * @param[in,out] S points to an instance of the Q31 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_q31( - arm_fir_sparse_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 sparse FIR filter. - * @param[in] S points to an instance of the Q15 sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_q15( - arm_fir_sparse_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - q15_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 sparse FIR filter. - * @param[in,out] S points to an instance of the Q15 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_q15( - arm_fir_sparse_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q7 sparse FIR filter. - * @param[in] S points to an instance of the Q7 sparse FIR structure. - * @param[in] pSrc points to the block of input data. - * @param[out] pDst points to the block of output data - * @param[in] pScratchIn points to a temporary buffer of size blockSize. - * @param[in] pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - */ - void arm_fir_sparse_q7( - arm_fir_sparse_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - q7_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 sparse FIR filter. - * @param[in,out] S points to an instance of the Q7 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] pCoeffs points to the array of filter coefficients. - * @param[in] pState points to the state buffer. - * @param[in] pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - */ - void arm_fir_sparse_init_q7( - arm_fir_sparse_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /** - * @brief Floating-point sin_cos function. - * @param[in] theta input value in degrees - * @param[out] pSinVal points to the processed sine output. - * @param[out] pCosVal points to the processed cos output. - */ - void arm_sin_cos_f32( - float32_t theta, - float32_t * pSinVal, - float32_t * pCosVal); - - - /** - * @brief Q31 sin_cos function. - * @param[in] theta scaled input value in degrees - * @param[out] pSinVal points to the processed sine output. - * @param[out] pCosVal points to the processed cosine output. - */ - void arm_sin_cos_q31( - q31_t theta, - q31_t * pSinVal, - q31_t * pCosVal); - - - /** - * @brief Floating-point complex conjugate. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_conj_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex conjugate. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_conj_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex conjugate. - * @param[in] pSrc points to the input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_conj_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @brief Floating-point complex magnitude squared - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_squared_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex magnitude squared - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_squared_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex magnitude squared - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_squared_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup PID PID Motor Control - * - * A Proportional Integral Derivative (PID) controller is a generic feedback control - * loop mechanism widely used in industrial control systems. - * A PID controller is the most commonly used type of feedback controller. - * - * This set of functions implements (PID) controllers - * for Q15, Q31, and floating-point data types. The functions operate on a single sample - * of data and each call to the function returns a single processed value. - * S points to an instance of the PID control data structure. in - * is the input sample value. The functions return the output value. - * - * \par Algorithm: - *
    -   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
    -   *    A0 = Kp + Ki + Kd
    -   *    A1 = (-Kp ) - (2 * Kd )
    -   *    A2 = Kd  
    - * - * \par - * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant - * - * \par - * \image html PID.gif "Proportional Integral Derivative Controller" - * - * \par - * The PID controller calculates an "error" value as the difference between - * the measured output and the reference input. - * The controller attempts to minimize the error by adjusting the process control inputs. - * The proportional value determines the reaction to the current error, - * the integral value determines the reaction based on the sum of recent errors, - * and the derivative value determines the reaction based on the rate at which the error has been changing. - * - * \par Instance Structure - * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. - * A separate instance structure must be defined for each PID Controller. - * There are separate instance structure declarations for each of the 3 supported data types. - * - * \par Reset Functions - * There is also an associated reset function for each data type which clears the state array. - * - * \par Initialization Functions - * There is also an associated initialization function for each data type. - * The initialization function performs the following operations: - * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. - * - Zeros out the values in the state buffer. - * - * \par - * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. - * - * \par Fixed-Point Behavior - * Care must be taken when using the fixed-point versions of the PID Controller functions. - * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup PID - * @{ - */ - - /** - * @brief Process function for the floating-point PID Control. - * @param[in,out] S is an instance of the floating-point PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - */ - CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32( - arm_pid_instance_f32 * S, - float32_t in) - { - float32_t out; - - /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ - out = (S->A0 * in) + - (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q31 PID Control. - * @param[in,out] S points to an instance of the Q31 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 64-bit accumulator. - * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. - * Thus, if the accumulator result overflows it wraps around rather than clip. - * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. - * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. - */ - CMSIS_INLINE __STATIC_INLINE q31_t arm_pid_q31( - arm_pid_instance_q31 * S, - q31_t in) - { - q63_t acc; - q31_t out; - - /* acc = A0 * x[n] */ - acc = (q63_t) S->A0 * in; - - /* acc += A1 * x[n-1] */ - acc += (q63_t) S->A1 * S->state[0]; - - /* acc += A2 * x[n-2] */ - acc += (q63_t) S->A2 * S->state[1]; - - /* convert output to 1.31 format to add y[n-1] */ - out = (q31_t) (acc >> 31u); - - /* out += y[n-1] */ - out += S->state[2]; - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - } - - - /** - * @brief Process function for the Q15 PID Control. - * @param[in,out] S points to an instance of the Q15 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using a 64-bit internal accumulator. - * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. - * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. - * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. - * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. - * Lastly, the accumulator is saturated to yield a result in 1.15 format. - */ - CMSIS_INLINE __STATIC_INLINE q15_t arm_pid_q15( - arm_pid_instance_q15 * S, - q15_t in) - { - q63_t acc; - q15_t out; - -#if defined (ARM_MATH_DSP) - __SIMD32_TYPE *vstate; - - /* Implementation of PID controller */ - - /* acc = A0 * x[n] */ - acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - vstate = __SIMD32_CONST(S->state); - acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); -#else - /* acc = A0 * x[n] */ - acc = ((q31_t) S->A0) * in; - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - acc += (q31_t) S->A1 * S->state[0]; - acc += (q31_t) S->A2 * S->state[1]; -#endif - - /* acc += y[n-1] */ - acc += (q31_t) S->state[2] << 15; - - /* saturate the output */ - out = (q15_t) (__SSAT((acc >> 15), 16)); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - } - - /** - * @} end of PID group - */ - - - /** - * @brief Floating-point matrix inverse. - * @param[in] src points to the instance of the input floating-point matrix structure. - * @param[out] dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - arm_status arm_mat_inverse_f32( - const arm_matrix_instance_f32 * src, - arm_matrix_instance_f32 * dst); - - - /** - * @brief Floating-point matrix inverse. - * @param[in] src points to the instance of the input floating-point matrix structure. - * @param[out] dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - arm_status arm_mat_inverse_f64( - const arm_matrix_instance_f64 * src, - arm_matrix_instance_f64 * dst); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup clarke Vector Clarke Transform - * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. - * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents - * in the two-phase orthogonal stator axis Ialpha and Ibeta. - * When Ialpha is superposed with Ia as shown in the figure below - * \image html clarke.gif Stator current space vector and its components in (a,b). - * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta - * can be calculated using only Ia and Ib. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeFormula.gif - * where Ia and Ib are the instantaneous stator phases and - * pIalpha and pIbeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup clarke - * @{ - */ - - /** - * - * @brief Floating-point Clarke transform - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - */ - CMSIS_INLINE __STATIC_INLINE void arm_clarke_f32( - float32_t Ia, - float32_t Ib, - float32_t * pIalpha, - float32_t * pIbeta) - { - /* Calculate pIalpha using the equation, pIalpha = Ia */ - *pIalpha = Ia; - - /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ - *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); - } - - - /** - * @brief Clarke transform for Q31 version - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_clarke_q31( - q31_t Ia, - q31_t Ib, - q31_t * pIalpha, - q31_t * pIbeta) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIalpha from Ia by equation pIalpha = Ia */ - *pIalpha = Ia; - - /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); - - /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ - product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); - - /* pIbeta is calculated by adding the intermediate products */ - *pIbeta = __QADD(product1, product2); - } - - /** - * @} end of clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q31 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_q7_to_q31( - q7_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_clarke Vector Inverse Clarke Transform - * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeInvFormula.gif - * where pIa and pIb are the instantaneous stator phases and - * Ialpha and Ibeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_clarke - * @{ - */ - - /** - * @brief Floating-point Inverse Clarke transform - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] pIa points to output three-phase coordinate a - * @param[out] pIb points to output three-phase coordinate b - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pIa, - float32_t * pIb) - { - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ - *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; - } - - - /** - * @brief Inverse Clarke transform for Q31 version - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] pIa points to output three-phase coordinate a - * @param[out] pIb points to output three-phase coordinate b - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the subtraction, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pIa, - q31_t * pIb) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); - - /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); - - /* pIb is calculated by subtracting the products */ - *pIb = __QSUB(product2, product1); - } - - /** - * @} end of inv_clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q15 vector. - * @param[in] pSrc input pointer - * @param[out] pDst output pointer - * @param[in] blockSize number of samples to process - */ - void arm_q7_to_q15( - q7_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup park Vector Park Transform - * - * Forward Park transform converts the input two-coordinate vector to flux and torque components. - * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents - * from the stationary to the moving reference frame and control the spatial relationship between - * the stator vector current and rotor flux vector. - * If we consider the d axis aligned with the rotor flux, the diagram below shows the - * current vector and the relationship from the two reference frames: - * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkFormula.gif - * where Ialpha and Ibeta are the stator vector components, - * pId and pIq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup park - * @{ - */ - - /** - * @brief Floating-point Park transform - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] pId points to output rotor reference frame d - * @param[out] pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * - * The function implements the forward Park transform. - * - */ - CMSIS_INLINE __STATIC_INLINE void arm_park_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pId, - float32_t * pIq, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ - *pId = Ialpha * cosVal + Ibeta * sinVal; - - /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ - *pIq = -Ialpha * sinVal + Ibeta * cosVal; - } - - - /** - * @brief Park transform for Q31 version - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] pId points to output rotor reference frame d - * @param[out] pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition and subtraction, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_park_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pId, - q31_t * pIq, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Ialpha * cosVal) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * sinVal) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Ialpha * sinVal) */ - product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * cosVal) */ - product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); - - /* Calculate pId by adding the two intermediate products 1 and 2 */ - *pId = __QADD(product1, product2); - - /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ - *pIq = __QSUB(product4, product3); - } - - /** - * @} end of park group - */ - - /** - * @brief Converts the elements of the Q7 vector to floating-point vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q7_to_float( - q7_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_park Vector Inverse Park transform - * Inverse Park transform converts the input flux and torque components to two-coordinate vector. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkInvFormula.gif - * where pIalpha and pIbeta are the stator vector components, - * Id and Iq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_park - * @{ - */ - - /** - * @brief Floating-point Inverse Park transform - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_park_f32( - float32_t Id, - float32_t Iq, - float32_t * pIalpha, - float32_t * pIbeta, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ - *pIalpha = Id * cosVal - Iq * sinVal; - - /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ - *pIbeta = Id * sinVal + Iq * cosVal; - } - - - /** - * @brief Inverse Park transform for Q31 version - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - CMSIS_INLINE __STATIC_INLINE void arm_inv_park_q31( - q31_t Id, - q31_t Iq, - q31_t * pIalpha, - q31_t * pIbeta, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Id * cosVal) */ - product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Iq * sinVal) */ - product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Id * sinVal) */ - product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Iq * cosVal) */ - product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); - - /* Calculate pIalpha by using the two intermediate products 1 and 2 */ - *pIalpha = __QSUB(product1, product2); - - /* Calculate pIbeta by using the two intermediate products 3 and 4 */ - *pIbeta = __QADD(product4, product3); - } - - /** - * @} end of Inverse park group - */ - - - /** - * @brief Converts the elements of the Q31 vector to floating-point vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q31_to_float( - q31_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup LinearInterpolate Linear Interpolation - * - * Linear interpolation is a method of curve fitting using linear polynomials. - * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line - * - * \par - * \image html LinearInterp.gif "Linear interpolation" - * - * \par - * A Linear Interpolate function calculates an output value(y), for the input(x) - * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) - * - * \par Algorithm: - *
    -   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
    -   *       where x0, x1 are nearest values of input x
    -   *             y0, y1 are nearest values to output y
    -   * 
    - * - * \par - * This set of functions implements Linear interpolation process - * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single - * sample of data and each call to the function returns a single processed value. - * S points to an instance of the Linear Interpolate function data structure. - * x is the input sample value. The functions returns the output value. - * - * \par - * if x is outside of the table boundary, Linear interpolation returns first value of the table - * if x is below input range and returns last value of table if x is above range. - */ - - /** - * @addtogroup LinearInterpolate - * @{ - */ - - /** - * @brief Process function for the floating-point Linear Interpolation Function. - * @param[in,out] S is an instance of the floating-point Linear Interpolation structure - * @param[in] x input sample to process - * @return y processed output sample. - * - */ - CMSIS_INLINE __STATIC_INLINE float32_t arm_linear_interp_f32( - arm_linear_interp_instance_f32 * S, - float32_t x) - { - float32_t y; - float32_t x0, x1; /* Nearest input values */ - float32_t y0, y1; /* Nearest output values */ - float32_t xSpacing = S->xSpacing; /* spacing between input values */ - int32_t i; /* Index variable */ - float32_t *pYData = S->pYData; /* pointer to output table */ - - /* Calculation of index */ - i = (int32_t) ((x - S->x1) / xSpacing); - - if (i < 0) - { - /* Iniatilize output for below specified range as least output value of table */ - y = pYData[0]; - } - else if ((uint32_t)i >= S->nValues) - { - /* Iniatilize output for above specified range as last output value of table */ - y = pYData[S->nValues - 1]; - } - else - { - /* Calculation of nearest input values */ - x0 = S->x1 + i * xSpacing; - x1 = S->x1 + (i + 1) * xSpacing; - - /* Read of nearest output values */ - y0 = pYData[i]; - y1 = pYData[i + 1]; - - /* Calculation of output */ - y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); - - } - - /* returns output value */ - return (y); - } - - - /** - * - * @brief Process function for the Q31 Linear Interpolation Function. - * @param[in] pYData pointer to Q31 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - CMSIS_INLINE __STATIC_INLINE q31_t arm_linear_interp_q31( - q31_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q31_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & (q31_t)0xFFF00000) >> 20); - - if (index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if (index < 0) - { - return (pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* shift left by 11 to keep fract in 1.31 format */ - fract = (x & 0x000FFFFF) << 11; - - /* Read two nearest output values from the index in 1.31(q31) format */ - y0 = pYData[index]; - y1 = pYData[index + 1]; - - /* Calculation of y0 * (1-fract) and y is in 2.30 format */ - y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); - - /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ - y += ((q31_t) (((q63_t) y1 * fract) >> 32)); - - /* Convert y to 1.31 format */ - return (y << 1u); - } - } - - - /** - * - * @brief Process function for the Q15 Linear Interpolation Function. - * @param[in] pYData pointer to Q15 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - CMSIS_INLINE __STATIC_INLINE q15_t arm_linear_interp_q15( - q15_t * pYData, - q31_t x, - uint32_t nValues) - { - q63_t y; /* output */ - q15_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & (int32_t)0xFFF00000) >> 20); - - if (index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if (index < 0) - { - return (pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y0 = pYData[index]; - y1 = pYData[index + 1]; - - /* Calculation of y0 * (1-fract) and y is in 13.35 format */ - y = ((q63_t) y0 * (0xFFFFF - fract)); - - /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ - y += ((q63_t) y1 * (fract)); - - /* convert y to 1.15 format */ - return (q15_t) (y >> 20); - } - } - - - /** - * - * @brief Process function for the Q7 Linear Interpolation Function. - * @param[in] pYData pointer to Q7 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - */ - CMSIS_INLINE __STATIC_INLINE q7_t arm_linear_interp_q7( - q7_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q7_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - uint32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - if (x < 0) - { - return (pYData[0]); - } - index = (x >> 20) & 0xfff; - - if (index >= (nValues - 1)) - { - return (pYData[nValues - 1]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index and are in 1.7(q7) format */ - y0 = pYData[index]; - y1 = pYData[index + 1]; - - /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ - y = ((y0 * (0xFFFFF - fract))); - - /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ - y += (y1 * fract); - - /* convert y to 1.7(q7) format */ - return (q7_t) (y >> 20); - } - } - - /** - * @} end of LinearInterpolate group - */ - - /** - * @brief Fast approximation to the trigonometric sine function for floating-point data. - * @param[in] x input value in radians. - * @return sin(x). - */ - float32_t arm_sin_f32( - float32_t x); - - - /** - * @brief Fast approximation to the trigonometric sine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - q31_t arm_sin_q31( - q31_t x); - - - /** - * @brief Fast approximation to the trigonometric sine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - q15_t arm_sin_q15( - q15_t x); - - - /** - * @brief Fast approximation to the trigonometric cosine function for floating-point data. - * @param[in] x input value in radians. - * @return cos(x). - */ - float32_t arm_cos_f32( - float32_t x); - - - /** - * @brief Fast approximation to the trigonometric cosine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - q31_t arm_cos_q31( - q31_t x); - - - /** - * @brief Fast approximation to the trigonometric cosine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - q15_t arm_cos_q15( - q15_t x); - - - /** - * @ingroup groupFastMath - */ - - - /** - * @defgroup SQRT Square Root - * - * Computes the square root of a number. - * There are separate functions for Q15, Q31, and floating-point data types. - * The square root function is computed using the Newton-Raphson algorithm. - * This is an iterative algorithm of the form: - *
    -   *      x1 = x0 - f(x0)/f'(x0)
    -   * 
    - * where x1 is the current estimate, - * x0 is the previous estimate, and - * f'(x0) is the derivative of f() evaluated at x0. - * For the square root function, the algorithm reduces to: - *
    -   *     x0 = in/2                         [initial guess]
    -   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
    -   * 
    - */ - - - /** - * @addtogroup SQRT - * @{ - */ - - /** - * @brief Floating-point square root function. - * @param[in] in input value. - * @param[out] pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - CMSIS_INLINE __STATIC_INLINE arm_status arm_sqrt_f32( - float32_t in, - float32_t * pOut) - { - if (in >= 0.0f) - { - -#if (__FPU_USED == 1) && defined ( __CC_ARM ) - *pOut = __sqrtf(in); -#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) - *pOut = __builtin_sqrtf(in); -#elif (__FPU_USED == 1) && defined(__GNUC__) - *pOut = __builtin_sqrtf(in); -#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) - __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); -#else - *pOut = sqrtf(in); -#endif - - return (ARM_MATH_SUCCESS); - } - else - { - *pOut = 0.0f; - return (ARM_MATH_ARGUMENT_ERROR); - } - } - - - /** - * @brief Q31 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. - * @param[out] pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q31( - q31_t in, - q31_t * pOut); - - - /** - * @brief Q15 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. - * @param[out] pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q15( - q15_t in, - q15_t * pOut); - - /** - * @} end of SQRT group - */ - - - /** - * @brief floating-point Circular write function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_f32( - int32_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const int32_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if (wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = (uint16_t)wOffset; - } - - - - /** - * @brief floating-point Circular Read function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularRead_f32( - int32_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - int32_t * dst, - int32_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if (dst == (int32_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if (rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Q15 Circular write function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q15( - q15_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q15_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if (wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = (uint16_t)wOffset; - } - - - /** - * @brief Q15 Circular Read function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q15( - q15_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q15_t * dst, - q15_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if (dst == (q15_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update wOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if (rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Q7 Circular write function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q7( - q7_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q7_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if (wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = (uint16_t)wOffset; - } - - - /** - * @brief Q7 Circular Read function. - */ - CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q7( - q7_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q7_t * dst, - q7_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while (i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if (dst == (q7_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if (rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Sum of the squares of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_q31( - q31_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - - /** - * @brief Sum of the squares of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Sum of the squares of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_q15( - q15_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - - /** - * @brief Sum of the squares of the elements of a Q7 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_power_q7( - q7_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Mean value of a Q7 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult); - - - /** - * @brief Mean value of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Mean value of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Mean value of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_mean_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Variance of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_var_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Variance of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_var_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Variance of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_var_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Root Mean Square of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_rms_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Root Mean Square of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_rms_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Root Mean Square of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_rms_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Standard deviation of the elements of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_std_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - - /** - * @brief Standard deviation of the elements of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_std_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - - /** - * @brief Standard deviation of the elements of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output value. - */ - void arm_std_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - - /** - * @brief Floating-point complex magnitude - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex magnitude - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex magnitude - * @param[in] pSrc points to the complex input vector - * @param[out] pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - */ - void arm_cmplx_mag_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q15 complex dot product - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] realResult real part of the result returned here - * @param[out] imagResult imaginary part of the result returned here - */ - void arm_cmplx_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t numSamples, - q31_t * realResult, - q31_t * imagResult); - - - /** - * @brief Q31 complex dot product - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] realResult real part of the result returned here - * @param[out] imagResult imaginary part of the result returned here - */ - void arm_cmplx_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t numSamples, - q63_t * realResult, - q63_t * imagResult); - - - /** - * @brief Floating-point complex dot product - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] realResult real part of the result returned here - * @param[out] imagResult imaginary part of the result returned here - */ - void arm_cmplx_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t numSamples, - float32_t * realResult, - float32_t * imagResult); - - - /** - * @brief Q15 complex-by-real multiplication - * @param[in] pSrcCmplx points to the complex input vector - * @param[in] pSrcReal points to the real input vector - * @param[out] pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - */ - void arm_cmplx_mult_real_q15( - q15_t * pSrcCmplx, - q15_t * pSrcReal, - q15_t * pCmplxDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex-by-real multiplication - * @param[in] pSrcCmplx points to the complex input vector - * @param[in] pSrcReal points to the real input vector - * @param[out] pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - */ - void arm_cmplx_mult_real_q31( - q31_t * pSrcCmplx, - q31_t * pSrcReal, - q31_t * pCmplxDst, - uint32_t numSamples); - - - /** - * @brief Floating-point complex-by-real multiplication - * @param[in] pSrcCmplx points to the complex input vector - * @param[in] pSrcReal points to the real input vector - * @param[out] pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - */ - void arm_cmplx_mult_real_f32( - float32_t * pSrcCmplx, - float32_t * pSrcReal, - float32_t * pCmplxDst, - uint32_t numSamples); - - - /** - * @brief Minimum value of a Q7 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] result is output pointer - * @param[in] index is the array index of the minimum value in the input buffer. - */ - void arm_min_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * result, - uint32_t * index); - - - /** - * @brief Minimum value of a Q15 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output pointer - * @param[in] pIndex is the array index of the minimum value in the input buffer. - */ - void arm_min_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - - - /** - * @brief Minimum value of a Q31 vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output pointer - * @param[out] pIndex is the array index of the minimum value in the input buffer. - */ - void arm_min_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - - - /** - * @brief Minimum value of a floating-point vector. - * @param[in] pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] pResult is output pointer - * @param[out] pIndex is the array index of the minimum value in the input buffer. - */ - void arm_min_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a Q7 vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a Q15 vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a Q31 vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - - -/** - * @brief Maximum value of a floating-point vector. - * @param[in] pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] pResult maximum value returned here - * @param[out] pIndex index of maximum value returned here - */ - void arm_max_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - - - /** - * @brief Q15 complex-by-complex multiplication - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_mult_cmplx_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @brief Q31 complex-by-complex multiplication - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_mult_cmplx_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t numSamples); - - - /** - * @brief Floating-point complex-by-complex multiplication - * @param[in] pSrcA points to the first input vector - * @param[in] pSrcB points to the second input vector - * @param[out] pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - */ - void arm_cmplx_mult_cmplx_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t numSamples); - - - /** - * @brief Converts the elements of the floating-point vector to Q31 vector. - * @param[in] pSrc points to the floating-point input vector - * @param[out] pDst points to the Q31 output vector - * @param[in] blockSize length of the input vector - */ - void arm_float_to_q31( - float32_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the floating-point vector to Q15 vector. - * @param[in] pSrc points to the floating-point input vector - * @param[out] pDst points to the Q15 output vector - * @param[in] blockSize length of the input vector - */ - void arm_float_to_q15( - float32_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the floating-point vector to Q7 vector. - * @param[in] pSrc points to the floating-point input vector - * @param[out] pDst points to the Q7 output vector - * @param[in] blockSize length of the input vector - */ - void arm_float_to_q7( - float32_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q31 vector to Q15 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q31_to_q15( - q31_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q31 vector to Q7 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q31_to_q7( - q31_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to floating-point vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q15_to_float( - q15_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q31 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q15_to_q31( - q15_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q7 vector. - * @param[in] pSrc is input pointer - * @param[out] pDst is output pointer - * @param[in] blockSize is the number of samples to process - */ - void arm_q15_to_q7( - q15_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup BilinearInterpolate Bilinear Interpolation - * - * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. - * The underlying function f(x, y) is sampled on a regular grid and the interpolation process - * determines values between the grid points. - * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. - * Bilinear interpolation is often used in image processing to rescale images. - * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. - * - * Algorithm - * \par - * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. - * For floating-point, the instance structure is defined as: - *
    -   *   typedef struct
    -   *   {
    -   *     uint16_t numRows;
    -   *     uint16_t numCols;
    -   *     float32_t *pData;
    -   * } arm_bilinear_interp_instance_f32;
    -   * 
    - * - * \par - * where numRows specifies the number of rows in the table; - * numCols specifies the number of columns in the table; - * and pData points to an array of size numRows*numCols values. - * The data table pTable is organized in row order and the supplied data values fall on integer indexes. - * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. - * - * \par - * Let (x, y) specify the desired interpolation point. Then define: - *
    -   *     XF = floor(x)
    -   *     YF = floor(y)
    -   * 
    - * \par - * The interpolated output point is computed as: - *
    -   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
    -   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
    -   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
    -   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
    -   * 
    - * Note that the coordinates (x, y) contain integer and fractional components. - * The integer components specify which portion of the table to use while the - * fractional components control the interpolation processor. - * - * \par - * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. - */ - - /** - * @addtogroup BilinearInterpolate - * @{ - */ - - - /** - * - * @brief Floating-point bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate. - * @param[in] Y interpolation coordinate. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE float32_t arm_bilinear_interp_f32( - const arm_bilinear_interp_instance_f32 * S, - float32_t X, - float32_t Y) - { - float32_t out; - float32_t f00, f01, f10, f11; - float32_t *pData = S->pData; - int32_t xIndex, yIndex, index; - float32_t xdiff, ydiff; - float32_t b1, b2, b3, b4; - - xIndex = (int32_t) X; - yIndex = (int32_t) Y; - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) - { - return (0); - } - - /* Calculation of index for two nearest points in X-direction */ - index = (xIndex - 1) + (yIndex - 1) * S->numCols; - - - /* Read two nearest points in X-direction */ - f00 = pData[index]; - f01 = pData[index + 1]; - - /* Calculation of index for two nearest points in Y-direction */ - index = (xIndex - 1) + (yIndex) * S->numCols; - - - /* Read two nearest points in Y-direction */ - f10 = pData[index]; - f11 = pData[index + 1]; - - /* Calculation of intermediate values */ - b1 = f00; - b2 = f01 - f00; - b3 = f10 - f00; - b4 = f00 - f01 - f10 + f11; - - /* Calculation of fractional part in X */ - xdiff = X - xIndex; - - /* Calculation of fractional part in Y */ - ydiff = Y - yIndex; - - /* Calculation of bi-linear interpolated output */ - out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; - - /* return to application */ - return (out); - } - - - /** - * - * @brief Q31 bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE q31_t arm_bilinear_interp_q31( - arm_bilinear_interp_instance_q31 * S, - q31_t X, - q31_t Y) - { - q31_t out; /* Temporary output */ - q31_t acc = 0; /* output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q31_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q31_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & (q31_t)0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & (q31_t)0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* shift left xfract by 11 to keep 1.31 format */ - xfract = (X & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; - x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; - - /* 20 bits for the fractional part */ - /* shift left yfract by 11 to keep 1.31 format */ - yfract = (Y & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; - y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ - out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); - acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); - - /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); - - /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* Convert acc to 1.31(q31) format */ - return ((q31_t)(acc << 2)); - } - - - /** - * @brief Q15 bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE q15_t arm_bilinear_interp_q15( - arm_bilinear_interp_instance_q15 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q15_t x1, x2, y1, y2; /* Nearest output values */ - q31_t xfract, yfract; /* X, Y fractional parts */ - int32_t rI, cI; /* Row and column indices */ - q15_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & (q31_t)0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & (q31_t)0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & 0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; - x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; - y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ - - /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ - /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ - out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); - acc = ((q63_t) out * (0xFFFFF - yfract)); - - /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); - acc += ((q63_t) out * (xfract)); - - /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* acc is in 13.51 format and down shift acc by 36 times */ - /* Convert out to 1.15 format */ - return ((q15_t)(acc >> 36)); - } - - - /** - * @brief Q7 bilinear interpolation. - * @param[in,out] S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - CMSIS_INLINE __STATIC_INLINE q7_t arm_bilinear_interp_q7( - arm_bilinear_interp_instance_q7 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q7_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q7_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & (q31_t)0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & (q31_t)0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & (q31_t)0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; - x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & (q31_t)0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; - y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ - out = ((x1 * (0xFFFFF - xfract))); - acc = (((q63_t) out * (0xFFFFF - yfract))); - - /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ - out = ((x2 * (0xFFFFF - yfract))); - acc += (((q63_t) out * (xfract))); - - /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y1 * (0xFFFFF - xfract))); - acc += (((q63_t) out * (yfract))); - - /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y2 * (yfract))); - acc += (((q63_t) out * (xfract))); - - /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ - return ((q7_t)(acc >> 40)); - } - - /** - * @} end of BilinearInterpolate group - */ - - -/* SMMLAR */ -#define multAcc_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) - -/* SMMLSR */ -#define multSub_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) - -/* SMMULR */ -#define mult_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) - -/* SMMLA */ -#define multAcc_32x32_keep32(a, x, y) \ - a += (q31_t) (((q63_t) x * y) >> 32) - -/* SMMLS */ -#define multSub_32x32_keep32(a, x, y) \ - a -= (q31_t) (((q63_t) x * y) >> 32) - -/* SMMUL */ -#define mult_32x32_keep32(a, x, y) \ - a = (q31_t) (((q63_t) x * y ) >> 32) - - -#if defined ( __CC_ARM ) - /* Enter low optimization region - place directly above function definition */ - #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("push") \ - _Pragma ("O1") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - - /* Exit low optimization region - place directly after end of function definition */ - #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) - #define LOW_OPTIMIZATION_EXIT \ - _Pragma ("pop") - #else - #define LOW_OPTIMIZATION_EXIT - #endif - - /* Enter low optimization region - place directly above function definition */ - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - - /* Exit low optimization region - place directly after end of function definition */ - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __GNUC__ ) - #define LOW_OPTIMIZATION_ENTER \ - __attribute__(( optimize("-O1") )) - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __ICCARM__ ) - /* Enter low optimization region - place directly above function definition */ - #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - - /* Exit low optimization region - place directly after end of function definition */ - #define LOW_OPTIMIZATION_EXIT - - /* Enter low optimization region - place directly above function definition */ - #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #endif - - /* Exit low optimization region - place directly after end of function definition */ - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __TI_ARM__ ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __CSMC__ ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined ( __TASKING__ ) - #define LOW_OPTIMIZATION_ENTER - #define LOW_OPTIMIZATION_EXIT - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#endif - - -#ifdef __cplusplus -} -#endif - - -#if defined ( __GNUC__ ) -#pragma GCC diagnostic pop -#endif - -#endif /* _ARM_MATH_H */ - -/** - * - * End of file. - */ diff --git a/arch/arm/common/cmsis/cmsis_armcc.h b/arch/arm/common/cmsis/cmsis_armcc.h index 3ddc308fc..4d9d0645d 100644 --- a/arch/arm/common/cmsis/cmsis_armcc.h +++ b/arch/arm/common/cmsis/cmsis_armcc.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file cmsis_armcc.h - * @brief CMSIS compiler ARMCC (ARM compiler V5) header file - * @version V5.0.1 - * @date 03. February 2017 + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -27,7 +27,7 @@ #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" #endif /* CMSIS compiler control architecture macros */ @@ -50,36 +50,56 @@ /* CMSIS compiler specific defines */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm #endif #ifndef __INLINE - #define __INLINE __inline + #define __INLINE __inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static __inline + #define __STATIC_INLINE static __inline #endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif #ifndef __NO_RETURN - #define __NO_RETURN __declspec(noreturn) + #define __NO_RETURN __declspec(noreturn) #endif #ifndef __USED - #define __USED __attribute__((used)) + #define __USED __attribute__((used)) #endif #ifndef __WEAK - #define __WEAK __attribute__((weak)) -#endif -#ifndef __UNALIGNED_UINT32 - #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) -#endif -#ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) + #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED - #define __PACKED __attribute__((packed)) + #define __PACKED __attribute__((packed)) #endif #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT __packed struct + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict #endif - /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface @@ -317,8 +337,6 @@ __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ -#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) - /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. @@ -352,9 +370,6 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) #endif } -#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ - - /*@} end of CMSIS_Core_RegAccFunctions */ @@ -428,9 +443,10 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) __schedule_barrier();\ } while (0U) + /** \brief Reverse byte order (32 bit) - \details Reverses the byte order in integer value. + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ @@ -439,7 +455,7 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) /** \brief Reverse byte order (16 bit) - \details Reverses the byte order in two unsigned short values. + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ @@ -453,13 +469,13 @@ __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(u /** - \brief Reverse byte order in signed short value - \details Reverses the byte order in a signed short value with sign extension to integer. + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ #ifndef __NO_EMBEDDED_ASM -__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) { revsh r0, r0 bx lr @@ -500,17 +516,17 @@ __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(in __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) { uint32_t result; - int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) + for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; s--; } result <<= s; /* shift when v's highest bits are zero */ - return(result); + return result; } #endif @@ -707,6 +723,58 @@ __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint3 */ #define __STRT(value, ptr) __strt(value, ptr) +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ diff --git a/arch/arm/common/cmsis/cmsis_armclang.h b/arch/arm/common/cmsis/cmsis_armclang.h index be7d1f39f..162a400ea 100644 --- a/arch/arm/common/cmsis/cmsis_armclang.h +++ b/arch/arm/common/cmsis/cmsis_armclang.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file cmsis_armclang.h - * @brief CMSIS compiler ARMCLANG (ARM compiler V6) header file - * @version V5.0.1 - * @date 02. February 2017 + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -22,47 +22,93 @@ * limitations under the License. */ +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + #ifndef __CMSIS_ARMCLANG_H #define __CMSIS_ARMCLANG_H +#pragma clang system_header /* treat file as system include file */ + #ifndef __ARM_COMPAT_H -#include /* Compatibility header for ARM Compiler 5 intrinsics */ +#include /* Compatibility header for Arm Compiler 5 intrinsics */ #endif /* CMSIS compiler specific defines */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm #endif #ifndef __INLINE - #define __INLINE __inline + #define __INLINE __inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static __inline + #define __STATIC_INLINE static __inline #endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((noreturn)) + #define __NO_RETURN __attribute__((__noreturn__)) #endif #ifndef __USED - #define __USED __attribute__((used)) + #define __USED __attribute__((used)) #endif #ifndef __WEAK - #define __WEAK __attribute__((weak)) + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) #endif -#ifndef __UNALIGNED_UINT32 +#ifndef __UNALIGNED_UINT32 /* deprecated */ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ struct __attribute__((packed)) T_UINT32 { uint32_t v; }; #pragma clang diagnostic pop - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif -#ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif -#ifndef __PACKED - #define __PACKED __attribute__((packed, aligned(1))) +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif -#ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict #endif @@ -93,7 +139,7 @@ \details Returns the content of the Control Register. \return Control Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; @@ -108,7 +154,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) \details Returns the content of the non-secure Control Register when in secure mode. \return non-secure Control Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) { uint32_t result; @@ -123,7 +169,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } @@ -135,7 +181,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t contr \details Writes the given value to the non-secure Control Register when in secure state. \param [in] control Control Register value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) { __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); } @@ -147,7 +193,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t \details Returns the content of the IPSR Register. \return IPSR Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; @@ -161,7 +207,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) \details Returns the content of the APSR Register. \return APSR Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) +__STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; @@ -175,7 +221,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) \details Returns the content of the xPSR Register. \return xPSR Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; @@ -189,9 +235,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) +__STATIC_FORCEINLINE uint32_t __get_PSP(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, psp" : "=r" (result) ); return(result); @@ -204,9 +250,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. \return PSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); @@ -219,7 +265,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } @@ -231,7 +277,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProc \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. \param [in] topOfProcStack Process Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) { __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); } @@ -243,9 +289,9 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t top \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) +__STATIC_FORCEINLINE uint32_t __get_MSP(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); @@ -258,9 +304,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. \return MSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); return(result); @@ -273,7 +319,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) { __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); } @@ -285,19 +331,46 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMain \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. \param [in] topOfMainStack Main Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) { __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); } #endif +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) { uint32_t result; @@ -312,7 +385,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. \return Priority Mask value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; @@ -327,7 +400,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ -__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } @@ -339,7 +412,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMa \details Assigns the given value to the non-secure Priority Mask Register when in secure state. \param [in] priMask Priority Mask */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) { __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); } @@ -370,7 +443,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t \details Returns the current value of the Base Priority register. \return Base Priority register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; @@ -385,7 +458,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) \details Returns the current value of the non-secure Base Priority register when in secure state. \return Base Priority register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t result; @@ -400,7 +473,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) { __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); } @@ -412,7 +485,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t baseP \details Assigns the given value to the non-secure Base Priority register when in secure state. \param [in] basePri Base Priority value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } @@ -425,7 +498,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } @@ -436,7 +509,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t b \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; @@ -451,7 +524,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) \details Returns the current value of the non-secure Fault Mask register when in secure state. \return Fault Mask register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t result; @@ -466,7 +539,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(vo \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } @@ -478,7 +551,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t fau \details Assigns the given value to the non-secure Fault Mask register when in secure state. \param [in] faultMask Fault Mask value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) { __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); } @@ -494,162 +567,204 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32 /** \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). \return PSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, psplim" : "=r" (result) ); - return(result); + return result; +#endif } - -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \return PSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); - return(result); + return result; +#endif } #endif /** \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif } -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif } #endif /** \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). \return MSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, msplim" : "=r" (result) ); - - return(result); + return result; +#endif } -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. \return MSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); - return(result); + return result; +#endif } #endif /** \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif } -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. \param [in] MainStackPtrLimit Main Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif } #endif #endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ - -#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) - /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ -/* #define __get_FPSCR __builtin_arm_get_fpscr */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - uint32_t result; - - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - return(result); +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr #else - return(0U); +#define __get_FPSCR() ((uint32_t)0U) #endif -} - /** \brief Set FPSCR \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ -/* #define __set_FPSCR __builtin_arm_set_fpscr */ -__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "memory"); +#define __set_FPSCR __builtin_arm_set_fpscr #else - (void)fpscr; +#define __set_FPSCR(x) ((void)(x)) #endif -} - -#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ - /*@} end of CMSIS_Core_RegAccFunctions */ @@ -726,45 +841,29 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) /** \brief Reverse byte order (32 bit) - \details Reverses the byte order in integer value. + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ -#define __REV __builtin_bswap32 +#define __REV(value) __builtin_bswap32(value) /** \brief Reverse byte order (16 bit) - \details Reverses the byte order in two unsigned short values. + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ -#define __REV16 __builtin_bswap16 /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */ -#if 0 -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} -#endif +#define __REV16(value) __ROR(__REV(value), 16) /** - \brief Reverse byte order in signed short value - \details Reverses the byte order in a signed short value with sign extension to integer. + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ - /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) -{ - int32_t result; - - __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} +#define __REVSH(value) (int16_t)__builtin_bswap16(value) /** @@ -774,8 +873,13 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) \param [in] op2 Number of Bits to rotate \return Rotated value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } return (op1 >> op2) | (op1 << (32U - op2)); } @@ -787,7 +891,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint \param [in] value is ignored by the processor. If required, a debugger can use it to store additional information about the breakpoint. */ -#define __BKPT(value) __ASM volatile ("bkpt "#value) +#define __BKPT(value) __ASM volatile ("bkpt "#value) /** @@ -796,30 +900,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint \param [in] value Value to reverse \return Reversed value */ - /* ToDo ARMCLANG: check if __builtin_arm_rbit is supported */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - -#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ - (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); -#else - int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ - - result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) - { - result <<= 1U; - result |= value & 1U; - s--; - } - result <<= s; /* shift when v's highest bits are zero */ -#endif - return(result); -} - +#define __RBIT __builtin_arm_rbit /** \brief Count leading zeros @@ -827,7 +908,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) \param [in] value Value to count the leading zeros \return number of leading zeros in value */ -#define __CLZ __builtin_clz +#define __CLZ (uint8_t)__builtin_clz #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ @@ -909,6 +990,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + /** \brief Signed Saturate \details Saturates a signed value. @@ -936,7 +1018,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) \param [in] value Value to rotate \return Rotated value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; @@ -951,7 +1033,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr) +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; @@ -966,7 +1048,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr) +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; @@ -981,7 +1063,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_ \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr) +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; @@ -996,7 +1078,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1008,7 +1090,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volat \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1020,11 +1102,64 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, vola \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ @@ -1038,7 +1173,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr) +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t result; @@ -1053,7 +1188,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t * \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr) +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t result; @@ -1068,7 +1203,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr) +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) { uint32_t result; @@ -1083,7 +1218,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1095,7 +1230,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volati \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1107,7 +1242,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volat \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1186,7 +1321,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volati #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1194,7 +1329,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1202,7 +1337,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1210,7 +1345,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1218,7 +1353,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1226,7 +1361,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1235,7 +1370,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, u } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1243,7 +1378,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1251,7 +1386,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1259,7 +1394,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1267,7 +1402,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1275,7 +1410,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1284,7 +1419,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, u } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1292,7 +1427,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1300,7 +1435,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1308,7 +1443,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1316,7 +1451,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1324,7 +1459,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1332,7 +1467,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1340,7 +1475,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1348,7 +1483,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1356,7 +1491,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1364,7 +1499,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1372,7 +1507,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1380,7 +1515,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1388,7 +1523,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1396,7 +1531,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1404,7 +1539,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1412,7 +1547,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1420,7 +1555,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1428,7 +1563,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1436,7 +1571,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1444,7 +1579,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1452,7 +1587,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1460,7 +1595,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1468,7 +1603,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1476,7 +1611,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1484,7 +1619,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1506,7 +1641,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, u __RES; \ }) -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) { uint32_t result; @@ -1514,7 +1649,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1522,7 +1657,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) { uint32_t result; @@ -1530,7 +1665,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1538,7 +1673,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1546,7 +1681,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1554,7 +1689,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1562,7 +1697,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1570,7 +1705,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1587,7 +1722,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1604,7 +1739,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1612,7 +1747,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1620,7 +1755,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1628,7 +1763,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1636,7 +1771,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1653,7 +1788,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1670,7 +1805,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1678,7 +1813,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) { int32_t result; @@ -1686,7 +1821,7 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, in return(result); } -__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) { int32_t result; @@ -1719,7 +1854,7 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, in #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) -__attribute__((always_inline)) __STATIC_INLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; diff --git a/arch/arm/common/cmsis/cmsis_compiler.h b/arch/arm/common/cmsis/cmsis_compiler.h index 874fca07c..94212eb87 100644 --- a/arch/arm/common/cmsis/cmsis_compiler.h +++ b/arch/arm/common/cmsis/cmsis_compiler.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file cmsis_compiler.h * @brief CMSIS compiler generic header file - * @version V5.0.1 - * @date 30. January 2017 + * @version V5.0.4 + * @date 10. January 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -28,14 +28,14 @@ #include /* - * ARM Compiler 4/5 + * Arm Compiler 4/5 */ #if defined ( __CC_ARM ) #include "cmsis_armcc.h" /* - * ARM Compiler 6 (armclang) + * Arm Compiler 6 (armclang) */ #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #include "cmsis_armclang.h" @@ -52,79 +52,71 @@ * IAR Compiler */ #elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include #ifndef __ASM - #define __ASM __asm + #define __ASM __asm #endif #ifndef __INLINE - #define __INLINE inline + #define __INLINE inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE #endif - - #include - #ifndef __NO_RETURN - #define __NO_RETURN __noreturn + #define __NO_RETURN __attribute__((noreturn)) #endif #ifndef __USED - #define __USED __root + #define __USED __attribute__((used)) #endif #ifndef __WEAK - #define __WEAK __weak - #endif - #ifndef __UNALIGNED_UINT32 - __packed struct T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) - #endif - #ifndef __ALIGNED - #define __ALIGNED(x) + #define __WEAK __attribute__((weak)) #endif #ifndef __PACKED - #define __PACKED __packed + #define __PACKED __attribute__((packed)) #endif #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT __packed struct - #endif - - -/* - * TI ARM Compiler - */ -#elif defined ( __TI_ARM__ ) - #include - - #ifndef __ASM - #define __ASM __asm + #define __PACKED_STRUCT struct __attribute__((packed)) #endif - #ifndef __INLINE - #define __INLINE inline + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) #endif - #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif - #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((noreturn)) + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) #endif - #ifndef __USED - #define __USED __attribute__((used)) + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif - #ifndef __WEAK - #define __WEAK __attribute__((weak)) + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) #endif - #ifndef __UNALIGNED_UINT32 - struct __attribute__((packed)) T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) + #define __ALIGNED(x) __attribute__((aligned(x))) #endif - #ifndef __PACKED - #define __PACKED __attribute__((packed)) - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __attribute__((packed)) + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT #endif @@ -139,35 +131,61 @@ */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm #endif #ifndef __INLINE - #define __INLINE inline + #define __INLINE inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((noreturn)) + #define __NO_RETURN __attribute__((noreturn)) #endif #ifndef __USED - #define __USED __attribute__((used)) + #define __USED __attribute__((used)) #endif #ifndef __WEAK - #define __WEAK __attribute__((weak)) + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ #endif - #ifndef __UNALIGNED_UINT32 + #ifndef __UNALIGNED_UINT32 /* deprecated */ struct __packed__ T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #define __ALIGNED(x) __align(x) #endif - #ifndef __PACKED - #define __PACKED __packed__ - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __packed__ + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT #endif @@ -178,13 +196,16 @@ #include #ifndef __ASM - #define __ASM _asm + #define __ASM _asm #endif #ifndef __INLINE - #define __INLINE inline + #define __INLINE inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE #endif #ifndef __NO_RETURN // NO RETURN is automatically detected hence no warning here @@ -195,21 +216,44 @@ #define __USED #endif #ifndef __WEAK - #define __WEAK __weak + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed #endif - #ifndef __UNALIGNED_UINT32 + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ @packed struct T_UINT32 { uint32_t v; }; - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) #endif #ifndef __ALIGNED #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. #define __ALIGNED(x) #endif - #ifndef __PACKED - #define __PACKED @packed - #endif - #ifndef __PACKED_STRUCT - #define __PACKED_STRUCT @packed struct + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT #endif @@ -217,48 +261,6 @@ #error Unknown compiler. #endif - /** - * @brief definition to read/write two 16 bit values. - */ -#if defined ( __CC_ARM ) - #define __SIMD32_TYPE int32_t __packed - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE __attribute__((always_inline)) - -#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE __attribute__((always_inline)) - -#elif defined ( __GNUC__ ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE __attribute__((always_inline)) - -#elif defined ( __ICCARM__ ) - #define __SIMD32_TYPE int32_t __packed - #define CMSIS_UNUSED - #define CMSIS_INLINE - -#elif defined ( __TI_ARM__ ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) - #define CMSIS_INLINE - -#elif defined ( __CSMC__ ) - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED - #define CMSIS_INLINE - -#elif defined ( __TASKING__ ) - #define __SIMD32_TYPE __unaligned int32_t - #define CMSIS_UNUSED - #define CMSIS_INLINE - -#else - #error Unknown compiler -#endif - #endif /* __CMSIS_COMPILER_H */ diff --git a/arch/arm/common/cmsis/cmsis_gcc.h b/arch/arm/common/cmsis/cmsis_gcc.h index 15b035f74..2d9db15a5 100644 --- a/arch/arm/common/cmsis/cmsis_gcc.h +++ b/arch/arm/common/cmsis/cmsis_gcc.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file cmsis_gcc.h * @brief CMSIS compiler GCC header file - * @version V5.0.1 - * @date 02. February 2017 + * @version V5.0.4 + * @date 09. April 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -31,41 +31,87 @@ #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + /* CMSIS compiler specific defines */ #ifndef __ASM - #define __ASM __asm + #define __ASM __asm #endif #ifndef __INLINE - #define __INLINE inline + #define __INLINE inline #endif #ifndef __STATIC_INLINE - #define __STATIC_INLINE static inline + #define __STATIC_INLINE static inline #endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif #ifndef __NO_RETURN - #define __NO_RETURN __attribute__((noreturn)) + #define __NO_RETURN __attribute__((__noreturn__)) #endif #ifndef __USED - #define __USED __attribute__((used)) + #define __USED __attribute__((used)) #endif #ifndef __WEAK - #define __WEAK __attribute__((weak)) + #define __WEAK __attribute__((weak)) #endif -#ifndef __UNALIGNED_UINT32 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpacked" -#pragma GCC diagnostic ignored "-Wattributes" +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" struct __attribute__((packed)) T_UINT32 { uint32_t v; }; -#pragma GCC diagnostic pop - #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) #endif -#ifndef __ALIGNED - #define __ALIGNED(x) __attribute__((aligned(x))) +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) #endif -#ifndef __PACKED - #define __PACKED __attribute__((packed, aligned(1))) +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) #endif -#ifndef __PACKED_STRUCT - #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict #endif @@ -80,7 +126,7 @@ \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) +__STATIC_FORCEINLINE void __enable_irq(void) { __ASM volatile ("cpsie i" : : : "memory"); } @@ -91,7 +137,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) +__STATIC_FORCEINLINE void __disable_irq(void) { __ASM volatile ("cpsid i" : : : "memory"); } @@ -102,7 +148,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) \details Returns the content of the Control Register. \return Control Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; @@ -117,7 +163,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) \details Returns the content of the non-secure Control Register when in secure mode. \return non-secure Control Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) { uint32_t result; @@ -132,7 +178,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } @@ -144,7 +190,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t contr \details Writes the given value to the non-secure Control Register when in secure state. \param [in] control Control Register value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) { __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); } @@ -156,7 +202,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t \details Returns the content of the IPSR Register. \return IPSR Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; @@ -170,7 +216,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) \details Returns the content of the APSR Register. \return APSR Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) +__STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; @@ -184,7 +230,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) \details Returns the content of the xPSR Register. \return xPSR Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; @@ -198,9 +244,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) +__STATIC_FORCEINLINE uint32_t __get_PSP(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, psp" : "=r" (result) ); return(result); @@ -213,9 +259,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. \return PSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); @@ -228,7 +274,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } @@ -240,7 +286,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProc \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. \param [in] topOfProcStack Process Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) { __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); } @@ -252,9 +298,9 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t top \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) +__STATIC_FORCEINLINE uint32_t __get_MSP(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); @@ -267,9 +313,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. \return MSP Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) { - register uint32_t result; + uint32_t result; __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); return(result); @@ -282,7 +328,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) \details Assigns the given value to the Main Stack Pointer (MSP). \param [in] topOfMainStack Main Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) { __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); } @@ -294,23 +340,50 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMain \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. \param [in] topOfMainStack Main Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) { __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); } #endif +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + /** \brief Get Priority Mask \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) { uint32_t result; - __ASM volatile ("MRS %0, primask" : "=r" (result) ); + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); return(result); } @@ -321,11 +394,11 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. \return Priority Mask value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; - __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); return(result); } #endif @@ -336,7 +409,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ -__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } @@ -348,7 +421,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMa \details Assigns the given value to the non-secure Priority Mask Register when in secure state. \param [in] priMask Priority Mask */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) { __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); } @@ -363,7 +436,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void) +__STATIC_FORCEINLINE void __enable_fault_irq(void) { __ASM volatile ("cpsie f" : : : "memory"); } @@ -374,7 +447,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void) \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void) +__STATIC_FORCEINLINE void __disable_fault_irq(void) { __ASM volatile ("cpsid f" : : : "memory"); } @@ -385,7 +458,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void) \details Returns the current value of the Base Priority register. \return Base Priority register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; @@ -400,7 +473,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) \details Returns the current value of the non-secure Base Priority register when in secure state. \return Base Priority register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) { uint32_t result; @@ -415,7 +488,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) { __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); } @@ -427,7 +500,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t baseP \details Assigns the given value to the non-secure Base Priority register when in secure state. \param [in] basePri Base Priority value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } @@ -440,7 +513,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } @@ -451,7 +524,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t b \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; @@ -466,7 +539,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) \details Returns the current value of the non-secure Fault Mask register when in secure state. \return Fault Mask register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) { uint32_t result; @@ -481,7 +554,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(vo \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } @@ -493,7 +566,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t fau \details Assigns the given value to the non-secure Fault Mask register when in secure state. \param [in] faultMask Fault Mask value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) { __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); } @@ -509,113 +582,175 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32 /** \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). \return PSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, psplim" : "=r" (result) ); - return(result); + return result; +#endif } - -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \return PSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); - return(result); + return result; +#endif } #endif /** \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif } -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif } #endif /** \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). \return MSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, msplim" : "=r" (result) ); - - return(result); + return result; +#endif } -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. \return MSPLIM Register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) { - register uint32_t result; - +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); - return(result); + return result; +#endif } #endif /** \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif } -#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ - (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) /** \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. \param [in] MainStackPtrLimit Main Stack Pointer value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) { +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif } #endif @@ -623,24 +758,28 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ -#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) - /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else uint32_t result; __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); return(result); +#endif #else - return(0U); + return(0U); #endif } @@ -650,20 +789,23 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ -__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif #else (void)fpscr; #endif } -#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ - (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ - - /*@} end of CMSIS_Core_RegAccFunctions */ @@ -691,21 +833,13 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ -//__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) -//{ -// __ASM volatile ("nop"); -//} -#define __NOP() __ASM volatile ("nop") /* This implementation generates debug information */ +#define __NOP() __ASM volatile ("nop") /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ -//__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) -//{ -// __ASM volatile ("wfi"); -//} -#define __WFI() __ASM volatile ("wfi") /* This implementation generates debug information */ +#define __WFI() __ASM volatile ("wfi") /** @@ -713,22 +847,14 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) \details Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of events occurs. */ -//__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) -//{ -// __ASM volatile ("wfe"); -//} -#define __WFE() __ASM volatile ("wfe") /* This implementation generates debug information */ +#define __WFE() __ASM volatile ("wfe") /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ -//__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) -//{ -// __ASM volatile ("sev"); -//} -#define __SEV() __ASM volatile ("sev") /* This implementation generates debug information */ +#define __SEV() __ASM volatile ("sev") /** @@ -737,7 +863,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ -__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) +__STATIC_FORCEINLINE void __ISB(void) { __ASM volatile ("isb 0xF":::"memory"); } @@ -748,7 +874,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __ISB(void) \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ -__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) +__STATIC_FORCEINLINE void __DSB(void) { __ASM volatile ("dsb 0xF":::"memory"); } @@ -759,7 +885,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __DSB(void) \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ -__attribute__((always_inline)) __STATIC_INLINE void __DMB(void) +__STATIC_FORCEINLINE void __DMB(void) { __ASM volatile ("dmb 0xF":::"memory"); } @@ -767,11 +893,11 @@ __attribute__((always_inline)) __STATIC_INLINE void __DMB(void) /** \brief Reverse byte order (32 bit) - \details Reverses the byte order in integer value. + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) return __builtin_bswap32(value); @@ -779,41 +905,41 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) uint32_t result; __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; #endif } /** \brief Reverse byte order (16 bit) - \details Reverses the byte order in two unsigned short values. + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) { uint32_t result; __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; } /** - \brief Reverse byte order in signed short value - \details Reverses the byte order in a signed short value with sign extension to integer. + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (short)__builtin_bswap16(value); + return (int16_t)__builtin_bswap16(value); #else - int32_t result; + int16_t result; __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; #endif } @@ -825,8 +951,13 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) \param [in] op2 Number of Bits to rotate \return Rotated value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } return (op1 >> op2) | (op1 << (32U - op2)); } @@ -847,7 +978,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) { uint32_t result; @@ -856,10 +987,10 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); #else - int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) + for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; @@ -867,7 +998,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) } result <<= s; /* shift when v's highest bits are zero */ #endif - return(result); + return result; } @@ -877,7 +1008,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) \param [in] value Value to count the leading zeros \return number of leading zeros in value */ -#define __CLZ __builtin_clz +#define __CLZ (uint8_t)__builtin_clz #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ @@ -890,7 +1021,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) { uint32_t result; @@ -912,7 +1043,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) { uint32_t result; @@ -934,7 +1065,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16 \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) { uint32_t result; @@ -951,7 +1082,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32 \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) { uint32_t result; @@ -968,7 +1099,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) { uint32_t result; @@ -985,7 +1116,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) { uint32_t result; @@ -998,7 +1129,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ -__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) +__STATIC_FORCEINLINE void __CLREX(void) { __ASM volatile ("clrex" ::: "memory"); } @@ -1015,11 +1146,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) /** \brief Signed Saturate \details Saturates a signed value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT(ARG1,ARG2) \ +__extension__ \ ({ \ int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ @@ -1030,11 +1162,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) /** \brief Unsigned Saturate \details Saturates an unsigned value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) \return Saturated value */ #define __USAT(ARG1,ARG2) \ + __extension__ \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ @@ -1049,7 +1182,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) \param [in] value Value to rotate \return Rotated value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; @@ -1064,7 +1197,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr) +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; @@ -1086,7 +1219,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr) +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; @@ -1108,7 +1241,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_ \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr) +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; @@ -1123,7 +1256,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1135,7 +1268,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volat \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1147,11 +1280,64 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, vola \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + #endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ @@ -1165,7 +1351,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr) +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) { uint32_t result; @@ -1180,7 +1366,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t * \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr) +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) { uint32_t result; @@ -1195,7 +1381,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr) +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) { uint32_t result; @@ -1210,7 +1396,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) { __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1222,7 +1408,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volati \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) { __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1234,7 +1420,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volat \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) { __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -1246,7 +1432,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volati \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) { uint32_t result; @@ -1261,7 +1447,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAEXB(volatile uint8_t \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) { uint32_t result; @@ -1276,7 +1462,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAEXH(volatile uint16 \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDAEX(volatile uint32_t *ptr) +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) { uint32_t result; @@ -1293,7 +1479,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDAEX(volatile uint32_ \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) { uint32_t result; @@ -1310,7 +1496,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEXB(uint8_t value, \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) { uint32_t result; @@ -1327,7 +1513,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEXH(uint16_t value, \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) { uint32_t result; @@ -1347,9 +1533,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEX(uint32_t value, @{ */ -#if (defined(__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) /* ToDo ARMCLANG: This should be ARCH >= ARMv7-M + SIMD */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1357,7 +1543,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1365,7 +1551,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1373,7 +1559,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1381,7 +1567,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1389,7 +1575,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1398,7 +1584,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, u } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1406,7 +1592,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1414,7 +1600,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1422,7 +1608,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1430,7 +1616,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1438,7 +1624,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1447,7 +1633,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, u } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1455,7 +1641,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1463,7 +1649,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1471,7 +1657,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1479,7 +1665,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1487,7 +1673,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1495,7 +1681,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1503,7 +1689,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1511,7 +1697,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1519,7 +1705,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1527,7 +1713,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1535,7 +1721,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1543,7 +1729,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1551,7 +1737,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1559,7 +1745,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1567,7 +1753,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1575,7 +1761,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1583,7 +1769,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1591,7 +1777,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1599,7 +1785,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1607,7 +1793,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1615,7 +1801,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1623,7 +1809,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uin return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1631,7 +1817,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1639,7 +1825,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1647,7 +1833,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1669,7 +1855,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, u __RES; \ }) -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) { uint32_t result; @@ -1677,7 +1863,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1685,7 +1871,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) { uint32_t result; @@ -1693,7 +1879,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1701,7 +1887,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1709,7 +1895,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1717,7 +1903,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1725,7 +1911,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1733,7 +1919,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1750,7 +1936,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1767,7 +1953,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1775,7 +1961,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1783,7 +1969,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1791,7 +1977,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, u return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1799,7 +1985,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, return(result); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1816,7 +2002,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1833,7 +2019,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, return(llr.w64); } -__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1841,7 +2027,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, ui return(result); } -__attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) { int32_t result; @@ -1849,7 +2035,7 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, in return(result); } -__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) { int32_t result; @@ -1882,7 +2068,7 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, in #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) -__attribute__((always_inline)) __STATIC_INLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; diff --git a/arch/arm/common/cmsis/cmsis_iccarm.h b/arch/arm/common/cmsis/cmsis_iccarm.h new file mode 100644 index 000000000..11c4af0eb --- /dev/null +++ b/arch/arm/common/cmsis/cmsis_iccarm.h @@ -0,0 +1,935 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 19. June 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/arch/arm/common/cmsis/cmsis_version.h b/arch/arm/common/cmsis/cmsis_version.h new file mode 100644 index 000000000..660f612aa --- /dev/null +++ b/arch/arm/common/cmsis/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/arch/arm/common/cmsis/core_armv8mbl.h b/arch/arm/common/cmsis/core_armv8mbl.h index 5ce9a5217..251e4ede3 100644 --- a/arch/arm/common/cmsis/core_armv8mbl.h +++ b/arch/arm/common/cmsis/core_armv8mbl.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_armv8mbl.h - * @brief CMSIS ARMv8MBL Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 22. June 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ -/* CMSIS cmGrebe definitions */ -#define __ARMv8MBL_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __ARMv8MBL_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ - __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M ( 2U) /*!< Cortex-M Core */ @@ -413,6 +415,9 @@ typedef struct #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ @@ -719,8 +724,8 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; @@ -728,26 +733,18 @@ typedef struct uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39U]; - __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ @@ -770,68 +767,25 @@ typedef struct #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -843,22 +797,16 @@ typedef struct #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -881,10 +829,17 @@ typedef struct __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 1U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1224,9 +1179,14 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL -/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for ARMv8-M Baseline */ -/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for ARMv8-M Baseline */ +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ @@ -1236,9 +1196,15 @@ typedef struct #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -1246,12 +1212,36 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 -/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt @@ -1263,7 +1253,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1280,7 +1270,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1299,7 +1289,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -1318,7 +1308,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1337,7 +1327,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1352,7 +1342,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1369,7 +1359,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1391,7 +1381,7 @@ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1412,8 +1402,8 @@ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1434,8 +1424,8 @@ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1492,6 +1482,58 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) } +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. @@ -1536,7 +1578,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -1561,7 +1603,7 @@ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1578,7 +1620,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1597,7 +1639,7 @@ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1614,7 +1656,11 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); } } @@ -1629,7 +1675,7 @@ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1644,7 +1690,7 @@ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1661,7 +1707,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1718,6 +1764,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/arch/arm/common/cmsis/core_armv8mml.h b/arch/arm/common/cmsis/core_armv8mml.h index c821f5699..3a3148ea3 100644 --- a/arch/arm/common/cmsis/core_armv8mml.h +++ b/arch/arm/common/cmsis/core_armv8mml.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_armv8mml.h - * @brief CMSIS ARMv8MML Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 07. December 2016 + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 06. July 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ -/* CMSIS ARMv8MML definitions */ -#define __ARMv8MML_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __ARMv8MML_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ - __ARMv8MML_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (81U) /*!< Cortex-M Core */ @@ -83,6 +85,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined __ARM_PCS_VFP #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -95,6 +108,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -107,6 +131,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -119,6 +154,17 @@ #define __FPU_USED 0U #endif + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -480,7 +526,7 @@ typedef struct uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; @@ -522,6 +568,9 @@ typedef struct #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ @@ -1337,8 +1386,8 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ uint32_t RESERVED1[55U]; @@ -1346,26 +1395,18 @@ typedef struct uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39U]; - __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ /* TPI Selected Pin Protocol Register Definitions */ #define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ @@ -1388,68 +1429,25 @@ typedef struct #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1461,22 +1459,16 @@ typedef struct #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -1505,10 +1497,17 @@ typedef struct __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1534,8 +1533,8 @@ typedef struct #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ @@ -2050,7 +2049,12 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ @@ -2062,9 +2066,15 @@ typedef struct #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -2072,6 +2082,27 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + /** \brief Set Priority Grouping @@ -2117,7 +2148,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2134,7 +2165,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2153,7 +2184,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -2172,7 +2203,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2191,7 +2222,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2206,7 +2237,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2223,7 +2254,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2245,7 +2276,7 @@ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2266,8 +2297,8 @@ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2288,8 +2319,8 @@ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2312,11 +2343,11 @@ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -2335,11 +2366,11 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -2431,7 +2462,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -2491,7 +2522,7 @@ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2508,7 +2539,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2527,7 +2558,7 @@ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2544,7 +2575,11 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); } } @@ -2559,7 +2594,7 @@ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2574,7 +2609,7 @@ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2591,7 +2626,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2613,11 +2648,11 @@ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -2635,17 +2670,24 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/arch/arm/common/cmsis/core_cm0.h b/arch/arm/common/cmsis/core_cm0.h index 2fb5821b8..f929bba07 100644 --- a/arch/arm/common/cmsis/core_cm0.h +++ b/arch/arm/common/cmsis/core_cm0.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_cm0.h * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @version V5.0.5 + * @date 28. May 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM0 definitions */ -#define __CM0_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM0_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ - __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ @@ -564,9 +566,14 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL -/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0 */ -/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0 */ +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ @@ -576,9 +583,15 @@ typedef struct /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -586,12 +599,20 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 -/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt @@ -603,7 +624,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -620,7 +641,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -639,7 +660,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -658,7 +679,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -677,7 +698,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -692,7 +713,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -744,6 +765,59 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) } +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. @@ -779,7 +853,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ diff --git a/arch/arm/common/cmsis/core_cm0plus.h b/arch/arm/common/cmsis/core_cm0plus.h index 751384b3c..424011ac3 100644 --- a/arch/arm/common/cmsis/core_cm0plus.h +++ b/arch/arm/common/cmsis/core_cm0plus.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_cm0plus.h * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @version V5.0.6 + * @date 28. May 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM0+ definitions */ -#define __CM0PLUS_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM0PLUS_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ - __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (0U) /*!< Cortex-M Core */ @@ -528,6 +530,8 @@ typedef struct __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 1U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -680,9 +684,14 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL -/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0+ */ -/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0+ */ +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ #define NVIC_DisableIRQ __NVIC_DisableIRQ @@ -692,9 +701,15 @@ typedef struct /*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -702,12 +717,20 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 -/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt @@ -719,7 +742,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -736,7 +759,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -755,7 +778,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -774,7 +797,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -793,7 +816,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -808,7 +831,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -860,6 +883,58 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) } +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. @@ -905,7 +980,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -921,6 +996,13 @@ __STATIC_INLINE void NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/arch/arm/common/cmsis/core_cm1.h b/arch/arm/common/cmsis/core_cm1.h new file mode 100644 index 000000000..0ed678e3b --- /dev/null +++ b/arch/arm/common/cmsis/core_cm1.h @@ -0,0 +1,976 @@ +/**************************************************************************//** + * @file core_cm1.h + * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File + * @version V1.0.0 + * @date 23. July 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM1_H_GENERIC +#define __CORE_CM1_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M1 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM1 definitions */ +#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ + __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (1U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM1_H_DEPENDANT +#define __CORE_CM1_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM1_REV + #define __CM1_REV 0x0100U + #warning "__CM1_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ + +#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M1 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/arch/arm/common/cmsis/core_cm23.h b/arch/arm/common/cmsis/core_cm23.h index 83055ba32..acbc5dfea 100644 --- a/arch/arm/common/cmsis/core_cm23.h +++ b/arch/arm/common/cmsis/core_cm23.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_cm23.h * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @version V5.0.7 + * @date 22. June 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,13 +60,15 @@ @{ */ -/* CMSIS cmGrebe definitions */ -#define __CM23_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM23_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ - __CM23_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ -#define __CORTEX_M (23U) /*!< Cortex-M Core */ +#define __CORTEX_M (23U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all @@ -413,6 +415,9 @@ typedef struct #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ @@ -719,7 +724,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -728,21 +733,21 @@ typedef struct uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ @@ -770,6 +775,9 @@ typedef struct #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ @@ -777,61 +785,79 @@ typedef struct #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -843,22 +869,19 @@ typedef struct #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -881,10 +904,17 @@ typedef struct __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 1U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1224,7 +1254,12 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else /*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ /*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ #define NVIC_EnableIRQ __NVIC_EnableIRQ @@ -1236,9 +1271,15 @@ typedef struct #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -1246,12 +1287,36 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 -/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) #define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) /** \brief Enable Interrupt @@ -1263,7 +1328,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1280,7 +1345,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1299,7 +1364,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -1318,7 +1383,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1337,7 +1402,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1352,7 +1417,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1369,7 +1434,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1391,7 +1456,7 @@ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1412,8 +1477,8 @@ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1434,8 +1499,8 @@ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1492,6 +1557,58 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) } +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + /** \brief Set Interrupt Vector \details Sets an interrupt vector in SRAM based interrupt vector table. @@ -1536,7 +1653,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -1561,7 +1678,7 @@ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1578,7 +1695,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1597,7 +1714,7 @@ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1614,7 +1731,11 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); } } @@ -1629,7 +1750,7 @@ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1644,7 +1765,7 @@ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1661,7 +1782,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1718,6 +1839,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/arch/arm/common/cmsis/core_cm3.h b/arch/arm/common/cmsis/core_cm3.h index c65ab14d0..74bff64be 100644 --- a/arch/arm/common/cmsis/core_cm3.h +++ b/arch/arm/common/cmsis/core_cm3.h @@ -1,12 +1,11 @@ - /**************************************************************************//** * @file core_cm3.h * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 30. January 2017 + * @version V5.0.8 + * @date 04. June 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -24,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -61,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ - __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (3U) /*!< Cortex-M Core */ @@ -780,7 +781,7 @@ typedef struct /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ @@ -994,7 +995,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -1005,7 +1006,7 @@ typedef struct __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; @@ -1075,8 +1076,11 @@ typedef struct #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ @@ -1101,12 +1105,15 @@ typedef struct #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1128,12 +1135,12 @@ typedef struct #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -1163,6 +1170,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1453,6 +1462,11 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + /** \brief Set Priority Grouping @@ -1463,7 +1477,7 @@ typedef struct priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ @@ -1472,7 +1486,7 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGr reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } @@ -1482,7 +1496,7 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGr \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ -CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } @@ -1494,11 +1508,11 @@ CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1511,11 +1525,11 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) \return 1 Interrupt is enabled. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1530,11 +1544,11 @@ CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -1549,11 +1563,11 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) \return 1 Interrupt status is pending. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1568,11 +1582,11 @@ CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1583,11 +1597,11 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) \param [in] IRQn Device specific interrupt number. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1600,11 +1614,11 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) \return 1 Interrupt status is active. \note IRQn must not be negative. */ -CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1622,15 +1636,15 @@ CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) \param [in] priority Priority to set. \note The priority cannot be set for every processor exception. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -1644,16 +1658,16 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t pr \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ -CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -1669,7 +1683,7 @@ CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) \param [in] SubPriority Subpriority value (starting from 0). \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). */ -CMSIS_INLINE __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; @@ -1696,7 +1710,7 @@ CMSIS_INLINE __STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGrou \param [out] pPreemptPriority Preemptive priority value (starting from 0). \param [out] pSubPriority Subpriority value (starting from 0). */ -CMSIS_INLINE __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) { uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ uint32_t PreemptPriorityBits; @@ -1719,7 +1733,7 @@ CMSIS_INLINE __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32 \param [in] IRQn Interrupt number \param [in] vector Address of interrupt handler function */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { uint32_t *vectors = (uint32_t *)SCB->VTOR; vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; @@ -1734,7 +1748,7 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vect \param [in] IRQn Interrupt number. \return Address of interrupt handler function */ -CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) { uint32_t *vectors = (uint32_t *)SCB->VTOR; return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; @@ -1745,7 +1759,7 @@ CMSIS_INLINE __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -CMSIS_INLINE __STATIC_INLINE void __NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -1762,6 +1776,13 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif /* ########################## FPU functions #################################### */ /** @@ -1779,7 +1800,7 @@ CMSIS_INLINE __STATIC_INLINE void __NVIC_SystemReset(void) - \b 1: Single precision FPU - \b 2: Double + Single precision FPU */ -CMSIS_INLINE __STATIC_INLINE uint32_t SCB_GetFPUType(void) +__STATIC_INLINE uint32_t SCB_GetFPUType(void) { return 0U; /* No FPU */ } @@ -1810,7 +1831,7 @@ CMSIS_INLINE __STATIC_INLINE uint32_t SCB_GetFPUType(void) function SysTick_Config is not included. In this case, the file device.h must contain a vendor-specific implementation of this function. */ -CMSIS_INLINE __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { @@ -1852,7 +1873,7 @@ extern volatile int32_t ITM_RxBuffer; /*!< External \param [in] ch Character to transmit. \returns Character to transmit. */ -CMSIS_INLINE __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) { if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ @@ -1873,7 +1894,7 @@ CMSIS_INLINE __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) \return Received character. \return -1 No character pending. */ -CMSIS_INLINE __STATIC_INLINE int32_t ITM_ReceiveChar (void) +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { int32_t ch = -1; /* no character available */ @@ -1893,7 +1914,7 @@ CMSIS_INLINE __STATIC_INLINE int32_t ITM_ReceiveChar (void) \return 0 No character available. \return 1 Character available. */ -CMSIS_INLINE __STATIC_INLINE int32_t ITM_CheckChar (void) +__STATIC_INLINE int32_t ITM_CheckChar (void) { if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) diff --git a/arch/arm/common/cmsis/core_cm33.h b/arch/arm/common/cmsis/core_cm33.h index 65da8ef52..6cd2db77f 100644 --- a/arch/arm/common/cmsis/core_cm33.h +++ b/arch/arm/common/cmsis/core_cm33.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_cm33.h * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File - * @version V5.0.2 - * @date 07. December 2016 + * @version V5.0.9 + * @date 06. July 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,19 +60,21 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM33 definitions */ -#define __CM33_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM33_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ - __CM33_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ -#define __CORTEX_M (33U) /*!< Cortex-M Core */ +#define __CORTEX_M (33U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP + #if defined (__TARGET_FPU_VFP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else @@ -83,8 +85,19 @@ #define __FPU_USED 0U #endif + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_PCS_VFP + #if defined (__ARM_PCS_VFP) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else @@ -95,6 +108,17 @@ #define __FPU_USED 0U #endif + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) @@ -107,8 +131,19 @@ #define __FPU_USED 0U #endif + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ + #if defined (__ARMVFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else @@ -119,8 +154,19 @@ #define __FPU_USED 0U #endif + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + #elif defined ( __TI_ARM__ ) - #if defined __TI_VFP_SUPPORT__ + #if defined (__TI_VFP_SUPPORT__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else @@ -132,7 +178,7 @@ #endif #elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ + #if defined (__FPU_VFP__) #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else @@ -480,7 +526,7 @@ typedef struct uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; @@ -522,6 +568,9 @@ typedef struct #define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ #define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + #define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ #define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ @@ -1081,7 +1130,7 @@ typedef struct /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ @@ -1337,7 +1386,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -1346,21 +1395,21 @@ typedef struct uint32_t RESERVED2[131U]; __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ uint32_t RESERVED5[39U]; __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ } TPI_Type; /* TPI Asynchronous Clock Prescaler Register Definitions */ @@ -1388,6 +1437,9 @@ typedef struct #define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ #define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + #define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ #define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ @@ -1395,61 +1447,79 @@ typedef struct #define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ #define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1461,22 +1531,19 @@ typedef struct #define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ #define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ #define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -1505,10 +1572,17 @@ typedef struct __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1534,8 +1608,8 @@ typedef struct #define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ /* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ #define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ #define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ @@ -2050,7 +2124,12 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ @@ -2062,9 +2141,15 @@ typedef struct #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -2072,6 +2157,27 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + /** \brief Set Priority Grouping @@ -2091,7 +2197,7 @@ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << 8U) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } @@ -2117,7 +2223,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2134,7 +2240,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2153,7 +2259,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -2172,7 +2278,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2191,7 +2297,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2206,7 +2312,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2223,7 +2329,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2245,7 +2351,7 @@ __STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2266,8 +2372,8 @@ __STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2288,8 +2394,8 @@ __STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); - return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2312,11 +2418,11 @@ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -2335,11 +2441,11 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -2431,7 +2537,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -2461,11 +2567,11 @@ __STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - reg_value = SCB_NS->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB_NS->AIRCR = reg_value; } @@ -2491,7 +2597,7 @@ __STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2508,7 +2614,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2527,7 +2633,7 @@ __STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2544,7 +2650,11 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); } } @@ -2559,7 +2669,7 @@ __STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2574,7 +2684,7 @@ __STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -2591,7 +2701,7 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -2613,11 +2723,11 @@ __STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -2635,17 +2745,24 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } #endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif /* ########################## FPU functions #################################### */ /** diff --git a/arch/arm/common/cmsis/core_cm4.h b/arch/arm/common/cmsis/core_cm4.h index 2da78d398..7d5687353 100644 --- a/arch/arm/common/cmsis/core_cm4.h +++ b/arch/arm/common/cmsis/core_cm4.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_cm4.h * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 30. January 2017 + * @version V5.0.8 + * @date 04. June 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (4U) /*!< Cortex-M Core */ @@ -844,7 +846,7 @@ typedef struct /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ @@ -1058,7 +1060,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -1069,7 +1071,7 @@ typedef struct __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; @@ -1139,8 +1141,11 @@ typedef struct #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ @@ -1165,12 +1170,15 @@ typedef struct #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1192,12 +1200,12 @@ typedef struct #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -1227,6 +1235,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1626,6 +1636,14 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + /** \brief Set Priority Grouping @@ -1645,7 +1663,7 @@ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } @@ -1671,7 +1689,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1688,7 +1706,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1707,7 +1725,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -1726,7 +1744,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1745,7 +1763,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1760,7 +1778,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1777,7 +1795,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1799,11 +1817,11 @@ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -1822,11 +1840,11 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -1918,7 +1936,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void __NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -1935,6 +1953,14 @@ __STATIC_INLINE void __NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + /* ########################## FPU functions #################################### */ /** diff --git a/arch/arm/common/cmsis/core_cm7.h b/arch/arm/common/cmsis/core_cm7.h index 18104f01c..a14dc623b 100644 --- a/arch/arm/common/cmsis/core_cm7.h +++ b/arch/arm/common/cmsis/core_cm7.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_cm7.h * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @version V5.0.8 + * @date 04. June 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,15 +23,15 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif #ifndef __CORE_CM7_H_GENERIC #define __CORE_CM7_H_GENERIC -#include +#include #ifdef __cplusplus extern "C" { @@ -60,11 +60,13 @@ @{ */ -/* CMSIS CM7 definitions */ -#define __CM7_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __CM7_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ - __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_M (7U) /*!< Cortex-M Core */ @@ -482,7 +484,7 @@ typedef struct uint32_t RESERVED4[15U]; __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ uint32_t RESERVED5[1U]; __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ uint32_t RESERVED6[1U]; @@ -1046,7 +1048,7 @@ typedef struct /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ @@ -1263,7 +1265,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -1274,7 +1276,7 @@ typedef struct __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; @@ -1344,8 +1346,11 @@ typedef struct #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ @@ -1370,12 +1375,15 @@ typedef struct #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1397,12 +1405,12 @@ typedef struct #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -1432,6 +1440,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1801,7 +1811,12 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ @@ -1813,9 +1828,15 @@ typedef struct #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -1823,6 +1844,14 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + /** \brief Set Priority Grouping @@ -1842,7 +1871,7 @@ __STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } @@ -1868,7 +1897,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1885,7 +1914,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1904,7 +1933,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -1923,7 +1952,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1942,7 +1971,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1957,7 +1986,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1974,7 +2003,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1996,11 +2025,11 @@ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -2019,11 +2048,11 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -2115,7 +2144,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -2132,6 +2161,13 @@ __STATIC_INLINE void NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif /* ########################## FPU functions #################################### */ /** @@ -2283,9 +2319,9 @@ __STATIC_INLINE void SCB_EnableDCache (void) __STATIC_INLINE void SCB_DisableDCache (void) { #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) - register uint32_t ccsidr; - register uint32_t sets; - register uint32_t ways; + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ __DSB(); diff --git a/arch/arm/common/cmsis/core_sc000.h b/arch/arm/common/cmsis/core_sc000.h index 8305271f4..9b67c92f3 100644 --- a/arch/arm/common/cmsis/core_sc000.h +++ b/arch/arm/common/cmsis/core_sc000.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_sc000.h * @brief CMSIS SC000 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @version V5.0.5 + * @date 28. May 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS SC000 definitions */ -#define __SC000_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __SC000_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ - __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_SC (000U) /*!< Cortex secure core */ @@ -692,7 +694,12 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else /*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ /*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ #define NVIC_EnableIRQ __NVIC_EnableIRQ @@ -704,9 +711,15 @@ typedef struct /*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -714,7 +727,13 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 -/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ /* The following MACROS handle generation of the register offset and byte masks */ #define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) #define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) @@ -731,7 +750,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -748,7 +767,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -767,7 +786,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -786,7 +805,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -805,7 +824,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -820,7 +839,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -907,7 +926,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ diff --git a/arch/arm/common/cmsis/core_sc300.h b/arch/arm/common/cmsis/core_sc300.h index 1b5041a78..3e8a47109 100644 --- a/arch/arm/common/cmsis/core_sc300.h +++ b/arch/arm/common/cmsis/core_sc300.h @@ -1,11 +1,11 @@ /**************************************************************************//** * @file core_sc300.h * @brief CMSIS SC300 Core Peripheral Access Layer Header File - * @version V5.0.1 - * @date 25. November 2016 + * @version V5.0.6 + * @date 04. June 2018 ******************************************************************************/ /* - * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -23,8 +23,8 @@ */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -60,11 +60,13 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS SC300 definitions */ -#define __SC300_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ -#define __SC300_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ - __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ #define __CORTEX_SC (300U) /*!< Cortex secure core */ @@ -975,7 +977,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -986,7 +988,7 @@ typedef struct __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; @@ -1056,8 +1058,11 @@ typedef struct #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ @@ -1082,12 +1087,15 @@ typedef struct #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1109,12 +1117,12 @@ typedef struct #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ @@ -1401,7 +1409,12 @@ typedef struct @{ */ -#ifndef CMSIS_NVIC_VIRTUAL +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping #define NVIC_EnableIRQ __NVIC_EnableIRQ @@ -1413,9 +1426,15 @@ typedef struct #define NVIC_GetActive __NVIC_GetActive #define NVIC_SetPriority __NVIC_SetPriority #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset #endif /* CMSIS_NVIC_VIRTUAL */ -#ifndef CMSIS_VECTAB_VIRTUAL +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else #define NVIC_SetVector __NVIC_SetVector #define NVIC_GetVector __NVIC_GetVector #endif /* (CMSIS_VECTAB_VIRTUAL) */ @@ -1423,6 +1442,12 @@ typedef struct #define NVIC_USER_IRQ_OFFSET 16 +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + /** \brief Set Priority Grouping @@ -1468,7 +1493,7 @@ __STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1485,7 +1510,7 @@ __STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1504,7 +1529,7 @@ __STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); __DSB(); __ISB(); } @@ -1523,7 +1548,7 @@ __STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1542,7 +1567,7 @@ __STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1557,7 +1582,7 @@ __STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); } } @@ -1574,7 +1599,7 @@ __STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { if ((int32_t)(IRQn) >= 0) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); } else { @@ -1596,11 +1621,11 @@ __STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { if ((int32_t)(IRQn) >= 0) { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } @@ -1619,11 +1644,11 @@ __STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -1715,7 +1740,7 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ diff --git a/arch/arm/common/cmsis/mpu_armv7.h b/arch/arm/common/cmsis/mpu_armv7.h new file mode 100644 index 000000000..01422033d --- /dev/null +++ b/arch/arm/common/cmsis/mpu_armv7.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if non-shareable) or 010b (if shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/arch/arm/common/cmsis/mpu_armv8.h b/arch/arm/common/cmsis/mpu_armv8.h new file mode 100644 index 000000000..62571da5b --- /dev/null +++ b/arch/arm/common/cmsis/mpu_armv8.h @@ -0,0 +1,333 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Msk) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/arch/arm/common/cmsis/tz_context.h b/arch/arm/common/cmsis/tz_context.h index cd6d8ab07..0d09749f3 100644 --- a/arch/arm/common/cmsis/tz_context.h +++ b/arch/arm/common/cmsis/tz_context.h @@ -1,5 +1,11 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ /* - * Copyright (c) 2015-2016 ARM Limited. All rights reserved. + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -14,56 +20,51 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * - * ---------------------------------------------------------------------------- - * - * $Date: 21. September 2016 - * $Revision: V1.0 - * - * Project: TrustZone for ARMv8-M - * Title: Context Management for ARMv8-M TrustZone - * - * Version 1.0 - * Initial Release - *---------------------------------------------------------------------------*/ + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif #ifndef TZ_CONTEXT_H #define TZ_CONTEXT_H - + #include - + #ifndef TZ_MODULEID_T #define TZ_MODULEID_T /// \details Data type that identifies secure software modules called by a process. typedef uint32_t TZ_ModuleId_t; #endif - + /// \details TZ Memory ID identifies an allocated memory slot. typedef uint32_t TZ_MemoryId_t; - + /// Initialize secure context memory system /// \return execution status (1: success, 0: error) uint32_t TZ_InitContextSystem_S (void); - + /// Allocate context memory for calling secure software modules in TrustZone /// \param[in] module identifies software modules called from non-secure mode /// \return value != 0 id TrustZone memory slot identifier /// \return value 0 no memory available or internal error TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); - + /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S /// \param[in] id TrustZone memory slot identifier /// \return execution status (1: success, 0: error) uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); - + /// Load secure context (called on RTOS thread context switch) /// \param[in] id TrustZone memory slot identifier /// \return execution status (1: success, 0: error) uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); - + /// Store secure context (called on RTOS thread context switch) /// \param[in] id TrustZone memory slot identifier /// \return execution status (1: success, 0: error) uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); - + #endif // TZ_CONTEXT_H diff --git a/arch/arm/cortex-a/Makefile b/arch/arm/cortex-a/Makefile new file mode 100644 index 000000000..58364c8de --- /dev/null +++ b/arch/arm/cortex-a/Makefile @@ -0,0 +1,19 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(LOSCFG_ARCH_CPU) + +LOCAL_SRCS := $(wildcard src/*.c) $(wildcard ../../common/*.c) $(wildcard src/*.S) +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/kernel/base/include \ + -I $(LITEOSTOPDIR)/kernel/extended/include + +ifeq ($(LITEOS_ARM_ARCH), -march=armv7-a) +LOCAL_SRCS += $(wildcard src/armv7a/*.S) +endif + +LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS) + +ifeq ($(LOSCFG_GDB), y) +LOCAL_FLAGS += $(AS_OBJS_LIBC_FLAGS) +endif +include $(MODULE) diff --git a/arch/arm/cortex-a/include/arch_config.h b/arch/arm/cortex-a/include/arch_config.h new file mode 100644 index 000000000..b61802e82 --- /dev/null +++ b/arch/arm/cortex-a/include/arch_config.h @@ -0,0 +1,81 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: Aarch32 Config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _ARCH_CONFIG_H +#define _ARCH_CONFIG_H + +#include "menuconfig.h" + +#define CPSR_INT_DISABLE 0xC0 /* Disable both FIQ and IRQ */ +#define CPSR_IRQ_DISABLE 0x80 /* IRQ disabled when =1 */ +#define CPSR_FIQ_DISABLE 0x40 /* FIQ disabled when =1 */ +#define CPSR_THUMB_ENABLE 0x20 /* Thumb mode when =1 */ +#define CPSR_USER_MODE 0x10 +#define CPSR_FIQ_MODE 0x11 +#define CPSR_IRQ_MODE 0x12 +#define CPSR_SVC_MODE 0x13 +#define CPSR_ABT_MODE 0x17 +#define CPSR_UNDEF_MODE 0x1B + +/* Define exception type ID */ +#define OS_EXCEPT_RESET 0x00 +#define OS_EXCEPT_UNDEF_INSTR 0x01 +#define OS_EXCEPT_SWI 0x02 +#define OS_EXCEPT_PREFETCH_ABORT 0x03 +#define OS_EXCEPT_DATA_ABORT 0x04 +#define OS_EXCEPT_FIQ 0x05 +#define OS_EXCEPT_ADDR_ABORT 0x06 +#define OS_EXCEPT_IRQ 0x07 + +/* Define core num */ +#define CORE_NUM 1 + +/* Initial bit32 stack value. */ +#define OS_STACK_INIT 0xCACACACA +/* Bit32 stack top magic number. */ +#define OS_STACK_MAGIC_WORD 0xCCCCCCCC + +#ifdef LOSCFG_GDB +#define OS_EXC_UNDEF_STACK_SIZE 512 +#define OS_EXC_ABT_STACK_SIZE 512 +#else +#define OS_EXC_UNDEF_STACK_SIZE 40 +#define OS_EXC_ABT_STACK_SIZE 40 +#endif +#define OS_EXC_FIQ_STACK_SIZE 64 +#define OS_EXC_IRQ_STACK_SIZE 64 +#define OS_EXC_SVC_STACK_SIZE 0x1000 +#define OS_EXC_STACK_SIZE 0x1000 + +#endif \ No newline at end of file diff --git a/arch/arm/cortex-a/include/los_atomic.h b/arch/arm/cortex-a/include/los_atomic.h new file mode 100644 index 000000000..44a4b29d0 --- /dev/null +++ b/arch/arm/cortex-a/include/los_atomic.h @@ -0,0 +1,919 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Atomic HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_atomic Atomic + * @ingroup kernel + */ + +#ifndef __LOS_ATOMIC_H__ +#define __LOS_ATOMIC_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef volatile INT32 Atomic; +typedef volatile INT64 Atomic64; + +/** + * @ingroup los_atomic + * @brief Atomic read. + * + * @par Description: + * This API is used to implement the atomic read and return the result value of the read. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    + * + * @param v [IN] The reading pointer. + * + * @retval #INT32 The result value of the read. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v) +{ + return *(volatile INT32 *)v; +} + +/** + * @ingroup los_atomic + * @brief Atomic setting. + * + * @par Description: + * This API is used to implement the atomic setting operation. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    + * + * @param v [IN] The variable pointer to be setting. + * @param setVal [IN] The value to be setting. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal) +{ + *(volatile INT32 *)v = setVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic addition. + * + * @par Description: + * This API is used to implement the atomic addition and return the result value of the augend. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • If the addtion result is not in the range of representable values for 32-bit signed integer, + * an int integer overflow may occur to the return value
    • + *
    + * + * @param v [IN] The augend pointer. + * @param addVal [IN] The addend. + * + * @retval #INT32 The result value of the augend. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %1, [%2]\n" + "add %1, %1, %3\n" + "strex %0, %1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(addVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic subtraction. + * + * @par Description: + * This API is used to implement the atomic subtraction and return the result value of the minuend. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • If the subtraction result is not in the range of representable values for 32-bit signed integer, + * an int integer overflow may occur to the return value
    • + *
    + * + * @param v [IN] The minuend pointer. + * @param subVal [IN] The subtrahend. + * + * @retval #INT32 The result value of the minuend. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %1, [%2]\n" + "sub %1, %1, %3\n" + "strex %0, %1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(subVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic addSelf. + * + * @par Description: + * This API is used to implement the atomic addSelf. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MAX to avoid integer overflow after adding 1.
    • + *
    + * + * @param v [IN] The addSelf variable pointer. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE VOID LOS_AtomicInc(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "add %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic addSelf. + * + * @par Description: + * This API is used to implement the atomic addSelf and return the result of addSelf. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MAX to avoid integer overflow after adding 1.
    • + *
    + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT32 The return value of variable addSelf. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicIncRet(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "add %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic auto-decrement. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MIN to avoid overflow after reducing 1.
    • + *
    + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE VOID LOS_AtomicDec(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic auto-decrement and return the result of auto-decrement. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MIN to avoid overflow after reducing 1.
    • + *
    + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval #INT32 The return value of variable auto-decrement. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 read. + * + * @par Description: + * This API is used to implement the atomic64 read and return the result value of the read. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    + * + * @param v [IN] The reading pointer. + * + * @retval #INT64 The result value of the read. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v) +{ + INT64 val; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%1]" + : "=&r"(val) + : "r"(v) + : "cc"); + } while (0); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 setting. + * + * @par Description: + * This API is used to implement the atomic64 setting operation. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    + * + * @param v [IN] The variable pointer to be setting. + * @param setVal [IN] The value to be setting. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal) +{ + INT64 tmp; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %1, %H1, [%2]\n" + "strexd %0, %3, %H3, [%2]" + : "=&r"(status), "=&r"(tmp) + : "r"(v), "r"(setVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic64 addition. + * + * @par Description: + * This API is used to implement the atomic64 addition and return the result value of the augend. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • If the addtion result is not in the range of representable values for 64-bit signed integer, + * an int integer overflow may occur to the return value
    • + *
    + * + * @param v [IN] The augend pointer. + * @param addVal [IN] The addend. + * + * @retval #INT64 The result value of the augend. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %1, %H1, [%2]\n" + "adds %Q1, %Q1, %Q3\n" + "adc %R1, %R1, %R3\n" + "strexd %0, %1, %H1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(addVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 subtraction. + * + * @par Description: + * This API is used to implement the atomic64 subtraction and return the result value of the minuend. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • If the subtraction result is not in the range of representable values for 64-bit signed integer, + * an int integer overflow may occur to the return value
    • + *
    + * + * @param v [IN] The minuend pointer. + * @param subVal [IN] The subtrahend. + * + * @retval #INT64 The result value of the minuend. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %1, %H1, [%2]\n" + "subs %Q1, %Q1, %Q3\n" + "sbc %R1, %R1, %R3\n" + "strexd %0, %1, %H1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(subVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 addSelf. + * + * @par Description: + * This API is used to implement the atomic64 addSelf . + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT64_MAX to avoid integer overflow after adding 1.
    • + *
    + * + * @param v [IN] The addSelf variable pointer. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "adds %Q0, %Q0, #1\n" + "adc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic64 addSelf. + * + * @par Description: + * This API is used to implement the atomic64 addSelf and return the result of addSelf. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT64_MAX to avoid integer overflow after adding 1.
    • + *
    + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT64 The return value of variable addSelf. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "adds %Q0, %Q0, #1\n" + "adc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic64 auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic64 auto-decrement. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT64_MIN to avoid overflow after reducing 1.
    • + *
    + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "subs %Q0, %Q0, #1\n" + "sbc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic64 auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic64 auto-decrement and return the result of auto-decrement. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT64_MIN to avoid overflow after reducing 1.
    • + *
    + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval #INT64 The return value of variable auto-decrement. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v) +{ + INT64 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "subs %Q0, %Q0, #1\n" + "sbc %R0, %R0, #0\n" + "strexd %1, %0, %H0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 8-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 8-bit variable and + * return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicXchgByte(volatile INT8 *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexb %0, [%3]\n" + "strexb %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 16-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 16-bit variable and + * return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicXchg16bits(volatile INT16 *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexh %0, [%3]\n" + "strexh %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable + * and return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "strex %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 64-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 64-bit variable + * and return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT64 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val) +{ + INT64 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "strexd %1, %4, %H4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 8-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 8-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchgByte(volatile INT8 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexb %0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "strexbeq %1, %5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 16-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 16-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg16bits(volatile INT16 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexh %0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "strexheq %1, %5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "strexeq %1, %5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 64-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 64-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal) +{ + INT64 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexd %0, %H0, [%3]\n" + "mov %1, #0\n" + "teq %0, %4\n" + "teqeq %H0, %H4\n" + "strexdeq %1, %5, %H5, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_ATOMIC_H__ */ diff --git a/arch/arm/cortex-a/include/los_exc.h b/arch/arm/cortex-a/include/los_exc.h new file mode 100644 index 000000000..62566dfac --- /dev/null +++ b/arch/arm/cortex-a/include/los_exc.h @@ -0,0 +1,240 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Exception handling HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_exc Exception handling + * @ingroup kernel + */ +#ifndef _LOS_EXC_H +#define _LOS_EXC_H + +#include "los_hwi.h" +#include "arch_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_exc + * Register information structure + * + * Description: register information stored when an exception occurs on an LPC2458 platform. + * + * Note: The following register names without uw are the register names used in the chip manual. + */ +#ifdef LOSCFG_ARCH_ARM_AARCH64 +#define EXC_GEN_REGS_NUM 30 +typedef struct { + UINT64 X[EXC_GEN_REGS_NUM]; /**< Register X0-X29 */ + UINT64 LR; /**< Program returning address. X30 */ + UINT64 SP; + UINT64 regELR; + UINT64 SPSR; +} ExcContext; +#else +typedef struct { + UINT32 regCPSR; /**< Current program status register (CPSR) */ + UINT32 R0; /**< Register R0 */ + UINT32 R1; /**< Register R1 */ + UINT32 R2; /**< Register R2 */ + UINT32 R3; /**< Register R3 */ + UINT32 R4; /**< Register R4 */ + UINT32 R5; /**< Register R5 */ + UINT32 R6; /**< Register R6 */ + UINT32 R7; /**< Register R7 */ + UINT32 R8; /**< Register R8 */ + UINT32 R9; /**< Register R9 */ + UINT32 R10; /**< Register R10 */ + UINT32 R11; /**< Register R11 */ + UINT32 R12; /**< Register R12 */ + UINT32 SP; /**< Stack pointer */ + UINT32 LR; /**< Program returning address. */ + UINT32 PC; /**< PC pointer of the exceptional function */ +} ExcContext; +#endif + +/** + * @ingroup los_exc + * Exception information structure + * + * Description: exception information stored when an exception occurs on an LPC2458 platform. + * + */ +typedef struct { + UINT16 phase; /**< Phase in which an exception occurs */ + UINT16 type; /**< Exception type */ + UINT16 nestCnt; /**< Count of nested exception */ + UINT16 reserved; /**< Reserved for alignment */ + ExcContext *context; /**< Hardware context when an exception occurs */ +} ExcInfo; + +/** + * @ingroup los_exc + * @brief Kernel FP Register address obtain function. + * + * @par Description: + * The API is used to obtain the FP Register address. + * @attention None. + * + * @param None. + * + * @retval #UINTPTR The FP Register address. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE UINTPTR Get_Fp(VOID) +{ + UINTPTR regFp; + +#ifdef LOSCFG_ARCH_ARM_AARCH64 + __asm__ __volatile__("mov %0, X29" : "=r"(regFp)); +#else + __asm__ __volatile__("mov %0, fp" : "=r"(regFp)); +#endif + + return regFp; +} + +/** + * @ingroup los_exc + * @brief Define an exception handling function hook. + * + * @par Description: + * This API is used to define the exception handling function hook based on the type of + * the exception handling function and record exceptions. + * @attention None. + * + * @param None. + * + * @retval None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +typedef VOID (*EXC_PROC_FUNC)(UINT32, ExcContext *); + +/** + * @ingroup los_exc + * @brief Register an exception handling hook. + * + * @par Description: + * This API is used to register an exception handling hook. + * @attention If the hook is registered for multiple times, the hook registered at the last time is effective. + * @attention The hook can be registered as NULL, indicating that the hook registration is canceled. + * @param excHook [IN] Type #EXC_PROC_FUNC: hook function. + * + * @retval #LOS_OK The exception handling hook is successfully registered. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook); + +/** + * @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. + * @since Huawei LiteOS V100R001C00 + */ +VOID LOS_Panic(const CHAR *fmt, ...); + +/** + * @ingroup los_exc + * @brief Kernel backtrace function. + * + * @par Description: + * Backtrace function that prints task call stack information traced from the running task. + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsBackTrace(VOID); + +/** + * @ingroup los_exc + * @brief Kernel task backtrace function. + * + * @par Description: + * Backtrace function that prints task call stack information traced from the input task. + * @attention + *
      + *
    • The input taskID should be valid.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsTaskBackTrace(UINT32 taskID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXC_H */ diff --git a/arch/arm/cortex-a/include/los_hw_cpu.h b/arch/arm/cortex-a/include/los_hw_cpu.h new file mode 100644 index 000000000..c130abb07 --- /dev/null +++ b/arch/arm/cortex-a/include/los_hw_cpu.h @@ -0,0 +1,250 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Hw CPU HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ + +#ifndef __LOS_HW_CPU_H__ +#define __LOS_HW_CPU_H__ + +#include "los_typedef.h" +#include "los_toolchain.h" +#include "los_hw_arch.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* ARM System Registers */ +#define DSB __asm__ volatile("dsb" ::: "memory") +#define DMB __asm__ volatile("dmb" ::: "memory") +#define ISB __asm__ volatile("isb" ::: "memory") +#define BARRIER __asm__ volatile("":::"memory") + +#define ARM_SYSREG_READ(REG) \ +({ \ + UINT32 _val; \ + __asm__ volatile("mrc " REG : "=r" (_val)); \ + _val; \ +}) + +#define ARM_SYSREG_WRITE(REG, val) \ +({ \ + __asm__ volatile("mcr " REG :: "r" (val)); \ + ISB; \ +}) + +#define ARM_SYSREG64_READ(REG) \ +({ \ + UINT64 _val; \ + __asm__ volatile("mrrc " REG : "=r" (_val)); \ + _val; \ +}) + +#define ARM_SYSREG64_WRITE(REG, val) \ +({ \ + __asm__ volatile("mcrr " REG :: "r" (val)); \ + ISB; \ +}) + +#define CP14_REG(CRn, Op1, CRm, Op2) "p14, "#Op1", %0, "#CRn","#CRm","#Op2 +#define CP15_REG(CRn, Op1, CRm, Op2) "p15, "#Op1", %0, "#CRn","#CRm","#Op2 +#define CP15_REG64(CRn, Op1) "p15, "#Op1", %0, %H0,"#CRn + +/* + * Identification registers (c0) + */ +#define MIDR CP15_REG(c0, 0, c0, 0) /* Main ID Register */ +#define MPIDR CP15_REG(c0, 0, c0, 5) /* Multiprocessor Affinity Register */ +#define CCSIDR CP15_REG(c0, 1, c0, 0) /* Cache Size ID Registers */ +#define CLIDR CP15_REG(c0, 1, c0, 1) /* Cache Level ID Register */ +#define VPIDR CP15_REG(c0, 4, c0, 0) /* Virtualization Processor ID Register */ +#define VMPIDR CP15_REG(c0, 4, c0, 5) /* Virtualization Multiprocessor ID Register */ + +/* + * System control registers (c1) + */ +#define SCTLR CP15_REG(c1, 0, c0, 0) /* System Control Register */ +#define ACTLR CP15_REG(c1, 0, c0, 1) /* Auxiliary Control Register */ +#define CPACR CP15_REG(c1, 0, c0, 2) /* Coprocessor Access Control Register */ + +/* + * Memory protection and control registers (c2 & c3) + */ +#define TTBR0 CP15_REG(c2, 0, c0, 0) /* Translation Table Base Register 0 */ +#define TTBR1 CP15_REG(c2, 0, c0, 1) /* Translation Table Base Register 1 */ +#define TTBCR CP15_REG(c2, 0, c0, 2) /* Translation Table Base Control Register */ +#define DACR CP15_REG(c3, 0, c0, 0) /* Domain Access Control Register */ + +/* + * Memory system fault registers (c5 & c6) + */ +#define DFSR CP15_REG(c5, 0, c0, 0) /* Data Fault Status Register */ +#define IFSR CP15_REG(c5, 0, c0, 1) /* Instruction Fault Status Register */ +#define DFAR CP15_REG(c6, 0, c0, 0) /* Data Fault Address Register */ +#define IFAR CP15_REG(c6, 0, c0, 2) /* Instruction Fault Address Register */ + +/* + * Process, context and thread ID registers (c13) + */ +#define FCSEIDR CP15_REG(c13, 0, c0, 0) /* FCSE Process ID Register */ +#define CONTEXTIDR CP15_REG(c13, 0, c0, 1) /* Context ID Register */ +#define TPIDRURW CP15_REG(c13, 0, c0, 2) /* User Read/Write Thread ID Register */ +#define TPIDRURO CP15_REG(c13, 0, c0, 3) /* User Read-Only Thread ID Register */ +#define TPIDRPRW CP15_REG(c13, 0, c0, 4) /* PL1 only Thread ID Register */ + +#define MPIDR_CPUID_MASK (0xffU) + +STATIC INLINE VOID *ArchCurrTaskGet(VOID) +{ + return (VOID *)ARM_SYSREG_READ(TPIDRPRW); +} + +STATIC INLINE VOID ArchCurrTaskSet(VOID *val) +{ + ARM_SYSREG_WRITE(TPIDRPRW, (UINT32)val); +} + +STATIC INLINE UINT32 ArchCurrCpuid(VOID) +{ + return 0; +} + +STATIC INLINE UINT64 OsHwIDGet(VOID) +{ + return ARM_SYSREG_READ(MPIDR); +} + +STATIC INLINE UINT32 OsMainIDGet(VOID) +{ + return ARM_SYSREG_READ(MIDR); +} + +/* CPU interrupt mask handle implementation */ +#if LOSCFG_ARM_ARCH >= 6 + +STATIC INLINE UINT32 ArchIntLock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "cpsid if " + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +STATIC INLINE UINT32 ArchIntUnlock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "cpsie if " + : "=r"(intSave) + : + : "memory"); + return intSave; +} + +#else + +STATIC INLINE UINT32 ArchIntLock(VOID) +{ + UINT32 intSave, temp; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "orr %1, %0, #0xc0 \n" + "msr cpsr_c, %1 " + :"=r"(intSave), "=r"(temp) + : :"memory"); + return intSave; +} + +STATIC INLINE UINT32 ArchIntUnlock(VOID) +{ + UINT32 intSave; + __asm__ __volatile__( + "mrs %0, cpsr \n" + "bic %0, %0, #0xc0 \n" + "msr cpsr_c, %0 " + : "=r"(intSave) + : : "memory"); + return intSave; +} + +#endif + +STATIC INLINE VOID ArchIntRestore(UINT32 intSave) +{ + __asm__ __volatile__( + "msr cpsr_c, %0 " + : + : "r"(intSave) + : "memory"); +} + +#define PSR_I_BIT 0x00000080U + +STATIC INLINE UINT32 OsIntLocked(VOID) +{ + UINT32 intSave; + + asm volatile( + "mrs %0, cpsr " + : "=r" (intSave) + : + : "memory", "cc"); + + return intSave & PSR_I_BIT; +} + +STATIC INLINE UINT32 ArchSPGet(VOID) +{ + UINT32 val; + __asm__ __volatile__("mov %0, sp" : "=r"(val)); + return val; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_HW_CPU_H__ */ diff --git a/arch/arm/cortex-a/libmk b/arch/arm/cortex-a/libmk new file mode 100644 index 000000000..83957c428 --- /dev/null +++ b/arch/arm/cortex-a/libmk @@ -0,0 +1,13 @@ +include $(LITEOSTOPDIR)/config.mk + +ARFLAGS = cr + +all: + mkdir -p $(OUT)/lib + cp -rf $(LITEOS_CPU_TYPE)/*.a $(OUT)/lib + + +clean: + rm -rf $(OUT)/lib/lib$(LITEOS_CPU_TYPE).a + +.PHONY: all clean diff --git a/arch/arm/cortex-a/src/armv7a/cache.S b/arch/arm/cortex-a/src/armv7a/cache.S new file mode 100644 index 000000000..568987411 --- /dev/null +++ b/arch/arm/cortex-a/src/armv7a/cache.S @@ -0,0 +1,82 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: cache + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "asm.h" + + .fpu vfpv4 + .arch armv7a +.macro DCACHE_LINE_SIZE, reg, tmp + mrc p15, 0, \tmp, c0, c0, 1 + lsr \tmp, \tmp, #16 + and \tmp, \tmp, #0xf + mov \reg, #4 + mov \reg, \reg, lsl \tmp +.endm + + +FUNCTION(arm_inv_cache_range) + push {r2, r3} + DCACHE_LINE_SIZE r2, r3 + sub r3, r2, #1 + tst r0, r3 + bic r0, r0, r3 + + mcrne p15, 0, r0, c7, c14, 1 + + tst r1, r3 + bic r1, r1, r3 + mcrne p15, 0, r1, c7, c14, 1 +1: + mcr p15, 0, r0, c7, c6, 1 + add r0, r0, r2 + cmp r0, r1 + blo 1b + dsb + pop {r2, r3} + mov pc, lr + +FUNCTION(arm_clean_cache_range) + push {r2, r3} + DCACHE_LINE_SIZE r2, r3 + sub r3, r2, #1 + bic r0, r0, r3 + +1: + mcr p15, 0, r0, c7, c10, 1 + add r0, r0, r2 + cmp r0, r1 + blo 1b + dsb + pop {r2, r3} + mov pc, lr diff --git a/arch/arm/cortex-a/src/armv7a/mmu.S b/arch/arm/cortex-a/src/armv7a/mmu.S new file mode 100644 index 000000000..d7d0a101c --- /dev/null +++ b/arch/arm/cortex-a/src/armv7a/mmu.S @@ -0,0 +1,113 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: mmu + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + + .global _platform_setup + .fpu vfpv4 + .arch armv7a + +.macro INVALIDATE_DCACHE_ALL + /* + * Invalidate Data cache + * to make the code general purpose, we calculate the + * cache size first and loop through each set + way + */ + mrc p15, 1, r0, c0, c0, 0 /* Read Cache Size ID */ + mov r3, #0x1ff + and r0, r3, r0, lsr #13 /* r0 = no. of sets - 1 */ + mov r1, #0 /* r1 = way counter way_loop */ +way_loop: + mov r3, #0 /* r3 = set counter set_loop */ +set_loop: + mov r2, r1, lsl #30 + orr r2, r3, lsl #5 /* r2 = set/way cache operation format */ + mcr p15, 0, r2, c7, c6, 2 /* Invalidate line described by r2 */ + add r3, r3, #1 /* Increment set counter */ + cmp r0, r3 /* Last set reached yet */ + bgt set_loop /* if not, iterate set_loop */ + add r1, r1, #1 /* else, next */ + cmp r1, #4 /* Last way reached yet */ + bne way_loop /* if not, iterate way_loop */ + + mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLB */ +.endm + +_platform_setup: + push {lr} + + cmp r11, #0 + bleq board_config + + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x1000 /* disable ICache [SCTRL:bit 12 set as 0] */ + bic r0, r0, #0x000f /* disable DCache, write buffer */ + mcr p15, 0, r0, c1, c0, 0 + ISB + + INVALIDATE_DCACHE_ALL + + mov r0, #0 /* TTBCR, Translation Table Base Control Register, select TTBR0 */ + mcr p15, 0, r0, c2, c0, 2 + ISB + + bl OsMmuInit /* MMU init */ + + mrc p15, 0, r0, c1, c0, 1 /* ACTLR, Auxlliary Control Register */ + orr r0, r0, #(1U << 6) /* SMP, Enables coherent requests to the processor. */ + orr r0, r0, #(1U << 2) /* Enable D-side prefetch */ + orr r0, r0, #(1U << 11) /* Global BP Enable bit */ + mcr p15, 0, r0, c1, c0, 1 /* ACTLR, Auxlliary Control Register */ + + ldr r2, =10f + + DSB + mov r0, #0 + tst r11, #0xf + mcrne p15, 0, r0, c8, c7, 0 /* TBLIALL, invalidate unified TLB */ + + mrc p15, 0, r0, c1, c0, 0 /* SCTLB, System Control Register */ + bic r0, #((1U << 29) | (1U << 28)) /* Disable TRE/AFE */ + orr r0, r0, #(1U << 12) /* enable ICache */ + orr r0, r0, #(1U << 2) /* Dcache enable */ + orr r0, r0, #(1U << 8) /* 'S' bit */ + orr r0, r0, #(1U << 5) /* CP15BEN bit */ + orr r0, r0, #1 /* mmu enable */ + mcr p15, 0, r0, c1, c0, 0 /* SCTLB, System Control Register */ + ISB + + mov pc, r2 + nop + nop + nop +10: + pop {pc} diff --git a/arch/arm/cortex-a/src/include/asm.h b/arch/arm/cortex-a/src/include/asm.h new file mode 100644 index 000000000..8a1666e22 --- /dev/null +++ b/arch/arm/cortex-a/src/include/asm.h @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Assembly HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef __ASM_H +#define __ASM_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define FUNCTION(x) .global x; .text; .code 32; x: + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __ASM_H */ diff --git a/kernel/base/include/los_memstat.ph b/arch/arm/cortex-a/src/include/los_exc_pri.h similarity index 75% rename from kernel/base/include/los_memstat.ph rename to arch/arm/cortex-a/src/include/los_exc_pri.h index 8d4e52a68..5a4f328da 100644 --- a/kernel/base/include/los_memstat.ph +++ b/arch/arm/cortex-a/src/include/los_exc_pri.h @@ -1,59 +1,55 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MEMSTAT_PH -#define _LOS_MEMSTAT_PH - -#include "los_typedef.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -extern VOID osTaskMemUsedInc(UINT32 uwUsedSize); -extern VOID osTaskMemUsedDec(UINT32 uwUsedSize); -extern UINT32 osTaskMemUsage(UINT32 uwTaskId); -extern UINT32 LOS_TaskMemUsage(UINT32 uwTaskId); - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_MEMSTAT_PH */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARM Exc Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_EXC_PRI_H +#define _LOS_EXC_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID BackTraceSub(UINTPTR regFP); +extern VOID OsExcInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXC_PRI_H */ \ No newline at end of file diff --git a/arch/arm/cortex-a/src/include/los_hw_pri.h b/arch/arm/cortex-a/src/include/los_hw_pri.h new file mode 100644 index 000000000..4d57ccc1d --- /dev/null +++ b/arch/arm/cortex-a/src/include/los_hw_pri.h @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Hw Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_HW_PRI_H +#define _LOS_HW_PRI_H + +#include "los_base.h" +#include "los_hw.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if defined(LOSCFG_ARCH_FPU_VFP_D16) +#define FP_REGS_NUM 16 +#elif defined (LOSCFG_ARCH_FPU_VFP_D32) +#define FP_REGS_NUM 32 +#endif +#define GEN_REGS_NUM 13 + +/* The size of this structure must be smaller than or equal to the size specified by OS_TSK_STACK_ALIGN (16 bytes). */ +typedef struct { +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + UINT64 D[FP_REGS_NUM]; /* D0-D31 */ + UINT32 regFPSCR; /* FPSCR */ + UINT32 regFPEXC; /* FPEXC */ +#endif + UINT32 R[GEN_REGS_NUM]; /* R0-R12 */ + UINT32 LR; /* R14 */ + UINT32 PC; /* R15 */ + UINT32 regPSR; +} TaskContext; + +STATIC INLINE UINT32 OsGetDFSR(VOID) +{ + UINT32 regDFSR; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" + : "=r"(regDFSR)); + return regDFSR; +} + +STATIC INLINE UINT32 OsGetIFSR(VOID) +{ + UINT32 regIFSR; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" + : "=r"(regIFSR)); + return regIFSR; +} + +STATIC INLINE UINT32 OsGetDFAR(VOID) +{ + UINT32 regDFAR; + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" + : "=r"(regDFAR)); + return regDFAR; +} + +STATIC INLINE UINT32 OsGetIFAR(VOID) +{ + UINT32 regIFAR; + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" + : "=r"(regIFAR)); + return regIFAR; +} + +/* + * Description : task stack initialization + * Input : taskID -- task ID + * stackSize -- task stack size + * topStack -- stack top of task (low address) + * Return : pointer to the task context + */ +extern VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack); +extern void arm_clean_cache_range(UINTPTR start, UINTPTR end); +extern void arm_inv_cache_range(UINTPTR start, UINTPTR end); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_PRI_H */ diff --git a/kernel/base/ipc/los_queue.inc b/arch/arm/cortex-a/src/include/los_hwi_pri.h similarity index 63% rename from kernel/base/ipc/los_queue.inc rename to arch/arm/cortex-a/src/include/los_hwi_pri.h index 939061eca..9c7bdeab1 100644 --- a/kernel/base/ipc/los_queue.inc +++ b/arch/arm/cortex-a/src/include/los_hwi_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Hwi Inner HeadFile * 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 @@ -22,20 +22,20 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_QUEUE_INC -#define _LOS_QUEUE_INC +#ifndef _LOS_HWI_PRI_H +#define _LOS_HWI_PRI_H -#include "los_queue.ph" +#include "los_hwi.h" #ifdef __cplusplus #if __cplusplus @@ -44,29 +44,27 @@ extern "C" { #endif /* __cplusplus */ /** - *@ingroup los_queue - *@brief Handle when read or write queue. - * - *@par Description: - *This API is used to handle when read or write queue. - *@attention - *
      - *
    • None.
    • - *
    - * - *@param UINT32 Queue id. - *@param UINT32 Operate type - *@param VOID * Buffer address. - *@param UINT32 Buffer size. - *@param UINT32 Timeout. - * - *@retval UINT32 Handle result. - *@par Dependency: - *
    • los_queue.inc: the header file that contains the API declaration.
    - *@see None. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_hwi + * The hwi form does not contain exceptions for Aarch32 */ -extern UINT32 osQueueOperate(UINT32 uwQueueID, UINT32 uwOperateType, VOID *pBufferAddr, UINT32 *puwBufferSize, UINT32 uwTimeOut); +#define OS_HWI_FORM_EXC_NUM 0 +#if OS_HWI_FORM_EXC_NUM != 0 +#error "OS_HWI_FORM_EXC_NUM must be zero" +#endif + +#define OS_SYS_VECTOR_CNT 0 +extern HWI_HANDLE_FORM_S g_hwiForm[OS_HWI_MAX_NUM + OS_SYS_VECTOR_CNT]; + +#ifdef LOSCFG_NO_SHARED_IRQ +#define HWI_IS_REGISTED(num) ((&g_hwiForm[num])->pfnHook != NULL) +#else +#define HWI_IS_REGISTED(num) ((&g_hwiForm[num])->pstNext != NULL) +#endif +extern VOID OsHwiInit(VOID); +extern VOID OsIncHwiFormCnt(UINT32 index); +extern UINT32 OsGetHwiFormCnt(UINT32 index); +extern CHAR *OsGetHwiFormName(UINT32 index); +extern VOID OsInterrupt(UINT32 intNum); #ifdef __cplusplus #if __cplusplus @@ -74,4 +72,4 @@ extern UINT32 osQueueOperate(UINT32 uwQueueID, UINT32 uwOperateType, VOID *pBuff #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* _LOS_QUEUE_INC */ +#endif /* _LOS_HWI_PRI_H */ diff --git a/arch/arm/cortex-a/src/include/los_mmu_pri.h b/arch/arm/cortex-a/src/include/los_mmu_pri.h new file mode 100644 index 000000000..ec5a89fcb --- /dev/null +++ b/arch/arm/cortex-a/src/include/los_mmu_pri.h @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: Arm-a Mmu Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MMU_PRI_H +#define _LOS_MMU_PRI_H + +#include "hisoc/mmu_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID OsSecPageInit(VOID); +extern VOID OsRemapNoCached(UINTPTR physAddr, size_t size); +extern VOID OsRemapCached(UINTPTR physAddr, size_t size); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MMU_PRI_H */ diff --git a/arch/arm/cortex-a/src/include/mmu.h b/arch/arm/cortex-a/src/include/mmu.h new file mode 100644 index 000000000..5693716c2 --- /dev/null +++ b/arch/arm/cortex-a/src/include/mmu.h @@ -0,0 +1,400 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARMv7 Mmu HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#ifndef _MMU_H +#define _MMU_H + +#include "los_typedef.h" +#include "los_toolchain.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define UNCACHEABLE 0 +#define CACHEABLE 1 +#define UNBUFFERABLE 0 +#define BUFFERABLE 1 +#define EXECUTABLE 0 +#define NON_EXECUTABLE 1 +#define ACCESS_RW 3 /* ap = 0 ap1 = 0b11 */ +#define ACCESS_RO 7 /* ap = 1 ap1 = 0b11 */ +#define ACCESS_NA 0 /* ap = 0 ap1 = 0 */ +#define D_MANAGER 0 +#define D_CLIENT 1 +#define D_NA 2 + +#define DOMAIN0 0 +#define DOMAIN1 1 +#define DOMAIN2 2 + +#define MMU_AP_STATE(flag) (((flag) & 0x1U) ? ACCESS_RW : ACCESS_RO) +#define MMU_CACHE_STATE(flag) (((flag) >> 1) & 0x1U) +#define MMU_BUFFER_STATE(flag) (((flag) >> 2) & 0x1U) +#define MMU_EXECUTE_STATE(flag) (((flag) >> 3) & 0x1U) +#define MMU_GET_AREA(flag) ((flag) & (0x1U << 4)) +#define MMU_DESC_LEN 4 +#define MMU_DESC_OFFSET(vBase) ((vBase) << 2) + +/** + * @ingroup mmu + * The access permission mode is read-only. + */ +#define ACCESS_PERM_RO_RO 0 + +/** + * @ingroup mmu + * The access permission mode is read and write. + */ +#define ACCESS_PERM_RW_RW (1U << 0) + +/** + * @ingroup mmu + * The cache enabled. + */ +#define CACHE_ENABLE (1U << 1) + +/** + * @ingroup mmu + * The cache disabled. + */ +#define CACHE_DISABLE 0 + +/** + * @ingroup mmu + * The buffer enabled. + */ +#define BUFFER_ENABLE (1U << 2) + +/** + * @ingroup mmu + * The buffer disabled. + */ +#define BUFFER_DISABLE 0 + +/** + * @ingroup mmu_config + * Set it non-executable. + */ +#define EXEC_DISABLE (1U << 3) + +/** + * @ingroup mmu_config + * Set it executable. + */ +#define EXEC_ENABLE 0 + +/** + * @ingroup mmu + * The first section(1M/item). + */ +#define FIRST_SECTION (1U << 4) + +/** + * @ingroup mmu + * The second page(4K/item). + */ +#define SECOND_PAGE 0 + +#define MMU_SHAREABLE 0 + +#define MMU_1K 0x400U +#define MMU_4K 0x1000U +#define MMU_16K 0x4000U +#define MMU_64K 0x10000U +#define MMU_1M 0x100000U +#define MMU_4G 0x100000000ULL + +#define SHIFT_1K 10 +#define SHIFT_4K 12 +#define SHIFT_16K 14 +#define SHIFT_64K 16 +#define SHIFT_1M 20 +#define SHIFT_2M 21 +#define SHIFT_1G 30 + +/** + * @ingroup mmu + * mmu second page information structure. + * + */ +typedef struct { + UINT32 page_addr; /* The second page start addr */ + UINT32 page_length; /* The second page length */ + + /* + * The second page page table storage addr, + * diff second page table can't be coincided + */ + UINT32 page_descriptor_addr; + + /* + * The second page type, it can be set + * small page ID(4K) : MMU_SECOND_LEVEL_SMALL_PAGE_TABLE_ID + * or big page ID(64K) : MMU_SECOND_LEVEL_BIG_PAGE_TABLE_ID + */ + UINT32 page_type; +} SENCOND_PAGE; + +/** + * @ingroup mmu + * mmu param setting information structure. + * + */ +typedef struct { + UINT32 startAddr; /* Starting address of a section. */ + UINT32 endAddr; /* Ending address of a section. */ + + /* + * Mode set. + * bit0: ACCESS_PERM_RW_RW/ACCESS_PERM_RO_RO(1/0) + * bit1: CACHE_ENABLE/CACHE_DISABLE(1/0) + * bit2: BUFFER_ENABLE/BUFFER_DISABLE(1/0) + * bit3: EXEC_DISENABLE/EXEC_ENABLE(1/0) + * bit4: FIRST_SECTION/SECOND_PAGE(1/0) + * bit5~7: ignore + */ + UINT32 uwFlag; + + /* + * the goal object of second page, + * if uwFlag is FIRST_SECTION, stPage will be ignored, and you can set this member as NULL + */ + SENCOND_PAGE *stPage; +} MMU_PARAM; + +/* ARM Domain Access Control Bit Masks */ +#define ACCESS_TYPE_NO_ACCESS(domainNum) (0x0U << ((domainNum) << 1)) +#define ACCESS_TYPE_CLIENT(domainNum) (0x1U << ((domainNum) << 1)) +#define ACCESS_TYPE_MANAGER(domainNum) (0x3U << ((domainNum) << 1)) + +#define MMU_FIRST_LEVEL_FAULT_ID 0x0 +#define MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1 +#define MMU_FIRST_LEVEL_SECTION_ID 0x2 +#define MMU_FIRST_LEVEL_RESERVED_ID 0x3 +/** + * @ingroup mmu + * The second page type select 64K + */ +#define MMU_SECOND_LEVEL_BIG_PAGE_TABLE_ID 0x1U + +/** + * @ingroup mmu + * The second page type select 4K + */ +#define MMU_SECOND_LEVEL_SMALL_PAGE_TABLE_ID 0x2U + +struct MMUFirstLevelFault { + UINT32 id : 2; /* [1 : 0] */ + UINT32 sbz : 30; /* [31 : 2] */ +}; + +struct MMUFirstLevelPageTable { + UINT32 id : 2; /* [1 : 0] */ + UINT32 pxn : 1; /* [2] */ + UINT32 ns : 1; /* [3] */ + UINT32 sbz : 1; /* [4] */ + UINT32 domain : 4; /* [8 : 5] */ + UINT32 imp : 1; /* [9] */ + UINT32 baseAddress : 22; /* [31 : 10] */ +}; + +struct MMUSecondLevelBigPageTable { + UINT32 id : 2; /* [1 : 0] */ + UINT32 b : 1; /* [2] */ + UINT32 c : 1; /* [3] */ + UINT32 ap1 : 2; /* [5 : 4] */ + UINT32 sbz : 3; /* [8 : 6] */ + UINT32 ap : 1; /* [9] */ + UINT32 s : 1; /* [10] */ + UINT32 ng : 1; /* [11] */ + UINT32 tex : 3; /* [14 : 12] */ + UINT32 xn : 1; /* [15] */ + UINT32 baseAddress : 16; /* [31 : 16] */ +}; + +struct MMUSecondLevelSmallPageTable { + UINT32 xn : 1; /* [0] */ + UINT32 id : 1; /* [1] */ + UINT32 b : 1; /* [2] */ + UINT32 c : 1; /* [3] */ + UINT32 ap1 : 2; /* [5 : 4] */ + UINT32 tex : 3; /* [8 : 6] */ + UINT32 ap : 1; /* [9] */ + UINT32 s : 1; /* [10] */ + UINT32 ng : 1; /* [11] */ + UINT32 baseAddress : 20; /* [31 : 12] */ +}; + +struct MMUFirstLevelSection { + UINT32 id : 2; /* [1 : 0] */ + UINT32 b : 1; /* [2] */ + UINT32 c : 1; /* [3] */ + UINT32 xn : 1; /* [4] */ + UINT32 domain : 4; /* [8 : 5] */ + UINT32 imp : 1; /* [9] */ + UINT32 ap1 : 2; /* [11 : 10] */ + UINT32 tex : 3; /* [14 : 12] */ + UINT32 ap : 1; /* [15] */ + UINT32 s : 1; /* [16] */ + UINT32 ng : 1; /* [17] */ + UINT32 revs : 1; /* [18] */ + UINT32 ns : 1; /* [19] */ + UINT32 baseAddress : 12; /* [31 : 20] */ +}; + +struct MMUFirstLevelReserved { + UINT32 id : 2; /* [1 : 0] */ + UINT32 sbz : 30; /* [31 : 2] */ +}; + +#define X_MMU_SET_AP_ALL(item, access) do { \ + (item).ap1 = (access) & 0x3U; \ + (item).ap = (access) >> 2; \ +} while (0) + +#define X_MMU_SET_BCX(item, buff, cache, exeNever) do { \ + (item).b = (buff); \ + (item).c = (cache); \ + (item).xn = (exeNever); \ +} while (0) + +#define X_MMU_CHG_DESC(aBase, vBase, size, baseAddress, tableBase) do { \ + UINT32 i, j, k; \ + k = (tableBase) + MMU_DESC_OFFSET(vBase); \ + for (j = (aBase), i = 0; i < (size); ++i, ++j, k += MMU_DESC_LEN) { \ + (baseAddress) = j; \ + *(UINTPTR *)k = desc.word; \ + } \ +} while (0) + +#define X_MMU_CHG_DESC_64K(aBase, vBase, size, baseAddress, tableBase) do { \ + UINT32 i, j, k, n; \ + k = (tableBase) + MMU_DESC_OFFSET(vBase); \ + for (j = (aBase), i = 0; i < (size); ++i, ++j) { \ + (baseAddress) = j; \ + for (n = 0; n < (MMU_64K / MMU_4K); ++n, k += MMU_DESC_LEN) { \ + *(UINTPTR *)k = desc.word; \ + } \ + } \ +} while (0) + +#define SECTION_CHANGE(item, cache, buff, access, exeNever) do { \ + union MMUFirstLevelDescriptor desc; \ + desc.word = (*(UINTPTR *)(item)); \ + desc.section.s = (MMU_SHAREABLE); \ + X_MMU_SET_BCX(desc.section, (buff), (cache), (exeNever)); \ + X_MMU_SET_AP_ALL(desc.section, (access)); \ + (*(UINTPTR *)(item)) = desc.word; \ +} while (0) + +#define X_MMU_SECTION(aBase, vBase, size, cache, buff, access, exeNever, sdomain) do { \ + union MMUFirstLevelDescriptor desc = { .word = 0 }; \ + desc.section.id = MMU_FIRST_LEVEL_SECTION_ID; \ + desc.section.s = (MMU_SHAREABLE); \ + desc.section.domain = (sdomain); \ + X_MMU_SET_BCX(desc.section, (buff), (cache), (exeNever)); \ + X_MMU_SET_AP_ALL(desc.section, (access)); \ + X_MMU_CHG_DESC(aBase, vBase, size, desc.section.baseAddress, ttbBase); \ +} while (0) + +#define X_MMU_ONE_LEVEL_PAGE(aBase, vBase, size, sdomain) do { \ + union MMUFirstLevelDescriptor desc = { .word = 0 }; \ + desc.pageTable.id = MMU_FIRST_LEVEL_PAGE_TABLE_ID; \ + desc.pageTable.domain = (sdomain); \ + X_MMU_CHG_DESC(aBase, vBase, size, desc.pageTable.baseAddress, ttbBase); \ +} while (0) + +#define X_MMU_TWO_LEVEL_PAGE(aBase, vBase, size, cache, buff, access, exeNever) do { \ + union MMUFirstLevelDescriptor desc = { .word = 0 }; \ + desc.smallPageTable.id = MMU_SECOND_LEVEL_SMALL_PAGE_TABLE_ID >> 1; \ + desc.smallPageTable.s = (MMU_SHAREABLE); \ + X_MMU_SET_BCX(desc.smallPageTable, (buff), (cache), (exeNever)); \ + X_MMU_SET_AP_ALL(desc.smallPageTable, (access)); \ + X_MMU_CHG_DESC(aBase, vBase, size, desc.smallPageTable.baseAddress, sttBase); \ +} while (0) + +#define X_MMU_TWO_LEVEL_PAGE64K(aBase, vBase, size, cache, buff, access, exeNever) do { \ + union MMUFirstLevelDescriptor desc = { .word = 0 }; \ + desc.bigPageTable.id = MMU_SECOND_LEVEL_BIG_PAGE_TABLE_ID; \ + desc.bigPageTable.s = (MMU_SHAREABLE); \ + X_MMU_SET_BCX(desc.bigPageTable, (buff), (cache), (exeNever)); \ + X_MMU_SET_AP_ALL(desc.bigPageTable, (access)); \ + X_MMU_CHG_DESC_64K(aBase, vBase, size, desc.bigPageTable.baseAddress, sttBase); \ +} while (0) + +union MMUFirstLevelDescriptor { + UINTPTR word; + struct MMUFirstLevelFault fault; + struct MMUFirstLevelPageTable pageTable; + struct MMUFirstLevelSection section; + struct MMUFirstLevelReserved reserved; + struct MMUSecondLevelSmallPageTable smallPageTable; + struct MMUSecondLevelBigPageTable bigPageTable; +}; + +STATIC INLINE VOID EnableAPCheck(VOID) +{ + UINT32 regDACR = ACCESS_TYPE_MANAGER(0) | + ACCESS_TYPE_CLIENT(1); + __asm volatile("mcr p15, 0, %0, c3, c0, 0" + : + : "r"(regDACR)); +} + +STATIC INLINE VOID DisableAPCheck(VOID) +{ + UINT32 regDACR = ACCESS_TYPE_MANAGER(0) | + ACCESS_TYPE_MANAGER(1); + __asm volatile("mcr p15, 0, %0, c3, c0, 0" + : + : "r"(regDACR)); +} + +STATIC INLINE VOID CleanTLB(VOID) +{ + __asm volatile("mov %0, #0\n" + "mcr p15, 0, %0, c8, c7, 0\n" + : + : "r"(0)); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _MMU_H */ diff --git a/arch/arm/cortex-a/src/jmp.S b/arch/arm/cortex-a/src/jmp.S new file mode 100644 index 000000000..e8908d393 --- /dev/null +++ b/arch/arm/cortex-a/src/jmp.S @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARMv7 JMP Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#include "asm.h" + +FUNCTION(longjmp) + ldmfd r0,{r4-r14} + cmp r1,#0 + moveq r1,#1 + mov r0,r1 + mov pc,lr + +FUNCTION(setjmp) + stmea r0,{r4-r14} + mov r0,#0 + mov pc,lr diff --git a/arch/arm/cortex-a/src/los_dispatch.S b/arch/arm/cortex-a/src/los_dispatch.S new file mode 100644 index 000000000..c1fcecbeb --- /dev/null +++ b/arch/arm/cortex-a/src/los_dispatch.S @@ -0,0 +1,205 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARMv7 Dispatch Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "asm.h" +#include "arch_config.h" + + .global OsStartToRun + .global OsTaskSchedule + .global OsIrqHandler + + .equ OS_TASK_STATUS_RUNNING, 0x0010U + + .fpu vfpv4 + +/* macros to align and unalign the stack on 8 byte boundary for ABI compliance */ +.macro STACK_ALIGN, reg + MOV \reg, sp + TST SP, #4 + SUBEQ SP, #4 + PUSH { \reg } +.endm + +.macro STACK_RESTORE, reg + POP { \reg } + MOV sp, \reg +.endm + +/* macros to save and restore fpu regs */ +.macro PUSH_FPU_REGS reg1 +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + VMRS \reg1, FPEXC + PUSH {\reg1} + VMRS \reg1, FPSCR + PUSH {\reg1} +#if defined(LOSCFG_ARCH_FPU_VFP_D32) + VPUSH {D16-D31} +#endif + VPUSH {D0-D15} +#endif +.endm + +.macro POP_FPU_REGS reg1 +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + VPOP {D0-D15} +#if defined(LOSCFG_ARCH_FPU_VFP_D32) + VPOP {D16-D31} +#endif + POP {\reg1} + VMSR FPSCR, \reg1 + POP {\reg1} + VMSR FPEXC, \reg1 +#endif +.endm + +/* R0: new task */ +OsStartToRun: + + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) + + LDRH R1, [R0, #4] + MOV R1, #OS_TASK_STATUS_RUNNING + STRH R1, [R0, #4] + + VPUSH {S0} /* fpu */ + VPOP {S0} + VPUSH {D0} + VPOP {D0} + + B OsTaskContextLoad + +/* + * R0: new task + * R1: run task + */ +OsTaskSchedule: + MRS R2, CPSR + PUSH {R2} + PUSH {LR} + + /* push r0-r12, lr */ + PUSH {R0-R12, LR} + + /* save fpu registers */ + PUSH_FPU_REGS R2 + + /* store sp on running task */ + STR SP, [R1] + +OsTaskContextLoad: + /* clear the flag of ldrex */ + CLREX + + /* switch to new task's sp */ + LDR SP, [R0] + + /* restore fpu registers */ + POP_FPU_REGS R2 + + /* restore r0-r12, lr */ + POP {R0-R12, LR} + + POP {R1} + POP {R2} + MSR CPSR, R2 + BX R1 + +OsIrqHandler: + SUB LR, LR, #4 + + /* save spsr and lr(svc's pc) onto the svc stack */ + SRSDB #0x13! + + /* disable irq, switch to svc mode */ + CPSID i, #0x13 + + /* push caller saved regs as trashed regs */ + PUSH {R0-R3, R12, LR} + + /* 8 bytes stack align */ + STACK_ALIGN R0 + + /* + * save fpu regs in case in case those been + * altered in interrupt handlers. + */ + PUSH_FPU_REGS R0 + + BLX HalIrqHandler + + /* process pending signals */ + BL OsTaskProcSignal + + /* check if needs to schedule */ + CMP R0, #0 + BLNE OsSchedPreempt + + /* restore fpu regs */ + POP_FPU_REGS R0 + + STACK_RESTORE R0 + +OsIrqContextRestore: + POP {R0-R3, R12, LR} + RFEIA SP! + + +FUNCTION(ArchSpinLock) + mov r1, #1 +1: + ldrex r2, [r0] + cmp r2, #0 + wfene + strexeq r2, r1, [r0] + cmpeq r2, #0 + bne 1b + dmb + bx lr + +FUNCTION(ArchSpinTrylock) + mov r1, #1 + mov r2, r0 + ldrex r0, [r2] + cmp r0, #0 + strexeq r0, r1, [r2] + dmb + bx lr + +FUNCTION(ArchSpinUnlock) + mov r1, #0 + dmb + str r1, [r0] + dsb + sev + bx lr diff --git a/arch/arm/cortex-a/src/los_exc.c b/arch/arm/cortex-a/src/los_exc.c new file mode 100644 index 000000000..b85668543 --- /dev/null +++ b/arch/arm/cortex-a/src/los_exc.c @@ -0,0 +1,552 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARMv7 Exc Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_exc.h" +#include "los_memory_pri.h" +#include "los_printf_pri.h" +#include "los_task_pri.h" +#include "los_hw_pri.h" +#ifdef LOSCFG_SHELL_EXCINFO +#include "los_excinfo_pri.h" +#endif +#ifdef LOSCFG_EXC_INTERACTION +#include "los_exc_interaction_pri.h" +#endif +#include "los_sys_stack_pri.h" +#include "los_stackinfo_pri.h" +#ifdef LOSCFG_COREDUMP +#include "los_coredump.h" +#endif +#ifdef LOSCFG_GDB +#include "gdb_int.h" +#endif +#include "los_mp.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr); +UINT32 g_curNestCount = 0; +STATIC EXC_PROC_FUNC g_excHook = (EXC_PROC_FUNC)OsExcHook; + +#define OS_MAX_BACKTRACE 15U +#define DUMPSIZE 128U +#define DUMPREGS 12U +#define INSTR_SET_MASK 0x01000020U +#define THUMB_INSTR_LEN 2U +#define ARM_INSTR_LEN 4U +#define POINTER_SIZE 4U + +#define GET_FS(fsr) (((fsr) & 0xFU) | (((fsr) & (1U << 10)) >> 6)) +#define GET_WNR(dfsr) ((dfsr) & (1U << 11)) + +#define IS_VALID_ADDR(ptr) (((ptr) >= SYS_MEM_BASE) && \ + ((ptr) <= g_sys_mem_addr_end) && \ + IS_ALIGNED((ptr), sizeof(CHAR *))) + +STATIC const StackInfo g_excStack[] = { + { &__undef_stack, OS_EXC_UNDEF_STACK_SIZE, "udf_stack" }, + { &__abt_stack, OS_EXC_ABT_STACK_SIZE, "abt_stack" }, + { &__fiq_stack, OS_EXC_FIQ_STACK_SIZE, "fiq_stack" }, + { &__svc_stack, OS_EXC_SVC_STACK_SIZE, "svc_stack" }, + { &__irq_stack, OS_EXC_IRQ_STACK_SIZE, "irq_stack" }, + { &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } +}; + +STATIC INT32 OsDecodeFS(UINT32 bitsFS) +{ + switch (bitsFS) { + case 0x05: /* 0b00101 */ + case 0x07: /* 0b00111 */ + PrintExcInfo("Translation fault, %s\n", (bitsFS & 0x2) ? "page" : "section"); + break; + case 0x09: /* 0b01001 */ + case 0x0b: /* 0b01011 */ + PrintExcInfo("Domain fault, %s\n", (bitsFS & 0x2) ? "page" : "section"); + break; + case 0x0d: /* 0b01101 */ + case 0x0f: /* 0b01111 */ + PrintExcInfo("Permission fault, %s\n", (bitsFS & 0x2) ? "page" : "section"); + break; + default: + PrintExcInfo("Unknown fault! FS:0x%x. " + "Check IFSR and DFSR in ARM Architecture Reference Manual.\n", + bitsFS); + break; + } + + return LOS_OK; +} + +STATIC INT32 OsDecodeInstructionFSR(UINT32 regIFSR) +{ + INT32 ret; + UINT32 bitsFS = GET_FS(regIFSR); /* FS bits[4]+[3:0] */ + + ret = OsDecodeFS(bitsFS); + return ret; +} + +STATIC INT32 OsDecodeDataFSR(UINT32 regDFSR) +{ + INT32 ret = 0; + UINT32 bitWnR = GET_WNR(regDFSR); /* WnR bit[11] */ + UINT32 bitsFS = GET_FS(regDFSR); /* FS bits[4]+[3:0] */ + + if (bitWnR) { + PrintExcInfo("Abort caused by a write instruction. "); + } else { + PrintExcInfo("Abort caused by a read instruction. "); + } + + if (bitsFS == 0x01) { /* 0b00001 */ + PrintExcInfo("Alignment fault.\n"); + return ret; + } + ret = OsDecodeFS(bitsFS); + return ret; +} + +STATIC VOID OsExcType(UINT32 excType, ExcContext *excBufAddr) +{ + /* undefinited exception handling or software interrupt */ + if ((excType == OS_EXCEPT_UNDEF_INSTR) || (excType == OS_EXCEPT_SWI)) { + if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0) { /* work status: ARM */ + excBufAddr->PC = excBufAddr->PC - ARM_INSTR_LEN; + } else if ((excBufAddr->regCPSR & INSTR_SET_MASK) == 0x20) { /* work status: Thumb */ + excBufAddr->PC = excBufAddr->PC - THUMB_INSTR_LEN; + } + } + + if (excType == OS_EXCEPT_PREFETCH_ABORT) { + PrintExcInfo("prefetch_abort fault fsr:0x%x, far:0x%0+8x\n", OsGetIFSR(), OsGetIFAR()); + (VOID)OsDecodeInstructionFSR(OsGetIFSR()); + } else if (excType == OS_EXCEPT_DATA_ABORT) { + PrintExcInfo("data_abort fsr:0x%x, far:0x%0+8x\n", OsGetDFSR(), OsGetDFAR()); + (VOID)OsDecodeDataFSR(OsGetDFSR()); + } +} + +STATIC const CHAR *g_excTypeString[] = { + "reset", + "undefined instruction", + "software interrupt", + "prefetch abort", + "data abort", + "fiq", + "address abort", + "irq" +}; + +STATIC VOID OsExcSysInfo(UINT32 excType, const ExcContext *excBufAddr) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + + PrintExcInfo("excType:%s\n" + "taskName = %s\n" + "taskID = %u\n" + "task stackSize = %u\n" + "system mem addr = 0x%x\n" + "excBuffAddr pc = 0x%x\n" + "excBuffAddr lr = 0x%x\n" + "excBuffAddr sp = 0x%x\n" + "excBuffAddr fp = 0x%x\n", + g_excTypeString[excType], + runTask->taskName, + runTask->taskID, + runTask->stackSize, + m_aucSysMem0, + excBufAddr->PC, + excBufAddr->LR, + excBufAddr->SP, + excBufAddr->R11); +} + +STATIC VOID OsExcRegsInfo(const ExcContext *excBufAddr) +{ + PrintExcInfo("R0 = 0x%x\n" + "R1 = 0x%x\n" + "R2 = 0x%x\n" + "R3 = 0x%x\n" + "R4 = 0x%x\n" + "R5 = 0x%x\n" + "R6 = 0x%x\n" + "R7 = 0x%x\n" + "R8 = 0x%x\n" + "R9 = 0x%x\n" + "R10 = 0x%x\n" + "R11 = 0x%x\n" + "R12 = 0x%x\n" + "CPSR = 0x%x\n", + excBufAddr->R0, excBufAddr->R1, excBufAddr->R2, + excBufAddr->R3, excBufAddr->R4, excBufAddr->R5, + excBufAddr->R6, excBufAddr->R7, excBufAddr->R8, + excBufAddr->R9, excBufAddr->R10, excBufAddr->R11, + excBufAddr->R12, excBufAddr->regCPSR); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_ExcRegHook(EXC_PROC_FUNC excHook) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + g_excHook = excHook; + LOS_IntRestore(intSave); + + return LOS_OK; +} + +EXC_PROC_FUNC OsExcRegHookGet(VOID) +{ + return g_excHook; +} + +VOID OsDumpContextMem(const ExcContext *excBufAddr) +{ + UINT32 count = 0; + const UINT32 *excReg = NULL; + + for (excReg = &(excBufAddr->R0); count <= DUMPREGS; excReg++, count++) { + if (IS_VALID_ADDR(*excReg)) { + PrintExcInfo("\ndump mem around R%u:%p", count, (*excReg)); + OsDumpMemByte(DUMPSIZE, ((*excReg) - (DUMPSIZE >> 1))); + } + } + + if (IS_VALID_ADDR(excBufAddr->SP)) { + PrintExcInfo("\ndump mem around SP:%p", excBufAddr->SP); + OsDumpMemByte(DUMPSIZE, (excBufAddr->SP - (DUMPSIZE >> 1))); + } +} + +/* this function is used to validate fp or validate the checking range start and end. */ +STATIC INLINE BOOL IsValidFP(UINTPTR regFP, UINTPTR start, UINTPTR end) +{ + return (regFP > start) && (regFP < end); +} + +STATIC INLINE BOOL FindSuitableStack(UINTPTR regFP, UINTPTR *start, UINTPTR *end) +{ + UINT32 index, stackStart, stackEnd; + BOOL found = FALSE; + LosTaskCB *taskCB = NULL; + const StackInfo *stack = NULL; + + /* Search in the task stacks */ + for (index = 0; index < g_taskMaxNum; index++) { + taskCB = &g_taskCBArray[index]; + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + + stackStart = taskCB->topOfStack; + stackEnd = taskCB->topOfStack + taskCB->stackSize; + if (IsValidFP(regFP, stackStart, stackEnd)) { + found = TRUE; + goto FOUND; + } + } + + /* Search in the exc stacks */ + for (index = 0; index < sizeof(g_excStack) / sizeof(StackInfo); index++) { + stack = &g_excStack[index]; + stackStart = (UINTPTR)stack->stackTop; + stackEnd = stackStart + LOSCFG_KERNEL_CORE_NUM * stack->stackSize; + if (IsValidFP(regFP, stackStart, stackEnd)) { + found = TRUE; + goto FOUND; + } + } + +FOUND: + if (found == TRUE) { + *start = stackStart; + *end = stackEnd; + } + + return found; +} + +VOID BackTraceSub(UINTPTR regFP) +{ + UINTPTR tmpFP; + UINTPTR backLR; + UINTPTR backFP = regFP; + UINTPTR stackStart, stackEnd; + UINT32 count = 0; + + if (FindSuitableStack(regFP, &stackStart, &stackEnd) == FALSE) { + return; + } + + /* + * Check whether it is the leaf function. + * Generally, the frame pointer points to the address of link register, while in the leaf function, + * there's no function call, and compiler will not store the link register, but the frame pointer + * will still be stored and updated. In that case we needs to find the right position of frame pointer. + */ + tmpFP = *((UINTPTR *)(regFP)); + if (IsValidFP(tmpFP, stackStart, stackEnd)) { + backFP = tmpFP; + PrintExcInfo("traceback fp fixed, trace using fp = 0x%x\n", backFP); + } + + while (IsValidFP(backFP, stackStart, stackEnd)) { + tmpFP = backFP; + backLR = *((UINTPTR *)(tmpFP)); + backFP = *((UINTPTR *)(tmpFP - POINTER_SIZE)); + PrintExcInfo("traceback %u -- lr = 0x%x fp = 0x%x\n", count, backLR, backFP); + + count++; + if ((count == OS_MAX_BACKTRACE) || (backFP == tmpFP)) { + break; + } + } +} + +VOID BackTrace(UINT32 regFP) +{ + PrintExcInfo("*******backtrace begin*******\n"); + + BackTraceSub(regFP); +} + +VOID OsExcInit(VOID) +{ + OsExcStackInfoReg(g_excStack, sizeof(g_excStack) / sizeof(g_excStack[0])); +} + +VOID OsExcHook(UINT32 excType, ExcContext *excBufAddr) +{ + OsExcType(excType, excBufAddr); + OsExcSysInfo(excType, excBufAddr); + OsExcRegsInfo(excBufAddr); + + BackTrace(excBufAddr->R11); + (VOID)OsShellCmdTskInfoGet(OS_ALL_TASK_MASK); + + OsExcStackInfo(); + + OsDumpContextMem(excBufAddr); + + (VOID)OsShellCmdMemCheck(0, NULL); + +#ifdef LOSCFG_COREDUMP + LOS_CoreDumpV2(excType, excBufAddr); +#endif +} + +VOID OsCallStackInfo(VOID) +{ + UINT32 count = 0; + LosTaskCB *runTask = OsCurrTaskGet(); + UINTPTR stackBottom = runTask->topOfStack + runTask->stackSize; + UINT32 *stackPointer = (UINT32 *)stackBottom; + + PrintExcInfo("runTask->stackPointer = 0x%x\n" + "runTask->topOfStack = 0x%x\n" + "text_start:0x%x,text_end:0x%x\n", + stackPointer, runTask->topOfStack, &__text_start, &__text_end); + + while ((stackPointer > (UINT32 *)runTask->topOfStack) && (count < OS_MAX_BACKTRACE)) { + if ((*stackPointer > (UINTPTR)(&__text_start)) && + (*stackPointer < (UINTPTR)(&__text_end)) && + IS_ALIGNED((*stackPointer), POINTER_SIZE)) { + if ((*(stackPointer - 1) > (UINT32)runTask->topOfStack) && + (*(stackPointer - 1) < stackBottom) && + IS_ALIGNED((*(stackPointer - 1)), POINTER_SIZE)) { + count++; + PrintExcInfo("traceback %u -- lr = 0x%x\n", count, *stackPointer); + } + } + stackPointer--; + } + PRINTK("\n"); +} + +VOID OsTaskBackTrace(UINT32 taskID) +{ + LosTaskCB *taskCB = NULL; + + if (taskID >= g_taskMaxNum) { + PRINT_ERR("\r\nTask PID is invalid!\n"); + return; + } + taskCB = OS_TCB_FROM_TID(taskID); + if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) || + (taskCB->taskEntry == NULL) || + (taskCB->taskName == NULL)) { + PRINT_ERR("\r\nThe task is not created!\n"); + return; + } + PRINTK("TaskName = %s\n", taskCB->taskName); + PRINTK("TaskID = 0x%x\n", taskCB->taskID); + BackTrace(((TaskContext *)(taskCB->stackPointer))->R[11]); /* R11 : FP */ +} + +VOID OsBackTrace(VOID) +{ + UINT32 regFP = Get_Fp(); + LosTaskCB *runTask = OsCurrTaskGet(); + PRINTK("OsBackTrace fp = 0x%x\n", regFP); + PRINTK("runTask->taskName = %s\n", runTask->taskName); + PRINTK("runTask->taskID = %u\n", runTask->taskID); + BackTrace(regFP); +} + +#ifdef LOSCFG_GDB +VOID OsUndefIncExcHandleEntry(ExcContext *excBufAddr) +{ + excBufAddr->PC -= 4; /* lr in undef is pc + 4 */ + + if (gdb_undef_hook(excBufAddr, OS_EXCEPT_UNDEF_INSTR)) { + return; + } + + if (g_excHook != NULL) { + g_excHook(OS_EXCEPT_UNDEF_INSTR, excBufAddr); + } + while (1) { + ; + } +} + +#if __LINUX_ARM_ARCH__ >= 7 +VOID OsPrefetchAbortExcHandleEntry(ExcContext *excBufAddr) +{ + excBufAddr->PC -= 4; /* lr in prefetch abort is pc + 4 */ + + if (gdbhw_hook(excBufAddr, OS_EXCEPT_PREFETCH_ABORT)) { + return; + } + + if (g_excHook != NULL) { + g_excHook(OS_EXCEPT_PREFETCH_ABORT, excBufAddr); + } + while (1) { + ; + } +} + +VOID OsDataAbortExcHandleEntry(ExcContext *excBufAddr) +{ + excBufAddr->PC -= 8; /* lr in data abort is pc + 8 */ + + if (gdbhw_hook(excBufAddr, OS_EXCEPT_DATA_ABORT)) { + return; + } + + if (g_excHook != NULL) { + g_excHook(OS_EXCEPT_DATA_ABORT, excBufAddr); + } + while (1) { + ; + } +} +#endif /* __LINUX_ARM_ARCH__ */ +#endif /* LOSCFG_GDB */ + +/* + * Description : EXC handler entry + * Input : excType --- exc type + * excBufAddr --- address of EXC buf + */ +LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, ExcContext *excBufAddr) +{ +#ifdef LOSCFG_SHELL_EXCINFO + log_read_write_fn func = GetExcInfoRW(); +#endif + + g_curNestCount++; + + if (g_excHook != NULL) { + if (g_curNestCount == 1) { +#ifdef LOSCFG_SHELL_EXCINFO + if (func != NULL) { + SetExcInfoIndex(0); + g_intCount[ArchCurrCpuid()] = 0; + OsRecordExcInfoTime(); + g_intCount[ArchCurrCpuid()] = 1; + } +#endif + g_excHook(excType, excBufAddr); + } else { + OsCallStackInfo(); + } + +#ifdef LOSCFG_SHELL_EXCINFO + if (func != NULL) { + PrintExcInfo("Be sure flash space bigger than GetExcInfoIndex():0x%x\n", GetExcInfoIndex()); + g_intCount[ArchCurrCpuid()] = 0; + func(GetRecordAddr(), GetRecordSpace(), 0, GetExcInfoBuf()); + g_intCount[ArchCurrCpuid()] = 1; + } +#endif + } +#ifdef LOSCFG_EXC_INTERACTION + OsExcInteractionTaskKeep(); +#endif + + while (1) { + ; + } +} + +__attribute__((noinline)) VOID LOS_Panic(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + UartVprintf(fmt, ap); + va_end(ap); + __asm__ __volatile__("swi 0"); +} + +/* stack protector */ +UINT32 __stack_chk_guard = 0xd00a0dff; + +VOID __stack_chk_fail(VOID) +{ + /* __builtin_return_address is a builtin function, building in gcc */ + LOS_Panic("stack-protector: Kernel stack is corrupted in: %p\n", + __builtin_return_address(0)); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-a/src/los_hw.c b/arch/arm/cortex-a/src/los_hw.c new file mode 100644 index 000000000..d59a0320e --- /dev/null +++ b/arch/arm/cortex-a/src/los_hw.c @@ -0,0 +1,168 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Hw Task Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_hw_pri.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* support cpu vendors */ +CpuVendor g_cpuTable[] = { + /* armv7-a */ + { 0xc07, "Cortex-A7" }, + { 0xc09, "Cortex-A9" }, + { 0, NULL } +}; + +/* logical cpu mapping */ +UINT64 g_cpuMap[LOSCFG_KERNEL_CORE_NUM] = { + [0 ... LOSCFG_KERNEL_CORE_NUM - 1] = (UINT64)(-1) +}; + +/* bit[30] is enable FPU */ +#define FP_EN (1U << 30) +LITE_OS_SEC_TEXT_INIT VOID OsTaskExit(VOID) +{ + __asm__ __volatile__("swi 0"); +} + +#ifdef LOSCFG_GDB +STATIC VOID OsTaskEntrySetupLoopFrame(UINT32) __attribute__((noinline, naked)); +VOID OsTaskEntrySetupLoopFrame(UINT32 arg0) +{ + asm volatile("\tsub fp, sp, #0x4\n" + "\tpush {fp, lr}\n" + "\tadd fp, sp, #0x4\n" + "\tpush {fp, lr}\n" + + "\tadd fp, sp, #0x4\n" + "\tbl OsTaskEntry\n" + + "\tpop {fp, lr}\n" + "\tpop {fp, pc}\n"); +} +#endif + +LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) +{ + UINT32 index = 1; + TaskContext *taskContext = NULL; + + OsStackInit(topStack, stackSize); + taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + + /* initialize the task context */ +#ifdef LOSCFG_GDB + taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame; +#else + taskContext->PC = (UINTPTR)OsTaskEntry; +#endif + taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */ + taskContext->R[0] = taskID; /* R0 */ + taskContext->R[index++] = 0x01010101; /* R1, 0x01010101 : reg initialed magic word */ + for (; index < GEN_REGS_NUM; index++) { + taskContext->R[index] = taskContext->R[index - 1] + taskContext->R[1]; /* R2 - R12 */ + } + +#ifdef LOSCFG_INTERWORK_THUMB + taskContext->regPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */ +#else + taskContext->regPSR = PSR_MODE_SVC_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */ +#endif + +#if !defined(LOSCFG_ARCH_FPU_DISABLE) + /* 0xAAA0000000000000LL : float reg initialed magic word */ + for (index = 0; index < FP_REGS_NUM; index++) { + taskContext->D[index] = 0xAAA0000000000000LL + index; /* D0 - D31 */ + } + taskContext->regFPSCR = 0; + taskContext->regFPEXC = FP_EN; +#endif + + return (VOID *)taskContext; +} + +VOID sev(VOID) +{ + __asm__ __volatile__ ("sev" : : : "memory"); +} + +VOID wfe(VOID) +{ + __asm__ __volatile__ ("wfe" : : : "memory"); +} + +VOID wfi(VOID) +{ + __asm__ __volatile__ ("wfi" : : : "memory"); +} + +VOID dmb(VOID) +{ + __asm__ __volatile__ ("dmb" : : : "memory"); +} + +VOID dsb(VOID) +{ + __asm__ __volatile__("dsb" : : : "memory"); +} + +VOID isb(VOID) +{ + __asm__ __volatile__("isb" : : : "memory"); +} + +VOID flush_icache(VOID) +{ + /* + * Use ICIALLUIS instead of ICIALLU. ICIALLUIS operates on all processors in the Inner + * shareable domain of the processor that performs the operation. + */ + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c1, 0" : : "r" (0) : "memory"); +} + +VOID flush_dcache(UINT32 start, UINT32 end) +{ + arm_clean_cache_range(start, end); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-a/src/los_hw_exc.S b/arch/arm/cortex-a/src/los_hw_exc.S new file mode 100644 index 000000000..1b2f35481 --- /dev/null +++ b/arch/arm/cortex-a/src/los_hw_exc.S @@ -0,0 +1,270 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARMv7 Hw Exc Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#include "arch_config.h" + + .extern g_losTask + .extern g_intCount + .extern g_curNestCount + .extern OsExcHandleEntry + .extern __svc_stack_top + .extern __exc_stack_top + .extern __stack_chk_guard + .extern OsRandomStackGuard +#ifdef LOSCFG_GDB + .extern OsUndefIncExcHandleEntry +#if __LINUX_ARM_ARCH__ >= 7 + .extern OsPrefetchAbortExcHandleEntry + .extern OsDataAbortExcHandleEntry +#endif +#endif + + .global _osExceptFiqHdl + .global _osExceptAddrAbortHdl + .global _osExceptDataAbortHdl + .global _osExceptPrefetchAbortHdl + .global _osExceptSwiHdl + .global _osExceptUndefInstrHdl + .global __stack_chk_guard_setup + + .equ MPIDR_CPUID_MASK, 0xffU + + .fpu vfpv4 + +/* param0 is stack bottom, param1 is stack size, R4 hold cpu id */ +.macro EXC_SP_SET param0, param1 + LDR R6, =\param0 + MOV R7, \param1 + MUL R7, R7, R4 + SUB R6, R6, R7 + MOV SP, R6 +.endm + +#ifdef LOSCFG_GDB +.macro GDB_HANDLE fun + SUB SP, SP, #12 + + STMFD SP!, {R0-R12} + MRS R1, SPSR + STMFD SP!, {R1} @save spsr + + ADD R0, SP, #14 * 4 + MOV R3, LR @save pc + + MRS R1, CPSR + MRS R2, SPSR + MOV R4, SP + + ORR R2, R2, #(CPSR_INT_DISABLE) + MSR CPSR_c, R2 + + STR SP, [R0] @SP + STR LR, [R0, #4] @LR + STR R3, [R0, #8] @PC + + ORR R1, R1, #(CPSR_INT_DISABLE) + BIC R1, R1, #OS_PSR_THUMB + MSR CPSR_c, R1 + MOV R0, R4 + + BL \fun + + ADD SP, SP, #4 + LDMFD SP!, {R0-R12} + + MOV R0, SP + ADD SP, SP, #8 + + LDR R1, [R0, #8] @get pc + STMFD SP!, {R1} + + AND R1, R1, #0x03 + CMP R1, #0 + BEQ 1f + LDR R1, [R0, #-14 * 4] + ORR R1, R1, #OS_PSR_THUMB + B 2f +1: + LDR R1, [R0, #-14 * 4] + +2: + MSR SPSR, R1 + + LDR R1, [R0, #-12 * 4] @get R1 + STMFD SP!, {R1} + LDR R1, [R0,#-13 * 4] @get R0 + STMFD SP!, {R1} + + LDMFD SP!, {R0-R1, PC}^ +.endm +#endif + +@ Description: Stack-Protector Init +__stack_chk_guard_setup: + PUSH {FP, LR} + BL OsRandomStackGuard + LDR R1, =__stack_chk_guard + MOV R3, R0 + ORR R2, R3, #0X80000000 + STR R2, [R1] + POP {FP, PC} + +@ Description: Undefined instruction exception handler +_osExceptUndefInstrHdl: +#ifdef LOSCFG_GDB + GDB_HANDLE OsUndefIncExcHandleEntry +#else + @ LR offset to return from this exception: 0. + STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. + + MOV R0, #OS_EXCEPT_UNDEF_INSTR @ Set exception ID to OS_EXCEPT_UNDEF_INSTR. + + B _osExceptDispatch @ Branch to global exception handler. + +#endif + +@ Description: Software interrupt exception handler +_osExceptSwiHdl: + STMFD SP!, {LR} @ Store PC + STMFD SP!, {LR} + STMFD SP!, {SP} + STMFD SP!, {R0-R12} @ Store SP,LR,R0-R12 + + MRS R1, SPSR @ Save exception`s CPSR. + STMFD SP!, {R1} @ Push task`s CPSR (i.e. exception SPSR). + + MOV R0, #OS_EXCEPT_SWI @ Set exception ID to OS_EXCEPT_SWI. + MOV R5, SP + + B _osExceptionSwi @ Branch to global exception handler. + +@ Description: Prefectch abort exception handler +_osExceptPrefetchAbortHdl: +#ifdef LOSCFG_GDB +#if __LINUX_ARM_ARCH__ >= 7 + GDB_HANDLE OsPrefetchAbortExcHandleEntry +#endif +#else + SUB LR, LR, #4 @ LR offset to return from this exception: -4. + STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. + + MOV R0, #OS_EXCEPT_PREFETCH_ABORT @ Set exception ID to OS_EXCEPT_PREFETCH_ABORT. + + B _osExceptDispatch @ Branch to global exception handler. +#endif + +@ Description: Data abort exception handler +_osExceptDataAbortHdl: +#ifdef LOSCFG_GDB +#if __LINUX_ARM_ARCH__ >= 7 + GDB_HANDLE OsDataAbortExcHandleEntry +#endif +#else + SUB LR, LR, #8 @ LR offset to return from this exception: -8. + STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. + + MOV R0, #OS_EXCEPT_DATA_ABORT @ Set exception ID to OS_EXCEPT_DATA_ABORT. + + B _osExceptDispatch @ Branch to global exception handler. +#endif + +@ Description: Address abort exception handler +_osExceptAddrAbortHdl: + SUB LR, LR, #8 @ LR offset to return from this exception: -8. + STMFD SP, {R0-R7} @ Push working registers, but don`t change SP. + + MOV R0, #OS_EXCEPT_ADDR_ABORT @ Set exception ID to OS_EXCEPT_ADDR_ABORT. + + B _osExceptDispatch @ Branch to global exception handler. + +@ Description: Fast interrupt request exception handler +_osExceptFiqHdl: + SUB LR, LR, #4 @ LR offset to return from this exception: -4. + STMFD SP, {R0-R7} @ Push working registers. + + MOV R0, #OS_EXCEPT_FIQ @ Set exception ID to OS_EXCEPT_FIQ. + + B _osExceptDispatch @ Branch to global exception handler. + +@ Description: Exception handler +@ Parameter : R0 Exception Type +@ Regs Hold : R3 Exception`s CPSR +_osExceptDispatch: + MRS R1, SPSR @ Save CPSR before exception. + MOV R2, LR @ Save PC before exception. + SUB R3, SP, #(8 * 4) @ Save the start address of working registers. + + MSR CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE) @ Switch to SVC mode, and disable all interrupts + MOV R5, SP + MRC P15, 0, R4, C0, C0, 5 + AND R4, R4, #MPIDR_CPUID_MASK @ Get Current cpu id + EXC_SP_SET __exc_stack_top, #OS_EXC_STACK_SIZE + + STMFD SP!, {R2} @ Push Exception PC + STMFD SP!, {LR} + STMFD SP!, {R5} @ Push original SP, + STMFD SP!, {R8-R12} @ Push original R12-R8, + LDMFD R3!, {R4-R11} @ Move original R7-R0 from exception stack to original stack. + STMFD SP!, {R4-R11} + STMFD SP!, {R1} @ Push task`s CPSR (i.e. exception SPSR). + +_osExceptionSwi: + MOV R1, SP + + LDR R2, =g_curNestCount @ if(g_curNestCount > 0) dump to _osExceptionGetSP + LDR R4, [R2] + + CMP R4, #0 + BNE _osExceptionGetSP + + MRC P15, 0, R4, C0, C0, 5 + AND R4, R4, #MPIDR_CPUID_MASK @ Get Current cpu id + LSL R2, R4, #2 + LDR R3, =g_intCount @ Judge the exception is occur in task stack or system stack + ADD R3, R3, R2 + LDR R2, [R3] + + CMP R2, #0 @ if (g_intCount[ArchCurrCpuid()] > 0) + BNE _osExceptionGetSP @ can not switch svc stack + + EXC_SP_SET __svc_stack_top, #OS_EXC_SVC_STACK_SIZE @ Switch to unified exception stack. + ADD R2, R2, #1 + STR R2, [R3] + +_osExceptionGetSP: + LDR R2, =OsExcHandleEntry @ OsExcHandleEntry(UINT32 excType, ExcContext * excBufAddr) + + MOV LR, PC + BX R2 + + .end diff --git a/arch/arm/cortex-a/src/los_hw_runstop.S b/arch/arm/cortex-a/src/los_hw_runstop.S new file mode 100644 index 000000000..e36960453 --- /dev/null +++ b/arch/arm/cortex-a/src/los_hw_runstop.S @@ -0,0 +1,135 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Hw Runstop handle + * 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. + * -------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "arch_config.h" + + .equ MPIDR_CPUID_MASK, 0xffU + + .extern g_saveAR + .extern g_saveSRContext + + .global OsSRSaveRegister + .global OsSRRestoreRegister + + .fpu vfpv4 + @.fpu neon + .arch armv7a + + .text + +OsSRSaveRegister: + PUSH {R2} + LDR R2, =g_saveAR + STR R0, [R2] + STR R1, [R2, #4] + POP {R2} + + MRC P15, 0, R0, c0, c0, 5 + AND R0, R0, #MPIDR_CPUID_MASK + MOV R1, #72 @This number is the total number of bytes in the task context register(R0~R15, SPSR, CPSR). + MUL R1, R1, R0 + + LDR R0, =g_saveSRContext + ADD R0, R0, R1 + ADD R0, R0, #72 + + MOV R1, SP + STMFD R0!, {R1} + + MRS R1, SPSR + 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} + + MRS R0, CPSR + STMFD R12!, {R0} + + BX LR + +OsSRRestoreRegister: + MRC P15, 0, R0, c0, c0, 5 + AND R0, R0, #MPIDR_CPUID_MASK + MOV R1, #72 @This number is the total number of bytes in the task context register(R0~R15, SPSR, CPSR). + MUL R1, R1, R0 + + LDR R12, =g_saveSRContext + ADD R12, R12, R1 + + LDMFD R12!, {R0} + MSR CPSR_cxsf, R0 + + LDMFD R12!, {R4-R11} + LDMFD R12!, {R0-R3} + + PUSH {R2} + LDR R2, =g_saveAR + STR R0, [R2] + STR R1, [R2, #4] + POP {R2} + + MOV R0, R12 + LDMFD R0!, {R12} + LDMFD R0!, {R1} @LR + LDMFD R0!, {R1} @PC + + MOV LR, R1 + + LDMFD R0!, {R1} + MSR SPSR_cxsf, R1 + + LDMFD R0!, {R1} + MOV SP, R1 + + LDR R0, =g_saveAR + LDR R0, [R0] + LDR R1, =g_saveAR + LDR R1, [R1, #4] + + BX LR + + .end diff --git a/kernel/base/include/los_timeslice.ph b/arch/arm/cortex-a/src/los_hw_tick.c similarity index 56% rename from kernel/base/include/los_timeslice.ph rename to arch/arm/cortex-a/src/los_hw_tick.c index d4ae9082a..1d521d613 100644 --- a/kernel/base/include/los_timeslice.ph +++ b/arch/arm/cortex-a/src/los_hw_tick.c @@ -1,102 +1,96 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@defgroup los_timeslice Timeslice - * @ingroup kernel - */ - -#ifndef _LOS_TIMESLICE_PH -#define _LOS_TIMESLICE_PH - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -/** - *@ingroup los_timeslice - *@brief Initialize time slices. - * - *@par Description: - *
      - *
    • This API is used to initialize time slices that defines the cycle of time slices according to LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT.
    • - *
    - *@attention - *
      - *
    • None.
    • - *
    - * - *@param None. - * - *@retval None. - *@par Dependency: - *
    • los_timeslice.ph: the header file that contains the API declaration.
    - *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern VOID osTimesliceInit(VOID); - -/** - *@ingroup los_timeslice - *@brief Check time slices. - * - *@par Description: - *
      - *
    • This API is used to check time slices. If the number of Ticks equals to the time for task switch, tasks are switched. Otherwise, the Tick counting continues.
    • - *
    - *@attention - *
      - *
    • None.
    • - *
    - * - *@param None. - * - *@retval None. - *@par Dependency: - *
    • los_timeslice.ph: the header file that contains the API declaration.
    - *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern VOID osTimesliceCheck(VOID); - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_TIMESLICE_PH */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Aarch32 Hw Tick Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_tick_pri.h" +#include "los_sys_pri.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond) +{ + if ((systemClock == 0) || + (tickPerSecond == 0) || + (tickPerSecond > systemClock)) { + return LOS_ERRNO_TICK_CFG_INVALID; + } + HalClockInit(); + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT VOID OsTickStart(VOID) +{ + HalClockStart(); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt) +{ + UINT64 cycle = HalClockGetCycles(); + + if ((highCnt == NULL) || (lowCnt == NULL)) { + return; + } + + *highCnt = cycle >> 32; /* 32:get high 32 bits */ + *lowCnt = cycle & 0xFFFFFFFFU; +} + +LITE_OS_SEC_TEXT_MINOR UINT64 LOS_CurrNanosec(VOID) +{ + DOUBLE nanos; + + nanos = (DOUBLE)HalClockGetCycles() * OS_SYS_NS_PER_SECOND / g_sysClock; + return (UINT64)nanos; +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_Udelay(UINT32 usecs) +{ + HalDelayUs(usecs); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_Mdelay(UINT32 msecs) +{ + HalDelayUs(msecs * 1000); /* 1000 : 1ms = 1000us */ +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-a/src/mmu_config.c b/arch/arm/cortex-a/src/mmu_config.c new file mode 100644 index 000000000..db2e64c1f --- /dev/null +++ b/arch/arm/cortex-a/src/mmu_config.c @@ -0,0 +1,427 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: MMU Config Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#include "los_config.h" +#include "hisoc/mmu_config.h" +#include "los_hwi.h" +#include "asm/dma.h" +#ifdef LOSCFG_KERNEL_RUNSTOP +#include "los_runstop_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* This is opration for page table */ +MMU_SET_PAGE_TABLE_PLACE + +SENCOND_PAGE g_mmuOsPage = {0}; +SENCOND_PAGE g_mmuAppPage = {0}; + +#ifdef LOSCFG_NULL_ADDRESS_PROTECT +__attribute__((aligned(MMU_1K))) UINT32 g_excSecondPageTable[MMU_1K]; +SENCOND_PAGE g_excPage = {0}; +#define EXC_VECTOR_ADDR 0xFFFF0000 +/* EXC_VECTOR_ALIGN equal the value that EXC_VECTOR_ADDR aligned by 1M */ +#define EXC_VECTOR_ALIGN 0xFFF00000 +#endif + +#define ITEM_PRINT_LEN 20 +#define BYTES_PER_ITEM 4 +#define ITEM_TYPE_MASK 0x3 + +STATIC VOID OsSetMemPage(MMU_PARAM *para) +{ + UINT32 pageBase; + UINT32 pageStartIndex, pageEndIndex; + UINT32 length, bitsCache, bitsBuf, bitsAP; +#if defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + UINT32 bitsXn; +#endif + UINT32 endAddr = para->endAddr; + UINT32 pageSize = (para->stPage->page_type == MMU_SECOND_LEVEL_BIG_PAGE_TABLE_ID) ? MMU_64K : MMU_4K; + UINT32 sttBase = para->stPage->page_descriptor_addr; + UINT32 rshiftBits = (pageSize == MMU_64K) ? SHIFT_64K : SHIFT_4K; + + if ((para->startAddr & (pageSize - 1)) != 0) { + return; + } + + if ((endAddr & (pageSize - 1)) != 0) { + endAddr = ALIGN(endAddr, pageSize); + } + + pageStartIndex = (para->startAddr - para->stPage->page_addr) >> rshiftBits; + pageEndIndex = (endAddr - para->stPage->page_addr) >> rshiftBits; + length = pageEndIndex - pageStartIndex; +#ifdef LOSCFG_NULL_ADDRESS_PROTECT + if (para->startAddr == EXC_VECTOR_ALIGN) { + para->startAddr -= EXC_VECTOR_ADDR - SYS_MEM_BASE; + } +#endif + bitsAP = MMU_AP_STATE(para->uwFlag); + bitsCache = MMU_CACHE_STATE(para->uwFlag); + bitsBuf = MMU_BUFFER_STATE(para->uwFlag); + +#ifdef LOSCFG_ARCH_ARM926 + if (pageSize == MMU_64K) { + pageBase = para->startAddr >> SHIFT_64K; + X_MMU_TWO_LEVEL_PAGE64K(pageBase, pageStartIndex, length, bitsCache, bitsBuf, bitsAP); + } else { + pageBase = para->startAddr >> SHIFT_4K; + X_MMU_TWO_LEVEL_PAGE(pageBase, pageStartIndex, length, bitsCache, bitsBuf, bitsAP); + } + +#elif defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + bitsXn = MMU_EXECUTE_STATE(para->uwFlag); + if (pageSize == MMU_64K) { + pageBase = para->startAddr >> SHIFT_64K; + X_MMU_TWO_LEVEL_PAGE64K(pageBase, pageStartIndex, length, bitsCache, bitsBuf, bitsAP, bitsXn); + } else { + pageBase = para->startAddr >> SHIFT_4K; + X_MMU_TWO_LEVEL_PAGE(pageBase, pageStartIndex, length, bitsCache, bitsBuf, bitsAP, bitsXn); + } +#endif +} + +STATIC UINT32 OsSetMmuFirstSection(const MMU_PARAM *para, UINT32 itemStart, UINT32 itemEnd) +{ + UINT32 intSave; + UINT32 itemTemp = itemStart; + UINT32 bitsCache, bitsBuf, bitsAP; +#if defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + UINT32 bitsXn = MMU_EXECUTE_STATE(para->uwFlag); +#endif + + bitsAP = MMU_AP_STATE(para->uwFlag); + bitsCache = MMU_CACHE_STATE(para->uwFlag); + bitsBuf = MMU_BUFFER_STATE(para->uwFlag); + + while (itemTemp <= itemEnd) { + if (((*(UINTPTR *)itemTemp) & ITEM_TYPE_MASK) != MMU_FIRST_LEVEL_SECTION_ID) { + PRINT_ERR("not all mem belongs to first section(1M every item), mmu table ID:%u\n", + ((*(UINTPTR *)itemTemp) & ITEM_TYPE_MASK)); + return LOS_NOK; + } + itemTemp += sizeof(UINTPTR); + } + + itemTemp = itemStart; + intSave = LOS_IntLock(); + DisableAPCheck(); + while (itemTemp <= itemEnd) { +#ifdef LOSCFG_ARCH_ARM926 + SECTION_CHANGE(itemTemp, bitsCache, bitsBuf, bitsAP); +#elif defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + SECTION_CHANGE(itemTemp, bitsCache, bitsBuf, bitsAP, bitsXn); +#endif + itemTemp += sizeof(UINTPTR); + } + EnableAPCheck(); + LOS_IntRestore(intSave); + dma_cache_clean(itemStart, itemEnd); + return LOS_OK; +} + +STATIC UINT32 OsSetMmuSecondPage(MMU_PARAM *para, UINT32 itemStart, UINT32 itemEnd) +{ + UINT32 intSave; + UINT32 itemTemp = itemStart; + UINT32 pageStart, pageEnd; + + if ((para->startAddr < para->stPage->page_addr) || + (para->endAddr > (para->stPage->page_length + para->stPage->page_addr))) { + PRINT_ERR("addr input not belongs to this second page \n" + "para->startAddr:0x%x, para->stPage->page_addr:0x%x\n", + para->startAddr, para->stPage->page_addr); + PRINT_ERR("para->endAddr:0x%x, (para->stPage->page_length + para->stPage->page_addr):0x%x\n", + para->endAddr, para->stPage->page_length + para->stPage->page_addr); + return LOS_NOK; + } + while (itemTemp <= itemEnd) { + if (((*(UINTPTR *)itemTemp) & ITEM_TYPE_MASK) != MMU_FIRST_LEVEL_PAGE_TABLE_ID) { + PRINT_ERR("not all mem belongs to second page(4K or 64K every item), mmu table ID:%u \n", + ((*(UINTPTR *)itemTemp) & ITEM_TYPE_MASK)); + return LOS_NOK; + } + itemTemp += sizeof(UINTPTR); + } + + intSave = LOS_IntLock(); + DisableAPCheck(); + OsSetMemPage(para); + EnableAPCheck(); + LOS_IntRestore(intSave); + pageStart = MMU_GET_SECOND_TABLE_ADDR(para->startAddr); + pageEnd = MMU_GET_SECOND_TABLE_ADDR(para->endAddr - 1); + dma_cache_clean(pageStart, pageEnd); + return LOS_OK; +} + +VOID LOS_SecPageEnable(SENCOND_PAGE *page, UINT32 flag) +{ + UINT32 pageStart, pageEnd; + UINT32 secStart, secEnd; + UINT32 ttbBase = FIRST_PAGE_DESCRIPTOR_ADDR; + MMU_PARAM para; + + if (page == NULL) { + PRINT_ERR("second page table(stPage) can't be NULL\n"); + return; + } + para.startAddr = page->page_addr; + para.endAddr = page->page_addr + page->page_length; + para.uwFlag = flag; + para.stPage = page; + + pageStart = page->page_descriptor_addr; + /* page size = 2 ^ 12, 4K */ + pageEnd = page->page_descriptor_addr + ((page->page_length >> SHIFT_4K) * BYTES_PER_ITEM); + DisableAPCheck(); + OsSetMemPage(¶); + dma_cache_clean(pageStart, pageEnd); + + X_MMU_ONE_LEVEL_PAGE(pageStart >> SHIFT_1K, page->page_addr >> SHIFT_1M, + page->page_length >> SHIFT_1M, D_CLIENT); + + secStart = ttbBase + ((para.startAddr >> SHIFT_1M) * BYTES_PER_ITEM); + secEnd = ttbBase + ((para.endAddr >> SHIFT_1M) * BYTES_PER_ITEM); + dma_cache_clean(secStart, secEnd); + CleanTLB(); + EnableAPCheck(); +} + +VOID LOS_MMUParamSet(MMU_PARAM *para) +{ + UINT32 ret; + UINT32 itemStart, itemEnd; + UINT32 tableType; + + if (para == NULL) { + PRINT_ERR("input is null\n"); + return; + } + itemStart = MMU_GET_FIRST_TABLE_ADDR(para->startAddr); + itemEnd = MMU_GET_FIRST_TABLE_ADDR(para->endAddr - 1); + if (itemStart > itemEnd) { + PRINT_ERR("wrong addr input, itemStart:0x%x, itemEnd:0x%x\n", itemStart, itemEnd); + return; + } + + tableType = MMU_GET_AREA(para->uwFlag); + if (tableType == SECOND_PAGE) { + ret = OsSetMmuSecondPage(para, itemStart, itemEnd); + if (ret == LOS_NOK) { + return; + } + } else if (tableType == FIRST_SECTION) { + ret = OsSetMmuFirstSection(para, itemStart, itemEnd); + if (ret == LOS_NOK) { + return; + } + } + + CleanTLB(); +} + +VOID OsSecPageInit(VOID) +{ + X_MMU_SECOND_TABLE_OS_PAGE_SET(); + X_MMU_SECOND_TABLE_APP_PAGE_SET(); +#ifdef LOSCFG_NULL_ADDRESS_PROTECT + X_MMU_SECOND_TABLE_EXC_PAGE_SET(); +#endif +} +VOID OsRemapCached(UINTPTR physAddr, size_t size) +{ + MMU_PARAM para; + + para.startAddr = physAddr; + para.endAddr = physAddr + size; +#ifdef LOSCFG_ARCH_ARM926 + para.uwFlag = BUFFER_ENABLE | CACHE_ENABLE | ACCESS_PERM_RW_RW; +#elif defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + para.uwFlag = BUFFER_ENABLE | CACHE_ENABLE | EXEC_DISABLE | ACCESS_PERM_RW_RW; +#endif + para.stPage = (SENCOND_PAGE *)&g_mmuAppPage; + LOS_MMUParamSet(¶); +} + +VOID OsRemapNoCached(UINTPTR physAddr, size_t size) +{ + MMU_PARAM para; + + para.startAddr = physAddr; + para.endAddr = physAddr + size; +#ifdef LOSCFG_ARCH_ARM926 + para.uwFlag = BUFFER_DISABLE | CACHE_DISABLE | ACCESS_PERM_RW_RW; +#elif defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + para.uwFlag = BUFFER_DISABLE | CACHE_DISABLE | EXEC_DISABLE | ACCESS_PERM_RW_RW; +#endif + para.stPage = (SENCOND_PAGE *)&g_mmuAppPage; + LOS_MMUParamSet(¶); +} + +VOID OsCodeProtect(VOID) +{ + CODE_PROTECT; +} + +INT32 OsMemNoAccessSet(UINTPTR startaddr, size_t length) +{ + UINTPTR ttbBase = FIRST_PAGE_DESCRIPTOR_ADDR; + UINTPTR endAddr = startaddr + length; + UINT32 base; + + if (startaddr >= endAddr) { + PRINT_ERR("The Input param invalid ,length equal 0 or the configuration scope overflow." + "startaddr:0x%x, length:0x%x\n", + startaddr, length); + return -1; + } + + if ((startaddr >= SYS_MEM_BASE) && (startaddr <= g_sys_mem_addr_end)) { + PRINT_ERR("The no access permission area sholud not contain os system mem,startaddr:0x%x\n", startaddr); + return -1; + } + if ((endAddr >= SYS_MEM_BASE) && (endAddr <= g_sys_mem_addr_end)) { + PRINT_ERR("The no access permission area sholud not contain os system mem,endAddr:0x%x\n", endAddr); + return -1; + } + if (((startaddr & (MMU_1M - 1)) != 0) || ((length & (MMU_1M - 1)) != 0)) { + PRINT_ERR("The start address or the length is not aligned as 1M, startaddr:0x%x, length:0x%x\n", startaddr, + length); + return -1; + } + + DisableAPCheck(); + base = startaddr >> SHIFT_1M; +#ifdef LOSCFG_ARCH_ARM926 + X_MMU_SECTION(base, base, length >> SHIFT_1M, 0, 0, 0, D_NA); +#elif defined(LOSCFG_ARCH_CORTEX_A7) || defined(LOSCFG_ARCH_CORTEX_A17) || defined(LOSCFG_ARCH_CORTEX_A53_AARCH32) + X_MMU_SECTION(base, base, length >> SHIFT_1M, 0, 0, 0, 0, D_NA); +#endif + dma_cache_clean(ttbBase + ((startaddr >> SHIFT_1M) * BYTES_PER_ITEM), + ttbBase + ((endAddr >> SHIFT_1M) * BYTES_PER_ITEM)); + + CleanTLB(); + EnableAPCheck(); + return 0; +} + +VOID OsPrintPageItem(const MMU_PARAM *para) +{ + UINT32 tmp; + UINT32 startAddr; + UINT32 pageLen; + + if (para == NULL) { + return; + } + + if (MMU_GET_AREA(para->uwFlag) == SECOND_PAGE) { + startAddr = para->stPage->page_descriptor_addr + + (((para->startAddr - para->stPage->page_addr) >> SHIFT_4K) * BYTES_PER_ITEM); + pageLen = ((para->endAddr - para->startAddr) >> SHIFT_4K) * BYTES_PER_ITEM; + if ((para->endAddr & (MMU_4K - 1)) != 0) { + pageLen += sizeof(UINT32); + } + PRINTK("SECOND_PAGE:\n"); + } else if (MMU_GET_AREA(para->uwFlag) == FIRST_SECTION) { + startAddr = FIRST_PAGE_DESCRIPTOR_ADDR + ((para->startAddr >> SHIFT_1M) * BYTES_PER_ITEM); + pageLen = ((para->endAddr - para->startAddr) >> SHIFT_1M) * BYTES_PER_ITEM; + if ((para->endAddr & (MMU_1M - 1)) != 0) { + pageLen += sizeof(UINT32); + } + PRINTK("FIRST_SECTION:\n"); + } else { + return; + } + + PRINTK("para->endAddr = 0x%x para->startAddr = 0x%x page_len = %u * 4\n", + para->endAddr, para->startAddr, pageLen / BYTES_PER_ITEM); + + for (tmp = 0; tmp < pageLen; tmp += sizeof(UINT32)) { + if (tmp % ITEM_PRINT_LEN == 0) { + PRINTK("\n"); + } + PRINTK ("0x%0+8x ", *(UINTPTR *)(startAddr + tmp)); + } + PRINTK("\n"); +} + +VOID OsMmuInit(VOID) +{ + UINT32 ttbBase = FIRST_PAGE_DESCRIPTOR_ADDR + 0x0; + UINT32 regDACR; + + /* Set the TTB register */ + __asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ttbBase)); + /* Set the Domain Access Control Register */ + regDACR = ACCESS_TYPE_MANAGER(DOMAIN0) | ACCESS_TYPE_CLIENT(DOMAIN1); /* D0:manager; D1:client */ + __asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r"(regDACR)); + +#ifdef LOSCFG_KERNEL_RUNSTOP + if (IsImageResume()) return; +#endif + + /* First clear all TT entries - ie Set them to Faulting */ + (VOID)memset_s((UINTPTR *)ttbBase, MMU_16K, 0, MMU_16K); + + /* + * Set domain of mmu descriptor of (0~1M) D_NA, check the illegal access to NULL pointer in code. + * Access to NULL pointer and mem (0 ~ 1M) will trigger exception immediately + */ + X_MMU_SECTION(0, 0, (MMU_1M >> SHIFT_1M), UNCACHEABLE, UNBUFFERABLE, + ACCESS_NA, NON_EXECUTABLE, D_NA); + + /* Set all mem 4G except (0~1M) as uncacheable & rw first */ + X_MMU_SECTION((MMU_1M >> SHIFT_1M), (MMU_1M >> SHIFT_1M), ((MMU_4G - MMU_1M) >> SHIFT_1M), + UNCACHEABLE, UNBUFFERABLE, ACCESS_RW, NON_EXECUTABLE, D_CLIENT); + + /* + * set table as your config + * 1: LITEOS_CACHE_ADDR ~ LITEOS_CACHE_ADDR + LITEOS_CACHE_LENGTH ---- set as section(1M) and cacheable & rw + */ + X_MMU_SECTION((LITEOS_CACHE_ADDR >> SHIFT_1M), (SYS_MEM_BASE >> SHIFT_1M), (LITEOS_CACHE_LENGTH >> SHIFT_1M), + CACHEABLE, BUFFERABLE, ACCESS_RW, NON_EXECUTABLE, 0); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-m/Makefile b/arch/arm/cortex-m/Makefile new file mode 100644 index 000000000..2a1bd1675 --- /dev/null +++ b/arch/arm/cortex-m/Makefile @@ -0,0 +1,15 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(LOSCFG_ARCH_CPU) + +LOCAL_SRCS += $(wildcard src/*.c) $(wildcard ../../common/*.c) $(wildcard $(MODULE_NAME)/gcc/*.S) $(wildcard $(MODULE_NAME)/*.c) +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/kernel/base/include \ + -I $(LITEOSTOPDIR)/kernel/extended/include + +LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS) + +ifeq ($(LOSCFG_GDB), y) +LOCAL_FLAGS += $(AS_OBJS_LIBC_FLAGS) +endif +include $(MODULE) diff --git a/arch/arm/cortex-m/cortex-m0/gcc/los_dispatch.S b/arch/arm/cortex-m/cortex-m0/gcc/los_dispatch.S new file mode 100644 index 000000000..05979638a --- /dev/null +++ b/arch/arm/cortex-m/cortex-m0/gcc/los_dispatch.S @@ -0,0 +1,137 @@ +.syntax unified +.arch armv6-m +.thumb + +.section .text +.equ OS_NVIC_INT_CTRL, 0xE000ED04 +.equ OS_NVIC_SYSPRI2, 0xE000ED20 +.equ OS_NVIC_PENDSV_PRI, 0x00F00000 +.equ OS_NVIC_PENDSVSET, 0x10000000 +.equ OS_TASK_STATUS_RUNNING, 0x0010 + + .type OsStartToRun, %function + .global OsStartToRun +OsStartToRun: + .fnstart + .cantunwind + LDR R4, =OS_NVIC_SYSPRI2 + LDR R5, =OS_NVIC_PENDSV_PRI + STR R5, [R4] + + LDR R1, =g_oldTask + STR R0, [R1] + + MOVS R1, #2 + MSR CONTROL, R1 + + + LDRH R7, [R0 , #4] + MOVS R6, #OS_TASK_STATUS_RUNNING + ORRS R7, R7, R6 + STRH R7, [R0 , #4] + + LDR R3, [R0] + ADDS R3, R3, #36 + + LDMFD R3!, {R0-R2} + ADDS R3, R3, #4 + LDMFD R3!, {R4-R7} + MSR PSP, R3 + SUBS R3, R3, #20 + LDR R3, [R3] + + MOV LR, R5 + CPSIE I + BX R6 + .fnend + + .type OsIntLock, %function + .global OsIntLock +OsIntLock: + .fnstart + .cantunwind + MRS R0, PRIMASK + CPSID I + BX LR + .fnend + + .type OsIntUnLock, %function + .global OsIntUnLock +OsIntUnLock: + .fnstart + .cantunwind + MRS R0, PRIMASK + CPSIE I + BX LR + .fnend + + .type OsIntRestore, %function + .global OsIntRestore +OsIntRestore: + .fnstart + .cantunwind + MSR PRIMASK, R0 + BX LR + .fnend + + .type OsTaskSchedule, %function + .global OsTaskSchedule +OsTaskSchedule: + .fnstart + .cantunwind + LDR R2, =OS_NVIC_INT_CTRL + LDR R3, =OS_NVIC_PENDSVSET + STR R3, [R2] + BX LR + .fnend + + .type PendSV_Handler, %function + .global PendSV_Handler +PendSV_Handler: + .fnstart + .cantunwind + MRS R12, PRIMASK + CPSID I + + + +TaskSwitch: + MRS R0, PSP + + SUBS R0, #36 + STMIA R0!, {R4-R7} + MOV R3, R8 + MOV R4, R9 + MOV R5, R10 + MOV R6, R11 + MOV R7, R12 + STMIA R0!, {R3 - R7} + + SUBS R0, #36 + + LDR R5, =g_oldTask + LDR R1, [R5] + STR R0, [R1] + + + LDR R0, =g_runTask + LDR R0, [R0] + /* g_oldTask = g_runTask */ + STR R0, [R5] + LDR R1, [R0] + ADDS R1, #16 + LDMFD R1!, {R3-R7} + MOV R8, R3 + MOV R9, R4 + MOV R10, R5 + MOV R11, R6 + MOV R12, R7 + SUBS R1, #36 + LDMFD R1!, {R4-R7} + + ADDS R1, #20 + MSR PSP, R1 + + MSR PRIMASK, R12 + BX LR + .fnend diff --git a/arch/arm/cortex-m/cortex-m0/include/core_cm0.h b/arch/arm/cortex-m/cortex-m0/include/core_cm0.h new file mode 100644 index 000000000..f548280de --- /dev/null +++ b/arch/arm/cortex-m/cortex-m0/include/core_cm0.h @@ -0,0 +1,947 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (5U) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (4U) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/kernel/base/core/los_tick.inc b/arch/arm/cortex-m/cortex-m0/include/los_armcm.h similarity index 76% rename from kernel/base/core/los_tick.inc rename to arch/arm/cortex-m/cortex-m0/include/los_armcm.h index 3a304b010..bd3d7041a 100644 --- a/kernel/base/core/los_tick.inc +++ b/arch/arm/cortex-m/cortex-m0/include/los_armcm.h @@ -1,40 +1,40 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_TICK_INC -#define _LOS_TICK_INC - -#include "los_tick.ph" - -#endif /* _LOS_TICK_INC */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS adapter CMSIS Core Peripheral Access LayerM0 + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_ARM_CM_H +#define _LOS_ARM_CM_H + +#include "core_cm0.h" + +#endif /* _LOS_ARM_CM_H */ diff --git a/arch/arm/arm-m/cortex-m7/los_exc.inc b/arch/arm/cortex-m/cortex-m0/include/los_exc_pri.h similarity index 56% rename from arch/arm/arm-m/cortex-m7/los_exc.inc rename to arch/arm/cortex-m/cortex-m0/include/los_exc_pri.h index c46c29130..f7e8c10de 100644 --- a/arch/arm/arm-m/cortex-m7/los_exc.inc +++ b/arch/arm/cortex-m/cortex-m0/include/los_exc_pri.h @@ -1,217 +1,170 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#ifndef _LOS_EXC_INC -#define _LOS_EXC_INC - -#include "los_exc.ph" -#include "los_sys.ph" -#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 - -/* - *异常类型:uwFaultAddr域是å¦æœ‰æ•ˆ æ ‡å¿—ä½ - */ -#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 - -/* - *异常类型:异常是å¦å‘ç”Ÿåœ¨ç¡¬ä¸­æ–­ä¸­æ ‡å¿—ä½ - */ -#define OS_EXC_FLAG_IN_HWI 0x02 - -#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB - -#define OS_EXC_FLAG_NO_FLOAT 0x10000000 - - -#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_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE -#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE - - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:总线状æ€å¯„存器入栈时å‘生错误 - */ -#define OS_EXC_BF_STKERR 1 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:总线状æ€å¯„存器出栈时å‘生错误 - */ -#define OS_EXC_BF_UNSTKERR 2 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:总线状æ€å¯„存器ä¸ç²¾ç¡®çš„æ•°æ®è®¿é—®è¿ä¾‹ - */ -#define OS_EXC_BF_IMPRECISERR 3 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:总线状æ€å¯„存器精确的数æ®è®¿é—®è¿ä¾‹ - */ -#define OS_EXC_BF_PRECISERR 4 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:总线状æ€å¯„存器å–指时的访问è¿ä¾‹ - */ -#define OS_EXC_BF_IBUSERR 5 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:存储器管ç†çŠ¶æ€å¯„存器入栈时å‘生错误 - */ -#define OS_EXC_MF_MSTKERR 6 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:存储器管ç†çŠ¶æ€å¯„存器出栈时å‘生错误 - */ -#define OS_EXC_MF_MUNSTKERR 7 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:存储器管ç†çŠ¶æ€å¯„存器数æ®è®¿é—®è¿ä¾‹ - */ -#define OS_EXC_MF_DACCVIOL 8 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:存储器管ç†çŠ¶æ€å¯„存器å–指访问è¿ä¾‹ - */ -#define OS_EXC_MF_IACCVIOL 9 - - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:用法错误,表示除法è¿ç®—时除数为零 - */ -#define OS_EXC_UF_DIVBYZERO 10 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:用法错误,未对é½è®¿é—®å¯¼è‡´çš„错误 - */ -#define OS_EXC_UF_UNALIGNED 11 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:用法错误,试图执行å处ç†å™¨ç›¸å…³æŒ‡ä»¤ - */ -#define OS_EXC_UF_NOCP 12 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:用法错误,在异常返回时试图éžæ³•åœ°åŠ è½½EXC_RETURN到PC - */ -#define OS_EXC_UF_INVPC 13 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:用法错误,试图切入ARMçŠ¶æ€ - */ -#define OS_EXC_UF_INVSTATE 14 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:用法错误,执行的指令其编ç æ˜¯æœªå®šä¹‰çš„——解ç ä¸èƒ½ - */ -#define OS_EXC_UF_UNDEFINSTR 15 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:NMI中断 - */ - -#define OS_EXC_CAUSE_NMI 16 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:硬fault - */ -#define OS_EXC_CAUSE_HARDFAULT 17 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:任务处ç†å‡½æ•°é€€å‡º - */ -#define OS_EXC_CAUSE_TASK_EXIT 18 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:致命错误 - */ -#define OS_EXC_CAUSE_FATAL_ERR 19 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:调试事件导致的硬fault - */ -#define OS_EXC_CAUSE_DEBUGEVT 20 - -/** - *@ingroup los_exc - *Cortex-M4异常具体类型:å–å‘é‡æ—¶å‘生的硬fault - */ -#define OS_EXC_CAUSE_VECTBL 21 - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#endif /* _LOS_EXC_INC */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#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 UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID*); + +typedef struct tagExcInfoCallBackArray { + ExcInfoType uwType; + UINT32 uwValid; + EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; + VOID *pArg; +} ExcInfoArray; + +#define MAX_SCENE_INFO_SIZE (8 + sizeof(EXC_INFO_S) - 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); + + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 + +#define OS_EXC_FLAG_IN_HWI 0x02 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +#define OS_EXC_FLAG_NO_FLOAT 0x10000000 + + +#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_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE +#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE + +#define OS_EXC_BF_STKERR 1 + +#define OS_EXC_BF_UNSTKERR 2 + +#define OS_EXC_BF_IMPRECISERR 3 + +#define OS_EXC_BF_PRECISERR 4 + +#define OS_EXC_BF_IBUSERR 5 + +#define OS_EXC_MF_MSTKERR 6 + +#define OS_EXC_MF_MUNSTKERR 7 + +#define OS_EXC_MF_DACCVIOL 8 + +#define OS_EXC_MF_IACCVIOL 9 + +#define OS_EXC_UF_DIVBYZERO 10 + +#define OS_EXC_UF_UNALIGNED 11 + +#define OS_EXC_UF_NOCP 12 + +#define OS_EXC_UF_INVPC 13 + +#define OS_EXC_UF_INVSTATE 14 + +#define OS_EXC_UF_UNDEFINSTR 15 + +#define OS_EXC_CAUSE_NMI 16 + +#define OS_EXC_CAUSE_HARDFAULT 17 + +#define OS_EXC_CAUSE_TASK_EXIT 18 + +#define OS_EXC_CAUSE_FATAL_ERR 19 + +#define OS_EXC_CAUSE_DEBUGEVT 20 + +#define OS_EXC_CAUSE_VECTBL 21 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/arch/arm/cortex-m/cortex-m0/los_exc.c b/arch/arm/cortex-m/cortex-m0/los_exc.c new file mode 100644 index 000000000..58c381388 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m0/los_exc.c @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_exc_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +LITE_OS_SEC_TEXT_INIT VOID OsExcInit(VOID) +{ +} + +VOID LOS_Panic(const CHAR *fmt, ...) +{ +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/arm-m/cortex-m3/gcc/los_dispatch_gcc.S b/arch/arm/cortex-m/cortex-m3/gcc/los_dispatch_gcc.S similarity index 100% rename from arch/arm/arm-m/cortex-m3/gcc/los_dispatch_gcc.S rename to arch/arm/cortex-m/cortex-m3/gcc/los_dispatch_gcc.S diff --git a/arch/arm/arm-m/cortex-m3/gcc/los_hw_exc_gcc.S b/arch/arm/cortex-m/cortex-m3/gcc/los_hw_exc_gcc.S similarity index 100% rename from arch/arm/arm-m/cortex-m3/gcc/los_hw_exc_gcc.S rename to arch/arm/cortex-m/cortex-m3/gcc/los_hw_exc_gcc.S diff --git a/arch/arm/arm-m/cortex-m3/iar/los_dispatch_iar.S b/arch/arm/cortex-m/cortex-m3/iar/los_dispatch_iar.S similarity index 100% rename from arch/arm/arm-m/cortex-m3/iar/los_dispatch_iar.S rename to arch/arm/cortex-m/cortex-m3/iar/los_dispatch_iar.S diff --git a/arch/arm/arm-m/cortex-m3/keil/los_dispatch_keil.S b/arch/arm/cortex-m/cortex-m3/keil/los_dispatch_keil.S similarity index 100% rename from arch/arm/arm-m/cortex-m3/keil/los_dispatch_keil.S rename to arch/arm/cortex-m/cortex-m3/keil/los_dispatch_keil.S diff --git a/arch/arm/arm-m/cortex-m3/keil/los_hw_exc_keil.S b/arch/arm/cortex-m/cortex-m3/keil/los_hw_exc_keil.S similarity index 100% rename from arch/arm/arm-m/cortex-m3/keil/los_hw_exc_keil.S rename to arch/arm/cortex-m/cortex-m3/keil/los_hw_exc_keil.S diff --git a/arch/arm/arm-m/cortex-m3/los_exc.c b/arch/arm/cortex-m/cortex-m3/los_exc.c similarity index 100% rename from arch/arm/arm-m/cortex-m3/los_exc.c rename to arch/arm/cortex-m/cortex-m3/los_exc.c diff --git a/arch/arm/arm-m/cortex-m0/los_exc.inc b/arch/arm/cortex-m/cortex-m3/los_exc.inc similarity index 100% rename from arch/arm/arm-m/cortex-m0/los_exc.inc rename to arch/arm/cortex-m/cortex-m3/los_exc.inc diff --git a/arch/arm/arm-m/cortex-m3/los_exc.ph b/arch/arm/cortex-m/cortex-m3/los_exc.ph similarity index 100% rename from arch/arm/arm-m/cortex-m3/los_exc.ph rename to arch/arm/cortex-m/cortex-m3/los_exc.ph diff --git a/arch/arm/arm-m/cortex-m3/test_funcs.S b/arch/arm/cortex-m/cortex-m3/test_funcs.S similarity index 100% rename from arch/arm/arm-m/cortex-m3/test_funcs.S rename to arch/arm/cortex-m/cortex-m3/test_funcs.S diff --git a/arch/arm/cortex-m/cortex-m4/gcc/los_dispatch.S b/arch/arm/cortex-m/cortex-m4/gcc/los_dispatch.S new file mode 100644 index 000000000..5925a1105 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/gcc/los_dispatch.S @@ -0,0 +1,127 @@ + +.syntax unified +.arch armv7e-m +.thumb + +.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 OsStartToRun, %function + .global OsStartToRun +OsStartToRun: + .fnstart + .cantunwind + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r1, =g_oldTask + str r0, [r1] + + ldr r1, =g_runTask + str r0, [r1] + + mov r1, #2 + msr CONTROL, r1 + + + 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 OsIntLock, %function + .global OsIntLock +OsIntLock: + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsid I + bx lr + .fnend + + .type OsIntUnLock, %function + .global OsIntUnLock +OsIntUnLock: + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsie I + bx lr + .fnend + + .type OsIntRestore, %function + .global OsIntRestore +OsIntRestore: + .fnstart + .cantunwind + msr PRIMASK, r0 + bx lr + .fnend + + .type OsTaskSchedule, %function + .global OsTaskSchedule +OsTaskSchedule: + .fnstart + .cantunwind + ldr r2, =OS_NVIC_INT_CTRL + ldr r3, =OS_NVIC_PENDSVSET + str r3, [r2] + bx lr + .fnend + + .type osPendSV, %function + .global osPendSV +osPendSV: + .fnstart + .cantunwind + mrs r12, PRIMASK + cpsid I + + +TaskSwitch: + mrs r0, psp + + stmfd r0!, {r4-r12} + vstmdb r0!, {d8-d15} + + ldr r5, =g_oldTask + ldr r1, [r5] + str r0, [r1] + + ldr r0, =g_runTask + ldr r0, [r0] + /* g_oldTask = g_runTask */ + str r0, [r5] + 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/gcc/los_hw_exc.S b/arch/arm/cortex-m/cortex-m4/gcc/los_hw_exc.S new file mode 100644 index 000000000..13b60c6f8 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/gcc/los_hw_exc.S @@ -0,0 +1,335 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: M7 Hw Exc Implementation + * 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. + * --------------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + + .syntax unified + .arch armv7-m + .thumb + .fpu vfpv4 + .section .text + + + .global OsExcNMI + .global OsExcHardFault + .global OsExcMemFault + .global OsExcBusFault + .global OsExcUsageFault + .global OsExcSvcCall + + .extern OsExcHandleEntry + .extern g_excTbl + .extern g_taskScheduled + + .equ OS_EXC_CAUSE_NMI , 16 + .equ OS_EXC_CAUSE_HARDFAULT , 17 + .equ HF_DEBUGEVT , 20 + .equ HF_VECTBL , 21 + .equ OS_EXC_FLAG_FAULTADDR_VALID , 0x10000 + .equ OS_EXC_FLAG_IN_HWI , 0x20000 + .equ OS_EXC_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 + .equ EXCEPT_FRAME_OFFSET_PC , 0x06 * 4 /* see cortex-m7 reference manual: chapter 2.3.7 */ + + .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 + + MRS R2, MSP + LDR R1, [R2, EXCEPT_FRAME_OFFSET_PC] + + 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, #OS_EXC_FLAG_FAULTADDR_VALID + B OsHFExcCommonBMU + .fnend + + .type HFMemFault, %function +HFMemFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #OS_EXC_FLAG_FAULTADDR_VALID + .fnend + + .type OsHFExcCommonBMU, %function + .global OsHFExcCommonBMU +OsHFExcCommonBMU: + .fnstart + .cantunwind + CLZ R2, R2 + LDR R3, =g_excTbl + 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, #OS_EXC_FLAG_FAULTADDR_VALID + AND R0, #0x1F00 + + B OsExcCommonBMU + .fnend + + .type ExcBusNoAddr, %function +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, #OS_EXC_FLAG_FAULTADDR_VALID + AND R0, #0x1B + + B OsExcCommonBMU + .fnend + + .type ExcMemNoAddr, %function +ExcMemNoAddr: + .fnstart + .cantunwind + MOV R12,#0 + B OsExcCommonBMU + .fnend + + .type OsExcUsageFault, %function + .global OsExcUsageFault +OsExcUsageFault: + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + LDR R1, =#0x030F + LSL R1, #16 + AND R0, R1 + MOV R12, #0 + +OsExcCommonBMU: + CLZ R0, R0 + LDR R3, =g_excTbl + 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, #OS_EXC_FLAG_IN_HWI + RBIT R2, R3 + CLZ R2, R2 + AND R12, #1 + ADD R2, R2, R12, LSL #5 /* calculate R2 (hwi number) as pid, thrid parameter */ + +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, #OS_EXC_FLAG_NO_FLOAT + B HandleEntry + +HwiActiveCheckNext: + 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 scheduled */ + 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, #OS_EXC_FLAG_NO_FLOAT + +HandleEntry: + MOV R3, R13 /* R13:the 4th param */ + CPSID I + CPSID F + B OsExcHandleEntry + + NOP 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 100644 index 000000000..927de9ebc --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/iar/los_dispatch_iar.S @@ -0,0 +1,129 @@ + +PRESERVE8 +REQUIRE8 +THUMB + +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 + + + EXPORT OsStartToRun +OsStartToRun + .fnstart + .cantunwind + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r1, =g_oldTask + str r0, [r1] + + ldr r1, =g_runTask + str r0, [r1] + + mov r1, #2 + msr CONTROL, r1 + + + 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 + + + EXPORT OsIntLock +OsIntLock + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsid I + bx lr + .fnend + + + EXPORT OsIntUnLock +OsIntUnLock + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsie I + bx lr + .fnend + + + EXPORT OsIntRestore +OsIntRestore + .fnstart + .cantunwind + msr PRIMASK, r0 + bx lr + .fnend + + + EXPORT OsTaskSchedule +OsTaskSchedule + .fnstart + .cantunwind + ldr r2, =OS_NVIC_INT_CTRL + ldr r3, =OS_NVIC_PENDSVSET + str r3, [r2] + bx lr + .fnend + + + EXPORT osPendSV +osPendSV + .fnstart + .cantunwind + mrs r12, PRIMASK + cpsid I + + +TaskSwitch + mrs r0, psp + + stmfd r0!, {r4-r12} + vstmdb r0!, {d8-d15} + + ldr r5, =g_oldTask + ldr r1, [r5] + str r0, [r1] + + ldr r0, =g_runTask + ldr r0, [r0] + ;/* g_oldTask = g_runTask */ + str r0, [r5] + ldr r1, [r0] + + vldmia r1!, {d8-d15} + ldmfd r1!, {r4-r12} + msr psp, r1 + + msr PRIMASK, r12 + bx lr + + .fnend + + END diff --git a/arch/arm/arm-m/cortex-m4/iar/los_hw_exc_iar.S b/arch/arm/cortex-m/cortex-m4/iar/los_hw_exc_iar.S similarity index 100% rename from arch/arm/arm-m/cortex-m4/iar/los_hw_exc_iar.S rename to arch/arm/cortex-m/cortex-m4/iar/los_hw_exc_iar.S diff --git a/arch/arm/cortex-m/cortex-m4/include/los_armcm.h b/arch/arm/cortex-m/cortex-m4/include/los_armcm.h new file mode 100644 index 000000000..2b7201bb1 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/include/los_armcm.h @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS adapter CMSIS Core Peripheral Access LayerM7 + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_ARM_CM_H +#define _LOS_ARM_CM_H + +#include "core_cm4.h" + +#endif /* _LOS_ARM_CM_H */ diff --git a/arch/arm/arm-m/cortex-m4/los_exc.ph b/arch/arm/cortex-m/cortex-m4/include/los_exc_pri.h similarity index 50% rename from arch/arm/arm-m/cortex-m4/los_exc.ph rename to arch/arm/cortex-m/cortex-m4/include/los_exc_pri.h index 31e7f6d52..f7e8c10de 100644 --- a/arch/arm/arm-m/cortex-m4/los_exc.ph +++ b/arch/arm/cortex-m/cortex-m4/include/los_exc_pri.h @@ -1,116 +1,170 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_EXC_PH -#define _LOS_EXC_PH - -#include "los_exc.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#if (LOSCFG_PLATFORM_EXC == YES) - -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 -} EXC_INFO_TYPE; - -typedef struct tagExcInfoCallBackArray -{ - EXC_INFO_TYPE uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -}EXC_INFO_ARRAY_S; - - -#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_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE -#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(EXC_INFO_S) - 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 - -#if (LOSCFG_SAVE_EXC_INFO == YES) -#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) -#else -#define MAX_EXC_MEM_SIZE ( 0 ) -#endif - -extern VOID osExcRegister(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg); - -#endif - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#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 UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID*); + +typedef struct tagExcInfoCallBackArray { + ExcInfoType uwType; + UINT32 uwValid; + EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; + VOID *pArg; +} ExcInfoArray; + +#define MAX_SCENE_INFO_SIZE (8 + sizeof(EXC_INFO_S) - 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); + + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 + +#define OS_EXC_FLAG_IN_HWI 0x02 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +#define OS_EXC_FLAG_NO_FLOAT 0x10000000 + + +#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_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE +#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE + +#define OS_EXC_BF_STKERR 1 + +#define OS_EXC_BF_UNSTKERR 2 + +#define OS_EXC_BF_IMPRECISERR 3 + +#define OS_EXC_BF_PRECISERR 4 + +#define OS_EXC_BF_IBUSERR 5 + +#define OS_EXC_MF_MSTKERR 6 + +#define OS_EXC_MF_MUNSTKERR 7 + +#define OS_EXC_MF_DACCVIOL 8 + +#define OS_EXC_MF_IACCVIOL 9 + +#define OS_EXC_UF_DIVBYZERO 10 + +#define OS_EXC_UF_UNALIGNED 11 + +#define OS_EXC_UF_NOCP 12 + +#define OS_EXC_UF_INVPC 13 + +#define OS_EXC_UF_INVSTATE 14 + +#define OS_EXC_UF_UNDEFINSTR 15 + +#define OS_EXC_CAUSE_NMI 16 + +#define OS_EXC_CAUSE_HARDFAULT 17 + +#define OS_EXC_CAUSE_TASK_EXIT 18 + +#define OS_EXC_CAUSE_FATAL_ERR 19 + +#define OS_EXC_CAUSE_DEBUGEVT 20 + +#define OS_EXC_CAUSE_VECTBL 21 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/arch/arm/cortex-m/cortex-m4/keil/los_dispatch_keil.S b/arch/arm/cortex-m/cortex-m4/keil/los_dispatch_keil.S new file mode 100644 index 000000000..1b73e19a6 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/keil/los_dispatch_keil.S @@ -0,0 +1,130 @@ + +PRESERVE8 +REQUIRE8 +THUMB + +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 + + AREA |.text|, CODE, READONLY + THUMB + + + EXPORT OsStartToRun +OsStartToRun + .fnstart + .cantunwind + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r1, =g_oldTask + str r0, [r1] + + ldr r1, =g_runTask + str r0, [r1] + + mov r1, #2 + msr CONTROL, r1 + + + 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 + + + EXPORT OsIntLock +OsIntLock + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsid I + bx lr + .fnend + + + EXPORT OsIntUnLock +OsIntUnLock + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsie I + bx lr + .fnend + + + EXPORT OsIntRestore +OsIntRestore + .fnstart + .cantunwind + msr PRIMASK, r0 + bx lr + .fnend + + + EXPORT OsTaskSchedule +OsTaskSchedule + .fnstart + .cantunwind + ldr r2, =OS_NVIC_INT_CTRL + ldr r3, =OS_NVIC_PENDSVSET + str r3, [r2] + bx lr + .fnend + + + EXPORT osPendSV +osPendSV + .fnstart + .cantunwind + mrs r12, PRIMASK + cpsid I + + +TaskSwitch + mrs r0, psp + + stmfd r0!, {r4-r12} + vstmdb r0!, {d8-d15} + + ldr r5, =g_oldTask + ldr r1, [r5] + str r0, [r1] + + ldr r0, =g_runTask + ldr r0, [r0] + ;/* g_oldTask = g_runTask */ + str r0, [r5] + ldr r1, [r0] + + vldmia r1!, {d8-d15} + ldmfd r1!, {r4-r12} + msr psp, r1 + + msr PRIMASK, r12 + bx lr + + .fnend + + ALIGN + END diff --git a/arch/arm/arm-m/cortex-m4/keil/los_hw_exc_keil.S b/arch/arm/cortex-m/cortex-m4/keil/los_hw_exc_keil.S similarity index 100% rename from arch/arm/arm-m/cortex-m4/keil/los_hw_exc_keil.S rename to arch/arm/cortex-m/cortex-m4/keil/los_hw_exc_keil.S 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 100644 index 000000000..adf6f081b --- /dev/null +++ b/arch/arm/cortex-m/cortex-m4/los_exc.c @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_exc_pri.h" +#ifdef LOSCFG_LIB_LIBC +#include "string.h" +#endif +#include "los_hwi_pri.h" +#include "los_memcheck_pri.h" +#include "los_tick_pri.h" +#include "securec.h" +#include "los_armcm.h" +#include "los_printf_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define USGFAULT (1U << 18) +#define BUSFAULT (1U << 17) +#define MEMFAULT (1U << 16) +#define DIV0FAULT (1U << 4) +#define HARD_FAULT_IRQN (-13) +#define MASK_16_BIT 16 + +UINT32 g_curNestCount = 0; +EXC_INFO_S g_excInfo; +UINT8 g_excTbl[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 +}; +ExcInfoArray g_excArray[OS_EXC_TYPE_MAX - 1]; +STATIC const CHAR *g_phaseName[] = { + "fault in init", + "fault in task", + "fault in interrupt", +}; + +__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"); +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcInfoDisplay(const EXC_INFO_S *exc) +{ + PrintExcInfo("Phase = %s\n" + "Type = 0x%x\n" + "FaultAddr = 0x%x\n" + "ThrdPid = 0x%x\n" + "R0 = 0x%x\n" + "R1 = 0x%x\n" + "R2 = 0x%x\n" + "R3 = 0x%x\n" + "R4 = 0x%x\n" + "R5 = 0x%x\n" + "R6 = 0x%x\n" + "R7 = 0x%x\n" + "R8 = 0x%x\n" + "R9 = 0x%x\n" + "R10 = 0x%x\n" + "R11 = 0x%x\n" + "R12 = 0x%x\n" + "PriMask = 0x%x\n" + "SP = 0x%x\n" + "LR = 0x%x\n" + "PC = 0x%x\n" + "xPSR = 0x%x\n", + g_phaseName[exc->phase], exc->type, exc->faultAddr, exc->thrdPid, exc->context->uwR0, + exc->context->uwR1, exc->context->uwR2, exc->context->uwR3, exc->context->uwR4, exc->context->uwR5, + exc->context->uwR6, exc->context->uwR7, exc->context->uwR8, exc->context->uwR9, + exc->context->uwR10, exc->context->uwR11, exc->context->uwR12, exc->context->uwPriMask, + exc->context->uwSP, exc->context->uwLR, exc->context->uwPC, exc->context->uwxPSR); + return; +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, + const EXC_CONTEXT_S *excBufAddr) +{ + UINT16 tmpFlag = (excType >> MASK_16_BIT) & OS_NULL_SHORT; /* 2:in intrrupt,1:faul addr valid */ + g_curNestCount++; + g_tickCount[ArchCurrCpuid()]++; + g_excInfo.nestCnt = g_curNestCount; + + g_excInfo.type = excType & OS_NULL_SHORT; + + if (tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) { + g_excInfo.faultAddr = faultAddr; + } else { + g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; + } + + if (ArchCurrTaskGet() != 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 = ((LosTaskCB *)ArchCurrTaskGet())->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 = (EXC_CONTEXT_S *)excBufAddr; + } + + OsExcInfoDisplay((const EXC_INFO_S *)&g_excInfo); + + while (1) { } +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcInit(VOID) +{ + g_hwiVec[HARD_FAULT_IRQN + OS_SYS_VECTOR_CNT] = OsExcHardFault; + g_hwiVec[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = OsExcNMI; + g_hwiVec[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = OsExcMemFault; + g_hwiVec[BusFault_IRQn + OS_SYS_VECTOR_CNT] = OsExcBusFault; + g_hwiVec[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = OsExcUsageFault; + g_hwiVec[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; +} + +/* stack protector */ +UINT32 __stack_chk_guard = 0xd00a0dff; + +VOID __stack_chk_fail(VOID) +{ + /* __builtin_return_address is a builtin function, building in gcc */ + LOS_Panic("stack-protector: Kernel stack is corrupted in: %p\n", __builtin_return_address(0)); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-m/cortex-m7/gcc/los_dispatch.S b/arch/arm/cortex-m/cortex-m7/gcc/los_dispatch.S new file mode 100644 index 000000000..5925a1105 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/gcc/los_dispatch.S @@ -0,0 +1,127 @@ + +.syntax unified +.arch armv7e-m +.thumb + +.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 OsStartToRun, %function + .global OsStartToRun +OsStartToRun: + .fnstart + .cantunwind + ldr r4, =OS_NVIC_SYSPRI2 + ldr r5, =OS_NVIC_PENDSV_PRI + str r5, [r4] + + ldr r1, =g_oldTask + str r0, [r1] + + ldr r1, =g_runTask + str r0, [r1] + + mov r1, #2 + msr CONTROL, r1 + + + 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 OsIntLock, %function + .global OsIntLock +OsIntLock: + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsid I + bx lr + .fnend + + .type OsIntUnLock, %function + .global OsIntUnLock +OsIntUnLock: + .fnstart + .cantunwind + mrs r0, PRIMASK + cpsie I + bx lr + .fnend + + .type OsIntRestore, %function + .global OsIntRestore +OsIntRestore: + .fnstart + .cantunwind + msr PRIMASK, r0 + bx lr + .fnend + + .type OsTaskSchedule, %function + .global OsTaskSchedule +OsTaskSchedule: + .fnstart + .cantunwind + ldr r2, =OS_NVIC_INT_CTRL + ldr r3, =OS_NVIC_PENDSVSET + str r3, [r2] + bx lr + .fnend + + .type osPendSV, %function + .global osPendSV +osPendSV: + .fnstart + .cantunwind + mrs r12, PRIMASK + cpsid I + + +TaskSwitch: + mrs r0, psp + + stmfd r0!, {r4-r12} + vstmdb r0!, {d8-d15} + + ldr r5, =g_oldTask + ldr r1, [r5] + str r0, [r1] + + ldr r0, =g_runTask + ldr r0, [r0] + /* g_oldTask = g_runTask */ + str r0, [r5] + 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-m7/gcc/los_hw_exc.S b/arch/arm/cortex-m/cortex-m7/gcc/los_hw_exc.S new file mode 100644 index 000000000..13b60c6f8 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/gcc/los_hw_exc.S @@ -0,0 +1,335 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: M7 Hw Exc Implementation + * 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. + * --------------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + + .syntax unified + .arch armv7-m + .thumb + .fpu vfpv4 + .section .text + + + .global OsExcNMI + .global OsExcHardFault + .global OsExcMemFault + .global OsExcBusFault + .global OsExcUsageFault + .global OsExcSvcCall + + .extern OsExcHandleEntry + .extern g_excTbl + .extern g_taskScheduled + + .equ OS_EXC_CAUSE_NMI , 16 + .equ OS_EXC_CAUSE_HARDFAULT , 17 + .equ HF_DEBUGEVT , 20 + .equ HF_VECTBL , 21 + .equ OS_EXC_FLAG_FAULTADDR_VALID , 0x10000 + .equ OS_EXC_FLAG_IN_HWI , 0x20000 + .equ OS_EXC_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 + .equ EXCEPT_FRAME_OFFSET_PC , 0x06 * 4 /* see cortex-m7 reference manual: chapter 2.3.7 */ + + .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 + + MRS R2, MSP + LDR R1, [R2, EXCEPT_FRAME_OFFSET_PC] + + 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, #OS_EXC_FLAG_FAULTADDR_VALID + B OsHFExcCommonBMU + .fnend + + .type HFMemFault, %function +HFMemFault: + .fnstart + .cantunwind + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #OS_EXC_FLAG_FAULTADDR_VALID + .fnend + + .type OsHFExcCommonBMU, %function + .global OsHFExcCommonBMU +OsHFExcCommonBMU: + .fnstart + .cantunwind + CLZ R2, R2 + LDR R3, =g_excTbl + 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, #OS_EXC_FLAG_FAULTADDR_VALID + AND R0, #0x1F00 + + B OsExcCommonBMU + .fnend + + .type ExcBusNoAddr, %function +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, #OS_EXC_FLAG_FAULTADDR_VALID + AND R0, #0x1B + + B OsExcCommonBMU + .fnend + + .type ExcMemNoAddr, %function +ExcMemNoAddr: + .fnstart + .cantunwind + MOV R12,#0 + B OsExcCommonBMU + .fnend + + .type OsExcUsageFault, %function + .global OsExcUsageFault +OsExcUsageFault: + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + LDR R1, =#0x030F + LSL R1, #16 + AND R0, R1 + MOV R12, #0 + +OsExcCommonBMU: + CLZ R0, R0 + LDR R3, =g_excTbl + 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, #OS_EXC_FLAG_IN_HWI + RBIT R2, R3 + CLZ R2, R2 + AND R12, #1 + ADD R2, R2, R12, LSL #5 /* calculate R2 (hwi number) as pid, thrid parameter */ + +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, #OS_EXC_FLAG_NO_FLOAT + B HandleEntry + +HwiActiveCheckNext: + 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 scheduled */ + 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, #OS_EXC_FLAG_NO_FLOAT + +HandleEntry: + MOV R3, R13 /* R13:the 4th param */ + CPSID I + CPSID F + B OsExcHandleEntry + + NOP diff --git a/arch/arm/cortex-m/cortex-m7/iar/los_dispatch_iar.S b/arch/arm/cortex-m/cortex-m7/iar/los_dispatch_iar.S new file mode 100644 index 000000000..6ad33eae6 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/iar/los_dispatch_iar.S @@ -0,0 +1,165 @@ +;---------------------------------------------------------------------------- + ; Copyright (c) <2013-2015>, + ; 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. + ;---------------------------------------------------------------------------*/ +;---------------------------------------------------------------------------- + ; Notice of Export Control Law + ; =============================================== + ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might + ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + ; applicable export control laws and regulations. + ;---------------------------------------------------------------------------*/ + + 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-m7/include/core_cm7.h b/arch/arm/cortex-m/cortex-m7/include/core_cm7.h new file mode 100644 index 000000000..8ce007b91 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/include/core_cm7.h @@ -0,0 +1,2669 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 04. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (5U) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB (1U) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/arch/arm/cortex-m/cortex-m7/include/los_armcm.h b/arch/arm/cortex-m/cortex-m7/include/los_armcm.h new file mode 100644 index 000000000..3d003d7e4 --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/include/los_armcm.h @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS adapter CMSIS Core Peripheral Access LayerM7 + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_ARM_CM_H +#define _LOS_ARM_CM_H + +#include "core_cm7.h" + +#endif /* _LOS_ARM_CM_H */ diff --git a/arch/arm/arm-m/cortex-m0/los_exc.ph b/arch/arm/cortex-m/cortex-m7/include/los_exc_pri.h similarity index 50% rename from arch/arm/arm-m/cortex-m0/los_exc.ph rename to arch/arm/cortex-m/cortex-m7/include/los_exc_pri.h index 4d0ca188f..f7e8c10de 100644 --- a/arch/arm/arm-m/cortex-m0/los_exc.ph +++ b/arch/arm/cortex-m/cortex-m7/include/los_exc_pri.h @@ -1,112 +1,170 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_EXC_PH -#define _LOS_EXC_PH - -#include "los_exc.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ -#if (LOSCFG_PLATFORM_EXC == YES) -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 -} EXC_INFO_TYPE; - -typedef struct tagExcInfoCallBackArray -{ - EXC_INFO_TYPE uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -}EXC_INFO_ARRAY_S; - - -#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_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE -#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(EXC_INFO_S) - 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 - -#if (LOSCFG_SAVE_EXC_INFO == YES) -#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) -#else -#define MAX_EXC_MEM_SIZE ( 0 ) -#endif - -extern VOID osExcRegister(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID *pArg); -#endif -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif \ No newline at end of file +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#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 UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID*); + +typedef struct tagExcInfoCallBackArray { + ExcInfoType uwType; + UINT32 uwValid; + EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; + VOID *pArg; +} ExcInfoArray; + +#define MAX_SCENE_INFO_SIZE (8 + sizeof(EXC_INFO_S) - 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); + + +#define OS_EXC_IN_INIT 0 +#define OS_EXC_IN_TASK 1 +#define OS_EXC_IN_HWI 2 + +#define OS_EXC_FLAG_FAULTADDR_VALID 0x01 + +#define OS_EXC_FLAG_IN_HWI 0x02 + +#define OS_EXC_IMPRECISE_ACCESS_ADDR 0xABABABAB + +#define OS_EXC_FLAG_NO_FLOAT 0x10000000 + + +#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_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE +#define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE + +#define OS_EXC_BF_STKERR 1 + +#define OS_EXC_BF_UNSTKERR 2 + +#define OS_EXC_BF_IMPRECISERR 3 + +#define OS_EXC_BF_PRECISERR 4 + +#define OS_EXC_BF_IBUSERR 5 + +#define OS_EXC_MF_MSTKERR 6 + +#define OS_EXC_MF_MUNSTKERR 7 + +#define OS_EXC_MF_DACCVIOL 8 + +#define OS_EXC_MF_IACCVIOL 9 + +#define OS_EXC_UF_DIVBYZERO 10 + +#define OS_EXC_UF_UNALIGNED 11 + +#define OS_EXC_UF_NOCP 12 + +#define OS_EXC_UF_INVPC 13 + +#define OS_EXC_UF_INVSTATE 14 + +#define OS_EXC_UF_UNDEFINSTR 15 + +#define OS_EXC_CAUSE_NMI 16 + +#define OS_EXC_CAUSE_HARDFAULT 17 + +#define OS_EXC_CAUSE_TASK_EXIT 18 + +#define OS_EXC_CAUSE_FATAL_ERR 19 + +#define OS_EXC_CAUSE_DEBUGEVT 20 + +#define OS_EXC_CAUSE_VECTBL 21 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/arch/arm/cortex-m/cortex-m7/keil/los_dispatch_keil.S b/arch/arm/cortex-m/cortex-m7/keil/los_dispatch_keil.S new file mode 100644 index 000000000..37e6be4fc --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/keil/los_dispatch_keil.S @@ -0,0 +1,168 @@ +;---------------------------------------------------------------------------- + ; Copyright (c) <2013-2015>, + ; 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. + ;---------------------------------------------------------------------------*/ +;---------------------------------------------------------------------------- + ; Notice of Export Control Law + ; =============================================== + ; Huawei LiteOS may be subject to applicable export control laws and regulations, which might + ; include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + ; Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + ; applicable export control laws and regulations. + ;---------------------------------------------------------------------------*/ + + 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 + + AREA |.text|, CODE, READONLY + 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 + + ALIGN + END + diff --git a/arch/arm/cortex-m/cortex-m7/los_exc.c b/arch/arm/cortex-m/cortex-m7/los_exc.c new file mode 100644 index 000000000..8137ff88b --- /dev/null +++ b/arch/arm/cortex-m/cortex-m7/los_exc.c @@ -0,0 +1,182 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_exc_pri.h" +#ifdef LOSCFG_LIB_LIBC +#include "string.h" +#endif +#include "los_hwi_pri.h" +#include "los_memcheck_pri.h" +#include "los_tick_pri.h" +#include "securec.h" +#include "core_cm7.h" +#include "los_printf_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define USGFAULT (1U << 18) +#define BUSFAULT (1U << 17) +#define MEMFAULT (1U << 16) +#define DIV0FAULT (1U << 4) +#define HARD_FAULT_IRQN (-13) +#define MASK_16_BIT 16 + +UINT32 g_curNestCount = 0; +EXC_INFO_S g_excInfo; +UINT8 g_excTbl[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 +}; +ExcInfoArray g_excArray[OS_EXC_TYPE_MAX - 1]; +STATIC const CHAR *g_phaseName[] = { + "fault in init", + "fault in task", + "fault in interrupt", +}; + +__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"); +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcInfoDisplay(const EXC_INFO_S *exc) +{ + PrintExcInfo("Phase = %s\n" + "Type = 0x%x\n" + "FaultAddr = 0x%x\n" + "ThrdPid = 0x%x\n" + "R0 = 0x%x\n" + "R1 = 0x%x\n" + "R2 = 0x%x\n" + "R3 = 0x%x\n" + "R4 = 0x%x\n" + "R5 = 0x%x\n" + "R6 = 0x%x\n" + "R7 = 0x%x\n" + "R8 = 0x%x\n" + "R9 = 0x%x\n" + "R10 = 0x%x\n" + "R11 = 0x%x\n" + "R12 = 0x%x\n" + "PriMask = 0x%x\n" + "SP = 0x%x\n" + "LR = 0x%x\n" + "PC = 0x%x\n" + "xPSR = 0x%x\n", + g_phaseName[exc->phase], exc->type, exc->faultAddr, exc->thrdPid, exc->context->uwR0, + exc->context->uwR1, exc->context->uwR2, exc->context->uwR3, exc->context->uwR4, exc->context->uwR5, + exc->context->uwR6, exc->context->uwR7, exc->context->uwR8, exc->context->uwR9, + exc->context->uwR10, exc->context->uwR11, exc->context->uwR12, exc->context->uwPriMask, + exc->context->uwSP, exc->context->uwLR, exc->context->uwPC, exc->context->uwxPSR); + return; +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, + const EXC_CONTEXT_S *excBufAddr) +{ + UINT16 tmpFlag = (excType >> MASK_16_BIT) & OS_NULL_SHORT; /* 2:in intrrupt,1:faul addr valid */ + g_curNestCount++; + g_tickCount[ArchCurrCpuid()]++; + g_excInfo.nestCnt = g_curNestCount; + + g_excInfo.type = excType & OS_NULL_SHORT; + + if (tmpFlag & OS_EXC_FLAG_FAULTADDR_VALID) { + g_excInfo.faultAddr = faultAddr; + } else { + g_excInfo.faultAddr = OS_EXC_IMPRECISE_ACCESS_ADDR; + } + + if (ArchCurrTaskGet() != 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 = ((LosTaskCB *)ArchCurrTaskGet())->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 = (EXC_CONTEXT_S *)excBufAddr; + } + + OsExcInfoDisplay((const EXC_INFO_S *)&g_excInfo); + + while (1) { } +} + +LITE_OS_SEC_TEXT_INIT VOID OsExcInit(VOID) +{ + g_hwiVec[HARD_FAULT_IRQN + OS_SYS_VECTOR_CNT] = OsExcHardFault; + g_hwiVec[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = OsExcNMI; + g_hwiVec[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = OsExcMemFault; + g_hwiVec[BusFault_IRQn + OS_SYS_VECTOR_CNT] = OsExcBusFault; + g_hwiVec[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = OsExcUsageFault; + g_hwiVec[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; +} + +/* stack protector */ +UINT32 __stack_chk_guard = 0xd00a0dff; + +VOID __stack_chk_fail(VOID) +{ + /* __builtin_return_address is a builtin function, building in gcc */ + LOS_Panic("stack-protector: Kernel stack is corrupted in: %p\n", __builtin_return_address(0)); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/cortex-m/include/arch_config.h b/arch/arm/cortex-m/include/arch_config.h new file mode 100644 index 000000000..6d24fd3ba --- /dev/null +++ b/arch/arm/cortex-m/include/arch_config.h @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: Cortex-m Config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _ARCH_CONFIG_H +#define _ARCH_CONFIG_H + +/* Initial bit32 stack value. */ +#define OS_STACK_INIT 0xCACACACA +/* Bit32 stack top magic number. */ +#define OS_STACK_MAGIC_WORD 0xCCCCCCCC + +#endif diff --git a/arch/arm/cortex-m/include/cmsis_compiler.h b/arch/arm/cortex-m/include/cmsis_compiler.h new file mode 100644 index 000000000..79a2cac36 --- /dev/null +++ b/arch/arm/cortex-m/include/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/arch/arm/cortex-m/include/cmsis_gcc.h b/arch/arm/cortex-m/include/cmsis_gcc.h new file mode 100644 index 000000000..df45af943 --- /dev/null +++ b/arch/arm/cortex-m/include/cmsis_gcc.h @@ -0,0 +1,2085 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/arch/arm/cortex-m/include/los_atomic.h b/arch/arm/cortex-m/include/los_atomic.h new file mode 100644 index 000000000..7adcd9947 --- /dev/null +++ b/arch/arm/cortex-m/include/los_atomic.h @@ -0,0 +1,793 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Atomic HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_atomic Atomic + * @ingroup kernel + */ + +#ifndef __LOS_ATOMIC_H__ +#define __LOS_ATOMIC_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef volatile INT32 Atomic; +typedef volatile INT64 Atomic64; + +/** + * @ingroup los_atomic + * @brief Atomic read. + * + * @par Description: + * This API is used to implement the atomic read and return the result value of the read. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    + * + * @param v [IN] The reading pointer. + * + * @retval #INT32 The result value of the read. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v) +{ + return *v; +} + +/** + * @ingroup los_atomic + * @brief Atomic setting. + * + * @par Description: + * This API is used to implement the atomic setting operation. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    + * + * @param v [IN] The variable pointer to be setting. + * @param setVal [IN] The value to be setting. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal) +{ + *v = setVal; +} + +#if __ARM_ARCH >= 7 +/** + * ARMv6-M does not support exclusive access instructions such as LDREX or STREX, or any other atomic swap instruction. + * ARMv7-M does not support LDREXD and STREXD. + * */ +/** + * @ingroup los_atomic + * @brief Atomic addition. + * + * @par Description: + * This API is used to implement the atomic addition and return the result value of the augend. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • If the addtion result is not in the range of representable values for 32-bit signed integer, + * an int integer overflow may occur to the return value
    • + *
    + * + * @param v [IN] The augend pointer. + * @param addVal [IN] The addend. + * + * @retval #INT32 The result value of the augend. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %1, [%2]\n" + "add %1, %1, %3\n" + "strex %0, %1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(addVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic subtraction. + * + * @par Description: + * This API is used to implement the atomic subtraction and return the result value of the minuend. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • If the subtraction result is not in the range of representable values for 32-bit signed integer, + * an int integer overflow may occur to the return value
    • + *
    + * + * @param v [IN] The minuend pointer. + * @param subVal [IN] The subtrahend. + * + * @retval #INT32 The result value of the minuend. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %1, [%2]\n" + "sub %1, %1, %3\n" + "strex %0, %1, [%2]" + : "=&r"(status), "=&r"(val) + : "r"(v), "r"(subVal) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic addSelf. + * + * @par Description: + * This API is used to implement the atomic addSelf. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MAX to avoid integer overflow after adding 1.
    • + *
    + * + * @param v [IN] The addSelf variable pointer. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_AtomicInc(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "add %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic addSelf. + * + * @par Description: + * This API is used to implement the atomic addSelf and return the result of addSelf. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MAX to avoid integer overflow after adding 1.
    • + *
    + * + * @param v [IN] The addSelf variable pointer. + * + * @retval #INT32 The return value of variable addSelf. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicIncRet(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "add %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic auto-decrement. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MIN to avoid overflow after reducing 1.
    • + *
    + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval none. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE VOID LOS_AtomicDec(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); +} + +/** + * @ingroup los_atomic + * @brief Atomic auto-decrement. + * + * @par Description: + * This API is used to implementating the atomic auto-decrement and return the result of auto-decrement. + * @attention + *
      + *
    • The pointer v must not be NULL.
    • + *
    • The value which v point to must not be INT_MIN to avoid overflow after reducing 1.
    • + *
    + * + * @param v [IN] The auto-decrement variable pointer. + * + * @retval #INT32 The return value of variable auto-decrement. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v) +{ + INT32 val; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "sub %0, %0, #1\n" + "strex %1, %0, [%3]" + : "=&r"(val), "=&r"(status), "+m"(*v) + : "r"(v) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return val; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 8-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 8-bit variable and + * return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicXchgByte(volatile INT8 *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexb %0, [%3]\n" + "strexb %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 16-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 16-bit variable and + * return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE INT32 LOS_AtomicXchg16bits(volatile INT16 *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrexh %0, [%3]\n" + "strexh %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable + * and return the previous value of the atomic variable. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The exchange value. + * + * @retval #INT32 The previous value of the atomic variable + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("ldrex %0, [%3]\n" + "strex %1, %4, [%3]" + : "=&r"(prevVal), "=&r"(status), "+m"(*v) + : "r"(v), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 8-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 8-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchgByte(volatile INT8 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("1: ldrexb %0, %2\n" + " mov %1, #0\n" + " cmp %0, %3\n" + " bne 2f\n" + " strexb %1, %4, %2\n" + "2:" + : "=&r"(prevVal), "=&r"(status), "+Q"(*v) + : "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 16-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 16-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg16bits(volatile INT16 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("1: ldrexh %0, %2\n" + " mov %1, #0\n" + " cmp %0, %3\n" + " bne 2f\n" + " strexh %1, %4, %2\n" + "2:" + : "=&r"(prevVal), "=&r"(status), "+Q"(*v) + : "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +/** + * @ingroup los_atomic + * @brief Atomic exchange for 32-bit variable with compare. + * + * @par Description: + * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to oldVal. + * @attention + *
      The pointer v must not be NULL.
    + * + * @param v [IN] The variable pointer. + * @param val [IN] The new value. + * @param oldVal [IN] The old value. + * + * @retval TRUE The previous value of the atomic variable is not equal to oldVal. + * @retval FALSE The previous value of the atomic variable is equal to oldVal. + * @par Dependency: + *
    • los_atomic.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 status; + + do { + __asm__ __volatile__("1: ldrex %0, %2\n" + " mov %1, #0\n" + " cmp %0, %3\n" + " bne 2f\n" + " strex %1, %4, %2\n" + "2:" + : "=&r"(prevVal), "=&r"(status), "+Q"(*v) + : "r"(oldVal), "r"(val) + : "cc"); + } while (__builtin_expect(status != 0, 0)); + + return prevVal != oldVal; +} + +#else /* __ARM_ARCH < 7 */ + +STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal) +{ + INT32 val; + UINT32 intSave; + + intSave = LOS_IntLock(); + *v += addVal; + val = *v; + LOS_IntRestore(intSave); + + return val; +} + +STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal) +{ + INT32 val; + UINT32 intSave; + + intSave = LOS_IntLock(); + *v -= subVal; + val = *v; + LOS_IntRestore(intSave); + + return val; +} + +STATIC INLINE VOID LOS_AtomicInc(Atomic *v) +{ + (VOID)LOS_AtomicAdd(v, 1); +} + +STATIC INLINE VOID LOS_AtomicDec(Atomic *v) +{ + (VOID)LOS_AtomicSub(v, 1); +} + +STATIC INLINE INT32 LOS_AtomicIncRet(Atomic *v) +{ + return LOS_AtomicAdd(v, 1);; +} + +STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v) +{ + return LOS_AtomicSub(v, 1);; +} + +STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v) +{ + INT64 val; + UINT32 intSave; + + intSave = LOS_IntLock(); + val = *v; + LOS_IntRestore(intSave); + + return val; +} + +STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal) +{ + UINT32 intSave; + + intSave = LOS_IntLock(); + *v = setVal; + LOS_IntRestore(intSave); +} + +STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal) +{ + INT64 val; + UINT32 intSave; + + intSave = LOS_IntLock(); + *v += addVal; + val = *v; + LOS_IntRestore(intSave); + + return val; +} + +STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal) +{ + INT64 val; + UINT32 intSave; + + intSave = LOS_IntLock(); + *v -= subVal; + val = *v; + LOS_IntRestore(intSave); + + return val; +} + +STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v) +{ + (VOID)LOS_Atomic64Add(v, 1); +} + +STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v) +{ + return LOS_Atomic64Add(v, 1); +} + +STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v) +{ + (VOID)LOS_Atomic64Sub(v, 1); +} + +STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v) +{ + return LOS_Atomic64Sub(v, 1); +} + +STATIC INLINE INT32 LOS_AtomicXchgByte(volatile INT8 *v, INT32 val) +{ + UINT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + /* In order to avoid sign extension instructions, first cast the data to unsigned data! */ + prevVal = (UINT32)*(volatile UINT8 *)v; + *v = (INT8)val; + LOS_IntRestore(intSave); + + return (INT32)prevVal; +} + +STATIC INLINE INT32 LOS_AtomicXchg16bits(volatile INT16 *v, INT32 val) +{ + UINT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + /* In order to avoid sign extension instructions, first cast the data to unsigned data! */ + prevVal = (UINT32)*(volatile UINT16 *)v; + *v = (INT16)val; + LOS_IntRestore(intSave); + + return (INT32)prevVal; +} + +STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val) +{ + INT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + prevVal = *v; + *v = val; + LOS_IntRestore(intSave); + + return prevVal; +} + +STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val) +{ + INT64 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + prevVal = *v; + *v = val; + LOS_IntRestore(intSave); + + return prevVal; +} + +STATIC INLINE BOOL LOS_AtomicCmpXchgByte(volatile INT8 *v, INT32 val, INT32 oldVal) +{ + UINT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + /* In order to avoid sign extension instructions, first cast the data to unsigned data! */ + prevVal = (UINT32)*(volatile UINT8 *)v; + if (prevVal == (UINT32)oldVal) { + *v = (INT8)val; + } + LOS_IntRestore(intSave); + + return prevVal != (UINT32)oldVal; +} + +STATIC INLINE BOOL LOS_AtomicCmpXchg16bits(volatile INT16 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + /* In order to avoid sign extension instructions, first cast the data to unsigned data! */ + prevVal = (UINT32)*(volatile UINT16 *)v; + if (prevVal == (UINT32)oldVal) { + *v = val; + } + LOS_IntRestore(intSave); + + return prevVal != (UINT32)oldVal; +} + +STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + prevVal = *v; + if (prevVal == oldVal) { + *v = val; + } + LOS_IntRestore(intSave); + + return prevVal != oldVal; +} + +STATIC INLINE BOOL LOS_AtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal) +{ + INT64 prevVal; + UINT32 intSave; + + intSave = LOS_IntLock(); + prevVal = *v; + if (prevVal == oldVal) { + *v = val; + } + LOS_IntRestore(intSave); + + return prevVal != oldVal; +} +#endif /* __ARM_ARCH */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_ATOMIC_H__ */ diff --git a/arch/arm/cortex-m/include/los_exc.h b/arch/arm/cortex-m/include/los_exc.h new file mode 100644 index 000000000..140f3696d --- /dev/null +++ b/arch/arm/cortex-m/include/los_exc.h @@ -0,0 +1,377 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: Exception Handler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_EXC_H +#define _LOS_EXC_H + +#include "los_hwi_pri.h" +#include "los_task_pri.h" +#include "los_queue.h" +#include "los_config.h" + +#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 + +#define FAULT_STATUS_REG_BIT 32 +/** + *@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 VOID (* EXC_PROC_FUNC)(UINT32, EXC_CONTEXT_S *); +VOID OsExcHandleEntry(UINT32 uwExcType, UINT32 uwFaultAddr, UINT32 uwPid, const EXC_CONTEXT_S * pstExcBufAddr); + +/** + * @ingroup los_hwi + * @brief: Exception initialization. + * + * @par Description: + * This API is used to configure the exception function vector table. + * + * @attention: + *
    • None.
    + * + * @param None. + * + * @retval: None + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +VOID OsExcInit(VOID); + +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 m_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. + *@since Huawei LiteOS V100R001C00 +*/ +void LOS_Panic(const char *fmt, ...); + +/** + * @ingroup los_exc + * Cortex-M3:bus fault err in stack + */ +#define OS_EXC_BF_STKERR 1 + +/** + * @ingroup los_exc + * Cortex-M3:bus fault err out stack + */ +#define OS_EXC_BF_UNSTKERR 2 + +/** + * @ingroup los_exc + * Cortex-M3:bus fault err imprecise access + */ +#define OS_EXC_BF_IMPRECISERR 3 + +/** + * @ingroup los_exc + * Cortex-M3:bus fault err precise access + */ +#define OS_EXC_BF_PRECISERR 4 + +/** + * @ingroup los_exc + * Cortex-M3:bus fault err ibus + */ +#define OS_EXC_BF_IBUSERR 5 + +/** + * @ingroup los_exc + * Cortex-M3:mem fault err for manager resiter in stack + */ +#define OS_EXC_MF_MSTKERR 6 + +/** + * @ingroup los_exc + * Cortex-M3:mem fault err for manager resiter out stack + */ +#define OS_EXC_MF_MUNSTKERR 7 + +/** + * @ingroup los_exc + * Cortex-M3:mem fault err for data access invalid + */ +#define OS_EXC_MF_DACCVIOL 8 + +/** + * @ingroup los_exc + * Cortex-M3:mem fault err for instruction access invalid + */ +#define OS_EXC_MF_IACCVIOL 9 + + +/** + * @ingroup los_exc + * Cortex-M3: divide zero err + */ +#define OS_EXC_UF_DIVBYZERO 10 + +/** + * @ingroup los_exc + * Cortex-M3: data unaligned err + */ +#define OS_EXC_UF_UNALIGNED 11 + +/** + * @ingroup los_exc + * Cortex-M3: no co-processor err + */ +#define OS_EXC_UF_NOCP 12 + +/** + * @ingroup los_exc + * Cortex-M3: invalid PC err + */ +#define OS_EXC_UF_INVPC 13 + +/** + * @ingroup los_exc + * Cortex-M3:invalid state err + */ +#define OS_EXC_UF_INVSTATE 14 + +/** + * @ingroup los_exc + * Cortex-M3:undefined instruction err + */ +#define OS_EXC_UF_UNDEFINSTR 15 + +/** + * @ingroup los_exc + * Cortex-M3: nu-masked interrupt + */ +#define OS_EXC_CAUSE_NMI 16 + +/** + * @ingroup los_exc + * Cortex-M3: hardware fault + */ +#define OS_EXC_CAUSE_HARDFAULT 17 + +/** + * @ingroup los_exc + * Cortex-M3:task exit err + */ +#define OS_EXC_CAUSE_TASK_EXIT 18 + +/** + * @ingroup los_exc + * Cortex-M3:fatal err + */ +#define OS_EXC_CAUSE_FATAL_ERR 19 + +/** + * @ingroup los_exc + * Cortex-M3: debug event trigger hardware interrupt err + */ +#define OS_EXC_CAUSE_DEBUGEVT 20 + +/** + * @ingroup los_exc + * Cortex-M3:access vector trigger hardware interrupt err + */ +#define OS_EXC_CAUSE_VECTBL 21 + + +typedef struct tagExcInfo { + UINT16 phase; /* Phase in which an exception occurs: + * 0 means that the exception occurred during initialization, + * 1 means that the exception occurred in the task, + * 2 means that the exception occurred in the interrupt. + */ + UINT16 type; /* Exception type */ + UINT32 faultAddr; /* The wrong access address when the exception occurred */ + UINT32 thrdPid; /* An exception occurred during the interrupt indicating the interrupt number, + * An exception occurs in the task, indicating the task id, + * If it occurs in the initialization, it is 0xffffffff + */ + UINT16 nestCnt; /* Count of nested exception */ + UINT16 reserved; /* Reserved for alignment */ + EXC_CONTEXT_S *context; /* Hardware context when an exception occurs */ +} EXC_INFO_S; + +extern UINT32 g_curNestCount; +extern UINT32 g_intCount[]; +extern EXC_INFO_S m_stExcInfo; + +VOID OsExcInfoDisplay(const EXC_INFO_S *exc); + +extern UINT8 g_uwExcTbl[32]; + +/** + * @ingroup los_exc + * @brief Kernel task backtrace function. + * + * @par Description: + * Backtrace function that prints task call stack information traced from the input task. + * @attention + *
      + *
    • The input taskID should be valid.
    • + *
    + * + * @param taskID [IN] Type #UINT32 Task ID. + * + * @retval #None. + * + * @par Dependency: + * los_exc.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsTaskBackTrace(UINT32 taskID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_EXC_H */ + diff --git a/arch/arm/cortex-m/include/los_hw_cpu.h b/arch/arm/cortex-m/include/los_hw_cpu.h new file mode 100644 index 000000000..21f4cb915 --- /dev/null +++ b/arch/arm/cortex-m/include/los_hw_cpu.h @@ -0,0 +1,111 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: cortex-m Hw CPU HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ + +#ifndef __LOS_HW_CPU_H__ +#define __LOS_HW_CPU_H__ + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define CPUID_BASE 0xE000ED00 /* Main ID Register */ +#define ARM_SYSREG_READ(addr) (*(volatile unsigned *)(uintptr_t)(addr)) + +extern VOID *g_runTask; +extern VOID *g_oldTask; +STATIC INLINE VOID *ArchCurrTaskGet(VOID) +{ + return g_runTask; +} + +STATIC INLINE VOID ArchCurrTaskSet(VOID* val) +{ + g_runTask = val; +} + +STATIC INLINE UINT32 ArchCurrCpuid(void) +{ + return 0; +} + + +STATIC INLINE UINT32 OsMainIDGet(VOID) +{ + return ARM_SYSREG_READ(CPUID_BASE); +} + +STATIC INLINE UINT32 ArchSPGet(VOID) +{ + UINT32 val; + asm volatile("mov %0, sp" : "=r"(val)); + return val; +} + +STATIC INLINE UINT32 OsIntLocked(VOID) +{ + UINT32 intSave; + + asm volatile( + "mrs %0, primask " + : "=r" (intSave) + : + : "memory"); + + return intSave; +} + +extern UINT32 OsIntUnLock(VOID); +extern UINT32 OsIntLock(VOID); +extern VOID OsIntRestore(UINT32 uvIntSave); + +#define ArchIntLock() OsIntLock() +#define ArchIntUnlock() OsIntUnLock() +#define ArchIntRestore(intSave) OsIntRestore(intSave) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* __LOS_HW_CPU_H__ */ diff --git a/arch/arm/cortex-m/include/los_hwi_pri.h b/arch/arm/cortex-m/include/los_hwi_pri.h new file mode 100644 index 000000000..07a65e560 --- /dev/null +++ b/arch/arm/cortex-m/include/los_hwi_pri.h @@ -0,0 +1,362 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: hwi cortex-m + * 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. + * --------------------------------------------------------------------------- */ +/*---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + *---------------------------------------------------------------------------*/ + +/** + * @defgroup los_hwi Hardware interrupt + * @ingroup kernel + */ +#ifndef _LOS_HWI_M_H +#define _LOS_HWI_M_H + +#include "los_base.h" +#include "los_sys.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_PLATFORM_HWI == YES) +/** + * @ingroup los_hwi + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM 32 +#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 + * Count of M-Core system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 16 + +/** + * @ingroup los_hwi + * AIRCR register priority group parameter . + */ +#define OS_NVIC_AIRCR_PRIGROUP 7 +#endif + +/** + * @ingroup los_hwi + * SysTick control and status register. + */ +#define OS_SYSTICK_CONTROL_REG 0xE000E010 + +/** + * @ingroup los_hw + * SysTick reload value register. + */ +#define OS_SYSTICK_RELOAD_REG 0xE000E014 + +/** + * @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 activity status 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 + +#if (LOSCFG_PLATFORM_HWI == YES) +/** + * @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 + +extern HWI_HANDLE_FORM_S g_hwiForm[OS_HWI_MAX_NUM + OS_SYS_VECTOR_CNT]; + +/** + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiVec[OS_VECTOR_CNT]; +extern VOID IrqEntryV7M(VOID); +#if (OS_HWI_WITH_ARG == YES) +/** + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVector(num, vector, arg) do { \ + g_hwiVec[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)IrqEntryV7M;\ + g_hwiForm[num + OS_SYS_VECTOR_CNT].pfnHook = vector; \ + g_hwiForm[num + OS_SYS_VECTOR_CNT].uwParam = (VOID*)arg; \ +} while (0) +#else +/** + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVector(num, vector) do { \ + g_hwiVec[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)IrqEntryV7M;\ + g_hwiForm[num + OS_SYS_VECTOR_CNT].pfnHook = vector; \ +} while (0) +#endif + +extern VOID OsInterrupt(UINT32 intNum); + +extern VOID OsHwiInit(VOID); +#endif + +/** + * @ingroup los_hwi + * @brief: Default vector handling function. + * + * @par Description: + * This API is used to configure interrupt for null function. + * + * @attention: + *
    • None.
    + * + * @param:None. + * + * @retval:None. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsHwiDefaultHandler(VOID); + +/** + * @ingroup los_hwi + * @brief: Reset the vector table. + * + * @par Description: + * This API is used to reset the vector table. + * + * @attention: + *
    • None.
    + * + * @param:None. + * + * @retval:None. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +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: + *
    • None.
    + * + * @param:None. + * + * @retval:None. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID osPendSV(VOID); + +extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); + +#if (LOSCFG_PLATFORM_HWI == NO) +extern BOOL OsIntActive(VOID); +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _LOS_HWI_M_H */ diff --git a/arch/arm/cortex-m/include/mpu_armv7.h b/arch/arm/cortex-m/include/mpu_armv7.h new file mode 100644 index 000000000..be73de161 --- /dev/null +++ b/arch/arm/cortex-m/include/mpu_armv7.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if non-shareable) or 010b (if shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/arch/arm/arm-m/include/los_hw.h b/arch/arm/cortex-m/src/include/los_hw_pri.h similarity index 52% rename from arch/arm/arm-m/include/los_hw.h rename to arch/arm/cortex-m/src/include/los_hw_pri.h index 7be91f666..305298efb 100644 --- a/arch/arm/arm-m/include/los_hw.h +++ b/arch/arm/cortex-m/src/include/los_hw_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Cortex-M Hw Inner HeadFile * 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 @@ -22,24 +22,19 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ - /**@defgroup los_hw hardware - *@ingroup kernel - */ - -#ifndef _LOS_HW_H -#define _LOS_HW_H +#ifndef _LOS_HW_PRI_H +#define _LOS_HW_PRI_H -#include "los_base.h" #ifdef __cplusplus #if __cplusplus extern "C" { @@ -58,28 +53,30 @@ extern "C" { */ #define osTaskTrap() __asm(" TRAP #31") -/** - * @ingroup los_hw - * Check task schedule. - */ -#define LOS_CHECK_SCHEDULE ((!g_usLosTaskLock)) - -/** - * @ingroup los_hw - * FPU exist macro: If it exist, save EXC_RETURN value in the context of the task to check - * the size of the stack frame(BIT_4: 1 ---> 8 words, 0 ---> 26 wrods) used by the task. - */ -#define FPU_EXIST ( (defined ( __CC_ARM ) && defined ( __TARGET_FPU_VFP )) \ - || (defined ( __ICCARM__ ) && defined ( __ARMVFP__ )) \ - || (defined ( __GNUC__ ) && defined ( __VFP_FP__ ) && !defined( __SOFTFP__ )) ) - - /** * @ingroup los_hw * Define the type of a task context control block. */ -typedef struct tagTskContext -{ +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; @@ -89,9 +86,6 @@ typedef struct tagTskContext UINT32 uwR10; UINT32 uwR11; UINT32 uwPriMask; -#if FPU_EXIST - UINT32 uwExcReturn; -#endif UINT32 uwR0; UINT32 uwR1; UINT32 uwR2; @@ -100,10 +94,30 @@ typedef struct tagTskContext 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 } TSK_CONTEXT_S; - /** * @ingroup los_hw * @brief: Task stack initialization. @@ -114,83 +128,23 @@ typedef struct tagTskContext * @attention: *
    • None.
    * - * @param uwTaskID [IN] Type#UINT32: TaskID. - * @param uwStackSize [IN] Type#UINT32: Total size of the stack. - * @param pTopStack [IN] Type#VOID *: Top of task's stack. + * @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: pstContext Type#TSK_CONTEXT_S *. * @par Dependency: - *
    • los_hw.h: the header file that contains the API declaration.
    + *
    • los_hw_pri.h: the header file that contains the API declaration.
    * @see None. * @since Huawei LiteOS V100R001C00 */ -extern VOID * osTskStackInit(UINT32 uwTaskID, UINT32 uwStackSize, VOID *pTopStack); - - +extern VOID* OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack); /** - * @ingroup los_hw - * @brief: Task scheduling Function. - * - * @par Description: - * This API is used to scheduling task. - * - * @attention: - *
    • None.
    - * - * @param None. - * - * @retval: None. - * @par Dependency: - *
    • los_hw.h: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 - */ -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: - *
    • None.
    - * - * @param None. - * - * @retval: None. - * @par Dependency: - *
    • los_hw.h: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern VOID LOS_Schedule(VOID); - -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: - *
    • None.
    - * - * @param None. - * - * @retval: None. - * @par Dependency: - *
    • los_hw.h: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 + * @ingroup los_hw + * Disable IRQ Interrupts. */ - -extern VOID osEnterSleep(VOID); +extern VOID __disable_irq(void); #ifdef __cplusplus #if __cplusplus @@ -198,6 +152,5 @@ extern VOID osEnterSleep(VOID); #endif /* __cplusplus */ #endif /* __cplusplus */ - -#endif /* _LOS_HW_H */ +#endif /* _LOS_HW_PRI_H */ diff --git a/arch/arm/arm-m/src/los_hw.c b/arch/arm/cortex-m/src/los_hw.c similarity index 62% rename from arch/arm/arm-m/src/los_hw.c rename to arch/arm/cortex-m/src/los_hw.c index 22c625f24..9d7d1ed17 100644 --- a/arch/arm/arm-m/src/los_hw.c +++ b/arch/arm/cortex-m/src/los_hw.c @@ -1,165 +1,166 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_base.h" -#include "los_task.ph" -#include "los_hw.h" -#include "los_priqueue.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -/***************************************************************************** - Function : osSchedule - Description : task scheduling - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osSchedule(VOID) -{ - osTaskSchedule(); -} - -/***************************************************************************** - Function : LOS_Schedule - Description : Function to determine whether task scheduling is required - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID LOS_Schedule(VOID) -{ - UINTPTR uvIntSave; - - uvIntSave = LOS_IntLock(); - - /* Find the highest task */ - g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList); - - /* In case that running is not highest then reschedule */ - if (g_stLosTask.pstRunTask != g_stLosTask.pstNewTask) - { - if ((!g_usLosTaskLock)) - { - (VOID)LOS_IntRestore(uvIntSave); - - osTaskSchedule(); - - return; - } - } - - (VOID)LOS_IntRestore(uvIntSave); -} - -/***************************************************************************** - Function : osTaskExit - Description : Task exit function - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID osTaskExit(VOID) +/*---------------------------------------------------------------------------- + * Copyright (c) <2013-2018>, + * 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. + *---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + *---------------------------------------------------------------------------*/ + +#include "los_base.h" +#include "los_hw_pri.h" +#include "los_task_pri.h" +#include "los_hw.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +VOID *g_runTask = NULL; +VOID *g_oldTask = NULL; + +/* support cpu vendors */ +CpuVendor g_cpuTable[] = { + /* armv7-m */ + { 0xC20, "Cortex-M0" }, + { 0xC21, "Cortex-M1" }, + { 0xC23, "Cortex-M3" }, + { 0xC24, "Cortex-M4" }, + { 0xC27, "Cortex-M7" }, + { 0xD21, "Cortex-M33" }, + { 0, NULL } +}; + +/***************************************************************************** + 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 : uwTaskID --- TaskID - uwStackSize --- Total size of the stack - pTopStack --- Top of task's stack - Output : None - Return : Context pointer - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID *osTskStackInit(UINT32 uwTaskID, UINT32 uwStackSize, VOID *pTopStack) -{ - TSK_CONTEXT_S *pstContext; - - /*initialize the task stack, write magic num to stack top*/ - memset(pTopStack, OS_TASK_STACK_INIT, uwStackSize); - *((UINT32 *)(pTopStack)) = OS_TASK_MAGIC_WORD; - - pstContext = (TSK_CONTEXT_S *)(((UINT32)pTopStack + uwStackSize) - sizeof(TSK_CONTEXT_S)); - - pstContext->uwR4 = 0x04040404L; - pstContext->uwR5 = 0x05050505L; - pstContext->uwR6 = 0x06060606L; - pstContext->uwR7 = 0x07070707L; - pstContext->uwR8 = 0x08080808L; - pstContext->uwR9 = 0x09090909L; - pstContext->uwR10 = 0x10101010L; - pstContext->uwR11 = 0x11111111L; - /* The initial interruption state(PRIMASK value: 0 --- enable) of the task */ - pstContext->uwPriMask = 0; -#if FPU_EXIST - /** - * The initial EXC_RETURN value(use 8 word stack frame, return to thread mode and use PSP). - * Please do not modify it. - */ - pstContext->uwExcReturn = 0xFFFFFFFD; -#endif - pstContext->uwR0 = uwTaskID; - pstContext->uwR1 = 0x01010101L; - pstContext->uwR2 = 0x02020202L; - pstContext->uwR3 = 0x03030303L; - pstContext->uwR12 = 0x12121212L; - pstContext->uwLR = (UINT32)osTaskExit; - pstContext->uwPC = (UINT32)osTaskEntry; - pstContext->uwxPSR = 0x01000000L; - - return (VOID *)pstContext; -} - -LITE_OS_SEC_TEXT_INIT VOID osEnterSleep(VOID) -{ - __DSB(); - __WFI(); - __ISB(); -} - -#ifdef __cplusplus -#if __cplusplus + while (1) { } } -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - + +/***************************************************************************** + Function : OsTaskStackInit + Description : Task stack initialization function + Input : taskID --- TaskID + uwStackSize --- Total size of the stack + pTopStack --- Top of task's stack + Output : None + Return : Context pointer + *****************************************************************************/ +LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 uwStackSize, VOID *pTopStack) +{ + TSK_CONTEXT_S *pstContext; + + OsStackInit(pTopStack, uwStackSize); + pstContext = (TSK_CONTEXT_S *)(((UINT32)pTopStack + uwStackSize) - sizeof(TSK_CONTEXT_S)); + +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED) && (__FPU_USED == 1U))) + pstContext->S16 = 0xAA000010; + pstContext->S17 = 0xAA000011; + pstContext->S18 = 0xAA000012; + pstContext->S19 = 0xAA000013; + pstContext->S20 = 0xAA000014; + pstContext->S21 = 0xAA000015; + pstContext->S22 = 0xAA000016; + pstContext->S23 = 0xAA000017; + pstContext->S24 = 0xAA000018; + pstContext->S25 = 0xAA000019; + pstContext->S26 = 0xAA00001A; + pstContext->S27 = 0xAA00001B; + pstContext->S28 = 0xAA00001C; + pstContext->S29 = 0xAA00001D; + pstContext->S30 = 0xAA00001E; + pstContext->S31 = 0xAA00001F; + pstContext->S0 = 0xAA000000; + pstContext->S1 = 0xAA000001; + pstContext->S2 = 0xAA000002; + pstContext->S3 = 0xAA000003; + pstContext->S4 = 0xAA000004; + pstContext->S5 = 0xAA000005; + pstContext->S6 = 0xAA000006; + pstContext->S7 = 0xAA000007; + pstContext->S8 = 0xAA000008; + pstContext->S9 = 0xAA000009; + pstContext->S10 = 0xAA00000A; + pstContext->S11 = 0xAA00000B; + pstContext->S12 = 0xAA00000C; + pstContext->S13 = 0xAA00000D; + pstContext->S14 = 0xAA00000E; + pstContext->S15 = 0xAA00000F; + pstContext->FPSCR = 0x00000000; + pstContext->NO_NAME = 0xAA000011; +#endif + + pstContext->uwR4 = 0x04040404L; + pstContext->uwR5 = 0x05050505L; + pstContext->uwR6 = 0x06060606L; + pstContext->uwR7 = 0x07070707L; + pstContext->uwR8 = 0x08080808L; + pstContext->uwR9 = 0x09090909L; + pstContext->uwR10 = 0x10101010L; + pstContext->uwR11 = 0x11111111L; + pstContext->uwPriMask = 0; + pstContext->uwR0 = taskID; + pstContext->uwR1 = 0x01010101L; + pstContext->uwR2 = 0x02020202L; + pstContext->uwR3 = 0x03030303L; + pstContext->uwR12 = 0x12121212L; + pstContext->uwLR = (UINT32)OsTaskExit; + pstContext->uwPC = (UINT32)OsTaskEntry; + pstContext->uwxPSR = 0x01000000L; + + return (VOID *)pstContext; +} + +VOID wfi(VOID) +{ + __asm__ __volatile__ ("wfi"); +} + +VOID dsb(VOID) +{ + __asm__ __volatile__ ("dsb 0xF":::"memory"); +} + + +#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 100644 index 000000000..dbc82a8ba --- /dev/null +++ b/arch/arm/cortex-m/src/los_hw_tick.c @@ -0,0 +1,169 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: hw_tick + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_hwi_pri.h" +#include "los_tick_pri.h" +#include "los_base.h" +#include "los_task_pri.h" +#include "los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define CYCLE_REG_MASK 0xFFFFFFFFU + +#define TICK_INTR_CHECK 0x4000000U + +#define OS_CYCLE_PER_TICK (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +LITE_OS_SEC_BSS UINT32 g_cyclesPerTick; + +LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond) +{ + return LOS_OK; +} + +/* + * Description : Configure Tick Interrupt Start + * return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed + */ +LITE_OS_SEC_TEXT_INIT VOID OsTickStart(VOID) +{ + if ((OS_SYS_CLOCK == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) { + return; + } + +#if (LOSCFG_PLATFORM_HWI == YES) +#if (OS_HWI_WITH_ARG == YES) + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)OsTickHandler, NULL); +#else + OsSetVector(SysTick_IRQn, OsTickHandler); +#endif +#endif + + g_cyclesPerTick = OS_CYCLE_PER_TICK; + + (VOID)SysTick_Config(OS_CYCLE_PER_TICK); + + return; +} + +/* + * Description : Get System cycle count + * output : highCnt --- CpuTick High 4 byte + * lowCnt --- CpuTick Low 4 byte + */ +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINT32 intSave; + + if ((highCnt == NULL) || (lowCnt == NULL)) { + return; + } + + intSave = LOS_IntLock(); + + swTick = LOS_TickCountGet(); + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response */ + if ((SCB->ICSR & TICK_INTR_CHECK) != 0) { + hwCycle = SysTick->VAL; + swTick++; + } + + cycle = (swTick * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle); + LOS_IntRestore(intSave); + + *highCnt = cycle >> 32; /* 32:get high 32 bits */ + *lowCnt = cycle & CYCLE_REG_MASK; + + return; +} + +/* + * Description : Get Sys tick cycle count + * output : highCnt --- SysTick count High 4 byte + * lowCnt --- SysTick count Low 4 byte + */ +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetSystickCycle(UINT32 *highCnt, UINT32 *lowCnt) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINT32 intSave; + UINT32 systickLoad; + UINT32 systickCur; + + if ((highCnt == NULL) || (lowCnt == NULL)) { + return; + } + + intSave = LOS_IntLock(); + + swTick = LOS_TickCountGet(); + + systickLoad = SysTick->LOAD; + systickCur = SysTick->VAL; + hwCycle = systickLoad - systickCur; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response */ + if ((SCB->ICSR & TICK_INTR_CHECK) != 0) { + hwCycle = systickLoad - systickCur; + swTick++; + } + + cycle = swTick * systickLoad + hwCycle; + + LOS_IntRestore(intSave); + + *highCnt = cycle >> 32; /* 32:get high 32 bits */ + *lowCnt = cycle & CYCLE_REG_MASK; + + return; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/arm-m/src/los_hwi.c b/arch/arm/cortex-m/src/los_hwi_m.c similarity index 50% rename from arch/arm/arm-m/src/los_hwi.c rename to arch/arm/cortex-m/src/los_hwi_m.c index 57770eb51..3e104cc09 100644 --- a/arch/arm/arm-m/src/los_hwi.c +++ b/arch/arm/cortex-m/src/los_hwi_m.c @@ -1,296 +1,225 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_hwi.h" -#if (LOSCFG_KERNEL_TICKLESS == YES) -#include "los_tickless.ph" -#endif -#if (LOSCFG_PLATFORM_HWI == NO) -#include "los_tick.ph" -#endif - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#if (LOSCFG_PLATFORM_HWI == YES) - -/*lint -save -e40 -e522 -e533*/ - -LITE_OS_SEC_DATA_INIT 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 m_pstHwiForm[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)PendSV_Handler, // [14] PendSV Handler - (HWI_PROC_FUNC)osHwiDefaultHandler, // [15] SysTick Handler -}; -#if (OS_HWI_WITH_ARG == YES) -LITE_OS_SEC_DATA_INIT HWI_SLAVE_FUNC m_pstHwiSlaveForm[OS_VECTOR_CNT] = {{(HWI_PROC_FUNC)0,(HWI_ARG_T)0}}; -#else -LITE_OS_SEC_DATA_INIT HWI_PROC_FUNC m_pstHwiSlaveForm[OS_VECTOR_CNT] = {0}; -#endif - -#endif /*(LOSCFG_PLATFORM_HWI == YES)*/ - -/***************************************************************************** - 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(); -} - -#if (LOSCFG_PLATFORM_HWI == YES) -/***************************************************************************** - 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 uwIrqNum = osIntNumGet(); - PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, uwIrqNum); - while(1); -} - -/***************************************************************************** - Function : osInterrupt - Description : Hardware interrupt entry function - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osInterrupt(VOID) -{ - UINT32 uwHwiIndex; - UINT32 uwIntSave; - -#if(LOSCFG_KERNEL_RUNSTOP == YES) - SCB->SCR &= (UINT32)~((UINT32)SCB_SCR_SLEEPDEEP_Msk); -#endif - - uwIntSave = LOS_IntLock(); - - g_vuwIntCount++; - - LOS_IntRestore(uwIntSave); - - uwHwiIndex = osIntNumGet(); -#if (LOSCFG_KERNEL_TICKLESS == YES) - osUpdateKernelTickCount(uwHwiIndex); -#endif - -#if (OS_HWI_WITH_ARG == YES) - if (m_pstHwiSlaveForm[uwHwiIndex].pfnHandler!=0) - { - m_pstHwiSlaveForm[uwHwiIndex].pfnHandler((VOID*)m_pstHwiSlaveForm[uwHwiIndex].pParm); - } -#else - if (m_pstHwiSlaveForm[uwHwiIndex] !=0) - { - m_pstHwiSlaveForm[uwHwiIndex](); - } -#endif - uwIntSave = LOS_IntLock(); - - g_vuwIntCount--; - - LOS_IntRestore(uwIntSave); - -} -/***************************************************************************** - Function : osHwiInit - Description : initialization of the hardware interrupt - Input : None - Output : None - Return : OS_SUCCESS - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID osHwiInit() -{ - UINT32 uwIndex; - - for(uwIndex = OS_SYS_VECTOR_CNT; uwIndex < OS_VECTOR_CNT; uwIndex++) - { - m_pstHwiForm[uwIndex] = (HWI_PROC_FUNC)osHwiDefaultHandler; - } - - /* Interrupt vector table location */ - SCB->VTOR = (UINT32)m_pstHwiForm; -#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 : uwHwiNum --- hwi num to create - usHwiPrio --- priority of the hwi - usMode --- unused - pfnHandler --- hwi handler - uwArg --- param of the hwi handler - Output : None - Return : OS_SUCCESS on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate( HWI_HANDLE_T uwHwiNum, - HWI_PRIOR_T usHwiPrio, - HWI_MODE_T usMode, - HWI_PROC_FUNC pfnHandler, - HWI_ARG_T uwArg ) -{ - UINTPTR uvIntSave; - - if (NULL == pfnHandler) - { - return OS_ERRNO_HWI_PROC_FUNC_NULL; - } - - if (uwHwiNum >= OS_HWI_MAX_NUM) - { - return OS_ERRNO_HWI_NUM_INVALID; - } - - if (m_pstHwiForm[uwHwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)osHwiDefaultHandler) - { - return OS_ERRNO_HWI_ALREADY_CREATED; - } - - if ((usHwiPrio > OS_HWI_PRIO_LOWEST) || (usHwiPrio < OS_HWI_PRIO_HIGHEST)) - { - return OS_ERRNO_HWI_PRIO_INVALID; - } - - uvIntSave = LOS_IntLock(); -#if (OS_HWI_WITH_ARG == YES) - osSetVector(uwHwiNum, pfnHandler, uwArg); -#else - osSetVector(uwHwiNum, pfnHandler); -#endif - NVIC_EnableIRQ((IRQn_Type)uwHwiNum); - NVIC_SetPriority((IRQn_Type)uwHwiNum, usHwiPrio); - - LOS_IntRestore(uvIntSave); - - return LOS_OK; - -} - -/***************************************************************************** - Function : LOS_HwiDelete - Description : Delete hardware interrupt - Input : uwHwiNum --- 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 uwHwiNum) -{ - UINT32 uwIntSave; - - if (uwHwiNum >= OS_HWI_MAX_NUM) - { - return OS_ERRNO_HWI_NUM_INVALID; - } - - NVIC_DisableIRQ((IRQn_Type)uwHwiNum); - - uwIntSave = LOS_IntLock(); - - m_pstHwiForm[uwHwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)osHwiDefaultHandler; - - LOS_IntRestore(uwIntSave); - - return LOS_OK; -} - -#else - -/***************************************************************************** - Function : SysTick_Handler - Description : This function handles SysTick exception, Call LiteOS interface - osTickHandler. - Input : None - Output : None - Return : None - *****************************************************************************/ -void SysTick_Handler(void) -{ - if (g_bSysTickStart) - { - osTickHandler(); - } - else - { - g_ullTickCount++; - } -} - -#endif /*(LOSCFG_PLATFORM_HWI == YES)*/ - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2018. All rights reserved. + * Description: hwi_v7m + * 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. + * --------------------------------------------------------------------------- */ +/*---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + *---------------------------------------------------------------------------*/ + +#include "los_task_pri.h" +#include "los_hwi_pri.h" +#include "los_armcm.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_PLATFORM_HWI == YES) +LITE_OS_SEC_TEXT_MINOR VOID OsHwiDefaultHandler(VOID); +#endif + +#if (LOSCFG_PLATFORM_HWI == NO) +BOOL OsIntActive(VOID) +{ + UINT32 ic; + __asm__ __volatile__("MRS %0, xpsr" : "=r"(ic)); + return ((ic & 0x0000003f) != 0); /* 0x0000003f: mask of interrupt context */ +} +#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 + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID OsHwiDefaultHandler(VOID) +{ + UINT32 irqNum = OsIntNumGet(); + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); + while (1) { }; +} + +#if (LOSCFG_PLATFORM_HWI == YES) + +#ifdef __ICCARM__ +#pragma location = ".data.vector" +#elif defined (__CC_ARM) || defined (__GNUC__) +LITE_OS_SEC_DATA_VEC +#endif + +HWI_PROC_FUNC g_hwiVec[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)OsHwiDefaultHandler, // [15] SysTick Handler +}; + +/***************************************************************************** + Function : IrqEntryV7M + Description : irq entry for cortex-m + Input : irq number + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT_MINOR VOID IrqEntryV7M(VOID) +{ + UINT32 hwiIndex; + +#if (LOSCFG_KERNEL_RUNSTOP == YES) + SCB->SCR &= (UINT32)~((UINT32)SCB_SCR_SLEEPDEEP_Msk); +#endif + + hwiIndex = OsIntNumGet(); + OsInterrupt(hwiIndex); +#if (LOSCFG_KERNEL_RUNSTOP == YES) + if (g_srStateFlag == SENSORHUB_SLEEP) { + DisableWakeUpTimer(); + LOS_SystemWakeup(hwiIndex); + g_srStateFlag = SENSORHUB_CLODBOOT; + OsSRRestoreRegister(); + } +#endif + if (OsTaskProcSignal() != 0) { + OsSchedPreempt(); + } +} + +/***************************************************************************** + Function : HalIrqInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : NONE + *****************************************************************************/ +VOID HalIrqInit(VOID) +{ + UINT32 index; + for (index = OS_SYS_VECTOR_CNT; index < OS_VECTOR_CNT; index++) { + g_hwiVec[index] = (HWI_PROC_FUNC)IrqEntryV7M; + } + + /* Interrupt vector table location */ + SCB->VTOR = (UINT32)g_hwiVec; + +#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ + NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); +#endif + + return; +} + +/***************************************************************************** + Function : HalIrqCreate + Description : create hardware interrupt + Input : irq --- hwi num to create + priority --- priority of the hwi + Output : None + Return : OS_SUCCESS on success or error code on failure + *****************************************************************************/ +UINT32 HalIrqCreate(UINT32 irq, UINT8 priority) +{ + UINT32 intSave; + + if ((priority > OS_HWI_PRIO_LOWEST) || (priority < OS_HWI_PRIO_HIGHEST)) { + return OS_ERRNO_HWI_PRIO_INVALID; + } + + intSave = LOS_IntLock(); + + NVIC_EnableIRQ((IRQn_Type)irq); + NVIC_SetPriority((IRQn_Type)irq, priority); + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/***************************************************************************** + Function : LOS_HwiDelete + Description : Delete hardware interrupt + Input : irq --- hwi num to delete + Output : None + Return : LOS_OK on success or error code on failure + *****************************************************************************/ +UINT32 HalIrqDelete(HWI_HANDLE_T irq) +{ + NVIC_DisableIRQ((IRQn_Type)irq); + + return LOS_OK; +} + +VOID HalIrqMask(UINT32 vector) +{ + NVIC_DisableIRQ(vector); +} + +VOID HalIrqUnmask(UINT32 vector) +{ + NVIC_EnableIRQ(vector); +} + +VOID HalIrqPending(UINT32 vector) +{ + NVIC_SetPendingIRQ(vector); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/arch/arm/include/los_hw.h b/arch/arm/include/los_hw.h new file mode 100644 index 000000000..a15945fba --- /dev/null +++ b/arch/arm/include/los_hw.h @@ -0,0 +1,301 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Hw HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ +#ifndef _LOS_HW_H +#define _LOS_HW_H + +#include "los_typedef.h" +#include "los_hw_cpu.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_SCHEDULE_IN_IRQ 0x0 +#define OS_SCHEDULE_IN_TASK 0x1 + +#define PSR_T_ARM 0x00000000u +#define PSR_T_THUMB 0x00000020u +#define PSR_MODE_SVC 0x00000013u +#define PSR_MODE_SYS 0x0000001Fu +#define PSR_FIQ_DIS 0x00000040u +#define PSR_IRQ_DIS 0x00000080u + +#define PSR_MODE_SVC_THUMB (PSR_MODE_SVC | PSR_T_THUMB | PSR_FIQ_DIS | PSR_IRQ_DIS) +#define PSR_MODE_SVC_ARM (PSR_MODE_SVC | PSR_T_ARM | PSR_FIQ_DIS | PSR_IRQ_DIS) + +#define PSR_MODE_SYS_THUMB (PSR_MODE_SYS | PSR_T_THUMB) +#define PSR_MODE_SYS_ARM (PSR_MODE_SYS | PSR_T_ARM) + +typedef struct { + const UINT32 partNo; + const CHAR *cpuName; +} CpuVendor; + +extern CpuVendor g_cpuTable[]; +extern UINT64 g_cpuMap[]; + +#define CPU_MAP_GET(cpuid) g_cpuMap[(cpuid)] +#define CPU_MAP_SET(cpuid, hwid) g_cpuMap[(cpuid)] = (hwid) + +/** + * @ingroup los_hw + * @brief Set Event. + * + * @par Description: + *
      + *
    • This API is used to send an event to all cores within a muti-processor system.
    • + *
    + * @attention + *
      + *
    • This API is not implemented.
    • + *
    + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see wfe. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID sev(VOID); + +/** + * @ingroup los_hw + * @brief Wait for event. + * + * @par Description: + *
      + *
    • This API is used to suspend execution until events occurs if the event register is not set.
    • + *
    + * @attention + *
      + *
    • This API is not implemented.
    • + *
    + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see sev. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID wfe(VOID); + +/** + * @ingroup los_hw + * @brief Wait for interrupt. + * + * @par Description: + *
      + *
    • This API is used to suspend execution until interrupt or a debug request occurs.
    • + *
    + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID wfi(VOID); + +/** + * @ingroup los_hw + * @brief Data Memory Barrier. + * + * @par Description: + *
      + *
    • This API is used as a memory barrier
    • + *
    + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID dmb(VOID); + +/** + * @ingroup los_hw + * @brief Data Synchronization Barrier. + * + * @par Description: + *
      + *
    • This API is used as a special kind of memory barrier
    • + *
    + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID dsb(VOID); + +/** + * @ingroup los_hw + * @brief Instruction Synchronization Barrier. + * + * @par Description: + *
      + *
    • This API is used to flush the pipeline in the processor, + * so that all instructions following the ISB are fetched from cache or memory, + * after the instruction has been completed.
    • + *
    + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID isb(VOID); + +/** + * @ingroup los_hw + * @brief Invalidate instruction cache. + * + * @par Description: + *
      + *
    • This API is used to invalidate the instruction cache.
    • + *
    + * @attention None. + * + * @param None. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID flush_icache(VOID); + +/** + * @ingroup los_hw + * @brief Flush data cache. + * + * @par Description: + *
      + *
    • This API is used to flush the data cache to the memory.
    • + *
    + * @attention + *
      + *
    • The input end address must be greater than the input start address.
    • + *
    + * + * @param start [IN] Type #int Flush start address. + * @param end [IN] Type #int Flush end address. + * + * @retval #None. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID flush_dcache(UINTPTR start, UINTPTR end); + +/** + * @ingroup los_hw + * @brief Get cpu core name. + * + * @par Description: + *
      + *
    • This API is used to get cpu core name.
    • + *
    + * @attention + *
      + *
    • None.
    • + *
    + * + * @param + * @retval #CHAR * cpu core name. + * + * @par Dependency: + * los_hw.h: the header file that contains the API declaration. + * @see None. + * @since Huawei LiteOS V200R003C00 + */ +STATIC INLINE const CHAR *LOS_CpuInfo(VOID) +{ + INT32 i; + UINT32 midr = OsMainIDGet(); + /* [15:4] is the primary part number */ + UINT32 partNo = (midr & 0xFFF0) >> 0x4; + + for (i = 0; g_cpuTable[i].partNo != 0; i++) { + if (partNo == g_cpuTable[i].partNo) { + return g_cpuTable[i].cpuName; + } + } + + return "unknown"; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_H */ diff --git a/arch/arm/include/los_hw_arch.h b/arch/arm/include/los_hw_arch.h new file mode 100644 index 000000000..281a082fd --- /dev/null +++ b/arch/arm/include/los_hw_arch.h @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: hardware Arch Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_hw Hardware + * @ingroup kernel + */ + +#ifndef _LOS_HW_ARCH_H +#define _LOS_HW_ARCH_H + +# if defined(__GNUC__) +# if defined(__aarch64__) +# define LOSCFG_ARM_AARCH64 1 +# endif +# +# define LOSCFG_ARM_ARCH __ARM_ARCH +# else +# error "unsupported compiler!" +# endif + +#endif diff --git a/arch/arm/include/los_hw_tick_pri.h b/arch/arm/include/los_hw_tick_pri.h new file mode 100644 index 000000000..c9874a7a2 --- /dev/null +++ b/arch/arm/include/los_hw_tick_pri.h @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: Arm-a Hw Tick Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_HW_TICK_PRI_H +#define _LOS_HW_TICK_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond); +extern VOID OsTickStart(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HW_TICK_PRI_H */ diff --git a/arch/arm/include/los_sys_stack_pri.h b/arch/arm/include/los_sys_stack_pri.h new file mode 100644 index 000000000..9880e1b98 --- /dev/null +++ b/arch/arm/include/los_sys_stack_pri.h @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Stack Headfile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_SYS_STACK_H +#define _LOS_SYS_STACK_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_AARCH64 +extern UINTPTR __stack_startup; +extern UINTPTR __stack_startup_top; +#else +extern UINTPTR __fiq_stack_top; +extern UINTPTR __svc_stack_top; +extern UINTPTR __abt_stack_top; +extern UINTPTR __undef_stack_top; +extern UINTPTR __exc_stack_top; +extern UINTPTR __fiq_stack; +extern UINTPTR __svc_stack; +extern UINTPTR __abt_stack; +extern UINTPTR __undef_stack; +extern UINTPTR __exc_stack; +#endif +extern UINTPTR __irq_stack_top; +extern UINTPTR __irq_stack; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/arch/common/los_hwi.c b/arch/common/los_hwi.c new file mode 100644 index 000000000..0cd1bd6d2 --- /dev/null +++ b/arch/common/los_hwi.c @@ -0,0 +1,430 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ARM Hwi Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_hwi_pri.h" + +#if (LOSCFG_PLATFORM_HWI == YES) +#include "los_memory.h" +#include "los_spinlock.h" + +#if (LOSCFG_KERNEL_TRACE == YES) +#include "los_trace.h" +#endif + +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif + +#if (LOSCFG_KERNEL_TICKLESS == YES) +#include "los_tickless_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* spinlock for hwi module */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_hwiSpin); +#define HWI_LOCK(state) LOS_SpinLockSave(&g_hwiSpin, &(state)) +#define HWI_UNLOCK(state) LOS_SpinUnlockRestore(&g_hwiSpin, (state)) + +size_t g_intCount[LOSCFG_KERNEL_CORE_NUM] = {0}; +HWI_HANDLE_FORM_S g_hwiForm[OS_HWI_MAX_NUM + OS_SYS_VECTOR_CNT]; +STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0}; +STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0}; + +VOID OsIncHwiFormCnt(UINT32 index) +{ + g_hwiFormCnt[index]++; +} + +UINT32 OsGetHwiFormCnt(UINT32 index) +{ + return g_hwiFormCnt[index]; +} + +CHAR *OsGetHwiFormName(UINT32 index) +{ + return g_hwiFormName[index]; +} + +typedef VOID (*HWI_PROC_FUNC0)(VOID); +typedef VOID (*HWI_PROC_FUNC2)(INT32, VOID *); + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +STATIC INLINE VOID OsIrqNestingActive(UINT32 intNum) +{ + /* preemption not allowed when handling tick interrupt */ + if (intNum != OS_TICK_INT_NUM) { + (VOID)LOS_IntUnLock(); + } +} + +STATIC INLINE VOID OsIrqNestingInactive(UINT32 intNum) +{ + if (intNum != OS_TICK_INT_NUM) { + (VOID)LOS_IntLock(); + } +} + +size_t OsIrqNestingCntGet(VOID) +{ + return g_intCount[ArchCurrCpuid()]; +} +#endif + +STATIC INLINE VOID OsIrqError(UINT32 intNum) +{ + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, intNum); + for (; ;) { } +} + +VOID OsInterrupt(UINT32 intNum) +{ + HWI_HANDLE_FORM_S *hwiForm = NULL; + size_t *intCnt = NULL; + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + OsCpupIrqStart(); +#endif + + intCnt = &g_intCount[ArchCurrCpuid()]; + *intCnt = *intCnt + 1; + +#if (LOSCFG_KERNEL_TRACE == YES) + LOS_Trace(LOS_TRACE_INTERRUPT, intNum, IRQ_DIRECT_IN); +#endif + +#if (LOSCFG_KERNEL_TICKLESS == YES) + OsTicklessUpdate(intNum); +#endif + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION + OsIrqNestingActive(intNum); +#endif + + hwiForm = (&g_hwiForm[intNum]); +#ifndef LOSCFG_NO_SHARED_IRQ + while (hwiForm->pstNext != NULL) { + hwiForm = hwiForm->pstNext; +#endif + + if (hwiForm->uwParam) { + HWI_PROC_FUNC2 func = (HWI_PROC_FUNC2)hwiForm->pfnHook; + if (func != NULL) { + UINTPTR *param = (UINTPTR *)(hwiForm->uwParam); + func((INT32)(*param), (VOID *)(*(param + 1))); + } else { + OsIrqError(intNum); + } + } else { + HWI_PROC_FUNC0 func = (HWI_PROC_FUNC0)hwiForm->pfnHook; + if (func != NULL) { + func(); + } else { + OsIrqError(intNum); + } + } +#ifndef LOSCFG_NO_SHARED_IRQ + } +#endif + + ++g_hwiFormCnt[intNum]; + +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION + OsIrqNestingInactive(intNum); +#endif + +#if (LOSCFG_KERNEL_TRACE == YES) + LOS_Trace(LOS_TRACE_INTERRUPT, intNum, IRQ_DIRECT_OUT); +#endif + + *intCnt = *intCnt - 1; + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + OsCpupIrqEnd(intNum); +#endif +} + +STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam) +{ + HWI_IRQ_PARAM_S *paramByAlloc = NULL; + + if (irqParam != NULL) { + paramByAlloc = (HWI_IRQ_PARAM_S *)LOS_MemAlloc(m_aucSysMem0, sizeof(HWI_IRQ_PARAM_S)); + if (paramByAlloc == NULL) { + return LOS_NOK; + } + (VOID)memcpy_s(paramByAlloc, sizeof(HWI_IRQ_PARAM_S), irqParam, sizeof(HWI_IRQ_PARAM_S)); + } + return (HWI_ARG_T)paramByAlloc; +} +#ifdef LOSCFG_NO_SHARED_IRQ +STATIC UINT32 OsHwiDelNoShared(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + + HWI_LOCK(intSave); + g_hwiForm[hwiNum].pfnHook = NULL; + if (g_hwiForm[hwiNum].uwParam) { + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)g_hwiForm[hwiNum].uwParam); + } + g_hwiForm[hwiNum].uwParam = 0; + + HWI_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsHwiCreateNoShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, const HWI_IRQ_PARAM_S *irqParam) +{ + HWI_ARG_T retParam; + UINT32 intSave; + + (VOID)hwiMode; + HWI_LOCK(intSave); + if (g_hwiForm[hwiNum].pfnHook == NULL) { + g_hwiForm[hwiNum].pfnHook = hwiHandler; + + retParam = OsHwiCpIrqParam(irqParam); + if (retParam == LOS_NOK) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_NO_MEMORY; + } + g_hwiForm[hwiNum].uwParam = retParam; + } else { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_ALREADY_CREATED; + } + HWI_UNLOCK(intSave); + return LOS_OK; +} +#else +STATIC UINT32 OsHwiDelShared(HWI_HANDLE_T hwiNum, const HWI_IRQ_PARAM_S *irqParam) +{ + HWI_HANDLE_FORM_S *hwiForm = NULL; + HWI_HANDLE_FORM_S *hwiFormtmp = NULL; + UINT32 hwiValid = FALSE; + UINT32 intSave; + + HWI_LOCK(intSave); + hwiForm = &g_hwiForm[hwiNum]; + hwiFormtmp = hwiForm; + + if ((hwiForm->uwParam & IRQF_SHARED) && ((irqParam == NULL) || (irqParam->pDevId == NULL))) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_SHARED_ERROR; + } + + if ((hwiForm->pstNext != NULL) && !(hwiForm->uwParam & IRQF_SHARED)) { + hwiForm = hwiForm->pstNext; + if (hwiForm->uwParam) { + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)hwiForm->uwParam); + } + (VOID)LOS_MemFree(m_aucSysMem0, hwiForm); + hwiFormtmp->pstNext = NULL; + + g_hwiFormName[hwiNum] = NULL; + + HWI_UNLOCK(intSave); + return LOS_OK; + } + hwiForm = hwiForm->pstNext; + while (hwiForm != NULL) { + if (((HWI_IRQ_PARAM_S *)(hwiForm->uwParam))->pDevId != irqParam->pDevId) { + hwiFormtmp = hwiForm; + hwiForm = hwiForm->pstNext; + } else { + hwiFormtmp->pstNext = hwiForm->pstNext; + (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)hwiForm->uwParam); + (VOID)LOS_MemFree(m_aucSysMem0, hwiForm); + + hwiValid = TRUE; + break; + } + } + + if (hwiValid != TRUE) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_HWINUM_UNCREATE; + } + + if (g_hwiForm[hwiNum].pstNext == NULL) { + g_hwiForm[hwiNum].uwParam = 0; + g_hwiFormName[hwiNum] = NULL; + } + + HWI_UNLOCK(intSave); + return LOS_OK; +} + +STATIC UINT32 OsHwiCreateShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, const HWI_IRQ_PARAM_S *irqParam) +{ + UINT32 intSave; + HWI_HANDLE_FORM_S *hwiFormNode = NULL; + HWI_HANDLE_FORM_S *hwiForm = NULL; + HWI_IRQ_PARAM_S *hwiParam = NULL; + HWI_MODE_T modeResult = hwiMode & IRQF_SHARED; + + if (modeResult && ((irqParam == NULL) || (irqParam->pDevId == NULL))) { + return OS_ERRNO_HWI_SHARED_ERROR; + } + + HWI_LOCK(intSave); + + hwiForm = &g_hwiForm[hwiNum]; + if ((hwiForm->pstNext != NULL) && ((modeResult == 0) || (!(hwiForm->uwParam & IRQF_SHARED)))) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_SHARED_ERROR; + } + + while (hwiForm->pstNext != NULL) { + hwiForm = hwiForm->pstNext; + hwiParam = (HWI_IRQ_PARAM_S *)(hwiForm->uwParam); + if (hwiParam->pDevId == irqParam->pDevId) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_ALREADY_CREATED; + } + } + + hwiFormNode = (HWI_HANDLE_FORM_S *)LOS_MemAlloc(m_aucSysMem0, sizeof(HWI_HANDLE_FORM_S)); + if (hwiFormNode == NULL) { + HWI_UNLOCK(intSave); + return OS_ERRNO_HWI_NO_MEMORY; + } + + hwiFormNode->uwParam = OsHwiCpIrqParam(irqParam); + if (hwiFormNode->uwParam == LOS_NOK) { + HWI_UNLOCK(intSave); + (VOID)LOS_MemFree(m_aucSysMem0, hwiFormNode); + return OS_ERRNO_HWI_NO_MEMORY; + } + + hwiFormNode->pfnHook = hwiHandler; + hwiFormNode->pstNext = (struct tagHwiHandleForm *)NULL; + hwiForm->pstNext = hwiFormNode; + + if ((irqParam != NULL) && (irqParam->pName != NULL)) { + g_hwiFormName[hwiNum] = (CHAR *)irqParam->pName; + } + + g_hwiForm[hwiNum].uwParam = modeResult; + + HWI_UNLOCK(intSave); + return LOS_OK; +} +#endif + +/* + * Description : initialization of the hardware interrupt + */ +LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID) +{ + UINT32 hwiNum; + + for (hwiNum = 0; hwiNum < OS_HWI_MAX_NUM; hwiNum++) { + g_hwiForm[hwiNum].pfnHook = NULL; + g_hwiForm[hwiNum].uwParam = 0; + g_hwiForm[hwiNum].pstNext = NULL; + } + + (VOID)memset_s(g_hwiFormName, (sizeof(CHAR *) * OS_HWI_MAX_NUM), 0, (sizeof(CHAR *) * OS_HWI_MAX_NUM)); + + HalIrqInit(); + + return; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, + HWI_IRQ_PARAM_S *irqParam) +{ + UINT32 ret; + + if (hwiHandler == NULL) { + return OS_ERRNO_HWI_PROC_FUNC_NULL; + } + if ((hwiNum > OS_USER_HWI_MAX) || ((INT32)hwiNum < OS_USER_HWI_MIN)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + +#ifdef LOSCFG_NO_SHARED_IRQ + ret = OsHwiCreateNoShared(hwiNum + OS_SYS_VECTOR_CNT, hwiMode, hwiHandler, irqParam); +#else + ret = OsHwiCreateShared(hwiNum + OS_SYS_VECTOR_CNT, hwiMode, hwiHandler, irqParam); +#endif +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION + if (ret == LOS_OK) { + ret = HalIrqSetPrio(hwiNum, (UINT8)hwiPrio); + } +#endif + if (ret == LOS_OK) { + (VOID)HalIrqCreate(hwiNum, (UINT8)hwiPrio); + } + + return ret; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam) +{ + UINT32 ret; + + if ((hwiNum > OS_USER_HWI_MAX) || ((INT32)hwiNum < OS_USER_HWI_MIN)) { + return OS_ERRNO_HWI_NUM_INVALID; + } + +#ifdef LOSCFG_NO_SHARED_IRQ + (VOID)irqParam; + ret = OsHwiDelNoShared(hwiNum + OS_SYS_VECTOR_CNT); +#else + ret = OsHwiDelShared(hwiNum + OS_SYS_VECTOR_CNT, irqParam); +#endif + if (ret == LOS_OK) { + (VOID)HalIrqDelete(hwiNum); + } + return ret; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/arch/common/los_hwi.h b/arch/common/los_hwi.h new file mode 100644 index 000000000..dcfcfa478 --- /dev/null +++ b/arch/common/los_hwi.h @@ -0,0 +1,447 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Hwi HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_hwi Hardware interrupt + * @ingroup kernel + */ +#ifndef _LOS_HWI_H +#define _LOS_HWI_H + +#include "los_base.h" +#include "hal_hwi.h" +#if (LOSCFG_PLATFORM_HWI == NO) +#include "los_hwi_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_PLATFORM_HWI == YES) +/** + * @ingroup los_hwi + * Count of interrupts. + */ +extern size_t g_intCount[]; + +/** + * @ingroup los_hwi + * An interrupt is active. + */ +#define OS_INT_ACTIVE ({ \ + size_t intCount; \ + UINT32 intSave_ = LOS_IntLock(); \ + intCount = g_intCount[ArchCurrCpuid()]; \ + LOS_IntRestore(intSave_); \ + intCount; \ +}) +#else +#define OS_INT_ACTIVE (OsIntActive()) +#endif + +/** + * @ingroup los_hwi + * An interrupt is inactive. + */ +#define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) + +#if (LOSCFG_PLATFORM_HWI == YES) +/** + * @ingroup los_hwi + * Highest priority of a hardware interrupt. + */ +#define OS_HWI_PRIO_HIGHEST 0 + +/** + * @ingroup los_hwi + * Lowest priority of a hardware interrupt. + */ +#define OS_HWI_PRIO_LOWEST 31 + +/** + * @ingroup los_hwi + * Max name length of a hardware interrupt. + */ +#define OS_HWI_MAX_NAMELEN 10 + +/** + * @ingroup los_hwi + * number of exceptions for core + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + + +/** + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. + */ +#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. + */ +#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 + * Hardware interrupt error code: The API is called during an interrupt, which is forbidden. + * + * Value: 0x02000908 + * + * * Solution: Do not call the API during an interrupt. + */ +#define OS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08) + +/** + * @ingroup los_hwi + * Hardware interrupt error code:the hwi support SHARED error. + * + * Value: 0x02000909 + * + * * Solution: Check the input params hwiMode and irqParam of LOS_HwiCreate or + * LOS_HwiDelete whether adapt the current hwi. + */ +#define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09) + +/** + * @ingroup los_hwi + * Hardware interrupt error code:Invalid interrupt Arg when interrupt mode is IRQF_SHARED. + * + * Value: 0x0200090a + * + * * Solution: Check the interrupt Arg, Arg should not be NULL and pDevId should not be NULL. + */ +#define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a) + +/** + * @ingroup los_hwi + * Hardware interrupt error code:The interrupt corresponded to the hwi number or devid has not been created. + * + * Value: 0x0200090b + * + * * Solution: Check the hwi number or devid, make sure the hwi number or devid need to delete. + */ +#define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b) + +/** + * @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 UINTPTR HWI_ARG_T; + +/** + * @ingroup los_hwi + * Define the type of a hardware interrupt handling function. + */ +typedef VOID (*HWI_PROC_FUNC)(VOID); + +/* + * These flags used only by the kernel as part of the + * irq handling routines. + * + * IRQF_SHARED - allow sharing the irq among several devices + */ +#define IRQF_SHARED 0x8000U + +typedef struct tagHwiHandleForm { + HWI_PROC_FUNC pfnHook; + HWI_ARG_T uwParam; + struct tagHwiHandleForm *pstNext; + UINTPTR uwReserved; +} HWI_HANDLE_FORM_S; + +typedef struct tagIrqParam { + int swIrq; + VOID *pDevId; + const CHAR *pName; +} HWI_IRQ_PARAM_S; +#endif + +/** + * @ingroup los_hwi + * @brief Disable all interrupts. + * + * @par Description: + *
      + *
    • This API is used to disable all IRQ and FIQ interrupts in the CPSR.
    • + *
    + * @attention + *
      + *
    • None.
    • + *
    + * + * @param None. + * + * @retval #UINT32 CPSR value obtained before all interrupts are disabled. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see LOS_IntRestore + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE UINT32 LOS_IntLock(VOID) +{ + return ArchIntLock(); +} + +/** + * @ingroup los_hwi + * @brief Enable all interrupts. + * + * @par Description: + *
      + *
    • This API is used to enable all IRQ and FIQ interrupts in the CPSR.
    • + *
    + * @attention + *
      + *
    • None.
    • + *
    + * + * @param None. + * + * @retval #UINT32 CPSR value obtained after all interrupts are enabled. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see LOS_IntLock + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE UINT32 LOS_IntUnLock(VOID) +{ + return ArchIntUnlock(); +} + +/** + * @ingroup los_hwi + * @brief Restore interrupts. + * + * @par Description: + *
      + *
    • This API is used to restore the CPSR value obtained before all interrupts are disabled.
    • + *
    + * @attention + *
      + *
    • This API can be called only after all interrupts are disabled, and the input parameter value should be + * the value returned by LOS_IntLock.
    • + *
    + * + * @param intSave [IN] Type #UINT32 : CPSR value obtained before all interrupts are disabled. + * + * @retval None. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see LOS_IntLock + * @since Huawei LiteOS V100R001C00 + */ +STATIC INLINE VOID LOS_IntRestore(UINT32 intSave) +{ + ArchIntRestore(intSave); +} + +#if (LOSCFG_PLATFORM_HWI == YES) +/** + * @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 + *
      + *
    • The hardware interrupt module is usable only when the configuration item for + * hardware interrupt tailoring is enabled.
    • + *
    • Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX].
    • + *
    • OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.
    • + *
    • Before executing an interrupt on a platform, refer to the chip manual of the platform.
    • + *
    • The parameter handler of this interface is a interrupt handler, it should be correct, otherwise, + * the system may be abnormal.
    • + *
    • The input irqParam could be NULL, if not, it should be address which point to a struct HWI_IRQ_PARAM_S
    • + *
    + * + * @param hwiNum [IN] Type #HWI_HANDLE_T: hardware interrupt number. + * for an ARM926 platform is [0,31]. + * @param hwiPrio [IN] Type #HWI_PRIOR_T: hardware interrupt priority. The value range is + * [0, GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 1] << PRIORITY_SHIFT. + * @param hwiMode [IN] Type #HWI_MODE_T: hardware interrupt mode. Ignore this parameter temporarily. + * @param hwiHandler [IN] Type #HWI_PROC_FUNC: interrupt handler used when a hardware interrupt is triggered. + * @param irqParam [IN] Type #HWI_IRQ_PARAM_S: input parameter of the interrupt handler used when + * a hardware interrupt is triggered. + * + * @retval #OS_ERRNO_HWI_PROC_FUNC_NULL Null hardware interrupt handling function. + * @retval #OS_ERRNO_HWI_NUM_INVALID Invalid interrupt number. + * @retval #OS_ERRNO_HWI_NO_MEMORY Insufficient memory for hardware interrupt creation. + * @retval #OS_ERRNO_HWI_ALREADY_CREATED The interrupt handler being created has already been created. + * @retval #LOS_OK The interrupt is successfully created. + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T hwiMode, + HWI_PROC_FUNC hwiHandler, + HWI_IRQ_PARAM_S *irqParam); + +/** + * @ingroup los_hwi + * @brief delete a hardware interrupt. + * + * @par Description: + * This API is used to delete a hardware interrupt. + * + * @attention + *
      + *
    • The hardware interrupt module is usable only when the configuration item for + * hardware interrupt tailoring is enabled.
    • + *
    • Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX].
    • + *
    • OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.
    • + *
    • Before executing an interrupt on a platform, refer to the chip manual of the platform.
    • + *
    + * + * @param hwiNum [IN] Type #HWI_HANDLE_T: hardware interrupt number. + * @param irqParam [IN] Type #HWI_IRQ_PARAM_S *: id of hardware interrupt which will base on + * when delete the hardware interrupt. + * + * @retval #OS_ERRNO_HWI_NUM_INVALID Invalid interrupt number. + * @retval #OS_ERRNO_HWI_SHARED_ERROR Invalid interrupt mode. + * @retval #LOS_OK The interrupt is successfully deleted. + * @retval #LOS_NOK The interrupt is failed deleted based on the pDev_ID. + + * @par Dependency: + *
    • los_hwi.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam); + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HWI_H */ diff --git a/components/fs/devfs/los_devfs.c b/components/fs/devfs/los_devfs.c index 87608e4ec..d34a565d0 100644 --- a/components/fs/devfs/los_devfs.c +++ b/components/fs/devfs/los_devfs.c @@ -35,8 +35,6 @@ #include #include -#if (LOSCFG_ENABLE_DEVFS == YES) - static void *devfs_root = NULL; UINT32 los_devfs_init (void) @@ -86,5 +84,3 @@ UINT32 los_devfs_link (const char *path_in_mp, uint32_t flags, return ret == 0 ? LOS_OK : LOS_NOK; } -#endif - diff --git a/components/fs/vfs/los_vfs.c b/components/fs/vfs/los_vfs.c index 8f95ff976..e0d01eade 100644 --- a/components/fs/vfs/los_vfs.c +++ b/components/fs/vfs/los_vfs.c @@ -42,9 +42,6 @@ #include "fs/sys/fcntl.h" #include "fs/los_vfs.h" - -#if (LOSCFG_ENABLE_VFS == YES) - struct file files [LOS_MAX_FILES]; UINT32 fs_mutex = LOS_ERRNO_MUX_PTR_NULL; struct mount_point *mount_points = NULL; @@ -1251,6 +1248,4 @@ int mkdir (const char *path, int mode) int ret = los_mkdir (path, mode); return MAP_TO_POSIX_RET(ret); } - #endif -#endif \ No newline at end of file diff --git a/components/lib/libc/errno.c b/components/lib/libc/errno.c index 9de7f2ece..43bc33340 100644 --- a/components/lib/libc/errno.c +++ b/components/lib/libc/errno.c @@ -1,70 +1,79 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Error + * + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * Huawei LiteOS may be subject to applicable export control laws and regulations, + * which might include those applicable to Huawei LiteOS of U.S. and the country + * in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in + * compliance with such applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ -/* Includes -----------------------------------------------------------------*/ - -#include "los_config.h" +#include "errno.h" +#include "los_errno.h" #include "los_task.h" -#include "los_printf.h" - - -/* Typedefs -----------------------------------------------------------------*/ - -typedef struct TaskReent -{ - int errno; -} TaskReent; +int errno_array[LOSCFG_BASE_CORE_TSK_CONFIG + 1]; -/* Local variables ----------------------------------------------------------*/ +/* the specific errno get or set in interrupt service routine */ +static int errno_isr; -static TaskReent g_task_reent[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; +void set_errno(int err_code) { + /* errno can not be set to 0 as posix standard */ + if (err_code == 0) + return; + if (OS_INT_INACTIVE) + errno_array[LOS_CurTaskIDGet()] = err_code; + else + errno_isr = err_code; +} -/* Public functions ---------------------------------------------------------*/ +int get_errno(void) { + if (OS_INT_INACTIVE) + return errno_array[LOS_CurTaskIDGet()]; + else + return errno_isr; +} -int *task_errno(void) -{ - UINT32 taskid = LOS_CurTaskIDGet(); +int *__errno_location(void) { + if (OS_INT_INACTIVE) + return &errno_array[LOS_CurTaskIDGet()]; + else + return &errno_isr; +} - if (taskid <= LOSCFG_BASE_CORE_TSK_LIMIT) - { - return &g_task_reent[taskid].errno; - } - else - { - PRINT_WARN("TaskID[%d] is invalid\n", taskid); - return &g_task_reent[0].errno; - } +volatile int *__os_errno(void) { + if (OS_INT_INACTIVE) + return (volatile int *)(&errno_array[LOS_CurTaskIDGet()]); + else + return (volatile int *)(&errno_isr); } + diff --git a/components/lib/libc/newlib_stub.c b/components/lib/libc/newlib_stub.c index 7d95c705a..e02e0b6c3 100644 --- a/components/lib/libc/newlib_stub.c +++ b/components/lib/libc/newlib_stub.c @@ -31,7 +31,6 @@ * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. *---------------------------------------------------------------------------*/ - #include #include #include @@ -113,5 +112,3 @@ void abort(void) { while (1); } - - diff --git a/components/lib/libsec/LICENSE b/components/lib/libsec/LICENSE new file mode 100644 index 000000000..42f2a8367 --- /dev/null +++ b/components/lib/libsec/LICENSE @@ -0,0 +1,124 @@ +木兰宽æ¾è®¸å¯è¯ï¼Œ 第2版 + +2020å¹´1月 http://license.coscl.org.cn/MulanPSL2 + +您对“软件â€çš„å¤åˆ¶ã€ä½¿ç”¨ã€ä¿®æ”¹åŠåˆ†å‘å—木兰宽æ¾è®¸å¯è¯ï¼Œç¬¬2版(“本许å¯è¯â€ï¼‰çš„如下æ¡æ¬¾çš„约æŸï¼š + +0. 定义 + +“软件†是指由“贡献â€æž„æˆçš„许å¯åœ¨â€œæœ¬è®¸å¯è¯â€ä¸‹çš„程åºå’Œç›¸å…³æ–‡æ¡£çš„集åˆã€‚ + +“贡献†是指由任一“贡献者â€è®¸å¯åœ¨â€œæœ¬è®¸å¯è¯â€ä¸‹çš„å—版æƒæ³•ä¿æŠ¤çš„作å“。 + +“贡献者†是指将å—版æƒæ³•ä¿æŠ¤çš„作å“许å¯åœ¨â€œæœ¬è®¸å¯è¯â€ä¸‹çš„自然人或“法人实体â€ã€‚ + +“法人实体†是指æ交贡献的机构åŠå…¶â€œå…³è”实体â€ã€‚ + +“关è”实体†是指,对“本许å¯è¯â€ä¸‹çš„行为方而言,控制ã€å—控制或与其共åŒå—控制的机构,此处的控制是指有å—控方或共åŒå—控方至少50%直接或间接的投票æƒã€èµ„金或其他有价è¯åˆ¸ã€‚ + +1. 授予版æƒè®¸å¯ + +æ¯ä¸ªâ€œè´¡çŒ®è€…â€æ ¹æ®â€œæœ¬è®¸å¯è¯â€æŽˆäºˆæ‚¨æ°¸ä¹…性的ã€å…¨çƒæ€§çš„ã€å…费的ã€éžç‹¬å çš„ã€ä¸å¯æ’¤é”€çš„版æƒè®¸å¯ï¼Œæ‚¨å¯ä»¥å¤åˆ¶ã€ä½¿ç”¨ã€ä¿®æ”¹ã€åˆ†å‘其“贡献â€ï¼Œä¸è®ºä¿®æ”¹ä¸Žå¦ã€‚ + +2. æŽˆäºˆä¸“åˆ©è®¸å¯ + +æ¯ä¸ªâ€œè´¡çŒ®è€…â€æ ¹æ®â€œæœ¬è®¸å¯è¯â€æŽˆäºˆæ‚¨æ°¸ä¹…性的ã€å…¨çƒæ€§çš„ã€å…费的ã€éžç‹¬å çš„ã€ä¸å¯æ’¤é”€çš„(根æ®æœ¬æ¡è§„定撤销除外)专利许å¯ï¼Œä¾›æ‚¨åˆ¶é€ ã€å§”托制造ã€ä½¿ç”¨ã€è®¸è¯ºé”€å”®ã€é”€å”®ã€è¿›å£å…¶â€œè´¡çŒ®â€æˆ–以其他方å¼è½¬ç§»å…¶â€œè´¡çŒ®â€ã€‚å‰è¿°ä¸“利许å¯ä»…é™äºŽâ€œè´¡çŒ®è€…â€çŽ°åœ¨æˆ–å°†æ¥æ‹¥æœ‰æˆ–控制的其“贡献â€æœ¬èº«æˆ–其“贡献â€ä¸Žè®¸å¯â€œè´¡çŒ®â€æ—¶çš„“软件â€ç»“åˆè€Œå°†å¿…然会侵犯的专利æƒåˆ©è¦æ±‚,ä¸åŒ…括对“贡献â€çš„修改或包å«â€œè´¡çŒ®â€çš„其他结åˆã€‚如果您或您的“关è”实体â€ç›´æŽ¥æˆ–间接地,就“软件â€æˆ–其中的“贡献â€å¯¹ä»»ä½•äººå‘起专利侵æƒè¯‰è®¼ï¼ˆåŒ…括å诉或交å‰è¯‰è®¼ï¼‰æˆ–其他专利维æƒè¡ŒåŠ¨ï¼ŒæŒ‡æŽ§å…¶ä¾µçŠ¯ä¸“利æƒï¼Œåˆ™â€œæœ¬è®¸å¯è¯â€æŽˆäºˆæ‚¨å¯¹â€œè½¯ä»¶â€çš„专利许å¯è‡ªæ‚¨æ起诉讼或å‘èµ·ç»´æƒè¡ŒåŠ¨ä¹‹æ—¥ç»ˆæ­¢ã€‚ + +3. æ— å•†æ ‡è®¸å¯ + +“本许å¯è¯â€ä¸æ供对“贡献者â€çš„商å“å称ã€å•†æ ‡ã€æœåŠ¡æ ‡å¿—或产å“å称的商标许å¯ï¼Œä½†æ‚¨ä¸ºæ»¡è¶³ç¬¬4æ¡è§„定的声明义务而必须使用除外。 + +4. 分å‘é™åˆ¶ + +您å¯ä»¥åœ¨ä»»ä½•åª’介中将“软件â€ä»¥æºç¨‹åºå½¢å¼æˆ–å¯æ‰§è¡Œå½¢å¼é‡æ–°åˆ†å‘,ä¸è®ºä¿®æ”¹ä¸Žå¦ï¼Œä½†æ‚¨å¿…é¡»å‘接收者æ供“本许å¯è¯â€çš„副本,并ä¿ç•™â€œè½¯ä»¶â€ä¸­çš„版æƒã€å•†æ ‡ã€ä¸“利åŠå…责声明。 + +5. å…责声明与责任é™åˆ¶ + +“软件â€åŠå…¶ä¸­çš„“贡献â€åœ¨æ供时ä¸å¸¦ä»»ä½•æ˜Žç¤ºæˆ–默示的担ä¿ã€‚在任何情况下,“贡献者â€æˆ–版æƒæ‰€æœ‰è€…ä¸å¯¹ä»»ä½•äººå› ä½¿ç”¨â€œè½¯ä»¶â€æˆ–其中的“贡献â€è€Œå¼•å‘的任何直接或间接æŸå¤±æ‰¿æ‹…责任,ä¸è®ºå› ä½•ç§åŽŸå› å¯¼è‡´æˆ–者基于何ç§æ³•å¾‹ç†è®ºï¼Œå³ä½¿å…¶æ›¾è¢«å»ºè®®æœ‰æ­¤ç§æŸå¤±çš„å¯èƒ½æ€§ã€‚ + +6. 语言 + +“本许å¯è¯â€ä»¥ä¸­è‹±æ–‡åŒè¯­è¡¨è¿°ï¼Œä¸­è‹±æ–‡ç‰ˆæœ¬å…·æœ‰åŒç­‰æ³•å¾‹æ•ˆåŠ›ã€‚如果中英文版本存在任何冲çªä¸ä¸€è‡´ï¼Œä»¥ä¸­æ–‡ç‰ˆä¸ºå‡†ã€‚ + +æ¡æ¬¾ç»“æŸ + +如何将木兰宽æ¾è®¸å¯è¯ï¼Œç¬¬2版,应用到您的软件 + +如果您希望将木兰宽æ¾è®¸å¯è¯ï¼Œç¬¬2版,应用到您的新软件,为了方便接收者查阅,建议您完æˆå¦‚下三步: + +1, 请您补充如下声明中的空白,包括软件åã€è½¯ä»¶çš„首次å‘表年份以åŠæ‚¨ä½œä¸ºç‰ˆæƒäººçš„åå­—ï¼› + +2, 请您在软件包的一级目录下创建以“LICENSEâ€ä¸ºå的文件,将整个许å¯è¯æ–‡æœ¬æ”¾å…¥è¯¥æ–‡ä»¶ä¸­ï¼› + +3, 请将如下声明文本放入æ¯ä¸ªæºæ–‡ä»¶çš„头部注释中。 + +Copyright (c) [Year] [name of copyright holder] +[Software Name] is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. +Mulan Permissive Software License,Version 2 +Mulan Permissive Software License,Version 2 (Mulan PSL v2) + +January 2020 http://license.coscl.org.cn/MulanPSL2 + +Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: + +0. Definition + +Software means the program and related documents which are licensed under this License and comprise all Contribution(s). + +Contribution means the copyrightable work licensed by a particular Contributor under this License. + +Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. + +Legal Entity means the entity making a Contribution and all its Affiliates. + +Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, 'control' means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. + +1. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. + +2. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. + +3. No Trademark License + +No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4. + +4. Distribution Restriction + +You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. + +5. Disclaimer of Warranty and Limitation of Liability + +THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT'S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +6. Language + +THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. + +END OF THE TERMS AND CONDITIONS + +How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software + +To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: + +Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; +Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package; +Attach the statement to the appropriate annotated syntax at the beginning of each source file. +Copyright (c) [Year] [name of copyright holder] +[Software Name] is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. \ No newline at end of file diff --git a/components/lib/libsec/Makefile b/components/lib/libsec/Makefile new file mode 100644 index 000000000..fe8e11b4f --- /dev/null +++ b/components/lib/libsec/Makefile @@ -0,0 +1,17 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := sec + +LOCAL_SRCS := $(wildcard src/*.c) +ifneq ($(LOSCFG_FS_VFS), y) +LOCAL_SRCS := $(filter-out src/scanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/fscanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/fwscanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/vfscanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/vfwscanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/vscanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/vwscanf_s.c, $(LOCAL_SRCS)) +LOCAL_SRCS := $(filter-out src/wscanf_s.c, $(LOCAL_SRCS)) +endif + +include $(MODULE) diff --git a/components/lib/libsec/README.en.md b/components/lib/libsec/README.en.md new file mode 100644 index 000000000..8ce43d768 --- /dev/null +++ b/components/lib/libsec/README.en.md @@ -0,0 +1,67 @@ +# bounds_checking_function + +#### Description + +- following the standard of C11 Annex K (bound-checking interfaces), functions of the common memory/string operation classes, such as memcpy_s, strcpy_s, are selected and implemented. + +- other standard functions in C11 Annex K will be analyzed in the future and implemented in this organization if necessary. + +- handles the release, update, and maintenance of bounds_checking_function. + +#### Function List + +- memcpy_s +- wmemcpy_s +- memmove_s +- wmemmove_s +- memset_s +- strcpy_s +- wcscpy_s +- strncpy_s +- wcsncpy_s +- strcat_s +- wcscat_s +- strncat_s +- wcsncat_s +- strtok_s +- cwcstok_s +- sprintf_s +- swprintf_s +- vsprintf_s +- vswprintf_s +- snprintf_s +- vsnprintf_s +- scanf_s +- wscanf_s +- vscanf_s +- vwscanf_s +- fscanf_s +- fwscanf_s +- vfscanf_s +- vfwscanf_s +- sscanf_s +- swscanf_s +- vsscanf_s +- vswscanf_s +- gets_s + + +#### Building + +- compilation steps + +1. Add all the .c files under /src to the source code listing for the build script. + +2. In the build options, specify the header directory and the build options required for the project (for example, add +-Ipath_to_include -fstack-protector-strong -fPIC -Wall -D_FORTIFY_SOURCE=2 -O2 in CFLAGS). + +3. Generate .o files for each .c file. + +4. Generate static or shared libraries for .o files according to project requirements. + +- compiling examples: +``` +gcc -o memcpy_s.o -c -Iinclude -fstack-protector-strong -fPIC -Wall -D_FORTIFY_SOURCE=2 -O2 src/memcpy_s.c +``` + + diff --git a/components/lib/libsec/include/securec.h b/components/lib/libsec/include/securec.h new file mode 100644 index 000000000..e0a977e27 --- /dev/null +++ b/components/lib/libsec/include/securec.h @@ -0,0 +1,630 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: The user of this secure c library should include this header file in you source code. + * This header file declare all supported API prototype of the library, + * such as memcpy_s, strcpy_s, wcscpy_s,strcat_s, strncat_s, sprintf_s, scanf_s, and so on. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27 +#define SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27 + +#include "securectype.h" +#ifndef SECUREC_HAVE_STDARG_H +#define SECUREC_HAVE_STDARG_H 1 +#endif + +#if SECUREC_HAVE_STDARG_H +#include +#endif + +#ifndef SECUREC_HAVE_ERRNO_H +#define SECUREC_HAVE_ERRNO_H 1 +#endif + +/* EINVAL ERANGE may defined in errno.h */ +#if SECUREC_HAVE_ERRNO_H +#if SECUREC_IN_KERNEL +#include +#else +#include +#endif +#endif + +/* Define error code */ +#if defined(SECUREC_NEED_ERRNO_TYPE) || !defined(__STDC_WANT_LIB_EXT1__) || \ + (defined(__STDC_WANT_LIB_EXT1__) && (!__STDC_WANT_LIB_EXT1__)) +#ifndef SECUREC_DEFINED_ERRNO_TYPE +#define SECUREC_DEFINED_ERRNO_TYPE +/* Just check whether macrodefinition exists. */ +#ifndef errno_t +typedef int errno_t; +#endif +#endif +#endif + +/* Success */ +#ifndef EOK +#define EOK 0 +#endif + +#ifndef EINVAL +/* The src buffer is not correct and destination buffer cant not be reset */ +#define EINVAL 22 +#endif + +#ifndef EINVAL_AND_RESET +/* Once the error is detected, the dest buffer must be reseted! Value is 22 or 128 */ +#define EINVAL_AND_RESET 150 +#endif + +#ifndef ERANGE +/* The destination buffer is not long enough and destination buffer can not be reset */ +#define ERANGE 34 +#endif + +#ifndef ERANGE_AND_RESET +/* Once the error is detected, the dest buffer must be reseted! Value is 34 or 128 */ +#define ERANGE_AND_RESET 162 +#endif + +#ifndef EOVERLAP_AND_RESET +/* Once the buffer overlap is detected, the dest buffer must be reseted! Value is 54 or 128 */ +#define EOVERLAP_AND_RESET 182 +#endif + +/* If you need export the function of this library in Win32 dll, use __declspec(dllexport) */ +#ifndef SECUREC_API +#if defined(SECUREC_DLL_EXPORT) +#define SECUREC_API __declspec(dllexport) +#elif defined(SECUREC_DLL_IMPORT) +#define SECUREC_API __declspec(dllimport) +#else +/* + * Standardized function declaration. If a security function is declared in the your code, + * it may cause a compilation alarm,Please delete the security function you declared. + * Adding extern under windows will cause the system to have inline functions to expand, + * so do not add the extern in default + */ +#if defined(_MSC_VER) +#define SECUREC_API +#else +#define SECUREC_API extern +#endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + /* + * Description: The GetHwSecureCVersion function get SecureC Version string and version number. + * Parameter: verNumber - to store version number (for example value is 0x500 | 0xa) + * Return: version string + */ + SECUREC_API const char *GetHwSecureCVersion(unsigned short *verNumber); + +#if SECUREC_ENABLE_MEMSET + /* + * Description: The memset_s function copies the value of c (converted to an unsigned char) into each of + * the first count characters of the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: c - the value to be copied + * Parameter: count - copies count bytes of value to dest + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t memset_s(void *dest, size_t destMax, int c, size_t count); +#endif + +#ifndef SECUREC_ONLY_DECLARE_MEMSET +#define SECUREC_ONLY_DECLARE_MEMSET 0 +#endif + +#if !SECUREC_ONLY_DECLARE_MEMSET + +#if SECUREC_ENABLE_MEMMOVE + /* + * Description: The memmove_s function copies n characters from the object pointed to by src + * into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count bytes from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count); +#endif + +#if SECUREC_ENABLE_MEMCPY + /* + * Description: The memcpy_s function copies n characters from the object pointed to + * by src into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count bytes from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count); +#endif + +#if SECUREC_ENABLE_STRCPY + /* + * Description: The strcpy_s function copies the string pointed to by strSrc (including + * the terminating null character) into the array pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCPY + /* + * Description: The strncpy_s function copies not more than n successive characters (not including + * the terminating null character) from the array pointed to by strSrc to the array pointed to by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Parameter: strSrc - source address + * Parameter: count - copies count characters from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_STRCAT + /* + * Description: The strcat_s function appends a copy of the string pointed to by strSrc (including + * the terminating null character) to the end of the string pointed to by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character) + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCAT + /* + * Description: The strncat_s function appends not more than n successive characters (not including + * the terminating null character) + * from the array pointed to by strSrc to the end of the string pointed to by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Parameter: strSrc - source address + * Parameter: count - copies count characters from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_VSPRINTF + /* + * Description: The vsprintf_s function is equivalent to the vsprintf function except for the parameter destMax + * and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide characte) + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1. + */ + SECUREC_API int vsprintf_s(char *strDest, size_t destMax, const char *format, + va_list argList) SECUREC_ATTRIBUTE(3, 0); +#endif + +#if SECUREC_ENABLE_SPRINTF + /* + * Description: The sprintf_s function is equivalent to the sprintf function except for the parameter destMax + * and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: format - fromat string + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1. + */ + SECUREC_API int sprintf_s(char *strDest, size_t destMax, const char *format, ...) SECUREC_ATTRIBUTE(3, 4); +#endif + +#if SECUREC_ENABLE_VSNPRINTF + /* + * Description: The vsnprintf_s function is equivalent to the vsnprintf function except for + * the parameter destMax/count and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0') + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs + */ + SECUREC_API int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, + va_list argList) SECUREC_ATTRIBUTE(4, 0); +#endif + +#if SECUREC_ENABLE_SNPRINTF + /* + * Description: The snprintf_s function is equivalent to the snprintf function except for + * the parameter destMax/count and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0') + * Parameter: format - fromat string + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs + */ + SECUREC_API int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, + ...) SECUREC_ATTRIBUTE(4, 5); +#endif + +#if SECUREC_SNPRINTF_TRUNCATED + /* + * Description: The vsnprintf_truncated_s function is equivalent to the vsnprintf_s function except + * no count parameter and return value + * Parameter: strDest - produce output according to a format ,write to the character string strDest + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs + */ + SECUREC_API int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, + va_list argList) SECUREC_ATTRIBUTE(3, 0); + + /* + * Description: The snprintf_truncated_s function is equivalent to the snprintf_2 function except + * no count parameter and return value + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: format - fromat string + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs + */ + SECUREC_API int snprintf_truncated_s(char *strDest, size_t destMax, + const char *format, ...) SECUREC_ATTRIBUTE(3, 4); +#endif + +#if SECUREC_ENABLE_SCANF + /* + * Description: The scanf_s function is equivalent to fscanf_s with the argument stdin + * interposed before the arguments to scanf_s + * Parameter: format - fromat string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int scanf_s(const char *format, ...); +#endif + +#if SECUREC_ENABLE_VSCANF + /* + * Description: The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int vscanf_s(const char *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SSCANF + /* + * Description: The sscanf_s function is equivalent to fscanf_s, except that input is obtained from a + * string (specified by the argument buffer) rather than from a stream + * Parameter: buffer - read character from buffer + * Parameter: format - fromat string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int sscanf_s(const char *buffer, const char *format, ...); +#endif + +#if SECUREC_ENABLE_VSSCANF + /* + * Description: The vsscanf_s function is equivalent to sscanf_s, with the variable argument list + * replaced by argList + * Parameter: buffer - read character from buffer + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int vsscanf_s(const char *buffer, const char *format, va_list argList); +#endif + +#if SECUREC_ENABLE_FSCANF + /* + * Description: The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers + * apply to a pair of arguments (unless assignment suppression is indicated by a*) + * Parameter: stream - stdio file stream + * Parameter: format - fromat string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int fscanf_s(FILE *stream, const char *format, ...); +#endif + +#if SECUREC_ENABLE_VFSCANF + /* + * Description: The vfscanf_s function is equivalent to fscanf_s, with the variable argument list + * replaced by argList + * Parameter: stream - stdio file stream + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int vfscanf_s(FILE *stream, const char *format, va_list argList); +#endif + +#if SECUREC_ENABLE_STRTOK + /* + * Description: The strtok_s function parses a string into a sequence of strToken, + * replace all characters in strToken string that match to strDelimit set with 0. + * On the first call to strtok_s the string to be parsed should be specified in strToken. + * In each subsequent call that should parse the same string, strToken should be NULL + * Parameter: strToken - the string to be delimited + * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string + * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function + * Return: On the first call returns the address of the first non \0 character, otherwise NULL is returned. + * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call, + * return NULL if the *context string length is equal 0, otherwise return *context. + */ + SECUREC_API char *strtok_s(char *strToken, const char *strDelimit, char **context); +#endif + +#if SECUREC_ENABLE_GETS && !SECUREC_IN_KERNEL + /* + * Description: The gets_s function reads at most one less than the number of characters specified + * by destMax from the stream pointed to by stdin, into the array pointed to by buffer + * Parameter: buffer - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Return: buffer if there was no runtime-constraint violation,If an error occurred Return: NULL. + */ + SECUREC_API char *gets_s(char *buffer, size_t destMax); +#endif + +#if SECUREC_ENABLE_WCHAR_FUNC +#if SECUREC_ENABLE_MEMCPY + /* + * Description: The wmemcpy_s function copies n successive wide characters from the object pointed to + * by src into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count); +#endif + +#if SECUREC_ENABLE_MEMMOVE + /* + * Description: The wmemmove_s function copies n successive wide characters from the object + * pointed to by src into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count); +#endif + +#if SECUREC_ENABLE_STRCPY + /* + * Description: The wcscpy_s function copies the wide string pointed to by strSrc (including theterminating + * null wide character) into the array pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCPY + /* + * Description: The wcsncpy_s function copies not more than n successive wide characters (not including the + * terminating null wide character) from the array pointed to by strSrc to the array pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) + * Parameter: strSrc - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_STRCAT + /* + * Description: The wcscat_s function appends a copy of the wide string pointed to by strSrc (including the + * terminating null wide character) to the end of the wide string pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCAT + /* + * Description: The wcsncat_s function appends not more than n successive wide characters (not including the + * terminating null wide character) from the array pointed to by strSrc to the end of the wide string pointed to + * by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) + * Parameter: strSrc - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ + SECUREC_API errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_STRTOK + /* + * Description: The wcstok_s function is the wide-character equivalent of the strtok_s function + * Parameter: strToken - the string to be delimited + * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string + * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function + * Return: a pointer to the first character of a token, or a null pointer if there is no token + * or there is a runtime-constraint violation. + */ + SECUREC_API wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context); +#endif + +#if SECUREC_ENABLE_VSPRINTF + /* + * Description: The vswprintf_s function is the wide-character equivalent of the vsprintf_s function + * Parameter: strDest - produce output according to a format ,write to the character string strDest + * Parameter: destMax - The maximum length of destination buffer(including the terminating null ) + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null wide characte), + * If an error occurred Return: -1. + */ + SECUREC_API int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SPRINTF + + /* + * Description: The swprintf_s function is the wide-character equivalent of the sprintf_s function + * Parameter: strDest - produce output according to a format ,write to the character string strDest + * Parameter: destMax - The maximum length of destination buffer(including the terminating null ) + * Parameter: format - fromat string + * Return: the number of characters printed(not including the terminating null wide characte), + * If an error occurred Return: -1. + */ + SECUREC_API int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_FSCANF + /* + * Description: The fwscanf_s function is the wide-character equivalent of the fscanf_s function + * Parameter: stream - stdio file stream + * Parameter: format - fromat string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int fwscanf_s(FILE *stream, const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_VFSCANF + /* + * Description: The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function + * Parameter: stream - stdio file stream + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SCANF + /* + * Description: The wscanf_s function is the wide-character equivalent of the scanf_s function + * Parameter: format - fromat string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int wscanf_s(const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_VSCANF + /* + * Description: The vwscanf_s function is the wide-character equivalent of the vscanf_s function + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int vwscanf_s(const wchar_t *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SSCANF + /* + * Description: The swscanf_s function is the wide-character equivalent of the sscanf_s function + * Parameter: buffer - read character from buffer + * Parameter: format - fromat string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_VSSCANF + /* + * Description: The vswscanf_s function is the wide-character equivalent of the vsscanf_s function + * Parameter: buffer - read character from buffer + * Parameter: format - fromat string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ + SECUREC_API int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList); +#endif +#endif /* SECUREC_ENABLE_WCHAR_FUNC */ +#endif + + /* Those functions are used by macro ,must declare hare , also for without function declaration warning */ + extern errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count); + extern errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc); + +#if SECUREC_WITH_PERFORMANCE_ADDONS + /* Those functions are used by macro */ + extern errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count); + extern errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count); + extern errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count); + extern errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count); + +/* The strcpy_sp is a macro, not a function in performance optimization mode. */ +#define strcpy_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRCPY_SM((dest), (destMax), (src)) : \ + strcpy_s((dest), (destMax), (src))) + +/* The strncpy_sp is a macro, not a function in performance optimization mode. */ +#define strncpy_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) && \ + __builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRNCPY_SM((dest), (destMax), (src), (count)) : \ + strncpy_s((dest), (destMax), (src), (count))) + +/* The strcat_sp is a macro, not a function in performance optimization mode. */ +#define strcat_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRCAT_SM((dest), (destMax), (src)) : \ + strcat_s((dest), (destMax), (src))) + +/* The strncat_sp is a macro, not a function in performance optimization mode. */ +#define strncat_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) && \ + __builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRNCAT_SM((dest), (destMax), (src), (count)) : \ + strncat_s((dest), (destMax), (src), (count))) + +/* The memcpy_sp is a macro, not a function in performance optimization mode. */ +#define memcpy_sp(dest, destMax, src, count) (__builtin_constant_p((count)) ? \ + (SECUREC_MEMCPY_SM((dest), (destMax), (src), (count))) : \ + (__builtin_constant_p((destMax)) ? \ + (((size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \ + memcpy_sOptTc((dest), (destMax), (src), (count)) : ERANGE) : \ + memcpy_sOptAsm((dest), (destMax), (src), (count)))) + +/* The memset_sp is a macro, not a function in performance optimization mode. */ +#define memset_sp(dest, destMax, c, count) (__builtin_constant_p((count)) ? \ + (SECUREC_MEMSET_SM((dest), (destMax), (c), (count))) : \ + (__builtin_constant_p((destMax)) ? \ + (((((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \ + memset_sOptTc((dest), (destMax), (c), (count)) : ERANGE) : \ + memset_sOptAsm((dest), (destMax), (c), (count)))) + +#endif + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/components/lib/libsec/include/securectype.h b/components/lib/libsec/include/securectype.h new file mode 100644 index 000000000..17cca940d --- /dev/null +++ b/components/lib/libsec/include/securectype.h @@ -0,0 +1,570 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define internal used macro and data type. The marco of SECUREC_ON_64BITS + * will be determined in this header file, which is a switch for part + * of code. Some macro are used to supress warning by MS compiler. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7 +#define SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7 + +#ifndef SECUREC_USING_STD_SECURE_LIB +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#if defined(__STDC_WANT_SECURE_LIB__) && (!__STDC_WANT_SECURE_LIB__) +/* Security functions have been provided since vs2005, default use of system library functions */ +#define SECUREC_USING_STD_SECURE_LIB 0 +#else +#define SECUREC_USING_STD_SECURE_LIB 1 +#endif +#else +#define SECUREC_USING_STD_SECURE_LIB 0 +#endif +#endif + +/* Compatibility with older Secure C versions, shielding VC symbol redefinition warning */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!SECUREC_USING_STD_SECURE_LIB) +#ifndef SECUREC_DISABLE_CRT_FUNC +#define SECUREC_DISABLE_CRT_FUNC 1 +#endif +#ifndef SECUREC_DISABLE_CRT_IMP +#define SECUREC_DISABLE_CRT_IMP 1 +#endif +#else /* MSC VER */ +#ifndef SECUREC_DISABLE_CRT_FUNC +#define SECUREC_DISABLE_CRT_FUNC 0 +#endif +#ifndef SECUREC_DISABLE_CRT_IMP +#define SECUREC_DISABLE_CRT_IMP 0 +#endif +#endif + +#if SECUREC_DISABLE_CRT_FUNC +#ifdef __STDC_WANT_SECURE_LIB__ +#undef __STDC_WANT_SECURE_LIB__ +#endif +#define __STDC_WANT_SECURE_LIB__ 0 +#endif + +#if SECUREC_DISABLE_CRT_IMP +#ifdef _CRTIMP_ALTERNATIVE +#undef _CRTIMP_ALTERNATIVE +#endif +#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */ +#endif + +/* Compile in kernel under macro control */ +#ifndef SECUREC_IN_KERNEL +#ifdef __KERNEL__ +#define SECUREC_IN_KERNEL 1 +#else +#define SECUREC_IN_KERNEL 0 +#endif +#endif + +#if SECUREC_IN_KERNEL +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 0 +#endif +#ifndef SECUREC_ENABLE_WCHAR_FUNC +#define SECUREC_ENABLE_WCHAR_FUNC 0 +#endif +#else /* SECUREC_IN_KERNEL */ +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 1 +#endif +#ifndef SECUREC_ENABLE_WCHAR_FUNC +#define SECUREC_ENABLE_WCHAR_FUNC 1 +#endif +#endif + +/* Default secure function declaration, default declarations for non-standard functions */ +#ifndef SECUREC_SNPRINTF_TRUNCATED +#define SECUREC_SNPRINTF_TRUNCATED 1 +#endif + +#if SECUREC_USING_STD_SECURE_LIB +#if defined(_MSC_VER) && _MSC_VER >= 1400 +/* Declare secure functions that are not available in the VS compiler */ +#ifndef SECUREC_ENABLE_MEMSET +#define SECUREC_ENABLE_MEMSET 1 +#endif +/* VS 2005 have vsnprintf_s function */ +#ifndef SECUREC_ENABLE_VSNPRINTF +#define SECUREC_ENABLE_VSNPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_SNPRINTF +/* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security function */ +#define snprintf_s _snprintf_s +#define SECUREC_ENABLE_SNPRINTF 0 +#endif +/* Before VS 2010 do not have v functions */ +#if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS) +#ifndef SECUREC_ENABLE_VFSCANF +#define SECUREC_ENABLE_VFSCANF 1 +#endif +#ifndef SECUREC_ENABLE_VSCANF +#define SECUREC_ENABLE_VSCANF 1 +#endif +#ifndef SECUREC_ENABLE_VSSCANF +#define SECUREC_ENABLE_VSSCANF 1 +#endif +#endif + +#else /* MSC VER */ +#ifndef SECUREC_ENABLE_MEMSET +#define SECUREC_ENABLE_MEMSET 0 +#endif +#ifndef SECUREC_ENABLE_SNPRINTF +#define SECUREC_ENABLE_SNPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_VSNPRINTF +#define SECUREC_ENABLE_VSNPRINTF 0 +#endif +#endif + +#ifndef SECUREC_ENABLE_MEMMOVE +#define SECUREC_ENABLE_MEMMOVE 0 +#endif +#ifndef SECUREC_ENABLE_MEMCPY +#define SECUREC_ENABLE_MEMCPY 0 +#endif +#ifndef SECUREC_ENABLE_STRCPY +#define SECUREC_ENABLE_STRCPY 0 +#endif +#ifndef SECUREC_ENABLE_STRNCPY +#define SECUREC_ENABLE_STRNCPY 0 +#endif +#ifndef SECUREC_ENABLE_STRCAT +#define SECUREC_ENABLE_STRCAT 0 +#endif +#ifndef SECUREC_ENABLE_STRNCAT +#define SECUREC_ENABLE_STRNCAT 0 +#endif +#ifndef SECUREC_ENABLE_SPRINTF +#define SECUREC_ENABLE_SPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_VSPRINTF +#define SECUREC_ENABLE_VSPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_SSCANF +#define SECUREC_ENABLE_SSCANF 0 +#endif +#ifndef SECUREC_ENABLE_VSSCANF +#define SECUREC_ENABLE_VSSCANF 0 +#endif +#ifndef SECUREC_ENABLE_SCANF +#define SECUREC_ENABLE_SCANF 0 +#endif +#ifndef SECUREC_ENABLE_VSCANF +#define SECUREC_ENABLE_VSCANF 0 +#endif + +#ifndef SECUREC_ENABLE_FSCANF +#define SECUREC_ENABLE_FSCANF 0 +#endif +#ifndef SECUREC_ENABLE_VFSCANF +#define SECUREC_ENABLE_VFSCANF 0 +#endif +#ifndef SECUREC_ENABLE_STRTOK +#define SECUREC_ENABLE_STRTOK 0 +#endif +#ifndef SECUREC_ENABLE_GETS +#define SECUREC_ENABLE_GETS 0 +#endif + +#else /* SECUREC USE STD SECURE LIB */ + +#ifndef SECUREC_ENABLE_MEMSET +#define SECUREC_ENABLE_MEMSET 1 +#endif +#ifndef SECUREC_ENABLE_MEMMOVE +#define SECUREC_ENABLE_MEMMOVE 1 +#endif +#ifndef SECUREC_ENABLE_MEMCPY +#define SECUREC_ENABLE_MEMCPY 1 +#endif +#ifndef SECUREC_ENABLE_STRCPY +#define SECUREC_ENABLE_STRCPY 1 +#endif +#ifndef SECUREC_ENABLE_STRNCPY +#define SECUREC_ENABLE_STRNCPY 1 +#endif +#ifndef SECUREC_ENABLE_STRCAT +#define SECUREC_ENABLE_STRCAT 1 +#endif +#ifndef SECUREC_ENABLE_STRNCAT +#define SECUREC_ENABLE_STRNCAT 1 +#endif +#ifndef SECUREC_ENABLE_SPRINTF +#define SECUREC_ENABLE_SPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_VSPRINTF +#define SECUREC_ENABLE_VSPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_SNPRINTF +#define SECUREC_ENABLE_SNPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_VSNPRINTF +#define SECUREC_ENABLE_VSNPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_SSCANF +#define SECUREC_ENABLE_SSCANF 1 +#endif +#ifndef SECUREC_ENABLE_VSSCANF +#define SECUREC_ENABLE_VSSCANF 1 +#endif +#ifndef SECUREC_ENABLE_SCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF 1 +#else +#define SECUREC_ENABLE_SCANF 0 +#endif +#endif +#ifndef SECUREC_ENABLE_VSCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_VSCANF 1 +#else +#define SECUREC_ENABLE_VSCANF 0 +#endif +#endif + +#ifndef SECUREC_ENABLE_FSCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_FSCANF 1 +#else +#define SECUREC_ENABLE_FSCANF 0 +#endif +#endif +#ifndef SECUREC_ENABLE_VFSCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_VFSCANF 1 +#else +#define SECUREC_ENABLE_VFSCANF 0 +#endif +#endif + +#ifndef SECUREC_ENABLE_STRTOK +#define SECUREC_ENABLE_STRTOK 1 +#endif +#ifndef SECUREC_ENABLE_GETS +#define SECUREC_ENABLE_GETS 1 +#endif +#endif /* SECUREC_USE_STD_SECURE_LIB */ + +#if !SECUREC_ENABLE_SCANF_FILE +#if SECUREC_ENABLE_FSCANF +#undef SECUREC_ENABLE_FSCANF +#define SECUREC_ENABLE_FSCANF 0 +#endif +#if SECUREC_ENABLE_VFSCANF +#undef SECUREC_ENABLE_VFSCANF +#define SECUREC_ENABLE_VFSCANF 0 +#endif +#if SECUREC_ENABLE_SCANF +#undef SECUREC_ENABLE_SCANF +#define SECUREC_ENABLE_SCANF 0 +#endif +#if SECUREC_ENABLE_FSCANF +#undef SECUREC_ENABLE_FSCANF +#define SECUREC_ENABLE_FSCANF 0 +#endif + +#endif + +#if SECUREC_IN_KERNEL +#include +#include +#else +#ifndef SECUREC_HAVE_STDIO_H +#define SECUREC_HAVE_STDIO_H 1 +#endif +#ifndef SECUREC_HAVE_STRING_H +#define SECUREC_HAVE_STRING_H 1 +#endif +#ifndef SECUREC_HAVE_STDLIB_H +#define SECUREC_HAVE_STDLIB_H 1 +#endif +#if SECUREC_HAVE_STDIO_H +#include +#endif +#if SECUREC_HAVE_STRING_H +#include +#endif +#if SECUREC_HAVE_STDLIB_H +#include +#endif +#endif + +/* + * If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS macro, default is enable. + * The macro is automatically closed on the windows platform and linux kernel + */ +#ifndef SECUREC_WITH_PERFORMANCE_ADDONS +#if SECUREC_IN_KERNEL +#define SECUREC_WITH_PERFORMANCE_ADDONS 0 +#else +#define SECUREC_WITH_PERFORMANCE_ADDONS 1 +#endif +#endif + +/* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */ +#if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && !defined(SECUREC_COMPATIBLE_LINUX_FORMAT) +#ifndef SECUREC_COMPATIBLE_WIN_FORMAT +#define SECUREC_COMPATIBLE_WIN_FORMAT +#endif +#endif + +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) +/* On windows platform, can't use optimized function for there is no __builtin_constant_p like function */ +/* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */ +#ifdef SECUREC_WITH_PERFORMANCE_ADDONS +#undef SECUREC_WITH_PERFORMANCE_ADDONS +#define SECUREC_WITH_PERFORMANCE_ADDONS 0 +#endif +#endif + +#if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || defined(_VXWORKS_PLATFORM_) || \ + defined(SECUREC_VXWORKS_VERSION_5_4) +#ifndef SECUREC_VXWORKS_PLATFORM +#define SECUREC_VXWORKS_PLATFORM +#endif +#endif + +/* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */ +#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && !defined(SECUREC_VXWORKS_PLATFORM) +#ifndef SECUREC_COMPATIBLE_LINUX_FORMAT +#define SECUREC_COMPATIBLE_LINUX_FORMAT +#endif +#endif + +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT +#ifndef SECUREC_HAVE_STDDEF_H +#define SECUREC_HAVE_STDDEF_H 1 +#endif +/* Some system may no stddef.h */ +#if SECUREC_HAVE_STDDEF_H +#if !SECUREC_IN_KERNEL +#include +#endif +#endif +#endif + +/* + * Add the -DSECUREC_SUPPORT_FORMAT_WARNING=1 compiler option to supoort -Wformat=2. + * Default does not check the format is that the same data type in the actual code. + * In the product is different in the original data type definition of VxWorks and Linux. + */ +#ifndef SECUREC_SUPPORT_FORMAT_WARNING +#define SECUREC_SUPPORT_FORMAT_WARNING 0 +#endif + +#if SECUREC_SUPPORT_FORMAT_WARNING +#define SECUREC_ATTRIBUTE(x, y) __attribute__((format(printf, (x), (y)))) +#else +#define SECUREC_ATTRIBUTE(x, y) +#endif + +/* + * Add the -DSECUREC_SUPPORT_BUILTIN_EXPECT=0 compiler option, if complier can not support __builtin_expect. + */ +#ifndef SECUREC_SUPPORT_BUILTIN_EXPECT +#define SECUREC_SUPPORT_BUILTIN_EXPECT 1 +#endif + +#if SECUREC_SUPPORT_BUILTIN_EXPECT && defined(__GNUC__) && ((__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))) +/* + * This is a built-in function that can be used without a declaration, if warning for declaration not found occurred, + * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to complier options + */ +#ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE +long __builtin_expect(long exp, long c); +#endif + +#define SECUREC_LIKELY(x) __builtin_expect(!!(x), 1) +#define SECUREC_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define SECUREC_LIKELY(x) (x) +#define SECUREC_UNLIKELY(x) (x) +#endif + +/* Define the max length of the string */ +#ifndef SECUREC_STRING_MAX_LEN +#define SECUREC_STRING_MAX_LEN 0x7fffffffUL +#endif +#define SECUREC_WCHAR_STRING_MAX_LEN (SECUREC_STRING_MAX_LEN / sizeof(wchar_t)) + +/* Add SECUREC_MEM_MAX_LEN for memcpy and memmove */ +#ifndef SECUREC_MEM_MAX_LEN +#define SECUREC_MEM_MAX_LEN 0x7fffffffUL +#endif +#define SECUREC_WCHAR_MEM_MAX_LEN (SECUREC_MEM_MAX_LEN / sizeof(wchar_t)) + +#if SECUREC_STRING_MAX_LEN > 0x7fffffffUL +#error "max string is 2G" +#endif + +#if (defined(__GNUC__) && defined(__SIZEOF_POINTER__)) +#if (__SIZEOF_POINTER__ != 4) && (__SIZEOF_POINTER__ != 8) +#error "unsupported system" +#endif +#endif + +#if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64) +#define SECUREC_ON_64BITS +#endif + +#if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && defined(__SIZEOF_POINTER__)) +#if __SIZEOF_POINTER__ == 8 +#define SECUREC_ON_64BITS +#endif +#endif + +#if defined(__SVR4) || defined(__svr4__) +#define SECUREC_ON_SOLARIS +#endif + +#if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS)) +#define SECUREC_ON_UNIX +#endif + +/* + * Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknow system on default, + * and strtold. + * The function strtold is referenced first at ISO9899:1999(C99), and some old compilers can + * not support these functions. Here provides a macro to open these functions: + * SECUREC_SUPPORT_STRTOLD -- If defined, strtold will be used + */ +#ifndef SECUREC_SUPPORT_STRTOLD +#define SECUREC_SUPPORT_STRTOLD 0 +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) +#if defined(__USE_ISOC99) || \ + (defined(_AIX) && defined(_ISOC99_SOURCE)) || \ + (defined(__hpux) && defined(__ia64)) || \ + (defined(SECUREC_ON_SOLARIS) && (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ + defined(_STDC_C99) || defined(__EXTENSIONS__)) +#undef SECUREC_SUPPORT_STRTOLD +#define SECUREC_SUPPORT_STRTOLD 1 +#endif +#endif +#if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_))) +#undef SECUREC_SUPPORT_STRTOLD +#define SECUREC_SUPPORT_STRTOLD 0 +#endif +#endif + +#if SECUREC_WITH_PERFORMANCE_ADDONS + +#ifndef SECUREC_TWO_MIN +#define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* For strncpy_s performance optimization */ +#define SECUREC_STRNCPY_SM(dest, destMax, src, count) \ + (((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ + (SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= (size_t)(destMax)) ? \ + (((size_t)(count) < strlen(src)) ? (memcpy((dest), (src), (count)), *((char *)(dest) + (count)) = '\0', EOK) : \ + (memcpy((dest), (src), strlen(src) + 1), EOK)) : (strncpy_error((dest), (destMax), (src), (count)))) + +#define SECUREC_STRCPY_SM(dest, destMax, src) \ + (((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ + (strlen(src) + 1) <= (size_t)(destMax)) ? (memcpy((dest), (src), strlen(src) + 1), EOK) : \ + (strcpy_error((dest), (destMax), (src)))) + +/* For strcat_s performance optimization */ +#if defined(__GNUC__) +#define SECUREC_STRCAT_SM(dest, destMax, src) ({ \ + int catRet_ = EOK; \ + if ((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ + char *catTmpDst_ = (char *)(dest); \ + size_t catRestSize_ = (destMax); \ + while (catRestSize_ > 0 && *catTmpDst_ != '\0') { \ + ++catTmpDst_; \ + --catRestSize_; \ + } \ + if (catRestSize_ == 0) { \ + catRet_ = EINVAL; \ + } else if ((strlen(src) + 1) <= catRestSize_) { \ + memcpy(catTmpDst_, (src), strlen(src) + 1); \ + catRet_ = EOK; \ + } else { \ + catRet_ = ERANGE; \ + } \ + if (catRet_ != EOK) { \ + catRet_ = strcat_s((dest), (destMax), (src)); \ + } \ + } else { \ + catRet_ = strcat_s((dest), (destMax), (src)); \ + } \ + catRet_; \ +}) +#else +#define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src)) +#endif + +/* For strncat_s performance optimization */ +#if defined(__GNUC__) +#define SECUREC_STRNCAT_SM(dest, destMax, src, count) ({ \ + int ncatRet_ = EOK; \ + if ((void *)(dest) != NULL && (void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ + (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ + char *ncatTmpDest_ = (char *)(dest); \ + size_t ncatRestSize_ = (size_t)(destMax); \ + while (ncatRestSize_ > 0 && *ncatTmpDest_ != '\0') { \ + ++ncatTmpDest_; \ + --ncatRestSize_; \ + } \ + if (ncatRestSize_ == 0) { \ + ncatRet_ = EINVAL; \ + } else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= ncatRestSize_) { \ + if ((size_t)(count) < strlen(src)) { \ + memcpy(ncatTmpDest_, (src), (count)); \ + *(ncatTmpDest_ + (count)) = '\0'; \ + } else { \ + memcpy(ncatTmpDest_, (src), strlen(src) + 1); \ + } \ + } else { \ + ncatRet_ = ERANGE; \ + } \ + if (ncatRet_ != EOK) { \ + ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \ + } \ + } else { \ + ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \ + } \ + ncatRet_; \ +}) +#else +#define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s((dest), (destMax), (src), (count)) +#endif + +/* This macro do not check buffer overlap by default */ +#define SECUREC_MEMCPY_SM(dest, destMax, src, count) \ + (!(((size_t)(destMax) == 0) || \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ + ((size_t)(count) > (size_t)(destMax)) || ((void *)(dest)) == NULL || ((void *)(src) == NULL)) ? \ + (memcpy((dest), (src), (count)), EOK) : \ + (memcpy_s((dest), (destMax), (src), (count)))) + +#define SECUREC_MEMSET_SM(dest, destMax, c, count) \ + (!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ + ((void *)(dest) == NULL) || ((size_t)(count) > (size_t)(destMax))) ? \ + (memset((dest), (c), (count)), EOK) : \ + (memset_s((dest), (destMax), (c), (count)))) + +#endif +#endif + diff --git a/components/lib/libsec/libmk b/components/lib/libsec/libmk new file mode 100644 index 000000000..b4de400d3 --- /dev/null +++ b/components/lib/libsec/libmk @@ -0,0 +1,13 @@ +include $(LITEOSTOPDIR)/config.mk + +ARFLAGS = cr + +all: + mkdir -p $(OUT)/lib + cp -rf $(LITEOS_CPU_TYPE)/*.a $(OUT)/lib + + +clean: + rm -rf $(OUT)/lib/libsec.a + +.PHONY: all clean diff --git a/components/lib/libsec/src/fscanf_s.c b/components/lib/libsec/src/fscanf_s.c new file mode 100644 index 000000000..2d1e735c3 --- /dev/null +++ b/components/lib/libsec/src/fscanf_s.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: fscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The fscanf_s function is equivalent to fscanf except that the c, s, + * and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a*) + * The fscanf function reads data from the current position of stream into + * the locations given by argument (if any). Each argument must be a pointer + * to a variable of a type that corresponds to a type specifier in format. + * format controls the interpretation of the input fields and has the same + * form and function as the format argument for scanf. + * + * + * stream Pointer to FILE structure. + * format Format control string, see Format Specifications. + * ... Optional arguments. + * + * + * ... The convered value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int fscanf_s(FILE *stream, const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vfscanf_s(stream, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + diff --git a/components/lib/libsec/src/fwscanf_s.c b/components/lib/libsec/src/fwscanf_s.c new file mode 100644 index 000000000..ed2438b1d --- /dev/null +++ b/components/lib/libsec/src/fwscanf_s.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: fwscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The fwscanf_s function is the wide-character equivalent of the fscanf_s function + * The fwscanf_s function reads data from the current position of stream into + * the locations given by argument (if any). Each argument must be a pointer + * to a variable of a type that corresponds to a type specifier in format. + * format controls the interpretation of the input fields and has the same + * form and function as the format argument for scanf. + * + * + * stream Pointer to FILE structure. + * format Format control string, see Format Specifications. + * ... Optional arguments. + * + * + * ... The converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int fwscanf_s(FILE *stream, const wchar_t *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vfwscanf_s(stream, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + diff --git a/components/lib/libsec/src/gets_s.c b/components/lib/libsec/src/gets_s.c new file mode 100644 index 000000000..18d785888 --- /dev/null +++ b/components/lib/libsec/src/gets_s.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: gets_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * The parameter size is buffer size in byte + */ +SECUREC_INLINE void SecTrimCRLF(char *buffer, size_t size) +{ + size_t len = strlen(buffer); + --len; /* Unsigned integer wrapping is accepted and is checked afterwards */ + while (len < size && (buffer[len] == '\r' || buffer[len] == '\n')) { + buffer[len] = '\0'; + --len; /* Unsigned integer wrapping is accepted and is checked next loop */ + } +} + +/* + * + * The gets_s function reads at most one less than the number of characters + * specified by destMax from the std input stream, into the array pointed to by buffer + * The line consists of all characters up to and including + * the first newline character ('\n'). gets_s then replaces the newline + * character with a null character ('\0') before returning the line. + * If the first character read is the end-of-file character, a null character + * is stored at the beginning of buffer and NULL is returned. + * + * + * buffer Storage location for input string. + * destMax The size of the buffer. + * + * + * buffer is updated + * + * + * buffer Successful operation + * NULL Improper parameter or read fail + */ +char *gets_s(char *buffer, size_t destMax) +{ +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT + size_t bufferSize = ((destMax == (size_t)(-1)) ? SECUREC_STRING_MAX_LEN : destMax); +#else + size_t bufferSize = destMax; +#endif + + if (buffer == NULL || bufferSize == 0 || bufferSize > SECUREC_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_PARAMTER("gets_s"); + return NULL; + } + + if (fgets(buffer, (int)bufferSize, SECUREC_STREAM_STDIN) != NULL) { + SecTrimCRLF(buffer, bufferSize); + return buffer; + } + + return NULL; +} + diff --git a/components/lib/libsec/src/input.inl b/components/lib/libsec/src/input.inl new file mode 100644 index 000000000..06fff4157 --- /dev/null +++ b/components/lib/libsec/src/input.inl @@ -0,0 +1,2227 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Used by secureinput_a.c and secureinput_w.c to include. + * This file provides a template function for ANSI and UNICODE compiling by + * different type definition. The functions of SecInputS or + * SecInputSW provides internal implementation for scanf family API, such as sscanf_s, fscanf_s. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 +#define INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 + +#if SECUREC_IN_KERNEL +#if !defined(SECUREC_CTYPE_MACRO_ADAPT) +#include +#endif +#else +#if !defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT) +#include +#ifdef SECUREC_FOR_WCHAR +#include /* For iswspace */ +#endif +#endif +#endif + +#ifndef EOF +#define EOF (-1) +#endif + +#define SECUREC_NUM_WIDTH_SHORT 0 +#define SECUREC_NUM_WIDTH_INT 1 +#define SECUREC_NUM_WIDTH_LONG 2 +#define SECUREC_NUM_WIDTH_LONG_LONG 3 /* Also long double */ + +#define SECUREC_BUFFERED_BLOK_SIZE 1024U + +#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(va_copy) && !defined(__va_copy) +/* The name is the same as system macro. */ +#define __va_copy(dest, src) do { \ + size_t destSize_ = (size_t)sizeof(dest); \ + size_t srcSize_ = (size_t)sizeof(src); \ + if (destSize_ != srcSize_) { \ + (void)memcpy((dest), (src), sizeof(va_list)); \ + } else { \ + (void)memcpy(&(dest), &(src), sizeof(va_list)); \ + } \ +} SECUREC_WHILE_ZERO +#endif + +#define SECUREC_MULTI_BYTE_MAX_LEN 6 + +/* Compatibility macro name cannot be modifie */ +#ifndef UNALIGNED +#if !(defined(_M_IA64)) && !(defined(_M_AMD64)) +#define UNALIGNED +#else +#define UNALIGNED __unaligned +#endif +#endif + +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) +/* Max 64bit value is 0xffffffffffffffff */ +#define SECUREC_MAX_64BITS_VALUE 18446744073709551615ULL +#define SECUREC_MAX_64BITS_VALUE_DIV_TEN 1844674407370955161ULL +#define SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT 18446744073709551610ULL +#define SECUREC_MIN_64BITS_NEG_VALUE 9223372036854775808ULL +#define SECUREC_MAX_64BITS_POS_VALUE 9223372036854775807ULL +#define SECUREC_MIN_32BITS_NEG_VALUE 2147483648UL +#define SECUREC_MAX_32BITS_POS_VALUE 2147483647UL +#define SECUREC_MAX_32BITS_VALUE 4294967295UL +#define SECUREC_MAX_32BITS_VALUE_INC 4294967296UL +#define SECUREC_MAX_32BITS_VALUE_DIV_TEN 429496729UL +#define SECUREC_LONG_BIT_NUM ((unsigned int)(sizeof(long) << 3U)) +/* Use ULL to clean up cl6x compilation alerts */ +#define SECUREC_MAX_LONG_POS_VALUE ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)) - 1) +#define SECUREC_MIN_LONG_NEG_VALUE ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1))) + +/* Covert to long long to clean up cl6x compilation alerts */ +#define SECUREC_LONG_HEX_BEYOND_MAX(number) (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 4U)) > 0) +#define SECUREC_LONG_OCTAL_BEYOND_MAX(number) (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 3U)) > 0) + +#define SECUREC_QWORD_HEX_BEYOND_MAX(number) (((number) >> (64U - 4U)) > 0) +#define SECUREC_QWORD_OCTAL_BEYOND_MAX(number) (((number) >> (64U - 3U)) > 0) + +#define SECUREC_LP64_BIT_WIDTH 64 +#define SECUREC_LP32_BIT_WIDTH 32 + +#define SECUREC_CONVERT_IS_SIGNED(conv) ((conv) == 'd' || (conv) == 'i') +#endif + +#define SECUREC_BRACE '{' /* [ to { */ +#define SECUREC_FILED_WIDTH_ENOUGH(spec) ((spec)->widthSet == 0 || (spec)->width > 0) +#define SECUREC_FILED_WIDTH_DEC(spec) do { \ + if ((spec)->widthSet != 0) { \ + --(spec)->width; \ + } \ +} SECUREC_WHILE_ZERO + +#ifdef SECUREC_FOR_WCHAR +/* Bits for all wchar, size is 65536/8, only supports wide characters with a maximum length of two bytes */ +#define SECUREC_BRACKET_TABLE_SIZE 8192 +#define SECUREC_EOF WEOF +#define SECUREC_MB_LEN 16 /* Max. # bytes in multibyte char ,see MB_LEN_MAX */ +#else +/* Bits for all char, size is 256/8 */ +#define SECUREC_BRACKET_TABLE_SIZE 32 +#define SECUREC_EOF EOF +#endif + +#if SECUREC_HAVE_WCHART +#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || \ + ((spec).isWCharOrLong <= 0 && (spec).arrayWidth > SECUREC_STRING_MAX_LEN) || \ + ((spec).isWCharOrLong > 0 && (spec).arrayWidth > SECUREC_WCHAR_STRING_MAX_LEN)) +#else +#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || (spec).arrayWidth > SECUREC_STRING_MAX_LEN) +#endif + +typedef struct { +#ifdef SECUREC_FOR_WCHAR + unsigned char *table; /* Default NULL */ +#else + unsigned char table[SECUREC_BRACKET_TABLE_SIZE]; /* Array length is large enough in application scenarios */ +#endif + unsigned char mask; /* Default 0 */ +} SecBracketTable; + +#ifdef SECUREC_FOR_WCHAR +#define SECUREC_INIT_BRACKET_TABLE { NULL, 0 } +#else +#define SECUREC_INIT_BRACKET_TABLE { {0}, 0 } +#endif + +#if SECUREC_ENABLE_SCANF_FLOAT +typedef struct { + size_t floatStrTotalLen; /* Initialization must be length of buffer in charater */ + size_t floatStrUsedLen; /* Store float string len */ + SecChar *floatStr; /* Initialization must point to buffer */ + SecChar *allocatedFloatStr; /* Initialization must be NULL to store alloced point */ + SecChar buffer[SECUREC_FLOAT_BUFSIZE + 1]; +} SecFloatSpec; +#endif + +#define SECUREC_NUMBER_STATE_DEFAULT 0U +#define SECUREC_NUMBER_STATE_STARTED 1U + +typedef struct { + SecInt ch; /* Char read from input */ + int charCount; /* Number of characters processed */ + void *argPtr; /* Variable parameter pointer, point to the end of the string */ + size_t arrayWidth; /* Length of pointer Variable parameter, in charaters */ + SecUnsignedInt64 number64; /* Store input number64 value */ + unsigned long number; /* Store input number32 value */ + int numberWidth; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */ + int numberArgType; /* 1 for 64-bit integer, 0 otherwise. use it as decode function index */ + unsigned int negative; /* 0 is positive */ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + unsigned int beyondMax; /* Non-zero means beyond */ +#endif + unsigned int numberState; /* Identifies whether to start processing numbers, 1 is can input number*/ + int width; /* Width number in format */ + int widthSet; /* 0 is not set width in format */ + int convChr; /* Lowercase format conversion characters */ + int oriConvChr; /* Store original format conversion, convChr may change when parsing integers */ + signed char isWCharOrLong; /* -1/0 not wchar or long, 1 for wchar or long */ + unsigned char suppress; /* 0 is not have %* in format */ +} SecScanSpec; + +#ifdef SECUREC_FOR_WCHAR +#define SECUREC_GETC fgetwc +#define SECUREC_UN_GETC ungetwc +/* Only supports wide characters with a maximum length of two bytes in format string */ +#define SECUREC_BRACKET_CHAR_MASK 0xffffU +#else +#define SECUREC_GETC fgetc +#define SECUREC_UN_GETC ungetc +#define SECUREC_BRACKET_CHAR_MASK 0xffU +#endif + +#define SECUREC_CHAR_SIZE ((unsigned int)(sizeof(SecChar))) +/* To avoid 648, mask high bit: 0x00ffffff 0x0000ffff or 0x00000000 */ +#define SECUREC_CHAR_MASK_HIGH (((((((((unsigned int)(-1) >> SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \ + SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \ + SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \ + SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) + +/* For char is 0xff, wcahr_t is 0xffff or 0xffffffff. */ +#define SECUREC_CHAR_MASK (~((((((((((unsigned int)(-1) & SECUREC_CHAR_MASK_HIGH) << \ + SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \ + SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \ + SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \ + SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE)) + +/* According wchar_t has multiple bytes, so use sizeof */ +#define SECUREC_GET_CHAR(stream, outCh) do { \ + if ((stream)->count >= sizeof(SecChar)) { \ + *(outCh) = (SecInt)(SECUREC_CHAR_MASK & \ + (unsigned int)(int)(*((const SecChar *)(const void *)(stream)->cur))); \ + (stream)->cur += sizeof(SecChar); \ + (stream)->count -= sizeof(SecChar); \ + } else { \ + *(outCh) = SECUREC_EOF; \ + } \ +} SECUREC_WHILE_ZERO + +#define SECUREC_UN_GET_CHAR(stream) do { \ + if ((stream)->cur > (stream)->base) { \ + (stream)->cur -= sizeof(SecChar); \ + (stream)->count += sizeof(SecChar); \ + } \ +} SECUREC_WHILE_ZERO + +/* Convert wchar_t to int and then to unsigned int to keep data clearing warning */ +#define SECUREC_TO_LOWERCASE(chr) ((int)((unsigned int)(int)(chr) | (unsigned int)('a' - 'A'))) + +/* Record a flag for each bit */ +#define SECUREC_BRACKET_INDEX(x) ((unsigned int)(x) >> 3U) +#define SECUREC_BRACKET_VALUE(x) ((unsigned char)(1U << ((unsigned int)(x) & 7U))) +#if SECUREC_IN_KERNEL +#define SECUREC_CONVERT_IS_UNSIGNED(conv) ((conv) == 'x' || (conv) == 'o' || (conv) == 'u') +#endif + +/* + * Set char in %[xxx] into table, only supports wide characters with a maximum length of two bytes + */ +SECUREC_INLINE void SecBracketSetBit(unsigned char *table, SecUnsignedChar ch) +{ + unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); + unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); + /* Do not use |= optimize this code, it will cause compiling warning */ + table[tableIndex] = (unsigned char)(table[tableIndex] | tableValue); +} + +SECUREC_INLINE void SecBracketSetBitRange(unsigned char *table, SecUnsignedChar startCh, SecUnsignedChar endCh) +{ + SecUnsignedChar expCh; + /* %[a-z] %[a-a] Format %[a-\xff] end is 0xFF, condition (expCh <= endChar) cause dead loop */ + for (expCh = startCh; expCh < endCh; ++expCh) { + SecBracketSetBit(table, expCh); + } + SecBracketSetBit(table, endCh); +} +/* + * Determine whether the expression can be satisfied + */ +SECUREC_INLINE int SecCanInputForBracket(int convChr, SecInt ch, const SecBracketTable *bracketTable) +{ + unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); + unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); +#ifdef SECUREC_FOR_WCHAR + if (((unsigned int)(int)ch & (~(SECUREC_BRACKET_CHAR_MASK))) != 0) { + /* The value of the wide character exceeds the size of two bytes */ + return 0; + } + return (int)(convChr == SECUREC_BRACE && bracketTable->table != NULL && + ((bracketTable->table[tableIndex] ^ bracketTable->mask) & tableValue) != 0); +#else + return (int)(convChr == SECUREC_BRACE && + ((bracketTable->table[tableIndex] ^ bracketTable->mask) & tableValue) != 0); +#endif +} + +/* + * String input ends when blank character is encountered + */ +SECUREC_INLINE int SecCanInputString(int convChr, SecInt ch) +{ + return (int)(convChr == 's' && + (!(ch >= SECUREC_CHAR('\t') && ch <= SECUREC_CHAR('\r')) && ch != SECUREC_CHAR(' '))); +} + +/* + * Can input a character when format is %c + */ +SECUREC_INLINE int SecCanInputCharacter(int convChr) +{ + return (int)(convChr == 'c'); +} + +/* + * Determine if it is a 64-bit pointer function + * Return 0 is not ,1 is 64bit pointer + */ +SECUREC_INLINE int SecNumberArgType(size_t sizeOfVoidStar) +{ + /* Point size is 4 or 8 , Under the 64 bit system, the value not 0 */ + /* To clear e778 */ + if ((sizeOfVoidStar & sizeof(SecInt64)) != 0) { + return 1; + } + return 0; +} +SECUREC_INLINE int SecIsDigit(SecInt ch); +SECUREC_INLINE int SecIsXdigit(SecInt ch); +SECUREC_INLINE int SecIsSpace(SecInt ch); +SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter); +SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter); +SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter); + +#if SECUREC_ENABLE_SCANF_FLOAT + +/* + * Convert a floating point string to a floating point number + */ +SECUREC_INLINE void SecAssignFloat(const char *floatStr, int numberWidth, void *argPtr) +{ + char *endPtr = NULL; + double d; +#if SECUREC_SUPPORT_STRTOLD + if (numberWidth == SECUREC_NUM_WIDTH_LONG_LONG) { + long double d2 = strtold(floatStr, &endPtr); + *(long double UNALIGNED *)(argPtr) = d2; + return; + } +#endif + d = strtod(floatStr, &endPtr); + if (numberWidth > SECUREC_NUM_WIDTH_INT) { + *(double UNALIGNED *)(argPtr) = (double)d; + } else { + *(float UNALIGNED *)(argPtr) = (float)d; + } +} + +#ifdef SECUREC_FOR_WCHAR +/* + * Convert a floating point wchar string to a floating point number + * Success ret 0 + */ +SECUREC_INLINE int SecAssignFloatW(const SecFloatSpec *floatSpec, const SecScanSpec *spec) +{ + /* Convert float string */ + size_t mbsLen; + size_t tempFloatStrLen = (size_t)(floatSpec->floatStrTotalLen + 1) * sizeof(wchar_t); + char *tempFloatStr = (char *)SECUREC_MALLOC(tempFloatStrLen); + + if (tempFloatStr == NULL) { + return -1; + } + tempFloatStr[0] = '\0'; + SECUREC_MASK_MSVC_CRT_WARNING + mbsLen = wcstombs(tempFloatStr, floatSpec->floatStr, tempFloatStrLen - 1); + SECUREC_END_MASK_MSVC_CRT_WARNING + /* This condition must satisfy mbsLen is not -1 */ + if (mbsLen >= tempFloatStrLen) { + SECUREC_FREE(tempFloatStr); + return -1; + } + tempFloatStr[mbsLen] = '\0'; + SecAssignFloat(tempFloatStr, spec->numberWidth, spec->argPtr); + SECUREC_FREE(tempFloatStr); + return 0; +} +#endif + +/* + * Init SecFloatSpec befor parse format + */ +SECUREC_INLINE void SecInitFloatSpec(SecFloatSpec *floatSpec) +{ + floatSpec->floatStr = floatSpec->buffer; + floatSpec->allocatedFloatStr = NULL; + floatSpec->floatStrTotalLen = sizeof(floatSpec->buffer) / sizeof(floatSpec->buffer[0]); + floatSpec->floatStrUsedLen = 0; +} + +SECUREC_INLINE void SecFreeFloatSpec(SecFloatSpec *floatSpec, int *doneCount) +{ + /* LSD 2014.3.6 add, clear the stack data */ + if (memset_s(floatSpec->buffer, sizeof(floatSpec->buffer), 0, sizeof(floatSpec->buffer)) != EOK) { + *doneCount = 0; /* This code just to meet the coding requirements */ + } + /* The pFloatStr can be alloced in SecExtendFloatLen function, clear and free it */ + if (floatSpec->allocatedFloatStr != NULL) { + size_t bufferSize = floatSpec->floatStrTotalLen * sizeof(SecChar); + if (memset_s(floatSpec->allocatedFloatStr, bufferSize, 0, bufferSize) != EOK) { + *doneCount = 0; /* This code just to meet the coding requirements */ + } + SECUREC_FREE(floatSpec->allocatedFloatStr); + floatSpec->allocatedFloatStr = NULL; + floatSpec->floatStr = NULL; + } +} + +/* + * Splice floating point string + * Return 0 OK + */ +SECUREC_INLINE int SecExtendFloatLen(SecFloatSpec *floatSpec) +{ + if (floatSpec->floatStrUsedLen >= floatSpec->floatStrTotalLen) { + /* Buffer size is len x sizeof(SecChar) */ + size_t oriSize = floatSpec->floatStrTotalLen * sizeof(SecChar); + /* Add one character to clear tool warning */ + size_t nextSize = (oriSize * 2) + sizeof(SecChar); /* Multiply 2 to extend buffer size */ + + /* Prevents integer overflow, the maximum length of SECUREC_MAX_WIDTH_LEN is enough */ + if (nextSize <= (size_t)SECUREC_MAX_WIDTH_LEN) { + void *nextBuffer = (void *)SECUREC_MALLOC(nextSize); + if (nextBuffer == NULL) { + return -1; + } + if (memcpy_s(nextBuffer, nextSize, floatSpec->floatStr, oriSize) != EOK) { + SECUREC_FREE(nextBuffer); /* This is a dead code, just to meet the coding requirements */ + return -1; + } + /* Clear old buffer memory */ + if (memset_s(floatSpec->floatStr, oriSize, 0, oriSize) != EOK) { + SECUREC_FREE(nextBuffer); /* This is a dead code, just to meet the coding requirements */ + return -1; + } + /* Free old allocated buffer */ + if (floatSpec->allocatedFloatStr != NULL) { + SECUREC_FREE(floatSpec->allocatedFloatStr); + } + floatSpec->allocatedFloatStr = (SecChar *)(nextBuffer); /* Use to clear free on stack warning */ + floatSpec->floatStr = (SecChar *)(nextBuffer); + floatSpec->floatStrTotalLen = nextSize / sizeof(SecChar); /* Get buffer total len in character */ + return 0; + } + return -1; /* Next size is beyond max */ + } + return 0; +} + +/* Do not use localeconv()->decimal_pointif onlay support '.' */ +SECUREC_INLINE int SecIsFloatDecimal(SecChar ch) +{ + return (int)(ch == SECUREC_CHAR('.')); +} + +SECUREC_INLINE int SecInputFloatSign(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) +{ + if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) { + return 0; + } + spec->ch = SecGetChar(stream, &(spec->charCount)); + if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) { + SECUREC_FILED_WIDTH_DEC(spec); /* Make sure the count after un get char is correct */ + if (spec->ch == SECUREC_CHAR('-')) { + floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('-'); + ++floatSpec->floatStrUsedLen; + if (SecExtendFloatLen(floatSpec) != 0) { + return -1; + } + } + } else { + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + } + return 0; +} + +SECUREC_INLINE int SecInputFloatDigit(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) +{ + /* Now get integral part */ + while (SECUREC_FILED_WIDTH_ENOUGH(spec)) { + spec->ch = SecGetChar(stream, &(spec->charCount)); + if (SecIsDigit(spec->ch) == 0) { + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + return 0; + } + SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ + spec->numberState = SECUREC_NUMBER_STATE_STARTED; + floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch; + ++floatSpec->floatStrUsedLen; + if (SecExtendFloatLen(floatSpec) != 0) { + return -1; + } + } + return 0; +} + +/* +* Scan value of exponent. +* Return 0 OK +*/ +SECUREC_INLINE int SecInputFloatE(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) +{ + if (SecInputFloatSign(stream, spec, floatSpec) == -1) { + return -1; + } + if (SecInputFloatDigit(stream, spec, floatSpec) != 0) { + return -1; + } + return 0; +} + +SECUREC_INLINE int SecInputFloatFractional(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) +{ + if (SECUREC_FILED_WIDTH_ENOUGH(spec)) { + spec->ch = SecGetChar(stream, &(spec->charCount)); + if (SecIsFloatDecimal((SecChar)spec->ch) == 0) { + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + return 0; + } + SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ + /* Now check for decimal */ + floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch; + ++floatSpec->floatStrUsedLen; + if (SecExtendFloatLen(floatSpec) != 0) { + return -1; + } + if (SecInputFloatDigit(stream, spec, floatSpec) != 0) { + return -1; + } + } + return 0; +} + +SECUREC_INLINE int SecInputFloatExponent(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) +{ + /* Now get exponent part */ + if (spec->numberState == SECUREC_NUMBER_STATE_STARTED && SECUREC_FILED_WIDTH_ENOUGH(spec)) { + spec->ch = SecGetChar(stream, &(spec->charCount)); + if (spec->ch != SECUREC_CHAR('e') && spec->ch != SECUREC_CHAR('E')) { + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + return 0; + } + SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ + floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('e'); + ++floatSpec->floatStrUsedLen; + if (SecExtendFloatLen(floatSpec) != 0) { + return -1; + } + if (SecInputFloatE(stream, spec, floatSpec) != 0) { + return -1; + } + } + return 0; +} + +/* +* Scan %f. +* Return 0 OK +*/ +SECUREC_INLINE int SecInputFloat(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) +{ + floatSpec->floatStrUsedLen = 0; + + /* The following code sequence is strict */ + if (SecInputFloatSign(stream, spec, floatSpec) != 0) { + return -1; + } + if (SecInputFloatDigit(stream, spec, floatSpec) != 0) { + return -1; + } + if (SecInputFloatFractional(stream, spec, floatSpec) != 0) { + return -1; + } + if (SecInputFloatExponent(stream, spec, floatSpec) != 0) { + return -1; + } + + /* Make sure have a string terminator, buffer is large enough */ + floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('\0'); + if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) { + return 0; + } + return -1; +} +#endif + +#if (!defined(SECUREC_FOR_WCHAR) && SECUREC_HAVE_WCHART && SECUREC_HAVE_MBTOWC) || \ + (!defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)) +/* LSD only multi-bytes string need isleadbyte() function */ +SECUREC_INLINE int SecIsLeadByte(SecInt ch) +{ + unsigned int c = (unsigned int)ch; +#if !(defined(_MSC_VER) || defined(_INC_WCTYPE)) + return (int)(c & 0x80U); /* Use bitwise operation to check if the most significant bit is 1 */ +#else + return (int)isleadbyte((int)(c & 0xffU)); /* Use bitwise operations to limit character values to valid ranges */ +#endif +} +#endif + +/* + * Parsing whether it is a wide character + */ +SECUREC_INLINE void SecUpdateWcharFlagByType(SecUnsignedChar ch, SecScanSpec *spec) +{ + if (spec->isWCharOrLong != 0) { + /* Wide character identifiers have been explicitly set by l or h flag */ + return; + } + + /* Set default flag */ +#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT) + spec->isWCharOrLong = 1; /* On windows wide char version %c %s %[ is wide char */ +#else + spec->isWCharOrLong = -1; /* On linux all version %c %s %[ is multi char */ +#endif + + if (ch == SECUREC_CHAR('C') || ch == SECUREC_CHAR('S')) { +#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT) + spec->isWCharOrLong = -1; /* On windows wide char version %C %S is multi char */ +#else + spec->isWCharOrLong = 1; /* On linux all version %C %S is wide char */ +#endif + } + + return; +} +/* + * Decode %l %ll + */ +SECUREC_INLINE void SecDecodeScanQualifierL(const SecUnsignedChar **format, SecScanSpec *spec) +{ + const SecUnsignedChar *fmt = *format; + if (*(fmt + 1) == SECUREC_CHAR('l')) { + spec->numberArgType = 1; + spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; + ++fmt; + } else { + spec->numberWidth = SECUREC_NUM_WIDTH_LONG; +#if defined(SECUREC_ON_64BITS) && !(defined(SECUREC_COMPATIBLE_WIN_FORMAT)) + /* On window 64 system sizeof long is 32bit */ + spec->numberArgType = 1; +#endif + spec->isWCharOrLong = 1; + } + *format = fmt; +} + +/* + * Decode %I %I43 %I64 %Id %Ii %Io ... + * Set finishFlag to 1 finish Flag + */ +SECUREC_INLINE void SecDecodeScanQualifierI(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag) +{ + const SecUnsignedChar *fmt = *format; + if ((*(fmt + 1) == SECUREC_CHAR('6')) && + (*(fmt + 2) == SECUREC_CHAR('4'))) { /* Offset 2 for I64 */ + spec->numberArgType = 1; + *format = *format + 2; /* Add 2 to skip I64 point to '4' next loop will inc */ + } else if ((*(fmt + 1) == SECUREC_CHAR('3')) && + (*(fmt + 2) == SECUREC_CHAR('2'))) { /* Offset 2 for I32 */ + *format = *format + 2; /* Add 2 to skip I32 point to '2' next loop will inc */ + } else if ((*(fmt + 1) == SECUREC_CHAR('d')) || + (*(fmt + 1) == SECUREC_CHAR('i')) || + (*(fmt + 1) == SECUREC_CHAR('o')) || + (*(fmt + 1) == SECUREC_CHAR('x')) || + (*(fmt + 1) == SECUREC_CHAR('X'))) { + spec->numberArgType = SecNumberArgType(sizeof(void *)); + } else { + /* For %I */ + spec->numberArgType = SecNumberArgType(sizeof(void *)); + *finishFlag = 1; + } +} + +SECUREC_INLINE int SecDecodeScanWidth(const SecUnsignedChar **format, SecScanSpec *spec) +{ + const SecUnsignedChar *fmt = *format; + while (SecIsDigit((SecInt)(int)(*fmt)) != 0) { + spec->widthSet = 1; + if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(spec->width)) { + return -1; + } + spec->width = (int)SECUREC_MUL_TEN((unsigned int)spec->width) + (unsigned char)(*fmt - SECUREC_CHAR('0')); + ++fmt; + } + *format = fmt; + return 0; +} + +/* + * Init default flags for each format. do not init ch this variable is context-dependent + */ +SECUREC_INLINE void SecSetDefaultScanSpec(SecScanSpec *spec) +{ + /* The ch and charCount member variables cannot be initialized here */ + spec->argPtr = NULL; + spec->arrayWidth = 0; + spec->number64 = 0; + spec->number = 0; + spec->numberWidth = SECUREC_NUM_WIDTH_INT; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */ + spec->numberArgType = 0; /* 1 for 64-bit integer, 0 otherwise */ + spec->width = 0; + spec->widthSet = 0; + spec->convChr = 0; + spec->oriConvChr = 0; + spec->isWCharOrLong = 0; + spec->suppress = 0; +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + spec->beyondMax = 0; +#endif + spec->negative = 0; + spec->numberState = SECUREC_NUMBER_STATE_DEFAULT; +} + +/* + * Decode qualifier %I %L %h ... + * Set finishFlag to 1 finish Flag + */ +SECUREC_INLINE void SecDecodeScanQualifier(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag) +{ + switch (**format) { + case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('N'): + break; + case SECUREC_CHAR('h'): + --spec->numberWidth; /* The h for SHORT , hh for CHAR */ + spec->isWCharOrLong = -1; + break; +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT + case SECUREC_CHAR('j'): + spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; /* For intmax_t or uintmax_t */ + spec->numberArgType = 1; + break; + case SECUREC_CHAR('t'): /* fall-through */ /* FALLTHRU */ +#endif +#if SECUREC_IN_KERNEL + case SECUREC_CHAR('Z'): /* fall-through */ /* FALLTHRU */ +#endif + case SECUREC_CHAR('z'): +#ifdef SECUREC_ON_64BITS + spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; + spec->numberArgType = 1; +#else + spec->numberWidth = SECUREC_NUM_WIDTH_LONG; +#endif + break; + case SECUREC_CHAR('L'): /* For long double */ /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('q'): + spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; + spec->numberArgType = 1; + break; + case SECUREC_CHAR('l'): + SecDecodeScanQualifierL(format, spec); + break; + case SECUREC_CHAR('w'): + spec->isWCharOrLong = 1; + break; + case SECUREC_CHAR('*'): + spec->suppress = 1; + break; + case SECUREC_CHAR('I'): + SecDecodeScanQualifierI(format, spec, finishFlag); + break; + default: + *finishFlag = 1; + break; + } +} +/* + * Decode width and qualifier in format + */ +SECUREC_INLINE int SecDecodeScanFlag(const SecUnsignedChar **format, SecScanSpec *spec) +{ + const SecUnsignedChar *fmt = *format; + int finishFlag = 0; + + do { + ++fmt; /* First skip % , next seek fmt */ + /* May %*6d , so put it inside the loop */ + if (SecDecodeScanWidth(&fmt, spec) != 0) { + return -1; + } + SecDecodeScanQualifier(&fmt, spec, &finishFlag); + } while (finishFlag == 0); + *format = fmt; + return 0; +} + +/* + * Judging whether a zeroing buffer is needed according to different formats + */ +SECUREC_INLINE int SecDecodeClearFormat(const SecUnsignedChar *format, int *convChr) +{ + const SecUnsignedChar *fmt = format; + /* To lowercase */ + int ch = SECUREC_TO_LOWERCASE(*fmt); + if (!(ch == 'c' || ch == 's' || ch == SECUREC_BRACE)) { + return -1; /* First argument is not a string type */ + } + if (ch == SECUREC_BRACE) { +#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT)) + if (*fmt == SECUREC_CHAR('{')) { + return -1; + } +#endif + ++fmt; + if (*fmt == SECUREC_CHAR('^')) { + ++fmt; + } + if (*fmt == SECUREC_CHAR(']')) { + ++fmt; + } + while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) { + ++fmt; + } + if (*fmt == SECUREC_CHAR('\0')) { + return -1; /* Trunc'd format string */ + } + } + *convChr = ch; + return 0; +} + +/* + * Add L'\0' for wchar string , add '\0' for char string + */ +SECUREC_INLINE void SecAddEndingZero(void *ptr, const SecScanSpec *spec) +{ + if (spec->suppress == 0) { + *(char *)ptr = '\0'; +#if SECUREC_HAVE_WCHART + if (spec->isWCharOrLong > 0) { + *(wchar_t UNALIGNED *)ptr = L'\0'; + } +#endif + } +} + +SECUREC_INLINE void SecDecodeClearArg(SecScanSpec *spec, va_list argList) +{ + va_list argListSave; /* Backup for argList value, this variable don't need initialized */ + (void)memset(&argListSave, 0, sizeof(va_list)); /* To clear e530 argListSave not initialized */ +#if defined(va_copy) + va_copy(argListSave, argList); +#elif defined(__va_copy) /* For vxworks */ + __va_copy(argListSave, argList); +#else + argListSave = argList; +#endif + spec->argPtr = (void *)va_arg(argListSave, void *); + /* Get the next argument, size of the array in characters */ + /* Use 0xffffffffUL mask to Support pass integer as array length */ + spec->arrayWidth = ((size_t)(va_arg(argListSave, size_t))) & 0xffffffffUL; + va_end(argListSave); + /* To clear e438 last value assigned not used , the compiler will optimize this code */ + (void)argListSave; +} + +#ifdef SECUREC_FOR_WCHAR +/* + * Clean up the first %s %c buffer to zero for wchar version + */ +void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList) +#else +/* + * Clean up the first %s %c buffer to zero for char version + */ +void SecClearDestBuf(const char *buffer, const char *format, va_list argList) +#endif +{ + SecScanSpec spec; + int convChr = 0; + const SecUnsignedChar *fmt = (const SecUnsignedChar *)format; + if (fmt == NULL) { + return; + } + + /* Find first % */ + while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR('%')) { + ++fmt; + } + if (*fmt == SECUREC_CHAR('\0')) { + return; + } + + SecSetDefaultScanSpec(&spec); + if (SecDecodeScanFlag(&fmt, &spec) != 0) { + return; + } + + /* Update wchar flag for %S %C */ + SecUpdateWcharFlagByType(*fmt, &spec); + if (spec.suppress != 0) { + return; + } + + if (SecDecodeClearFormat(fmt, &convChr) != 0) { + return; + } + + if (buffer != NULL && *buffer != SECUREC_CHAR('\0') && convChr != 's') { + /* + * When buffer not empty just clear %s. + * Example call sscanf by argment of (" \n", "%s", s, sizeof(s)) + */ + return; + } + + SecDecodeClearArg(&spec, argList); + /* There is no need to judge the upper limit */ + if (spec.arrayWidth == 0 || spec.argPtr == NULL) { + return; + } + /* Clear one char */ + SecAddEndingZero(spec.argPtr, &spec); + return; +} + +/* + * Assign number to output buffer + */ +SECUREC_INLINE void SecAssignNumber(const SecScanSpec *spec) +{ + void *argPtr = spec->argPtr; + if (spec->numberArgType != 0) { +#if defined(SECUREC_VXWORKS_PLATFORM) +#if defined(SECUREC_VXWORKS_PLATFORM_COMP) + *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64); +#else + /* Take number64 as unsigned number unsigned to int clear Compile warning */ + *(SecInt64 UNALIGNED *)argPtr = *(SecUnsignedInt64 *)(&(spec->number64)); +#endif +#else + /* Take number64 as unsigned number */ + *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64); +#endif + return; + } + if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) { + /* Take number as unsigned number */ + *(long UNALIGNED *)argPtr = (long)(spec->number); + } else if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) { + *(int UNALIGNED *)argPtr = (int)(spec->number); + } else if (spec->numberWidth == SECUREC_NUM_WIDTH_SHORT) { + /* Take number as unsigned number */ + *(short UNALIGNED *)argPtr = (short)(spec->number); + } else { /* < 0 for hh format modifier */ + /* Take number as unsigned number */ + *(char UNALIGNED *)argPtr = (char)(spec->number); + } +} + +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) +/* + * Judge the long bit width + */ +SECUREC_INLINE int SecIsLongBitEqual(int bitNum) +{ + return (int)((unsigned int)bitNum == SECUREC_LONG_BIT_NUM); +} +#endif + +/* + * Convert hexadecimal characters to decimal value + */ +SECUREC_INLINE int SecHexValueOfChar(SecInt ch) +{ + /* Use isdigt Causing tool false alarms */ + return (int)((ch >= '0' && ch <= '9') ? ((unsigned char)ch - '0') : + ((((unsigned char)ch | (unsigned char)('a' - 'A')) - ('a')) + 10)); /* Adding 10 is to hex value */ +} + +/* + * Parse decimal character to integer for 32bit . + */ +static void SecDecodeNumberDecimal(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + unsigned long decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN; +#ifdef SECUREC_ON_64BITS + if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { + decimalEdge = (unsigned long)SECUREC_MAX_64BITS_VALUE_DIV_TEN; + } +#endif + if (spec->number > decimalEdge) { + spec->beyondMax = 1; + } +#endif + spec->number = SECUREC_MUL_TEN(spec->number); +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (spec->number == SECUREC_MUL_TEN(decimalEdge)) { + /* This code is specially converted to unsigned long type for compatibility */ + SecUnsignedInt64 number64As = (unsigned long)SECUREC_MAX_64BITS_VALUE - spec->number; + if (number64As < (SecUnsignedInt64)((SecUnsignedInt)spec->ch - SECUREC_CHAR('0'))) { + spec->beyondMax = 1; + } + } +#endif + spec->number += (unsigned long)((SecUnsignedInt)spec->ch - SECUREC_CHAR('0')); +} + +/* + * Parse Hex character to integer for 32bit . + */ +static void SecDecodeNumberHex(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (SECUREC_LONG_HEX_BEYOND_MAX(spec->number)) { + spec->beyondMax = 1; + } +#endif + spec->number = SECUREC_MUL_SIXTEEN(spec->number); + spec->number += (unsigned long)(unsigned int)SecHexValueOfChar(spec->ch); +} + +/* + * Parse Octal character to integer for 32bit . + */ +static void SecDecodeNumberOctal(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (SECUREC_LONG_OCTAL_BEYOND_MAX(spec->number)) { + spec->beyondMax = 1; + } +#endif + spec->number = SECUREC_MUL_EIGHT(spec->number); + spec->number += (unsigned long)((SecUnsignedInt)spec->ch - SECUREC_CHAR('0')); +} + +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) +/* Compatible with integer negative values other than int */ +SECUREC_INLINE void SecFinishNumberNegativeOther(SecScanSpec *spec) +{ + if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { + if (spec->number > SECUREC_MIN_LONG_NEG_VALUE) { + spec->number = SECUREC_MIN_LONG_NEG_VALUE; + } else { + spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ + } + if (spec->beyondMax != 0) { + if (spec->numberWidth < SECUREC_NUM_WIDTH_INT) { + spec->number = 0; + } + if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG) { + spec->number = SECUREC_MIN_LONG_NEG_VALUE; + } + } + } else { /* For o, u, x, X, p */ + spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ + if (spec->beyondMax != 0) { + spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; + } + } +} +/* Compatible processing of integer negative numbers */ +SECUREC_INLINE void SecFinishNumberNegativeInt(SecScanSpec *spec) +{ + if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { +#ifdef SECUREC_ON_64BITS + if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { + if ((spec->number > SECUREC_MIN_64BITS_NEG_VALUE)) { + spec->number = 0; + } else { + spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ + } + } +#else + if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { + if ((spec->number > SECUREC_MIN_32BITS_NEG_VALUE)) { + spec->number = SECUREC_MIN_32BITS_NEG_VALUE; + } else { + spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ + } + } +#endif + if (spec->beyondMax != 0) { +#ifdef SECUREC_ON_64BITS + if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { + spec->number = 0; + } +#else + if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { + spec->number = SECUREC_MIN_32BITS_NEG_VALUE; + } +#endif + } + } else { /* For o, u, x, X ,p */ +#ifdef SECUREC_ON_64BITS + if (spec->number > SECUREC_MAX_32BITS_VALUE_INC) { + spec->number = SECUREC_MAX_32BITS_VALUE; + } else { + spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ + } +#else + spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ +#endif + if (spec->beyondMax != 0) { + spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; + } + } +} + +/* Compatible with integer positive values other than int */ +SECUREC_INLINE void SecFinishNumberPositiveOther(SecScanSpec *spec) +{ + if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { + if (spec->number > SECUREC_MAX_LONG_POS_VALUE) { + spec->number = SECUREC_MAX_LONG_POS_VALUE; + } + if ((spec->beyondMax != 0 && spec->numberWidth < SECUREC_NUM_WIDTH_INT)) { + spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; + } + if (spec->beyondMax != 0 && spec->numberWidth == SECUREC_NUM_WIDTH_LONG) { + spec->number = SECUREC_MAX_LONG_POS_VALUE; + } + } else { + if (spec->beyondMax != 0) { + spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; + } + } +} + +/* Compatible processing of integer positive numbers */ +SECUREC_INLINE void SecFinishNumberPositiveInt(SecScanSpec *spec) +{ + if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { +#ifdef SECUREC_ON_64BITS + if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { + if (spec->number > SECUREC_MAX_64BITS_POS_VALUE) { + spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; + } + } + if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { + spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; + } +#else + if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { + if (spec->number > SECUREC_MAX_32BITS_POS_VALUE) { + spec->number = SECUREC_MAX_32BITS_POS_VALUE; + } + } + if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { + spec->number = SECUREC_MAX_32BITS_POS_VALUE; + } +#endif + } else { /* For o,u,x,X,p */ + if (spec->beyondMax != 0) { + spec->number = SECUREC_MAX_32BITS_VALUE; + } + } +} + +#endif + +/* + * Parse decimal character to integer for 64bit . + */ +static void SecDecodeNumber64Decimal(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (spec->number64 > SECUREC_MAX_64BITS_VALUE_DIV_TEN) { + spec->beyondMax = 1; + } +#endif + spec->number64 = SECUREC_MUL_TEN(spec->number64); +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (spec->number64 == SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT) { + SecUnsignedInt64 number64As = (SecUnsignedInt64)SECUREC_MAX_64BITS_VALUE - spec->number64; + if (number64As < (SecUnsignedInt64)((SecUnsignedInt)spec->ch - SECUREC_CHAR('0'))) { + spec->beyondMax = 1; + } + } +#endif + spec->number64 += (SecUnsignedInt64)((SecUnsignedInt)spec->ch - SECUREC_CHAR('0')); +} + +/* + * Parse Hex character to integer for 64bit . + */ +static void SecDecodeNumber64Hex(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (SECUREC_QWORD_HEX_BEYOND_MAX(spec->number64)) { + spec->beyondMax = 1; + } +#endif + spec->number64 = SECUREC_MUL_SIXTEEN(spec->number64); + spec->number64 += (SecUnsignedInt64)(unsigned int)SecHexValueOfChar(spec->ch); +} + +/* + * Parse Octal character to integer for 64bit . + */ +static void SecDecodeNumber64Octal(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (SECUREC_QWORD_OCTAL_BEYOND_MAX(spec->number64)) { + spec->beyondMax = 1; + } +#endif + spec->number64 = SECUREC_MUL_EIGHT(spec->number64); + spec->number64 += (SecUnsignedInt64)((SecUnsignedInt)spec->ch - SECUREC_CHAR('0')); +} + +#define SECUREC_DECODE_NUMBER_FUNC_NUM 2 + +/* + * Parse 64-bit integer formatted input, return 0 when ch is a number. + */ +SECUREC_INLINE int SecDecodeNumber(SecScanSpec *spec) +{ + /* Function name cannot add address symbol, causing 546 alarm */ + static void (*secDecodeNumberHex[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { + SecDecodeNumberHex, SecDecodeNumber64Hex + }; + static void (*secDecodeNumberOctal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { + SecDecodeNumberOctal, SecDecodeNumber64Octal + }; + static void (*secDecodeNumberDecimal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { + SecDecodeNumberDecimal, SecDecodeNumber64Decimal + }; + if (spec->convChr == 'x' || spec->convChr == 'p') { + if (SecIsXdigit(spec->ch) != 0) { + (*secDecodeNumberHex[spec->numberArgType])(spec); + } else { + return -1; + } + return 0; + } + if (SecIsDigit(spec->ch) == 0) { + return -1; + } + if (spec->convChr == 'o') { + if (spec->ch < SECUREC_CHAR('8')) { /* Octal maximum limit '8' */ + (*secDecodeNumberOctal[spec->numberArgType])(spec); + } else { + return -1; + } + } else { /* The convChr is 'd' */ + (*secDecodeNumberDecimal[spec->numberArgType])(spec); + } + return 0; +} + +/* + * Complete the final 32-bit integer formatted input + */ +static void SecFinishNumber(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (spec->negative != 0) { + if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) { + SecFinishNumberNegativeInt(spec); + } else { + SecFinishNumberNegativeOther(spec); + } + } else { + if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) { + SecFinishNumberPositiveInt(spec); + } else { + SecFinishNumberPositiveOther(spec); + } + } +#else + if (spec->negative != 0) { +#if defined(__hpux) + if (spec->oriConvChr != 'p') { + spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ + } +#else + spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ +#endif + } +#endif + return; +} + +/* + * Complete the final 64-bit integer formatted input + */ +static void SecFinishNumber64(SecScanSpec *spec) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) + if (spec->negative != 0) { + if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { + if (spec->number64 > SECUREC_MIN_64BITS_NEG_VALUE) { + spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE; + } else { + spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ + } + if (spec->beyondMax != 0) { + spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE; + } + } else { /* For o, u, x, X, p */ + spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ + if (spec->beyondMax != 0) { + spec->number64 = SECUREC_MAX_64BITS_VALUE; + } + } + } else { + if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { + if (spec->number64 > SECUREC_MAX_64BITS_POS_VALUE) { + spec->number64 = SECUREC_MAX_64BITS_POS_VALUE; + } + if (spec->beyondMax != 0) { + spec->number64 = SECUREC_MAX_64BITS_POS_VALUE; + } + } else { + if (spec->beyondMax != 0) { + spec->number64 = SECUREC_MAX_64BITS_VALUE; + } + } + } +#else + if (spec->negative != 0) { +#if defined(__hpux) + if (spec->oriConvChr != 'p') { + spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ + } +#else + spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ +#endif + } +#endif + return; +} + +#if SECUREC_ENABLE_SCANF_FILE + +/* + * Adjust the pointer position of the file stream + */ +SECUREC_INLINE void SecSeekStream(SecFileStream *stream) +{ + if (stream->count == 0) { + if (feof(stream->pf) != 0) { + /* File pointer at the end of file, don't need to seek back */ + stream->base[0] = '\0'; + return; + } + } + /* Seek to original position, for file read, but nothing to input */ + if (fseek(stream->pf, stream->oriFilePos, SEEK_SET) != 0) { + /* Seek failed, ignore it */ + stream->oriFilePos = 0; + return; + } + + if (stream->fileRealRead > 0) { /* Do not seek without input data */ +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) + size_t residue = stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE; + size_t loops; + for (loops = 0; loops < (stream->fileRealRead / SECUREC_BUFFERED_BLOK_SIZE); ++loops) { + if (fread(stream->base, (size_t)SECUREC_BUFFERED_BLOK_SIZE, (size_t)1, stream->pf) != (size_t)1) { + break; + } + } + if (residue != 0) { + long curFilePos; + if (fread(stream->base, residue, (size_t)1, stream->pf) != (size_t)1) { + return; + } + curFilePos = ftell(stream->pf); + if (curFilePos < stream->oriFilePos || + (size_t)(unsigned long)(curFilePos - stream->oriFilePos) < stream->fileRealRead) { + /* Try to remedy the problem */ + (void)fseek(stream->pf, (long)stream->fileRealRead, SEEK_CUR); + } + } +#else + /* Seek from oriFilePos. Regardless of the integer sign problem, call scanf will not read very large data */ + if (fseek(stream->pf, (long)stream->fileRealRead, SEEK_CUR) != 0) { + /* Seek failed, ignore it */ + stream->oriFilePos = 0; + return; + } +#endif + } + return; +} + +/* + * Adjust the pointer position of the file stream and free memory + */ +SECUREC_INLINE void SecAdjustStream(SecFileStream *stream) +{ + if (stream != NULL && (stream->flag & SECUREC_FILE_STREAM_FLAG) != 0 && stream->base != NULL) { + SecSeekStream(stream); + SECUREC_FREE(stream->base); + stream->base = NULL; + } + return; +} +#endif + +SECUREC_INLINE void SecSkipSpaceFormat(const SecUnsignedChar **format) +{ + const SecUnsignedChar *fmt = *format; + while (SecIsSpace((SecInt)(int)(*fmt)) != 0) { + ++fmt; + } + *format = fmt; +} + +#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION) +/* + * Handling multi-character characters + */ +SECUREC_INLINE int SecDecodeLeadByte(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream) +{ +#if SECUREC_HAVE_MBTOWC + const SecUnsignedChar *fmt = *format; + int ch1 = (int)spec->ch; + int ch2 = SecGetChar(stream, &(spec->charCount)); + spec->ch = (SecInt)ch2; + if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch2) { + /* LSD in console mode, ungetc twice may cause problem */ + SecUnGetChar(ch2, stream, &(spec->charCount)); + SecUnGetChar(ch1, stream, &(spec->charCount)); + return -1; + } + ++fmt; + if ((unsigned int)MB_CUR_MAX >= SECUREC_UTF8_BOM_HEADER_SIZE && + (((unsigned char)ch1 & SECUREC_UTF8_LEAD_1ST) == SECUREC_UTF8_LEAD_1ST) && + (((unsigned char)ch2 & SECUREC_UTF8_LEAD_2ND) == SECUREC_UTF8_LEAD_2ND)) { + /* This char is very likely to be a UTF-8 char */ + wchar_t tempWChar; + char temp[SECUREC_MULTI_BYTE_MAX_LEN]; + int ch3 = (int)SecGetChar(stream, &(spec->charCount)); + spec->ch = (SecInt)ch3; + if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch3) { + SecUnGetChar(ch3, stream, &(spec->charCount)); + return -1; + } + temp[0] = (char)ch1; + temp[1] = (char)ch2; /* 1 index of second character */ + temp[2] = (char)ch3; /* 2 index of third character */ + temp[3] = '\0'; /* 3 of string terminator position */ + if (mbtowc(&tempWChar, temp, sizeof(temp)) > 0) { + /* Succeed */ + ++fmt; + --spec->charCount; + } else { + SecUnGetChar(ch3, stream, &(spec->charCount)); + } + } + --spec->charCount; /* Only count as one character read */ + *format = fmt; + return 0; +#else + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + (void)format; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + return -1; +#endif +} +#endif + +/* + * Resolving sequence of characters from %[ format, format wile point to ']' + */ +SECUREC_INLINE int SecSetupBracketTable(const SecUnsignedChar **format, SecBracketTable *bracketTable) +{ + const SecUnsignedChar *fmt = *format; + SecUnsignedChar prevChar = 0; +#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT)) + if (*fmt == SECUREC_CHAR('{')) { + return -1; + } +#endif + /* For building "table" data */ + ++fmt; /* Skip [ */ + bracketTable->mask = 0; /* Set all bits to 0 */ + if (*fmt == SECUREC_CHAR('^')) { + ++fmt; + bracketTable->mask = (unsigned char)0xffU; /* Use 0xffU to set all bits to 1 */ + } + if (*fmt == SECUREC_CHAR(']')) { + prevChar = SECUREC_CHAR(']'); + ++fmt; + SecBracketSetBit(bracketTable->table, SECUREC_CHAR(']')); + } + while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) { + SecUnsignedChar expCh = *fmt; + ++fmt; + if (expCh != SECUREC_CHAR('-') || prevChar == 0 || *fmt == SECUREC_CHAR(']')) { + /* Normal character */ + prevChar = expCh; + SecBracketSetBit(bracketTable->table, expCh); + } else { + /* For %[a-z] */ + expCh = *fmt; /* Get end of range */ + ++fmt; + if (prevChar <= expCh) { /* %[a-z] %[a-a] */ + SecBracketSetBitRange(bracketTable->table, prevChar, expCh); + } else { + /* For %[z-a] */ +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) + /* Swap start and end characters */ + SecBracketSetBitRange(bracketTable->table, expCh, prevChar); +#else + SecBracketSetBit(bracketTable->table, SECUREC_CHAR('-')); + SecBracketSetBit(bracketTable->table, expCh); +#endif + } + prevChar = 0; + } + } + *format = fmt; + return 0; +} + +#ifdef SECUREC_FOR_WCHAR +SECUREC_INLINE int SecInputForWchar(SecScanSpec *spec) +{ + void *endPtr = spec->argPtr; + if (spec->isWCharOrLong > 0) { + *(wchar_t UNALIGNED *)endPtr = (wchar_t)spec->ch; + endPtr = (wchar_t *)endPtr + 1; + --spec->arrayWidth; + } else { +#if SECUREC_HAVE_WCTOMB + int temp; + char tmpBuf[SECUREC_MB_LEN + 1]; + SECUREC_MASK_MSVC_CRT_WARNING temp = wctomb(tmpBuf, (wchar_t)spec->ch); + SECUREC_END_MASK_MSVC_CRT_WARNING + if (temp <= 0 || (size_t)(unsigned int)temp > sizeof(tmpBuf)) { + /* If wctomb error, then ignore character */ + return 0; + } + if (((size_t)(unsigned int)temp) > spec->arrayWidth) { + return -1; + } + if (memcpy_s(endPtr, spec->arrayWidth, tmpBuf, (size_t)(unsigned int)temp) != EOK) { + return -1; + } + endPtr = (char *)endPtr + temp; + spec->arrayWidth -= (size_t)(unsigned int)temp; +#else + return -1; +#endif + } + spec->argPtr = endPtr; + return 0; +} +#endif + +#ifndef SECUREC_FOR_WCHAR +#if SECUREC_HAVE_WCHART +SECUREC_INLINE wchar_t SecConvertInputCharToWchar(SecScanSpec *spec, SecFileStream *stream) +{ + wchar_t tempWChar = L'?'; /* Set default char is ? */ +#if SECUREC_HAVE_MBTOWC + char temp[SECUREC_MULTI_BYTE_MAX_LEN + 1]; + temp[0] = (char)spec->ch; + temp[1] = '\0'; +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) + if (SecIsLeadByte(spec->ch) != 0) { + spec->ch = SecGetChar(stream, &(spec->charCount)); + temp[1] = (char)spec->ch; + temp[2] = '\0'; /* 2 of string terminator position */ + } + if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) { + /* No string termination error for tool */ + tempWChar = L'?'; + } +#else + if (SecIsLeadByte(spec->ch) != 0) { + int convRes = 0; + int di = 1; + /* On Linux like system, the string is encoded in UTF-8 */ + while (convRes <= 0 && di < (int)MB_CUR_MAX && di < SECUREC_MULTI_BYTE_MAX_LEN) { + spec->ch = SecGetChar(stream, &(spec->charCount)); + temp[di] = (char)spec->ch; + ++di; + temp[di] = '\0'; + convRes = mbtowc(&tempWChar, temp, sizeof(temp)); + } + if (convRes <= 0) { + tempWChar = L'?'; + } + } else { + if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) { + tempWChar = L'?'; + } + } +#endif +#else + (void)spec; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */ +#endif /* SECUREC_HAVE_MBTOWC */ + + return tempWChar; +} +#endif /* SECUREC_HAVE_WCHART */ + +SECUREC_INLINE int SecInputForChar(SecScanSpec *spec, SecFileStream *stream) +{ + void *endPtr = spec->argPtr; + if (spec->isWCharOrLong > 0) { +#if SECUREC_HAVE_WCHART + *(wchar_t UNALIGNED *)endPtr = SecConvertInputCharToWchar(spec, stream); + endPtr = (wchar_t *)endPtr + 1; + --spec->arrayWidth; +#else + (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + return -1; +#endif + } else { + *(char *)endPtr = (char)spec->ch; + endPtr = (char *)endPtr + 1; + --spec->arrayWidth; + } + spec->argPtr = endPtr; + return 0; +} +#endif + +/* + * Scan digital part of %d %i %o %u %x %p. + * Return 0 OK + */ +SECUREC_INLINE int SecInputNumberDigital(SecFileStream *stream, SecScanSpec *spec) +{ + static void (*secFinishNumber[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { + SecFinishNumber, SecFinishNumber64 + }; + while (SECUREC_FILED_WIDTH_ENOUGH(spec)) { + spec->ch = SecGetChar(stream, &(spec->charCount)); + /* Decode ch to number */ + if (SecDecodeNumber(spec) != 0) { + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + break; + } + SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ + spec->numberState = SECUREC_NUMBER_STATE_STARTED; + } + /* Handling integer negative numbers and beyond max */ + (*secFinishNumber[spec->numberArgType])(spec); + if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) { + return 0; + } + return -1; +} + +/* + * Scan %d %i %o %u %x %p. + * Return 0 OK + */ +SECUREC_INLINE int SecInputNumber(SecFileStream *stream, SecScanSpec *spec) +{ + /* Character already read */ + if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) { + if (spec->ch == SECUREC_CHAR('-')) { + spec->negative = 1; +#if SECUREC_IN_KERNEL + /* In kernel Refuse to enter negative number */ + if (SECUREC_CONVERT_IS_UNSIGNED(spec->oriConvChr)) { + return -1; + } +#endif + } + SECUREC_FILED_WIDTH_DEC(spec); /* Do not need to check width here, must be greater than 0 */ + spec->ch = SecGetChar(stream, &(spec->charCount)); /* Eat + or - */ + spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next character, used for the '0' judgments */ + SecUnGetChar(spec->ch, stream, &(spec->charCount)); /* Not sure if it was actually read, so push back */ + } + + if (spec->oriConvChr == 'i') { + spec->convChr = 'd'; /* The i could be d, o, or x, use d as default */ + } + + if (spec->ch == SECUREC_CHAR('0') && (spec->oriConvChr == 'x' || spec->oriConvChr == 'i') && + SECUREC_FILED_WIDTH_ENOUGH(spec)) { + /* Input string begin with 0, may be 0x123 0X123 0123 0x 01 0yy 09 0 0ab 00 */ + SECUREC_FILED_WIDTH_DEC(spec); + spec->ch = SecGetChar(stream, &(spec->charCount)); /* ch is '0' */ + + /* Read only '0' due to width limitation */ + if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) { + /* The number or number64 in spec has been set 0 */ + return 0; + } + + spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next char to check x or X, do not dec width */ + if ((SecChar)spec->ch == SECUREC_CHAR('x') || (SecChar)spec->ch == SECUREC_CHAR('X')) { + spec->convChr = 'x'; + SECUREC_FILED_WIDTH_DEC(spec); /* Make incorrect width for x or X */ + } else { + if (spec->oriConvChr == 'i') { + spec->convChr = 'o'; + } + /* For "0y" "08" "01" "0a" ... ,push the 'y' '8' '1' 'a' back */ + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + /* Since 0 has been read, it indicates that a valid character has been read */ + spec->numberState = SECUREC_NUMBER_STATE_STARTED; + } + } + return SecInputNumberDigital(stream, spec); +} + +/* + * Scan %c %s %[ + * Return 0 OK + */ +SECUREC_INLINE int SecInputString(SecFileStream *stream, SecScanSpec *spec, + const SecBracketTable *bracketTable, int *doneCount) +{ + void *startPtr = spec->argPtr; + int suppressed = 0; + int errNoMem = 0; + + while (SECUREC_FILED_WIDTH_ENOUGH(spec)) { + SECUREC_FILED_WIDTH_DEC(spec); + spec->ch = SecGetChar(stream, &(spec->charCount)); + /* + * The char condition or string condition and bracket condition. + * Only supports wide characters with a maximum length of two bytes + */ + if (spec->ch != SECUREC_EOF && (SecCanInputCharacter(spec->convChr) != 0 || + SecCanInputString(spec->convChr, spec->ch) != 0 || + SecCanInputForBracket(spec->convChr, spec->ch, bracketTable) != 0)) { + if (spec->suppress != 0) { + /* Used to identify processed data for %*, use argPtr to identify will cause 613, so use suppressed */ + suppressed = 1; + continue; + } + /* Now suppress is not set */ + if (spec->arrayWidth == 0) { + errNoMem = 1; /* We have exhausted the user's buffer */ + break; + } +#ifdef SECUREC_FOR_WCHAR + errNoMem = SecInputForWchar(spec); +#else + errNoMem = SecInputForChar(spec, stream); +#endif + if (errNoMem != 0) { + break; + } + } else { + SecUnGetChar(spec->ch, stream, &(spec->charCount)); + break; + } + } + + if (errNoMem != 0) { + /* In case of error, blank out the input buffer */ + SecAddEndingZero(startPtr, spec); + return -1; + } + if ((spec->suppress != 0 && suppressed == 0) || + (spec->suppress == 0 && startPtr == spec->argPtr)) { + /* No input was scanned */ + return -1; + } + if (spec->convChr != 'c') { + /* Add null-terminate for strings */ + SecAddEndingZero(spec->argPtr, spec); + } + if (spec->suppress == 0) { + *doneCount = *doneCount + 1; + } + return 0; +} + +#ifdef SECUREC_FOR_WCHAR +/* + * Alloce buffer for wchar version of %[. + * Return 0 OK + */ +SECUREC_INLINE int SecAllocBracketTable(SecBracketTable *bracketTable) +{ + if (bracketTable->table == NULL) { + /* Table should be freed after use */ + bracketTable->table = (unsigned char *)SECUREC_MALLOC(SECUREC_BRACKET_TABLE_SIZE); + if (bracketTable->table == NULL) { + return -1; + } + } + return 0; +} + +/* + * Free buffer for wchar version of %[ + */ +SECUREC_INLINE void SecFreeBracketTable(SecBracketTable *bracketTable) +{ + if (bracketTable->table != NULL) { + SECUREC_FREE(bracketTable->table); + bracketTable->table = NULL; + } +} +#endif + +#ifdef SECUREC_FOR_WCHAR +/* + * Formatting input core functions for wchar version.Called by a function such as vswscanf_s + */ +int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList) +#else +/* + * Formatting input core functions for char version.Called by a function such as vsscanf_s + */ +int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList) +#endif +{ + const SecUnsignedChar *format = (const SecUnsignedChar *)cFormat; + SecBracketTable bracketTable = SECUREC_INIT_BRACKET_TABLE; + SecScanSpec spec; + int doneCount = 0; + int formatError = 0; + int paraIsNull = 0; + int match = 0; /* When % is found , inc this value */ + int errRet = 0; +#if SECUREC_ENABLE_SCANF_FLOAT + SecFloatSpec floatSpec; + SecInitFloatSpec(&floatSpec); +#endif + spec.ch = 0; /* Need to initialize to 0 */ + spec.charCount = 0; /* Need to initialize to 0 */ + + /* Format must not NULL, use err < 1 to claer 845 */ + while (errRet < 1 && *format != SECUREC_CHAR('\0')) { + /* Skip space in format and space in input */ + if (SecIsSpace((SecInt)(int)(*format)) != 0) { + /* Read first no space char */ + spec.ch = SecSkipSpaceChar(stream, &(spec.charCount)); + /* Read the EOF cannot be returned directly here, because the case of " %n" needs to be handled */ + /* Put fist no space char backup. put EOF back is also OK, and to modify the character count */ + SecUnGetChar(spec.ch, stream, &(spec.charCount)); + SecSkipSpaceFormat(&format); + continue; + } + + if (*format != SECUREC_CHAR('%')) { + spec.ch = SecGetChar(stream, &(spec.charCount)); + if ((int)(*format) != (int)(spec.ch)) { + SecUnGetChar(spec.ch, stream, &(spec.charCount)); + break; + } + ++format; +#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION) + if (SecIsLeadByte(spec.ch) != 0) { + if (SecDecodeLeadByte(&spec, &format, stream) != 0) { + break; + } + } +#endif + continue; + } + + /* Now *format is % */ + /* Set default value for each % */ + SecSetDefaultScanSpec(&spec); + if (SecDecodeScanFlag(&format, &spec) != 0) { + formatError = 1; + ++errRet; + continue; + } + if (!SECUREC_FILED_WIDTH_ENOUGH(&spec)) { + /* 0 width in format */ + ++errRet; + continue; + } + + /* Update wchar flag for %S %C */ + SecUpdateWcharFlagByType(*format, &spec); + + spec.convChr = SECUREC_TO_LOWERCASE(*format); + spec.oriConvChr = spec.convChr; /* convChr may be modified to handle integer logic */ + if (spec.convChr != 'n') { + if (spec.convChr != 'c' && spec.convChr != SECUREC_BRACE) { + spec.ch = SecSkipSpaceChar(stream, &(spec.charCount)); + } else { + spec.ch = SecGetChar(stream, &(spec.charCount)); + } + if (spec.ch == SECUREC_EOF) { + ++errRet; + continue; + } + } + + /* Now no 0 width in format and get one char from input */ + switch (spec.oriConvChr) { + case 'c': /* Also 'C' */ + if (spec.widthSet == 0) { + spec.widthSet = 1; + spec.width = 1; + } + /* fall-through */ /* FALLTHRU */ + case 's': /* Also 'S': */ + /* fall-through */ /* FALLTHRU */ + case SECUREC_BRACE: + /* Unset last char to stream */ + SecUnGetChar(spec.ch, stream, &(spec.charCount)); + /* Check dest buffer and size */ + if (spec.suppress == 0) { + spec.argPtr = (void *)va_arg(argList, void *); + if (spec.argPtr == NULL) { + paraIsNull = 1; + ++errRet; + continue; + } + /* Get the next argument, size of the array in characters */ +#ifdef SECUREC_ON_64BITS + /* Use 0xffffffffUL mask to Support pass integer as array length */ + spec.arrayWidth = ((size_t)(va_arg(argList, size_t))) & 0xffffffffUL; +#else /* !SECUREC_ON_64BITS */ + spec.arrayWidth = (size_t)va_arg(argList, size_t); +#endif + if (SECUREC_ARRAY_WIDTH_IS_WRONG(spec)) { + /* Do not clear buffer just go error */ + ++errRet; + continue; + } + /* One element is needed for '\0' for %s and %[ */ + if (spec.convChr != 'c') { + --spec.arrayWidth; + } + } else { + /* Set argPtr to NULL is necessary, in supress mode we don't use argPtr to store data */ + spec.argPtr = NULL; + } + + if (spec.convChr == SECUREC_BRACE) { + /* Malloc when first %[ is meet for wchar version */ +#ifdef SECUREC_FOR_WCHAR + if (SecAllocBracketTable(&bracketTable) != 0) { + ++errRet; + continue; + } +#endif + (void)memset(bracketTable.table, 0, (size_t)SECUREC_BRACKET_TABLE_SIZE); + if (SecSetupBracketTable(&format, &bracketTable) != 0) { + ++errRet; + continue; + } + + if (*format == SECUREC_CHAR('\0')) { + /* Default add string terminator */ + SecAddEndingZero(spec.argPtr, &spec); + ++errRet; + /* Truncated format */ + continue; + } + } + + /* Set completed. Now read string or character */ + if (SecInputString(stream, &spec, &bracketTable, &doneCount) != 0) { + ++errRet; + continue; + } + break; + case 'p': + /* Make %hp same as %p */ + spec.numberWidth = SECUREC_NUM_WIDTH_INT; +#ifdef SECUREC_ON_64BITS + spec.numberArgType = 1; +#endif + /* fall-through */ /* FALLTHRU */ + case 'o': /* fall-through */ /* FALLTHRU */ + case 'u': /* fall-through */ /* FALLTHRU */ + case 'd': /* fall-through */ /* FALLTHRU */ + case 'i': /* fall-through */ /* FALLTHRU */ + case 'x': + /* Unset last char to stream */ + SecUnGetChar(spec.ch, stream, &(spec.charCount)); + if (SecInputNumber(stream, &spec) != 0) { + ++errRet; + continue; + } + if (spec.suppress == 0) { + spec.argPtr = (void *)va_arg(argList, void *); + if (spec.argPtr == NULL) { + paraIsNull = 1; + ++errRet; + continue; + } + SecAssignNumber(&spec); + ++doneCount; + } + break; + case 'n': /* Char count */ + if (spec.suppress == 0) { + spec.argPtr = (void *)va_arg(argList, void *); + if (spec.argPtr == NULL) { + paraIsNull = 1; + ++errRet; + continue; + } + spec.number = (unsigned long)(unsigned int)(spec.charCount); + spec.numberArgType = 0; + SecAssignNumber(&spec); + } + break; + case 'e': /* fall-through */ /* FALLTHRU */ + case 'f': /* fall-through */ /* FALLTHRU */ + case 'g': /* Scan a float */ + /* Unset last char to stream */ + SecUnGetChar(spec.ch, stream, &(spec.charCount)); +#if SECUREC_ENABLE_SCANF_FLOAT + if (SecInputFloat(stream, &spec, &floatSpec) != 0) { + ++errRet; + continue; + } + if (spec.suppress == 0) { + spec.argPtr = (void *)va_arg(argList, void *); + if (spec.argPtr == NULL) { + ++errRet; + paraIsNull = 1; + continue; + } +#ifdef SECUREC_FOR_WCHAR + if (SecAssignFloatW(&floatSpec, &spec) != 0) { + ++errRet; + continue; + } +#else + SecAssignFloat(floatSpec.floatStr, spec.numberWidth, spec.argPtr); +#endif + ++doneCount; + } + break; +#else /* SECUREC_ENABLE_SCANF_FLOAT */ + ++errRet; + continue; +#endif + default: + if ((int)(*format) != (int)spec.ch) { + SecUnGetChar(spec.ch, stream, &(spec.charCount)); + formatError = 1; + ++errRet; + continue; + } else { + --match; /* Compensate for the self-increment of the following code */ + } + break; + } + ++match; + ++format; + } + +#ifdef SECUREC_FOR_WCHAR + SecFreeBracketTable(&bracketTable); +#endif + +#if SECUREC_ENABLE_SCANF_FLOAT + SecFreeFloatSpec(&floatSpec, &doneCount); +#endif + +#if SECUREC_ENABLE_SCANF_FILE + SecAdjustStream(stream); +#endif + + if (spec.ch == SECUREC_EOF) { + return ((doneCount != 0 || match != 0) ? doneCount : SECUREC_SCANF_EINVAL); + } + if (formatError != 0 || paraIsNull != 0) { + /* Invalid Input Format or parameter, but not meet EOF */ + return SECUREC_SCANF_ERROR_PARA; + } + return doneCount; +} + +#if SECUREC_ENABLE_SCANF_FILE +#if SECUREC_USE_STD_UNGETC +/* + * Get char from stream use std function + */ +SECUREC_INLINE SecInt SecGetCharFromStream(const SecFileStream *stream) +{ + SecInt ch; + ch = SECUREC_GETC(stream->pf); + return ch; +} +#else +/* + * Get char from stream or buffer + */ +SECUREC_INLINE SecInt SecGetCharFromStream(SecFileStream *stream) +{ + SecInt ch; + if (stream->fUnGet == 1) { + ch = (SecInt) stream->lastChar; + stream->fUnGet = 0; + } else { + ch = SECUREC_GETC(stream->pf); + stream->lastChar = (unsigned int)ch; + } + return ch; +} +#endif + +/* + * Try to read the BOM header, when meet a BOM head, discard it, then data is Aligned to base + */ +SECUREC_INLINE void SecReadAndSkipBomHeader(SecFileStream *stream) +{ + /* Use size_t type conversion to clean e747 */ + stream->count = fread(stream->base, (size_t)1, (size_t)SECUREC_BOM_HEADER_SIZE, stream->pf); + if (stream->count > SECUREC_BOM_HEADER_SIZE) { + stream->count = 0; + } + if (SECUREC_BEGIN_WITH_BOM(stream->base, stream->count)) { + /* It's BOM header, discard it */ + stream->count = 0; + } +} + +/* + * Get char from file stream or buffer + */ +SECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream) +{ + SecInt ch; + if (stream->count < sizeof(SecChar)) { + /* Load file to buffer */ + size_t len; + if (stream->base != NULL) { + /* Put the last unread data in the buffer head */ + for (len = 0; len < stream->count; ++len) { + stream->base[len] = stream->cur[len]; + } + } else { + stream->oriFilePos = ftell(stream->pf); /* Save original file read position */ + if (stream->oriFilePos == -1) { + /* It may be a pipe stream */ + stream->flag = SECUREC_PIPE_STREAM_FLAG; + return SecGetCharFromStream(stream); + } + /* Reserve the length of BOM head */ + stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE + + SECUREC_BOM_HEADER_SIZE + sizeof(SecChar)); /* To store '\0' and aligned to wide char */ + if (stream->base == NULL) { + return SECUREC_EOF; + } + /* First read file */ + if (stream->oriFilePos == 0) { + /* Make sure the data is aligned to base */ + SecReadAndSkipBomHeader(stream); + } + } + + /* Skip existing data and read data */ + len = fread(stream->base + stream->count, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf); + if (len > SECUREC_BUFFERED_BLOK_SIZE) { /* It won't happen, */ + len = 0; + } + stream->count += len; + stream->cur = stream->base; + stream->flag |= SECUREC_LOAD_FILE_TO_MEM_FLAG; + stream->base[stream->count] = '\0'; /* For tool Warning string null */ + } + + SECUREC_GET_CHAR(stream, &ch); + if (ch != SECUREC_EOF) { + stream->fileRealRead += sizeof(SecChar); + } + return ch; +} +#endif + +/* + * Get char for wchar version + */ +SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter) +{ + *counter = *counter + 1; /* Always plus 1 */ + /* The main scenario is scanf str */ + if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) { + SecInt ch; + SECUREC_GET_CHAR(stream, &ch); + return ch; + } +#if SECUREC_ENABLE_SCANF_FILE + if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) { + return SecGetCharFromFile(stream); + } + if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) { + return SecGetCharFromStream(stream); + } +#endif + return SECUREC_EOF; +} + +/* + * Unget Public realizatio char for wchar and char version + */ +SECUREC_INLINE void SecUnGetCharImpl(SecInt ch, SecFileStream *stream) +{ + if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) { + SECUREC_UN_GET_CHAR(stream); + return; + } +#if SECUREC_ENABLE_SCANF_FILE + if ((stream->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) != 0) { + SECUREC_UN_GET_CHAR(stream); + if (stream->fileRealRead > 0) { + stream->fileRealRead -= sizeof(SecChar); + } + return; + } + if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) { +#if SECUREC_USE_STD_UNGETC + (void)SECUREC_UN_GETC(ch, stream->pf); +#else + stream->lastChar = (unsigned int)ch; + stream->fUnGet = 1; +#endif + return; + } +#else + (void)ch; /* To clear e438 last value assigned not used , the compiler will optimize this code */ +#endif +} + +/* + * Unget char for char version + */ +SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter) +{ + *counter = *counter - 1; /* Always mius 1 */ + if (ch != SECUREC_EOF) { + SecUnGetCharImpl(ch, stream); + } +} + +/* + * Skip space char by isspace + */ +SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter) +{ + SecInt ch; + do { + ch = SecGetChar(stream, counter); + if (ch == SECUREC_EOF) { + break; + } + } while (SecIsSpace(ch) != 0); + return ch; +} +#endif /* INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 */ + diff --git a/components/lib/libsec/src/memcpy_s.c b/components/lib/libsec/src/memcpy_s.c new file mode 100644 index 000000000..4062a322d --- /dev/null +++ b/components/lib/libsec/src/memcpy_s.c @@ -0,0 +1,564 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: memcpy_s function + * Author: lishunda + * Create: 2014-02-25 + */ +/* + * [Standardize-exceptions] Use unsafe function: Portability + * [reason] Use unsafe function to implement security function to maintain platform compatibility. + * And sufficient input validation is performed before calling + */ + +#include "securecutil.h" + +#ifndef SECUREC_MEMCOPY_WITH_PERFORMANCE +#define SECUREC_MEMCOPY_WITH_PERFORMANCE 0 +#endif + +#if SECUREC_WITH_PERFORMANCE_ADDONS || SECUREC_MEMCOPY_WITH_PERFORMANCE +#ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE +#define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL +#endif + +#define SECUREC_SMALL_MEM_COPY(dest, src, count) do { \ + if (SECUREC_ADDR_ALIGNED_8(dest) && SECUREC_ADDR_ALIGNED_8(src)) { \ + /* Use struct assignment */ \ + switch (count) { \ + case 1: \ + *(unsigned char *)(dest) = *(const unsigned char *)(src); \ + break; \ + case 2: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 2); \ + break; \ + case 3: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 3); \ + break; \ + case 4: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 4); \ + break; \ + case 5: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 5); \ + break; \ + case 6: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 6); \ + break; \ + case 7: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 7); \ + break; \ + case 8: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 8); \ + break; \ + case 9: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 9); \ + break; \ + case 10: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 10); \ + break; \ + case 11: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 11); \ + break; \ + case 12: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 12); \ + break; \ + case 13: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 13); \ + break; \ + case 14: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 14); \ + break; \ + case 15: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 15); \ + break; \ + case 16: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 16); \ + break; \ + case 17: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 17); \ + break; \ + case 18: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 18); \ + break; \ + case 19: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 19); \ + break; \ + case 20: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 20); \ + break; \ + case 21: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 21); \ + break; \ + case 22: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 22); \ + break; \ + case 23: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 23); \ + break; \ + case 24: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 24); \ + break; \ + case 25: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 25); \ + break; \ + case 26: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 26); \ + break; \ + case 27: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 27); \ + break; \ + case 28: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 28); \ + break; \ + case 29: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 29); \ + break; \ + case 30: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 30); \ + break; \ + case 31: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 31); \ + break; \ + case 32: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 32); \ + break; \ + case 33: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 33); \ + break; \ + case 34: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 34); \ + break; \ + case 35: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 35); \ + break; \ + case 36: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 36); \ + break; \ + case 37: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 37); \ + break; \ + case 38: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 38); \ + break; \ + case 39: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 39); \ + break; \ + case 40: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 40); \ + break; \ + case 41: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 41); \ + break; \ + case 42: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 42); \ + break; \ + case 43: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 43); \ + break; \ + case 44: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 44); \ + break; \ + case 45: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 45); \ + break; \ + case 46: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 46); \ + break; \ + case 47: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 47); \ + break; \ + case 48: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 48); \ + break; \ + case 49: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 49); \ + break; \ + case 50: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 50); \ + break; \ + case 51: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 51); \ + break; \ + case 52: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 52); \ + break; \ + case 53: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 53); \ + break; \ + case 54: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 54); \ + break; \ + case 55: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 55); \ + break; \ + case 56: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 56); \ + break; \ + case 57: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 57); \ + break; \ + case 58: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 58); \ + break; \ + case 59: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 59); \ + break; \ + case 60: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 60); \ + break; \ + case 61: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 61); \ + break; \ + case 62: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 62); \ + break; \ + case 63: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 63); \ + break; \ + case 64: \ + SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 64); \ + break; \ + default: \ + /* Do nothing */ \ + break; \ + } /* END switch */ \ + } else { \ + unsigned char *tmpDest_ = (unsigned char *)(dest); \ + const unsigned char *tmpSrc_ = (const unsigned char *)(src); \ + switch (count) { \ + case 64: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 63: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 62: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 61: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 60: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 59: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 58: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 57: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 56: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 55: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 54: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 53: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 52: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 51: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 50: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 49: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 48: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 47: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 46: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 45: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 44: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 43: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 42: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 41: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 40: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 39: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 38: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 37: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 36: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 35: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 34: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 33: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 32: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 31: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 30: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 29: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 28: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 27: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 26: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 25: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 24: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 23: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 22: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 21: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 20: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 19: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 18: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 17: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 16: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 15: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 14: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 13: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 12: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 11: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 10: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 9: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 8: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 7: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 6: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 5: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 4: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 3: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 2: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 1: \ + *(tmpDest_++) = *(tmpSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + default: \ + /* Do nothing */ \ + break; \ + } \ + } \ +} SECUREC_WHILE_ZERO + +/* + * Performance optimization + */ +#define SECUREC_MEMCPY_OPT(dest, src, count) do { \ + if ((count) > SECUREC_MEMCOPY_THRESHOLD_SIZE) { \ + SECUREC_MEMCPY_WARP_OPT((dest), (src), (count)); \ + } else { \ + SECUREC_SMALL_MEM_COPY((dest), (src), (count)); \ + } \ +} SECUREC_WHILE_ZERO +#endif + +/* + * Handling errors + */ +SECUREC_INLINE errno_t SecMemcpyError(void *dest, size_t destMax, const void *src, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("memcpy_s"); + return ERANGE; + } + if (dest == NULL || src == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("memcpy_s"); + if (dest != NULL) { + (void)memset(dest, 0, destMax); + return EINVAL_AND_RESET; + } + return EINVAL; + } + if (count > destMax) { + (void)memset(dest, 0, destMax); + SECUREC_ERROR_INVALID_RANGE("memcpy_s"); + return ERANGE_AND_RESET; + } + if (SECUREC_MEMORY_IS_OVERLAP(dest, src, count)) { + (void)memset(dest, 0, destMax); + SECUREC_ERROR_BUFFER_OVERLAP("memcpy_s"); + return EOVERLAP_AND_RESET; + } + /* Count is 0 or dest equal src also ret EOK */ + return EOK; +} + +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) + /* + * The fread API in windows will call memcpy_s and pass 0xffffffff to destMax. + * To avoid the failure of fread, we don't check desMax limit. + */ +#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \ + (dest) != NULL && (src) != NULL && \ + (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) +#else +#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \ + (dest) != NULL && (src) != NULL && (destMax) <= SECUREC_MEM_MAX_LEN && \ + (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) +#endif + +/* + * + * The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest + * + * + * dest Destination buffer. + * destMax Size of the destination buffer. + * src Buffer to copy from. + * count Number of characters to copy + * + * + * dest buffer is updated. + * + * + * EOK Success + * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN + * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN + * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0 + * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN + * and dest != NULL and src != NULL + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and + * count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL + * and src != NULL and dest != src + * + * if an error occured, dest will be filled with 0. + * If the source and destination overlap, the behavior of memcpy_s is undefined. + * Use memmove_s to handle overlapping regions. + */ +errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count) +{ + if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) { +#if SECUREC_MEMCOPY_WITH_PERFORMANCE + SECUREC_MEMCPY_OPT(dest, src, count); +#else + SECUREC_MEMCPY_WARP_OPT(dest, src, count); +#endif + return EOK; + } + /* Meet some runtime violation, return error code */ + return SecMemcpyError(dest, destMax, src, count); +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(memcpy_s); +#endif + +#if SECUREC_WITH_PERFORMANCE_ADDONS +/* + * Performance optimization + */ +errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count) +{ + if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) { + SECUREC_MEMCPY_OPT(dest, src, count); + return EOK; + } + /* Meet some runtime violation, return error code */ + return SecMemcpyError(dest, destMax, src, count); +} + +/* Trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" */ +errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count) +{ + if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL && \ + count > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) { + SECUREC_MEMCPY_OPT(dest, src, count); + return EOK; + } + /* Meet some runtime violation, return error code */ + return SecMemcpyError(dest, destMax, src, count); +} +#endif + diff --git a/components/lib/libsec/src/memmove_s.c b/components/lib/libsec/src/memmove_s.c new file mode 100644 index 000000000..417df8828 --- /dev/null +++ b/components/lib/libsec/src/memmove_s.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: memmove_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +#ifdef SECUREC_NOT_CALL_LIBC_CORE_API +/* + * Implementing memory data movement + */ +SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count) +{ + unsigned char *pDest = (unsigned char *)dst; + const unsigned char *pSrc = (const unsigned char *)src; + size_t maxCount = count; + + if (dst <= src || pDest >= (pSrc + maxCount)) { + /* + * Non-Overlapping Buffers + * Copy from lower addresses to higher addresses + */ + while (maxCount > 0) { + --maxCount; + *pDest = *pSrc; + ++pDest; + ++pSrc; + } + } else { + /* + * Overlapping Buffers + * Copy from higher addresses to lower addresses + */ + pDest = pDest + maxCount - 1; + pSrc = pSrc + maxCount - 1; + while (maxCount > 0) { + --maxCount; + *pDest = *pSrc; + --pDest; + --pSrc; + } + } +} +#endif + +/* + * + * The memmove_s function copies count bytes of characters from src to dest. + * This function can be assigned correctly when memory overlaps. + * + * dest Destination object. + * destMax Size of the destination buffer. + * src Source object. + * count Number of characters to copy. + * + * + * dest buffer is uptdated. + * + * + * EOK Success + * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN + * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN + * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0 + * ERANGE_AND_RESET count > destMax and dest != NULL and src != NULL and destMax != 0 + * and destMax <= SECUREC_MEM_MAX_LEN + * + * If an error occured, dest will be filled with 0 when dest and destMax valid. + * If some regions of the source area and the destination overlap, memmove_s + * ensures that the original source bytes in the overlapping region are copied + * before being overwritten. + */ +errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("memmove_s"); + return ERANGE; + } + if (dest == NULL || src == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("memmove_s"); + if (dest != NULL) { + (void)memset(dest, 0, destMax); + return EINVAL_AND_RESET; + } + return EINVAL; + } + if (count > destMax) { + (void)memset(dest, 0, destMax); + SECUREC_ERROR_INVALID_RANGE("memmove_s"); + return ERANGE_AND_RESET; + } + if (dest == src) { + return EOK; + } + + if (count > 0) { +#ifdef SECUREC_NOT_CALL_LIBC_CORE_API + SecUtilMemmove(dest, src, count); +#else + /* Use underlying memmove for performance consideration */ + (void)memmove(dest, src, count); +#endif + } + return EOK; +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(memmove_s); +#endif + diff --git a/components/lib/libsec/src/memset_s.c b/components/lib/libsec/src/memset_s.c new file mode 100644 index 000000000..fc0cdbe6d --- /dev/null +++ b/components/lib/libsec/src/memset_s.c @@ -0,0 +1,509 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: memset_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +#define SECUREC_MEMSET_PARAM_OK(dest, destMax, count) (SECUREC_LIKELY((destMax) <= SECUREC_MEM_MAX_LEN && \ + (dest) != NULL && (count) <= (destMax))) + +#if SECUREC_WITH_PERFORMANCE_ADDONS + +/* Use union to clear strict-aliasing warning */ +typedef union { + SecStrBuf32 buf32; + SecStrBuf31 buf31; + SecStrBuf30 buf30; + SecStrBuf29 buf29; + SecStrBuf28 buf28; + SecStrBuf27 buf27; + SecStrBuf26 buf26; + SecStrBuf25 buf25; + SecStrBuf24 buf24; + SecStrBuf23 buf23; + SecStrBuf22 buf22; + SecStrBuf21 buf21; + SecStrBuf20 buf20; + SecStrBuf19 buf19; + SecStrBuf18 buf18; + SecStrBuf17 buf17; + SecStrBuf16 buf16; + SecStrBuf15 buf15; + SecStrBuf14 buf14; + SecStrBuf13 buf13; + SecStrBuf12 buf12; + SecStrBuf11 buf11; + SecStrBuf10 buf10; + SecStrBuf9 buf9; + SecStrBuf8 buf8; + SecStrBuf7 buf7; + SecStrBuf6 buf6; + SecStrBuf5 buf5; + SecStrBuf4 buf4; + SecStrBuf3 buf3; + SecStrBuf2 buf2; +} SecStrBuf32Union; +/* C standard initializes the first member of the consortium. */ +static const SecStrBuf32 g_allZero = {{ + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}}; +static const SecStrBuf32 g_allFF = {{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}}; + +/* Clear coversion warning strict aliasing" */ +SECUREC_INLINE const SecStrBuf32Union *SecStrictAliasingCast(const SecStrBuf32 *buf) +{ + return (const SecStrBuf32Union *)buf; +} + +#ifndef SECUREC_MEMSET_THRESHOLD_SIZE +#define SECUREC_MEMSET_THRESHOLD_SIZE 32UL +#endif + +#define SECUREC_UNALIGNED_SET(dest, c, count) do { \ + unsigned char *pDest_ = (unsigned char *)(dest); \ + switch (count) { \ + case 32: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 31: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 30: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 29: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 28: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 27: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 26: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 25: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 24: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 23: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 22: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 21: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 20: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 19: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 18: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 17: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 16: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 15: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 14: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 13: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 12: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 11: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 10: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 9: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 8: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 7: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 6: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 5: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 4: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 3: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 2: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + case 1: \ + *(pDest_++) = (unsigned char)(c); \ + /* fall-through */ /* FALLTHRU */ \ + default: \ + /* Do nothing */ \ + break; \ + } \ +} SECUREC_WHILE_ZERO + +#define SECUREC_SET_VALUE_BY_STRUCT(dest, dataName, n) do { \ + *(SecStrBuf##n *)(dest) = *(const SecStrBuf##n *)(&((SecStrictAliasingCast(&(dataName)))->buf##n)); \ +} SECUREC_WHILE_ZERO + +#define SECUREC_ALIGNED_SET_OPT_ZERO_FF(dest, c, count) do { \ + switch (c) { \ + case 0: \ + switch (count) { \ + case 1: \ + *(unsigned char *)(dest) = (unsigned char)0; \ + break; \ + case 2: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 2); \ + break; \ + case 3: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 3); \ + break; \ + case 4: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 4); \ + break; \ + case 5: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 5); \ + break; \ + case 6: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 6); \ + break; \ + case 7: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 7); \ + break; \ + case 8: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 8); \ + break; \ + case 9: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 9); \ + break; \ + case 10: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 10); \ + break; \ + case 11: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 11); \ + break; \ + case 12: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 12); \ + break; \ + case 13: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 13); \ + break; \ + case 14: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 14); \ + break; \ + case 15: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 15); \ + break; \ + case 16: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 16); \ + break; \ + case 17: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 17); \ + break; \ + case 18: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 18); \ + break; \ + case 19: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 19); \ + break; \ + case 20: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 20); \ + break; \ + case 21: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 21); \ + break; \ + case 22: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 22); \ + break; \ + case 23: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 23); \ + break; \ + case 24: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 24); \ + break; \ + case 25: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 25); \ + break; \ + case 26: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 26); \ + break; \ + case 27: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 27); \ + break; \ + case 28: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 28); \ + break; \ + case 29: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 29); \ + break; \ + case 30: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 30); \ + break; \ + case 31: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 31); \ + break; \ + case 32: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 32); \ + break; \ + default: \ + /* Do nothing */ \ + break; \ + } \ + break; \ + case 0xFF: \ + switch (count) { \ + case 1: \ + *(unsigned char *)(dest) = (unsigned char)0xffU; \ + break; \ + case 2: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 2); \ + break; \ + case 3: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 3); \ + break; \ + case 4: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 4); \ + break; \ + case 5: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 5); \ + break; \ + case 6: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 6); \ + break; \ + case 7: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 7); \ + break; \ + case 8: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 8); \ + break; \ + case 9: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 9); \ + break; \ + case 10: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 10); \ + break; \ + case 11: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 11); \ + break; \ + case 12: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 12); \ + break; \ + case 13: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 13); \ + break; \ + case 14: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 14); \ + break; \ + case 15: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 15); \ + break; \ + case 16: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 16); \ + break; \ + case 17: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 17); \ + break; \ + case 18: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 18); \ + break; \ + case 19: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 19); \ + break; \ + case 20: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 20); \ + break; \ + case 21: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 21); \ + break; \ + case 22: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 22); \ + break; \ + case 23: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 23); \ + break; \ + case 24: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 24); \ + break; \ + case 25: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 25); \ + break; \ + case 26: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 26); \ + break; \ + case 27: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 27); \ + break; \ + case 28: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 28); \ + break; \ + case 29: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 29); \ + break; \ + case 30: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 30); \ + break; \ + case 31: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 31); \ + break; \ + case 32: \ + SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 32); \ + break; \ + default: \ + /* Do nothing */ \ + break; \ + } \ + break; \ + default: \ + SECUREC_UNALIGNED_SET((dest), (c), (count)); \ + break; \ + } /* END switch */ \ +} SECUREC_WHILE_ZERO + +#define SECUREC_SMALL_MEM_SET(dest, c, count) do { \ + if (SECUREC_ADDR_ALIGNED_8((dest))) { \ + SECUREC_ALIGNED_SET_OPT_ZERO_FF((dest), (c), (count)); \ + } else { \ + SECUREC_UNALIGNED_SET((dest), (c), (count)); \ + } \ +} SECUREC_WHILE_ZERO + +/* + * Performance optimization + */ +#define SECUREC_MEMSET_OPT(dest, c, count) do { \ + if ((count) > SECUREC_MEMSET_THRESHOLD_SIZE) { \ + SECUREC_MEMSET_WARP_OPT((dest), (c), (count)); \ + } else { \ + SECUREC_SMALL_MEM_SET((dest), (c), (count)); \ + } \ +} SECUREC_WHILE_ZERO +#endif + +/* + * Handling errors + */ +SECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c, size_t count) +{ + /* Check destMax is 0 compatible with _sp macro */ + if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("memset_s"); + return ERANGE; + } + if (dest == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("memset_s"); + return EINVAL; + } + if (count > destMax) { + (void)memset(dest, c, destMax); /* Set entire buffer to value c */ + SECUREC_ERROR_INVALID_RANGE("memset_s"); + return ERANGE_AND_RESET; + } + return EOK; +} + +/* + * + * The memset_s function copies the value of c (converted to an unsigned char) + * into each of the first count characters of the object pointed to by dest. + * + * + * dest Pointer to destination. + * destMax The size of the buffer. + * c Character to set. + * count Number of characters. + * + * + * dest buffer is uptdated. + * + * + * EOK Success + * EINVAL dest == NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN + * ERANGE destMax > SECUREC_MEM_MAX_LEN or (destMax is 0 and count > destMax) + * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL + * + * if return ERANGE_AND_RESET then fill dest to c ,fill length is destMax + */ +errno_t memset_s(void *dest, size_t destMax, int c, size_t count) +{ + if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) { + SECUREC_MEMSET_WARP_OPT(dest, c, count); + return EOK; + } + /* Meet some runtime violation, return error code */ + return SecMemsetError(dest, destMax, c, count); +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(memset_s); +#endif + +#if SECUREC_WITH_PERFORMANCE_ADDONS +/* + * Performance optimization + */ +errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count) +{ + if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) { + SECUREC_MEMSET_OPT(dest, c, count); + return EOK; + } + /* Meet some runtime violation, return error code */ + return SecMemsetError(dest, destMax, c, count); +} + +/* + * Performance optimization, trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" + */ +errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count) +{ + if (SECUREC_LIKELY(count <= destMax && dest != NULL)) { + SECUREC_MEMSET_OPT(dest, c, count); + return EOK; + } + /* Meet some runtime violation, return error code */ + return SecMemsetError(dest, destMax, c, count); +} +#endif + diff --git a/components/lib/libsec/src/output.inl b/components/lib/libsec/src/output.inl new file mode 100644 index 000000000..20dd4b3bd --- /dev/null +++ b/components/lib/libsec/src/output.inl @@ -0,0 +1,1668 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Used by secureprintoutput_a.c and secureprintoutput_w.c to include. + * This file provides a template function for ANSI and UNICODE compiling + * by different type definition. The functions of SecOutputS or + * SecOutputSW provides internal implementation for printf family API, such as sprintf, swprintf_s. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 +#define OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 + +#ifndef SECUREC_ENABLE_SPRINTF_LONG_DOUBLE +/* Some compilers do not support long double */ +#define SECUREC_ENABLE_SPRINTF_LONG_DOUBLE 1 +#endif + +#define SECUREC_NULL_STRING_SIZE 8 +#define SECUREC_STATE_TABLE_SIZE 337 + +#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS) +#define SECUREC_DIV_QUOTIENT_OCTAL(val64) ((val64) >> 3ULL) +#define SECUREC_DIV_RESIDUE_OCTAL(val64) ((val64) & 7ULL) + +#define SECUREC_DIV_QUOTIENT_HEX(val64) ((val64) >> 4ULL) +#define SECUREC_DIV_RESIDUE_HEX(val64) ((val64) & 0xfULL) +#endif + +#define SECUREC_RADIX_OCTAL 8U +#define SECUREC_RADIX_DECIMAL 10U +#define SECUREC_RADIX_HEX 16U +#define SECUREC_PREFIX_LEN 2 +/* Size include '+' and '\0' */ +#define SECUREC_FLOAT_BUF_EXT 2 + +/* Sign extend or Zero-extend */ +#define SECUREC_GET_LONG_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ + (SecInt64)(long)va_arg(argList, long) : \ + (SecInt64)(unsigned long)va_arg(argList, long)) + +/* Sign extend or Zero-extend */ +#define SECUREC_GET_CHAR_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ + SecUpdateNegativeChar(&(attr), ((char)va_arg(argList, int))) : \ + (SecInt64)(unsigned char)va_arg(argList, int)) + +/* Sign extend or Zero-extend */ +#define SECUREC_GET_SHORT_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ + (SecInt64)(short)va_arg(argList, int) : \ + (SecInt64)(unsigned short)va_arg(argList, int)) + +/* Sign extend or Zero-extend */ +#define SECUREC_GET_INT_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ + (SecInt64)(int)va_arg(argList, int) : \ + (SecInt64)(unsigned int)va_arg(argList, int)) + +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT +/* Sign extend or Zero-extend. No suitable macros were found to handle the branch */ +#define SECUREC_GET_SIZE_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ + ((SecIsSameSize(sizeof(size_t), sizeof(long)) != 0) ? (SecInt64)(long)va_arg(argList, long) : \ + ((SecIsSameSize(sizeof(size_t), sizeof(long long)) != 0) ? (SecInt64)(long long)va_arg(argList, long long) : \ + (SecInt64)(int)va_arg(argList, int))) : \ + (SecInt64)(size_t)va_arg(argList, size_t)) +#endif + +typedef union { + /* Integer formatting refers to the end of the buffer, plus 1 to prevent tool alarms */ + char str[SECUREC_BUFFER_SIZE + 1]; +#if SECUREC_HAVE_WCHART + wchar_t wStr[SECUREC_WCHAR_BUFFER_SIZE]; /* Just for %lc */ +#endif +} SecBuffer; + +typedef union { + char *str; /* Not a null terminated string */ +#if SECUREC_HAVE_WCHART + wchar_t *wStr; +#endif +} SecFormatBuf; + +typedef struct { + const char *digits; /* Point to the hexadecimal subset */ + SecFormatBuf text; /* Point to formated string */ + int textLen; /* Length of the text */ + int textIsWide; /* Flag for text is wide chars ; 0 is not wide char */ + unsigned int radix; /* Use for output number , default set to 10 */ + unsigned int flags; + int fldWidth; + int precision; + int dynWidth; /* %* 1 width from variable parameter ;0 not */ + int dynPrecision; /* %.* 1 precision from variable parameter ;0 not */ + int padding; /* Padding len */ + int prefixLen; /* Length of prefix, 0 or 1 or 2 */ + SecChar prefix[SECUREC_PREFIX_LEN]; /* Prefix is 0 or 0x */ + SecBuffer buffer; +} SecFormatAttr; + +#if SECUREC_ENABLE_SPRINTF_FLOAT +#ifdef SECUREC_STACK_SIZE_LESS_THAN_1K +#define SECUREC_FMT_STR_LEN 8 +#else +#define SECUREC_FMT_STR_LEN 16 +#endif +typedef struct { + char buffer[SECUREC_FMT_STR_LEN]; + char *fmtStr; /* Initialization must point to buffer */ + char *allocatedFmtStr; /* Initialization must be NULL to store alloced point */ + char *floatBuffer; /* Use heap memory if the SecFormatAttr.buffer is not enough */ + int bufferSize; /* The size of floatBuffer */ +} SecFloatAdapt; +#endif + +/* Use 20 to Align the data */ +#define SECUREC_DIGITS_BUF_SIZE 20 +/* Some systems can not use pointers to point to string literals, but can use string arrays. */ +/* For example, when handling code under uboot, there is a problem with the pointer */ +static const char g_itoaUpperDigits[SECUREC_DIGITS_BUF_SIZE] = "0123456789ABCDEFX"; +static const char g_itoaLowerDigits[SECUREC_DIGITS_BUF_SIZE] = "0123456789abcdefx"; + +#if SECUREC_ENABLE_SPRINTF_FLOAT +/* Call system sprintf to format float value */ +SECUREC_INLINE int SecFormatFloat(char *strDest, const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + SECUREC_MASK_MSVC_CRT_WARNING + ret = vsprintf(strDest, format, argList); + SECUREC_END_MASK_MSVC_CRT_WARNING + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + +#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && SECUREC_ENABLE_SPRINTF_LONG_DOUBLE +/* Out put long double value to dest */ +SECUREC_INLINE void SecFormatLongDouble(SecFormatAttr *attr, const SecFloatAdapt *floatAdapt, long double ldValue) +{ + int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ? (-attr->fldWidth) : attr->fldWidth); + if (attr->dynWidth != 0 && attr->dynPrecision != 0) { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, attr->precision, ldValue); + } else if (attr->dynWidth != 0) { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, ldValue); + } else if (attr->dynPrecision != 0) { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, attr->precision, ldValue); + } else { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, ldValue); + } + if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) { + attr->textLen = 0; + } +} +#endif + +/* Out put double value to dest */ +SECUREC_INLINE void SecFormatDouble(SecFormatAttr *attr, const SecFloatAdapt *floatAdapt, double dValue) +{ + int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ? (-attr->fldWidth) : attr->fldWidth); + if (attr->dynWidth != 0 && attr->dynPrecision != 0) { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, attr->precision, dValue); + } else if (attr->dynWidth != 0) { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, dValue); + } else if (attr->dynPrecision != 0) { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, attr->precision, dValue); + } else { + attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, dValue); + } + if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) { + attr->textLen = 0; + } +} +#endif + +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT +/* To clear e506 warning */ +SECUREC_INLINE int SecIsSameSize(size_t sizeA, size_t sizeB) +{ + return (int)(sizeA == sizeB); +} +#endif + +#ifndef SECUREC_ON_64BITS +/* + * Compiler Optimized Division 8. + * The text.str point to buffer end, must be Large enough + */ +SECUREC_INLINE void SecNumber32ToOctalString(SecUnsignedInt32 number, SecFormatAttr *attr) +{ + SecUnsignedInt32 val32 = number; + do { + --attr->text.str; + /* Just use lowerDigits for 0 - 9 */ + *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_OCTAL]; + val32 /= SECUREC_RADIX_OCTAL; + } while (val32 != 0); +} + +#ifdef _AIX +/* + * Compiler Optimized Division 10. + * The text.str point to buffer end, must be Large enough + */ +SECUREC_INLINE void SecNumber32ToDecString(SecUnsignedInt32 number, SecFormatAttr *attr) +{ + SecUnsignedInt32 val32 = number; + do { + --attr->text.str; + /* Just use lowerDigits for 0 - 9 */ + *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL]; + val32 /= SECUREC_RADIX_DECIMAL; + } while (val32 != 0); +} +#endif +/* + * Compiler Optimized Division 16. + * The text.str point to buffer end, must be Large enough + */ +SECUREC_INLINE void SecNumber32ToHexString(SecUnsignedInt32 number, SecFormatAttr *attr) +{ + SecUnsignedInt32 val32 = number; + do { + --attr->text.str; + *(attr->text.str) = attr->digits[val32 % SECUREC_RADIX_HEX]; + val32 /= SECUREC_RADIX_HEX; + } while (val32 != 0); +} + +#ifndef _AIX +/* Use fast div 10 */ +SECUREC_INLINE void SecNumber32ToDecStringFast(SecUnsignedInt32 number, SecFormatAttr *attr) +{ + SecUnsignedInt32 val32 = number; + do { + SecUnsignedInt32 quotient; + SecUnsignedInt32 remain; + --attr->text.str; + *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL]; + quotient = (val32 >> 1U) + (val32 >> 2U); /* Fast div magic 2 */ + quotient = quotient + (quotient >> 4U); /* Fast div magic 4 */ + quotient = quotient + (quotient >> 8U); /* Fast div magic 8 */ + quotient = quotient + (quotient >> 16U); /* Fast div magic 16 */ + quotient = quotient >> 3U; /* Fast div magic 3 */ + remain = val32 - SECUREC_MUL_TEN(quotient); + val32 = (remain > 9U) ? (quotient + 1U) : quotient; /* Fast div magic 9 */ + } while (val32 != 0); +} +#endif + +SECUREC_INLINE void SecNumber32ToString(SecUnsignedInt32 number, SecFormatAttr *attr) +{ + switch (attr->radix) { + case SECUREC_RADIX_HEX: + SecNumber32ToHexString(number, attr); + break; + case SECUREC_RADIX_OCTAL: + SecNumber32ToOctalString(number, attr); + break; + case SECUREC_RADIX_DECIMAL: +#ifdef _AIX + /* The compiler will optimize div 10 */ + SecNumber32ToDecString(number, attr); +#else + SecNumber32ToDecStringFast(number, attr); +#endif + break; + default: + /* Do nothing */ + break; + } +} +#endif + +#if defined(SECUREC_USE_SPECIAL_DIV64) || (defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)) +/* + * This function just to clear warning, on sume vxworks compiler shift 32 bit make warnigs + */ +SECUREC_INLINE SecUnsignedInt64 SecU64Shr32(SecUnsignedInt64 number) +{ + return (((number) >> 16U) >> 16U); /* Two shifts of 16 bits to realize shifts of 32 bits */ +} +/* + * Fast divide by 10 algorithm. + * Calculation divisor multiply 0xcccccccccccccccdULL, resultHi64 >> 3 as quotient + */ +SECUREC_INLINE void SecU64Div10(SecUnsignedInt64 divisor, SecUnsignedInt64 *quotient, SecUnsignedInt32 *residue) +{ + SecUnsignedInt64 mask = 0xffffffffULL; /* Use 0xffffffffULL as 32 bit mask */ + SecUnsignedInt64 magicHi = 0xccccccccULL; /* Fast divide 10 magic numbers high 32bit 0xccccccccULL */ + SecUnsignedInt64 magicLow = 0xcccccccdULL; /* Fast divide 10 magic numbers low 32bit 0xcccccccdULL */ + SecUnsignedInt64 divisorHi = (SecUnsignedInt64)(SecU64Shr32(divisor)); /* High 32 bit use */ + SecUnsignedInt64 divisorLow = (SecUnsignedInt64)(divisor & mask); /* Low 32 bit mask */ + SecUnsignedInt64 factorHi = divisorHi * magicHi; + SecUnsignedInt64 factorLow1 = divisorHi * magicLow; + SecUnsignedInt64 factorLow2 = divisorLow * magicHi; + SecUnsignedInt64 factorLow3 = divisorLow * magicLow; + SecUnsignedInt64 carry = (factorLow1 & mask) + (factorLow2 & mask) + SecU64Shr32(factorLow3); + SecUnsignedInt64 resultHi64 = factorHi + SecU64Shr32(factorLow1) + SecU64Shr32(factorLow2) + SecU64Shr32(carry); + + *quotient = resultHi64 >> 3U; /* Fast divide 10 magic numbers 3 */ + *residue = (SecUnsignedInt32)(divisor - ((*quotient) * 10)); /* Quotient mul 10 */ + return; +} +#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS) +/* + * Divide function for VXWORKS + */ +SECUREC_INLINE int SecU64Div32(SecUnsignedInt64 divisor, SecUnsignedInt32 radix, + SecUnsignedInt64 *quotient, SecUnsignedInt32 *residue) +{ + switch (radix) { + case SECUREC_RADIX_DECIMAL: + SecU64Div10(divisor, quotient, residue); + break; + case SECUREC_RADIX_HEX: + *quotient = SECUREC_DIV_QUOTIENT_HEX(divisor); + *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_HEX(divisor); + break; + case SECUREC_RADIX_OCTAL: + *quotient = SECUREC_DIV_QUOTIENT_OCTAL(divisor); + *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_OCTAL(divisor); + break; + default: + return -1; /* This does not happen in the current file */ + } + return 0; +} +SECUREC_INLINE void SecNumber64ToStringSpecial(SecUnsignedInt64 number, SecFormatAttr *attr) +{ + SecUnsignedInt64 val64 = number; + do { + SecUnsignedInt32 digit = 0; /* Ascii value of digit */ + SecUnsignedInt64 quotient = 0; + if (SecU64Div32(val64, (SecUnsignedInt32)attr->radix, "ient, &digit) != 0) { + /* Just break, when enter this function, no error is returned */ + break; + } + --attr->text.str; + *(attr->text.str) = attr->digits[digit]; + val64 = quotient; + } while (val64 != 0); +} +#endif +#endif + +#if defined(SECUREC_ON_64BITS) || !defined(SECUREC_VXWORKS_VERSION_5_4) +#if defined(SECUREC_USE_SPECIAL_DIV64) +/* The compiler does not provide 64 bit division problems */ +SECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number, SecFormatAttr *attr) +{ + SecUnsignedInt64 val64 = number; + do { + SecUnsignedInt64 quotient = 0; + SecUnsignedInt32 digit = 0; + SecU64Div10(val64, "ient, &digit); + --attr->text.str; + /* Just use lowerDigits for 0 - 9 */ + *(attr->text.str) = g_itoaLowerDigits[digit]; + val64 = quotient; + } while (val64 != 0); +} +#else +/* + * Compiler Optimized Division 10. + * The text.str point to buffer end, must be Large enough + */ +SECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number, SecFormatAttr *attr) +{ + SecUnsignedInt64 val64 = number; + do { + --attr->text.str; + /* Just use lowerDigits for 0 - 9 */ + *(attr->text.str) = g_itoaLowerDigits[val64 % SECUREC_RADIX_DECIMAL]; + val64 /= SECUREC_RADIX_DECIMAL; + } while (val64 != 0); +} +#endif + +/* + * Compiler Optimized Division 8. + * The text.str point to buffer end, must be Large enough + */ +SECUREC_INLINE void SecNumber64ToOctalString(SecUnsignedInt64 number, SecFormatAttr *attr) +{ + SecUnsignedInt64 val64 = number; + do { + --attr->text.str; + /* Just use lowerDigits for 0 - 9 */ + *(attr->text.str) = g_itoaLowerDigits[val64 % SECUREC_RADIX_OCTAL]; + val64 /= SECUREC_RADIX_OCTAL; + } while (val64 != 0); +} +/* + * Compiler Optimized Division 16. + * The text.str point to buffer end, must be Large enough + */ +SECUREC_INLINE void SecNumber64ToHexString(SecUnsignedInt64 number, SecFormatAttr *attr) +{ + SecUnsignedInt64 val64 = number; + do { + --attr->text.str; + *(attr->text.str) = attr->digits[val64 % SECUREC_RADIX_HEX]; + val64 /= SECUREC_RADIX_HEX; + } while (val64 != 0); +} + +SECUREC_INLINE void SecNumber64ToString(SecUnsignedInt64 number, SecFormatAttr *attr) +{ + switch (attr->radix) { + /* The compiler will optimize div 10 */ + case SECUREC_RADIX_DECIMAL: + SecNumber64ToDecString(number, attr); + break; + case SECUREC_RADIX_OCTAL: + SecNumber64ToOctalString(number, attr); + break; + case SECUREC_RADIX_HEX: + SecNumber64ToHexString(number, attr); + break; + default: + /* Do nothing */ + break; + } +} +#endif + +/* + * Converting integers to string + */ +SECUREC_INLINE void SecNumberToString(SecUnsignedInt64 number, SecFormatAttr *attr) +{ +#ifdef SECUREC_ON_64BITS + SecNumber64ToString(number, attr); +#else /* For 32 bits system */ + if (number <= 0xffffffffUL) { /* Use 0xffffffffUL to check if the value is in the 32-bit range */ + /* In most case, the value to be converted is small value */ + SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number; + SecNumber32ToString(n32Tmp, attr); + } else { + /* The value to be converted is greater than 4G */ +#if defined(SECUREC_VXWORKS_VERSION_5_4) + SecNumber64ToStringSpecial(number, attr); +#else + SecNumber64ToString(number, attr); +#endif + } +#endif +} + +SECUREC_INLINE int SecIsNumberNeedTo32Bit(const SecFormatAttr *attr) +{ + return (int)(((attr->flags & SECUREC_FLAG_I64) == 0) && +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT + ((attr->flags & SECUREC_FLAG_INTMAX) == 0) && +#endif +#ifdef SECUREC_ON_64BITS + ((attr->flags & SECUREC_FLAG_PTRDIFF) == 0) && + ((attr->flags & SECUREC_FLAG_SIZE) == 0) && +#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */ + ((attr->flags & SECUREC_FLAG_LONG) == 0) && +#endif +#endif + ((attr->flags & SECUREC_FLAG_LONGLONG) == 0)); +} + +SECUREC_INLINE void SecNumberToBuffer(SecFormatAttr *attr, SecInt64 num64) +{ + SecUnsignedInt64 number; + /* Check for negative; copy into number */ + if ((attr->flags & SECUREC_FLAG_SIGNED) != 0 && num64 < 0) { + number = (SecUnsignedInt64)(0 - (SecUnsignedInt64)num64); /* Wrap with unsigned int64 numbers */ + attr->flags |= SECUREC_FLAG_NEGATIVE; + } else { + number = (SecUnsignedInt64)num64; + } + if (SecIsNumberNeedTo32Bit(attr) != 0) { + number = (number & (SecUnsignedInt64)0xffffffffUL); /* Use 0xffffffff as 32 bit mask */ + } + + /* The text.str must be point to buffer.str, this pointer is used outside the function */ + attr->text.str = &attr->buffer.str[SECUREC_BUFFER_SIZE]; + + if (number == 0) { + /* Turn off hex prefix default, and textLen is zero */ + attr->prefixLen = 0; + attr->textLen = 0; + return; + } + + /* Convert integer to string. It must be invoked when number > 0, otherwise the following logic is incorrect */ + SecNumberToString(number, attr); + /* Compute length of number, text.str must be in buffer.str */ + attr->textLen = (int)(size_t)((char *)&attr->buffer.str[SECUREC_BUFFER_SIZE] - attr->text.str); +} + +/* Use loop copy char or wchar_t string */ +SECUREC_INLINE void SecWriteStringToStreamOpt(SecPrintfStream *stream, const SecChar *str, int len) +{ + int i; + const SecChar *tmp = str; + for (i = 0; i < len; ++i) { + *((SecChar *)(void *)(stream->cur)) = *(const SecChar *)(tmp); + stream->cur += sizeof(SecChar); + tmp = tmp + 1; + } + stream->count -= len * (int)(sizeof(SecChar)); +} + +SECUREC_INLINE void SecWriteStringToStream(SecPrintfStream *stream, const SecChar *str, int len) +{ + if (len < 12) { /* Performance optimization for mobile number length 12 */ + SecWriteStringToStreamOpt(stream, str, len); + } else { + size_t count = (size_t)(unsigned int)len * (sizeof(SecChar)); + SECUREC_MEMCPY_WARP_OPT(stream->cur, str, count); + stream->cur += (size_t)((size_t)(unsigned int)len * (sizeof(SecChar))); + stream->count -= len * (int)(sizeof(SecChar)); + } +} + +/* + * Return if buffer length is enough + * The count variable can be reduced to 0, and the external function complements the \0 terminator. + */ +SECUREC_INLINE int SecIsStreamBufEnough(const SecPrintfStream *stream, int needLen) +{ + return ((int)(stream->count - (needLen * (int)(sizeof(SecChar)))) >= 0); +} + +#ifdef SECUREC_FOR_WCHAR +SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f, int *pnumwritten); +SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len, SecPrintfStream *f, int *pnumwritten); +#define SECUREC_WRITE_MULTI_CHAR SecWriteMultiCharW +#define SECUREC_WRITE_STRING SecWriteStringW +#else +SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten); +SECUREC_INLINE void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten); +#define SECUREC_WRITE_MULTI_CHAR SecWriteMultiChar +#define SECUREC_WRITE_STRING SecWriteString +#endif + +/* Write left padding */ +SECUREC_INLINE void SecWriteLeftPadding(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ + if ((attr->flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) == 0 && attr->padding > 0) { + /* Pad on left with blanks */ + SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), attr->padding, stream, charsOut); + } +} + +/* Write prefix */ +SECUREC_INLINE void SecWritePrefix(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ + if (attr->prefixLen > 0) { + if (SecIsStreamBufEnough(stream, attr->prefixLen) != 0) { + /* Max prefix len is 2, use loop copy */ + SecWriteStringToStreamOpt(stream, attr->prefix, attr->prefixLen); + *charsOut += attr->prefixLen; + } else { + SECUREC_WRITE_STRING(attr->prefix, attr->prefixLen, stream, charsOut); + } + } +} + +/* Write leading zeros */ +SECUREC_INLINE void SecWriteLeadingZero(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ + if ((attr->flags & SECUREC_FLAG_LEADZERO) != 0 && (attr->flags & SECUREC_FLAG_LEFT) == 0 && + attr->padding > 0) { + SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR('0'), attr->padding, stream, charsOut); + } +} + +/* Write right padding */ +SECUREC_INLINE void SecWriteRightPadding(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ + if (*charsOut >= 0 && (attr->flags & SECUREC_FLAG_LEFT) != 0 && attr->padding > 0) { + /* Pad on right with blanks */ + SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), attr->padding, stream, charsOut); + } +} + +/* Write text string */ +SECUREC_INLINE void SecWriteStringChk(SecPrintfStream *stream, const SecChar *str, int len, int *charsOut) +{ + if (SecIsStreamBufEnough(stream, len) != 0) { + SecWriteStringToStream(stream, str, len); + *charsOut += len; + } else { + SECUREC_WRITE_STRING(str, len, stream, charsOut); + } +} + +#ifdef SECUREC_FOR_WCHAR +#if SECUREC_HAVE_MBTOWC +SECUREC_INLINE void SecWriteTextAfterMbtowc(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ + const char *p = attr->text.str; + int count = attr->textLen; + while (count > 0) { + wchar_t wChar = L'\0'; + int retVal = mbtowc(&wChar, p, (size_t)MB_CUR_MAX); + if (retVal <= 0) { + *charsOut = -1; + break; + } + SecWriteCharW(wChar, stream, charsOut); + if (*charsOut == -1) { + break; + } + p += retVal; + count -= retVal; + } +} +#endif +#else /* Not SECUREC_FOR_WCHAR */ +#if SECUREC_HAVE_WCTOMB +SECUREC_INLINE void SecWriteTextAfterWctomb(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ + const wchar_t *p = attr->text.wStr; + int count = attr->textLen; + while (count > 0) { + char tmpBuf[SECUREC_MB_LEN + 1]; + SECUREC_MASK_MSVC_CRT_WARNING + int retVal = wctomb(tmpBuf, *p); + SECUREC_END_MASK_MSVC_CRT_WARNING + if (retVal <= 0) { + *charsOut = -1; + break; + } + SecWriteString(tmpBuf, retVal, stream, charsOut); + if (*charsOut == -1) { + break; + } + --count; + ++p; + } +} +#endif +#endif + +#if SECUREC_ENABLE_SPRINTF_FLOAT +/* + * Write text of float + * Using independent functions to optimize the expansion of inline functions by the compiler + */ +SECUREC_INLINE void SecWriteFloatText(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ +#ifdef SECUREC_FOR_WCHAR +#if SECUREC_HAVE_MBTOWC + SecWriteTextAfterMbtowc(stream, attr, charsOut); +#else + *charsOut = -1; + (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */ +#endif +#else /* Not SECUREC_FOR_WCHAR */ + SecWriteString(attr->text.str, attr->textLen, stream, charsOut); +#endif +} +#endif + +/* Write text of integer or string ... */ +SECUREC_INLINE void SecWriteText(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) +{ +#ifdef SECUREC_FOR_WCHAR + if (attr->textIsWide != 0) { + SecWriteStringChk(stream, attr->text.wStr, attr->textLen, charsOut); + } else { +#if SECUREC_HAVE_MBTOWC + SecWriteTextAfterMbtowc(stream, attr, charsOut); +#else + *charsOut = -1; +#endif + } + +#else /* Not SECUREC_FOR_WCHAR */ + if (attr->textIsWide != 0) { +#if SECUREC_HAVE_WCTOMB + SecWriteTextAfterWctomb(stream, attr, charsOut); +#else + *charsOut = -1; +#endif + } else { + SecWriteStringChk(stream, attr->text.str, attr->textLen, charsOut); + } +#endif +} + +#define SECUREC_FMT_STATE_OFFSET 256 + +SECUREC_INLINE SecFmtState SecDecodeState(SecChar ch, SecFmtState lastState) +{ + static const unsigned char stateTable[SECUREC_STATE_TABLE_SIZE] = { + /* + * Type + * 0: nospecial meanin; + * 1: '%' + * 2: '.' + * 3: '*' + * 4: '0' + * 5: '1' ... '9' + * 6: ' ', '+', '-', '#' + * 7: 'h', 'l', 'L', 'w' , 'N', 'z', 'q', 't', 'j' + * 8: 'd', 'o', 'u', 'i', 'x', 'X', 'e', 'f', 'g', 'E', 'F', 'G', 's', 'c', '[', 'p' + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00, + 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08, + 0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + /* Fill zero for normal char 128 byte for 0x80 - 0xff */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* + * State + * 0: normal + * 1: percent + * 2: flag + * 3: width + * 4: dot + * 5: precis + * 6: size + * 7: type + * 8: invalid + */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05, + 0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, + 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, + 0x00 + }; + +#ifdef SECUREC_FOR_WCHAR + /* Convert to unsigned char to clear gcc 4.3.4 warning */ + unsigned char fmtType = (unsigned char)((((unsigned int)(int)(ch)) <= (unsigned int)(int)(L'~')) ? \ + (stateTable[(unsigned char)(ch)]) : 0); + return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID + 1) + + (unsigned char)(lastState) + SECUREC_FMT_STATE_OFFSET]); +#else + unsigned char fmtType = stateTable[(unsigned char)(ch)]; + return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID + 1) + + (unsigned char)(lastState) + SECUREC_FMT_STATE_OFFSET]); +#endif +} + +SECUREC_INLINE void SecDecodeFlags(SecChar ch, SecFormatAttr *attr) +{ + switch (ch) { + case SECUREC_CHAR(' '): + attr->flags |= SECUREC_FLAG_SIGN_SPACE; + break; + case SECUREC_CHAR('+'): + attr->flags |= SECUREC_FLAG_SIGN; + break; + case SECUREC_CHAR('-'): + attr->flags |= SECUREC_FLAG_LEFT; + break; + case SECUREC_CHAR('0'): + attr->flags |= SECUREC_FLAG_LEADZERO; /* Add zero th the front */ + break; + case SECUREC_CHAR('#'): + attr->flags |= SECUREC_FLAG_ALTERNATE; /* Output %x with 0x */ + break; + default: + /* Do nothing */ + break; + } + return; +} + +/* + * Decoded size identifier in format string to Reduce the number of lines of function code + */ +SECUREC_INLINE int SecDecodeSizeI(SecFormatAttr *attr, const SecChar **format) +{ +#ifdef SECUREC_ON_64BITS + attr->flags |= SECUREC_FLAG_I64; /* %I to INT64 */ +#endif + if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) { + (*format) += 2; /* Add 2 to skip I64 */ + attr->flags |= SECUREC_FLAG_I64; /* %I64 to INT64 */ + } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) { + (*format) += 2; /* Add 2 to skip I32 */ + attr->flags &= ~SECUREC_FLAG_I64; /* %I64 to INT32 */ + } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) || + (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) || + (**format == SECUREC_CHAR('x')) || (**format == SECUREC_CHAR('X'))) { + /* Do nothing */ + } else { + /* Compatibility code for "%I" just print I */ + return -1; + } + return 0; +} +/* + * Decoded size identifier in format string, and skip format to next charater + */ +SECUREC_INLINE int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format) +{ + switch (ch) { + case SECUREC_CHAR('l'): + if (**format == SECUREC_CHAR('l')) { + *format = *format + 1; + attr->flags |= SECUREC_FLAG_LONGLONG; /* For long long */ + } else { + attr->flags |= SECUREC_FLAG_LONG; /* For long int or wchar_t */ + } + break; +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT + case SECUREC_CHAR('z'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('Z'): + attr->flags |= SECUREC_FLAG_SIZE; + break; + case SECUREC_CHAR('j'): + attr->flags |= SECUREC_FLAG_INTMAX; + break; +#endif + case SECUREC_CHAR('t'): + attr->flags |= SECUREC_FLAG_PTRDIFF; + break; + case SECUREC_CHAR('q'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('L'): + attr->flags |= (SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE); + break; + case SECUREC_CHAR('I'): + if (SecDecodeSizeI(attr, format) != 0) { + /* Compatibility code for "%I" just print I */ + return -1; + } + break; + case SECUREC_CHAR('h'): + if (**format == SECUREC_CHAR('h')) { + *format = *format + 1; + attr->flags |= SECUREC_FLAG_CHAR; /* For char */ + } else { + attr->flags |= SECUREC_FLAG_SHORT; /* For short int */ + } + break; + case SECUREC_CHAR('w'): + attr->flags |= SECUREC_FLAG_WIDECHAR; /* For wide char */ + break; + default: + /* Do nothing */ + break; + } + return 0; +} + +/* + * Decoded char type identifier + */ +SECUREC_INLINE void SecDecodeTypeC(SecFormatAttr *attr, unsigned int c) +{ + attr->textLen = 1; /* Only 1 wide character */ + +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS)) + attr->flags &= ~SECUREC_FLAG_LEADZERO; +#endif + +#ifdef SECUREC_FOR_WCHAR + if ((attr->flags & SECUREC_FLAG_SHORT) != 0) { + /* Get multibyte character from argument */ + attr->buffer.str[0] = (char)c; + attr->text.str = attr->buffer.str; + attr->textIsWide = 0; + } else { + attr->buffer.wStr[0] = (wchar_t)c; + attr->text.wStr = attr->buffer.wStr; + attr->textIsWide = 1; + } +#else /* Not SECUREC_FOR_WCHAR */ + if ((attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) != 0) { +#if SECUREC_HAVE_WCHART + attr->buffer.wStr[0] = (wchar_t)c; + attr->text.wStr = attr->buffer.wStr; + attr->textIsWide = 1; +#else + attr->textLen = 0; /* Ignore unsupported characters */ + attr->fldWidth = 0; /* No paddings */ +#endif + } else { + /* Get multibyte character from argument */ + attr->buffer.str[0] = (char)c; + attr->text.str = attr->buffer.str; + attr->textIsWide = 0; + } +#endif +} + +SECUREC_INLINE void SecDecodeTypeSchar(SecFormatAttr *attr) +{ + if (attr->text.str == NULL) { + /* + * Literal string to print null ptr, define it as array rather than const text area + * To avoid gcc warning with pointing const text with variable + */ + static char strNullString[SECUREC_NULL_STRING_SIZE] = "(null)"; + attr->text.str = strNullString; + } + if (attr->precision == -1) { + /* Precision NOT assigned */ + /* The strlen performance is high when the string length is greater than 32 */ + attr->textLen = (int)strlen(attr->text.str); + } else { + /* Precision assigned */ + size_t textLen; + SECUREC_CALC_STR_LEN(attr->text.str, (size_t)(unsigned int)attr->precision, &textLen); + attr->textLen = (int)textLen; + } +} + +SECUREC_INLINE void SecDecodeTypeSwchar(SecFormatAttr *attr) +{ +#if SECUREC_HAVE_WCHART + size_t textLen; + attr->textIsWide = 1; + if (attr->text.wStr == NULL) { + /* + * Literal string to print null ptr, define it as array rather than const text area + * To avoid gcc warning with pointing const text with variable + */ + static wchar_t wStrNullString[SECUREC_NULL_STRING_SIZE] = { L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0' }; + attr->text.wStr = wStrNullString; + } + /* The textLen in wchar_t,when precision is -1, it is unlimited */ + SECUREC_CALC_WSTR_LEN(attr->text.wStr, (size_t)(unsigned int)attr->precision, &textLen); + attr->textLen = (int)textLen; +#else + attr->textLen = 0; +#endif +} + +/* + * Decoded string identifier + */ +SECUREC_INLINE void SecDecodeTypeS(SecFormatAttr *attr, char *argPtr) +{ +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && (!defined(SECUREC_ON_UNIX)) + attr->flags &= ~SECUREC_FLAG_LEADZERO; +#endif + attr->text.str = argPtr; +#ifdef SECUREC_FOR_WCHAR +#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) + if ((attr->flags & SECUREC_FLAG_LONG) == 0) { + attr->flags |= SECUREC_FLAG_SHORT; + } +#endif + if ((attr->flags & SECUREC_FLAG_SHORT) != 0) { + /* The textLen now contains length in multibyte chars */ + SecDecodeTypeSchar(attr); + } else { + /* The textLen now contains length in wide chars */ + SecDecodeTypeSwchar(attr); + } +#else /* SECUREC_FOR_WCHAR */ + if ((attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) != 0) { + /* The textLen now contains length in wide chars */ + SecDecodeTypeSwchar(attr); + } else { + /* The textLen now contains length in multibyte chars */ + SecDecodeTypeSchar(attr); + } +#endif /* SECUREC_FOR_WCHAR */ + if (attr->textLen < 0) { + attr->textLen = 0; + } +} + +/* + * Write one character to dest buffer + */ +SECUREC_INLINE void SecOutputOneChar(SecChar ch, SecPrintfStream *stream, int *counter) +{ + /* Count must be reduced first, In order to identify insufficient length */ + stream->count -= (int)(sizeof(SecChar)); + if (stream->count >= 0) { + *((SecChar *)(void *)(stream->cur)) = (SecChar)ch; + stream->cur += sizeof(SecChar); + *counter = *(counter) + 1; + return; + } + /* No enough length */ + *counter = -1; +} + +/* + * Check precison in format + */ +SECUREC_INLINE int SecDecodePrecision(SecChar ch, SecFormatAttr *attr) +{ + if (attr->dynPrecision == 0) { + /* Add digit to current precision */ + if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->precision)) { + return -1; + } + attr->precision = (int)SECUREC_MUL_TEN((unsigned int)attr->precision) + + (unsigned char)(ch - SECUREC_CHAR('0')); + } else { + if (attr->precision < 0) { + attr->precision = -1; + } + if (attr->precision > SECUREC_MAX_WIDTH_LEN) { + return -1; + } + } + return 0; +} + +/* + * Check width in format + */ +SECUREC_INLINE int SecDecodeWidth(SecChar ch, SecFormatAttr *attr, SecFmtState lastState) +{ + if (attr->dynWidth == 0) { + if (lastState != STAT_WIDTH) { + attr->fldWidth = 0; + } + if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->fldWidth)) { + return -1; + } + attr->fldWidth = (int)SECUREC_MUL_TEN((unsigned int)attr->fldWidth) + + (unsigned char)(ch - SECUREC_CHAR('0')); + } else { + if (attr->fldWidth < 0) { + attr->flags |= SECUREC_FLAG_LEFT; + attr->fldWidth = (-attr->fldWidth); + if (attr->fldWidth > SECUREC_MAX_WIDTH_LEN) { + return -1; + } + } + } + return 0; +} + +/* + * The sprintf_s function processes the wide character as a parameter for %C + * The swprintf_s function processes the multiple character as a parameter for %C + */ +SECUREC_INLINE void SecUpdateWcharFlags(SecFormatAttr *attr) +{ + if ((attr->flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) == 0) { +#ifdef SECUREC_FOR_WCHAR + attr->flags |= SECUREC_FLAG_SHORT; +#else + attr->flags |= SECUREC_FLAG_WIDECHAR; +#endif + } +} +/* + * When encountering %S, current just same as %C + */ +SECUREC_INLINE void SecUpdateWstringFlags(SecFormatAttr *attr) +{ + SecUpdateWcharFlags(attr); +} + +#if SECUREC_IN_KERNEL +SECUREC_INLINE void SecUpdatePointFlagsForKernel(SecFormatAttr *attr) +{ + /* Width is not set */ + if (attr->fldWidth <= 0) { + attr->flags |= SECUREC_FLAG_LEADZERO; + attr->fldWidth = 2 * sizeof(void *); /* 2 x byte number is the length of hex */ + } + if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { + /* Alternate form means '0x' prefix */ + attr->prefix[0] = SECUREC_CHAR('0'); + attr->prefix[1] = SECUREC_CHAR('x'); + attr->prefixLen = SECUREC_PREFIX_LEN; + } + attr->flags |= SECUREC_FLAG_LONG; /* Converting a long */ +} +#endif + +SECUREC_INLINE void SecUpdatePointFlags(SecFormatAttr *attr) +{ + attr->flags |= SECUREC_FLAG_POINTER; +#if SECUREC_IN_KERNEL + SecUpdatePointFlagsForKernel(attr); +#else +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX)) +#if defined(SECUREC_VXWORKS_PLATFORM) + attr->precision = 1; +#else + attr->precision = 0; +#endif + attr->flags |= SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */ + attr->digits = g_itoaLowerDigits; +#else /* On unix or win */ +#if defined(_AIX) || defined(SECUREC_ON_SOLARIS) + attr->precision = 1; +#else + attr->precision = 2 * sizeof(void *); /* 2 x byte number is the length of hex */ +#endif +#if defined(SECUREC_ON_UNIX) + attr->digits = g_itoaLowerDigits; +#else + attr->digits = g_itoaUpperDigits; +#endif +#endif + +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) + attr->flags &= ~SECUREC_FLAG_LEADZERO; +#endif + +#ifdef SECUREC_ON_64BITS + attr->flags |= SECUREC_FLAG_I64; /* Converting an int64 */ +#else + attr->flags |= SECUREC_FLAG_LONG; /* Converting a long */ +#endif + /* Set up for %#p on different system */ + if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { + /* Alternate form means '0x' prefix */ + attr->prefix[0] = SECUREC_CHAR('0'); +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) + attr->prefix[1] = SECUREC_CHAR('x'); +#else + attr->prefix[1] = (SecChar)(attr->digits[16]); /* 16 for 'x' or 'X' */ +#endif +#if defined(_AIX) || defined(SECUREC_ON_SOLARIS) + attr->prefixLen = 0; +#else + attr->prefixLen = SECUREC_PREFIX_LEN; +#endif + } +#endif +} + +SECUREC_INLINE void SecUpdateXpxFlags(SecFormatAttr *attr, SecChar ch) +{ + /* Use unsigned lower hex output for 'x' */ + attr->digits = g_itoaLowerDigits; + attr->radix = SECUREC_RADIX_HEX; + switch (ch) { + case SECUREC_CHAR('p'): + /* Print a pointer */ + SecUpdatePointFlags(attr); + break; + case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */ + /* Unsigned upper hex output */ + attr->digits = g_itoaUpperDigits; + /* fall-through */ /* FALLTHRU */ + default: + /* For %#x or %#X */ + if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { + /* Alternate form means '0x' prefix */ + attr->prefix[0] = SECUREC_CHAR('0'); + attr->prefix[1] = (SecChar)(attr->digits[16]); /* 16 for 'x' or 'X' */ + attr->prefixLen = SECUREC_PREFIX_LEN; + } + break; + } +} +SECUREC_INLINE void SecUpdateOudiFlags(SecFormatAttr *attr, SecChar ch) +{ + /* Do not set digits here */ + switch (ch) { + case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */ + /* For signed decimal output */ + attr->flags |= SECUREC_FLAG_SIGNED; + /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('u'): + attr->radix = SECUREC_RADIX_DECIMAL; + attr->digits = g_itoaLowerDigits; + break; + case SECUREC_CHAR('o'): + /* For unsigned octal output */ + attr->radix = SECUREC_RADIX_OCTAL; + attr->digits = g_itoaLowerDigits; + if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { + /* Alternate form means force a leading 0 */ + attr->flags |= SECUREC_FLAG_FORCE_OCTAL; + } + break; + default: + /* Do nothing */ + break; + } +} + +#if SECUREC_ENABLE_SPRINTF_FLOAT +SECUREC_INLINE void SecFreeFloatBuffer(SecFloatAdapt *floatAdapt) +{ + if (floatAdapt->floatBuffer != NULL) { + SECUREC_FREE(floatAdapt->floatBuffer); + } + if (floatAdapt->allocatedFmtStr != NULL) { + SECUREC_FREE(floatAdapt->allocatedFmtStr); + } + floatAdapt->floatBuffer = NULL; + floatAdapt->allocatedFmtStr = NULL; + floatAdapt->fmtStr = NULL; + floatAdapt->bufferSize = 0; +} + +SECUREC_INLINE void SecSeekToFrontPercent(const SecChar **format) +{ + const SecChar *fmt = *format; + while (*fmt != SECUREC_CHAR('%')) { /* Must meet '%' */ + --fmt; + } + *format = fmt; +} + +/* Init float format, return 0 is OK */ +SECUREC_INLINE int SecInitFloatFmt(SecFloatAdapt *floatFmt, const SecChar *format) +{ + const SecChar *fmt = format - 2; /* Sub 2 to the position before 'f' or 'g' */ + int fmtStrLen; + int i; + + SecSeekToFrontPercent(&fmt); + /* Now fmt point to '%' */ + fmtStrLen = (int)(size_t)(format - fmt) + 1; /* With ending terminator */ + if (fmtStrLen > (int)sizeof(floatFmt->buffer)) { + /* When buffer is NOT enough, alloc a new buffer */ + floatFmt->allocatedFmtStr = (char *)SECUREC_MALLOC((size_t)((unsigned int)fmtStrLen)); + if (floatFmt->allocatedFmtStr == NULL) { + return -1; + } + floatFmt->fmtStr = floatFmt->allocatedFmtStr; + } else { + floatFmt->fmtStr = floatFmt->buffer; + floatFmt->allocatedFmtStr = NULL; /* Must set to NULL, later code free memory based on this identity */ + } + + for (i = 0; i < fmtStrLen - 1; ++i) { + /* Convert wchar to char */ + floatFmt->fmtStr[i] = (char)(fmt[i]); /* Copy the format string */ + } + floatFmt->fmtStr[fmtStrLen - 1] = '\0'; + + return 0; +} + +/* Init float buffer and format, return 0 is OK */ +SECUREC_INLINE int SecInitFloatBuffer(SecFloatAdapt *floatAdapt, const SecChar *format, SecFormatAttr *attr) +{ + floatAdapt->allocatedFmtStr = NULL; + floatAdapt->fmtStr = NULL; + floatAdapt->floatBuffer = NULL; + /* Compute the precision value */ + if (attr->precision < 0) { + attr->precision = SECUREC_FLOAT_DEFAULT_PRECISION; + } + /* + * Calc buffer size to store double value + * The maximum length of SECUREC_MAX_WIDTH_LEN is enough + */ + if ((attr->flags & SECUREC_FLAG_LONG_DOUBLE) != 0) { + if (attr->precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE_LB)) { + return -1; + } + /* Long double needs to meet the basic print length */ + floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE_LB + attr->precision + SECUREC_FLOAT_BUF_EXT; + } else { + if (attr->precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE)) { + return -1; + } + /* Double needs to meet the basic print length */ + floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE + attr->precision + SECUREC_FLOAT_BUF_EXT; + } + if (attr->fldWidth > floatAdapt->bufferSize) { + floatAdapt->bufferSize = attr->fldWidth + SECUREC_FLOAT_BUF_EXT; + } + + if (floatAdapt->bufferSize > SECUREC_BUFFER_SIZE) { + /* The current vlaue of SECUREC_BUFFER_SIZE could NOT store the formatted float string */ + floatAdapt->floatBuffer = (char *)SECUREC_MALLOC(((size_t)(unsigned int)floatAdapt->bufferSize)); + if (floatAdapt->floatBuffer == NULL) { + return -1; + } + attr->text.str = floatAdapt->floatBuffer; + } else { + attr->text.str = attr->buffer.str; /* Output buffer for float string with default size */ + } + + if (SecInitFloatFmt(floatAdapt, format) != 0) { + if (floatAdapt->floatBuffer != NULL) { + SECUREC_FREE(floatAdapt->floatBuffer); + floatAdapt->floatBuffer = NULL; + } + return -1; + } + return 0; +} +#endif + +SECUREC_INLINE SecInt64 SecUpdateNegativeChar(SecFormatAttr *attr, char ch) +{ + SecInt64 num64 = ch; /* Sign extend */ + if (num64 >= 128) { /* 128 on some platform, char is always unsigned */ + unsigned char tmp = (unsigned char)(~((unsigned char)ch)); + num64 = tmp + 1; + attr->flags |= SECUREC_FLAG_NEGATIVE; + } + return num64; +} + +/* + * If the precision is not satisfied, zero is added before the string + */ +SECUREC_INLINE void SecNumberSatisfyPrecision(SecFormatAttr *attr) +{ + int precision; + if (attr->precision < 0) { + precision = 1; /* Default precision 1 */ + } else { +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) + attr->flags &= ~SECUREC_FLAG_LEADZERO; +#else + if ((attr->flags & SECUREC_FLAG_POINTER) == 0) { + attr->flags &= ~SECUREC_FLAG_LEADZERO; + } +#endif + if (attr->precision > SECUREC_MAX_PRECISION) { + attr->precision = SECUREC_MAX_PRECISION; + } + precision = attr->precision; + } + while (attr->textLen < precision) { + --attr->text.str; + *(attr->text.str) = '0'; + ++attr->textLen; + } +} + +/* + * Add leading zero for %#o + */ +SECUREC_INLINE void SecNumberForceOctal(SecFormatAttr *attr) +{ + /* Force a leading zero if FORCEOCTAL flag set */ + if ((attr->flags & SECUREC_FLAG_FORCE_OCTAL) != 0 && + (attr->textLen == 0 || attr->text.str[0] != '0')) { + --attr->text.str; + *(attr->text.str) = '0'; + ++attr->textLen; + } +} + +SECUREC_INLINE void SecUpdateSignedNumberPrefix(SecFormatAttr *attr) +{ + if ((attr->flags & SECUREC_FLAG_SIGNED) == 0) { + return; + } + if ((attr->flags & SECUREC_FLAG_NEGATIVE) != 0) { + /* Prefix is '-' */ + attr->prefix[0] = SECUREC_CHAR('-'); + attr->prefixLen = 1; + return; + } + if ((attr->flags & SECUREC_FLAG_SIGN) != 0) { + /* Prefix is '+' */ + attr->prefix[0] = SECUREC_CHAR('+'); + attr->prefixLen = 1; + return; + } + if ((attr->flags & SECUREC_FLAG_SIGN_SPACE) != 0) { + /* Prefix is ' ' */ + attr->prefix[0] = SECUREC_CHAR(' '); + attr->prefixLen = 1; + return; + } + return; +} + +SECUREC_INLINE void SecNumberCompatZero(SecFormatAttr *attr) +{ +#if SECUREC_IN_KERNEL + if ((attr->flags & SECUREC_FLAG_POINTER) != 0) { + static char strNullPointer[SECUREC_NULL_STRING_SIZE] = "(null)"; + attr->text.str = strNullPointer; + attr->textLen = 6; /* Length of (null) is 6 */ + attr->flags &= ~SECUREC_FLAG_LEADZERO; + attr->prefixLen = 0; + if (attr->precision >= 0 && attr->precision < attr->textLen) { + attr->textLen = attr->precision; + } + } + if ((attr->flags & SECUREC_FLAG_POINTER) == 0 && attr->radix == SECUREC_RADIX_HEX && + (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { + /* Add 0x prefix for %x or %X, the prefix string has been set before */ + attr->prefixLen = SECUREC_PREFIX_LEN; + } +#elif defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX)) + if ((attr->flags & SECUREC_FLAG_POINTER) != 0) { + static char strNullPointer[SECUREC_NULL_STRING_SIZE] = "(nil)"; + attr->text.str = strNullPointer; + attr->textLen = 5; /* Length of (nil) is 5 */ + attr->flags &= ~SECUREC_FLAG_LEADZERO; + } +#elif defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux) + if ((attr->flags & SECUREC_FLAG_POINTER) != 0 && (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { + /* Add 0x prefix for %p, the prefix string has been set before */ + attr->prefixLen = SECUREC_PREFIX_LEN; + } +#endif + (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */ +} + +#ifdef SECUREC_FOR_WCHAR +/* + * Formatting output core functions for wchar version.Called by a function such as vswprintf_s + * The argList must not be declare as const + */ +SECUREC_INLINE int SecOutputSW(SecPrintfStream *stream, const wchar_t *cFormat, va_list argList) +#else +/* + * Formatting output core functions for char version.Called by a function such as vsnprintf_s + */ +SECUREC_INLINE int SecOutputS(SecPrintfStream *stream, const char *cFormat, va_list argList) +#endif +{ + const SecChar *format = cFormat; + int charsOut; /* Characters written */ + int noOutput = 0; /* Must be initialized or compiler alerts */ + SecFmtState state; + SecFormatAttr formatAttr; + + formatAttr.flags = 0; + formatAttr.textIsWide = 0; /* Flag for buffer contains wide chars */ + formatAttr.fldWidth = 0; + formatAttr.precision = 0; + formatAttr.dynWidth = 0; + formatAttr.dynPrecision = 0; + formatAttr.digits = g_itoaUpperDigits; + formatAttr.radix = SECUREC_RADIX_DECIMAL; + formatAttr.padding = 0; + formatAttr.textLen = 0; + formatAttr.text.str = NULL; + formatAttr.prefixLen = 0; + formatAttr.prefix[0] = SECUREC_CHAR('\0'); + formatAttr.prefix[1] = SECUREC_CHAR('\0'); + charsOut = 0; + state = STAT_NORMAL; /* Starting state */ + + /* Loop each format character */ + while (*format != SECUREC_CHAR('\0') && charsOut >= 0) { + SecFmtState lastState = state; + SecChar ch = *format; /* Currently read character */ + ++format; + state = SecDecodeState(ch, lastState); + switch (state) { + case STAT_NORMAL: + SecOutputOneChar(ch, stream, &charsOut); + continue; + case STAT_PERCENT: + /* Set default values */ + noOutput = 0; + formatAttr.prefixLen = 0; + formatAttr.textLen = 0; + formatAttr.flags = 0; + formatAttr.fldWidth = 0; + formatAttr.precision = -1; + formatAttr.textIsWide = 0; + formatAttr.dynWidth = 0; + formatAttr.dynPrecision = 0; + break; + case STAT_FLAG: + /* Set flag based on which flag character */ + SecDecodeFlags(ch, &formatAttr); + break; + case STAT_WIDTH: + /* Update width value */ + if (ch == SECUREC_CHAR('*')) { + /* get width from arg list */ + formatAttr.fldWidth = (int)va_arg(argList, int); + formatAttr.dynWidth = 1; + } + if (SecDecodeWidth(ch, &formatAttr, lastState) != 0) { + return -1; + } + break; + case STAT_DOT: + formatAttr.precision = 0; + break; + case STAT_PRECIS: + /* Update precison value */ + if (ch == SECUREC_CHAR('*')) { + /* Get precision from arg list */ + formatAttr.precision = (int)va_arg(argList, int); + formatAttr.dynPrecision = 1; + } + if (SecDecodePrecision(ch, &formatAttr) != 0) { + return -1; + } + break; + case STAT_SIZE: + /* Read a size specifier, set the formatAttr.flags based on it, and skip format to next charater */ + if (SecDecodeSize(ch, &formatAttr, &format) != 0) { + /* Compatibility code for "%I" just print I */ + SecOutputOneChar(ch, stream, &charsOut); + state = STAT_NORMAL; + continue; + } + break; + case STAT_TYPE: + switch (ch) { + case SECUREC_CHAR('C'): /* Wide char */ + SecUpdateWcharFlags(&formatAttr); + /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('c'): { + unsigned int cValue = (unsigned int)va_arg(argList, int); + SecDecodeTypeC(&formatAttr, cValue); + break; + } + case SECUREC_CHAR('S'): /* Wide char string */ + SecUpdateWstringFlags(&formatAttr); + /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('s'): { + char *argPtr = (char *)va_arg(argList, char *); + SecDecodeTypeS(&formatAttr, argPtr); + break; + } + case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */ + /* Default precision is 1 for g or G */ + if (formatAttr.precision == 0) { + formatAttr.precision = 1; + } + /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('f'): { +#if SECUREC_ENABLE_SPRINTF_FLOAT + /* Add following code to call system sprintf API for float number */ + SecFloatAdapt floatAdapt; + noOutput = 1; /* It's no more data needs to be written */ + + /* Now format is pointer to the next character of 'f' */ + if (SecInitFloatBuffer(&floatAdapt, format, &formatAttr) != 0) { + break; + } + + if ((formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) != 0) { +#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && SECUREC_ENABLE_SPRINTF_LONG_DOUBLE + long double tmp = (long double)va_arg(argList, long double); + SecFormatLongDouble(&formatAttr, &floatAdapt, tmp); +#else + double tmp = (double)va_arg(argList, double); + SecFormatDouble(&formatAttr, &floatAdapt, tmp); +#endif + } else { + double tmp = (double)va_arg(argList, double); + SecFormatDouble(&formatAttr, &floatAdapt, tmp); + } + + /* Only need write formated float string */ + SecWriteFloatText(stream, &formatAttr, &charsOut); + SecFreeFloatBuffer(&floatAdapt); + break; +#else + return -1; +#endif + } + case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('p'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('x'): /* fall-through */ /* FALLTHRU */ + SecUpdateXpxFlags(&formatAttr, ch); + /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('u'): /* fall-through */ /* FALLTHRU */ + case SECUREC_CHAR('o'): { + SecInt64 num64; + SecUpdateOudiFlags(&formatAttr, ch); + /* Read argument into variable num64. Be careful, depend on the order of judgment */ + if ((formatAttr.flags & SECUREC_FLAG_I64) != 0 || + (formatAttr.flags & SECUREC_FLAG_LONGLONG) != 0) { + num64 = (SecInt64)va_arg(argList, SecInt64); /* Maximum Bit Width sign bit unchanged */ + } else if ((formatAttr.flags & SECUREC_FLAG_LONG) != 0) { + num64 = SECUREC_GET_LONG_FROM_ARG(formatAttr); + } else if ((formatAttr.flags & SECUREC_FLAG_CHAR) != 0) { + num64 = SECUREC_GET_CHAR_FROM_ARG(formatAttr); + } else if ((formatAttr.flags & SECUREC_FLAG_SHORT) != 0) { + num64 = SECUREC_GET_SHORT_FROM_ARG(formatAttr); +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT + } else if ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) != 0) { + num64 = (ptrdiff_t)va_arg(argList, ptrdiff_t); /* Sign extend */ + } else if ((formatAttr.flags & SECUREC_FLAG_SIZE) != 0) { + num64 = SECUREC_GET_SIZE_FROM_ARG(formatAttr); + } else if ((formatAttr.flags & SECUREC_FLAG_INTMAX) != 0) { + num64 = (SecInt64)va_arg(argList, SecInt64); +#endif + } else { + num64 = SECUREC_GET_INT_FROM_ARG(formatAttr); + } + + /* The order of the following calls must be correct */ + SecNumberToBuffer(&formatAttr, num64); + SecNumberSatisfyPrecision(&formatAttr); + SecNumberForceOctal(&formatAttr); + SecUpdateSignedNumberPrefix(&formatAttr); + if (num64 == 0) { + SecNumberCompatZero(&formatAttr); + } + break; + } + default: + /* Do nothing */ + break; + } + + if (noOutput == 0) { + /* Calculate amount of padding */ + formatAttr.padding = (formatAttr.fldWidth - formatAttr.textLen) - formatAttr.prefixLen; + + /* Put out the padding, prefix, and text, in the correct order */ + SecWriteLeftPadding(stream, &formatAttr, &charsOut); + SecWritePrefix(stream, &formatAttr, &charsOut); + SecWriteLeadingZero(stream, &formatAttr, &charsOut); + SecWriteText(stream, &formatAttr, &charsOut); + SecWriteRightPadding(stream, &formatAttr, &charsOut); + } + break; + case STAT_INVALID: /* fall-through */ /* FALLTHRU */ + default: + return -1; /* Input format is wrong(STAT_INVALID), directly return */ + } + } + + if (state != STAT_NORMAL && state != STAT_TYPE) { + return -1; + } + + return charsOut; /* The number of characters written */ +} + +/* + * Output one zero character zero into the SecPrintfStream structure + * If there is not enough space, make sure f->count is less than 0 + */ +SECUREC_INLINE int SecPutZeroChar(SecPrintfStream *str) +{ + --str->count; + if (str->count >= 0) { + *(str->cur) = '\0'; + str->cur = str->cur + 1; + return 0; + } + return -1; +} + +#endif /* OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 */ + diff --git a/components/lib/libsec/src/scanf_s.c b/components/lib/libsec/src/scanf_s.c new file mode 100644 index 000000000..0ae200e68 --- /dev/null +++ b/components/lib/libsec/src/scanf_s.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: scanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s + * The scanf_s function reads data from the standard input stream stdin and + * writes the data into the location that's given by argument. Each argument + * must be a pointer to a variable of a type that corresponds to a type specifier + * in format. If copying occurs between strings that overlap, the behavior is + * undefined. + * + * + * format Format control string. + * ... Optional arguments. + * + * + * ... The converted value stored in user assigned address + * + * + * Returns the number of fields successfully converted and assigned; + * the return value does not include fields that were read but not assigned. + * A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int scanf_s(const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vscanf_s(format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + diff --git a/components/lib/libsec/src/secinput.h b/components/lib/libsec/src/secinput.h new file mode 100644 index 000000000..15c10451a --- /dev/null +++ b/components/lib/libsec/src/secinput.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define macro, data struct, and declare function prototype, + * which is used by input.inl, secureinput_a.c and secureinput_w.c. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#include "securecutil.h" + +#define SECUREC_SCANF_EINVAL (-1) +#define SECUREC_SCANF_ERROR_PARA (-2) + +/* For internal stream flag */ +#define SECUREC_MEM_STR_FLAG 0x01U +#define SECUREC_FILE_STREAM_FLAG 0x02U +#define SECUREC_PIPE_STREAM_FLAG 0x04U +#define SECUREC_LOAD_FILE_TO_MEM_FLAG 0x08U + +#define SECUREC_UCS_BOM_HEADER_SIZE 2U +#define SECUREC_UCS_BOM_HEADER_BE_1ST 0xfeU +#define SECUREC_UCS_BOM_HEADER_BE_2ST 0xffU +#define SECUREC_UCS_BOM_HEADER_LE_1ST 0xffU +#define SECUREC_UCS_BOM_HEADER_LE_2ST 0xfeU +#define SECUREC_UTF8_BOM_HEADER_SIZE 3U +#define SECUREC_UTF8_BOM_HEADER_1ST 0xefU +#define SECUREC_UTF8_BOM_HEADER_2ND 0xbbU +#define SECUREC_UTF8_BOM_HEADER_3RD 0xbfU +#define SECUREC_UTF8_LEAD_1ST 0xe0U +#define SECUREC_UTF8_LEAD_2ND 0x80U + +#define SECUREC_BEGIN_WITH_UCS_BOM(s, len) ((len) >= SECUREC_UCS_BOM_HEADER_SIZE && \ + (((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_LE_1ST && \ + (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_LE_2ST) || \ + ((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_BE_1ST && \ + (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_BE_2ST))) + +#define SECUREC_BEGIN_WITH_UTF8_BOM(s, len) ((len) >= SECUREC_UTF8_BOM_HEADER_SIZE && \ + (unsigned char)((s)[0]) == SECUREC_UTF8_BOM_HEADER_1ST && \ + (unsigned char)((s)[1]) == SECUREC_UTF8_BOM_HEADER_2ND && \ + (unsigned char)((s)[2]) == SECUREC_UTF8_BOM_HEADER_3RD) + +#ifdef SECUREC_FOR_WCHAR +#define SECUREC_BOM_HEADER_SIZE SECUREC_UCS_BOM_HEADER_SIZE +#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UCS_BOM((s), (len)) +#else +#define SECUREC_BOM_HEADER_SIZE SECUREC_UTF8_BOM_HEADER_SIZE +#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UTF8_BOM((s), (len)) +#endif + +typedef struct { + unsigned int flag; /* Mark the properties of input stream */ + char *base; /* The pointer to the header of buffered string */ + const char *cur; /* The pointer to next read position */ + size_t count; /* The size of buffered string in bytes */ +#if SECUREC_ENABLE_SCANF_FILE + FILE *pf; /* The file pointer */ + size_t fileRealRead; + long oriFilePos; /* The original position of file offset when fscanf is called */ +#if !SECUREC_USE_STD_UNGETC + unsigned int lastChar; /* The char code of last input */ + int fUnGet; /* The boolean flag of pushing a char back to read stream */ +#endif +#endif +} SecFileStream; + +#if SECUREC_ENABLE_SCANF_FILE && !SECUREC_USE_STD_UNGETC +#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) do { \ + (stream)->pf = (fp); \ + (stream)->fileRealRead = 0; \ + (stream)->oriFilePos = 0; \ + (stream)->lastChar = 0; \ + (stream)->fUnGet = 0; \ +} SECUREC_WHILE_ZERO +#elif SECUREC_ENABLE_SCANF_FILE && SECUREC_USE_STD_UNGETC +#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) do { \ + (stream)->pf = (fp); \ + (stream)->fileRealRead = 0; \ + (stream)->oriFilePos = 0; \ +} SECUREC_WHILE_ZERO +#else +/* Disable file */ +#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) +#endif + +/* This initialization for eliminating redundant initialization. */ +#define SECUREC_FILE_STREAM_FROM_STRING(stream, buf, cnt) do { \ + (stream)->flag = SECUREC_MEM_STR_FLAG; \ + (stream)->base = NULL; \ + (stream)->cur = (buf); \ + (stream)->count = (cnt); \ + SECUREC_FILE_STREAM_INIT_FILE((stream), NULL); \ +} SECUREC_WHILE_ZERO + +/* This initialization for eliminating redundant initialization. */ +#define SECUREC_FILE_STREAM_FROM_FILE(stream, fp) do { \ + (stream)->flag = SECUREC_FILE_STREAM_FLAG; \ + (stream)->base = NULL; \ + (stream)->cur = NULL; \ + (stream)->count = 0; \ + SECUREC_FILE_STREAM_INIT_FILE((stream), (fp)); \ +} SECUREC_WHILE_ZERO + +/* This initialization for eliminating redundant initialization. */ +#define SECUREC_FILE_STREAM_FROM_STDIN(stream) do { \ + (stream)->flag = SECUREC_PIPE_STREAM_FLAG; \ + (stream)->base = NULL; \ + (stream)->cur = NULL; \ + (stream)->count = 0; \ + SECUREC_FILE_STREAM_INIT_FILE((stream), SECUREC_STREAM_STDIN); \ +} SECUREC_WHILE_ZERO + +#ifdef __cplusplus +extern "C" { +#endif + int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList); + void SecClearDestBuf(const char *buffer, const char *format, va_list argList); +#ifdef SECUREC_FOR_WCHAR + int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList); + void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList); +#endif + +/* 20150105 For software and hardware decoupling,such as UMG */ +#ifdef SECUREC_SYSAPI4VXWORKS +#ifdef feof +#undef feof +#endif + extern int feof(FILE *stream); +#endif + +#if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT) +#ifndef isspace +#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n')) +#endif +#ifndef iswspace +#define iswspace(c) (((c) == L' ') || ((c) == L'\t') || ((c) == L'\r') || ((c) == L'\n')) +#endif +#ifndef isascii +#define isascii(c) (((unsigned char)(c)) <= 0x7f) +#endif +#ifndef isupper +#define isupper(c) ((c) >= 'A' && (c) <= 'Z') +#endif +#ifndef islower +#define islower(c) ((c) >= 'a' && (c) <= 'z') +#endif +#ifndef isalpha +#define isalpha(c) (isupper(c) || (islower(c))) +#endif +#ifndef isdigit +#define isdigit(c) ((c) >= '0' && (c) <= '9') +#endif +#ifndef isxupper +#define isxupper(c) ((c) >= 'A' && (c) <= 'F') +#endif +#ifndef isxlower +#define isxlower(c) ((c) >= 'a' && (c) <= 'f') +#endif +#ifndef isxdigit +#define isxdigit(c) (isdigit(c) || isxupper(c) || isxlower(c)) +#endif +#endif + +#ifdef __cplusplus +} +#endif +/* Reserved file operation macro interface, s is FILE *, i is fileno zero. */ +#ifndef SECUREC_LOCK_FILE +#define SECUREC_LOCK_FILE(s) +#endif + +#ifndef SECUREC_UNLOCK_FILE +#define SECUREC_UNLOCK_FILE(s) +#endif + +#ifndef SECUREC_LOCK_STDIN +#define SECUREC_LOCK_STDIN(i, s) +#endif + +#ifndef SECUREC_UNLOCK_STDIN +#define SECUREC_UNLOCK_STDIN(i, s) +#endif +#endif + diff --git a/components/lib/libsec/src/securecutil.c b/components/lib/libsec/src/securecutil.c new file mode 100644 index 000000000..140cbf3c2 --- /dev/null +++ b/components/lib/libsec/src/securecutil.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Provides internal functions used by this library, such as memory + * copy and memory move. Besides, include some helper function for + * printf family API, such as SecVsnprintfImpl + * Author: lishunda + * Create: 2014-02-25 + */ + +/* Avoid duplicate header files,not include securecutil.h */ +#include "securecutil.h" + +#if defined(ANDROID) && (SECUREC_HAVE_WCTOMB || SECUREC_HAVE_MBTOWC) +#include +#if SECUREC_HAVE_WCTOMB +/* + * Convert wide characters to narrow multi-bytes + */ +int wctomb(char *s, wchar_t wc) +{ + return wcrtomb(s, wc, NULL); +} +#endif + +#if SECUREC_HAVE_MBTOWC +/* + * Converting narrow multi-byte characters to wide characters + */ +int mbtowc(wchar_t *pwc, const char *s, size_t n) +{ + return mbrtowc(pwc, s, n, NULL); +} +#endif +#endif + +/* The V100R001C01 version num is 0x5 (High 8 bits) */ +#define SECUREC_C_VERSION 0x500U +#define SECUREC_SPC_VERSION 0xaU +#define SECUREC_VERSION_STR "V100R001C01SPC010B002" + +/* + * Get version string and version number. + * The rules for version number are as follows: + * 1) SPC verNumber<->verStr like: + * 0x201<->C01 + * 0x202<->C01SPC001 Redefine numbers after this version + * 0x502<->C01SPC002 + * 0x503<->C01SPC003 + * ... + * 0X50a<->SPC010 + * 0X50b<->SPC011 + * ... + * 0x700<->C02 + * 0x701<->C01SPC001 + * 0x702<->C02SPC002 + * ... + * 2) CP verNumber<->verStr like: + * 0X601<->CP0001 + * 0X602<->CP0002 + * ... + */ +const char *GetHwSecureCVersion(unsigned short *verNumber) +{ + if (verNumber != NULL) { + *verNumber = (unsigned short)(SECUREC_C_VERSION | SECUREC_SPC_VERSION); + } + return SECUREC_VERSION_STR; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(GetHwSecureCVersion); +#endif + diff --git a/components/lib/libsec/src/securecutil.h b/components/lib/libsec/src/securecutil.h new file mode 100644 index 000000000..38cbd3e61 --- /dev/null +++ b/components/lib/libsec/src/securecutil.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define macro, data struct, and declare internal used function prototype, + * which is used by secure functions. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F +#define SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F +#include "securec.h" + +#if (defined(_MSC_VER)) && (_MSC_VER >= 1400) +/* Shield compilation alerts using discarded functions and Constant expression to maximize code compatibility */ +#define SECUREC_MASK_MSVC_CRT_WARNING __pragma(warning(push)) \ + __pragma(warning(disable : 4996 4127)) +#define SECUREC_END_MASK_MSVC_CRT_WARNING __pragma(warning(pop)) +#else +#define SECUREC_MASK_MSVC_CRT_WARNING +#define SECUREC_END_MASK_MSVC_CRT_WARNING +#endif +#define SECUREC_WHILE_ZERO SECUREC_MASK_MSVC_CRT_WARNING while (0) SECUREC_END_MASK_MSVC_CRT_WARNING + +/* Automatically identify the platform that supports strnlen function, and use this function to improve performance */ +#ifndef SECUREC_HAVE_STRNLEN +#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) +#if SECUREC_IN_KERNEL +#define SECUREC_HAVE_STRNLEN 0 +#else +#if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ >= 10 +#define SECUREC_HAVE_STRNLEN 1 +#else +#define SECUREC_HAVE_STRNLEN 0 +#endif +#endif +#else +#define SECUREC_HAVE_STRNLEN 0 +#endif +#endif + +#if SECUREC_IN_KERNEL +/* In kernel disbale functions */ +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 0 +#endif +#ifndef SECUREC_ENABLE_SCANF_FLOAT +#define SECUREC_ENABLE_SCANF_FLOAT 0 +#endif +#ifndef SECUREC_ENABLE_SPRINTF_FLOAT +#define SECUREC_ENABLE_SPRINTF_FLOAT 0 +#endif +#ifndef SECUREC_HAVE_MBTOWC +#define SECUREC_HAVE_MBTOWC 0 +#endif +#ifndef SECUREC_HAVE_WCTOMB +#define SECUREC_HAVE_WCTOMB 0 +#endif +#ifndef SECUREC_HAVE_WCHART +#define SECUREC_HAVE_WCHART 0 +#endif +#else /* Not in kernel */ +/* Systems that do not support file, can define this macro to 0. */ +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 1 +#endif +#ifndef SECUREC_ENABLE_SCANF_FLOAT +#define SECUREC_ENABLE_SCANF_FLOAT 1 +#endif +/* Systems that do not support float, can define this macro to 0. */ +#ifndef SECUREC_ENABLE_SPRINTF_FLOAT +#define SECUREC_ENABLE_SPRINTF_FLOAT 1 +#endif +#ifndef SECUREC_HAVE_MBTOWC +#define SECUREC_HAVE_MBTOWC 1 +#endif +#ifndef SECUREC_HAVE_WCTOMB +#define SECUREC_HAVE_WCTOMB 1 +#endif +#ifndef SECUREC_HAVE_WCHART +#define SECUREC_HAVE_WCHART 1 +#endif +#endif + +#ifndef SECUREC_USE_STD_UNGETC +#define SECUREC_USE_STD_UNGETC 1 +#endif + +#ifndef SECUREC_ENABLE_INLINE +#define SECUREC_ENABLE_INLINE 0 +#endif + +#ifndef SECUREC_INLINE +#if SECUREC_ENABLE_INLINE +#define SECUREC_INLINE static inline +#else +#define SECUREC_INLINE static +#endif +#endif + +#ifndef SECUREC_WARP_OUTPUT +#if SECUREC_IN_KERNEL +#define SECUREC_WARP_OUTPUT 1 +#else +#define SECUREC_WARP_OUTPUT 0 +#endif +#endif + +#ifndef SECUREC_STREAM_STDIN +#define SECUREC_STREAM_STDIN stdin +#endif + +#define SECUREC_MUL_SIXTEEN(x) ((x) << 4U) +#define SECUREC_MUL_EIGHT(x) ((x) << 3U) +#define SECUREC_MUL_TEN(x) ((((x) << 2U) + (x)) << 1U) +/* Limited format input and output width, use signed integer */ +#define SECUREC_MAX_WIDTH_LEN_DIV_TEN 21474836 +#define SECUREC_MAX_WIDTH_LEN (SECUREC_MAX_WIDTH_LEN_DIV_TEN * 10) +/* Is the x multiplied by 10 greater than */ +#define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x) (((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN)) + +#define SECUREC_FLOAT_BUFSIZE (309 + 40) /* Max length of double value */ +#define SECUREC_FLOAT_BUFSIZE_LB (4932 + 40) /* Max length of long double value */ +#define SECUREC_FLOAT_DEFAULT_PRECISION 6 + +/* This macro does not handle pointer equality or integer overflow */ +#define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \ + (((src) < (dest) && ((const char *)(src) + (count)) <= (char *)(dest)) || \ + ((dest) < (src) && ((char *)(dest) + (count)) <= (const char *)(src))) + +#define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \ + (((src) < (dest) && ((const char *)(src) + (count)) > (char *)(dest)) || \ + ((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src))) + +/* + * Check whether the strings overlap, len is the length of the string not include terminator + * Length is related to data type char or wchar , do not force conversion of types + */ +#define SECUREC_STRING_NO_OVERLAP(dest, src, len) \ + (((src) < (dest) && ((src) + (len)) < (dest)) || \ + ((dest) < (src) && ((dest) + (len)) < (src))) + +/* + * Check whether the strings overlap for strcpy wcscpy function, dest len and src Len are not include terminator + * Length is related to data type char or wchar , do not force conversion of types + */ +#define SECUREC_STRING_IS_OVERLAP(dest, src, len) \ + (((src) < (dest) && ((src) + (len)) >= (dest)) || \ + ((dest) < (src) && ((dest) + (len)) >= (src))) + +/* + * Check whether the strings overlap for strcat wcscat function, dest len and src Len are not include terminator + * Length is related to data type char or wchar , do not force conversion of types + */ +#define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \ + (((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \ + ((src) < (dest) && ((src) + (srcLen)) >= (dest))) + +#if SECUREC_HAVE_STRNLEN +#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \ + *(outLen) = strnlen((str), (maxLen)); \ +} SECUREC_WHILE_ZERO +#define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) do { \ + if ((maxLen) > 8) { \ + /* Optimization or len less then 8 */ \ + if (*((str) + 0) == '\0') { \ + *(outLen) = 0; \ + } else if (*((str) + 1) == '\0') { \ + *(outLen) = 1; \ + } else if (*((str) + 2) == '\0') { \ + *(outLen) = 2; \ + } else if (*((str) + 3) == '\0') { \ + *(outLen) = 3; \ + } else if (*((str) + 4) == '\0') { \ + *(outLen) = 4; \ + } else if (*((str) + 5) == '\0') { \ + *(outLen) = 5; \ + } else if (*((str) + 6) == '\0') { \ + *(outLen) = 6; \ + } else if (*((str) + 7) == '\0') { \ + *(outLen) = 7; \ + } else if (*((str) + 8) == '\0') { \ + /* Optimization with a length of 8 */ \ + *(outLen) = 8; \ + } else { \ + /* The offset is 8 because the performance of 8 byte alignment is high */ \ + *(outLen) = 8 + strnlen((str) + 8, (maxLen) - 8); \ + } \ + } else { \ + SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \ + } \ +} SECUREC_WHILE_ZERO +#else +#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \ + const char *strEnd_ = (const char *)(str); \ + size_t availableSize_ = (size_t)(maxLen); \ + while (availableSize_ > 0 && *strEnd_ != '\0') { \ + --availableSize_; \ + ++strEnd_; \ + } \ + *(outLen) = (size_t)(strEnd_ - (str)); \ +} SECUREC_WHILE_ZERO +#define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN +#endif + +#define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) do { \ + const wchar_t *strEnd_ = (const wchar_t *)(str); \ + size_t len_ = 0; \ + while (len_ < (maxLen) && *strEnd_ != L'\0') { \ + ++len_; \ + ++strEnd_; \ + } \ + *(outLen) = len_; \ +} SECUREC_WHILE_ZERO + +/* + * Performance optimization, product may disable inline function. + * Using function pointer for MEMSET to prevent compiler optimization when cleaning up memory. + */ +#ifdef SECUREC_USE_ASM +#define SECUREC_MEMSET_FUNC_OPT memset_opt +#define SECUREC_MEMCPY_FUNC_OPT memcpy_opt +#else +#define SECUREC_MEMSET_FUNC_OPT memset +#define SECUREC_MEMCPY_FUNC_OPT memcpy +#endif + +#define SECUREC_MEMCPY_WARP_OPT(dest, src, count) (void)SECUREC_MEMCPY_FUNC_OPT((dest), (src), (count)) + +#ifndef SECUREC_MEMSET_INDIRECT_USE +/* Can be turned off for scenarios that do not allow pointer calls */ +#define SECUREC_MEMSET_INDIRECT_USE 1 +#endif + +#if SECUREC_MEMSET_INDIRECT_USE +#define SECUREC_MEMSET_WARP_OPT(dest, value, count) do { \ + void *(* const volatile fn_)(void *s_, int c_, size_t n_) = SECUREC_MEMSET_FUNC_OPT; \ + (void)(*fn_)((dest), (value), (count)); \ +} SECUREC_WHILE_ZERO +#else +#define SECUREC_MEMSET_WARP_OPT(dest, value, count) (void)SECUREC_MEMSET_FUNC_OPT((dest), (value), (count)) +#endif + +#ifdef SECUREC_FORMAT_OUTPUT_INPUT +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) || defined(__ARMCC_VERSION) +typedef __int64 SecInt64; +typedef unsigned __int64 SecUnsignedInt64; +#if defined(__ARMCC_VERSION) +typedef unsigned int SecUnsignedInt32; +#else +typedef unsigned __int32 SecUnsignedInt32; +#endif +#else +typedef unsigned int SecUnsignedInt32; +typedef long long SecInt64; +typedef unsigned long long SecUnsignedInt64; +#endif + +#ifdef SECUREC_FOR_WCHAR +#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(__WINT_TYPE__) +typedef wchar_t wint_t; +#endif +#ifndef WEOF +#define WEOF ((wchar_t)(-1)) +#endif +#define SECUREC_CHAR(x) L ## x +typedef wchar_t SecChar; +typedef wchar_t SecUnsignedChar; +typedef wint_t SecInt; +typedef wint_t SecUnsignedInt; +#else /* no SECUREC_FOR_WCHAR */ +#define SECUREC_CHAR(x) (x) +typedef char SecChar; +typedef unsigned char SecUnsignedChar; +typedef int SecInt; +typedef unsigned int SecUnsignedInt; +#endif +#endif + +/* + * Determine whether the address is 8-byte aligned + * Some systems do not have uintptr_t type, so use NULL to clear tool alarm 507 + */ +#define SECUREC_ADDR_ALIGNED_8(addr) ((((size_t)(addr)) & 7U) == 0) /* Use 7 to check aligned 8 */ + +/* + * If you define the memory allocation function, you need to define the function prototype. + * You can define this macro as a header file. + */ +#if defined(SECUREC_MALLOC_PROTOTYPE) +SECUREC_MALLOC_PROTOTYPE +#endif + +#ifndef SECUREC_MALLOC +#define SECUREC_MALLOC(x) malloc((size_t)(x)) +#endif + +#ifndef SECUREC_FREE +#define SECUREC_FREE(x) free((void *)(x)) +#endif + +/* Improve performance with struct assignment, buf1 is not defined to avoid tool false positive */ +#define SECUREC_COPY_VALUE_BY_STRUCT(dest, src, n) do { \ + *(SecStrBuf##n *)(void *)(dest) = *(const SecStrBuf##n *)(const void *)(src); \ +} SECUREC_WHILE_ZERO + +typedef struct { + unsigned char buf[2]; /* Performance optimization code structure assignment length 2 bytes */ +} SecStrBuf2; +typedef struct { + unsigned char buf[3]; /* Performance optimization code structure assignment length 3 bytes */ +} SecStrBuf3; +typedef struct { + unsigned char buf[4]; /* Performance optimization code structure assignment length 4 bytes */ +} SecStrBuf4; +typedef struct { + unsigned char buf[5]; /* Performance optimization code structure assignment length 5 bytes */ +} SecStrBuf5; +typedef struct { + unsigned char buf[6]; /* Performance optimization code structure assignment length 6 bytes */ +} SecStrBuf6; +typedef struct { + unsigned char buf[7]; /* Performance optimization code structure assignment length 7 bytes */ +} SecStrBuf7; +typedef struct { + unsigned char buf[8]; /* Performance optimization code structure assignment length 8 bytes */ +} SecStrBuf8; +typedef struct { + unsigned char buf[9]; /* Performance optimization code structure assignment length 9 bytes */ +} SecStrBuf9; +typedef struct { + unsigned char buf[10]; /* Performance optimization code structure assignment length 10 bytes */ +} SecStrBuf10; +typedef struct { + unsigned char buf[11]; /* Performance optimization code structure assignment length 11 bytes */ +} SecStrBuf11; +typedef struct { + unsigned char buf[12]; /* Performance optimization code structure assignment length 12 bytes */ +} SecStrBuf12; +typedef struct { + unsigned char buf[13]; /* Performance optimization code structure assignment length 13 bytes */ +} SecStrBuf13; +typedef struct { + unsigned char buf[14]; /* Performance optimization code structure assignment length 14 bytes */ +} SecStrBuf14; +typedef struct { + unsigned char buf[15]; /* Performance optimization code structure assignment length 15 bytes */ +} SecStrBuf15; +typedef struct { + unsigned char buf[16]; /* Performance optimization code structure assignment length 16 bytes */ +} SecStrBuf16; +typedef struct { + unsigned char buf[17]; /* Performance optimization code structure assignment length 17 bytes */ +} SecStrBuf17; +typedef struct { + unsigned char buf[18]; /* Performance optimization code structure assignment length 18 bytes */ +} SecStrBuf18; +typedef struct { + unsigned char buf[19]; /* Performance optimization code structure assignment length 19 bytes */ +} SecStrBuf19; +typedef struct { + unsigned char buf[20]; /* Performance optimization code structure assignment length 20 bytes */ +} SecStrBuf20; +typedef struct { + unsigned char buf[21]; /* Performance optimization code structure assignment length 21 bytes */ +} SecStrBuf21; +typedef struct { + unsigned char buf[22]; /* Performance optimization code structure assignment length 22 bytes */ +} SecStrBuf22; +typedef struct { + unsigned char buf[23]; /* Performance optimization code structure assignment length 23 bytes */ +} SecStrBuf23; +typedef struct { + unsigned char buf[24]; /* Performance optimization code structure assignment length 24 bytes */ +} SecStrBuf24; +typedef struct { + unsigned char buf[25]; /* Performance optimization code structure assignment length 25 bytes */ +} SecStrBuf25; +typedef struct { + unsigned char buf[26]; /* Performance optimization code structure assignment length 26 bytes */ +} SecStrBuf26; +typedef struct { + unsigned char buf[27]; /* Performance optimization code structure assignment length 27 bytes */ +} SecStrBuf27; +typedef struct { + unsigned char buf[28]; /* Performance optimization code structure assignment length 28 bytes */ +} SecStrBuf28; +typedef struct { + unsigned char buf[29]; /* Performance optimization code structure assignment length 29 bytes */ +} SecStrBuf29; +typedef struct { + unsigned char buf[30]; /* Performance optimization code structure assignment length 30 bytes */ +} SecStrBuf30; +typedef struct { + unsigned char buf[31]; /* Performance optimization code structure assignment length 31 bytes */ +} SecStrBuf31; +typedef struct { + unsigned char buf[32]; /* Performance optimization code structure assignment length 32 bytes */ +} SecStrBuf32; +typedef struct { + unsigned char buf[33]; /* Performance optimization code structure assignment length 33 bytes */ +} SecStrBuf33; +typedef struct { + unsigned char buf[34]; /* Performance optimization code structure assignment length 34 bytes */ +} SecStrBuf34; +typedef struct { + unsigned char buf[35]; /* Performance optimization code structure assignment length 35 bytes */ +} SecStrBuf35; +typedef struct { + unsigned char buf[36]; /* Performance optimization code structure assignment length 36 bytes */ +} SecStrBuf36; +typedef struct { + unsigned char buf[37]; /* Performance optimization code structure assignment length 37 bytes */ +} SecStrBuf37; +typedef struct { + unsigned char buf[38]; /* Performance optimization code structure assignment length 38 bytes */ +} SecStrBuf38; +typedef struct { + unsigned char buf[39]; /* Performance optimization code structure assignment length 39 bytes */ +} SecStrBuf39; +typedef struct { + unsigned char buf[40]; /* Performance optimization code structure assignment length 40 bytes */ +} SecStrBuf40; +typedef struct { + unsigned char buf[41]; /* Performance optimization code structure assignment length 41 bytes */ +} SecStrBuf41; +typedef struct { + unsigned char buf[42]; /* Performance optimization code structure assignment length 42 bytes */ +} SecStrBuf42; +typedef struct { + unsigned char buf[43]; /* Performance optimization code structure assignment length 43 bytes */ +} SecStrBuf43; +typedef struct { + unsigned char buf[44]; /* Performance optimization code structure assignment length 44 bytes */ +} SecStrBuf44; +typedef struct { + unsigned char buf[45]; /* Performance optimization code structure assignment length 45 bytes */ +} SecStrBuf45; +typedef struct { + unsigned char buf[46]; /* Performance optimization code structure assignment length 46 bytes */ +} SecStrBuf46; +typedef struct { + unsigned char buf[47]; /* Performance optimization code structure assignment length 47 bytes */ +} SecStrBuf47; +typedef struct { + unsigned char buf[48]; /* Performance optimization code structure assignment length 48 bytes */ +} SecStrBuf48; +typedef struct { + unsigned char buf[49]; /* Performance optimization code structure assignment length 49 bytes */ +} SecStrBuf49; +typedef struct { + unsigned char buf[50]; /* Performance optimization code structure assignment length 50 bytes */ +} SecStrBuf50; +typedef struct { + unsigned char buf[51]; /* Performance optimization code structure assignment length 51 bytes */ +} SecStrBuf51; +typedef struct { + unsigned char buf[52]; /* Performance optimization code structure assignment length 52 bytes */ +} SecStrBuf52; +typedef struct { + unsigned char buf[53]; /* Performance optimization code structure assignment length 53 bytes */ +} SecStrBuf53; +typedef struct { + unsigned char buf[54]; /* Performance optimization code structure assignment length 54 bytes */ +} SecStrBuf54; +typedef struct { + unsigned char buf[55]; /* Performance optimization code structure assignment length 55 bytes */ +} SecStrBuf55; +typedef struct { + unsigned char buf[56]; /* Performance optimization code structure assignment length 56 bytes */ +} SecStrBuf56; +typedef struct { + unsigned char buf[57]; /* Performance optimization code structure assignment length 57 bytes */ +} SecStrBuf57; +typedef struct { + unsigned char buf[58]; /* Performance optimization code structure assignment length 58 bytes */ +} SecStrBuf58; +typedef struct { + unsigned char buf[59]; /* Performance optimization code structure assignment length 59 bytes */ +} SecStrBuf59; +typedef struct { + unsigned char buf[60]; /* Performance optimization code structure assignment length 60 bytes */ +} SecStrBuf60; +typedef struct { + unsigned char buf[61]; /* Performance optimization code structure assignment length 61 bytes */ +} SecStrBuf61; +typedef struct { + unsigned char buf[62]; /* Performance optimization code structure assignment length 62 bytes */ +} SecStrBuf62; +typedef struct { + unsigned char buf[63]; /* Performance optimization code structure assignment length 63 bytes */ +} SecStrBuf63; +typedef struct { + unsigned char buf[64]; /* Performance optimization code structure assignment length 64 bytes */ +} SecStrBuf64; + +/* + * User can change the error handler by modify the following definition, + * such as logging the detail error in file. + */ +#if defined(_DEBUG) || defined(DEBUG) +#if defined(SECUREC_ERROR_HANDLER_BY_ASSERT) +#define SECUREC_ERROR_INVALID_PARAMTER(msg) assert(msg "invalid argument" == NULL) +#define SECUREC_ERROR_INVALID_RANGE(msg) assert(msg "invalid dest buffer size" == NULL) +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) assert(msg "buffer overlap" == NULL) +#elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF) +#if SECUREC_IN_KERNEL +#define SECUREC_ERROR_INVALID_PARAMTER(msg) printk("%s invalid argument\n", msg) +#define SECUREC_ERROR_INVALID_RANGE(msg) printk("%s invalid dest buffer size\n", msg) +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printk("%s buffer overlap\n", msg) +#else +#define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg) +#define SECUREC_ERROR_INVALID_RANGE(msg) printf("%s invalid dest buffer size\n", msg) +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg) +#endif +#elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) +#define SECUREC_ERROR_INVALID_PARAMTER(msg) LogSecureCRuntimeError(msg " EINVAL\n") +#define SECUREC_ERROR_INVALID_RANGE(msg) LogSecureCRuntimeError(msg " ERANGE\n") +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) LogSecureCRuntimeError(msg " EOVERLAP\n") +#endif +#endif + +/* Default handler is none */ +#ifndef SECUREC_ERROR_INVALID_PARAMTER +#define SECUREC_ERROR_INVALID_PARAMTER(msg) +#endif +#ifndef SECUREC_ERROR_INVALID_RANGE +#define SECUREC_ERROR_INVALID_RANGE(msg) +#endif +#ifndef SECUREC_ERROR_BUFFER_OVERLAP +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Assembly language memory copy and memory set for X86 or MIPS ... */ +#ifdef SECUREC_USE_ASM + void *memcpy_opt(void *dest, const void *src, size_t n); + void *memset_opt(void *s, int c, size_t n); +#endif + +#if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) + void LogSecureCRuntimeError(const char *errDetail); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif + diff --git a/components/lib/libsec/src/secureinput_a.c b/components/lib/libsec/src/secureinput_a.c new file mode 100644 index 000000000..10b7f3571 --- /dev/null +++ b/components/lib/libsec/src/secureinput_a.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: By defining data type for ANSI string and including "input.inl", + * this file generates real underlying function used by scanf family API. + * Author: lishunda + * Create: 2014-02-25 + */ + +#define SECUREC_FORMAT_OUTPUT_INPUT 1 +#ifdef SECUREC_FOR_WCHAR +#undef SECUREC_FOR_WCHAR +#endif + +#include "secinput.h" + +#include "input.inl" + +SECUREC_INLINE int SecIsDigit(SecInt ch) +{ + /* SecInt to unsigned char clear 571, use bit mask to clear negative return of ch */ + return isdigit((int)((unsigned int)(unsigned char)(ch) & 0xffU)); +} +SECUREC_INLINE int SecIsXdigit(SecInt ch) +{ + return isxdigit((int)((unsigned int)(unsigned char)(ch) & 0xffU)); +} +SECUREC_INLINE int SecIsSpace(SecInt ch) +{ + return isspace((int)((unsigned int)(unsigned char)(ch) & 0xffU)); +} + diff --git a/components/lib/libsec/src/secureinput_w.c b/components/lib/libsec/src/secureinput_w.c new file mode 100644 index 000000000..79955794e --- /dev/null +++ b/components/lib/libsec/src/secureinput_w.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: By defining data type for UNICODE string and including "input.inl", + * this file generates real underlying function used by scanf family API. + * Author: lishunda + * Create: 2014-02-25 + */ + +/* If some platforms don't have wchar.h, dont't include it */ +#if !(defined(SECUREC_VXWORKS_PLATFORM)) +/* If there is no macro below, it will cause vs2010 compiling alarm */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#ifndef __STDC_WANT_SECURE_LIB__ +/* The order of adjustment is to eliminate alarm of Duplicate Block */ +#define __STDC_WANT_SECURE_LIB__ 0 +#endif +#ifndef _CRTIMP_ALTERNATIVE +#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */ +#endif +#endif +#include +#endif + +/* Disable wchar func to clear vs warning */ +#define SECUREC_ENABLE_WCHAR_FUNC 0 +#define SECUREC_FORMAT_OUTPUT_INPUT 1 + +#ifndef SECUREC_FOR_WCHAR +#define SECUREC_FOR_WCHAR +#endif + +#include "secinput.h" + +#include "input.inl" + +SECUREC_INLINE unsigned int SecWcharHighBits(SecInt ch) +{ + /* Convert int to unsigned int clear 571 */ + return ((unsigned int)(int)ch & (~0xffU)); +} + +SECUREC_INLINE unsigned char SecWcharLowByte(SecInt ch) +{ + /* Convert int to unsigned int clear 571 */ + return (unsigned char)((unsigned int)(int)ch & 0xffU); +} + +SECUREC_INLINE int SecIsDigit(SecInt ch) +{ + if (SecWcharHighBits(ch) != 0) { + return 0; /* Same as isdigit */ + } + return isdigit((int)SecWcharLowByte(ch)); +} + +SECUREC_INLINE int SecIsXdigit(SecInt ch) +{ + if (SecWcharHighBits(ch) != 0) { + return 0; /* Same as isxdigit */ + } + return isxdigit((int)SecWcharLowByte(ch)); +} + +SECUREC_INLINE int SecIsSpace(SecInt ch) +{ + return iswspace((wint_t)(int)(ch)); +} + diff --git a/components/lib/libsec/src/secureprintoutput.h b/components/lib/libsec/src/secureprintoutput.h new file mode 100644 index 000000000..843217ae0 --- /dev/null +++ b/components/lib/libsec/src/secureprintoutput.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define macro, enum, data struct, and declare internal used function + * prototype, which is used by output.inl, secureprintoutput_w.c and + * secureprintoutput_a.c. + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#define SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#include "securecutil.h" + +/* + * Flag definitions. + * Using macros instead of enumerations is because some of the enumerated types under the compiler are 16bit. + */ +#define SECUREC_FLAG_SIGN 0x00001U +#define SECUREC_FLAG_SIGN_SPACE 0x00002U +#define SECUREC_FLAG_LEFT 0x00004U +#define SECUREC_FLAG_LEADZERO 0x00008U +#define SECUREC_FLAG_LONG 0x00010U +#define SECUREC_FLAG_SHORT 0x00020U +#define SECUREC_FLAG_SIGNED 0x00040U +#define SECUREC_FLAG_ALTERNATE 0x00080U +#define SECUREC_FLAG_NEGATIVE 0x00100U +#define SECUREC_FLAG_FORCE_OCTAL 0x00200U +#define SECUREC_FLAG_LONG_DOUBLE 0x00400U +#define SECUREC_FLAG_WIDECHAR 0x00800U +#define SECUREC_FLAG_LONGLONG 0x01000U +#define SECUREC_FLAG_CHAR 0x02000U +#define SECUREC_FLAG_POINTER 0x04000U +#define SECUREC_FLAG_I64 0x08000U +#define SECUREC_FLAG_PTRDIFF 0x10000U +#define SECUREC_FLAG_SIZE 0x20000U +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT +#define SECUREC_FLAG_INTMAX 0x40000U +#endif + +/* State definitions. Identify the status of the current format */ +typedef enum { + STAT_NORMAL, + STAT_PERCENT, + STAT_FLAG, + STAT_WIDTH, + STAT_DOT, + STAT_PRECIS, + STAT_SIZE, + STAT_TYPE, + STAT_INVALID +} SecFmtState; + +/* Format output buffer pointer and available size */ +typedef struct { + int count; + char *cur; +} SecPrintfStream; + +#ifndef SECUREC_BUFFER_SIZE +#if SECUREC_IN_KERNEL +#define SECUREC_BUFFER_SIZE 32 +#elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K) +/* + * SECUREC BUFFER SIZE Can not be less than 23 + * The length of the octal representation of 64-bit integers with zero lead + */ +#define SECUREC_BUFFER_SIZE 256 +#else +#define SECUREC_BUFFER_SIZE 512 +#endif +#endif +#if SECUREC_BUFFER_SIZE < 23 +#error SECUREC_BUFFER_SIZE Can not be less than 23 +#endif +/* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as possible */ +#define SECUREC_WCHAR_BUFFER_SIZE 4 + +#define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE +/* Max. # bytes in multibyte char ,see MB_LEN_MAX */ +#define SECUREC_MB_LEN 16 +/* The return value of the internal function, which is returned when truncated */ +#define SECUREC_PRINTF_TRUNCATE (-2) + +#define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \ + ((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) + +#define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) do { \ + if ((strDest) != NULL && (destMax) > 0 && (destMax) <= (maxLimit)) { \ + *(strDest) = '\0'; \ + } \ +} SECUREC_WHILE_ZERO + +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT +#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \ + (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \ + ((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1))) + +#else +#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \ + (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \ + ((count) > (SECUREC_STRING_MAX_LEN - 1))) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList); +#ifdef SECUREC_FOR_WCHAR + int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, const wchar_t *format, va_list argList); +#endif +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/lib/libsec/src/secureprintoutput_a.c b/components/lib/libsec/src/secureprintoutput_a.c new file mode 100644 index 000000000..64762c067 --- /dev/null +++ b/components/lib/libsec/src/secureprintoutput_a.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: By defining corresponding macro for ANSI string and including "output.inl", + * this file generates real underlying function used by printf family API. + * Author: lishunda + * Create: 2014-02-25 + */ + +#define SECUREC_FORMAT_OUTPUT_INPUT 1 + +#ifdef SECUREC_FOR_WCHAR +#undef SECUREC_FOR_WCHAR +#endif + +#include "secureprintoutput.h" +#if SECUREC_WARP_OUTPUT +#define SECUREC_FORMAT_FLAG_TABLE_SIZE 128 +SECUREC_INLINE const char *SecSkipKnownFlags(const char *format) +{ + static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = { + /* + * Known flag is "0123456789 +-#hlLwZzjqt*I$" + */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + const char *fmt = format; + while (*fmt != '\0') { + char fmtChar = *fmt; + if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */ + break; + } + if (flagTable[(unsigned char)fmtChar] == 0) { + break; + } + ++fmt; + } + return fmt; +} + +SECUREC_INLINE int SecFormatContainN(const char *format) +{ + const char *fmt = format; + while (*fmt != '\0') { + ++fmt; + /* Skip normal char */ + if (*(fmt - 1) != '%') { + continue; + } + /* Meet %% */ + if (*fmt == '%') { + ++fmt; /* Point to the character after the %. Correct handling %%xx */ + continue; + } + /* Now parse %..., fmt point to the character after the % */ + fmt = SecSkipKnownFlags(fmt); + if (*fmt == 'n') { + return 1; + } + } + return 0; +} +/* + * Multi character formatted output implementation, the count include \0 character, must be greater than zero + */ +int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList) +{ + int retVal; + if (SecFormatContainN(format) != 0) { + string[0] = '\0'; + return -1; + } + retVal = vsnprintf(string, count, format, argList); + if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */ + /* The buffer was too small; we return truncation */ + string[count - 1] = '\0'; + return SECUREC_PRINTF_TRUNCATE; + } + if (retVal < 0) { + string[0] = '\0'; /* Empty the dest strDest */ + return -1; + } + return retVal; +} +#else +#if SECUREC_IN_KERNEL +#include +#endif + +#ifndef EOF +#define EOF (-1) +#endif + +#include "output.inl" + +/* + * Multi character formatted output implementation + */ +int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList) +{ + SecPrintfStream str; + int retVal; + + str.count = (int)count; /* The count include \0 character, must be greater than zero */ + str.cur = string; + + retVal = SecOutputS(&str, format, argList); + if (retVal >= 0) { + if (SecPutZeroChar(&str) == 0) { + return retVal; + } + } + if (str.count < 0) { + /* The buffer was too small, then truncate */ + string[count - 1] = '\0'; + return SECUREC_PRINTF_TRUNCATE; + } + string[0] = '\0'; /* Empty the dest string */ + return -1; +} + +/* + * Write a wide character + */ +SECUREC_INLINE void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten) +{ + int count; + for (count = num; count > 0; --count) { + --f->count; /* f -> count may be negative,indicating insufficient space */ + if (f->count < 0) { + *pnumwritten = -1; + return; + } + *(f->cur) = ch; + ++f->cur; + *pnumwritten = *pnumwritten + 1; + } +} + +/* + * Write string function, where this function is called, make sure that len is greater than 0 + */ +SECUREC_INLINE void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten) +{ + const char *str = string; + int count; + for (count = len; count > 0; --count) { + --f->count; /* f -> count may be negative,indicating insufficient space */ + if (f->count < 0) { + *pnumwritten = -1; + return; + } + *(f->cur) = *str; + ++f->cur; + ++str; + } + *pnumwritten = *pnumwritten + (int)(size_t)(str - string); +} +#endif + diff --git a/components/lib/libsec/src/secureprintoutput_w.c b/components/lib/libsec/src/secureprintoutput_w.c new file mode 100644 index 000000000..4d06a64a3 --- /dev/null +++ b/components/lib/libsec/src/secureprintoutput_w.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: By defining corresponding macro for UNICODE string and including "output.inl", + * this file generates real underlying function used by printf family API. + * Author: lishunda + * Create: 2014-02-25 + */ + +/* If some platforms don't have wchar.h, dont't include it */ +#if !(defined(SECUREC_VXWORKS_PLATFORM)) +/* If there is no macro above, it will cause compiling alarm */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#ifndef _CRTIMP_ALTERNATIVE +#define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */ +#endif +#ifndef __STDC_WANT_SECURE_LIB__ +#define __STDC_WANT_SECURE_LIB__ 0 +#endif +#endif +#include +#endif + +/* Disable wchar func to clear vs warning */ +#define SECUREC_ENABLE_WCHAR_FUNC 0 +#define SECUREC_FORMAT_OUTPUT_INPUT 1 + +#ifndef SECUREC_FOR_WCHAR +#define SECUREC_FOR_WCHAR +#endif + +#if defined(SECUREC_WARP_OUTPUT) && SECUREC_WARP_OUTPUT +#undef SECUREC_WARP_OUTPUT +#define SECUREC_WARP_OUTPUT 0 +#endif + +#include "secureprintoutput.h" + +SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, int *pnumwritten); +SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroCount); + +#include "output.inl" + +/* + * Wide character formatted output implementation + */ +int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, const wchar_t *format, va_list argList) +{ + SecPrintfStream str; + int retVal; /* If initialization causes e838 */ + + str.cur = (char *)string; + /* This count include \0 character, Must be greater than zero */ + str.count = (int)(sizeInWchar * sizeof(wchar_t)); + + retVal = SecOutputSW(&str, format, argList); + if (retVal >= 0) { + if (SecPutWcharStrEndingZero(&str, (int)sizeof(wchar_t)) == 0) { + return retVal; + } + } + if (str.count < 0) { + /* The buffer was too small, then truncate */ + string[sizeInWchar - 1] = L'\0'; + return SECUREC_PRINTF_TRUNCATE; + } + string[0] = L'\0'; /* Empty the dest string */ + return -1; +} + +/* + * Output a wide character zero end into the SecPrintfStream structure + */ +SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroCount) +{ + int count; + for (count = zeroCount; count > 0; --count) { + if (SecPutZeroChar(str) != 0) { + return -1; + } + } + return 0; +} + +/* + * Output a wide character into the SecPrintfStream structure + */ +SECUREC_INLINE int SecPutCharW(wchar_t ch, SecPrintfStream *f) +{ + f->count -= (int)sizeof(wchar_t); /* f -> count may be negative,indicating insufficient space */ + if (f->count >= 0) { + *(wchar_t *)(void *)(f->cur) = ch; + f->cur += sizeof(wchar_t); + return 0; + } + return -1; +} + +/* + * Output a wide character into the SecPrintfStream structure, returns the number of characters written + */ +SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, int *pnumwritten) +{ + if (SecPutCharW(ch, f) == 0) { + *pnumwritten = *pnumwritten + 1; + } else { + *pnumwritten = -1; + } +} + +/* + * Output multiple wide character into the SecPrintfStream structure, returns the number of characters written + */ +SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f, int *pnumwritten) +{ + int count; + for (count = num; count > 0; --count) { + SecWriteCharW(ch, f, pnumwritten); + if (*pnumwritten == -1) { + break; + } + } +} + +/* + * Output a wide string into the SecPrintfStream structure, returns the number of characters written + */ +SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len, SecPrintfStream *f, int *pnumwritten) +{ + const wchar_t *str = string; + int count; + for (count = len; count > 0; --count) { + SecWriteCharW(*str, f, pnumwritten); + ++str; + if (*pnumwritten == -1) { + break; + } + } +} + diff --git a/components/lib/libsec/src/snprintf_s.c b/components/lib/libsec/src/snprintf_s.c new file mode 100644 index 000000000..491c0a8d2 --- /dev/null +++ b/components/lib/libsec/src/snprintf_s.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: snprintf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +#if SECUREC_ENABLE_SNPRINTF +/* + * + * The snprintf_s function is equivalent to the snprintf function + * except for the parameter destMax/count and the explicit runtime-constraints violation + * The snprintf_s function formats and stores count or fewer characters in + * strDest and appends a terminating null. Each argument (if any) is converted + * and output according to the corresponding format specification in format. + * The formatting is consistent with the printf family of functions; If copying + * occurs between strings that overlap, the behavior is undefined. + * + * + * strDest Storage location for the output. + * destMax The size of the storage location for output. Size + * in bytes for snprintf_s or size in words for snwprintf_s. + * count Maximum number of character to store. + * format Format-control string. + * ... Optional arguments. + * + * + * strDest is updated + * + * + * return the number of characters written, not including the terminating null + * return -1 if an error occurs. + * return -1 if count < destMax and the output string has been truncated + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + * + */ +int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vsnprintf_s(strDest, destMax, count, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(snprintf_s); +#endif +#endif + +#if SECUREC_SNPRINTF_TRUNCATED +/* + * + * The snprintf_truncated_s function is equivalent to the snprintf function + * except for the parameter destMax/count and the explicit runtime-constraints violation + * The snprintf_truncated_s function formats and stores count or fewer characters in + * strDest and appends a terminating null. Each argument (if any) is converted + * and output according to the corresponding format specification in format. + * The formatting is consistent with the printf family of functions; If copying + * occurs between strings that overlap, the behavior is undefined. + * + * + * strDest Storage location for the output. + * destMax The size of the storage location for output. Size + * in bytes for snprintf_truncated_s or size in words for snwprintf_s. + * format Format-control string. + * ... Optional arguments. + * + * + * strDest is updated + * + * + * return the number of characters written, not including the terminating null + * return -1 if an error occurs. + * return destMax-1 if output string has been truncated + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + * + */ +int snprintf_truncated_s(char *strDest, size_t destMax, const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vsnprintf_truncated_s(strDest, destMax, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(snprintf_truncated_s); +#endif + +#endif + diff --git a/components/lib/libsec/src/sprintf_s.c b/components/lib/libsec/src/sprintf_s.c new file mode 100644 index 000000000..95b448586 --- /dev/null +++ b/components/lib/libsec/src/sprintf_s.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: sprintf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The sprintf_s function is equivalent to the sprintf function + * except for the parameter destMax and the explicit runtime-constraints violation + * The sprintf_s function formats and stores a series of characters and values + * in strDest. Each argument (if any) is converted and output according to + * the corresponding format specification in format. The format consists of + * ordinary characters and has the same form and function as the format argument + * for printf. A null character is appended after the last character written. + * If copying occurs between strings that overlap, the behavior is undefined. + * + * + * strDest Storage location for output. + * destMax Maximum number of characters to store. + * format Format-control string. + * ... Optional arguments + * + * + * strDest is updated + * + * + * return the number of bytes stored in strDest, not counting the terminating null character. + * return -1 if an error occurred. + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +int sprintf_s(char *strDest, size_t destMax, const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vsprintf_s(strDest, destMax, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(sprintf_s); +#endif + diff --git a/components/lib/libsec/src/sscanf_s.c b/components/lib/libsec/src/sscanf_s.c new file mode 100644 index 000000000..ba5680f03 --- /dev/null +++ b/components/lib/libsec/src/sscanf_s.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: sscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The sscanf_s function is equivalent to fscanf_s, + * except that input is obtained from a string (specified by the argument buffer) rather than from a stream + * The sscanf function reads data from buffer into the location given by each + * argument. Every argument must be a pointer to a variable with a type that + * corresponds to a type specifier in format. The format argument controls the + * interpretation of the input fields and has the same form and function as + * the format argument for the scanf function. + * If copying takes place between strings that overlap, the behavior is undefined. + * + * + * buffer Stored data. + * format Format control string, see Format Specifications. + * ... Optional arguments. + * + * + * ... The converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. + * A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int sscanf_s(const char *buffer, const char *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vsscanf_s(buffer, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(sscanf_s); +#endif + diff --git a/components/lib/libsec/src/strcat_s.c b/components/lib/libsec/src/strcat_s.c new file mode 100644 index 000000000..05c1c3230 --- /dev/null +++ b/components/lib/libsec/src/strcat_s.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: strcat_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * Befor this function, the basic parameter checking has been done + */ +SECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax, const char *strSrc) +{ + size_t destLen; + size_t srcLen; + size_t maxSrcLen; + SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); + /* Only optimize strSrc, do not apply this function to strDest */ + maxSrcLen = destMax - destLen; + SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen); + + if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { + strDest[0] = '\0'; + if (strDest + destLen <= strSrc && destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_BUFFER_OVERLAP("strcat_s"); + return EOVERLAP_AND_RESET; + } + if (srcLen + destLen >= destMax || strDest == strSrc) { + strDest[0] = '\0'; + if (destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_INVALID_RANGE("strcat_s"); + return ERANGE_AND_RESET; + } + SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen + 1); /* Single character length include \0 */ + return EOK; +} + +/* + * + * The strcat_s function appends a copy of the string pointed to by strSrc (including the terminating null character) + * to the end of the string pointed to by strDest. + * The initial character of strSrc overwrites the terminating null character of strDest. + * strcat_s will return EOVERLAP_AND_RESET if the source and destination strings overlap. + * + * Note that the second parameter is the total size of the buffer, not the + * remaining size. + * + * + * strDest Null-terminated destination string buffer. + * destMax Size of the destination string buffer. + * strSrc Null-terminated source string buffer. + * + * + * strDest is updated + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN + * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or + * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN) + * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN + * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc) +{ + if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("strcat_s"); + return ERANGE; + } + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); + if (strDest != NULL) { + strDest[0] = '\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + return SecDoCat(strDest, destMax, strSrc); +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(strcat_s); +#endif + diff --git a/components/lib/libsec/src/strcpy_s.c b/components/lib/libsec/src/strcpy_s.c new file mode 100644 index 000000000..e7921eae1 --- /dev/null +++ b/components/lib/libsec/src/strcpy_s.c @@ -0,0 +1,349 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: strcpy_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +#ifndef SECUREC_STRCPY_WITH_PERFORMANCE +#define SECUREC_STRCPY_WITH_PERFORMANCE 1 +#endif + +#define SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc) ((destMax) > 0 && \ + (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && (strDest) != (strSrc)) + +#if (!SECUREC_IN_KERNEL) && SECUREC_STRCPY_WITH_PERFORMANCE +#ifndef SECUREC_STRCOPY_THRESHOLD_SIZE +#define SECUREC_STRCOPY_THRESHOLD_SIZE 32UL +#endif +/* The purpose of converting to void is to clean up the alarm */ +#define SECUREC_SMALL_STR_COPY(strDest, strSrc, lenWithTerm) do { \ + if (SECUREC_ADDR_ALIGNED_8(strDest) && SECUREC_ADDR_ALIGNED_8(strSrc)) { \ + /* Use struct assignment */ \ + switch (lenWithTerm) { \ + case 1: \ + *(strDest) = *(strSrc); \ + break; \ + case 2: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 2); \ + break; \ + case 3: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 3); \ + break; \ + case 4: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 4); \ + break; \ + case 5: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 5); \ + break; \ + case 6: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 6); \ + break; \ + case 7: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 7); \ + break; \ + case 8: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 8); \ + break; \ + case 9: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 9); \ + break; \ + case 10: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 10); \ + break; \ + case 11: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 11); \ + break; \ + case 12: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 12); \ + break; \ + case 13: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 13); \ + break; \ + case 14: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 14); \ + break; \ + case 15: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 15); \ + break; \ + case 16: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 16); \ + break; \ + case 17: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 17); \ + break; \ + case 18: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 18); \ + break; \ + case 19: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 19); \ + break; \ + case 20: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 20); \ + break; \ + case 21: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 21); \ + break; \ + case 22: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 22); \ + break; \ + case 23: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 23); \ + break; \ + case 24: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 24); \ + break; \ + case 25: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 25); \ + break; \ + case 26: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 26); \ + break; \ + case 27: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 27); \ + break; \ + case 28: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 28); \ + break; \ + case 29: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 29); \ + break; \ + case 30: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 30); \ + break; \ + case 31: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 31); \ + break; \ + case 32: \ + SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 32); \ + break; \ + default: \ + /* Do nothing */ \ + break; \ + } /* END switch */ \ + } else { \ + char *tmpStrDest_ = (char *)(strDest); \ + const char *tmpStrSrc_ = (const char *)(strSrc); \ + switch (lenWithTerm) { \ + case 32: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 31: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 30: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 29: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 28: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 27: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 26: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 25: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 24: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 23: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 22: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 21: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 20: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 19: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 18: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 17: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 16: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 15: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 14: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 13: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 12: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 11: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 10: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 9: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 8: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 7: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 6: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 5: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 4: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 3: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 2: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + case 1: \ + *(tmpStrDest_++) = *(tmpStrSrc_++); \ + /* fall-through */ /* FALLTHRU */ \ + default: \ + /* Do nothing */ \ + break; \ + } \ + } \ +} SECUREC_WHILE_ZERO +#endif + +#if SECUREC_IN_KERNEL || (!SECUREC_STRCPY_WITH_PERFORMANCE) +#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)) +#else +/* + * Performance optimization. lenWithTerm include '\0' + */ +#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) do { \ + if ((lenWithTerm) > SECUREC_STRCOPY_THRESHOLD_SIZE) { \ + SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)); \ + } else { \ + SECUREC_SMALL_STR_COPY((dest), (src), (lenWithTerm)); \ + } \ +} SECUREC_WHILE_ZERO +#endif + +/* + * Check Src Range + */ +SECUREC_INLINE errno_t CheckSrcRange(char *strDest, size_t destMax, const char *strSrc) +{ + size_t tmpDestMax = destMax; + const char *tmpSrc = strSrc; + /* Use destMax as boundary checker and destMax must be greater than zero */ + while (*tmpSrc != '\0' && tmpDestMax > 0) { + ++tmpSrc; + --tmpDestMax; + } + if (tmpDestMax == 0) { + strDest[0] = '\0'; + SECUREC_ERROR_INVALID_RANGE("strcpy_s"); + return ERANGE_AND_RESET; + } + return EOK; +} + +/* + * Handling errors + */ +errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc) +{ + if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("strcpy_s"); + return ERANGE; + } + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("strcpy_s"); + if (strDest != NULL) { + strDest[0] = '\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + return CheckSrcRange(strDest, destMax, strSrc); +} + +/* + * + * The strcpy_s function copies the string pointed to strSrc + * (including the terminating null character) into the array pointed to by strDest + * The destination string must be large enough to hold the source string, + * including the terminating null character. strcpy_s will return EOVERLAP_AND_RESET + * if the source and destination strings overlap. + * + * + * strDest Location of destination string buffer + * destMax Size of the destination string buffer. + * strSrc Null-terminated source string buffer. + * + * + * strDest is updated. + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN + * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN + * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN + * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc) +{ + if (SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc)) { + size_t srcStrLen; + SECUREC_CALC_STR_LEN(strSrc, destMax, &srcStrLen); + ++srcStrLen; /* The length include '\0' */ + + if (srcStrLen <= destMax) { + /* Use mem overlap check include '\0' */ + if (SECUREC_MEMORY_NO_OVERLAP(strDest, strSrc, srcStrLen)) { + /* Performance optimization srcStrLen include '\0' */ + SECUREC_STRCPY_OPT(strDest, strSrc, srcStrLen); + return EOK; + } else { + strDest[0] = '\0'; + SECUREC_ERROR_BUFFER_OVERLAP("strcpy_s"); + return EOVERLAP_AND_RESET; + } + } + } + return strcpy_error(strDest, destMax, strSrc); +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(strcpy_s); +#endif + diff --git a/components/lib/libsec/src/strncat_s.c b/components/lib/libsec/src/strncat_s.c new file mode 100644 index 000000000..3baf9bf24 --- /dev/null +++ b/components/lib/libsec/src/strncat_s.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: strncat_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * Befor this function, the basic parameter checking has been done + */ +SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax, const char *strSrc, size_t count) +{ + size_t destLen; + size_t srcLen; + SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); + /* + * The strSrc is no longer optimized. The reason is that when count is small, + * the efficiency of strnlen is higher than that of self realization. + */ + SECUREC_CALC_STR_LEN(strSrc, count, &srcLen); + + if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { + strDest[0] = '\0'; + if (strDest + destLen <= strSrc && destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_BUFFER_OVERLAP("strncat_s"); + return EOVERLAP_AND_RESET; + } + if (srcLen + destLen >= destMax || strDest == strSrc) { + strDest[0] = '\0'; + if (destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_INVALID_RANGE("strncat_s"); + return ERANGE_AND_RESET; + } + SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen); /* No terminator */ + *(strDest + destLen + srcLen) = '\0'; + return EOK; +} + +/* + * + * The strncat_s function appends not more than n successive characters + * (not including the terminating null character) + * from the array pointed to by strSrc to the end of the string pointed to by strDest + * The strncat_s function try to append the first D characters of strSrc to + * the end of strDest, where D is the lesser of count and the length of strSrc. + * If appending those D characters will fit within strDest (whose size is given + * as destMax) and still leave room for a null terminator, then those characters + * are appended, starting at the original terminating null of strDest, and a + * new terminating null is appended; otherwise, strDest[0] is set to the null + * character. + * + * + * strDest Null-terminated destination string. + * destMax Size of the destination buffer. + * strSrc Null-terminated source string. + * count Number of character to append, or truncate. + * + * + * strDest is updated + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN + * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid)or + * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN) + * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN + * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("strncat_s"); + return ERANGE; + } + + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); + if (strDest != NULL) { + strDest[0] = '\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + if (count > SECUREC_STRING_MAX_LEN) { +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT + if (count == (size_t)(-1)) { + /* Windows internal functions may pass in -1 when calling this function */ + return SecDoCatLimit(strDest, destMax, strSrc, destMax); + } +#endif + strDest[0] = '\0'; + SECUREC_ERROR_INVALID_RANGE("strncat_s"); + return ERANGE_AND_RESET; + } + return SecDoCatLimit(strDest, destMax, strSrc, count); +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(strncat_s); +#endif + diff --git a/components/lib/libsec/src/strncpy_s.c b/components/lib/libsec/src/strncpy_s.c new file mode 100644 index 000000000..5bbf08145 --- /dev/null +++ b/components/lib/libsec/src/strncpy_s.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: strncpy_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) +#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \ + (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \ + ((count) <= SECUREC_STRING_MAX_LEN || (count) == ((size_t)(-1))) && (count) > 0)) +#else +#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \ + (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \ + (count) <= SECUREC_STRING_MAX_LEN && (count) > 0)) +#endif + +/* + * Check Src Count Range + */ +SECUREC_INLINE errno_t CheckSrcCountRange(char *strDest, size_t destMax, const char *strSrc, size_t count) +{ + size_t tmpDestMax = destMax; + size_t tmpCount = count; + const char *endPos = strSrc; + + /* Use destMax and count as boundary checker and destMax must be greater than zero */ + while (*(endPos) != '\0' && tmpDestMax > 0 && tmpCount > 0) { + ++endPos; + --tmpCount; + --tmpDestMax; + } + if (tmpDestMax == 0) { + strDest[0] = '\0'; + SECUREC_ERROR_INVALID_RANGE("strncpy_s"); + return ERANGE_AND_RESET; + } + return EOK; +} + +/* + * Handling errors, when dest euqal src return EOK + */ +errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("strncpy_s"); + return ERANGE; + } + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("strncpy_s"); + if (strDest != NULL) { + strDest[0] = '\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + if (count > SECUREC_STRING_MAX_LEN) { + strDest[0] = '\0'; /* Clear dest string */ + SECUREC_ERROR_INVALID_RANGE("strncpy_s"); + return ERANGE_AND_RESET; + } + if (count == 0) { + strDest[0] = '\0'; + return EOK; + } + return CheckSrcCountRange(strDest, destMax, strSrc, count); +} + +/* + * + * The strncpy_s function copies not more than n successive characters (not including the terminating null character) + * from the array pointed to by strSrc to the array pointed to by strDest. + * + * + * strDest Destination string. + * destMax The size of the destination string, in characters. + * strSrc Source string. + * count Number of characters to be copied. + * + * + * strDest is updated + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN + * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN + * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN + * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count) +{ + if (SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count)) { + size_t minCpLen; /* Use it to store the maxi length limit */ + if (count < destMax) { + SECUREC_CALC_STR_LEN(strSrc, count, &minCpLen); /* No ending terminator */ + } else { + size_t tmpCount = destMax; +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT + if (count == ((size_t)(-1))) { + tmpCount = destMax - 1; + } +#endif + SECUREC_CALC_STR_LEN(strSrc, tmpCount, &minCpLen); /* No ending terminator */ + if (minCpLen == destMax) { + strDest[0] = '\0'; + SECUREC_ERROR_INVALID_RANGE("strncpy_s"); + return ERANGE_AND_RESET; + } + } + if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, minCpLen) || strDest == strSrc) { + /* Not overlap */ + SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, minCpLen); /* Copy string without terminator */ + strDest[minCpLen] = '\0'; + return EOK; + } else { + strDest[0] = '\0'; + SECUREC_ERROR_BUFFER_OVERLAP("strncpy_s"); + return EOVERLAP_AND_RESET; + } + } + return strncpy_error(strDest, destMax, strSrc, count); +} + +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(strncpy_s); +#endif + diff --git a/components/lib/libsec/src/strtok_s.c b/components/lib/libsec/src/strtok_s.c new file mode 100644 index 000000000..b04793bcf --- /dev/null +++ b/components/lib/libsec/src/strtok_s.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: strtok_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +SECUREC_INLINE int SecIsInDelimit(char ch, const char *strDelimit) +{ + const char *ctl = strDelimit; + while (*ctl != '\0' && *ctl != ch) { + ++ctl; + } + return (int)(*ctl != '\0'); +} + +/* + * Find beginning of token (skip over leading delimiters). + * Note that there is no token if this loop sets string to point to the terminal null. + */ +SECUREC_INLINE char *SecFindBegin(char *strToken, const char *strDelimit) +{ + char *token = strToken; + while (*token != '\0') { + if (SecIsInDelimit(*token, strDelimit) != 0) { + ++token; + continue; + } + /* Don't find any delimiter in string header, break the loop */ + break; + } + return token; +} + +/* + * Find rest of token + */ +SECUREC_INLINE char *SecFindRest(char *strToken, const char *strDelimit) +{ + /* Find the rest of the token. If it is not the end of the string, put a null there */ + char *token = strToken; + while (*token != '\0') { + if (SecIsInDelimit(*token, strDelimit) != 0) { + /* Find a delimiter, set string termintor */ + *token = '\0'; + ++token; + break; + } + ++token; + } + return token; +} + +/* + * Find the final position pointer + */ +SECUREC_INLINE char *SecUpdateToken(char *strToken, const char *strDelimit, char **context) +{ + /* Point to updated position. Record string position for next search in the context */ + *context = SecFindRest(strToken, strDelimit); + /* Determine if a token has been found. */ + if (*context == strToken) { + return NULL; + } + return strToken; +} + +/* + * + * The strtok_s function parses a string into a sequence of strToken, + * replace all characters in strToken string that match to strDelimit set with 0. + * On the first call to strtok_s the string to be parsed should be specified in strToken. + * In each subsequent call that should parse the same string, strToken should be NULL + * + * strToken String containing token or tokens. + * strDelimit Set of delimiter characters. + * context Used to store position information between calls + * to strtok_s + * + * context is updated + * + * On the first call returns the address of the first non \0 character, otherwise NULL is returned. + * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call, + * return NULL if the *context string length is equal 0, otherwise return *context. + */ +char *strtok_s(char *strToken, const char *strDelimit, char **context) +{ + char *orgToken = strToken; + /* Validate delimiter and string context */ + if (context == NULL || strDelimit == NULL) { + return NULL; + } + /* Valid input string and string pointer from where to search */ + if (orgToken == NULL && *context == NULL) { + return NULL; + } + /* If string is null, continue searching from previous string position stored in context */ + if (orgToken == NULL) { + orgToken = *context; + } + orgToken = SecFindBegin(orgToken, strDelimit); + return SecUpdateToken(orgToken, strDelimit, context); +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(strtok_s); +#endif + diff --git a/components/lib/libsec/src/swprintf_s.c b/components/lib/libsec/src/swprintf_s.c new file mode 100644 index 000000000..2d2ad42b1 --- /dev/null +++ b/components/lib/libsec/src/swprintf_s.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: swprintf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The swprintf_s function is the wide-character equivalent of the sprintf_s function + * + * + * strDest Storage location for the output. + * destMax Maximum number of characters to store. + * format Format-control string. + * ... Optional arguments + * + * + * strDest is updated + * + * + * return the number of wide characters stored in strDest, not counting the terminating null wide character. + * return -1 if an error occurred. + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vswprintf_s(strDest, destMax, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + diff --git a/components/lib/libsec/src/swscanf_s.c b/components/lib/libsec/src/swscanf_s.c new file mode 100644 index 000000000..987b6893d --- /dev/null +++ b/components/lib/libsec/src/swscanf_s.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: swscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * The swscanf_s function is the wide-character equivalent of the sscanf_s function + * The swscanf_s function reads data from buffer into the location given by + * each argument. Every argument must be a pointer to a variable with a type + * that corresponds to a type specifier in format. The format argument controls + * the interpretation of the input fields and has the same form and function + * as the format argument for the scanf function. If copying takes place between + * strings that overlap, the behavior is undefined. + * + * + * buffer Stored data. + * format Format control string, see Format Specifications. + * ... Optional arguments. + * + * + * ... the converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; The return value does not include fields that were read but not + * assigned. + * A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vswscanf_s(buffer, format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + diff --git a/components/lib/libsec/src/vfscanf_s.c b/components/lib/libsec/src/vfscanf_s.c new file mode 100644 index 000000000..96aee67fa --- /dev/null +++ b/components/lib/libsec/src/vfscanf_s.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vfscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "secinput.h" + +/* + * + * The vfscanf_s function is equivalent to fscanf_s, with the variable argument list replaced by argList + * The vfscanf_s function reads data from the current position of stream into + * the locations given by argument (if any). Each argument must be a pointer + * to a variable of a type that corresponds to a type specifier in format. + * format controls the interpretation of the input fields and has the same + * form and function as the format argument for scanf. + * + * + * stream Pointer to FILE structure. + * format Format control string, see Format Specifications. + * argList pointer to list of arguments + * + * + * argList the converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int vfscanf_s(FILE *stream, const char *format, va_list argList) +{ + int retVal; /* If initialization causes e838 */ + SecFileStream fStr; + + if (stream == NULL || format == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s"); + return SECUREC_SCANF_EINVAL; + } + if (stream == SECUREC_STREAM_STDIN) { + return vscanf_s(format, argList); + } + + SECUREC_LOCK_FILE(stream); + SECUREC_FILE_STREAM_FROM_FILE(&fStr, stream); + retVal = SecInputS(&fStr, format, argList); + SECUREC_UNLOCK_FILE(stream); + if (retVal < 0) { + SECUREC_ERROR_INVALID_PARAMTER("vfscanf_s"); + return SECUREC_SCANF_EINVAL; + } + + return retVal; +} + diff --git a/components/lib/libsec/src/vfwscanf_s.c b/components/lib/libsec/src/vfwscanf_s.c new file mode 100644 index 000000000..0fd0c350c --- /dev/null +++ b/components/lib/libsec/src/vfwscanf_s.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vfwscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECUREC_FOR_WCHAR +#define SECUREC_FOR_WCHAR +#endif + +#include "secinput.h" + +/* + * + * The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function + * The vfwscanf_s function reads data from the current position of stream into + * the locations given by argument (if any). Each argument must be a pointer + * to a variable of a type that corresponds to a type specifier in format. + * format controls the interpretation of the input fields and has the same form + * and function as the format argument for scanf. + * + * + * stream Pointer to FILE structure. + * format Format control string, see Format Specifications. + * argList pointer to list of arguments + * + * + * argList the converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList) +{ + int retVal; /* If initialization causes e838 */ + SecFileStream fStr; + + if (stream == NULL || format == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s"); + return SECUREC_SCANF_EINVAL; + } + if (stream == SECUREC_STREAM_STDIN) { + return vwscanf_s(format, argList); + } + + SECUREC_LOCK_FILE(stream); + SECUREC_FILE_STREAM_FROM_FILE(&fStr, stream); + retVal = SecInputSW(&fStr, format, argList); + SECUREC_UNLOCK_FILE(stream); + if (retVal < 0) { + SECUREC_ERROR_INVALID_PARAMTER("vfwscanf_s"); + return SECUREC_SCANF_EINVAL; + } + return retVal; +} + diff --git a/components/lib/libsec/src/vscanf_s.c b/components/lib/libsec/src/vscanf_s.c new file mode 100644 index 000000000..23edffe13 --- /dev/null +++ b/components/lib/libsec/src/vscanf_s.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "secinput.h" + +/* + * + * The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList, + * The vscanf_s function reads data from the standard input stream stdin and + * writes the data into the location that's given by argument. Each argument + * must be a pointer to a variable of a type that corresponds to a type specifier + * in format. If copying occurs between strings that overlap, the behavior is + * undefined. + * + * + * format Format control string. + * argList pointer to list of arguments + * + * + * argList the converted value stored in user assigned address + * + * + * Returns the number of fields successfully converted and assigned; + * the return value does not include fields that were read but not assigned. + * A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int vscanf_s(const char *format, va_list argList) +{ + int retVal; /* If initialization causes e838 */ + SecFileStream fStr; + SECUREC_FILE_STREAM_FROM_STDIN(&fStr); + /* + * The "va_list" has different definition on different platform, so we can't use argList == NULL + * To determine it's invalid. If you has fixed platform, you can check some fields to validate it, + * such as "argList == NULL" or argList.xxx != NULL or *(size_t *)&argList != 0. + */ + if (format == NULL || fStr.pf == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("vscanf_s"); + return SECUREC_SCANF_EINVAL; + } + + SECUREC_LOCK_STDIN(0, fStr.pf); + retVal = SecInputS(&fStr, format, argList); + SECUREC_UNLOCK_STDIN(0, fStr.pf); + if (retVal < 0) { + SECUREC_ERROR_INVALID_PARAMTER("vscanf_s"); + return SECUREC_SCANF_EINVAL; + } + return retVal; +} + diff --git a/components/lib/libsec/src/vsnprintf_s.c b/components/lib/libsec/src/vsnprintf_s.c new file mode 100644 index 000000000..36619d87a --- /dev/null +++ b/components/lib/libsec/src/vsnprintf_s.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vsnprintf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "secureprintoutput.h" + +#if SECUREC_ENABLE_VSNPRINTF +/* + * + * The vsnprintf_s function is equivalent to the vsnprintf function + * except for the parameter destMax/count and the explicit runtime-constraints violation + * The vsnprintf_s function takes a pointer to an argument list, then formats + * and writes up to count characters of the given data to the memory pointed + * to by strDest and appends a terminating null. + * + * + * strDest Storage location for the output. + * destMax The size of the strDest for output. + * count Maximum number of character to write(not including + * the terminating NULL) + * format Format-control string. + * argList pointer to list of arguments. + * + * + * strDest is updated + * + * + * return the number of characters written, not including the terminating null + * return -1 if an error occurs. + * return -1 if count < destMax and the output string has been truncated + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list argList) +{ + int retVal; + + if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, SECUREC_STRING_MAX_LEN)) { + SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); + SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); + return -1; + } + + if (destMax > count) { + retVal = SecVsnprintfImpl(strDest, count + 1, format, argList); + if (retVal == SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not destroyed 2014.2.18 */ + /* The string has been truncated, return -1 */ + return -1; /* To skip error handler, return strlen(strDest) or -1 */ + } + } else { + retVal = SecVsnprintfImpl(strDest, destMax, format, argList); +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT + if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) { + return -1; + } +#endif + } + + if (retVal < 0) { + strDest[0] = '\0'; /* Empty the dest strDest */ + if (retVal == SECUREC_PRINTF_TRUNCATE) { + /* Buffer too small */ + SECUREC_ERROR_INVALID_RANGE("vsnprintf_s"); + } + SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); + return -1; + } + + return retVal; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(vsnprintf_s); +#endif +#endif + +#if SECUREC_SNPRINTF_TRUNCATED +/* + * + * The vsnprintf_truncated_s function is equivalent to the vsnprintf function + * except for the parameter destMax/count and the explicit runtime-constraints violation + * The vsnprintf_truncated_s function takes a pointer to an argument list, then formats + * and writes up to count characters of the given data to the memory pointed + * to by strDest and appends a terminating null. + * + * + * strDest Storage location for the output. + * destMax The size of the strDest for output. + * the terminating NULL) + * format Format-control string. + * argList pointer to list of arguments. + * + * + * strDest is updated + * + * + * return the number of characters written, not including the terminating null + * return -1 if an error occurs. + * return destMax-1 if output string has been truncated + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, va_list argList) +{ + int retVal; + + if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) { + SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); + SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); + return -1; + } + + retVal = SecVsnprintfImpl(strDest, destMax, format, argList); + if (retVal < 0) { + if (retVal == SECUREC_PRINTF_TRUNCATE) { + return (int)(destMax - 1); /* To skip error handler, return strlen(strDest) */ + } + strDest[0] = '\0'; /* Empty the dest strDest */ + SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); + return -1; + } + + return retVal; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(vsnprintf_truncated_s); +#endif +#endif + diff --git a/components/lib/libsec/src/vsprintf_s.c b/components/lib/libsec/src/vsprintf_s.c new file mode 100644 index 000000000..012f522c4 --- /dev/null +++ b/components/lib/libsec/src/vsprintf_s.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vsprintf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "secureprintoutput.h" + +/* + * + * The vsprintf_s function is equivalent to the vsprintf function + * except for the parameter destMax and the explicit runtime-constraints violation + * The vsprintf_s function takes a pointer to an argument list, and then formats + * and writes the given data to the memory pointed to by strDest. + * The function differ from the non-secure versions only in that the secure + * versions support positional parameters. + * + * + * strDest Storage location for the output. + * destMax Size of strDest + * format Format specification. + * argList pointer to list of arguments + * + * + * strDest is updated + * + * + * return the number of characters written, not including the terminating null character, + * return -1 if an error occurs. + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +int vsprintf_s(char *strDest, size_t destMax, const char *format, va_list argList) +{ + int retVal; /* If initialization causes e838 */ + + if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) { + SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); + SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s"); + return -1; + } + + retVal = SecVsnprintfImpl(strDest, destMax, format, argList); + if (retVal < 0) { + strDest[0] = '\0'; + if (retVal == SECUREC_PRINTF_TRUNCATE) { + /* Buffer is too small */ + SECUREC_ERROR_INVALID_RANGE("vsprintf_s"); + } + SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s"); + return -1; + } + + return retVal; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(vsprintf_s); +#endif + diff --git a/components/lib/libsec/src/vsscanf_s.c b/components/lib/libsec/src/vsscanf_s.c new file mode 100644 index 000000000..6612d2fa0 --- /dev/null +++ b/components/lib/libsec/src/vsscanf_s.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vsscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "secinput.h" +#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL && \ + (!defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT)) +#include +#endif + +/* + * + * vsscanf_s + * + * + * + * The vsscanf_s function is equivalent to sscanf_s, with the variable argument list replaced by argList + * The vsscanf_s function reads data from buffer into the location given by + * each argument. Every argument must be a pointer to a variable with a type + * that corresponds to a type specifier in format. The format argument controls + * the interpretation of the input fields and has the same form and function + * as the format argument for the scanf function. + * If copying takes place between strings that overlap, the behavior is undefined. + * + * + * buffer Stored data + * format Format control string, see Format Specifications. + * argList pointer to list of arguments + * + * + * argList the converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int vsscanf_s(const char *buffer, const char *format, va_list argList) +{ + size_t count; /* If initialization causes e838 */ + int retVal; + SecFileStream fStr; + + /* Validation section */ + if (buffer == NULL || format == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); + return SECUREC_SCANF_EINVAL; + } + count = strlen(buffer); + if (count == 0 || count > SECUREC_STRING_MAX_LEN) { + SecClearDestBuf(buffer, format, argList); + SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); + return SECUREC_SCANF_EINVAL; + } +#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL + /* + * On vxworks platform when buffer is white string, will set first %s argument tu zero.like following useage: + * " \v\f\t\r\n", "%s", str, strSize + * Do not check all character, just first and last character then consider it is white string + */ + if (isspace((int)(unsigned char)buffer[0]) != 0 && isspace((int)(unsigned char)buffer[count - 1]) != 0) { + SecClearDestBuf(buffer, format, argList); + } +#endif + SECUREC_FILE_STREAM_FROM_STRING(&fStr, buffer, count); + retVal = SecInputS(&fStr, format, argList); + if (retVal < 0) { + SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); + return SECUREC_SCANF_EINVAL; + } + return retVal; +} +#if SECUREC_IN_KERNEL +EXPORT_SYMBOL(vsscanf_s); +#endif + diff --git a/components/lib/libsec/src/vswprintf_s.c b/components/lib/libsec/src/vswprintf_s.c new file mode 100644 index 000000000..38b0b4045 --- /dev/null +++ b/components/lib/libsec/src/vswprintf_s.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vswprintf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECUREC_FOR_WCHAR +#define SECUREC_FOR_WCHAR +#endif + +#include "secureprintoutput.h" + +/* + * + * The vswprintf_s function is the wide-character equivalent of the vsprintf_s function + * + * + * strDest Storage location for the output. + * destMax Maximum number of characters to store + * format Format specification. + * argList pointer to list of arguments + * + * + * strDest is updated + * + * + * return the number of wide characters stored in strDest, not counting the terminating null wide character. + * return -1 if an error occurred. + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList) +{ + int retVal; /* If initialization causes e838 */ + if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN)) { + SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN); + SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s"); + return -1; + } + + retVal = SecVswprintfImpl(strDest, destMax, format, argList); + if (retVal < 0) { + strDest[0] = L'\0'; + if (retVal == SECUREC_PRINTF_TRUNCATE) { + /* Buffer too small */ + SECUREC_ERROR_INVALID_RANGE("vswprintf_s"); + } + SECUREC_ERROR_INVALID_PARAMTER("vswprintf_s"); + return -1; + } + + return retVal; +} + diff --git a/components/lib/libsec/src/vswscanf_s.c b/components/lib/libsec/src/vswscanf_s.c new file mode 100644 index 000000000..d416b96c7 --- /dev/null +++ b/components/lib/libsec/src/vswscanf_s.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vswscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECUREC_FOR_WCHAR +#define SECUREC_FOR_WCHAR +#endif + +#include "secinput.h" + +SECUREC_INLINE size_t SecWcslen(const wchar_t *s) +{ + const wchar_t *end = s; + while (*end != L'\0') { + ++end; + } + return ((size_t)((end - s))); +} + +/* + * + * The vswscanf_s function is the wide-character equivalent of the vsscanf_s function + * The vsscanf_s function reads data from buffer into the location given by + * each argument. Every argument must be a pointer to a variable with a type + * that corresponds to a type specifier in format. + * The format argument controls the interpretation of the input fields and + * has the same form and function as the format argument for the scanf function. + * If copying takes place between strings that overlap, the behavior is undefined. + * + * + * buffer Stored data + * format Format control string, see Format Specifications. + * argList pointer to list of arguments + * + * + * argList the converted value stored in user assigned address + * + * + * Each of these functions returns the number of fields successfully converted + * and assigned; the return value does not include fields that were read but + * not assigned. A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList) +{ + size_t count; /* If initialization causes e838 */ + SecFileStream fStr; + int retVal; + + /* Validation section */ + if (buffer == NULL || format == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s"); + return SECUREC_SCANF_EINVAL; + } + count = SecWcslen(buffer); + if (count == 0 || count > SECUREC_WCHAR_STRING_MAX_LEN) { + SecClearDestBufW(buffer, format, argList); + SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s"); + return SECUREC_SCANF_EINVAL; + } + SECUREC_FILE_STREAM_FROM_STRING(&fStr, (const char *)buffer, count * sizeof(wchar_t)); + retVal = SecInputSW(&fStr, format, argList); + if (retVal < 0) { + SECUREC_ERROR_INVALID_PARAMTER("vswscanf_s"); + return SECUREC_SCANF_EINVAL; + } + return retVal; +} + diff --git a/components/lib/libsec/src/vwscanf_s.c b/components/lib/libsec/src/vwscanf_s.c new file mode 100644 index 000000000..90f49a1c3 --- /dev/null +++ b/components/lib/libsec/src/vwscanf_s.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: vwscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#ifndef SECUREC_FOR_WCHAR +#define SECUREC_FOR_WCHAR +#endif + +#include "secinput.h" + +/* + * + * The vwscanf_s function is the wide-character equivalent of the vscanf_s function + * The vwscanf_s function is the wide-character version of vscanf_s. The + * function reads data from the standard input stream stdin and writes the + * data into the location that's given by argument. Each argument must be a + * pointer to a variable of a type that corresponds to a type specifier in + * format. If copying occurs between strings that overlap, the behavior is + * undefined. + * + * + * format Format control string. + * argList pointer to list of arguments + * + * + * argList the converted value stored in user assigned address + * + * + * Returns the number of fields successfully converted and assigned; + * the return value does not include fields that were read but not assigned. + * A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int vwscanf_s(const wchar_t *format, va_list argList) +{ + int retVal; /* If initialization causes e838 */ + SecFileStream fStr; + SECUREC_FILE_STREAM_FROM_STDIN(&fStr); + if (format == NULL || fStr.pf == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s"); + return SECUREC_SCANF_EINVAL; + } + + SECUREC_LOCK_STDIN(0, fStr.pf); + retVal = SecInputSW(&fStr, format, argList); + SECUREC_UNLOCK_STDIN(0, fStr.pf); + if (retVal < 0) { + SECUREC_ERROR_INVALID_PARAMTER("vwscanf_s"); + return SECUREC_SCANF_EINVAL; + } + + return retVal; +} + diff --git a/components/lib/libsec/src/wcscat_s.c b/components/lib/libsec/src/wcscat_s.c new file mode 100644 index 000000000..780907bf3 --- /dev/null +++ b/components/lib/libsec/src/wcscat_s.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wcscat_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * Befor this function, the basic parameter checking has been done + */ +SECUREC_INLINE errno_t SecDoCatW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc) +{ + size_t destLen; + size_t srcLen; + size_t maxCount; /* Store the maximum available count */ + + /* To calculate the length of a wide character, the parameter must be a wide character */ + SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen); + maxCount = destMax - destLen; + SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen); + + if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { + strDest[0] = L'\0'; + if (strDest + destLen <= strSrc && destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("wcscat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_BUFFER_OVERLAP("wcscat_s"); + return EOVERLAP_AND_RESET; + } + if (srcLen + destLen >= destMax || strDest == strSrc) { + strDest[0] = L'\0'; + if (destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("wcscat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_INVALID_RANGE("wcscat_s"); + return ERANGE_AND_RESET; + } + /* Copy single character length include \0 */ + SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, (srcLen + 1) * sizeof(wchar_t)); + return EOK; +} + +/* + * + * The wcscat_s function appends a copy of the wide string pointed to by strSrc +* (including the terminating null wide character) + * to the end of the wide string pointed to by strDest. + * The arguments and return value of wcscat_s are wide-character strings. + * + * The wcscat_s function appends strSrc to strDest and terminates the resulting + * string with a null character. The initial character of strSrc overwrites the + * terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the + * source and destination strings overlap. + * + * Note that the second parameter is the total size of the buffer, not the + * remaining size. + * + * + * strDest Null-terminated destination string buffer. + * destMax Size of the destination string buffer. + * strSrc Null-terminated source string buffer. + * + * + * strDest is updated + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or + * (strDest != NULL and strSrc is NULLL and destMax != 0 + * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN) + * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 + * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc) +{ + if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("wcscat_s"); + return ERANGE; + } + + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("wcscat_s"); + if (strDest != NULL) { + strDest[0] = L'\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + + return SecDoCatW(strDest, destMax, strSrc); +} + diff --git a/components/lib/libsec/src/wcscpy_s.c b/components/lib/libsec/src/wcscpy_s.c new file mode 100644 index 000000000..89c281df6 --- /dev/null +++ b/components/lib/libsec/src/wcscpy_s.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wcscpy_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +SECUREC_INLINE errno_t SecDoCpyW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc) +{ + size_t srcStrLen; + SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen); + + if (srcStrLen == destMax) { + strDest[0] = L'\0'; + SECUREC_ERROR_INVALID_RANGE("wcscpy_s"); + return ERANGE_AND_RESET; + } + if (strDest == strSrc) { + return EOK; + } + + if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) { + /* Performance optimization, srcStrLen is single character length include '\0' */ + SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, (srcStrLen + 1) * sizeof(wchar_t)); + return EOK; + } else { + strDest[0] = L'\0'; + SECUREC_ERROR_BUFFER_OVERLAP("wcscpy_s"); + return EOVERLAP_AND_RESET; + } +} + +/* + * + * The wcscpy_s function copies the wide string pointed to by strSrc + * (including theterminating null wide character) into the array pointed to by strDest + + * + * strDest Destination string buffer + * destMax Size of the destination string buffer. + * strSrc Null-terminated source string buffer. + * + * + * strDest is updated. + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * EINVAL_AND_RESET strDest != NULL and strSrc is NULLL and destMax != 0 + * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 + * ERANGE_AND_RESET destMax <= length of strSrc and strDest != strSrc + * and strDest != NULL and strSrc != NULL and destMax != 0 + * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and destMax != 0 + * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * and strDest != NULL and strSrc !=NULL and strDest != strSrc + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc) +{ + if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("wcscpy_s"); + return ERANGE; + } + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("wcscpy_s"); + if (strDest != NULL) { + strDest[0] = L'\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + return SecDoCpyW(strDest, destMax, strSrc); +} + diff --git a/components/lib/libsec/src/wcsncat_s.c b/components/lib/libsec/src/wcsncat_s.c new file mode 100644 index 000000000..6151da442 --- /dev/null +++ b/components/lib/libsec/src/wcsncat_s.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wcsncat_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * Befor this function, the basic parameter checking has been done + */ +SECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count) +{ + /* To calculate the length of a wide character, the parameter must be a wide character */ + size_t destLen; + size_t srcLen; + SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen); + SECUREC_CALC_WSTR_LEN(strSrc, count, &srcLen); + + if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { + strDest[0] = L'\0'; + if (strDest + destLen <= strSrc && destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_BUFFER_OVERLAP("wcsncat_s"); + return EOVERLAP_AND_RESET; + } + if (srcLen + destLen >= destMax || strDest == strSrc) { + strDest[0] = L'\0'; + if (destLen == destMax) { + SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s"); + return EINVAL_AND_RESET; + } + SECUREC_ERROR_INVALID_RANGE("wcsncat_s"); + return ERANGE_AND_RESET; + } + SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen * sizeof(wchar_t)); /* no terminator */ + *(strDest + destLen + srcLen) = L'\0'; + return EOK; +} + +/* + * + * The wcsncat_s function appends not more than n successive wide characters + * (not including the terminating null wide character) + * from the array pointed to by strSrc to the end of the wide string pointed to by strDest. + * + * The wcsncat_s function try to append the first D characters of strSrc to + * the end of strDest, where D is the lesser of count and the length of strSrc. + * If appending those D characters will fit within strDest (whose size is + * given as destMax) and still leave room for a null terminator, then those + * characters are appended, starting at the original terminating null of + * strDest, and a new terminating null is appended; otherwise, strDest[0] is + * set to the null character. + * + * + * strDest Null-terminated destination string. + * destMax Size of the destination buffer. + * strSrc Null-terminated source string. + * count Number of character to append, or truncate. + * + * + * strDest is updated + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or + * (strDest != NULL and strSrc is NULLL and destMax != 0 and + * destMax <= SECUREC_WCHAR_STRING_MAX_LEN) + * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 + * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("wcsncat_s"); + return ERANGE; + } + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("wcsncat_s"); + if (strDest != NULL) { + strDest[0] = L'\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + if (count > SECUREC_WCHAR_STRING_MAX_LEN) { +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT + if (count == ((size_t)(-1))) { + /* Windows internal functions may pass in -1 when calling this function */ + return SecDoCatLimitW(strDest, destMax, strSrc, destMax); + } +#endif + strDest[0] = L'\0'; + SECUREC_ERROR_INVALID_RANGE("wcsncat_s"); + return ERANGE_AND_RESET; + } + return SecDoCatLimitW(strDest, destMax, strSrc, count); +} + diff --git a/components/lib/libsec/src/wcsncpy_s.c b/components/lib/libsec/src/wcsncpy_s.c new file mode 100644 index 000000000..8bd5737bb --- /dev/null +++ b/components/lib/libsec/src/wcsncpy_s.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wcsncpy_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +SECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count) +{ + size_t srcStrLen; + if (count < destMax) { + SECUREC_CALC_WSTR_LEN(strSrc, count, &srcStrLen); + } else { + SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen); + } + if (srcStrLen == destMax) { + strDest[0] = L'\0'; + SECUREC_ERROR_INVALID_RANGE("wcsncpy_s"); + return ERANGE_AND_RESET; + } + if (strDest == strSrc) { + return EOK; + } + if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) { + /* Performance optimization srcStrLen not include '\0' */ + SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, srcStrLen * sizeof(wchar_t)); + *(strDest + srcStrLen) = L'\0'; + return EOK; + } else { + strDest[0] = L'\0'; + SECUREC_ERROR_BUFFER_OVERLAP("wcsncpy_s"); + return EOVERLAP_AND_RESET; + } +} + +/* + * + * The wcsncpy_s function copies not more than n successive wide characters + * (not including the terminating null wide character) + * from the array pointed to by strSrc to the array pointed to by strDest + * + * + * strDest Destination string. + * destMax The size of the destination string, in characters. + * strSrc Source string. + * count Number of characters to be copied. + * + * + * strDest is updated + * + * + * EOK Success + * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * EINVAL_AND_RESET strDest != NULL and strSrc is NULLL and destMax != 0 + * and destMax <= SECUREC_WCHAR_STRING_MAX_LEN + * ERANGE destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0 + * ERANGE_AND_RESET count > SECUREC_WCHAR_STRING_MAX_LEN or + * (destMax <= length of strSrc and destMax <= count and strDest != strSrc + * and strDest != NULL and strSrc != NULL and destMax != 0 and + * destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap) + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid + * + * + * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid + */ +errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) { + SECUREC_ERROR_INVALID_RANGE("wcsncpy_s"); + return ERANGE; + } + if (strDest == NULL || strSrc == NULL) { + SECUREC_ERROR_INVALID_PARAMTER("wcsncpy_s"); + if (strDest != NULL) { + strDest[0] = L'\0'; + return EINVAL_AND_RESET; + } + return EINVAL; + } + if (count > SECUREC_WCHAR_STRING_MAX_LEN) { +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT + if (count == (size_t)(-1)) { + return SecDoCpyLimitW(strDest, destMax, strSrc, destMax - 1); + } +#endif + strDest[0] = L'\0'; /* Clear dest string */ + SECUREC_ERROR_INVALID_RANGE("wcsncpy_s"); + return ERANGE_AND_RESET; + } + + if (count == 0) { + strDest[0] = L'\0'; + return EOK; + } + + return SecDoCpyLimitW(strDest, destMax, strSrc, count); +} + diff --git a/components/lib/libsec/src/wcstok_s.c b/components/lib/libsec/src/wcstok_s.c new file mode 100644 index 000000000..19284f334 --- /dev/null +++ b/components/lib/libsec/src/wcstok_s.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wcstok_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +SECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit) +{ + const wchar_t *ctl = strDelimit; + while (*ctl != L'\0' && *ctl != ch) { + ++ctl; + } + return (int)(*ctl != L'\0'); +} + +/* + * Find beginning of token (skip over leading delimiters). + * Note that there is no token if this loop sets string to point to the terminal null. + */ +SECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken, const wchar_t *strDelimit) +{ + wchar_t *token = strToken; + while (*token != L'\0') { + if (SecIsInDelimitW(*token, strDelimit) != 0) { + ++token; + continue; + } + /* Don't find any delimiter in string header, break the loop */ + break; + } + return token; +} + +/* + * Find the end of the token. If it is not the end of the string, put a null there. + */ +SECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken, const wchar_t *strDelimit) +{ + wchar_t *token = strToken; + while (*token != L'\0') { + if (SecIsInDelimitW(*token, strDelimit) != 0) { + /* Find a delimiter, set string termintor */ + *token = L'\0'; + ++token; + break; + } + ++token; + } + return token; +} + +/* + * Update Token wide character function + */ +SECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context) +{ + /* Point to updated position. Record string position for next search in the context */ + *context = SecFindRestW(strToken, strDelimit); + /* Determine if a token has been found */ + if (*context == strToken) { + return NULL; + } + return strToken; +} + +/* + * + * wcstok_s + * + * + * + * The wcstok_s function is the wide-character equivalent of the strtok_s function + * + * + * strToken String containing token or tokens. + * strDelimit Set of delimiter characters. + * context Used to store position information between calls to + * wcstok_s. + * + * + * context is updated + * + * The wcstok_s function is the wide-character equivalent of the strtok_s function + */ +wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context) +{ + wchar_t *orgToken = strToken; + /* Validation section */ + if (context == NULL || strDelimit == NULL) { + return NULL; + } + if (orgToken == NULL && *context == NULL) { + return NULL; + } + /* If string==NULL, continue with previous string */ + if (orgToken == NULL) { + orgToken = *context; + } + orgToken = SecFindBeginW(orgToken, strDelimit); + return SecUpdateTokenW(orgToken, strDelimit, context); +} + diff --git a/components/lib/libsec/src/wmemcpy_s.c b/components/lib/libsec/src/wmemcpy_s.c new file mode 100644 index 000000000..99611809f --- /dev/null +++ b/components/lib/libsec/src/wmemcpy_s.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wmemcpy_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * + * The wmemcpy_s function copies n successive wide characters + * from the object pointed to by src into the object pointed to by dest.t. + * + * + * dest Destination buffer. + * destMax Size of the destination buffer. + * src Buffer to copy from. + * count Number of characters to copy. + * + * + * dest buffer is uptdated. + * + * + * EOK Success + * EINVAL dest is NULL and destMax != 0 and count <= destMax + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN + * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax + * ERANGE destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or + * (count > destMax and dest is NULL and destMax != 0 + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN) + * ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0 + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN + * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and + * count <= destMax destMax != 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN + * and dest != NULL and src != NULL and dest != src + * + * if an error occured, dest will be filled with 0 when dest and destMax valid . + * If the source and destination overlap, the behavior of wmemcpy_s is undefined. + * Use wmemmove_s to handle overlapping regions. + */ +errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) { + SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s"); + return ERANGE; + } + if (count > destMax) { + SECUREC_ERROR_INVALID_PARAMTER("wmemcpy_s"); + if (dest != NULL) { + (void)memset(dest, 0, destMax * sizeof(wchar_t)); + return ERANGE_AND_RESET; + } + return ERANGE; + } + return memcpy_s(dest, destMax * sizeof(wchar_t), src, count * sizeof(wchar_t)); +} + diff --git a/components/lib/libsec/src/wmemmove_s.c b/components/lib/libsec/src/wmemmove_s.c new file mode 100644 index 000000000..e66e29b73 --- /dev/null +++ b/components/lib/libsec/src/wmemmove_s.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wmemmove_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securecutil.h" + +/* + * + * The wmemmove_s function copies n successive wide characters from the object pointed + * to by src into the object pointed to by dest. + * + * + * dest Destination buffer. + * destMax Size of the destination buffer. + * src Source object. + * count Number of bytes or character to copy. + * + * + * dest is updated. + * + * + * EOK Success + * EINVAL dest is NULL and destMax != 0 and count <= destMax + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN + * EINVAL_AND_RESET dest != NULL and src is NULLL and destMax != 0 + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax + * ERANGE destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or + * (count > destMax and dest is NULL and destMax != 0 + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN) + * ERANGE_AND_RESET count > destMax and dest != NULL and destMax != 0 + * and destMax <= SECUREC_WCHAR_MEM_MAX_LEN + * + * + * If an error occured, dest will be filled with 0 when dest and destMax valid. + * If some regions of the source area and the destination overlap, wmemmove_s + * ensures that the original source bytes in the overlapping region are copied + * before being overwritten + */ +errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count) +{ + if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) { + SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s"); + return ERANGE; + } + if (count > destMax) { + SECUREC_ERROR_INVALID_PARAMTER("wmemmove_s"); + if (dest != NULL) { + (void)memset(dest, 0, destMax * sizeof(wchar_t)); + return ERANGE_AND_RESET; + } + return ERANGE; + } + return memmove_s(dest, destMax * sizeof(wchar_t), src, count * sizeof(wchar_t)); +} + diff --git a/components/lib/libsec/src/wscanf_s.c b/components/lib/libsec/src/wscanf_s.c new file mode 100644 index 000000000..0a3df7768 --- /dev/null +++ b/components/lib/libsec/src/wscanf_s.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: wscanf_s function + * Author: lishunda + * Create: 2014-02-25 + */ + +#include "securec.h" + +/* + * + * + * The wscanf_s function is the wide-character equivalent of the scanf_s function + * The wscanf_s function reads data from the standard input stream stdin and + * writes the data into the location that's given by argument. Each argument + * must be a pointer to a variable of a type that corresponds to a type specifier + * in format. If copying occurs between strings that overlap, the behavior is + * undefined. + * + * + * format Format control string. + * ... Optional arguments. + * + * + * ... the converted value stored in user assigned address + * + * + * Returns the number of fields successfully converted and assigned; + * the return value does not include fields that were read but not assigned. + * A return value of 0 indicates that no fields were assigned. + * return -1 if an error occurs. + */ +int wscanf_s(const wchar_t *format, ...) +{ + int ret; /* If initialization causes e838 */ + va_list argList; + + va_start(argList, format); + ret = vwscanf_s(format, argList); + va_end(argList); + (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ + + return ret; +} + diff --git a/components/net/at_device/nb_bc95/bc95.c b/components/net/at_device/nb_bc95/bc95.c index e55c7cddf..001b75482 100644 --- a/components/net/at_device/nb_bc95/bc95.c +++ b/components/net/at_device/nb_bc95/bc95.c @@ -39,15 +39,11 @@ //#include "bc95_test.h" - - - extern at_task at; at_adaptor_api bc95_interface; extern char rbuf[AT_DATA_LEN]; extern char wbuf[AT_DATA_LEN]; - typedef struct { uint32_t data_len; diff --git a/components/net/at_frame/at_main.c b/components/net/at_frame/at_main.c index 517bd46da..04a15cf21 100644 --- a/components/net/at_frame/at_main.c +++ b/components/net/at_frame/at_main.c @@ -40,8 +40,8 @@ #ifdef WITH_SOTA #include "sota/sota.h" #endif -#include "los_sys.ph" -#include "los_tick.ph" +#include "los_sys_pri.h" +#include "los_tick.h" static at_config at_user_conf; @@ -842,21 +842,18 @@ int32_t at_init(at_config *config) void at_deinit(void) { - - int cnt = 0; const int max_try_num = 10; + TSK_INFO_S stTaskInfo; - - while(LOS_TaskNameGet(at.tsk_hdl) != NULL && cnt < max_try_num) + while(LOS_TaskInfoGet(at.tsk_hdl, &stTaskInfo) != LOS_OK && cnt < max_try_num) { write_at_task_msg(AT_TASK_QUIT); LOS_TaskDelay(1000); cnt++; } - - if (LOS_TaskNameGet(at.tsk_hdl) != NULL) + if (LOS_TaskInfoGet(at.tsk_hdl, &stTaskInfo) != LOS_OK) { if(LOS_OK != LOS_TaskDelete(at.tsk_hdl)) { diff --git a/demos/agenttiny_lwm2m/agent_tiny_demo.h b/demos/agenttiny_lwm2m/agent_tiny_demo.h index f5bc149bb..eb7b465d7 100644 --- a/demos/agenttiny_lwm2m/agent_tiny_demo.h +++ b/demos/agenttiny_lwm2m/agent_tiny_demo.h @@ -36,7 +36,7 @@ #define __AGENT_TINY_DEMO_H_ #include "los_base.h" -#include "los_task.ph" +#include "los_task.h" #include "los_typedef.h" #include "los_sys.h" #include "atiny_lwm2m/agenttiny.h" diff --git a/demos/fs/fs_common.h b/demos/fs/fs_common.h index 39c8da275..9ef69ddfb 100644 --- a/demos/fs/fs_common.h +++ b/demos/fs/fs_common.h @@ -36,7 +36,7 @@ #define __FS_DEMO_H__ #include #include -#include "los_task.ph" +#include "los_task.h" #include "hal_spi_flash.h" #include "fs/sys/fcntl.h" #include "fs/los_vfs.h" diff --git a/demos/kernel/include/los_demo_debug.h b/demos/kernel/include/los_demo_debug.h index ea7a8859b..4eee7c595 100644 --- a/demos/kernel/include/los_demo_debug.h +++ b/demos/kernel/include/los_demo_debug.h @@ -39,7 +39,6 @@ #ifndef _LOS_DEMO_DEBUG_H #define _LOS_DEMO_DEBUG_H -#include "target_config.h" #include "los_typedef.h" #include diff --git a/demos/nbiot_without_atiny/sota_demo.c b/demos/nbiot_without_atiny/sota_demo.c index d4f7aa227..73ad7ea4b 100644 --- a/demos/nbiot_without_atiny/sota_demo.c +++ b/demos/nbiot_without_atiny/sota_demo.c @@ -133,7 +133,11 @@ void nb_sota_demo(void) flash_op.ota_info.key.rsa_N = "C94BECB7BCBFF459B9A71F12C3CC0603B11F0D3A366A226FD3E73D453F96EFBBCD4DFED6D9F77FD78C3AB1805E1BD3858131ACB5303F61AF524F43971B4D429CB847905E68935C1748D0096C1A09DD539CE74857F9FDF0B0EA61574C5D76BD9A67681AC6A9DB1BB22F17120B1DBF3E32633DCE34F5446F52DD7335671AC3A1F21DC557FA4CE9A4E0E3E99FED33A0BAA1C6F6EE53EDD742284D6582B51E4BF019787B8C33C2F2A095BEED11D6FE68611BD00825AF97DB985C62C3AE0DC69BD7D0118E6D620B52AFD514AD5BFA8BAB998332213D7DBF5C98DC86CB8D4F98A416802B892B8D6BEE5D55B7E688334B281E4BEDDB11BD7B374355C5919BA5A9A1C91F"; flash_op.ota_info.key.rsa_E = "10001"; hal_init_ota(); +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) LOS_SwtmrCreate(SOTA_MAX_TIME_OUT, LOS_SWTMR_MODE_NO_SELFDELETE, (SWTMR_PROC_FUNC)sota_timeout_handler, &g_sota_timer, 1, OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_SENSITIVE); +#else + LOS_SwtmrCreate(SOTA_MAX_TIME_OUT, LOS_SWTMR_MODE_NO_SELFDELETE, (SWTMR_PROC_FUNC)sota_timeout_handler, &g_sota_timer, 1); +#endif sota_init(&flash_op); (void)at.oob_register("+NNMI:", strlen("+NNMI:"), sota_callback, sota_cmd_match); } diff --git a/doc/Huawei_LiteOS_Developer_Guide_zh.md b/doc/Huawei_LiteOS_Developer_Guide_zh.md index 3f163f0b5..ad3264595 100644 --- a/doc/Huawei_LiteOS_Developer_Guide_zh.md +++ b/doc/Huawei_LiteOS_Developer_Guide_zh.md @@ -6,21 +6,21 @@ * [2.å‰è¨€](#2) * [3.概述](#3) * [4.基础内核](#4) -* [4.1.任务](#4.1) -* [4.2.内存](#4.2) -* [4.3.中断机制](#4.3) -* [4.4.队列](#4.4) -* [4.5.事件](#4.5) -* [4.6.互斥é”](#4.6) -* [4.7.ä¿¡å·é‡](#4.7) -* [4.8时间管ç†](#4.8) -* [4.9.软件定时器](#4.9) -* [4.10.åŒå‘链表](#4.10) -* [5.Agent Tiny](#5) +* [4.1.任务](#5) +* [4.2.内存](#6) +* [4.3.中断机制](#7) +* [4.4.队列](#8) +* [4.5.事件](#9) +* [4.6.互斥é”](#10) +* [4.7.ä¿¡å·é‡](#11) +* [4.8.时间管ç†](#12) +* [4.9.软件定时器](#13) +* [4.10.错误处ç†](#14) +* [4.11.åŒå‘链表](#15) -

    1.知识共享许å¯å议说明

    +

    1.知识共享许å¯å议说明

    **您å¯ä»¥è‡ªç”±åœ°ï¼š** @@ -48,11 +48,10 @@ 未æä¾›ä¿è¯ã€‚本授æƒæ¡æ¬¾æœªå¿…能完全æ供您预期用途所需è¦çš„所有许å¯ã€‚例如:形象æƒã€éšç§æƒã€è‘—作人格æƒç­‰å…¶ä»–æƒåˆ©ï¼Œå¯èƒ½é™åˆ¶æ‚¨å¦‚何使用本素æ。 -![](./meta/DevGuide/icon_notice.png) -为了方便用户ç†è§£ï¼Œè¿™æ˜¯å议的概述. å¯ä»¥è®¿é—®ç½‘å€äº†è§£å®Œæ•´å议内容。 +>![](public_sys-resources/icon-notice.gif) **须知:** +>为了方便用户ç†è§£ï¼Œè¿™æ˜¯å议的概述。å¯ä»¥è®¿é—®ç½‘å€äº†è§£å®Œæ•´å议内容。 - -

    2.å‰è¨€

    +

    2.å‰è¨€

    **目的** @@ -75,90 +74,189 @@ |![](./meta/DevGuide/icon_warning.png)| 用于警示潜在的å±é™©æƒ…形,若ä¸é¿å…,å¯èƒ½ä¼šå¯¼è‡´äººå‘˜æ­»äº¡æˆ–严é‡çš„人身伤害 | |![](./meta/DevGuide/icon_careful.png)| 用于警示潜在的å±é™©æƒ…形,若ä¸é¿å…,å¯èƒ½ä¼šå¯¼è‡´ä¸­åº¦æˆ–轻微的人身伤害 | |![](./meta/DevGuide/icon_notice.png)| 用于传递设备或环境安全警示信æ¯ï¼Œè‹¥ä¸é¿å…,å¯èƒ½ä¼šå¯¼è‡´è®¾å¤‡æŸåã€æ•°æ®ä¸¢å¤±ã€è®¾å¤‡æ€§èƒ½é™ä½Žæˆ–其它ä¸å¯é¢„知的结果,“注æ„â€ä¸æ¶‰åŠäººèº«ä¼¤å®³ | -|**说明** | “说明â€ä¸æ˜¯å®‰å…¨è­¦ç¤ºä¿¡æ¯ï¼Œä¸æ¶‰åŠäººèº«ã€è®¾å¤‡åŠçŽ¯å¢ƒä¼¤å®³ä¿¡æ¯ | +|![](./meta/DevGuide/icon_note.png)| “说明â€ä¸æ˜¯å®‰å…¨è­¦ç¤ºä¿¡æ¯ï¼Œä¸æ¶‰åŠäººèº«ã€è®¾å¤‡åŠçŽ¯å¢ƒä¼¤å®³ä¿¡æ¯ | -**修订记录** -修改记录累积了æ¯æ¬¡æ–‡æ¡£æ›´æ–°çš„说明,最新版本的文档包å«ä»¥å‰æ‰€æœ‰æ–‡æ¡£ç‰ˆæœ¬çš„更新内容。 -| 日期 | 修订版本 | æè¿° | -| - | :- | :- | -| 2018å¹´03月30æ—¥ | V2.1.1 | 社区开æºç‰ˆæœ¬ | +

    3.概述

    +Huawei LiteOS 是åŽä¸ºé¢å‘物è”网领域开å‘的一个基于实时内核的轻é‡çº§æ“作系统。基础内核支æŒä»»åŠ¡ç®¡ç†ã€å†…存管ç†ã€æ—¶é—´ç®¡ç†ã€é€šä¿¡æœºåˆ¶ã€ä¸­æ–­ç®¡ç†ã€é˜Ÿåˆ—管ç†ã€äº‹ä»¶ç®¡ç†ã€å®šæ—¶å™¨ç­‰æ“作系统基础组件,更好地支æŒä½ŽåŠŸè€—åœºæ™¯ï¼Œæ”¯æŒ Tickless 机制,支æŒå®šæ—¶å™¨å¯¹é½ã€‚ -

    3.概述

    +Huawei LiteOS 自开æºç¤¾åŒºå‘布以æ¥ï¼Œå›´ç»• NB-IoT 物è”网市场从技术ã€ç”Ÿæ€ã€è§£å†³æ–¹æ¡ˆã€å•†ç”¨æ”¯æŒç­‰å¤šç»´åº¦ä½¿èƒ½åˆä½œä¼™ä¼´ï¼Œæž„建开æºçš„物è”网生æ€,ç›®å‰å·²ç»èšåˆäº† 50+ MCU 和解决方案åˆä½œä¼™ä¼´ï¼Œå…±åŒæŽ¨å‡ºä¸€æ‰¹å¼€æºå¼€å‘套件和行业解决方案,帮助众多行业客户快速的推出物è”网终端和æœåŠ¡ï¼Œå®¢æˆ·æ¶µç›–抄表ã€åœè½¦ã€è·¯ç¯ã€çŽ¯ä¿ã€å…±äº«å•è½¦ã€ç‰©æµç­‰ä¼—多行业,为开å‘者æä¾› “一站å¼â€ 完整软件平å°ï¼Œæœ‰æ•ˆé™ä½Žå¼€å‘门槛ã€ç¼©çŸ­å¼€å‘周期。 ### èƒŒæ™¯ä»‹ç» -Huawei LiteOS是轻é‡çº§çš„实时æ“作系统,是åŽä¸ºIOT OS。 - -Huawei LiteOS Kernel的基本框架图: +Huawei LiteOS是轻é‡çº§çš„实时æ“作系统,是åŽä¸ºIoT OS。 -![](./meta/DevGuide/pic1.png) +**图 1** Huawei LiteOS Kernel的基本框架图 +![](figures/Huawei-LiteOS-Kernel的基本框架图.png "Huawei-LiteOS-Kernel的基本框架图") Huawei LiteOS基础内核是最精简的Huawei LiteOSæ“作系统代ç ï¼ŒåŒ…括任务管ç†ã€å†…存管ç†ã€æ—¶é—´ç®¡ç†ã€é€šä¿¡æœºåˆ¶ã€ä¸­æ–­ç®¡ç†ã€é˜Ÿåˆ—管ç†ã€äº‹ä»¶ç®¡ç†ã€å®šæ—¶å™¨ç­‰æ“作系统基础组件,å¯ä»¥å•ç‹¬è¿è¡Œã€‚ -**Huawei LiteOS Kernel的优势** +## Huawei LiteOS Kernel的优势 -高实时性,高稳定性。 +- 高实时性,高稳定性。 +- 超å°å†…核,基础内核体积å¯ä»¥è£å‰ªè‡³ä¸åˆ°10K。 +- 低功耗。 +- 支æŒåŠŸèƒ½é™æ€è£å‰ªã€‚ -超å°å†…核,基础内核体积å¯ä»¥è£å‰ªè‡³ä¸åˆ°10K。 +## å„模å—简介 -低功耗。 +**任务** -支æŒåŠ¨æ€åŠ è½½ã€åˆ†æ•£åŠ è½½ã€‚ +æ供任务的创建ã€åˆ é™¤ã€å»¶è¿Ÿã€æŒ‚èµ·ã€æ¢å¤ç­‰åŠŸèƒ½ï¼Œä»¥åŠé”定和解é”任务调度。支æŒä»»åŠ¡æŒ‰ä¼˜å…ˆçº§é«˜ä½Žçš„抢å è°ƒåº¦åŠåŒä¼˜å…ˆçº§æ—¶é—´ç‰‡è½®è½¬è°ƒåº¦ã€‚ -支æŒåŠŸèƒ½é™æ€è£å‰ªã€‚ +**任务åŒæ­¥** -å„模å—简介 +- ä¿¡å·é‡ï¼šæ”¯æŒä¿¡å·é‡çš„创建ã€åˆ é™¤ã€ç”³è¯·å’Œé‡Šæ”¾ç­‰åŠŸèƒ½ã€‚ +- 互斥é”:支æŒäº’æ–¥é”的创建ã€åˆ é™¤ã€ç”³è¯·å’Œé‡Šæ”¾ç­‰åŠŸèƒ½ã€‚ +**硬件相关** -**任务** -æ供任务的创建ã€åˆ é™¤ã€å»¶è¿Ÿã€æŒ‚èµ·ã€æ¢å¤ç­‰åŠŸèƒ½ï¼Œä»¥åŠé”定和解é”任务调度。支æŒä»»åŠ¡æŒ‰ä¼˜å…ˆçº§é«˜ä½Žçš„抢å è°ƒåº¦åŠåŒä¼˜å…ˆçº§æ—¶é—´ç‰‡è½®è½¬è°ƒåº¦ã€‚ +æ供中断ã€å®šæ—¶å™¨ç­‰åŠŸèƒ½ã€‚ -**任务åŒæ­¥** -- ä¿¡å·é‡ï¼šæ”¯æŒä¿¡å·é‡çš„创建ã€åˆ é™¤ã€ç”³è¯·å’Œé‡Šæ”¾ç­‰åŠŸèƒ½ã€‚ -- 互斥é”:支æŒäº’æ–¥é”的创建ã€åˆ é™¤ã€ç”³è¯·å’Œé‡Šæ”¾ç­‰åŠŸèƒ½ã€‚ +- 中断:æ供中断的创建ã€åˆ é™¤ã€ä½¿èƒ½ã€ç¦æ­¢ã€è¯·æ±‚ä½çš„清除等功能。 +- 定时器:æ供定时器的创建ã€åˆ é™¤ã€å¯åŠ¨ã€åœæ­¢ç­‰åŠŸèƒ½ã€‚ -**硬件相关** -æ供中断ã€å®šæ—¶å™¨ç­‰åŠŸèƒ½ã€‚ -- 中断:æ供中断的创建ã€åˆ é™¤ã€ä½¿èƒ½ã€ç¦æ­¢ã€è¯·æ±‚ä½çš„清除等功能。 -- 定时器:æ供定时器的创建ã€åˆ é™¤ã€å¯åŠ¨ã€åœæ­¢ç­‰åŠŸèƒ½ã€‚ +**IPC通信** -**IPC通信** -æ供事件ã€æ¶ˆæ¯é˜Ÿåˆ—功能。 -- 事件:支æŒè¯»äº‹ä»¶å’Œå†™äº‹ä»¶åŠŸèƒ½ã€‚ -- 消æ¯é˜Ÿåˆ—:支æŒæ¶ˆæ¯é˜Ÿåˆ—的创建ã€åˆ é™¤ã€å‘é€å’ŒæŽ¥æ”¶åŠŸèƒ½ã€‚ +æ供事件ã€æ¶ˆæ¯é˜Ÿåˆ—功能。 -**时间管ç†** -- 系统时间:系统时间是由定时/计数器产生的输出脉冲触å‘中断而产生的。 -- Tick时间:Tick是æ“作系统调度的基本时间å•ä½ï¼Œå¯¹åº”的时长由系统主频åŠæ¯ç§’Tick数决定,由用户é…置。 -- 软件定时器:以Tick为å•ä½çš„定时器功能,软件定时器的超时处ç†å‡½æ•°åœ¨ç³»ç»Ÿåˆ›å»ºçš„Tick软中断中被调用。 +- 事件:支æŒè¯»äº‹ä»¶å’Œå†™äº‹ä»¶åŠŸèƒ½ã€‚ +- 消æ¯é˜Ÿåˆ—:支æŒæ¶ˆæ¯é˜Ÿåˆ—的创建ã€åˆ é™¤ã€å‘é€å’ŒæŽ¥æ”¶åŠŸèƒ½ã€‚ -**内存管ç†** -- æä¾›é™æ€å†…存和动æ€å†…存两ç§ç®—法,支æŒå†…存申请ã€é‡Šæ”¾ã€‚ç›®å‰æ”¯æŒçš„内存管ç†ç®—法有固定大å°çš„BOX算法ã€åŠ¨æ€ç”³è¯·SLABã€DLINK算法。 -- æ供内存统计ã€å†…存越界检测功能。 +**时间管ç†** -### 支æŒçš„æ ¸ +- 系统时间:系统时间是由定时/计数器产生的输出脉冲触å‘中断而产生的。 +- Tick时间:Tick是æ“作系统调度的基本时间å•ä½ï¼Œå¯¹åº”的时长由系统主频åŠæ¯ç§’Tick数决定,由用户é…置。 +- 软件定时器:以Tick为å•ä½çš„定时器功能,软件定时器的超时处ç†å‡½æ•°åœ¨ç³»ç»Ÿåˆ›å»ºçš„Tick软中断中被调用。 + +**内存管ç†** -Huawei LiteOSå¼€æºKernel支æŒçš„æ ¸ +- æä¾›é™æ€å†…存和动æ€å†…存两ç§ç®—法,支æŒå†…存申请ã€é‡Šæ”¾ã€‚ç›®å‰æ”¯æŒçš„内存管ç†ç®—法有固定大å°çš„BOX算法ã€åŠ¨æ€ç”³è¯·SLABã€DLINK算法。 +- æ供内存统计ã€å†…存越界检测功能。 -| 支æŒçš„æ ¸ | 芯片 | -|-----------|----------------------| -| Cortex-M0 | STM32L053R8Txã€ATSAMD21G18Aã€ATSAMD21J18Aã€ATSAMR21G18Aã€EFM32HG322F64ã€MKL26Z128ã€MKW41Z512ã€LPC824M201JHI33ã€MM32L073PFã€nRF51822ã€NANO130KE3BN | -| Cortex-M3 | STM32F103RBã€ATSAM4SD32Cã€EFM32GG990F1024ã€GD32F103VCT6ã€GD32150R8ã€GD32F190R8ã€GD32F207VCã€MM32F103CBT6ã€MM32L373PS | -| Cortex-M4 | STM32F411REã€STM32F412ZGã€STM32F429ZIã€STM32F429IGã€STM32L476RGã€EFM32PG1B200F256GM48 ã€GD32F450IKã€CC3220SFã€LPC54114j256BD64ã€nRF52840ã€nRF52832ã€NUC472HI8AEã€ATSAMG55J19ã€ADuCM4050LF | -| Cortex-M7 | STM32F746ZGã€ATSAME70Q21 | +### 支æŒçš„æ ¸ + +**表 1** Huawei LiteOSå¼€æºKernel支æŒçš„æ ¸ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    支æŒçš„æ ¸

    +

    芯片

    +

    Cortex-A7

    +

    Hi3516A V300

    +

    Hi3516C V500

    +

    Hi3516E V200

    +

    Hi3516E V300

    +

    Hi3516D V200

    +

    Hi3516D V300

    +

    Hi3518E V300

    +

    Hi3536

    +

    Hi3556 V100

    +

    Hi3556 V200

    +

    Hi3559 V200

    +

    Hi3716M V430

    +

    Cortex-A17

    +

    Hi3536

    +

    Hi3556 V100

    +

    Hi3559 V100

    +

    Cortex-A53

    +

    Hi3519A V100

    +

    Hi3556A V100

    +

    Hi3559A V100

    +

    Hi3796M V200

    +

    Hi3798C V200

    +

    Hi3798M V200

    +

    Hi3798M V300

    +

    Hi3798M V310

    +

    Cortex-M0

    +

    STM32L053R8Tx

    +

    ATSAMD21G18A

    +

    ATSAMD21J18A

    +

    ATSAMR21G18A

    +

    EFM32HG322F64

    +

    MKL26Z128

    +

    MKW41Z512

    +

    LPC824M201JHI33

    +

    MM32L073PF

    +

    nRF51822

    +

    NANO130KE3BN

    +

    Cortex-M3

    +

    K3V3,K3V3+

    +

    STM32F103RB

    +

    ATSAM4SD32C

    +

    EFM32GG990F1024

    +

    GD32F103VCT6

    +

    GD32150R8

    +

    GD32F190R8

    +

    GD32F207VC

    +

    MM32F103CBT6

    +

    MM32L373PS

    +

    Cortex-M4

    +

    STM32F411RE

    +

    STM32F412ZG

    +

    STM32F429ZI

    +

    STM32F429IG

    +

    STM32L476RG

    +

    EFM32PG1B200F256GM48

    +

    GD32F450IK

    +

    CC3220SF

    +

    LPC54114j256BD64

    +

    nRF52840

    +

    nRF52832

    +

    NUC472HI8AE

    +

    ATSAMG55J19

    +

    ADuCM4050LF

    +

    Cortex-M7

    +

    K3V5

    +

    STM32F746ZG

    +

    ATSAME70Q21

    +

    ARM9

    +

    Hi3516C V200

    +

    Hi3516C V300

    +

    Hi3516E V100

    +

    Hi3518E V200

    +

    Hi3911

    +
    ### ä½¿ç”¨çº¦æŸ -- Huawei LiteOSæ供一套Huawei LiteOS接å£ï¼ŒåŒæ—¶æ”¯æŒCMSIS接å£ï¼Œå®ƒä»¬åŠŸèƒ½ä¸€è‡´ï¼Œä½†æ··ç”¨CMSISå’ŒHuawei LiteOS接å£å¯èƒ½ä¼šå¯¼è‡´ä¸å¯é¢„知的错误,例如用CMSIS接å£ç”³è¯·ä¿¡å·é‡ï¼Œä½†ç”¨Huawei LiteOS接å£é‡Šæ”¾ä¿¡å·é‡ã€‚ -- å¼€å‘驱动程åºåªèƒ½ç”¨Huawei LiteOS的接å£ï¼Œä¸Šå±‚APP建议用CMSIS接å£ã€‚ +- Huawei LiteOSæ供一套Huawei LiteOS接å£ï¼ŒåŒæ—¶æ”¯æŒCMSIS接å£ï¼Œå®ƒä»¬åŠŸèƒ½ä¸€è‡´ï¼Œä½†æ··ç”¨CMSISå’ŒHuawei LiteOS接å£å¯èƒ½ä¼šå¯¼è‡´ä¸å¯é¢„知的错误,例如用CMSIS接å£ç”³è¯·ä¿¡å·é‡ï¼Œä½†ç”¨Huawei LiteOS接å£é‡Šæ”¾ä¿¡å·é‡ã€‚ +- å¼€å‘驱动程åºåªèƒ½ç”¨Huawei LiteOS的接å£ï¼Œä¸Šå±‚APP建议用CMSIS接å£ã€‚

    4.基础内核

    -

    4.1 任务

    +

    4.1 任务

    ### 概述 @@ -175,202 +273,682 @@ Huawei LiteOS的任务一共有32个优先级(0-31),最高优先级为0,最 **任务状æ€** -Huawei LiteOS系统中的æ¯ä¸€ä»»åŠ¡éƒ½æœ‰å¤šç§è¿è¡ŒçŠ¶æ€ã€‚系统åˆå§‹åŒ–完æˆåŽï¼Œåˆ›å»ºçš„任务就å¯ä»¥åœ¨ç³»ç»Ÿä¸­ç«žäº‰ä¸€å®šçš„资æºï¼Œç”±å†…核进行调度。 - -任务状æ€é€šå¸¸åˆ†ä¸ºä»¥ä¸‹å››ç§ï¼š - -- 就绪(Ready):该任务在就绪列表中,åªç­‰å¾…CPU。 -- è¿è¡Œï¼ˆRunning):该任务正在执行。 -- 阻塞(Blocked):该任务ä¸åœ¨å°±ç»ªåˆ—表中。包å«ä»»åŠ¡è¢«æŒ‚èµ·ã€ä»»åŠ¡è¢«å»¶æ—¶ã€ä»»åŠ¡æ­£åœ¨ç­‰å¾…ä¿¡å·é‡ã€è¯»å†™é˜Ÿåˆ—或者等待读写事件等。 -- 退出æ€ï¼ˆDead):该任务è¿è¡Œç»“æŸï¼Œç­‰å¾…系统回收资æºã€‚ +Huawei LiteOS系统中的æ¯ä¸€ä»»åŠ¡éƒ½æœ‰å¤šç§è¿è¡ŒçŠ¶æ€ã€‚系统åˆå§‹åŒ–完æˆåŽï¼Œåˆ›å»ºçš„任务就å¯ä»¥åœ¨ç³»ç»Ÿä¸­ç«žäº‰ä¸€å®šçš„资æºï¼Œç”±å†…核进行调度。 -![](./meta/DevGuide/pic2.png) +任务状æ€é€šå¸¸åˆ†ä¸ºä»¥ä¸‹å››ç§ï¼š -任务状æ€ç¤ºæ„图 +- 就绪(Ready):该任务在就绪列表中,åªç­‰å¾…CPU。 +- è¿è¡Œï¼ˆRunning):该任务正在执行。 +- 阻塞(Blocked):该任务ä¸åœ¨å°±ç»ªåˆ—表中。包å«ä»»åŠ¡è¢«æŒ‚èµ·ã€ä»»åŠ¡è¢«å»¶æ—¶ã€ä»»åŠ¡æ­£åœ¨ç­‰å¾…ä¿¡å·é‡ã€è¯»å†™é˜Ÿåˆ—或者等待读写事件等。 +- 退出æ€ï¼ˆDead):该任务è¿è¡Œç»“æŸï¼Œç­‰å¾…系统回收资æºã€‚ +**图 1** 任务状æ€ç¤ºæ„图 +![](figures/任务状æ€ç¤ºæ„图.png "任务状æ€ç¤ºæ„图") -**任务状æ€è¿ç§»è¯´æ˜Ž** +任务状æ€è¿ç§»è¯´æ˜Žï¼š -**就绪æ€â†’è¿è¡Œæ€ï¼š** +- 就绪æ€â†’è¿è¡Œæ€ï¼š -任务创建åŽè¿›å…¥å°±ç»ªæ€ï¼Œå‘生任务切æ¢æ—¶ï¼Œå°±ç»ªåˆ—表中最高优先级的任务被执行,从而进入è¿è¡Œæ€ï¼Œä½†æ­¤åˆ»è¯¥ä»»åŠ¡ä¾æ—§åœ¨å°±ç»ªåˆ—表中。 +任务创建åŽè¿›å…¥å°±ç»ªæ€ï¼Œå‘生任务切æ¢æ—¶ï¼Œå°±ç»ªåˆ—表中最高优先级的任务被执行,从而进入è¿è¡Œæ€ï¼Œä½†æ­¤åˆ»è¯¥ä»»åŠ¡ä¾æ—§åœ¨å°±ç»ªåˆ—表中。 -**è¿è¡Œæ€â†’阻塞æ€ï¼š** +- è¿è¡Œæ€â†’阻塞æ€ï¼š -正在è¿è¡Œçš„任务å‘生阻塞(挂起ã€å»¶æ—¶ã€èŽ·å–互斥é”ã€è¯»æ¶ˆæ¯ã€è¯»ä¿¡å·é‡ç­‰å¾…等)时,该任务会从就绪列表中删除,任务状æ€ç”±è¿è¡Œæ€å˜æˆé˜»å¡žæ€ï¼Œç„¶åŽå‘生任务切æ¢ï¼Œè¿è¡Œå°±ç»ªåˆ—表中剩余最高优先级任务。 +正在è¿è¡Œçš„任务å‘生阻塞(挂起ã€å»¶æ—¶ã€èŽ·å–互斥é”ã€è¯»æ¶ˆæ¯ã€è¯»ä¿¡å·é‡ç­‰å¾…等)时,该任务会从就绪列表中删除,任务状æ€ç”±è¿è¡Œæ€å˜æˆé˜»å¡žæ€ï¼Œç„¶åŽå‘生任务切æ¢ï¼Œè¿è¡Œå°±ç»ªåˆ—表中剩余最高优先级任务。 -**阻塞æ€â†’就绪æ€ï¼ˆé˜»å¡žæ€â†’è¿è¡Œæ€ï¼‰ï¼š** +- 阻塞æ€â†’就绪æ€ï¼ˆé˜»å¡žæ€â†’è¿è¡Œæ€ï¼‰ï¼š -阻塞的任务被æ¢å¤åŽï¼ˆä»»åŠ¡æ¢å¤ã€å»¶æ—¶æ—¶é—´è¶…æ—¶ã€è¯»ä¿¡å·é‡è¶…时或读到信å·é‡ç­‰ï¼‰ï¼Œæ­¤æ—¶è¢«æ¢å¤çš„任务会被加入就绪列表,从而由阻塞æ€å˜æˆå°±ç»ªæ€ï¼›æ­¤æ—¶å¦‚果被æ¢å¤ä»»åŠ¡çš„优先级高于正在è¿è¡Œä»»åŠ¡çš„优先级,则会å‘生任务切æ¢ï¼Œå°†è¯¥ä»»åŠ¡ç”±å°±ç»ªæ€å˜æˆè¿è¡Œæ€ã€‚ +阻塞的任务被æ¢å¤åŽï¼ˆä»»åŠ¡æ¢å¤ã€å»¶æ—¶æ—¶é—´è¶…æ—¶ã€è¯»ä¿¡å·é‡è¶…时或读到信å·é‡ç­‰ï¼‰ï¼Œæ­¤æ—¶è¢«æ¢å¤çš„任务会被加入就绪列表,从而由阻塞æ€å˜æˆå°±ç»ªæ€ï¼›æ­¤æ—¶å¦‚果被æ¢å¤ä»»åŠ¡çš„优先级高于正在è¿è¡Œä»»åŠ¡çš„优先级,则会å‘生任务切æ¢ï¼Œå°†è¯¥ä»»åŠ¡ç”±å°±ç»ªæ€å˜æˆè¿è¡Œæ€ã€‚ -**就绪æ€â†’阻塞æ€ï¼š** +- 就绪æ€â†’阻塞æ€ï¼š -任务也有å¯èƒ½åœ¨å°±ç»ªæ€æ—¶è¢«é˜»å¡žï¼ˆæŒ‚起),此时任务状æ€ä¼šç”±å°±ç»ªæ€è½¬å˜ä¸ºé˜»å¡žæ€ï¼Œè¯¥ä»»åŠ¡ä»Žå°±ç»ªåˆ—表中删除,ä¸ä¼šå‚与任务调度,直到该任务被æ¢å¤ã€‚ +任务也有å¯èƒ½åœ¨å°±ç»ªæ€æ—¶è¢«é˜»å¡žï¼ˆæŒ‚起),此时任务状æ€ä¼šç”±å°±ç»ªæ€è½¬å˜ä¸ºé˜»å¡žæ€ï¼Œè¯¥ä»»åŠ¡ä»Žå°±ç»ªåˆ—表中删除,ä¸ä¼šå‚与任务调度,直到该任务被æ¢å¤ã€‚ -**è¿è¡Œæ€â†’就绪æ€ï¼š** +- è¿è¡Œæ€â†’就绪æ€ï¼š -有更高优先级任务创建或者æ¢å¤åŽï¼Œä¼šå‘生任务调度,此刻就绪列表中最高优先级任务å˜ä¸ºè¿è¡Œæ€ï¼Œé‚£ä¹ˆåŽŸå…ˆè¿è¡Œçš„任务由è¿è¡Œæ€å˜ä¸ºå°±ç»ªæ€ï¼Œä¾ç„¶åœ¨å°±ç»ªåˆ—表中。 +有更高优先级任务创建或者æ¢å¤åŽï¼Œä¼šå‘生任务调度,此刻就绪列表中最高优先级任务å˜ä¸ºè¿è¡Œæ€ï¼Œé‚£ä¹ˆåŽŸå…ˆè¿è¡Œçš„任务由è¿è¡Œæ€å˜ä¸ºå°±ç»ªæ€ï¼Œä¾ç„¶åœ¨å°±ç»ªåˆ—表中。 -**è¿è¡Œæ€â†’退出æ€:** +- è¿è¡Œæ€â†’é€€å‡ºæ€ -è¿è¡Œä¸­çš„任务è¿è¡Œç»“æŸï¼Œå†…核自动将此任务删除,任务状æ€ç”±è¿è¡Œæ€å˜ä¸ºé€€å‡ºæ€ã€‚ +è¿è¡Œä¸­çš„任务è¿è¡Œç»“æŸï¼Œä»»åŠ¡çŠ¶æ€ç”±è¿è¡Œæ€å˜ä¸ºé€€å‡ºæ€ã€‚退出æ€åŒ…å«ä»»åŠ¡è¿è¡Œç»“æŸçš„正常退出以åŠInvalid状æ€ã€‚例如,未设置分离属性(LOS\_TASK\_STATUS\_DETACHED)的任务,è¿è¡Œç»“æŸåŽå¯¹å¤–呈现的是Invalid状æ€ï¼Œå³é€€å‡ºæ€ã€‚ -**阻塞æ€â†’退出æ€:** +- 阻塞æ€â†’é€€å‡ºæ€ -阻塞的任务调用删除接å£ï¼Œä»»åŠ¡çŠ¶æ€ç”±é˜»å¡žæ€å˜ä¸ºé€€å‡ºæ€ã€‚ +阻塞的任务调用删除接å£ï¼Œä»»åŠ¡çŠ¶æ€ç”±é˜»å¡žæ€å˜ä¸ºé€€å‡ºæ€ã€‚ -**任务ID** +**任务ID** -任务ID,在任务创建时通过å‚数返回给用户,作为任务的一个éžå¸¸é‡è¦çš„标识。用户å¯ä»¥é€šè¿‡ä»»åŠ¡ID对指定任务进行任务挂起ã€ä»»åŠ¡æ¢å¤ã€æŸ¥è¯¢ä»»åŠ¡åç­‰æ“作。 +任务ID,在任务创建时通过å‚数返回给用户,作为任务的一个éžå¸¸é‡è¦çš„标识。用户å¯ä»¥é€šè¿‡ä»»åŠ¡ID对指定任务进行任务挂起ã€ä»»åŠ¡æ¢å¤ã€æŸ¥è¯¢ä»»åŠ¡åç­‰æ“作。 -**任务优先级** +**任务优先级** -优先级表示任务执行的优先顺åºã€‚任务的优先级决定了在å‘生任务切æ¢æ—¶å³å°†è¦æ‰§è¡Œçš„任务。在就绪列表中的最高优先级的任务将得到执行。 +优先级表示任务执行的优先顺åºã€‚任务的优先级决定了在å‘生任务切æ¢æ—¶å³å°†è¦æ‰§è¡Œçš„任务。在就绪列表中的最高优先级的任务将得到执行。 -**任务入å£å‡½æ•°** +**任务入å£å‡½æ•°** -æ¯ä¸ªæ–°ä»»åŠ¡å¾—到调度åŽå°†æ‰§è¡Œçš„函数。该函数由用户实现,在任务创建时,通过任务创建结构体指定。 +æ¯ä¸ªæ–°ä»»åŠ¡å¾—到调度åŽå°†æ‰§è¡Œçš„函数。该函数由用户实现,在任务创建时,通过任务创建结构体指定。 -**任务控制å—TCB** +**任务控制å—TCB** -æ¯ä¸€ä¸ªä»»åŠ¡éƒ½å«æœ‰ä¸€ä¸ªä»»åŠ¡æŽ§åˆ¶å—(TCB)。TCB包å«äº†ä»»åŠ¡ä¸Šä¸‹æ–‡æ ˆæŒ‡é’ˆï¼ˆstack pointer)ã€ä»»åŠ¡çŠ¶æ€ã€ä»»åŠ¡ä¼˜å…ˆçº§ã€ä»»åŠ¡IDã€ä»»åŠ¡åã€ä»»åŠ¡æ ˆå¤§å°ç­‰ä¿¡æ¯ã€‚TCBå¯ä»¥å映出æ¯ä¸ªä»»åŠ¡è¿è¡Œæƒ…况。 +æ¯ä¸€ä¸ªä»»åŠ¡éƒ½å«æœ‰ä¸€ä¸ªä»»åŠ¡æŽ§åˆ¶å—\(TCB\)。TCB包å«äº†ä»»åŠ¡ä¸Šä¸‹æ–‡æ ˆæŒ‡é’ˆï¼ˆstack pointer)ã€ä»»åŠ¡çŠ¶æ€ã€ä»»åŠ¡ä¼˜å…ˆçº§ã€ä»»åŠ¡IDã€ä»»åŠ¡åã€ä»»åŠ¡æ ˆå¤§å°ç­‰ä¿¡æ¯ã€‚TCBå¯ä»¥å映出æ¯ä¸ªä»»åŠ¡è¿è¡Œæƒ…况。 -**任务栈** +**任务栈** -æ¯ä¸€ä¸ªä»»åŠ¡éƒ½æ‹¥æœ‰ä¸€ä¸ªç‹¬ç«‹çš„栈空间,我们称为任务栈。栈空间里ä¿å­˜çš„ä¿¡æ¯åŒ…å«å±€éƒ¨å˜é‡ã€å¯„存器ã€å‡½æ•°å‚æ•°ã€å‡½æ•°è¿”回地å€ç­‰ã€‚任务在任务切æ¢æ—¶ä¼šå°†åˆ‡å‡ºä»»åŠ¡çš„上下文信æ¯ä¿å­˜åœ¨è‡ªèº«çš„任务栈空间里é¢ï¼Œä»¥ä¾¿ä»»åŠ¡æ¢å¤æ—¶è¿˜åŽŸçŽ°åœºï¼Œä»Žè€Œåœ¨ä»»åŠ¡æ¢å¤åŽåœ¨åˆ‡å‡ºç‚¹ç»§ç»­å¼€å§‹æ‰§è¡Œã€‚ +æ¯ä¸€ä¸ªä»»åŠ¡éƒ½æ‹¥æœ‰ä¸€ä¸ªç‹¬ç«‹çš„栈空间,我们称为任务栈。栈空间里ä¿å­˜çš„ä¿¡æ¯åŒ…å«å±€éƒ¨å˜é‡ã€å¯„存器ã€å‡½æ•°å‚æ•°ã€å‡½æ•°è¿”回地å€ç­‰ã€‚任务在任务切æ¢æ—¶ä¼šå°†åˆ‡å‡ºä»»åŠ¡çš„上下文信æ¯ä¿å­˜åœ¨è‡ªèº«çš„任务栈空间里é¢ï¼Œä»¥ä¾¿ä»»åŠ¡æ¢å¤æ—¶è¿˜åŽŸçŽ°åœºï¼Œä»Žè€Œåœ¨ä»»åŠ¡æ¢å¤åŽåœ¨åˆ‡å‡ºç‚¹ç»§ç»­å¼€å§‹æ‰§è¡Œã€‚ -**任务上下文** +**任务上下文** -任务在è¿è¡Œè¿‡ç¨‹ä¸­ä½¿ç”¨åˆ°çš„一些资æºï¼Œå¦‚寄存器等,我们称为任务上下文。当这个任务挂起时,其他任务继续执行,在任务æ¢å¤åŽï¼Œå¦‚果没有把任务上下文ä¿å­˜ä¸‹æ¥ï¼Œæœ‰å¯èƒ½ä»»åŠ¡åˆ‡æ¢ä¼šä¿®æ”¹å¯„存器中的值,从而导致未知错误。 +任务在è¿è¡Œè¿‡ç¨‹ä¸­ä½¿ç”¨åˆ°çš„一些资æºï¼Œå¦‚寄存器等,我们称为任务上下文。当这个任务挂起时,其他任务继续执行,在任务æ¢å¤åŽï¼Œå¦‚果没有把任务上下文ä¿å­˜ä¸‹æ¥ï¼Œæœ‰å¯èƒ½ä»»åŠ¡åˆ‡æ¢ä¼šä¿®æ”¹å¯„存器中的值,从而导致未知错误。 -因此,Huawei LiteOS在任务挂起的时候会将本任务的任务上下文信æ¯ï¼Œä¿å­˜åœ¨è‡ªå·±çš„任务栈里é¢ï¼Œä»¥ä¾¿ä»»åŠ¡æ¢å¤åŽï¼Œä»Žæ ˆç©ºé—´ä¸­æ¢å¤æŒ‚起时的上下文信æ¯ï¼Œä»Žè€Œç»§ç»­æ‰§è¡Œè¢«æŒ‚起时被打断的代ç ã€‚ +因此,Huawei LiteOS在任务挂起的时候会将本任务的任务上下文信æ¯ï¼Œä¿å­˜åœ¨è‡ªå·±çš„任务栈里é¢ï¼Œä»¥ä¾¿ä»»åŠ¡æ¢å¤åŽï¼Œä»Žæ ˆç©ºé—´ä¸­æ¢å¤æŒ‚起时的上下文信æ¯ï¼Œä»Žè€Œç»§ç»­æ‰§è¡Œè¢«æŒ‚起时被打断的代ç ã€‚ -**任务切æ¢** +**任务切æ¢** -任务切æ¢åŒ…å«èŽ·å–就绪列表中最高优先级任务ã€åˆ‡å‡ºä»»åŠ¡ä¸Šä¸‹æ–‡ä¿å­˜ã€åˆ‡å…¥ä»»åŠ¡ä¸Šä¸‹æ–‡æ¢å¤ç­‰åŠ¨ä½œã€‚ +任务切æ¢åŒ…å«èŽ·å–就绪列表中最高优先级任务ã€åˆ‡å‡ºä»»åŠ¡ä¸Šä¸‹æ–‡ä¿å­˜ã€åˆ‡å…¥ä»»åŠ¡ä¸Šä¸‹æ–‡æ¢å¤ç­‰åŠ¨ä½œã€‚ #### è¿ä½œæœºåˆ¶ -Huawei LiteOS任务管ç†æ¨¡å—æ供任务创建ã€ä»»åŠ¡åˆ é™¤ã€ä»»åŠ¡å»¶æ—¶ã€ä»»åŠ¡æŒ‚起和任务æ¢å¤ã€æ›´æ”¹ä»»åŠ¡ä¼˜å…ˆçº§ã€é”任务调度和解é”任务调度ã€æ ¹æ®ä»»åŠ¡æŽ§åˆ¶å—查询任务IDã€æ ¹æ®ID查询任务控制å—ä¿¡æ¯åŠŸèƒ½ã€‚ +Huawei LiteOS任务管ç†æ¨¡å—æ供任务创建ã€ä»»åŠ¡å»¶æ—¶ã€ä»»åŠ¡æŒ‚起和任务æ¢å¤ã€é”任务调度和解é”任务调度ã€æ ¹æ®ID查询任务控制å—ä¿¡æ¯åŠŸèƒ½ã€‚ -在任务模å—åˆå§‹åŒ–时,系统会先申请任务控制å—需è¦çš„内存空间,如果系统å¯ç”¨çš„内存空间å°äºŽå…¶æ‰€éœ€è¦çš„内存空间,任务模å—就会åˆå§‹åŒ–失败。如果任务åˆå§‹åŒ–æˆåŠŸï¼Œåˆ™ç³»ç»Ÿå¯¹ä»»åŠ¡æŽ§åˆ¶å—内容进行åˆå§‹åŒ–。 - -用户创建任务时,系统会将任务栈进行åˆå§‹åŒ–,预置上下文。此外,系统还会将“任务入å£å‡½æ•°â€åœ°å€æ”¾åœ¨ç›¸åº”ä½ç½®ã€‚这样在任务第一次å¯åŠ¨è¿›å…¥è¿è¡Œæ€æ—¶ï¼Œå°†ä¼šæ‰§è¡Œâ€œä»»åŠ¡å…¥å£å‡½æ•°â€ã€‚ +用户创建任务时,系统会将任务栈进行åˆå§‹åŒ–,预置上下文。此外,系统还会将“任务入å£å‡½æ•°â€åœ°å€æ”¾åœ¨ç›¸åº”ä½ç½®ã€‚这样在任务第一次å¯åŠ¨è¿›å…¥è¿è¡Œæ€æ—¶ï¼Œå°†ä¼šæ‰§è¡Œâ€œä»»åŠ¡å…¥å£å‡½æ•°â€ã€‚ ### å¼€å‘指导 #### 使用场景 -任务创建åŽï¼Œå†…æ ¸å¯ä»¥æ‰§è¡Œé”任务调度,解é”任务调度,挂起,æ¢å¤ï¼Œå»¶æ—¶ç­‰æ“作,åŒæ—¶ä¹Ÿå¯ä»¥è®¾ç½®ä»»åŠ¡ä¼˜å…ˆçº§ï¼ŒèŽ·å–任务优先级。任务结æŸçš„时候,则进行当å‰ä»»åŠ¡è‡ªåˆ é™¤æ“作。 +任务创建åŽï¼Œå†…æ ¸å¯ä»¥æ‰§è¡Œé”任务调度,解é”任务调度,挂起,æ¢å¤ï¼Œå»¶æ—¶ç­‰æ“作,åŒæ—¶ä¹Ÿå¯ä»¥è®¾ç½®ä»»åŠ¡ä¼˜å…ˆçº§ï¼ŒèŽ·å–任务优先级。任务结æŸçš„时候,如果任务的状æ€æ˜¯è‡ªåˆ é™¤çŠ¶æ€ï¼ˆLOS\_TASK\_STATUS\_DETACHED),则进行当å‰ä»»åŠ¡è‡ªåˆ é™¤æ“作。 #### 功能 Huawei LiteOS 系统中的任务管ç†æ¨¡å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ -| 功能分类 | 接å£å | æè¿° | -|------------------|----------------------|-----------------------------------------------| -| 任务的创建和删除 | LOS\_TaskCreateOnly | 创建任务,并使该任务进入suspend状æ€ï¼Œå¹¶ä¸è°ƒåº¦ | -| | LOS\_TaskCreate | 创建任务,并使该任务进入ready状æ€ï¼Œå¹¶è°ƒåº¦ | -| | LOS\_TaskDelete | 删除指定的任务 | -| 任务状æ€æŽ§åˆ¶ | LOS\_TaskResume | æ¢å¤æŒ‚起的任务 | -| | LOS\_TaskSuspend | 挂起指定的任务 | -| | LOS\_TaskDelay | 任务延时等待 | -| | LOS\_TaskYield | 显å¼æ”¾æƒï¼Œè°ƒæ•´æŒ‡å®šä¼˜å…ˆçº§çš„ä»»åŠ¡è°ƒåº¦é¡ºåº | -| 任务调度的控制 | LOS\_TaskLock | é”任务调度 | -| | LOS\_TaskUnlock | 解é”任务调度 | -| 任务优先级的控制 | LOS\_CurTaskPriSet | 设置当å‰ä»»åŠ¡çš„优先级 | -| | LOS\_TaskPriSet | 设置指定任务的优先级 | -| | LOS\_TaskPriGet | 获å–指定任务的优先级 | -| 任务信æ¯èŽ·å– | LOS\_CurTaskIDGet | 获å–当å‰ä»»åŠ¡çš„ID | -| | LOS\_TaskInfoGet | 获å–æŒ‡å®šä»»åŠ¡çš„ä¿¡æ¯ | -| | LOS\_TaskStatusGet | 获å–æŒ‡å®šä»»åŠ¡çš„çŠ¶æ€ | -| | LOS\_TaskNameGet | 获å–指定任务的å称 | -| | LOS\_TaskInfoMonitor | 监控所有任务,获å–æ‰€æœ‰ä»»åŠ¡çš„ä¿¡æ¯ | -| | LOS\_NextTaskIDGet | 获å–å³å°†è¢«è°ƒåº¦çš„任务的ID | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    任务的创建和删除

    +

    LOS_TaskCreateOnly

    +

    创建任务,并使该任务进入suspend状æ€ï¼Œå¹¶ä¸è°ƒåº¦ã€‚

    +

    LOS_TaskCreate

    +

    创建任务,并使该任务进入ready状æ€ï¼Œå¹¶è°ƒåº¦ã€‚

    +

    LOS_TaskDelete

    +

    删除指定的任务。

    +

    任务状æ€æŽ§åˆ¶

    +

    LOS_TaskResume

    +

    æ¢å¤æŒ‚起的任务。

    +

    LOS_TaskSuspend

    +

    挂起指定的任务。

    +

    LOS_TaskDelay

    +

    任务延时等待。

    +

    LOS_TaskYield

    +

    显å¼æ”¾æƒï¼Œè°ƒæ•´æŒ‡å®šä¼˜å…ˆçº§çš„任务调度顺åºã€‚

    +

    任务调度的控制

    +

    LOS_TaskLock

    +

    é”任务调度。

    +

    LOS_TaskUnlock

    +

    解é”任务调度。

    +

    任务优先级的控制

    +

    LOS_CurTaskPriSet

    +

    设置当å‰ä»»åŠ¡çš„优先级。

    +

    LOS_TaskPriSet

    +

    设置指定任务的优先级。

    +

    LOS_TaskPriGet

    +

    获å–指定任务的优先级。

    +

    任务信æ¯èŽ·å–

    +

    +

    +

    +

    +

    LOS_CurTaskIDGet

    +

    获å–当å‰ä»»åŠ¡çš„ID。

    +

    LOS_TaskInfoGet

    +

    获å–指定任务的信æ¯ã€‚

    +

    LOS_TaskStatusGet

    +

    获å–指定任务的状æ€ã€‚

    +

    LOS_TaskNameGet

    +

    获å–指定任务的å称。

    +

    LOS_TaskInfoMonitor

    +

    监控所有任务,获å–所有任务的信æ¯ã€‚

    +

    LOS_NextTaskIDGet

    +

    获å–å³å°†è¢«è°ƒåº¦çš„任务的ID。

    +
    #### å¼€å‘æµç¨‹ -以创建任务为例,讲解开å‘æµç¨‹ã€‚ +以创建任务为例,讲解开å‘æµç¨‹ã€‚ 1. 在los\_config.h中é…置任务模å—。 - é…ç½®LOSCFG\_BASE\_CORE\_TSK\_LIMIT系统支æŒæœ€å¤§ä»»åŠ¡æ•°ï¼Œè¿™ä¸ªå¯ä»¥æ ¹æ®éœ€æ±‚自己é…置。 - - é…ç½®LOSCFG\_BASE\_CORE\_TSK\_IDLE\_STACK\_SIZE 空闲(IDLE)任务栈大å°ï¼Œè¿™ä¸ªé»˜è®¤å³å¯ã€‚ - - é…ç½®LOSCFG\_BASE\_CORE\_TSK\_DEFAULT\_STACK\_SIZE默认任务栈大å°ï¼Œç”¨æˆ·æ ¹æ®è‡ªå·±çš„需求进行é…置,在用户创建任务时,å¯ä»¥è¿›è¡Œé’ˆå¯¹æ€§è®¾ç½®ã€‚ - - é…ç½®LOSCFG\_BASE\_CORE\_TIMESLICE时间片开关为YES。 - - é…ç½®LOSCFG\_BASE\_CORE\_TIMESLICE\_TIMEOUT时间片,根æ®å®žé™…情况自己é…置。 + é…ç½®LOSCFG\_BASE\_CORE\_TSK\_LIMIT系统支æŒæœ€å¤§ä»»åŠ¡æ•°ï¼Œè¿™ä¸ªå¯ä»¥æ ¹æ®éœ€æ±‚自己é…置。 - é…ç½®LOSCFG\_BASE\_CORE\_TSK\_MONITOR任务监测模å—è£å‰ªå¼€å…³ï¼Œå¯é€‰æ‹©æ˜¯å¦æ‰“开。 - -2. é”任务LOS\_TaskLock,é”ä½ä»»åŠ¡ï¼Œé˜²æ­¢é«˜ä¼˜å…ˆçº§ä»»åŠ¡è°ƒåº¦ã€‚ + é…ç½®LOSCFG\_BASE\_CORE\_TSK\_IDLE\_STACK\_SIZE 空闲(IDLE)任务栈大å°ï¼Œè¿™ä¸ªé»˜è®¤å³å¯ã€‚ -3. 创建任务LOS\_TaskCreate。 + é…ç½®LOSCFG\_BASE\_CORE\_TSK\_DEFAULT\_STACK\_SIZE默认任务栈大å°ï¼Œç”¨æˆ·æ ¹æ®è‡ªå·±çš„需求进行é…置,在用户创建任务时,å¯ä»¥è¿›è¡Œé’ˆå¯¹æ€§è®¾ç½®ã€‚ -4. 解é”任务LOS\_TaskUnlock,让任务按照优先级进行调度。 + é…ç½®LOSCFG\_BASE\_CORE\_TIMESLICE时间片开关为YES。 -5. 延时任务LOS\_TaskDelay,任务延时等待。 + é…ç½®LOSCFG\_BASE\_CORE\_TIMESLICE\_TIMEOUT时间片,根æ®å®žé™…情况自己é…置。 -6. 挂起指定的任务LOS\_TaskSuspend,任务挂起等待æ¢å¤æ“作。 - -7. æ¢å¤æŒ‚起的任务LOS\_TaskResume。 + é…ç½®LOSCFG\_BASE\_CORE\_TSK\_MONITOR任务监测模å—è£å‰ªå¼€å…³ï¼Œå¯é€‰æ‹©æ˜¯å¦æ‰“开。 +2. é”任务LOS\_TaskLock,é”ä½ä»»åŠ¡ï¼Œé˜²æ­¢é«˜ä¼˜å…ˆçº§ä»»åŠ¡è°ƒåº¦ã€‚ +3. 创建任务LOS\_TaskCreate。 +4. 解é”任务LOS\_TaskUnlock,让任务按照优先级进行调度。 +5. 延时任务LOS\_TaskDelay,任务延时等待。 +6. 挂起指定的任务LOS\_TaskSuspend,任务挂起等待æ¢å¤æ“作。 +7. æ¢å¤æŒ‚起的任务LOS\_TaskResume。 #### TASKçŠ¶æ€ -Huawei LiteOS任务的状æ€ç”±å†…核自动维护,对用户ä¸å¯è§ï¼Œä¸éœ€è¦ç”¨æˆ·åŽ»æ“作。 +Huawei LiteOS任务的大多数状æ€ç”±å†…核维护,唯有自删除状æ€å¯¹ç”¨æˆ·å¯è§ï¼Œéœ€è¦ç”¨æˆ·åœ¨åˆ›å»ºä»»åŠ¡æ—¶ä¼ å…¥ï¼š + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    1

    +

    LOS_TASK_STATUS_DETACHED

    +

    0x0100

    +

    任务是自删除的

    +
    + +用户在调用LOS\_TaskCreate接å£åˆ›å»ºä»»åŠ¡æ—¶ï¼Œéœ€è¦å°†åˆ›å»ºä»»åŠ¡çš„TSK\_INIT\_PARAM\_Så‚æ•°çš„uwResved域设置为LOS\_TASK\_STATUS\_DETACHED,å³è‡ªåˆ é™¤çŠ¶æ€ï¼Œè®¾ç½®æˆè‡ªåˆ é™¤çŠ¶æ€çš„任务会在è¿è¡Œå®Œæˆæ—¶è¿›è¡Œè‡ªåˆ é™¤åŠ¨ä½œã€‚ + +>![](public_sys-resources/icon-notice.gif) **须知:** +> +>- 在调用内核LOS\_TaskCreate接å£åˆ›å»ºä»»åŠ¡æ—¶ï¼Œé»˜è®¤å¿…é¡»è¦å°†ä»»åŠ¡çŠ¶æ€è®¾ç½®ä¸ºLOS\_TASK\_STATUS\_DETACHED。 #### TASKé”™è¯¯ç  -对任务存在失败å¯èƒ½æ€§çš„æ“作,包括创建任务ã€åˆ é™¤ä»»åŠ¡ã€æŒ‚起任务ã€æ¢å¤ä»»åŠ¡ã€å»¶æ—¶ä»»åŠ¡ç­‰ç­‰ï¼Œå‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ - -| åºå· | 定义 | 实际数值 | æè¿° | å‚考解决方案 | -|------|-----------------------------------------------|------------|----------------------------------------|--------------------------------------------| -| 1 | LOS\_ERRNO\_TSK\_NO\_MEMORY | 0x03000200 | 内存空间ä¸è¶³ | 分é…更大的内存分区 | -| 2 | LOS\_ERRNO\_TSK\_PTR\_NULL | 0x02000201 | 任务å‚数为空 | 检查任务å‚æ•° | -| 3 | LOS\_ERRNO\_TSK\_STKSZ\_NOT\_ALIGN | 0x02000202 | 任务栈大å°æœªå¯¹é½ | 对é½ä»»åŠ¡æ ˆ | -| 4 | LOS\_ERRNO\_TSK\_PRIOR\_ERROR | 0x02000203 | ä¸æ­£ç¡®çš„任务优先级 | 检查任务优先级 | -| 5 | LOS\_ERRNO\_TSK\_ENTRY\_NULL | 0x02000204 | 任务入å£å‡½æ•°ä¸ºç©º | 定义任务入å£å‡½æ•° | -| 6 | LOS\_ERRNO\_TSK\_NAME\_EMPTY | 0x02000205 | 任务å为空 | 设置任务å | -| 7 | LOS\_ERRNO\_TSK\_STKSZ\_TOO\_SMALL | 0x02000206 | ä»»åŠ¡æ ˆå¤ªå° | 扩大任务栈 | -| 8 | LOS\_ERRNO\_TSK\_ID\_INVALID | 0x02000207 | 无效的任务ID | 检查任务ID | -| 9 | LOS\_ERRNO\_TSK\_ALREADY\_SUSPENDED | 0x02000208 | 任务已ç»è¢«æŒ‚èµ· | 等待这个任务被æ¢å¤åŽï¼Œå†åŽ»å°è¯•æŒ‚起这个任务 | -| 10 | LOS\_ERRNO\_TSK\_NOT\_SUSPENDED | 0x02000209 | 任务未被挂起 | 挂起这个任务 | -| 11 | LOS\_ERRNO\_TSK\_NOT\_CREATED | 0x0200020a | 任务未被创建 | 创建这个任务 | -| 12 | LOS\_ERRNO\_TSK\_OPERATE\_SWTMR | 0x02000222 | ä¸å…许æ“作软件定时器任务 | 用户ä¸è¦è¯•å›¾åŽ»æ“作软件定时器任务的设置 | -| 13 | LOS\_ERRNO\_TSK\_MSG\_NONZERO | 0x0200020c | 任务信æ¯éžé›¶ | æš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç  | -| 14 | LOS\_ERRNO\_TSK\_DELAY\_IN\_INT | 0x0300020d | 中断期间,进行任务延时 | 等待退出中断åŽå†è¿›è¡Œå»¶æ—¶æ“作 | -| 15 | LOS\_ERRNO\_TSK\_DELAY\_IN\_LOCK | 0x0200020e | 任务被é”的状æ€ä¸‹ï¼Œè¿›è¡Œå»¶æ—¶ | 等待解é”任务之åŽå†è¿›è¡Œå»¶æ—¶æ“作 | -| 16 | LOS\_ERRNO\_TSK\_YIELD\_INVALID\_TASK | 0x0200020f | 将被排入行程的任务是无效的 | 检查这个任务 | -| 17 | LOS\_ERRNO\_TSK\_YIELD\_NOT\_ENOUGH\_TASK | 0x02000210 | 没有或者仅有一个å¯ç”¨ä»»åŠ¡èƒ½è¿›è¡Œè¡Œç¨‹å®‰æŽ’ | 增加任务数 | -| 18 | LOS\_ERRNO\_TSK\_TCB\_UNAVAILABLE | 0x02000211 | 没有空闲的任务控制å—å¯ç”¨ | 增加任务控制å—æ•°é‡ | -| 19 | LOS\_ERRNO\_TSK\_HOOK\_NOT\_MATCH | 0x02000212 | 任务的钩å­å‡½æ•°ä¸åŒ¹é… | æš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç  | -| 20 | LOS\_ERRNO\_TSK\_HOOK\_IS\_FULL | 0x02000213 | 任务的钩å­å‡½æ•°æ•°é‡è¶…è¿‡ç•Œé™ | æš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç  | -| 21 | LOS\_ERRNO\_TSK\_OPERATE\_IDLE | 0x02000214 | 这是个IDLE任务 | 检查任务ID,ä¸è¦è¯•å›¾æ“作IDLE任务 | -| 22 | LOS\_ERRNO\_TSK\_SUSPEND\_LOCKED | 0x03000215 | 将被挂起的任务处于被é”çŠ¶æ€ | 等待任务解é”åŽå†å°è¯•æŒ‚起任务 | -| 23 | LOS\_ERRNO\_TSK\_FREE\_STACK\_FAILED | 0x02000217 | 任务栈free失败 | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 24 | LOS\_ERRNO\_TSK\_STKAREA\_TOO\_SMALL | 0x02000218 | ä»»åŠ¡æ ˆåŒºåŸŸå¤ªå° | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 25 | LOS\_ERRNO\_TSK\_ACTIVE\_FAILED | 0x03000219 | 任务触å‘失败 | 创建一个IDLE任务åŽæ‰§è¡Œä»»åŠ¡è½¬æ¢ | -| 26 | LOS\_ERRNO\_TSK\_CONFIG\_TOO\_MANY | 0x0200021a | 过多的任务é…置项 | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 27 | LOS\_ERRNO\_TSK\_CP\_SAVE\_AREA\_NOT\_ALIGN | 0x0200021b | æš‚æ—  | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 28 | LOS\_ERRNO\_TSK\_MSG\_Q\_TOO\_MANY | 0x0200021d | æš‚æ—  | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 29 | LOS\_ERRNO\_TSK\_CP\_SAVE\_AREA\_NULL | 0x0200021e | æš‚æ—  | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 30 | LOS\_ERRNO\_TSK\_SELF\_DELETE\_ERR | 0x0200021f | æš‚æ—  | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 31 | LOS\_ERRNO\_TSK\_STKSZ\_TOO\_LARGE | 0x02000220 | 任务栈大å°è®¾ç½®è¿‡å¤§ | å‡å°ä»»åŠ¡æ ˆå¤§å° | -| 32 | LOS\_ERRNO\_TSK\_SUSPEND\_SWTMR\_NOT\_ALLOWED | 0x02000221 | ä¸å…许挂起软件定时器任务 | 检查任务ID, ä¸è¦è¯•å›¾æŒ‚起软件定时器任务 | - -**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下 +对任务存在失败å¯èƒ½æ€§çš„æ“作,包括创建任务ã€åˆ é™¤ä»»åŠ¡ã€æŒ‚起任务ã€æ¢å¤ä»»åŠ¡ã€å»¶æ—¶ä»»åŠ¡ç­‰ç­‰ï¼Œå‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_TSK_NO_MEMORY

    +

    0x03000200

    +

    内存空间ä¸è¶³

    +

    分é…更大的内存分区

    +

    2

    +

    LOS_ERRNO_TSK_PTR_NULL

    +

    0x02000201

    +

    任务å‚数为空

    +

    检查任务å‚æ•°

    +

    3

    +

    LOS_ERRNO_TSK_STKSZ_NOT_ALIGN

    +

    0x02000202

    +

    任务栈大å°æœªå¯¹é½

    +

    对é½ä»»åŠ¡æ ˆï¼Œæš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    4

    +

    LOS_ERRNO_TSK_PRIOR_ERROR

    +

    0x02000203

    +

    ä¸æ­£ç¡®çš„任务优先级

    +

    检查任务优先级

    +

    5

    +

    LOS_ERRNO_TSK_ENTRY_NULL

    +

    0x02000204

    +

    任务入å£å‡½æ•°ä¸ºç©º

    +

    定义任务入å£å‡½æ•°

    +

    6

    +

    LOS_ERRNO_TSK_NAME_EMPTY

    +

    0x02000205

    +

    任务å为空

    +

    设置任务å

    +

    7

    +

    LOS_ERRNO_TSK_STKSZ_TOO_SMALL

    +

    0x02000206

    +

    任务栈太å°

    +

    扩大任务栈

    +

    8

    +

    LOS_ERRNO_TSK_ID_INVALID

    +

    0x02000207

    +

    无效的任务ID

    +

    检查任务ID

    +

    9

    +

    LOS_ERRNO_TSK_ALREADY_SUSPENDED

    +

    0x02000208

    +

    任务已ç»è¢«æŒ‚èµ·

    +

    等待这个任务被æ¢å¤åŽï¼Œå†åŽ»å°è¯•æŒ‚起这个任务

    +

    10

    +

    LOS_ERRNO_TSK_NOT_SUSPENDED

    +

    0x02000209

    +

    任务未被挂起

    +

    挂起这个任务

    +

    11

    +

    LOS_ERRNO_TSK_NOT_CREATED

    +

    0x0200020a

    +

    任务未被创建

    +

    创建这个任务

    +

    12

    +

    LOS_ERRNO_TSK_DELETE_LOCKE

    +

    0x0300020b

    +

    删除任务时,任务处于被é”状æ€

    +

    等待解é”任务之åŽå†è¿›è¡Œåˆ é™¤æ“作

    +

    13

    +

    LOS_ERRNO_TSK_MSG_NONZERO

    +

    0x0200020c

    +

    任务信æ¯éžé›¶

    +

    æš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    14

    +

    LOS_ERRNO_TSK_DELAY_IN_INT

    +

    0x0300020d

    +

    中断期间,进行任务延时

    +

    等待退出中断åŽå†è¿›è¡Œå»¶æ—¶æ“作

    +

    15

    +

    LOS_ERRNO_TSK_DELAY_IN_LOCK

    +

    0x0200020e

    +

    任务被é”的状æ€ä¸‹ï¼Œè¿›è¡Œå»¶æ—¶

    +

    等待解é”任务之åŽå†è¿›è¡Œå»¶æ—¶æ“作

    +

    16

    +

    LOS_ERRNO_TSK_YIELD_IN_LOCK

    +

    0x0200020f

    +

    任务被é”的状æ€ä¸‹ï¼Œè¿›è¡ŒYieldæ“作

    +

    等待任务解é”åŽè¿›è¡ŒYieldæ“作

    +

    17

    +

    LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK

    +

    0x02000210

    +

    没有或者仅有一个å¯ç”¨ä»»åŠ¡èƒ½è¿›è¡Œè¡Œç¨‹å®‰æŽ’

    +

    增加任务数

    +

    18

    +

    LOS_ERRNO_TSK_TCB_UNAVAILABLE

    +

    0x02000211

    +

    没有空闲的任务控制å—å¯ç”¨

    +

    增加任务控制å—æ•°é‡

    +

    19

    +

    LOS_ERRNO_TSK_HOOK_NOT_MATCH

    +

    0x02000212

    +

    任务的钩å­å‡½æ•°ä¸åŒ¹é…

    +

    æš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    20

    +

    LOS_ERRNO_TSK_HOOK_IS_FULL

    +

    0x02000213

    +

    任务的钩å­å‡½æ•°æ•°é‡è¶…过界é™

    +

    æš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    21

    +

    LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK

    +

    0x02000214

    +

    这是个系统级别的任务

    +

    检查任务ID,ä¸è¦è¯•å›¾æ“作系统任务

    +

    22

    +

    LOS_ERRNO_TSK_SUSPEND_LOCKED

    +

    0x03000215

    +

    将被挂起的任务处于被é”状æ€

    +

    等待任务解é”åŽå†å°è¯•æŒ‚起任务

    +

    23

    +

    LOS_ERRNO_TSK_FREE_STACK_FAILED

    +

    0x02000217

    +

    任务栈free失败

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    24

    +

    LOS_ERRNO_TSK_STKAREA_TOO_SMALL

    +

    0x02000218

    +

    任务栈区域太å°

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    25

    +

    LOS_ERRNO_TSK_ACTIVE_FAILED

    +

    0x03000219

    +

    任务触å‘失败

    +

    创建一个IDLE任务åŽæ‰§è¡Œä»»åŠ¡è½¬æ¢ï¼Œæš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    26

    +

    LOS_ERRNO_TSK_CONFIG_TOO_MANY

    +

    0x0200021a

    +

    过多的任务é…置项

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    27

    +

    LOS_ERRNO_TSK_CP_SAVE_AREA_NOT_ALIGN

    +

    0x0200021b

    +

    æš‚æ— 

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    28

    +

    LOS_ERRNO_TSK_MSG_Q_TOO_MANY

    +

    0x0200021d

    +

    æš‚æ— 

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    29

    +

    LOS_ERRNO_TSK_CP_SAVE_AREA_NULL

    +

    0x0200021e

    +

    æš‚æ— 

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    30

    +

    LOS_ERRNO_TSK_SELF_DELETE_ERR

    +

    0x0200021f

    +

    æš‚æ— 

    +

    该错误ç æš‚ä¸ä½¿ç”¨

    +

    31

    +

    LOS_ERRNO_TSK_STKSZ_TOO_LARGE

    +

    0x02000220

    +

    任务栈大å°è®¾ç½®è¿‡å¤§

    +

    å‡å°ä»»åŠ¡æ ˆå¤§å°

    +

    32

    +

    LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED

    +

    0x02000221

    +

    ä¸å…许挂起软件定时器任务

    +

    检查任务ID, ä¸è¦è¯•å›¾æŒ‚起软件定时器任务,暂ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    33

    +

    LOS_ERRNO_TSK_DELAY_IN_SWTMR_TSK

    +

    0x03000222

    +

    在软件定时器回调中,调用任务延时

    +

    ä¸è¦åœ¨è½¯ä»¶å®šæ—¶å™¨ä¸­è°ƒç”¨ä»»åŠ¡å»¶æ—¶ï¼Œæš‚ä¸ä½¿ç”¨è¯¥é”™è¯¯ç 

    +

    34

    +

    LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR

    +

    0x03000223

    +

    任务CPU亲和性Mask有误

    +

    检查传入的亲和性Mask

    +

    35

    +

    LOS_ERRNO_TSK_YIELD_IN_INT

    +

    0x02000224

    +

    任务在中断中进行Yieldæ“作

    +

    ä¸è¦åœ¨ä¸­æ–­ä¸­è¿›è¡ŒYieldæ“作

    +
    + +**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下: ``` - #define LOS_ERRNO_OS_NORMAL(MID,ERRNO) - (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) - LOS_ERRTYPE_NORMAL :Define the error level as critical - LOS_ERRNO_OS_ID :OS error code flag. - MID:OS_MOUDLE_ID - ERRNO:error ID number +#define LOS_ERRNO_OS_NORMAL(MID,ERRNO) \ +(LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) +LOS_ERRTYPE_NORMAL :Define the error level as critical +LOS_ERRNO_OS_ID :OS error code flag. +MID:OS_MOUDLE_ID +ERRNO:error ID number ``` 例如: @@ -379,236 +957,249 @@ Huawei LiteOS任务的状æ€ç”±å†…核自动维护,对用户ä¸å¯è§ï¼Œä¸éœ€ LOS_ERRNO_TSK_NO_MEMORY LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x00) ``` -![](./meta/DevGuide/icon_notice.png) - 错误ç åºå· 0x16ã€0x1cã€0x0b,未被定义,ä¸å¯ç”¨ã€‚ +>![](public_sys-resources/icon-notice.gif) **须知:** +>错误ç åºå· 0x16ã€0x1cã€0x0b,未被定义,ä¸å¯ç”¨ã€‚ #### å¹³å°å·®å¼‚性 -无。 +无。 ### 注æ„事项 -- 创建新任务时,会对之å‰è‡ªåˆ é™¤ä»»åŠ¡çš„任务控制å—和任务栈进行回收,éžè‡ªåˆ é™¤ä»»åŠ¡çš„控制å—和栈在任务删除的时候已ç»å›žæ”¶ã€‚ - -- 任务å是指针没有分é…空间,在设置任务å时,ç¦æ­¢å°†å±€éƒ¨å˜é‡çš„地å€èµ‹å€¼ç»™ä»»åŠ¡å指针。 - -- 若指定的任务栈大å°ä¸º0,则使用é…置项LOSCFG\_BASE\_CORE\_TSK\_DEFAULT\_STACK\_SIZE指定默认的任务栈大å°ã€‚ - -- 任务栈的大å°æŒ‰8字节大å°å¯¹é½ã€‚确定任务栈大å°çš„原则是,够用就行:多了浪费,少了任务栈溢出。 - -- 挂起任务的时候若为当å‰ä»»åŠ¡ä¸”å·²é”任务,则ä¸èƒ½è¢«æŒ‚起。 - -- 空闲(IDLE)任务åŠè½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡ä¸èƒ½è¢«æŒ‚起或者删除。 - -- 在中断处ç†å‡½æ•°ä¸­æˆ–者在é”任务的情况下,执行LOS\_TaskDelayæ“作会失败。 - -- é”任务调度,并ä¸å…³ä¸­æ–­ï¼Œå› æ­¤ä»»åŠ¡ä»å¯è¢«ä¸­æ–­æ‰“断。 - -- é”任务调度必须和解é”任务调度é…åˆä½¿ç”¨ã€‚ - -- 设置任务优先级的时候å¯èƒ½ä¼šå‘生任务调度。 - -- 除去空闲(IDLE)任务以外,系统å¯é…置的任务资æºä¸ªæ•°æ˜¯æŒ‡ï¼šæ•´ä¸ªç³»ç»Ÿçš„任务资æºæ€»ä¸ªæ•°ï¼Œè€Œéžç”¨æˆ·èƒ½ä½¿ç”¨çš„任务资æºä¸ªæ•°ã€‚例如:系统软件定时器多å ç”¨ä¸€ä¸ªä»»åŠ¡èµ„æºæ•°ï¼Œé‚£ä¹ˆç³»ç»Ÿå¯é…置的任务资æºå°±ä¼šå‡å°‘一个。 - -- 为了防止系统出现问题,系统ç¦æ­¢å¯¹è½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡ä¼˜å…ˆçº§è¿›è¡Œä¿®æ”¹ã€‚ - -- LOS\_CurTaskPriSetå’ŒLOS\_TaskPriSet接å£ä¸èƒ½åœ¨ä¸­æ–­ä¸­ä½¿ç”¨ã€‚ - -- LOS\_TaskPriGet接å£ä¼ å…¥çš„task ID对应的任务未创建或者超过最大任务数,统一返回0xffff。 - -- 在删除任务时è¦ä¿è¯ä»»åŠ¡ç”³è¯·çš„资æºï¼ˆå¦‚互斥é”ã€ä¿¡å·é‡ç­‰ï¼‰å·²è¢«é‡Šæ”¾ã€‚ +- 创建新任务时,会对之å‰è‡ªåˆ é™¤ä»»åŠ¡çš„任务控制å—和任务栈进行回收,éžè‡ªåˆ é™¤ä»»åŠ¡çš„控制å—和栈在任务删除的时候已ç»å›žæ”¶ã€‚ +- 任务å是指针没有分é…空间,在设置任务å时,ç¦æ­¢å°†å±€éƒ¨å˜é‡çš„地å€èµ‹å€¼ç»™ä»»åŠ¡å指针。 +- 若指定的任务栈大å°ä¸º0,则使用é…置项LOSCFG\_BASE\_CORE\_TSK\_DEFAULT\_STACK\_SIZE指定默认的任务栈大å°ã€‚ +- 任务栈的大å°æŒ‰8字节大å°å¯¹é½ã€‚确定任务栈大å°çš„原则是,够用就行:多了浪费,少了任务栈溢出。 +- 挂起任务的时候若为当å‰ä»»åŠ¡ä¸”å·²é”任务,则ä¸èƒ½è¢«æŒ‚起。 +- 空闲(IDLE)任务åŠè½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡ä¸èƒ½è¢«æŒ‚起或者删除。 +- 在中断处ç†å‡½æ•°ä¸­æˆ–者在é”任务的情况下,执行LOS\_TaskDelayæ“作会失败。 +- é”任务调度,并ä¸å…³ä¸­æ–­ï¼Œå› æ­¤ä»»åŠ¡ä»å¯è¢«ä¸­æ–­æ‰“断。 +- é”任务调度必须和解é”任务调度é…åˆä½¿ç”¨ã€‚ +- 设置任务优先级的时候å¯èƒ½ä¼šå‘生任务调度。 +- 系统å¯é…置的任务资æºä¸ªæ•°æ˜¯æŒ‡ï¼šæ•´ä¸ªç³»ç»Ÿçš„任务资æºæ€»ä¸ªæ•°ï¼Œè€Œéžç”¨æˆ·èƒ½ä½¿ç”¨çš„任务资æºä¸ªæ•°ã€‚例如:系统软件定时器多å ç”¨ä¸€ä¸ªä»»åŠ¡èµ„æºæ•°ï¼Œé‚£ä¹ˆç³»ç»Ÿå¯é…置的任务资æºå°±ä¼šå‡å°‘一个。 +- ä¸å»ºè®®ä½¿ç”¨LOS\_CurTaskPriSet或者LOS\_TaskPriSet接å£æ¥ä¿®æ”¹è½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡çš„优先级,å¦åˆ™å¯èƒ½ä¼šå¯¼è‡´ç³»ç»Ÿå‡ºçŽ°é—®é¢˜ã€‚ +- LOS\_CurTaskPriSetå’ŒLOS\_TaskPriSet接å£ä¸èƒ½åœ¨ä¸­æ–­ä¸­ä½¿ç”¨ã€‚ +- LOS\_TaskPriGet接å£ä¼ å…¥çš„task ID对应的任务未创建或者超过最大任务数,统一返回0xffff。 +- 在删除任务时è¦ä¿è¯ä»»åŠ¡ç”³è¯·çš„资æºï¼ˆå¦‚互斥é”ã€ä¿¡å·é‡ç­‰ï¼‰å·²è¢«é‡Šæ”¾ã€‚ ### 编程实例 #### 实例æè¿° -下é¢çš„示例介ç»ä»»åŠ¡çš„基本æ“作方法,包å«ä»»åŠ¡åˆ›å»ºã€ä»»åŠ¡å»¶æ—¶ã€ä»»åŠ¡é”与解é”调度ã€æŒ‚èµ·å’Œæ¢å¤ã€æŸ¥è¯¢å½“å‰ä»»åŠ¡PIDã€æ ¹æ®PID查询任务信æ¯ç­‰æ“作,é˜è¿°ä»»åŠ¡ä¼˜å…ˆçº§è°ƒåº¦çš„机制以åŠå„接å£çš„应用。 +下é¢çš„示例介ç»ä»»åŠ¡çš„基本æ“作方法,包å«ä»»åŠ¡åˆ›å»ºã€ä»»åŠ¡å»¶æ—¶ã€ä»»åŠ¡é”与解é”调度ã€æŒ‚èµ·å’Œæ¢å¤ã€æŸ¥è¯¢å½“å‰ä»»åŠ¡PIDã€æ ¹æ®PID查询任务信æ¯ç­‰æ“作,é˜è¿°ä»»åŠ¡ä¼˜å…ˆçº§è°ƒåº¦çš„机制以åŠå„接å£çš„应用。 1. 创建了2个任务:TaskHiå’ŒTaskLo。 - 2. TaskHi为高优先级任务。 - 3. TaskLo为低优先级任务。 #### 编程示例 -``` -static UINT32 g_uwTskHiID; -static UINT32 g_uwTskLoID; - -#define TSK_PRIOR_HI 4 -#define TSK_PRIOR_LO 5 - -static UINT32 Example_TaskHi(VOID) -{ - UINT32 uwRet = LOS_OK; - - dprintf("Enter TaskHi Handler.\r\n"); - - /*延时5个Tick,延时åŽè¯¥ä»»åŠ¡ä¼šæŒ‚起,执行剩余任务中高优先级的任务(g_uwTskLoID任务)*/ - uwRet = LOS_TaskDelay(5); - if (uwRet != LOS_OK) - { - dprintf("Delay Task Failed.\r\n"); - return LOS_NOK; - } +``` +UINT32 g_uwTskLoID; +UINT32 g_uwTskHiID; +#define TSK_PRIOR_HI 4 +#define TSK_PRIOR_LO 5 + +UINT32 Example_TaskHi(VOID) +{ + UINT32 uwRet; + UINT32 uwCurrentID; + TSK_INFO_S stTaskInfo; + + printf("Enter TaskHi Handler.\r\n"); + + /*延时2个Tick,延时åŽè¯¥ä»»åŠ¡ä¼šæŒ‚起,执行剩余任务中最高优先级的任务(g_uwTskLoID任务)*/ + uwRet = LOS_TaskDelay(2); + if (uwRet != LOS_OK) + { + printf("Delay Task Failed.\r\n"); + return LOS_NOK; + } + + /*2个Tick时间到了åŽï¼Œè¯¥ä»»åŠ¡æ¢å¤ï¼Œç»§ç»­æ‰§è¡Œ*/ + printf("TaskHi LOS_TaskDelay Done.\r\n"); + + /*挂起自身任务*/ + uwRet = LOS_TaskSuspend(g_uwTskHiID); + if (uwRet != LOS_OK) + { + printf("Suspend TaskHi Failed.\r\n"); + return LOS_NOK; + } + printf("TaskHi LOS_TaskResume Success.\r\n"); +} + +/*低优先级任务入å£å‡½æ•°*/ +UINT32 Example_TaskLo(VOID) +{ + UINT32 uwRet; + UINT32 uwCurrentID; + TSK_INFO_S stTaskInfo; + + printf("Enter TaskLo Handler.\r\n"); + + /*延时2个Tick,延时åŽè¯¥ä»»åŠ¡ä¼šæŒ‚起,执行剩余任务中就高优先级的任务(背景任务)*/ + uwRet = LOS_TaskDelay(2); + if (uwRet != LOS_OK) + { + printf("Delay TaskLo Failed.\r\n"); + return LOS_NOK; + } + + printf("TaskHi LOS_TaskSuspend Success.\r\n"); + + /*æ¢å¤è¢«æŒ‚起的任务g_uwTskHiID*/ + uwRet = LOS_TaskResume(g_uwTskHiID); + if (uwRet != LOS_OK) + { + printf("Resume TaskHi Failed.\r\n"); + return LOS_NOK; + } + + printf("TaskHi LOS_TaskDelete Success.\r\n"); +} + +/*任务测试入å£å‡½æ•°ï¼Œåœ¨é‡Œé¢åˆ›å»ºä¼˜å…ˆçº§ä¸ä¸€æ ·çš„两个任务*/ +UINT32 Example_TskCaseEntry(VOID) +{ + UINT32 uwRet; + TSK_INIT_PARAM_S stInitParam; + + /*é”任务调度*/ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success!\r\n"); + + stInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; + stInitParam.usTaskPrio = TSK_PRIOR_HI; + stInitParam.pcName = "HIGH_NAME"; + stInitParam.uwStackSize = 0x700; + stInitParam.uwResved = LOS_TASK_STATUS_DETACHED; + /*创建高优先级任务,由于é”任务调度,任务创建æˆåŠŸåŽä¸ä¼šé©¬ä¸Šæ‰§è¡Œ*/ + uwRet = LOS_TaskCreate(&g_uwTskHiID, &stInitParam); + if (uwRet != LOS_OK) + { + LOS_TaskUnlock(); + + printf("Example_TaskHi create Failed!\r\n"); + return LOS_NOK; + } + + printf("Example_TaskHi create Success!\r\n"); + + stInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; + stInitParam.usTaskPrio = TSK_PRIOR_LO; + stInitParam.pcName = "LOW_NAME"; + stInitParam.uwStackSize = 0x700; + stInitParam.uwResved = LOS_TASK_STATUS_DETACHED; + /*创建低优先级任务,由于é”任务调度,任务创建æˆåŠŸåŽä¸ä¼šé©¬ä¸Šæ‰§è¡Œ*/ + uwRet = LOS_TaskCreate(&g_uwTskLoID, &stInitParam); + if (uwRet != LOS_OK) + { + LOS_TaskUnlock(); + + printf("Example_TaskLo create Failed!\r\n"); + return LOS_NOK; + } + + printf("Example_TaskLo create Success!\r\n"); + + /*解é”任务调度,此时会å‘生任务调度,执行就绪列表中最高优先级任务*/ + LOS_TaskUnlock(); + + while(1){}; + + return LOS_OK; +} +``` - /*2个tick时间到了åŽï¼Œè¯¥ä»»åŠ¡æ¢å¤ï¼Œç»§ç»­æ‰§è¡Œ*/ - dprintf("TaskHi LOS_TaskDelay Done.\r\n"); +#### ç»“æžœéªŒè¯ - /*挂起自身任务*/ - uwRet = LOS_TaskSuspend(g_uwTskHiID); - if (uwRet != LOS_OK) - { - dprintf("Suspend TaskHi Failed.\r\n"); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_TASK,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return LOS_NOK; - } - - dprintf("TaskHi LOS_TaskResume Success.\r\n"); - - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_TASK,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - - /*删除任务*/ - if(LOS_OK != LOS_TaskDelete(g_uwTskHiID)) - { - dprintf("TaskHi delete failed .\n"); - return LOS_NOK; - } - - return LOS_OK; -} +编译è¿è¡Œå¾—到的结果为: -/*低优先级任务入å£å‡½æ•°*/ -static UINT32 Example_TaskLo(VOID) -{ - UINT32 uwRet; +![](figures/zh-cn_image_0238585887.jpg) - dprintf("Enter TaskLo Handler.\r\n"); +#### å®Œæ•´å®žä¾‹ä»£ç  - /*延时10个Tick,延时åŽè¯¥ä»»åŠ¡ä¼šæŒ‚起,执行剩余任务中就高优先级的任务(背景任务)*/ - uwRet = LOS_TaskDelay(10); - if (uwRet != LOS_OK) - { - dprintf("Delay TaskLo Failed.\r\n"); - return LOS_NOK; - } +[sample\_task\_smp.c](resource/sample_task_smp.c) - dprintf("TaskHi LOS_TaskSuspend Success.\r\n"); +

    4.2 内存

    - /*æ¢å¤è¢«æŒ‚起的任务g_uwTskHiID*/ - uwRet = LOS_TaskResume(g_uwTskHiID); - if (uwRet != LOS_OK) - { - dprintf("Resume TaskHi Failed.\r\n"); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_TASK,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return LOS_NOK; - } - - /*删除任务*/ - if(LOS_OK != LOS_TaskDelete(g_uwTskLoID)) - { - dprintf("TaskLo delete failed .\n"); - - return LOS_NOK; - } - - return LOS_OK; -``` +### 概述 -#### ç»“æžœéªŒè¯ +#### 基本概念 -编译è¿è¡Œå¾—到的结果为: -![](./meta/DevGuide/pic3.png) +内存管ç†æ¨¡å—管ç†ç³»ç»Ÿçš„内存资æºï¼Œå®ƒæ˜¯æ“作系统的核心模å—之一。主è¦åŒ…括内存的åˆå§‹åŒ–ã€åˆ†é…以åŠé‡Šæ”¾ã€‚ -

    4.2 内存

    +在系统è¿è¡Œè¿‡ç¨‹ä¸­ï¼Œå†…存管ç†æ¨¡å—通过对内存的申请/释放æ“作,æ¥ç®¡ç†ç”¨æˆ·å’ŒOS对内存的使用,使内存的利用率和使用效率达到最优,åŒæ—¶æœ€å¤§é™åº¦åœ°è§£å†³ç³»ç»Ÿçš„内存碎片问题。 -### 概述 +Huawei LiteOS的内存管ç†åˆ†ä¸ºé™æ€å†…存管ç†å’ŒåŠ¨æ€å†…存管ç†ï¼Œæ供内存åˆå§‹åŒ–ã€åˆ†é…ã€é‡Šæ”¾ç­‰åŠŸèƒ½ã€‚ -#### 基本概念 +**动æ€å†…存:** 在动æ€å†…存池中分é…用户指定大å°çš„内存å—。 -内存管ç†æ¨¡å—管ç†ç³»ç»Ÿçš„内存资æºï¼Œå®ƒæ˜¯æ“作系统的核心模å—之一。主è¦åŒ…括内存的åˆå§‹åŒ–ã€åˆ†é…以åŠé‡Šæ”¾ã€‚ +- 优点:按需分é…。 +- 缺点:内存池中å¯èƒ½å‡ºçŽ°ç¢Žç‰‡ã€‚ -在系统è¿è¡Œè¿‡ç¨‹ä¸­ï¼Œå†…存管ç†æ¨¡å—通过对内存的申请/释放æ“作,æ¥ç®¡ç†ç”¨æˆ·å’ŒOS对内存的使用,使内存的利用率和使用效率达到最优,åŒæ—¶æœ€å¤§é™åº¦åœ°è§£å†³ç³»ç»Ÿçš„内存碎片问题。 +**é™æ€å†…存:** 在é™æ€å†…存池中分é…用户åˆå§‹åŒ–时预设(固定)大å°çš„内存å—。 -Huawei LiteOS的内存管ç†åˆ†ä¸ºé™æ€å†…存管ç†å’ŒåŠ¨æ€å†…存管ç†ï¼Œæ供内存åˆå§‹åŒ–ã€åˆ†é…ã€é‡Šæ”¾ç­‰åŠŸèƒ½ã€‚ +- 优点:分é…和释放效率高,é™æ€å†…存池中无碎片。 +- 缺点:åªèƒ½ç”³è¯·åˆ°åˆå§‹åŒ–预设大å°çš„内存å—,ä¸èƒ½æŒ‰éœ€ç”³è¯·ã€‚ -- 动æ€å†…存:在动æ€å†…存池中分é…用户指定大å°çš„内存å—。 +#### 动æ€å†…å­˜è¿ä½œæœºåˆ¶ - - 优点:按需分é…。 +动æ€å†…存管ç†ï¼Œå³åœ¨å†…存资æºå……足的情况下,从系统é…置的一å—比较大的连续内存(内存池),根æ®ç”¨æˆ·éœ€æ±‚,分é…ä»»æ„大å°çš„内存å—。当用户ä¸éœ€è¦è¯¥å†…å­˜å—时,åˆå¯ä»¥é‡Šæ”¾å›žç³»ç»Ÿä¾›ä¸‹ä¸€æ¬¡ä½¿ç”¨ã€‚ - - 缺点:内存池中å¯èƒ½å‡ºçŽ°ç¢Žç‰‡ã€‚ +与é™æ€å†…存相比,动æ€å†…存管ç†çš„好处是按需分é…,缺点是内存池中容易出现碎片。 -- é™æ€å†…存:在é™æ€å†…存池中分é…用户åˆå§‹åŒ–时预设(固定)大å°çš„内存å—。 +LiteOS动æ€å†…存支æŒDLINKå’ŒBEST LITTLE两ç§æ ‡å‡†ç®—法。 - - 优点:分é…和释放效率高,é™æ€å†…存池中无碎片。 +**1.DLINK** - - 缺点:åªèƒ½ç”³è¯·åˆ°åˆå§‹åŒ–预设大å°çš„内存å—,ä¸èƒ½æŒ‰éœ€ç”³è¯·ã€‚ +DLINK动æ€å†…存管ç†ç»“构如图1所示: -#### 动æ€å†…å­˜è¿ä½œæœºåˆ¶ +**图 1** DLINK动æ€å†…存管ç†ç»“构图 +![](figures/zh-cn_image_0237405366.png "zh-cn_image_0237405366") -动æ€å†…存管ç†ï¼Œå³åœ¨å†…存资æºå……足的情况下,从系统é…置的一å—比较大的连续内存(内存池),根æ®ç”¨æˆ·éœ€æ±‚,分é…ä»»æ„大å°çš„内存å—。当用户ä¸éœ€è¦è¯¥å†…å­˜å—时,åˆå¯ä»¥é‡Šæ”¾å›žç³»ç»Ÿä¾›ä¸‹ä¸€æ¬¡ä½¿ç”¨ã€‚ +第一部分:堆内存(也称内存池)的起始地å€åŠå †åŒºåŸŸæ€»å¤§å°ã€‚ -与é™æ€å†…存相比,动æ€å†…存管ç†çš„好处是按需分é…,缺点是内存池中容易出现碎片。 +第二部分:本身是一个数组,æ¯ä¸ªå…ƒç´ æ˜¯ä¸€ä¸ªåŒå‘链表,所有free节点的控制头都会被分类挂在这个数组的åŒå‘链表中。 -LiteOS动æ€å†…存支æŒDLINKå’ŒBEST LITTLE两ç§æ ‡å‡†ç®—法。 +å‡è®¾å†…å­˜å…许的最å°èŠ‚点为2min字节,则数组的第一个åŒå‘链表存储的是所有size为2minmin+1çš„free节点,第二个åŒå‘链表存储的是所有size为2min+1min+2çš„free节点,ä¾æ¬¡ç±»æŽ¨ç¬¬n个åŒå‘链表存储的是所有size为2min+n-1min+nçš„free节点。æ¯æ¬¡ç”³è¯·å†…存的时候,会从这个数组检索最åˆé€‚大å°çš„free节点,进行分é…内存。æ¯æ¬¡é‡Šæ”¾å†…存时,会将该片内存作为free节点存储至这个数组,以便下次å†åˆ©ç”¨ã€‚ -**1. DLINK** +第三部分:å ç”¨å†…存池æžå¤§éƒ¨åˆ†çš„空间,是用于存放å„节点的实际区域。以下是LOS\_MEM\_DYN\_NODE节点结构体申明以åŠç®€å•ä»‹ç»ï¼š +``` +typedef struct tagLOS_MEM_DYN_NODE -DLINK动æ€å†…存管ç†ç»“构如下图所示: -![](./meta/DevGuide/pic4.png) +{ -**第一部分:** 堆内存(也称内存池)的起始地å€åŠå †åŒºåŸŸæ€»å¤§å°ã€‚ +LOS_DL_LIST stFreeNodeInfo; -**第二部分:** 本身是一个数组,æ¯ä¸ªå…ƒç´ æ˜¯ä¸€ä¸ªåŒå‘链表,所有free节点的控制头都会被分类挂在这个数组的åŒå‘链表中。 +struct tagLOS_MEM_DYN_NODE *pstPreNode; -å‡è®¾å†…å­˜å…许的最å°èŠ‚点为2min字节,则数组的第一个åŒå‘链表存储的是所有size为2min\min+1çš„free节点,第二个åŒå‘链表存储的是所有size为2min+1\min+2çš„free节点,ä¾æ¬¡ç±»æŽ¨ç¬¬n个åŒå‘链表存储的是所有size为2min+n-1\min+nçš„free节点。æ¯æ¬¡ç”³è¯·å†…存的时候,会从这个数组检索最åˆé€‚大å°çš„free节点,进行分é…内存。æ¯æ¬¡é‡Šæ”¾å†…存时,会将该片内存作为free节点存储至这个数组,以便下次å†åˆ©ç”¨ã€‚ +UINT32 uwSizeAndFlag; -**第三部分:** å ç”¨å†…存池æžå¤§éƒ¨åˆ†çš„空间,是用于存放å„节点的实际区域。以下是```LOS\_MEM\_DYN\_NODE```节点结构体申明以åŠç®€å•ä»‹ç»ï¼š -``` -typedef struct tagLOS_MEM_DYN_NODE -{ -LOS_DL_LIST stFreeNodeInfo; -struct tagLOS_MEM_DYN_NODE *pstPreNode; -UINT32 uwSizeAndFlag; -}LOS_MEM_DYN_NODE; +}LOS_MEM_DYN_NODE; ``` -![](./meta/DevGuide/pic5.png) - -**2.BEST LITTLE** - -LiteOS的动æ€å†…存分é…支æŒæœ€ä½³é€‚é…算法,å³BEST LITTLE,æ¯æ¬¡åˆ†é…时选择内存池中最å°æœ€é€‚åˆçš„内存å—进行分é…。LiteOS动æ€å†…存管ç†åœ¨æœ€ä½³é€‚é…算法的基础上加入了SLAB机制,用于分é…固定大å°çš„内存å—,进而å‡å°äº§ç”Ÿå†…存碎片的å¯èƒ½æ€§ã€‚ -LiteOS内存管ç†ä¸­çš„SLAB机制支æŒå¯é…置的SLAB CLASSæ•°ç›®åŠæ¯ä¸ªCLASS的最大空间,现以SLAB CLASS数目为4,æ¯ä¸ªCLASS的最大空间为512字节为例说明SLAB机制。在内存池中共有4个SLAB CLASS,æ¯ä¸ªSLAB CLASS的总共å¯åˆ†é…大å°ä¸º512字节,第一个SLAB CLASS被分为32个16字节的SLABå—,第二个SLAB CLASS被分为16个32字节的SLABå—,第三个SLAB CLASS被分为8个64字节的SLABå—,第四个SLAB CLASS被分为4个128字节的SLABå—。这4个SLAB CLASS是从内存池中按照最佳适é…算法分é…出æ¥çš„。 +**图 2** LOS\_MEM\_DYN\_NODE节点结构图 +![](figures/zh-cn_image_0237405430.png "zh-cn_image_0237405430") -åˆå§‹åŒ–内存管ç†æ—¶ï¼Œé¦–å…ˆåˆå§‹åŒ–内存池,然åŽåœ¨åˆå§‹åŒ–åŽçš„内存池中按照最佳适é…算法申请4个SLAB CLASS,å†é€ä¸ªæŒ‰ç…§SLAB内存管ç†æœºåˆ¶åˆå§‹åŒ–4个SLAB CLASS。 +**2.BEST LITTLE** -æ¯æ¬¡ç”³è¯·å†…存时,先在满足申请大å°çš„最佳SLAB CLASS中申请,(比如用户申请20字节内存,就在SLABå—大å°ä¸º32字节的SLAB CLASS中申请),如果申请æˆåŠŸï¼Œå°±å°†SLAB内存å—æ•´å—返回给用户,释放时整å—回收。如果满足æ¡ä»¶çš„SLAB CLASS中已无å¯ä»¥åˆ†é…的内存å—,则继续å‘内存池按照最佳适é…算法申请。需è¦æ³¨æ„的是,如果当å‰çš„SLAB CLASS中无å¯ç”¨SLABå—了,则直接å‘内存池申请,而ä¸ä¼šç»§ç»­å‘有ç€æ›´å¤§SLABå—空间的SLAB CLASS申请。 +LiteOS的动æ€å†…存分é…支æŒæœ€ä½³é€‚é…算法,å³BEST LITTLE,æ¯æ¬¡åˆ†é…时选择堆内存(内存池中)最å°æœ€é€‚åˆçš„内存å—进行分é…。 -释放内存时,先检查释放的内存å—是å¦å±žäºŽSLAB CLASS,如果是SLAB CLASS的内存å—,则还回对应的SLAB CLASS中,å¦åˆ™è¿˜å›žå†…存池中。 -![](./meta/DevGuide/pic6.png) +**图 3** BEST LITTLE动æ€å†…存管ç†ç»“构图 +![](figures/zh-cn_image_0237405390.png) -#### é™æ€å†…å­˜è¿ä½œæœºåˆ¶ +#### é™æ€å†…å­˜è¿ä½œæœºåˆ¶ -é™æ€å†…存实质上是一å—é™æ€æ•°ç»„,é™æ€å†…存池内的å—大å°åœ¨åˆå§‹åŒ–时设定,åˆå§‹åŒ–åŽå—大å°ä¸å¯å˜æ›´ã€‚ +é™æ€å†…存实质上是一å—é™æ€æ•°ç»„,é™æ€å†…存池内的å—大å°åœ¨åˆå§‹åŒ–时设定,åˆå§‹åŒ–åŽå—大å°ä¸å¯å˜æ›´ã€‚ -é™æ€å†…存池由一个控制å—和若干相åŒå¤§å°çš„内存å—æž„æˆã€‚控制å—ä½äºŽå†…存池头部,用于内存å—管ç†ã€‚内存å—的申请和释放以å—大å°ä¸ºç²’度。 +é™æ€å†…存池由一个控制å—和若干相åŒå¤§å°çš„内存å—æž„æˆã€‚控制å—ä½äºŽå†…存池头部,用于内存å—管ç†ã€‚内存å—的申请和释放以å—大å°ä¸ºç²’度。 -![](./meta/DevGuide/pic7.png) -é™æ€å†…存示æ„图 +**图 4** é™æ€å†…存示æ„图 +![](figures/é™æ€å†…存示æ„图.png "é™æ€å†…存示æ„图") ### 动æ€å†…å­˜ @@ -616,88 +1207,252 @@ LiteOS内存管ç†ä¸­çš„SLAB机制支æŒå¯é…置的SLAB CLASSæ•°ç›®åŠæ¯ä¸ªCLA ##### 使用场景 -内存管ç†çš„主è¦å·¥ä½œæ˜¯åŠ¨æ€çš„划分并管ç†ç”¨æˆ·åˆ†é…好的内存区间。 +内存管ç†çš„主è¦å·¥ä½œæ˜¯åŠ¨æ€çš„划分并管ç†ç”¨æˆ·åˆ†é…好的内存区间。 -动æ€å†…存管ç†ä¸»è¦æ˜¯åœ¨ç”¨æˆ·éœ€è¦ä½¿ç”¨å¤§å°ä¸ç­‰çš„内存å—的场景中使用。 +动æ€å†…存管ç†ä¸»è¦æ˜¯åœ¨ç”¨æˆ·éœ€è¦ä½¿ç”¨å¤§å°ä¸ç­‰çš„内存å—的场景中使用。 -当用户需è¦åˆ†é…内存时,å¯ä»¥é€šè¿‡æ“作系统的动æ€å†…存申请函数索å–指定大å°å†…å­˜å—,一旦使用完毕,通过动æ€å†…存释放函数归还所å ç”¨å†…存,使之å¯ä»¥é‡å¤ä½¿ç”¨ã€‚ +当用户需è¦åˆ†é…内存时,å¯ä»¥é€šè¿‡æ“作系统的动æ€å†…存申请函数申请指定大å°å†…å­˜å—,一旦使用完毕,通过动æ€å†…存释放函数归还所å ç”¨å†…存,使之å¯ä»¥é‡å¤ä½¿ç”¨ã€‚ ##### 功能 Huawei LiteOS系统中的动æ€å†…存管ç†æ¨¡å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ï¼Œå…·ä½“çš„API详è§æŽ¥å£æ‰‹å†Œã€‚ -| 功能分类 | 接å£å | æè¿° | -|----------------------------|---------------------------|------------------------------------------------------------------| -| 内存åˆå§‹åŒ– | LOS\_MemInit | åˆå§‹åŒ–一å—指定的动æ€å†…存池,大å°ä¸ºsize。 | -| 申请动æ€å†…å­˜ | LOS\_MemAlloc | 从指定动æ€å†…存池中申请size长度的内存。 | -| 释放动æ€å†…å­˜ | LOS\_MemFree | 释放已申请的内存。 | -| é‡æ–°ç”³è¯·å†…å­˜ | LOS\_MemRealloc | 按size大å°é‡æ–°åˆ†é…内存å—,并ä¿ç•™åŽŸå†…å­˜å—内容。 | -| 内存对é½åˆ†é… | LOS\_MemAllocAlign | 从指定动æ€å†…存池中申请长度为size且地å€æŒ‰boundary字节对é½çš„内存。 | -| 分æžå†…å­˜æ± çŠ¶æ€ | LOS\_MemStatisticsGet | 获å–æŒ‡å®šå†…å­˜æ± çš„ç»Ÿè®¡ä¿¡æ¯ | -| 查看内存池中最大å¯ç”¨ç©ºé—²å— | LOS\_MemGetMaxFreeBlkSize | 获å–指定内存池的最大å¯ç”¨ç©ºé—²å— | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    内存åˆå§‹åŒ–

    +

    LOS_MemInit

    +

    åˆå§‹åŒ–一å—指定的动æ€å†…存池,大å°ä¸ºsize。

    +

    删除内存池

    +

    LOS_MemDeInit

    +

    删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效。

    +

    申请动æ€å†…å­˜

    +

    LOS_MemAlloc

    +

    从指定动æ€å†…存池中申请size长度的内存。

    +

    释放动æ€å†…å­˜

    +

    LOS_MemFree

    +

    释放已申请的内存。

    +

    é‡æ–°ç”³è¯·å†…å­˜

    +

    LOS_MemRealloc

    +

    按size大å°é‡æ–°åˆ†é…内存å—,并ä¿ç•™åŽŸå†…å­˜å—内容。

    +

    内存对é½åˆ†é…

    +

    LOS_MemAllocAlign

    +

    从指定动æ€å†…存池中申请长度为size且地å€æŒ‰boundary字节对é½çš„内存。

    +

    获å–内存大å°

    +

    LOS_MemPoolSizeGet

    +

    获å–指定的动æ€å†…存池总大å°ã€‚

    +

    获å–内存大å°

    +

    LOS_MemTotalUsedGet

    +

    获å–指定动æ€å†…存池的总使用é‡å¤§å°ã€‚

    +

    获å–内存å—æ•°é‡

    +

    LOS_MemFreeBlksGet

    +

    获å–指定内存池的空闲内存å—æ•°é‡ã€‚

    +

    获å–内存å—æ•°é‡

    +

    LOS_MemUsedBlksGet

    +

    获å–指定内存池的已使用的内存å—æ•°é‡ã€‚

    +

    获å–分é…指定内存区域的任务ID

    +

    LOS_MemTaskIdGet

    +

    获å–分é…了指定内存区域的任务ID。

    +

    获å–内存池中最åŽä¸€ä¸ªä½¿ç”¨å†…å­˜å—的结æŸåœ°å€

    +

    LOS_MemLastUsedGet

    +

    获å–内存池最åŽä¸€ä¸ªä½¿ç”¨å†…å­˜å—的结æŸåœ°å€ã€‚

    +

    获å–内存结构信æ¯

    +

    LOS_MemInfoGet

    +

    获å–指定内存池的内存结构信æ¯ã€‚

    +

    对指定内存池åšå®Œæ•´æ€§æ£€æŸ¥

    +

    LOS_MemIntegrityCheck

    +

    对指定内存池åšå®Œæ•´æ€§æ£€æŸ¥ã€‚

    +

    获å–内存å—大å°

    +

    LOS_MemNodeSizeCheck

    +

    获å–内存å—的总大å°å’Œå¯æ“作大å°ã€‚

    +

    设定内存检查级别

    +

    LOS_MemCheckLevelSet

    +

    设定内存检查级别。

    +

    获å–内存检查级别

    +

    LOS_MemCheckLevelGet

    +

    获å–内存检查级别。

    +

    显示系统内存池

    +

    LOS_MemPoolList

    +

    打å°æ˜¾ç¤ºç³»ç»Ÿä¸­å·²åˆå§‹åŒ–的所有内存池,仅打开LOSCFG_MEM_MUL_POOL时有效

    +

    指定模å—申请动æ€å†…å­˜

    +

    LOS_MemMalloc

    +

    从指定动æ€å†…存池分é…内存给指定的模å—,并纳入模å—统计。

    +

    释放指定模å—的一个内存å—

    +

    LOS_MemMfree

    +

    释放已ç»ç”³è¯·çš„内存å—,并纳入模å—统计。

    +

    指定模å—内存对é½åˆ†é…

    +

    LOS_MemMallocAlign

    +

    从指定动æ€å†…存池中申请长度为size且地å€æŒ‰boundary字节对é½çš„内存,并纳入模å—统计。

    +

    指定模å—é‡æ–°åˆ†é…内存å—

    +

    LOS_MemMrealloc

    +

    按size大å°é‡æ–°åˆ†é…内存å—,并ä¿ç•™åŽŸå†…å­˜å—内容,并纳入模å—统计。

    +

    获å–模å—内存使用é‡

    +

    LOS_MemMusedGet

    +

    获å–指定模å—当å‰å†…存使用é‡ã€‚

    +

    显示空闲内存å—的规模和数é‡

    +

    LOS_MemFreeNodeShow

    +

    显示指定内存池当å‰ç©ºé—²å†…å­˜å—的规模åŠç›¸å¯¹åº”çš„æ•°é‡ã€‚

    +
    ##### DLINKå¼€å‘æµç¨‹ 1. é…置: -OS\_SYS\_MEM\_ADDR:系统动æ€å†…存池起始地å€ï¼Œä¸€èˆ¬ä¸éœ€è¦ä¿®æ”¹ã€‚ + OS\_SYS\_MEM\_ADDR:系统动æ€å†…存池起始地å€ï¼Œä¸€èˆ¬ä¸éœ€è¦ä¿®æ”¹ã€‚ -OS\_SYS\_MEM\_SIZE:系统动æ€å†…存池大å°ï¼Œä»¥byte为å•ä½ï¼Œç³»ç»Ÿé»˜è®¤åˆ†é…DDRåŽæœªä½¿ç”¨çš„空间。 + OS\_SYS\_MEM\_SIZE:系统动æ€å†…存池大å°ï¼Œä»¥byte为å•ä½ï¼Œç³»ç»Ÿé»˜è®¤åˆ†é…DDRåŽæœªä½¿ç”¨çš„空间。 -LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:内存越界检测开关,默认关闭。打开åŽï¼Œæ¯æ¬¡ç”³è¯·åŠ¨æ€å†…存时执行动æ€å†…å­˜å—越界检查;æ¯æ¬¡é‡Šæ”¾é™æ€å†…存时执行é™æ€å†…å­˜å—越界检查。 + LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:内存越界检测开关,默认关闭。打开åŽï¼Œæ¯æ¬¡ç”³è¯·åŠ¨æ€å†…存时执行动æ€å†…å­˜å—越界检查。 2. åˆå§‹åŒ–LOS\_MemInit。 -åˆå§‹ä¸€ä¸ªå†…存池åŽå¦‚图,生æˆä¸€ä¸ª EndNode,并且剩余的内存全部被标记为FreeNode节点。 -![](./meta/DevGuide/icon_notice.png) -EndNode作为内存池末尾的节点,size为0。 -![](./meta/DevGuide/pic8.png) + åˆå§‹ä¸€ä¸ªå†…存池åŽå¦‚图,生æˆä¸€ä¸ª EndNode,并且剩余的内存全部被标记为FreeNode节点。注:EndNode作为内存池末尾的节点,size为0。 -3. 申请任æ„大å°çš„动æ€å†…å­˜LOS\_MemAlloc。 + ![](figures/zh-cn_image_0238925517.jpg) -判断动æ€å†…存池中是å¦å­˜åœ¨ç”³è¯·é‡å¤§å°çš„空间,若存在,则划出一å—内存å—,以指针形å¼è¿”回,若ä¸å­˜åœ¨ï¼Œè¿”回NULL。 +3. 申请任æ„大å°çš„动æ€å†…å­˜LOS\_MemAlloc。 -调用三次LOS\_MemAlloc函数å¯ä»¥åˆ›å»ºä¸‰ä¸ªèŠ‚点,å‡è®¾å称分别为UsedA,UsedB,UsedC,大å°åˆ†åˆ«ä¸ºsizeA,sizeB,sizeC。因为刚åˆå§‹åŒ–内存池的时候åªæœ‰ä¸€ä¸ªå¤§çš„FreeNode,所以这些内存å—是从这个FreeNode中切割出æ¥çš„。 -![](./meta/DevGuide/pic9.png) + 判断动æ€å†…存池中是å¦å­˜åœ¨ç”³è¯·é‡å¤§å°çš„空间,若存在,则划出一å—内存å—,以指针形å¼è¿”回,若ä¸å­˜åœ¨ï¼Œè¿”回NULL。 -当内存池中存在多个FreeNode的时候进行malloc,将会适é…最åˆé€‚大å°çš„FreeNode用æ¥æ–°å»ºå†…å­˜å—,å‡å°‘内存碎片。若新建的内存å—ä¸ç­‰äºŽè¢«ä½¿ç”¨çš„FreeNode的大å°ï¼Œåˆ™åœ¨æ–°å»ºå†…å­˜å—åŽï¼Œå¤šä½™çš„内存åˆä¼šè¢«æ ‡è®°ä¸ºä¸€ä¸ªæ–°çš„FreeNode。 + 调用三次LOS\_MemAlloc函数å¯ä»¥åˆ›å»ºä¸‰ä¸ªèŠ‚点,å‡è®¾å称分别为UsedA,UsedB,UsedC,大å°åˆ†åˆ«ä¸ºsizeA,sizeB,sizeC。因为刚åˆå§‹åŒ–内存池的时候åªæœ‰ä¸€ä¸ªå¤§çš„FreeNode,所以这些内存å—是从这个FreeNode中切割出æ¥çš„。 -4. 释放动æ€å†…å­˜LOS\_MemFree。 + ![](figures/zh-cn_image_0237405378.jpg) -回收内存å—,供下一次使用。 + 当内存池中存在多个FreeNode的时候进行malloc,将会适é…最åˆé€‚大å°çš„FreeNode用æ¥æ–°å»ºå†…å­˜å—,å‡å°‘内存碎片。若新建的内存å—ä¸ç­‰äºŽè¢«ä½¿ç”¨çš„FreeNode的大å°ï¼Œåˆ™åœ¨æ–°å»ºå†…å­˜å—åŽï¼Œå¤šä½™çš„内存åˆä¼šè¢«æ ‡è®°ä¸ºä¸€ä¸ªæ–°çš„FreeNode。 -å‡è®¾è°ƒç”¨LOS\_MemFree释放内存å—UsedB,则会回收内存å—UsedB,并且将其标记为FreeNode。 -![](./meta/DevGuide/pic10.png) +4. 释放动æ€å†…å­˜LOS\_MemFree。 -##### BEST LITTLEå¼€å‘æµç¨‹ + 回收内存å—,供下一次使用。 -1. é…置: + å‡è®¾è°ƒç”¨LOS\_MemFree释放内存å—UsedB,则会回收内存å—UsedB,并且将其标记为FreeNode。 -OS\_SYS\_MEM\_ADDR:系统动æ€å†…存池起始地å€ï¼Œéœ€è¦ç”¨æˆ·æŒ‡å®šã€‚ + ![](figures/zh-cn_image_0237405424.jpg) -OS\_SYS\_MEM\_SIZE:系统动æ€å†…存池大å°ï¼Œä»¥byte为å•ä½ï¼Œéœ€è¦ç”¨æˆ·æ­£ç¡®è®¡ç®—。 -LOSCFG\_MEMORY\_BESTFIT:置为YES,选中内存管ç†ç®—法中的BESTFIT算法。 +##### BEST LITTLEå¼€å‘æµç¨‹ -LOSCFG\_KERNEL\_MEM\_SLAB:置为YES,打开内存管ç†ä¸­çš„SLAB机制。 +1. é…置: -SLAB\_MEM\_COUNT:该é…ç½®ä½äºŽå†…核中,一般ä¸éœ€è¦æ”¹åŠ¨ï¼Œè¡¨ç¤ºSLAB CLASSçš„æ•°é‡ï¼Œç›®å‰å†…æ ¸åˆå§‹åŒ–为4。 + OS\_SYS\_MEM\_ADDR:系统动æ€å†…存池起始地å€ï¼Œéœ€è¦ç”¨æˆ·æŒ‡å®šã€‚ -SLAB\_MEM\_ALLOCATOR\_SIZE:该é…ç½®ä½äºŽå†…核中,一般ä¸éœ€è¦æ”¹åŠ¨ï¼Œè¡¨ç¤ºæ¯ä¸ªSLAB CLASS的最大å¯åˆ†é…çš„å—的总空间。 + OS\_SYS\_MEM\_SIZE:系统动æ€å†…存池大å°ï¼Œä»¥byte为å•ä½ï¼Œéœ€è¦ç”¨æˆ·æ­£ç¡®è®¡ç®—。 -SLAB\_BASIC\_NEED\_SIZE:该é…ç½®ä½äºŽå†…核中,一般ä¸éœ€è¦æ”¹åŠ¨ï¼Œè¡¨ç¤ºåˆå§‹åŒ–SLAB机制时需è¦çš„最å°çš„堆空间。如果改动了SLAB\_MEM\_COUNTå’ŒSLAB\_MEM\_ALLOCATOR\_SIZEçš„é…置,就需è¦åŒæ­¥æ”¹åŠ¨è¿™ä¸ªé…置。 + LOSCFG\_MEMORY\_BESTFIT:置为YES,选择内存管ç†ç®—法中的BESTFIT算法。 -2. åˆå§‹åŒ–: +2. åˆå§‹åŒ–: -调用LOS\_MemInit函数åˆå§‹åŒ–用户指定的动æ€å†…存池,若用户使能了SLAB机制并且内存池中的å¯åˆ†é…内存大于SLAB需è¦çš„最å°å†…存,则会进一步åˆå§‹åŒ–SLAB CLASS。 + 调用LOS\_MemInit函数åˆå§‹åŒ–用户指定的动æ€å†…存池。 -3. 申请任æ„大å°çš„动æ€å†…存: +3. 申请任æ„大å°çš„动æ€å†…存: -调用LOS\_MemAlloc函数从指定的内存池中申请指定大å°çš„内存å—,申请时内存管ç†å…ˆå‘SLAB CLASS申请,申请失败åŽç»§ç»­å‘堆内存空间申请,最åŽå°†ç”³è¯·ç»“果返回给用户。在å‘堆内存空间申请时,会存在内存å—的切分。 - -4. 释放动æ€å†…存: + 调用LOS\_MemAlloc函数从指定的内存池中申请指定大å°çš„内存å—,申请时内存管ç†å‘堆内存空间申请,最åŽå°†ç”³è¯·ç»“果返回给用户。在å‘堆内存空间申请时,会存在内存å—的切分。 -调用LOS\_MemFree函数å‘指定的动æ€å†…存池释放指定的内存å—,释放时会先判断该内存å—是å¦å±žäºŽSLAB CLASS,若属于,则将该内存å—还回SLAB CLASS。å¦åˆ™ï¼Œå‘堆内存空间释放内存å—。在å‘堆内存空间释放时,会存在内存å—çš„åˆå¹¶ã€‚ +4. 释放动æ€å†…存: + + 调用LOS\_MemFree函数å‘指定的动æ€å†…存池释放指定的内存å—,å‘堆内存空间释放内存å—。在å‘堆内存空间释放时,会存在内存å—çš„åˆå¹¶ã€‚ ##### å¹³å°å·®å¼‚性 @@ -705,140 +1460,173 @@ SLAB\_BASIC\_NEED\_SIZE:该é…ç½®ä½äºŽå†…核中,一般ä¸éœ€è¦æ”¹åŠ¨ï¼Œè¡¨ #### 注æ„事项 -- 由于系统中动æ€å†…存管ç†éœ€è¦æ¶ˆè€—管ç†æŽ§åˆ¶å—结构的内存,故实际用户å¯ä½¿ç”¨ç©ºé—´æ€»é‡å°äºŽåœ¨é…置文件los\_config.h中é…置项OS\_SYS\_MEM\_SIZE的大å°ã€‚ - -- 系统中地å€å¯¹é½ç”³è¯·å†…存分é…LOS\_MemAllocAlignå¯èƒ½ä¼šæ¶ˆè€—部分对é½å¯¼è‡´çš„空间,故存在一些内存碎片,当系统释放该对é½å†…存时,åŒæ—¶å›žæ”¶ç”±äºŽå¯¹é½å¯¼è‡´çš„内存碎片。 +- 由于系统中动æ€å†…存管ç†éœ€è¦æ¶ˆè€—管ç†æŽ§åˆ¶å—结构的内存,故实际用户å¯ä½¿ç”¨ç©ºé—´æ€»é‡å°äºŽåœ¨é…置文件los\_config.h中é…置项OS\_SYS\_MEM\_SIZE的大å°ã€‚ +- 系统中地å€å¯¹é½ç”³è¯·å†…存分é…LOS\_MemAllocAlignå¯èƒ½ä¼šæ¶ˆè€—部分对é½å¯¼è‡´çš„空间,故存在一些内存碎片,当系统释放该对é½å†…存时,åŒæ—¶å›žæ”¶ç”±äºŽå¯¹é½å¯¼è‡´çš„内存碎片。 +- 系统中é‡æ–°åˆ†é…内存LOS\_MemRealloc函数如果分é…æˆåŠŸï¼Œç³»ç»Ÿä¼šè‡ªå·±åˆ¤å®šæ˜¯å¦éœ€è¦é‡Šæ”¾åŽŸæ¥ç”³è¯·çš„空间,返回é‡æ–°åˆ†é…的空间。如果é‡æ–°åˆ†é…失败,原æ¥çš„空间ä¿æŒä¸å˜ï¼Œå¹¶è¿”回NULL。ç¦æ­¢ä½¿ç”¨pPtr = LOS\_MemRealloc\(pool, pPtr, uwSize\); å³ï¼šä¸èƒ½ä½¿ç”¨åŽŸæœ¬çš„pPtrå˜é‡ç›´æŽ¥åŽ»æŽ¥æ”¶è¿”回值。 -- 系统中é‡æ–°åˆ†é…内存LOS\_MemRealloc函数如果分é…æˆåŠŸï¼Œç³»ç»Ÿä¼šè‡ªå·±åˆ¤å®šæ˜¯å¦éœ€è¦é‡Šæ”¾åŽŸæ¥ç”³è¯·çš„空间,返回é‡æ–°åˆ†é…的空间。用户ä¸éœ€è¦æ‰‹åŠ¨é‡Šæ”¾åŽŸæ¥çš„空间。 - -- 系统中多次调用LOS\_MemFree时,第一次会返回æˆåŠŸï¼Œä½†å¯¹åŒä¸€å—内存进行多次é‡å¤é‡Šæ”¾ä¼šå¯¼è‡´éžæ³•æŒ‡é’ˆæ“作,导致结果ä¸å¯é¢„知。 +- 系统中多次调用LOS\_MemFree时,第一次会返回æˆåŠŸï¼Œä½†å¯¹åŒä¸€å—内存进行多次é‡å¤é‡Šæ”¾ä¼šå¯¼è‡´éžæ³•æŒ‡é’ˆæ“作,导致结果ä¸å¯é¢„知。 +- 由于系统动æ€å†…存管ç†å†…存节点控制å—结构体中,节点sizeæ•°æ®ç±»åž‹ä¸ºUINT32,高两ä½ä¸ºæ ‡å¿—ä½ï¼Œå› æ­¤ç”¨æˆ·åˆå§‹åŒ–内存池的大å°ä¸èƒ½è¶…过1G,å¦åˆ™ä¼šå‡ºçŽ°ä¸å¯é¢„知结果。 +- 分模å—内存统计ä¾èµ–于LOSCFG\_MEM\_MUL\_MODULE,使用时需è¦åœ¨é…置文件中定义此å®ã€‚ #### 编程实例 ##### 实例æè¿° -Huawei LiteOSè¿è¡ŒæœŸé—´ï¼Œç”¨æˆ·éœ€è¦é¢‘ç¹çš„使用内存资æºï¼Œè€Œå†…存资æºæœ‰é™ï¼Œå¿…须确ä¿å°†æœ‰é™çš„内存资æºåˆ†é…给急需的程åºï¼ŒåŒæ—¶é‡Šæ”¾ä¸ç”¨çš„内存。 +Huawei LiteOSè¿è¡ŒæœŸé—´ï¼Œç”¨æˆ·éœ€è¦é¢‘ç¹çš„使用内存资æºï¼Œè€Œå†…存资æºæœ‰é™ï¼Œå¿…须确ä¿å°†æœ‰é™çš„内存资æºåˆ†é…给急需的程åºï¼ŒåŒæ—¶é‡Šæ”¾ä¸ç”¨çš„内存。 -通过Huawei LiteOS内存管ç†æ¨¡å—å¯ä»¥ä¿è¯é«˜æ•ˆã€æ­£ç¡®çš„申请ã€é‡Šæ”¾å†…存。 +通过Huawei LiteOS内存管ç†æ¨¡å—å¯ä»¥ä¿è¯é«˜æ•ˆã€æ­£ç¡®çš„申请ã€é‡Šæ”¾å†…存。 -本实例执行以下步骤: +本实例执行以下步骤: -1. åˆå§‹åŒ–一个动æ€å†…存池。 +1. åˆå§‹åŒ–一个动æ€å†…存池。 +2. 在动æ€å†…存池中申请一个内存å—。 +3. 使用这å—内存å—存放一个数æ®ã€‚ +4. 打å°å‡ºå­˜æ”¾åœ¨å†…å­˜å—中的数æ®ã€‚ +5. 释放掉这å—内存。 -2. 在动æ€å†…存池中申请一个内存å—。 +##### 编程实例 -3. 使用这å—内存å—存放一个数æ®ã€‚ +``` + UINT8 * m_aucSysMem_Tmp; + VOID los_memory_test() { + UINT32 *p_num = NULL; + UINT32 uwRet; + uwRet = LOS_MemInit(m_aucSysMem_Tmp, 32); + if (LOS_OK == uwRet) { + dprintf("内存池åˆå§‹åŒ–æˆåŠŸ!\n"); + } + else { + dprintf("内存池åˆå§‹åŒ–失败!\n"); + return; + } + /*分é…内存*/ + p_num = (int*)LOS_MemAlloc(m_aucSysMem_Tmp, 4); + if (NULL == p_num) { + dprintf("内存分é…失败!\n"); + return; + } + dprintf("内存分é…æˆåŠŸ\n"); + /*赋值*/ + *p_num = 828; + dprintf("*p_num = %d\n", *p_num); + /*释放内存*/ + uwRet = LOS_MemFree(m_aucSysMem_Tmp, p_num); + if (LOS_OK == uwRet) { + dprintf("内存释放æˆåŠŸ!\n"); + } + else { + dprintf("内存释放失败!\n"); + } + return; + } +``` -4. 打å°å‡ºå­˜æ”¾åœ¨å†…å­˜å—中的数æ®ã€‚ +##### ç»“æžœéªŒè¯ -5. 释放掉这å—内存。 +**图 1** 结果显示 -##### 编程实例 -``` -UINT32 Example_Dyn_Mem(VOID) -{ - UINT32 *p_num = NULL; - UINT32 uwRet; - uwRet = LOS_MemInit(m_aucSysMem0, OS_SYS_MEM_SIZE); - if (LOS_OK == uwRet) - { - dprintf("mempool init ok!\n");//内存åˆå§‹åŒ–æˆåŠŸï¼ - } - else - { - dprintf("mempool init failed!\n");//内存åˆå§‹åŒ–å¤±è´¥ï¼ - return LOS_NOK; - } - /*分é…内存*/ - p_num = (UINT32*)LOS_MemAlloc(m_aucSysMem0, 4); - if (NULL == p_num) - { - dprintf("mem alloc failed!\n");//内存分é…å¤±è´¥ï¼ - return LOS_NOK; - } - dprintf("mem alloc ok\n");//内存分é…æˆåŠŸï¼ - /*赋值*/ - *p_num = 828; - dprintf("*p_num = %d\n", *p_num); - /*释放内存*/ - uwRet = LOS_MemFree(m_aucSysMem0, p_num); - if (LOS_OK == uwRet) - { - dprintf("mem free ok!\n");//内存释放æˆåŠŸï¼ - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_DMEM,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - else - { - dprintf("mem free failed!\n");//å†…å­˜é‡Šæ”¾å¤±è´¥ï¼ - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_DMEM,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return LOS_NOK; - } - return LOS_OK; -} -``` +![](figures/zh-cn_image_0238601438.gif) -##### ç»“æžœéªŒè¯ -结果显示 -![](./meta/DevGuide/pic11.png) +##### å®Œæ•´å®žä¾‹ä»£ç  + +[sample\_mem.c](resource/sample_mem.c) ### é™æ€å†…å­˜ #### å¼€å‘指导 -##### 使用场景 - -当用户需è¦ä½¿ç”¨å›ºå®šé•¿åº¦çš„内存时,å¯ä»¥ä½¿ç”¨é™æ€å†…存分é…çš„æ–¹å¼èŽ·å–内存,一旦使用完毕,通过é™æ€å†…存释放函数归还所å ç”¨å†…存,使之å¯ä»¥é‡å¤ä½¿ç”¨ã€‚ +##### 使用场景 -##### 功能 -Huawei LiteOSçš„é™æ€å†…存管ç†ä¸»è¦ä¸ºç”¨æˆ·æ供以下功能。 +当用户需è¦ä½¿ç”¨å›ºå®šé•¿åº¦çš„内存时,å¯ä»¥ä½¿ç”¨é™æ€å†…存分é…çš„æ–¹å¼èŽ·å–内存,一旦使用完毕,通过é™æ€å†…存释放函数归还所å ç”¨å†…存,使之å¯ä»¥é‡å¤ä½¿ç”¨ã€‚ -| 功能分类 | 接å£å | æè¿° | -|--------------------|--------------------------|----------------------------------------------------------| -| åˆå§‹åŒ–é™æ€å†…å­˜ | LOS\_MemboxInit | åˆå§‹åŒ–一个é™æ€å†…存池,设定其起始地å€ã€æ€»å¤§å°åŠæ¯ä¸ªå—å¤§å° | -| 清除é™æ€å†…存内容 | LOS\_MemboxClr | 清零é™æ€å†…å­˜å— | -| 申请一å—é™æ€å†…å­˜ | LOS\_MemboxAlloc | 申请一å—é™æ€å†…å­˜å— | -| 释放内存 | LOS\_MemboxFree | 释放一个é™æ€å†…å­˜å— | -| 分æžé™æ€å†…å­˜æ± çŠ¶æ€ | LOS\_MemboxStatisticsGet | 获å–é™æ€å†…å­˜æ± çš„ç»Ÿè®¡ä¿¡æ¯ | +##### 功能 -##### å¼€å‘æµç¨‹ +Huawei LiteOSçš„é™æ€å†…存管ç†ä¸»è¦ä¸ºç”¨æˆ·æ供以下功能。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    åˆå§‹åŒ–é™æ€å†…å­˜

    +

    LOS_MemboxInit

    +

    åˆå§‹åŒ–一个é™æ€å†…存池,设定其起始地å€ã€æ€»å¤§å°åŠæ¯ä¸ªå—大å°ã€‚

    +

    清除é™æ€å†…存内容

    +

    LOS_MemboxClr

    +

    清零é™æ€å†…å­˜å—。

    +

    申请一å—é™æ€å†…å­˜

    +

    LOS_MemboxAlloc

    +

    申请一å—é™æ€å†…å­˜å—。

    +

    释放内存

    +

    LOS_MemboxFree

    +

    释放一个é™æ€å†…å­˜å—。

    +

    分æžé™æ€å†…存池状æ€

    +

    LOS_MemboxStatisticsGet

    +

    获å–é™æ€å†…存池的统计信æ¯ã€‚

    +

    打å°é™æ€å†…存池内容

    +

    LOS_ShowBox

    +

    打å°æŒ‡å®šé™æ€å†…存池所有节点信æ¯ï¼ˆæ‰“å°ç­‰çº§æ˜¯LOS_INFO_LEVEL)

    +
    -本节介ç»ä½¿ç”¨é™æ€å†…存的典型场景开å‘æµç¨‹ã€‚ +#### å¼€å‘æµç¨‹ -1. 规划一片内存区域作为é™æ€å†…存池。 +本节介ç»ä½¿ç”¨é™æ€å†…存的典型场景开å‘æµç¨‹ã€‚ -2. 调用LOS\_MemboxInit接å£ã€‚ +1. 规划一片内存区域作为é™æ€å†…存池。 +2. 调用LOS\_MemboxInit接å£ã€‚ - 系统内部将会åˆå§‹åŒ–é™æ€å†…存池。将入å‚指定的内存区域分割为Nå—(N值å–决于é™æ€å†…存总大å°å’Œå—大å°ï¼‰ï¼Œå°†æ‰€æœ‰å†…å­˜å—挂到空闲链表,在内存起始处放置控制头。 + 系统内部将会åˆå§‹åŒ–é™æ€å†…存池。将入å‚指定的内存区域分割为Nå—(N值å–决于é™æ€å†…存总大å°å’Œå—大å°ï¼‰ï¼Œå°†æ‰€æœ‰å†…å­˜å—挂到空闲链表,在内存起始处放置控制头。 -3. 调用LOS\_MemboxAlloc接å£ã€‚ +3. 调用LOS\_MemboxAlloc接å£ã€‚ - 系统内部将会从空闲链表中获å–第一个空闲å—,并返回该å—的用户空间地å€ã€‚ + 系统内部将会从空闲链表中获å–第一个空闲å—,并返回该å—的用户空间地å€ã€‚ -4. 调用LOS\_MemboxFree接å£ã€‚ +4. 调用LOS\_MemboxFree接å£ã€‚ - 将该å—内存加入空闲å—链表。 + 将该å—内存加入空闲å—链表。 -5. 调用LOS\_MemboxClr接å£ã€‚ +5. 调用LOS\_MemboxClr接å£ã€‚ - 系统内部清零é™æ€å†…å­˜å—,将入å‚地å€å¯¹åº”的内存å—清零。 + 系统内部清零é™æ€å†…å­˜å—,将入å‚地å€å¯¹åº”的内存å—清零。 -##### å¹³å°å·®å¼‚性 +#### å¹³å°å·®å¼‚性 -无。 +无。 #### 注æ„事项 -- é™æ€å†…存池区域,å¯ä»¥é€šè¿‡å®šä¹‰å…¨å±€æ•°ç»„或调用动æ€å†…存分é…接å£æ–¹å¼èŽ·å–。如果使用动æ€å†…存分é…æ–¹å¼ï¼Œåœ¨ä¸éœ€è¦é™æ€å†…存池时,注æ„è¦é‡Šæ”¾è¯¥æ®µå†…存,é¿å…内存泄露。 +- é™æ€å†…存池区域,å¯ä»¥é€šè¿‡å®šä¹‰å…¨å±€æ•°ç»„或调用动æ€å†…存分é…接å£æ–¹å¼èŽ·å–。如果使用动æ€å†…存分é…æ–¹å¼ï¼Œåœ¨ä¸éœ€è¦é™æ€å†…存池时,注æ„è¦é‡Šæ”¾è¯¥æ®µå†…存,é¿å…内存泄露。 #### 编程实例 @@ -846,620 +1634,935 @@ Huawei LiteOSçš„é™æ€å†…存管ç†ä¸»è¦ä¸ºç”¨æˆ·æ供以下功能。 Huawei LiteOSè¿è¡ŒæœŸé—´ï¼Œç”¨æˆ·éœ€è¦é¢‘ç¹çš„使用内存资æºï¼Œè€Œå†…存资æºæœ‰é™ï¼Œå¿…须确ä¿å°†æœ‰é™çš„内存资æºåˆ†é…给急需的程åºï¼ŒåŒæ—¶é‡Šæ”¾ä¸ç”¨çš„内存。 -通过内存管ç†æ¨¡å—å¯ä»¥ä¿è¯æ­£ç¡®ä¸”高效的申请释放内存。 - -本实例执行以下步骤: +通过内存管ç†æ¨¡å—å¯ä»¥ä¿è¯æ­£ç¡®ä¸”高效的申请释放内存。 -1. åˆå§‹åŒ–一个é™æ€å†…存池。 +本实例执行以下步骤: -2. 从é™æ€å†…存池中申请一å—é™æ€å†…存。 +1. åˆå§‹åŒ–一个é™æ€å†…存池。 +2. 从é™æ€å†…存池中申请一å—é™æ€å†…存。 +3. 使用这å—内存å—存放一个数æ®ã€‚ +4. 打å°å‡ºå­˜æ”¾åœ¨å†…å­˜å—中的数æ®ã€‚ +5. 清除内存å—中的数æ®ã€‚ +6. 释放掉这å—内存。 -3. 使用这å—内存å—存放一个数æ®ã€‚ +##### 编程实例 -4. 打å°å‡ºå­˜æ”¾åœ¨å†…å­˜å—中的数æ®ã€‚ +``` +VOID los_membox_test(void) { + UINT32 *p_num = NULL; + UINT32 uwBlkSize = 10, uwBoxSize = 100; + UINT32 uwRet; + UINT32 pBoxMem[1000]; + uwRet = LOS_MemboxInit(&pBoxMem[0], uwBoxSize, uwBlkSize); + if (uwRet != LOS_OK) + { + dprintf("内存池åˆå§‹åŒ–失败!\n"); + return; + } + else { + dprintf("内存池åˆå§‹åŒ–æˆåŠŸ!\n"); + } + + /*申请内存å—*/ + p_num = (int*)LOS_MemboxAlloc(pBoxMem); + if (NULL == p_num) { + dprintf("内存分é…失败!\n"); + return; + } + dprintf("内存分é…æˆåŠŸ\n"); + /*赋值*/ + *p_num = 828; + dprintf("*p_num = %d\n", *p_num); + /*清除内存内容*/ + LOS_MemboxClr(pBoxMem, p_num); + dprintf("清除内存内容æˆåŠŸ\n *p_num = %d\n", *p_num); + /*释放内存*/ + uwRet = LOS_MemboxFree(pBoxMem, p_num); + if (LOS_OK == uwRet) { + dprintf("内存释放æˆåŠŸ!\n"); + } + else{ + dprintf("内存释放失败!\n"); + } + return; +} +``` -5. 清除内存å—中的数æ®ã€‚ +##### ç»“æžœéªŒè¯ -6. 释放掉这å—内存。 +**图 1** 结果显示 -##### 编程实例 -``` -UINT32 Example_StaticMem(VOID) -{ - UINT32 *p_num = NULL; - UINT32 uwBlkSize = 3, uwBoxSize = 48; - UINT32 uwRet; - - uwRet = LOS_MemboxInit( &pBoxMem[0], uwBoxSize, uwBlkSize); - if(uwRet != LOS_OK) - { - dprintf("Mem box init failed\n");//内存池åˆå§‹åŒ–å¤±è´¥ï¼ - return LOS_NOK; - } - else - { - dprintf("Mem box init ok!\n");//内存池åˆå§‹åŒ–æˆåŠŸï¼ - } - - /*申请内存å—*/ - p_num = (UINT32*)LOS_MemboxAlloc(pBoxMem); - if (NULL == p_num) - { - dprintf("Mem box alloc failed!\n");//内存分é…å¤±è´¥ï¼ - return LOS_NOK; - } - dprintf("Mem box alloc ok\n"); - /*赋值*/ - *p_num = 828; - dprintf("*p_num = %d\n", *p_num); - /*清除内存内容*/ - LOS_MemboxClr(pBoxMem, p_num); - dprintf("clear data ok\n *p_num = %d\n", *p_num);//清除内存æˆåŠŸï¼ - /*释放内存*/ - uwRet = LOS_MemboxFree(pBoxMem, p_num); - if (LOS_OK == uwRet) - { - dprintf("Mem box free ok!\n");//内存释放æˆåŠŸï¼ - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SMEM,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - else - { - dprintf("Mem box free failed!\n");//å†…å­˜é‡Šæ”¾å¤±è´¥ï¼ - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SMEM,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - - return LOS_OK; -} -``` -##### ç»“æžœéªŒè¯ +![](figures/l00167098-中软欧拉开å‘部-iCOS-image-dd30deb7-1840-4cfc-b51d-e55d71b78f71.png) -结果显示 -![](./meta/DevGuide/pic12.png) +##### å®Œæ•´å®žä¾‹ä»£ç  -

    4.3 中断机制

    +[sample\_membox.c](resource/sample_membox.c) -### 概述 +

    4.3 中断机制

    -中断是指出现需è¦æ—¶ï¼ŒCPUæš‚åœæ‰§è¡Œå½“å‰ç¨‹åºï¼Œè½¬è€Œæ‰§è¡Œæ–°ç¨‹åºçš„过程。å³åœ¨ç¨‹åºè¿è¡Œè¿‡ç¨‹ä¸­ï¼Œç³»ç»Ÿå‡ºçŽ°äº†ä¸€ä¸ªå¿…须由CPUç«‹å³å¤„ç†çš„事务。此时,CPU暂时中止当å‰ç¨‹åºçš„执行转而处ç†è¿™ä¸ªäº‹åŠ¡ï¼Œè¿™ä¸ªè¿‡ç¨‹å°±å«åšä¸­æ–­ã€‚ +### 概述 -众多周知,CPU的处ç†é€Ÿåº¦æ¯”外设的è¿è¡Œé€Ÿåº¦å¿«å¾ˆå¤šï¼Œå¤–设å¯ä»¥åœ¨æ²¡æœ‰CPU介入的情况下完æˆä¸€å®šçš„工作,但æŸäº›æƒ…况下需è¦CPU为其åšä¸€å®šçš„工作。 -通过中断机制,在外设ä¸éœ€è¦CPU介入时,CPUå¯ä»¥æ‰§è¡Œå…¶å®ƒä»»åŠ¡ï¼Œè€Œå½“外设需è¦CPU时通过产生中断信å·ä½¿CPUç«‹å³ä¸­æ–­å½“å‰ä»»åŠ¡æ¥å“应中断请求。这样å¯ä»¥ä½¿CPUé¿å…把大é‡æ—¶é—´è€—费在等待ã€æŸ¥è¯¢å¤–设状æ€çš„æ“作上,因此将大大æ高系统实时性以åŠæ‰§è¡Œæ•ˆçŽ‡ã€‚ +中断是指出现需è¦æ—¶ï¼ŒCPUæš‚åœæ‰§è¡Œå½“å‰ç¨‹åºï¼Œè½¬è€Œæ‰§è¡Œæ–°ç¨‹åºçš„过程。å³åœ¨ç¨‹åºè¿è¡Œè¿‡ç¨‹ä¸­ï¼Œç³»ç»Ÿå‡ºçŽ°äº†ä¸€ä¸ªå¿…须由CPUç«‹å³å¤„ç†çš„事务。此时,CPU暂时中止当å‰ç¨‹åºçš„执行转而处ç†è¿™ä¸ªäº‹åŠ¡ï¼Œè¿™ä¸ªè¿‡ç¨‹å°±å«åšä¸­æ–­ã€‚ -Huawei LiteOS的中断支æŒï¼š +众所周知,CPU的处ç†é€Ÿåº¦æ¯”外设的è¿è¡Œé€Ÿåº¦å¿«å¾ˆå¤šï¼Œå¤–设å¯ä»¥åœ¨æ²¡æœ‰CPU介入的情况下完æˆä¸€å®šçš„工作,但æŸäº›æƒ…况下需è¦CPU为其åšä¸€å®šçš„工作。 -- 中断åˆå§‹åŒ– +通过中断机制,在外设ä¸éœ€è¦CPU介入时,CPUå¯ä»¥æ‰§è¡Œå…¶å®ƒä»»åŠ¡ï¼Œè€Œå½“外设需è¦CPU时通过产生中断信å·ä½¿CPUç«‹å³ä¸­æ–­å½“å‰ä»»åŠ¡æ¥å“应中断请求。这样å¯ä»¥ä½¿CPUé¿å…把大é‡æ—¶é—´è€—费在等待ã€æŸ¥è¯¢å¤–设状æ€çš„æ“作上,因此将大大æ高系统实时性以åŠæ‰§è¡Œæ•ˆçŽ‡ã€‚ -- 中断创建 +Huawei LiteOS的中断支æŒï¼š -- å¼€/关中断 +- 中断åˆå§‹åŒ– +- 中断创建 +- å¼€/关中断 +- æ¢å¤ä¸­æ–­ +- 中断使能 +- 中断å±è”½ -- æ¢å¤ä¸­æ–­ +**中断的介ç»** -- 中断使能 +与中断相关的硬件å¯ä»¥åˆ’分为三类:设备ã€ä¸­æ–­æŽ§åˆ¶å™¨ã€CPU本身。 -- 中断å±è”½ -![](./meta/DevGuide/icon_note.png) -Huawei LiteOS å¼€æºç‰ˆæœ¬å¯¹åº”的中断机制暂ä¸æ”¯æŒä¸­æ–­å…±äº«ã€‚ +设备:å‘起中断的æºï¼Œå½“设备需è¦è¯·æ±‚CPU时,产生一个中断信å·ï¼Œè¯¥ä¿¡å·è¿žæŽ¥è‡³ä¸­æ–­æŽ§åˆ¶å™¨ã€‚ -**中断的介ç»** +中断控制器:中断控制器是CPU众多外设中的一个,它一方é¢æŽ¥æ”¶å…¶å®ƒå¤–设中断引脚的输入,å¦ä¸€æ–¹é¢ï¼Œå®ƒä¼šå‘出中断信å·ç»™CPU。å¯ä»¥é€šè¿‡å¯¹ä¸­æ–­æŽ§åˆ¶å™¨ç¼–程实现对中断æºçš„优先级ã€è§¦å‘æ–¹å¼ã€æ‰“开和关闭æºç­‰è®¾ç½®æ“作。常用的中断控制器有VIC(Vector Interrupt Controller)和GIC(General Interrupt Controller),在ARM Cortex-M系列中使用的中断控制器是NVIC(Nested Vector Interrupt Controller)。在ARM Cortex-A7中使用的中断控制器是GIC。 -与中断相关的硬件å¯ä»¥åˆ’分为三类:设备ã€ä¸­æ–­æŽ§åˆ¶å™¨ã€CPU本身。 +CPU:CPU会å“应中断æºçš„请求,中断当å‰æ­£åœ¨æ‰§è¡Œçš„任务,转而执行中断处ç†ç¨‹åºã€‚ -设备:å‘起中断的æºï¼Œå½“设备需è¦è¯·æ±‚CPU时,产生一个中断信å·ï¼Œè¯¥ä¿¡å·è¿žæŽ¥è‡³ä¸­æ–­æŽ§åˆ¶å™¨ã€‚ +**和中断相关的åè¯è§£é‡Š** -中断控制器:中断控制器是CPU众多外设中的一个,它一方é¢æŽ¥æ”¶å…¶å®ƒå¤–设中断引脚的输入,å¦ä¸€æ–¹é¢ï¼Œå®ƒä¼šå‘出中断信å·ç»™CPU。å¯ä»¥é€šè¿‡å¯¹ä¸­æ–­æŽ§åˆ¶å™¨ç¼–程实现对中断æºçš„优先级ã€è§¦å‘æ–¹å¼ã€æ‰“开和关闭æºç­‰è®¾ç½®æ“作。常用的中断控制器有VIC(Vector Interrupt Controller)和GIC(General Interrupt Controller),在ARM Cortex-M系列中使用的中断控制器是NVIC(Nested Vector Interrupt Controller)。 +中断å·ï¼šæ¯ä¸ªä¸­æ–­è¯·æ±‚ä¿¡å·éƒ½ä¼šæœ‰ç‰¹å®šçš„标志,使得计算机能够判断是哪个设备æ出的中断请求,这个标志就是中断å·ã€‚ -CPU:CPU会å“应中断æºçš„请求,中断当å‰æ­£åœ¨æ‰§è¡Œçš„任务,转而执行中断处ç†ç¨‹åºã€‚ +中断请求:“紧急事件â€éœ€å‘CPUæ出申请(å‘一个电脉冲信å·ï¼‰ï¼Œè¦æ±‚中断,åŠè¦æ±‚CPUæš‚åœå½“å‰æ‰§è¡Œçš„任务,转而处ç†è¯¥â€œç´§æ€¥äº‹ä»¶â€ï¼Œè¿™ä¸€ç”³è¯·è¿‡ç¨‹ç§°ä¸ºä¸­æ–­ç”³è¯·ã€‚ -**和中断相关的åè¯è§£é‡Š** +中断优先级:为使系统能够åŠæ—¶å“应并处ç†æ‰€æœ‰ä¸­æ–­ï¼Œç³»ç»Ÿæ ¹æ®ä¸­æ–­æ—¶é—´çš„é‡è¦æ€§å’Œç´§è¿«ç¨‹åº¦ï¼Œå°†ä¸­æ–­æºåˆ†ä¸ºè‹¥å¹²ä¸ªçº§åˆ«ï¼Œç§°ä½œä¸­æ–­ä¼˜å…ˆçº§ã€‚Huawei LiteOS支æŒä¸­æ–­æŽ§åˆ¶å™¨çš„中断优先级åŠä¸­æ–­åµŒå¥—,åŒæ—¶ä¸­æ–­ç®¡ç†æœªå¯¹ä¼˜å…ˆçº§å’ŒåµŒå¥—进行é™åˆ¶ã€‚Huawei LiteOS中所有的中断æºä¼˜å…ˆçº§ç›¸åŒï¼Œä¸æ”¯æŒä¸­æ–­åµŒå¥—或抢å ã€‚ -中断å·ï¼šæ¯ä¸ªä¸­æ–­è¯·æ±‚ä¿¡å·éƒ½ä¼šæœ‰ç‰¹å®šçš„标志,使得计算机能够判断是哪个设备æ出的中断请求,这个标志就是中断å·ã€‚ +中断处ç†ç¨‹åºï¼šå½“外设产生中断请求åŽï¼ŒCPUæš‚åœå½“å‰çš„任务,转而å“应中断申请,å³æ‰§è¡Œä¸­æ–­å¤„ç†ç¨‹åºã€‚ -中断请求:“紧急事件â€éœ€å‘CPUæ出申请(å‘一个电脉冲信å·ï¼‰ï¼Œè¦æ±‚中断,åŠè¦æ±‚CPUæš‚åœå½“å‰æ‰§è¡Œçš„任务,转而处ç†è¯¥â€œç´§æ€¥äº‹ä»¶â€ï¼Œè¿™ä¸€ç”³è¯·è¿‡ç¨‹ç§°ä¸ºä¸­æ–­ç”³è¯·ã€‚ +中断触å‘:中断æºå‘出并é€ç»™CPU控制信å·ï¼Œå°†æŽ¥å£å¡ä¸Šçš„中断触å‘器置“1â€ï¼Œè¡¨æ˜Žè¯¥ä¸­æ–­æºäº§ç”Ÿäº†ä¸­æ–­ï¼Œè¦æ±‚CPU去å“应该中断,CPUæš‚åœå½“å‰ä»»åŠ¡ï¼Œæ‰§è¡Œç›¸åº”的中断处ç†ç¨‹åºã€‚ -中断优先级:为使系统能够åŠæ—¶å“应并处ç†æ‰€æœ‰ä¸­æ–­ï¼Œç³»ç»Ÿæ ¹æ®ä¸­æ–­æ—¶é—´çš„é‡è¦æ€§å’Œç´§è¿«ç¨‹åº¦ï¼Œå°†ä¸­æ–­æºåˆ†ä¸ºè‹¥å¹²ä¸ªçº§åˆ«ï¼Œç§°ä½œä¸­æ–­ä¼˜å…ˆçº§ã€‚Huawei LiteOS支æŒä¸­æ–­æŽ§åˆ¶å™¨çš„中断优先级åŠä¸­æ–­åµŒå¥—,åŒæ—¶ä¸­æ–­ç®¡ç†æœªå¯¹ä¼˜å…ˆçº§å’ŒåµŒå¥—进行é™åˆ¶ã€‚ +中断触å‘类型:外部中断申请通过一个物ç†ä¿¡å·å‘é€åˆ°NVIC或GIC,å¯ä»¥æ˜¯ç”µå¹³è§¦å‘或边沿触å‘。 -中断处ç†ç¨‹åºï¼šå½“外设产生中断请求åŽï¼ŒCPUæš‚åœå½“å‰çš„任务,转而å“应中断申请,å³æ‰§è¡Œä¸­æ–­å¤„ç†ç¨‹åºã€‚ +中断å‘é‡ï¼šä¸­æ–­æœåŠ¡ç¨‹åºçš„å…¥å£åœ°å€ã€‚ -中断触å‘:中断æºå‘出并é€ç»™CPU控制信å·ï¼Œå°†æŽ¥å£å¡ä¸Šçš„中断触å‘器置“1â€ï¼Œè¡¨æ˜Žè¯¥ä¸­æ–­æºäº§ç”Ÿäº†ä¸­æ–­ï¼Œè¦æ±‚CPU去å“应该中断,CPUæš‚åœå½“å‰ä»»åŠ¡ï¼Œæ‰§è¡Œç›¸åº”的中断处ç†ç¨‹åºã€‚ +中断å‘é‡è¡¨ï¼šå­˜å‚¨ä¸­æ–­å‘é‡çš„存储区,中断å‘é‡ä¸Žä¸­æ–­å·å¯¹åº”,中断å‘é‡åœ¨ä¸­æ–­å‘é‡è¡¨ä¸­æŒ‰ç…§ä¸­æ–­å·é¡ºåºå­˜å‚¨ã€‚ -中断触å‘类型:外部中断申请通过一个物ç†ä¿¡å·å‘é€åˆ°NVIC,å¯ä»¥æ˜¯ç”µå¹³è§¦å‘或边沿触å‘。 +中断共享:当外设较少时,å¯ä»¥å®žçŽ°ä¸€ä¸ªå¤–设对应一个中断å·ï¼Œä½†ä¸ºäº†æ”¯æŒæ›´å¤šçš„硬件设备,å¯ä»¥è®©å¤šä¸ªè®¾å¤‡å…±äº«ä¸€ä¸ªä¸­æ–­å·ï¼Œå…±äº«åŒä¸€ä¸ªä¸­æ–­çš„中断处ç†ç¨‹åºå½¢æˆä¸€ä¸ªé“¾è¡¨ï¼Œå½“外部设备产生中断申请时,系统会é历中断å·å¯¹åº”的中断处ç†ç¨‹åºé“¾è¡¨ã€‚ -中断å‘é‡ï¼šä¸­æ–­æœåŠ¡ç¨‹åºçš„å…¥å£åœ°å€ã€‚ +中断底åŠéƒ¨ï¼šä¸­æ–­å¤„ç†ç¨‹åºè€—时应尽å¯èƒ½çŸ­ï¼Œä»¥æ»¡è¶³ä¸­æ–­çš„快速å“应,为了平衡中断处ç†ç¨‹åºçš„性能与工作é‡ï¼Œå°†ä¸­æ–­å¤„ç†ç¨‹åºåˆ†è§£ä¸ºä¸¤éƒ¨åˆ†ï¼šé¡¶åŠéƒ¨å’Œåº•åŠéƒ¨ã€‚ -中断å‘é‡è¡¨ï¼šå­˜å‚¨ä¸­æ–­å‘é‡çš„存储区,中断å‘é‡ä¸Žä¸­æ–­å·å¯¹åº”,中断å‘é‡åœ¨ä¸­æ–­å‘é‡è¡¨ä¸­æŒ‰ç…§ä¸­æ–­å·é¡ºåºå­˜å‚¨ã€‚ +顶åŠéƒ¨å®Œæˆå°½å¯èƒ½å°‘的比较紧急的任务,它往往åªæ˜¯ç®€å•åœ°è¯»å–寄存器中的中断状æ€å¹¶æ¸…除中断标志ä½å³è¿›è¡Œâ€œç™»è®°å·¥ä½œâ€ï¼Œå°†è€—时的底åŠéƒ¨å¤„ç†ç¨‹åºæŒ‚到系统的底åŠéƒ¨æ‰§è¡Œé˜Ÿåˆ—中去。 ### å¼€å‘指导 -#### 使用场景 +#### 使用场景 -当有中断请求产生时,CPUæš‚åœå½“å‰çš„任务,转而去å“应外设请求。根æ®éœ€è¦ï¼Œç”¨æˆ·é€šè¿‡ä¸­æ–­ç”³è¯·ï¼Œæ³¨å†Œä¸­æ–­å¤„ç†ç¨‹åºï¼Œå¯ä»¥æŒ‡å®šCPUå“应中断请求时所执行的具体æ“作。 +当有中断请求产生时,CPUæš‚åœå½“å‰çš„任务,转而去å“应外设请求。根æ®éœ€è¦ï¼Œç”¨æˆ·é€šè¿‡ä¸­æ–­ç”³è¯·ï¼Œæ³¨å†Œä¸­æ–­å¤„ç†ç¨‹åºï¼Œå¯ä»¥æŒ‡å®šCPUå“应中断请求时所执行的具体æ“作。 #### 功能 -Huawei LiteOS 系统中的中断模å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ - -| **接å£å** | **æè¿°** | -|-----------------|--------------------------------| -| LOS\_HwiCreate | 硬中断创建,注册硬中断处ç†ç¨‹åº | -| LOS\_IntUnLock | 开中断 | -| LOS\_IntRestore | æ¢å¤åˆ°å…³ä¸­æ–­ä¹‹å‰çš„çŠ¶æ€ | -| LOS\_IntLock | 关中断 | -| LOS\_HwiDelete | 硬中断删除 | +Huawei LiteOS 系统中的中断模å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    接å£å

    +

    æè¿°

    +

    LOS_HwiCreate

    +

    硬中断创建,注册硬中断处ç†ç¨‹åº

    +

    LOS_IntUnLock

    +

    开中断

    +

    LOS_IntRestore

    +

    æ¢å¤åˆ°å…³ä¸­æ–­ä¹‹å‰çš„状æ€

    +

    LOS_IntLock

    +

    关中断

    +

    HalIrqMask

    +

    中断å±è”½ï¼ˆé€šè¿‡è®¾ç½®å¯„存器,ç¦æ­¢CPUå“应该中断)

    +

    HalIrqUnmask

    +

    中断使能(通过设置寄存器,å…许CPUå“应该中断)

    +

    HalIrqSetAffinity

    +

    设置中断的亲和性,å³è®¾ç½®ä¸­æ–­åœ¨å›ºå®šæ ¸å“应(该函数仅在SMP模å¼ä¸‹æ”¯æŒï¼‰

    +
    #### å¼€å‘æµç¨‹ 1. 修改é…置项 + - 打开硬中断è£å‰ªå¼€å…³ï¼šLOSCFG\_PLATFORM\_HWI定义为YES。 + - é…置硬中断使用最大数:LOSCFG\_PLATFORM\_HWI\_LIMIT。 - - 打开硬中断è£å‰ªå¼€å…³ï¼šLOSCFG\_PLATFORM\_HWI定义为YES - - - é…置硬中断使用最大数:LOSCFG\_PLATFORM\_HWI\_LIMIT - -2. 调用中断åˆå§‹åŒ–Los\_HwiInit接å£ã€‚ - -3. 调用中断创建接å£LOS\_HwiCreate创建中断,根æ®éœ€è¦ä½¿èƒ½æŒ‡å®šä¸­æ–­ã€‚ - -4. 调用LOS\_HwiDelete删除中断。 +2. 调用中断创建接å£LOS\_HwiCreate创建中断。 +3. 调用HalIrqUnmask接å£ä½¿èƒ½æŒ‡å®šä¸­æ–­ã€‚ +4. 调用HalIrqMask接å£å±è”½æŒ‡å®šä¸­æ–­ã€‚ ### 注æ„事项 -- æ ¹æ®å…·ä½“硬件,é…置支æŒçš„最大中断数åŠä¸­æ–­åˆå§‹åŒ–æ“作的寄存器地å€ã€‚ - -- 中断处ç†ç¨‹åºè€—æ—¶ä¸èƒ½è¿‡é•¿ï¼Œå½±å“CPU对中断的åŠæ—¶å“应。 +- æ ¹æ®å…·ä½“硬件,é…置支æŒçš„最大中断数åŠä¸­æ–­åˆå§‹åŒ–æ“作的寄存器地å€ã€‚ +- 中断共享机制,支æŒåŒä¸€ä¸­æ–­å¤„ç†ç¨‹åºçš„é‡å¤æŒ‚载,但中断处ç†ç¨‹åºçš„å…¥å‚dev必须唯一,å³åŒä¸€ä¸­æ–­å·ï¼ŒåŒä¸€devåªèƒ½æŒ‚载一次;但åŒä¸€ä¸­æ–­å·ï¼ŒåŒä¸€ä¸­æ–­å¤„ç†ç¨‹åºï¼Œdevä¸åŒåˆ™å¯ä»¥é‡å¤æŒ‚载。 -- 关中断åŽä¸èƒ½æ‰§è¡Œå¼•èµ·è°ƒåº¦çš„函数。 +- 中断处ç†ç¨‹åºè€—æ—¶ä¸èƒ½è¿‡é•¿ï¼Œå½±å“CPU对中断的åŠæ—¶å“应。 +- Cortex-M系列处ç†å™¨ä¸­1-15中断为内部使用,因此ä¸å»ºè®®ç”¨æˆ·åŽ»ç”³è¯·å’Œåˆ›å»ºã€‚ -- 中断æ¢å¤LOS\_IntRestore()çš„å…¥å‚必须是与之对应的LOS\_IntLock()ä¿å­˜çš„关中断之å‰çš„PRIMASK的值。 - -- Cortex-M系列处ç†å™¨ä¸­1-15中断为内部使用,因此ä¸å»ºè®®ç”¨æˆ·åŽ»ç”³è¯·å’Œåˆ›å»ºã€‚ +- 中断å“应过程中ä¸èƒ½æ‰§è¡Œå¼•èµ·è°ƒåº¦çš„函数。 +- 中断æ¢å¤LOS\_IntRestore\(\)çš„å…¥å‚必须是与之对应的LOS\_IntLock\(\)ä¿å­˜çš„关中断之å‰çš„CPSR的值。 +- Cortex-A7中0-31中断为内部使用,因此ä¸å»ºè®®ç”¨æˆ·åŽ»ç”³è¯·å’Œåˆ›å»ºã€‚ +- 一般ä¸ç›´æŽ¥è°ƒç”¨LOS\_HwiCreate\(\)创建中断;建议使用系统compat中的linux适é…接å£request\_irq创建中断。 ### 编程实例 #### 实例æè¿° -#### 本实例实现如下功能。 - -1. åˆå§‹åŒ–硬件中断 - -2. 中断注册 - -3. 触å‘中断 +本实例实现如下功能: -4. 查看打å°ç»“æžœ +1. 关中断 +2. 中断创建 +3. 中断使能 +4. 中断æ¢å¤ +5. 中断å±è”½ #### 编程示例 **å‰ææ¡ä»¶ï¼š** -在los\_config.h中,将```LOSCFG\_PLATFORM\_HWI```定义为YES。 +- 在los\_config.h中,将LOSCFG\_PLATFORM\_HWI定义为YES。 +- 在los\_config.h中,设置最大硬中断个数LOSCFG\_PLATFORM\_HWI\_LIMIT -在los\_config.h中,设置最大硬中断个数```OS\_HWI\_MAX\_USED\_NUM``` 。 +**说明:** ç›®å‰çš„中断测试代ç æ供了基本框架,中断硬件åˆå§‹åŒ–代ç è¯·ç”¨æˆ·æ ¹æ®å¼€å‘æ¿ç¡¬ä»¶æƒ…况在Example\_Exti0\_Init\(\)函数中自行实现。 -![](./meta/DevGuie/icon_note.png) -ç›®å‰çš„中断测试代ç æ供了基本框架,中断硬件åˆå§‹åŒ–代ç è¯·ç”¨æˆ·æ ¹æ®å¼€å‘æ¿ç¡¬ä»¶æƒ…况在Example\_Exti0\_Init()函数中自行实现。 - -代ç å®žçŽ°å¦‚下: -``` -static void Example_Exti0_Init() -{ - /*add your IRQ init code here*/ - - return; - -} - -static VOID User_IRQHandler(void) -{ - dprintf("\n User IRQ test\n"); - //LOS_InspectStatusSetByID(LOS_INSPECT_INTERRUPT,LOS_INSPECT_STU_SUCCESS); - return; +代ç å®žçŽ°å¦‚下: -} +``` + #include "los_hwi.h" + #include "los_typedef.h" + #define HWI_NUM_INT50 50 + void uart_irqhandle(int irq,void *dev) + { + printf("\n int the func uart_irqhandle \n"); + } + void hwi_test() + { + int a = 1; + UINTPTR uvIntSave; + uvIntSave = LOS_IntLock(); + LOS_HwiCreate(HWI_NUM_INT50, 0,0,uart_irqhandle,NULL);//创建中断 + HalIrqUnmask(HWI_NUM_INT50); + LOS_IntRestore(uvIntSave); + HalIrqMask(HWI_NUM_INT50); + } +``` -UINT32 Example_Interrupt(VOID) -{ - UINTPTR uvIntSave; - uvIntSave = LOS_IntLock(); - - Example_Exti0_Init(); - - LOS_HwiCreate(6, 0,0,User_IRQHandler,0);//创建中断 - - LOS_IntRestore(uvIntSave); - - return LOS_OK; -} -``` +#### 完整实例 -#### ç»“æžœéªŒè¯ -![](./meta/DevGuie/pic13.png) +[sample\_hwi.c](resource/sample_hwi.c) -

    4.4 队列

    +

    4.4 队列

    ### 概述 #### 基本概念 -队列åˆç§°æ¶ˆæ¯é˜Ÿåˆ—,是一ç§å¸¸ç”¨äºŽä»»åŠ¡é—´é€šä¿¡çš„æ•°æ®ç»“构,实现了接收æ¥è‡ªä»»åŠ¡æˆ–中断的ä¸å›ºå®šé•¿åº¦çš„消æ¯ï¼Œå¹¶æ ¹æ®ä¸åŒçš„接å£é€‰æ‹©ä¼ é€’消æ¯æ˜¯å¦å­˜æ”¾åœ¨è‡ªå·±ç©ºé—´ã€‚任务能够从队列里é¢è¯»å–消æ¯ï¼Œå½“队列中的消æ¯æ˜¯ç©ºæ—¶ï¼ŒæŒ‚起读å–任务;当队列中有新消æ¯æ—¶ï¼ŒæŒ‚起的读å–任务被唤醒并处ç†æ–°æ¶ˆæ¯ã€‚ - -用户在处ç†ä¸šåŠ¡æ—¶ï¼Œæ¶ˆæ¯é˜Ÿåˆ—æ供了异步处ç†æœºåˆ¶ï¼Œå…许将一个消æ¯æ”¾å…¥é˜Ÿåˆ—,但并ä¸ç«‹å³å¤„ç†å®ƒï¼ŒåŒæ—¶é˜Ÿåˆ—还能起到缓冲消æ¯ä½œç”¨ã€‚ -Huawei LiteOS中使用队列数æ®ç»“构实现任务异步通信工作,具有如下特性: +队列åˆç§°æ¶ˆæ¯é˜Ÿåˆ—,是一ç§å¸¸ç”¨äºŽä»»åŠ¡é—´é€šä¿¡çš„æ•°æ®ç»“构,实现了接收æ¥è‡ªä»»åŠ¡æˆ–中断的ä¸å›ºå®šé•¿åº¦çš„消æ¯ï¼Œå¹¶æ ¹æ®ä¸åŒçš„接å£é€‰æ‹©ä¼ é€’消æ¯æ˜¯å¦å­˜æ”¾åœ¨è‡ªå·±ç©ºé—´ã€‚任务能够从队列里é¢è¯»å–消æ¯ï¼Œå½“队列中的消æ¯æ˜¯ç©ºæ—¶ï¼ŒæŒ‚起读å–任务;当队列中有新消æ¯æ—¶ï¼ŒæŒ‚起的读å–任务被唤醒并处ç†æ–°æ¶ˆæ¯ã€‚ -- 消æ¯ä»¥å…ˆè¿›å…ˆå‡ºæ–¹å¼æŽ’队,支æŒå¼‚步读写工作方å¼ã€‚ +用户在处ç†ä¸šåŠ¡æ—¶ï¼Œæ¶ˆæ¯é˜Ÿåˆ—æ供了异步处ç†æœºåˆ¶ï¼Œå…许将一个消æ¯æ”¾å…¥é˜Ÿåˆ—,但并ä¸ç«‹å³å¤„ç†å®ƒï¼ŒåŒæ—¶é˜Ÿåˆ—还能起到缓冲消æ¯ä½œç”¨ã€‚ -- 读队列和写队列都支æŒè¶…时机制。 +Huawei LiteOS中使用队列数æ®ç»“构实现任务异步通信工作,具有如下特性: -- å‘é€æ¶ˆæ¯ç±»åž‹ç”±é€šä¿¡åŒæ–¹çº¦å®šï¼Œå¯ä»¥å…许ä¸åŒé•¿åº¦ï¼ˆä¸è¶…过队列节点最大值)消æ¯ã€‚ - -- 一个任务能够从任æ„一个消æ¯é˜Ÿåˆ—接收和å‘é€æ¶ˆæ¯ã€‚ - -- 多个任务能够从åŒä¸€ä¸ªæ¶ˆæ¯é˜Ÿåˆ—接收和å‘é€æ¶ˆæ¯ã€‚ - -- 当队列使用结æŸåŽï¼Œå¦‚果是动æ€ç”³è¯·çš„内存,需è¦é€šè¿‡é‡Šæ”¾å†…存函数回收。 +- 消æ¯ä»¥å…ˆè¿›å…ˆå‡ºæ–¹å¼æŽ’队,支æŒå¼‚步读写工作方å¼ã€‚ +- 读队列和写队列都支æŒè¶…时机制。 +- å‘é€æ¶ˆæ¯ç±»åž‹ç”±é€šä¿¡åŒæ–¹çº¦å®šï¼Œå¯ä»¥å…许ä¸åŒé•¿åº¦ï¼ˆä¸è¶…过队列节点最大值)消æ¯ã€‚ +- 一个任务能够从任æ„一个消æ¯é˜Ÿåˆ—接收和å‘é€æ¶ˆæ¯ã€‚ +- 多个任务能够从åŒä¸€ä¸ªæ¶ˆæ¯é˜Ÿåˆ—接收和å‘é€æ¶ˆæ¯ã€‚ +- 当队列使用结æŸåŽï¼Œå¦‚果是动æ€ç”³è¯·çš„内存,需è¦é€šè¿‡é‡Šæ”¾å†…存函数回收。 #### è¿ä½œæœºåˆ¶ **队列控制å—** -``` -/** - * @ingroup los_queue - * Queue information block structure - */ -typedef struct tagQueueCB -{ - UINT8 *pucQueue; /**< 队列指针 */ - UINT16 usQueueState; /**< é˜Ÿåˆ—çŠ¶æ€ */ - UINT16 usQueueLen; /**< 队列中消æ¯ä¸ªæ•° */ - UINT16 usQueueSize; /**< 消æ¯èŠ‚ç‚¹å¤§å° */ - UNIT16 usQueueID; /**< 队列IDå· */ - UINT16 usQueueHead; /**< 消æ¯å¤´èŠ‚点ä½ç½®ï¼ˆæ•°ç»„下标)*/ - UINT16 usQueueTail; /**< 消æ¯å°¾èŠ‚点ä½ç½®ï¼ˆæ•°ç»„下标)*/ - UINT16 usReadWritableCnt[2]; /**< 队列中å¯å†™æˆ–å¯è¯»æ¶ˆæ¯æ•°ï¼Œ0表示å¯è¯»ï¼Œ1表示å¯å†™*/ - LOS_DL_LIST stReadWriteableList[2]; /**< 读写阻塞队列,0表示读阻塞队列,1表示写阻塞队列*/ - LOS_DL_LIST stMemList; /**< MailBox模å—使用 */ -} QUEUE_CB_S; -``` - -æ¯ä¸ªé˜Ÿåˆ—控制å—中都å«æœ‰é˜Ÿåˆ—状æ€ï¼Œè¡¨ç¤ºè¯¥é˜Ÿåˆ—的使用情况: +``` + /** + * @ingroup los_queue + * Queue information block structure + */ + typedef struct + { + UINT8 *queueHandle; /**< 队列指针 */ + UINT16 queueState; /**< é˜Ÿåˆ—çŠ¶æ€ */ + UINT16 queueLen; /**< 队列中消æ¯ä¸ªæ•° */ + UINT16 queueSize; /**< 消æ¯èŠ‚ç‚¹å¤§å° */ + UINT16 queueID; /**< 队列ID */ + UINT16 queueHead; /**< 消æ¯å¤´èŠ‚点ä½ç½®ï¼ˆæ•°ç»„下标)*/ + UINT16 queueTail; /**< 消æ¯å°¾èŠ‚点ä½ç½®ï¼ˆæ•°ç»„下标)*/ + UINT16 readWriteableCnt[2]; /**< 队列中å¯è¯»æˆ–å¯å†™æ¶ˆæ¯æ•°ï¼Œ + 0:å¯è¯»ï¼Œ1:å¯å†™ */ + LOS_DL_LIST readWriteList[2]; /**< 读å–或写入消æ¯ä»»åŠ¡ç­‰å¾…链表, + 0:读å–链表,1:写入链表 */ + LOS_DL_LIST memList; /**< MailBox模å—使用 */ + } LosQueueCB; +``` -- OS\_QUEUE\_UNUSED:队列没有使用 +æ¯ä¸ªé˜Ÿåˆ—控制å—中都å«æœ‰é˜Ÿåˆ—状æ€ï¼Œè¡¨ç¤ºè¯¥é˜Ÿåˆ—的使用情况: -- OS\_QUEUE\_INUSED:队列被使用 +- OS\_QUEUE\_UNUSED:队列没有使用。 +- OS\_QUEUE\_INUSED:队列被使用。 **队列è¿ä½œåŽŸç†** -创建队列时,根æ®ç”¨æˆ·ä¼ å…¥é˜Ÿåˆ—长度和消æ¯èŠ‚点大å°æ¥å¼€è¾Ÿç›¸åº”的内存空间以供该队列使用,返回队列ID。 +创建队列时,根æ®ç”¨æˆ·ä¼ å…¥é˜Ÿåˆ—长度和消æ¯èŠ‚点大å°æ¥å¼€è¾Ÿç›¸åº”的内存空间以供该队列使用,返回队列ID。 -在队列控制å—中维护一个消æ¯å¤´èŠ‚点ä½ç½®Head和一个消æ¯å°¾èŠ‚点ä½ç½®Tailæ¥è¡¨ç¤ºå½“å‰é˜Ÿåˆ—中消æ¯å­˜å‚¨æƒ…况。Head表示队列中被å ç”¨æ¶ˆæ¯çš„起始ä½ç½®ã€‚Tail表示队列中被空闲消æ¯çš„起始ä½ç½®ã€‚刚创建时Headå’ŒTailå‡æŒ‡å‘队列起始ä½ç½®ã€‚ +在队列控制å—中维护一个消æ¯å¤´èŠ‚点ä½ç½®Head和一个消æ¯å°¾èŠ‚点ä½ç½®Tailæ¥è¡¨ç¤ºå½“å‰é˜Ÿåˆ—中消æ¯å­˜å‚¨æƒ…况。Head表示队列中被å ç”¨æ¶ˆæ¯çš„起始ä½ç½®ã€‚Tail表示队列中被空闲消æ¯çš„起始ä½ç½®ã€‚刚创建时Headå’ŒTailå‡æŒ‡å‘队列起始ä½ç½®ã€‚ -写队列时,根æ®Tail找到被å ç”¨æ¶ˆæ¯èŠ‚点末尾的空闲节点作为数æ®å†™å…¥å¯¹è±¡ã€‚如果Tailå·²ç»æŒ‡å‘队列尾则采用回å·æ–¹å¼ã€‚æ ¹æ®usWritableCnt判断队列是å¦å¯ä»¥å†™å…¥ï¼Œä¸èƒ½å¯¹å·²æ»¡ï¼ˆusWritableCnt为0)队列进行写队列æ“作。 +写队列时,根æ®Tail找到被å ç”¨æ¶ˆæ¯èŠ‚点末尾的空闲节点作为数æ®å†™å…¥å¯¹è±¡ã€‚如果Tailå·²ç»æŒ‡å‘队列尾则采用回å·æ–¹å¼ã€‚æ ¹æ®readWriteableCnt\[1\]判断队列是å¦å¯ä»¥å†™å…¥ï¼Œä¸èƒ½å¯¹å·²æ»¡ï¼ˆreadWriteableCnt\[1\]为0)队列进行写队列æ“作。 -读队列时,根æ®Head找到最先写入队列中的消æ¯èŠ‚点进行读å–。如果Headå·²ç»æŒ‡å‘队列尾则采用回å·æ–¹å¼ã€‚æ ¹æ®usReadableCnt判断队列是å¦æœ‰æ¶ˆæ¯è¯»å–,对全部空闲(usReadableCnt为0)队列进行读队列æ“作会引起任务挂起。 +读队列时,根æ®Head找到最先写入队列中的消æ¯èŠ‚点进行读å–。如果Headå·²ç»æŒ‡å‘队列尾则采用回å·æ–¹å¼ã€‚æ ¹æ®readWriteableCnt\[0\]判断队列是å¦æœ‰æ¶ˆæ¯è¯»å–,对全部空闲(readWriteableCnt\[0\]为0)队列进行读队列æ“作会引起任务挂起。 -删除队列时,根æ®ä¼ å…¥çš„队列ID寻找到对应的队列,把队列状æ€ç½®ä¸ºæœªä½¿ç”¨ï¼Œé‡Šæ”¾åŽŸé˜Ÿåˆ—所å çš„空间,对应的队列控制头置为åˆå§‹çŠ¶æ€ã€‚ +删除队列时,根æ®ä¼ å…¥çš„队列ID寻找到对应的队列,把队列状æ€ç½®ä¸ºæœªä½¿ç”¨ï¼Œé‡Šæ”¾åŽŸé˜Ÿåˆ—所å çš„空间,对应的队列控制头置为åˆå§‹çŠ¶æ€ã€‚ -队列读写数æ®æ“作示æ„图 -![](./meta/DevGuide/pic14.png) +**图 1** 队列读写数æ®æ“作示æ„图 +![](figures/队列读写数æ®æ“作示æ„图.png "队列读写数æ®æ“作示æ„图") ### å¼€å‘指导 #### 功能 -Huawei LiteOS中Message消æ¯å¤„ç†æ¨¡å—æ供了以下功能。 +Huawei LiteOS中Message消æ¯å¤„ç†æ¨¡å—æ供了以下功能。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    创建消æ¯é˜Ÿåˆ—

    +

    LOS_QueueCreate

    +

    创建一个消æ¯é˜Ÿåˆ—。

    +

    读队列(ä¸å¸¦æ‹·è´ï¼‰

    +

    LOS_QueueRead

    +

    读å–指定队列头部中的数æ®ï¼ˆé˜Ÿåˆ—节点中的数æ®å®žé™…上是一个地å€ï¼‰ã€‚

    +

    写队列(ä¸å¸¦æ‹·è´ï¼‰

    +

    LOS_QueueWrite

    +

    å‘指定队列尾部写入用户Buffer的地å€ã€‚

    +

    读队列(带拷è´ï¼‰

    +

    LOS_QueueReadCopy

    +

    读å–指定队列头部中的数æ®ã€‚

    +

    写队列(带拷è´ï¼‰

    +

    LOS_QueueWriteCopy

    +

    å‘指定队列尾部写入用户Bufferçš„æ•°æ®ã€‚

    +

    写队列(ä¸å¸¦æ‹·è´ï¼‰

    +

    LOS_QueueWriteHead

    +

    å‘指定队列的头部写入用户Buffer的地å€ã€‚

    +

    写队列(带拷è´ï¼‰

    +

    LOS_QueueWriteHeadCopy

    +

    å‘指定队列的头部写入用户Bufferçš„æ•°æ®ã€‚

    +

    删除队列

    +

    LOS_QueueDelete

    +

    删除一个指定的队列。

    +

    获å–队列信æ¯

    +

    LOS_QueueInfoGet

    +

    获å–指定队列信æ¯ã€‚

    +
    -| 功能分类 | 接å£å | æè¿° | -|--------------------|---------------------|----------------------------------------------------------| -| 创建消æ¯é˜Ÿåˆ— | LOS\_QueueCreate | 创建一个消æ¯é˜Ÿåˆ— | -| 读队列(ä¸å¸¦æ‹·è´ï¼‰ | LOS\_QueueRead | 读å–指定队列中的数æ®ã€‚(buff里存放的是队列节点的地å€ï¼‰ | -| 写队列(ä¸å¸¦æ‹·è´ï¼‰ | LOS\_QueueWrite | å‘指定队列写数æ®ã€‚(写入队列节点中的是buff的地å€ï¼‰ | -| 读队列(带拷è´ï¼‰ | LOS\_QueueReadCopy | 读å–指定队列中的数æ®ã€‚(buff里存放的是队列节点中的数æ®ï¼‰ | -| 写队列(带拷è´ï¼‰ | LOS\_QueueWriteCopy | å‘指定队列写数æ®ã€‚(写入队列节点中的是buff中的数æ®ï¼‰ | -| 写队列(头部) | LOS\_QueueWriteHead | å‘æŒ‡å®šé˜Ÿåˆ—çš„å¤´éƒ¨å†™æ•°æ® | -| 删除队列 | LOS\_QueueDelete | 删除一个指定的队列 | -| 获å–é˜Ÿåˆ—ä¿¡æ¯ | LOS\_QueueInfoGet | 获å–æŒ‡å®šé˜Ÿåˆ—ä¿¡æ¯ | - -#### å¼€å‘æµç¨‹ +#### å¼€å‘æµç¨‹ 使用队列模å—的典型æµç¨‹å¦‚下: 1. 创建消æ¯é˜Ÿåˆ—LOS\_QueueCreate。 - 创建æˆåŠŸåŽï¼Œå¯ä»¥å¾—到消æ¯é˜Ÿåˆ—çš„ID值。 - -2. 写队列æ“作函数LOS\_QueueWrite。 - -3. 读队列æ“作函数LOS\_QueueRead。 + 创建æˆåŠŸåŽï¼Œå¯ä»¥å¾—到消æ¯é˜Ÿåˆ—çš„ID值。 +2. 写队列æ“作函数LOS\_QueueWriteCopy。 +3. 读队列æ“作函数LOS\_QueueReadCopy。 4. 获å–队列信æ¯å‡½æ•°LOS\_QueueInfoGet。 - 5. 删除队列LOS\_QueueDelete。 #### QUEUEé”™è¯¯ç  -对队列存在失败å¯èƒ½æ€§çš„æ“作,包括创建队列ã€åˆ é™¤é˜Ÿåˆ—等等,å‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ - -| åºå· | 定义 | 实际数值 | æè¿° | å‚考解决方案 | -|------|-------------------------------------------|------------|-----------------------------------------------|-----------------------------------------------------------------------------------------------------------| -| 1 | LOS\_ERRNO\_QUEUE\_MAXNUM\_ZERO | 0x02000600 | 队列资æºçš„最大数目é…置为0 | é…ç½®è¦å¤§äºŽ0的队列资æºçš„最大数é‡ã€‚如果ä¸ä½¿ç”¨é˜Ÿåˆ—模å—,则将é…置项设置为将队列资æºçš„最大数é‡çš„剪è£è®¾ç½®ä¸ºNO。 | -| 2 | LOS\_ERRNO\_QUEUE\_NO\_MEMORY | 0x02000601 | 队列å—内存无法åˆå§‹åŒ– | 为队列å—分é…更大的内存分区,或å‡å°‘队列资æºçš„æœ€å¤§æ•°é‡ | -| 3 | LOS\_ERRNO\_QUEUE\_CREATE\_NO\_MEMORY | 0x02000602 | 队列创建的内存未能被请求 | 为队列分é…更多的内存,或å‡å°‘è¦åˆ›å»ºçš„队列中的队列长度和节点的数目。 | -| 4 | LOS\_ERRNO\_QUEUE\_SIZE\_TOO\_BIG | 0x02000603 | 队列创建时消æ¯é•¿åº¦è¶…è¿‡ä¸Šé™ | 更改创建队列中最大消æ¯çš„大å°è‡³ä¸è¶…è¿‡ä¸Šé™ | -| 5 | LOS\_ERRNO\_QUEUE\_CB\_UNAVAILABLE | 0x02000604 | 已超过创建的队列的数é‡çš„ä¸Šé™ | 增加队列的é…置资æºæ•°é‡ | -| 6 | LOS\_ERRNO\_QUEUE\_NOT\_FOUND | 0x02000605 | 无效的队列 | ç¡®ä¿é˜Ÿåˆ—ID是有效的 | -| 7 | LOS\_ERRNO\_QUEUE\_PEND\_IN\_LOCK | 0x02000606 | 当任务被é”定时,ç¦æ­¢åœ¨é˜Ÿåˆ—中被阻塞 | 使用队列å‰è§£é”任务 | -| 8 | LOS\_ERRNO\_QUEUE\_TIMEOUT | 0x02000607 | 等待处ç†é˜Ÿåˆ—的时间超时 | 检查设置的超时时间是å¦åˆé€‚ | -| 9 | LOS\_ERRNO\_QUEUE\_IN\_TSKUSE | 0x02000608 | 阻塞任务的队列ä¸èƒ½è¢«åˆ é™¤ | 使任务能够获得资æºè€Œä¸æ˜¯åœ¨é˜Ÿåˆ—中被阻塞 | -| 10 | LOS\_ERRNO\_QUEUE\_WRITE\_IN\_INTERRUPT | 0x02000609 | 在中断处ç†ç¨‹åºä¸­ä¸èƒ½å†™é˜Ÿåˆ— | 将写队列设为éžé˜»å¡žæ¨¡å¼ | -| 11 | LOS\_ERRNO\_QUEUE\_NOT\_CREATE | 0x0200060a | 队列未创建 | 检查队列中传递的å¥æŸ„是å¦æœ‰æ•ˆ | -| 12 | LOS\_ERRNO\_QUEUE\_IN\_TSKWRITE | 0x0200060b | 队列读写ä¸åŒæ­¥ | åŒæ­¥é˜Ÿåˆ—的读写 | -| 13 | LOS\_ERRNO\_QUEUE\_CREAT\_PTR\_NULL | 0x0200060c | 队列创建过程中传递的å‚数为空指针 | ç¡®ä¿ä¼ é€’çš„å‚æ•°ä¸ä¸ºç©ºæŒ‡é’ˆ | -| 14 | LOS\_ERRNO\_QUEUE\_PARA\_ISZERO | 0x0200060d | 队列创建过程中传递的队列长度或消æ¯èŠ‚点大å°ä¸º0 | 传入正确的队列长度和消æ¯èŠ‚ç‚¹å¤§å° | -| 15 | LOS\_ERRNO\_QUEUE\_INVALID | 0x0200060e | 读å–队列ã€å†™å…¥é˜Ÿåˆ—çš„handle无效 | 检查队列中传递的handle是å¦æœ‰æ•ˆ | -| 16 | LOS\_ERRNO\_QUEUE\_READ\_PTR\_NULL | 0x0200060f | 队列读å–过程中传递的指针为空 | 检查指针中传递的是å¦ä¸ºç©º | -| 17 | LOS\_ERRNO\_QUEUE\_READSIZE\_ISZERO | 0x02000610 | 队列读å–过程中传递的缓冲区大å°ä¸º0 | é€šè¿‡ä¸€ä¸ªæ­£ç¡®çš„ç¼“å†²åŒºå¤§å° | -| 18 | LOS\_ERRNO\_QUEUE\_WRITE\_PTR\_NULL | 0x02000612 | 队列写入过程中传递的指针为空 | 检查指针中传递的是å¦ä¸ºç©º | -| 19 | LOS\_ERRNO\_QUEUE\_WRITESIZE\_ISZERO | 0x02000613 | 队列写入过程中传递的缓冲区大å°ä¸º0 | é€šè¿‡ä¸€ä¸ªæ­£ç¡®çš„ç¼“å†²åŒºå¤§å° | -| 20 | LOS\_ERRNO\_QUEUE\_WRITE\_SIZE\_TOO\_BIG | 0x02000615 | 队列写入过程中传递的缓冲区大å°æ¯”队列大å°è¦å¤§ | å‡å°‘缓冲区大å°ï¼Œæˆ–增大队列节点 | -| 21 | LOS\_ERRNO\_QUEUE\_ISFULL | 0x02000616 | 在队列写入过程中没有å¯ç”¨çš„空闲节点 | ç¡®ä¿åœ¨é˜Ÿåˆ—写入之å‰ï¼Œå¯ä»¥ä½¿ç”¨ç©ºé—²çš„节点 | -| 22 | LOS\_ERRNO\_QUEUE\_PTR\_NULL | 0x02000617 | 正在获å–队列信æ¯æ—¶ä¼ é€’的指针为空 | 检查指针中传递的是å¦ä¸ºç©º | -| 23 | LOS\_ERRNO\_QUEUE\_READ\_IN\_INTERRUPT | 0x02000618 | 在中断处ç†ç¨‹åºä¸­ä¸èƒ½è¯»é˜Ÿåˆ— | 将读队列设为éžé˜»å¡žæ¨¡å¼ | -| 24 | LOS\_ERRNO\_QUEUE\_MAIL\_HANDLE\_INVALID | 0x02000619 | 正在释放队列的内存时传递的队列的handle无效 | 检查队列中传递的handle是å¦æœ‰æ•ˆ | -| 25 | LOS\_ERRNO\_QUEUE\_MAIL\_PTR\_INVALID | 0x0200061a | 传入的消æ¯å†…存池指针为空 | 检查指针是å¦ä¸ºç©º | -| 26 | LOS\_ERRNO\_QUEUE\_MAIL\_FREE\_ERROR | 0x0200061b | membox内存释放失败 | ä¼ å…¥éžç©ºmembox内存指针 | -| 27 | LOS\_ERRNO\_QUEUE\_ISEMPTY | 0x0200061d | 队列已空 | ç¡®ä¿åœ¨è¯»å–队列时包å«æ¶ˆæ¯ | -| 28 | LOS\_ERRNO\_QUEUE\_READ\_SIZE\_TOO\_SMALL | 0x0200061f | 读缓冲区大å°å°äºŽé˜Ÿåˆ—å¤§å° | 增加缓冲区大å°ï¼Œæˆ–å‡å°é˜Ÿåˆ—èŠ‚ç‚¹å¤§å° | +对队列存在失败å¯èƒ½æ€§çš„æ“作,包括创建队列ã€åˆ é™¤é˜Ÿåˆ—等等,å‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_QUEUE_MAXNUM_ZERO

    +

    0x02000600

    +

    队列资æºçš„最大数目é…置为0。

    +

    é…ç½®è¦å¤§äºŽ0的队列资æºçš„最大数é‡ã€‚如果ä¸ä½¿ç”¨é˜Ÿåˆ—模å—,则将é…置项设置为将队列资æºçš„最大数é‡çš„剪è£è®¾ç½®ä¸ºNO。

    +

    2

    +

    LOS_ERRNO_QUEUE_NO_MEMORY

    +

    0x02000601

    +

    队列å—内存无法åˆå§‹åŒ–。

    +

    为队列å—分é…更大的内存分区,或å‡å°‘队列资æºçš„最大数é‡ã€‚

    +

    +

    3

    +

    LOS_ERRNO_QUEUE_CREATE_NO_MEMORY

    +

    0x02000602

    +

    队列创建的内存未能被请求。

    +

    为队列分é…更多的内存,或å‡å°‘è¦åˆ›å»ºçš„队列中的队列长度和节点的数目。

    +

    4

    +

    LOS_ERRNO_QUEUE_SIZE_TOO_BIG

    +

    0x02000603

    +

    队列创建时消æ¯é•¿åº¦è¶…过上é™ã€‚

    +

    更改创建队列中最大消æ¯çš„大å°è‡³ä¸è¶…过上é™ã€‚

    +

    5

    +

    LOS_ERRNO_QUEUE_CB_UNAVAILABLE

    +

    0x02000604

    +

    已超过创建的队列的数é‡çš„上é™ã€‚

    +

    增加队列的é…置资æºæ•°é‡ã€‚

    +

    6

    +

    LOS_ERRNO_QUEUE_NOT_FOUND

    +

    0x02000605

    +

    无效的队列。

    +

    ç¡®ä¿é˜Ÿåˆ—ID有效。

    +

    7

    +

    LOS_ERRNO_QUEUE_PEND_IN_LOCK

    +

    0x02000606

    +

    当任务被é”定时,ç¦æ­¢åœ¨é˜Ÿåˆ—中被阻塞。

    +

    使用队列å‰è§£é”任务。

    +

    8

    +

    LOS_ERRNO_QUEUE_TIMEOUT

    +

    0x02000607

    +

    等待处ç†é˜Ÿåˆ—的时间超时。

    +

    检查设置的超时时间是å¦åˆé€‚。

    +

    9

    +

    LOS_ERRNO_QUEUE_IN_TSKUSE

    +

    0x02000608

    +

    阻塞任务的队列ä¸èƒ½è¢«åˆ é™¤ã€‚

    +

    使任务能够获得资æºè€Œä¸æ˜¯åœ¨é˜Ÿåˆ—中被阻塞。

    +

    10

    +

    LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT

    +

    0x02000609

    +

    在中断处ç†ç¨‹åºä¸­ä¸èƒ½å†™é˜Ÿåˆ—。

    +

    将写队列设为éžé˜»å¡žæ¨¡å¼ã€‚

    +

    11

    +

    LOS_ERRNO_QUEUE_NOT_CREATE

    +

    0x0200060a

    +

    队列未创建。

    +

    检查队列中传递的å¥æŸ„是å¦æœ‰æ•ˆã€‚

    +

    12

    +

    LOS_ERRNO_QUEUE_IN_TSKWRITE

    +

    0x0200060b

    +

    队列读写ä¸åŒæ­¥ã€‚

    +

    åŒæ­¥é˜Ÿåˆ—的读写。

    +

    13

    +

    LOS_ERRNO_QUEUE_CREAT_PTR_NULL

    +

    0x0200060c

    +

    队列创建过程中传递的å‚数为空指针。

    +

    ç¡®ä¿ä¼ é€’çš„å‚æ•°ä¸ä¸ºç©ºæŒ‡é’ˆã€‚

    +

    14

    +

    LOS_ERRNO_QUEUE_PARA_ISZERO

    +

    0x0200060d

    +

    队列创建过程中传递的队列长度或消æ¯èŠ‚点大å°ä¸º0。

    +

    传入正确的队列长度和消æ¯èŠ‚点大å°ã€‚

    +

    15

    +

    LOS_ERRNO_QUEUE_INVALID

    +

    0x0200060e

    +

    读å–队列ã€å†™å…¥é˜Ÿåˆ—çš„handle无效。

    +

    检查队列中传递的handle是å¦æœ‰æ•ˆ

    +

    16

    +

    LOS_ERRNO_QUEUE_READ_PTR_NULL

    +

    0x0200060f

    +

    队列读å–过程中传递的指针为空。

    +

    检查指针中传递的是å¦ä¸ºç©ºã€‚

    +

    17

    +

    LOS_ERRNO_QUEUE_READSIZE_ISZERO

    +

    0x02000610

    +

    队列读å–过程中传递的缓冲区大å°ä¸º0。

    +

    通过一个正确的缓冲区大å°ã€‚

    +

    18

    +

    LOS_ERRNO_QUEUE_WRITE_PTR_NULL

    +

    0x02000612

    +

    队列写入过程中传递的指针为空。

    +

    检查指针中传递的是å¦ä¸ºç©ºã€‚

    +

    19

    +

    LOS_ERRNO_QUEUE_WRITESIZE_ISZERO

    +

    0x02000613

    +

    队列写入过程中传递的缓冲区大å°ä¸º0。

    +

    通过一个正确的缓冲区大å°ã€‚

    +

    20

    +

    LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG

    +

    0x02000615

    +

    队列写入过程中传递的缓冲区大å°æ¯”队列大å°è¦å¤§ã€‚

    +

    å‡å°‘缓冲区大å°ï¼Œæˆ–增大队列节点。

    +

    +

    +

    21

    +

    LOS_ERRNO_QUEUE_ISFULL

    +

    0x02000616

    +

    在队列写入过程中没有å¯ç”¨çš„空闲节点。

    +

    ç¡®ä¿åœ¨é˜Ÿåˆ—写入之å‰ï¼Œå¯ä»¥ä½¿ç”¨ç©ºé—²çš„节点。

    +

    +

    +

    22

    +

    LOS_ERRNO_QUEUE_PTR_NULL

    +

    0x02000617

    +

    正在获å–队列信æ¯æ—¶ä¼ é€’的指针为空。

    +

    检查指针中传递的是å¦ä¸ºç©ºã€‚

    +

    23

    +

    LOS_ERRNO_QUEUE_READ_IN_INTERRUPT

    +

    0x02000618

    +

    在中断处ç†ç¨‹åºä¸­ä¸èƒ½è¯»é˜Ÿåˆ—。

    +

    将读队列设为éžé˜»å¡žæ¨¡å¼ã€‚

    +

    24

    +

    LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID

    +

    0x02000619

    +

    正在释放队列的内存时传递的队列的handle无效。

    +

    检查队列中传递的handle是å¦æœ‰æ•ˆã€‚

    +

    25

    +

    LOS_ERRNO_QUEUE_MAIL_PTR_INVALID

    +

    0x0200061a

    +

    传入的消æ¯å†…存池指针为空。

    +

    检查指针是å¦ä¸ºç©ºã€‚

    +

    26

    +

    LOS_ERRNO_QUEUE_MAIL_FREE_ERROR

    +

    0x0200061b

    +

    membox内存释放失败。

    +

    ä¼ å…¥éžç©ºmembox内存指针。

    +

    27

    +

    LOS_ERRNO_QUEUE_ISEMPTY

    +

    0x0200061d

    +

    队列已空。

    +

    ç¡®ä¿åœ¨è¯»å–队列时包å«æ¶ˆæ¯ã€‚

    +

    28

    +

    LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL

    +

    0x0200061f

    +

    读缓冲区大å°å°äºŽé˜Ÿåˆ—大å°ã€‚

    +

    增加缓冲区大å°ï¼Œæˆ–å‡å°é˜Ÿåˆ—节点大å°ã€‚

    +
    #### å¹³å°å·®å¼‚性 -无。 - -### 注æ„事项 - -- 系统å¯é…置的队列资æºä¸ªæ•°æ˜¯æŒ‡ï¼šæ•´ä¸ªç³»ç»Ÿçš„队列资æºæ€»ä¸ªæ•°ï¼Œè€Œéžç”¨æˆ·èƒ½ä½¿ç”¨çš„个数。例如:系统软件定时器多å ç”¨ä¸€ä¸ªé˜Ÿåˆ—资æºï¼Œé‚£ä¹ˆç³»ç»Ÿå¯é…置的队列资æºå°±ä¼šå‡å°‘一个。 -- 调用LOS\_QueueCreate 函数时所传入的队列å暂时未使用,作为以åŽçš„预留å‚数。 - -- 队列接å£å‡½æ•°ä¸­çš„å…¥å‚uwTimeOut是指相对时间。 +无。 -- LOS\_QueueReadCopyå’ŒLOS\_QueueWriteCopy是一组接å£ï¼ŒLOS\_QueueReadå’ŒLOS\_QueueWrite是一组接å£ï¼Œä¸¤ç»„接å£éœ€è¦é…套使用。 +### 注æ„事项 -- 鉴于LOS\_QueueWriteå’ŒLOS\_QueueRead这组接å£å®žé™…æ“作的是数æ®åœ°å€ï¼Œç”¨æˆ·å¿…é¡»ä¿è¯è°ƒç”¨LOS\_QueueRead获å–到的指针所指å‘内存区域在读队列期间没有被异常修改或释放,å¦åˆ™å¯èƒ½ä¼šå¯¼è‡´ä¸å¯é¢„知的åŽæžœã€‚ +- 系统å¯é…置的队列资æºä¸ªæ•°æ˜¯æŒ‡ï¼šæ•´ä¸ªç³»ç»Ÿçš„队列资æºæ€»ä¸ªæ•°ï¼Œè€Œéžç”¨æˆ·èƒ½ä½¿ç”¨çš„个数。例如:系统软件定时器多å ç”¨ä¸€ä¸ªé˜Ÿåˆ—资æºï¼Œé‚£ä¹ˆç³»ç»Ÿå¯é…置的队列资æºå°±ä¼šå‡å°‘一个。 +- 调用 LOS\_QueueCreate 函数时所传入的队列å暂时未使用,作为以åŽçš„预留å‚数。 +- 队列接å£å‡½æ•°ä¸­çš„å…¥å‚uwTimeOut是指相对时间。 +- LOS\_QueueReadCopyå’ŒLOS\_QueueWriteCopyåŠLOS\_QueueWriteHeadCopy是一组接å£ï¼ŒLOS\_QueueReadå’ŒLOS\_QueueWriteåŠLOS\_QueueWriteHead是一组接å£ï¼Œä¸¤ç»„接å£éœ€è¦é…套使用。 +- 鉴于LOS\_QueueWriteHeadå’ŒLOS\_QueueRead这组接å£å®žé™…æ“作的是数æ®åœ°å€ï¼Œç”¨æˆ·å¿…é¡»ä¿è¯è°ƒç”¨LOS\_QueueRead获å–到的指针所指å‘内存区域在读队列期间没有被异常修改或释放,å¦åˆ™å¯èƒ½ä¼šå¯¼è‡´ä¸å¯é¢„知的åŽæžœã€‚ +- 鉴于LOS\_QueueWriteå’ŒLOS\_QueueWriteHeadå’ŒLOS\_QueueRead这组接å£å®žé™…æ“作的是数æ®åœ°å€ï¼Œä¹Ÿå°±æ„味ç€å®žé™…Writeå’ŒRead的长度仅仅是一个指针数æ®ï¼Œå› æ­¤ç”¨æˆ·ä½¿ç”¨è¿™ç»„接å£ä¹‹å‰ï¼Œéœ€ç¡®ä¿ç›¸å…³é˜Ÿåˆ—在创建时的消æ¯é•¿åº¦ä¸ºä¸€ä¸ªæŒ‡é’ˆçš„长度,é¿å…ä¸å¿…è¦çš„浪费和读å–失败。 +- LOS\_QueueWriteå’ŒLOS\_QueueWriteHeadå’ŒLOS\_QueueRead这组接å£æ­£åœ¨è¢«é€æ­¥åºŸå¼ƒï¼Œå»ºè®®ä½¿ç”¨LOS\_QueueWriteCopyå’ŒLOS\_QueueWriteHeadCopyå’ŒLOS\_QueueReadCopyåšä¸ºæ›¿ä»£ã€‚ ### 编程实例 #### 实例æè¿° -创建一个队列,两个任务。任务1调用å‘é€æŽ¥å£å‘é€æ¶ˆæ¯ï¼›ä»»åŠ¡2通过接收接å£æŽ¥æ”¶æ¶ˆæ¯ã€‚ - -1. 通过LOS\_TaskCreate创建任务1和任务2。 -2. 通过LOS\_QueueCreate创建一个消æ¯é˜Ÿåˆ—。 - -3. 在任务1 send\_Entry中å‘é€æ¶ˆæ¯ã€‚ - -4. 在任务2 recv\_Entry中接收消æ¯ã€‚ +创建一个队列,两个任务。任务1调用å‘é€æŽ¥å£å‘é€æ¶ˆæ¯ï¼›ä»»åŠ¡2通过接收接å£æŽ¥æ”¶æ¶ˆæ¯ã€‚ -5. 通过LOS\_QueueDelete删除队列。 +1. 通过LOS\_TaskCreate创建任务1和任务2。 +2. 通过LOS\_QueueCreate创建一个消æ¯é˜Ÿåˆ—。 +3. 在任务1 send\_Entry中å‘é€æ¶ˆæ¯ã€‚ +4. 在任务2 recv\_Entry中接收消æ¯ã€‚ +5. 通过LOS\_QueueDelete删除队列。 #### 编程示例 -``` -#include "los_base.h" -#include "los_task.h" -#include "los_swtmr.h" -#include "los_hwi.h" -#include "los_queue.h" -#include "los_event.h" -#include "los_typedef.h" -#include "los_api_msgqueue.h" -#include "los_inspect_entry.h" +``` + #include "los_task.h" + #include "los_queue.h" + static UINT32 g_uwQueue; + CHAR abuf[] = "test is message x"; + + /*任务1å‘é€æ•°æ®*/ + void *send_Entry(void *arg) + { + UINT32 i = 0,uwRet = 0; + UINT32 uwlen = sizeof(abuf); + + while (i <5) + { + abuf[uwlen -2] = '0' + i; + i++; + + /*å°†abuf里的数æ®å†™å…¥é˜Ÿåˆ—*/ + uwRet = LOS_QueueWrite(g_uwQueue, abuf, uwlen, 0); + if(uwRet != LOS_OK) + { + dprintf("send message failure,error:%x\n",uwRet); + } + + LOS_TaskDelay(5); + } + } + + /*任务2接收数æ®*/ + void *recv_Entry(void *arg) + { + UINT32 uwReadbuf; + UINT32 uwRet = 0; + + while (1) + { + + /*读å–队列里的数æ®å­˜å…¥uwReadbuf里*/ + uwRet = LOS_QueueRead(g_uwQueue, &uwReadbuf, 50, 0); + if(uwRet != LOS_OK) + { + dprintf("recv message failure,error:%x\n",uwRet); + break; + } + + dprintf("recv message:%s\n", (char *)uwReadbuf); + LOS_TaskDelay(5); + } + /*删除队列*/ + while (LOS_OK != LOS_QueueDelete(g_uwQueue)) + { + LOS_TaskDelay(1); + } + + dprintf("delete the queue success!\n"); + } + + int Example_creat_task(void) + { + UINT32 uwRet = 0; + UINT32 uwTask1, uwTask2; + TSK_INIT_PARAM_S stInitParam1; + + /*创建任务1*/ + stInitParam1.pfnTaskEntry = send_Entry; + stInitParam1.usTaskPrio = 9; + stInitParam1.uwStackSize = 0x400; + stInitParam1.pcName = "sendQueue"; + stInitParam1.uwResved = LOS_TASK_STATUS_DETACHED; + LOS_TaskLock();//é”ä½ä»»åŠ¡ï¼Œé˜²æ­¢æ–°åˆ›å»ºçš„任务比本任务高而å‘生调度 + uwRet = LOS_TaskCreate(&uwTask1, &stInitParam1); + if(uwRet != LOS_OK) + { + dprintf("create task1 failed!,error:%x\n",uwRet); + return uwRet; + } + + /*创建任务2*/ + stInitParam1.pfnTaskEntry = recv_Entry; + uwRet = LOS_TaskCreate(&uwTask2, &stInitParam1); + if(uwRet != LOS_OK) + { + dprintf("create task2 failed!,error:%x\n",uwRet); + return uwRet; + } + + /*创建队列*/ + uwRet = LOS_QueueCreate("queue", 5, &g_uwQueue, 0, 50); + if(uwRet != LOS_OK) + { + dprintf("create queue failure!,error:%x\n",uwRet); + } + + dprintf("create the queue success!\n"); + LOS_TaskUnlock();//解é”任务,åªæœ‰é˜Ÿåˆ—创建åŽæ‰å¼€å§‹ä»»åŠ¡è°ƒåº¦ + } +``` -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ +#### ç»“æžœéªŒè¯ -static UINT32 g_uwQueue; -static CHAR abuf[] = "test is message x"; +![](figures/wwx300029-中软欧拉开å‘部-iCOS-image-7af87939-8a3f-4948-9de4-4032c6292d6e.png) -/*任务1å‘é€æ•°æ®*/ -static void *send_Entry(UINT32 uwParam1, - UINT32 uwParam2, - UINT32 uwParam3, - UINT32 uwParam4) -{ - UINT32 i = 0,uwRet = 0; - UINT32 uwlen = sizeof(abuf); +#### å®Œæ•´å®žä¾‹ä»£ç  - while (i < API_MSG_NUM) - { - abuf[uwlen -2] = '0' + i; - i++; +[sample\_queue.c](resource/sample_queue.c) - /*å°†abuf里的数æ®å†™å…¥é˜Ÿåˆ—*/ - uwRet = LOS_QueueWrite(g_uwQueue, abuf, uwlen, 0); - if(uwRet != LOS_OK) - { - dprintf("send message failure,error:%x\n",uwRet); - } - - LOS_TaskDelay(5); - } - return NULL; -} - -/*任务2接收数æ®*/ -static void *recv_Entry(UINT32 uwParam1, - UINT32 uwParam2, - UINT32 uwParam3, - UINT32 uwParam4) -{ - UINT32 uwReadbuf; - UINT32 uwRet = LOS_OK; - UINT32 uwMsgCount = 0; - - while (1) - { - - /*读å–队列里的数æ®å­˜å…¥uwReadbuf里*/ - uwRet = LOS_QueueRead(g_uwQueue, &uwReadbuf, 24, 0); - if(uwRet != LOS_OK) - { - dprintf("recv message failure,error:%x\n",uwRet); - break; - } - else - { - dprintf("recv message:%s\n", (char *)uwReadbuf); - uwMsgCount++; - } - - (void)LOS_TaskDelay(5); - } - /*删除队列*/ - while (LOS_OK != LOS_QueueDelete(g_uwQueue)) - { - (void)LOS_TaskDelay(1); - } - - dprintf("delete the queue success!\n"); - - if(API_MSG_NUM == uwMsgCount) - { - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_MSG,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - else - { - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_MSG,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - - return NULL; -} - -UINT32 Example_MsgQueue(void) -{ - UINT32 uwRet = 0; - UINT32 uwTask1, uwTask2; - TSK_INIT_PARAM_S stInitParam1; - - /*创建任务1*/ - stInitParam1.pfnTaskEntry = send_Entry; - stInitParam1.usTaskPrio = 9; - stInitParam1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - stInitParam1.pcName = "sendQueue"; - LOS_TaskLock();//é”ä½ä»»åŠ¡ï¼Œé˜²æ­¢æ–°åˆ›å»ºçš„任务比本任务高而å‘生调度 - uwRet = LOS_TaskCreate(&uwTask1, &stInitParam1); - if(uwRet != LOS_OK) - { - dprintf("create task1 failed!,error:%x\n",uwRet); - return uwRet; - } - - /*创建任务2*/ - stInitParam1.pfnTaskEntry = recv_Entry; - uwRet = LOS_TaskCreate(&uwTask2, &stInitParam1); - if(uwRet != LOS_OK) - { - dprintf("create task2 failed!,error:%x\n",uwRet); - return uwRet; - } - - /*创建队列*/ - uwRet = LOS_QueueCreate("queue", 5, &g_uwQueue, 0, 24); - if(uwRet != LOS_OK) - { - dprintf("create queue failure!,error:%x\n",uwRet); - } - - dprintf("create the queue success!\n"); - LOS_TaskUnlock();//解é”任务,åªæœ‰é˜Ÿåˆ—创建åŽæ‰å¼€å§‹ä»»åŠ¡è°ƒåº¦ - - return LOS_OK; -} -``` - -ç»“æžœéªŒè¯ -![](./meta/DevGuide/pic15.png) - - -

    4.5 事件

    +

    4.5 事件

    ### 概述 #### 基本概念 -事件是一ç§å®žçŽ°ä»»åŠ¡é—´é€šä¿¡çš„机制,å¯ç”¨äºŽå®žçŽ°ä»»åŠ¡é—´çš„åŒæ­¥ï¼Œä½†äº‹ä»¶é€šä¿¡åªèƒ½æ˜¯äº‹ä»¶ç±»åž‹çš„通信,无数æ®ä¼ è¾“。一个任务å¯ä»¥ç­‰å¾…多个事件的å‘生:å¯ä»¥æ˜¯ä»»æ„一个事件å‘生时唤醒任务进行事件处ç†;也å¯ä»¥æ˜¯å‡ ä¸ªäº‹ä»¶éƒ½å‘生åŽæ‰å”¤é†’任务进行事件处ç†ã€‚事件集åˆç”¨32ä½æ— ç¬¦å·æ•´åž‹å˜é‡æ¥è¡¨ç¤ºï¼Œæ¯ä¸€ä½ä»£è¡¨ä¸€ä¸ªäº‹ä»¶ã€‚ -多任务环境下,任务之间往往需è¦åŒæ­¥æ“作,一个等待å³æ˜¯ä¸€ä¸ªåŒæ­¥ã€‚事件å¯ä»¥æ供一对多ã€å¤šå¯¹å¤šçš„åŒæ­¥æ“作。一对多åŒæ­¥æ¨¡åž‹ï¼šä¸€ä¸ªä»»åŠ¡ç­‰å¾…多个事件的触å‘;多对多åŒæ­¥æ¨¡åž‹ï¼šå¤šä¸ªä»»åŠ¡ç­‰å¾…多个事件的触å‘。 +事件是一ç§å®žçŽ°ä»»åŠ¡é—´é€šä¿¡çš„机制,å¯ç”¨äºŽå®žçŽ°ä»»åŠ¡é—´çš„åŒæ­¥ã€‚一个任务å¯ä»¥ç­‰å¾…多个事件的å‘生:å¯ä»¥æ˜¯ä»»æ„一个事件å‘生时唤醒任务进行事件处ç†;也å¯ä»¥æ˜¯å‡ ä¸ªäº‹ä»¶éƒ½å‘生åŽæ‰å”¤é†’任务进行事件处ç†ã€‚ -任务å¯ä»¥é€šè¿‡åˆ›å»ºäº‹ä»¶æŽ§åˆ¶å—æ¥å®žçŽ°å¯¹äº‹ä»¶çš„触å‘和等待æ“作。Huawei LiteOS的事件仅用于任务间的åŒæ­¥ï¼Œä¸æ供数æ®ä¼ è¾“功能。 +多任务环境下,任务之间往往需è¦åŒæ­¥æ“作,一个等待å³æ˜¯ä¸€ä¸ªåŒæ­¥ã€‚事件å¯ä»¥æ供一对多ã€å¤šå¯¹å¤šçš„åŒæ­¥æ“作。一对多åŒæ­¥æ¨¡åž‹ï¼šä¸€ä¸ªä»»åŠ¡ç­‰å¾…多个事件的触å‘;多对多åŒæ­¥æ¨¡åž‹ï¼šå¤šä¸ªä»»åŠ¡ç­‰å¾…多个事件的触å‘。 -Huawei LiteOSæ供的事件具有如下特点: +任务å¯ä»¥é€šè¿‡åˆ›å»ºäº‹ä»¶æŽ§åˆ¶å—æ¥å®žçŽ°å¯¹äº‹ä»¶çš„触å‘和等待æ“作。 -- 事件ä¸ä¸Žä»»åŠ¡ç›¸å…³è”,事件相互独立,一个32ä½çš„å˜é‡ï¼Œç”¨äºŽæ ‡è¯†è¯¥ä»»åŠ¡å‘生的事件类型,其中æ¯ä¸€ä½è¡¨ç¤ºä¸€ç§äº‹ä»¶ç±»åž‹ï¼ˆ0表示该事件类型未å‘生ã€1表示该事件类型已ç»å‘生),一共31ç§äº‹ä»¶ç±»åž‹ï¼ˆç¬¬25ä½ä¿ç•™ï¼‰ã€‚ +Huawei LiteOSæ供的事件具有如下特点: -- 事件仅用于任务间的åŒæ­¥ï¼Œä¸æ供数æ®ä¼ è¾“功能。 - -- 多次å‘任务å‘é€åŒä¸€äº‹ä»¶ç±»åž‹ï¼Œç­‰æ•ˆäºŽåªå‘é€ä¸€æ¬¡ã€‚ - -- å…许多个任务对åŒä¸€äº‹ä»¶è¿›è¡Œè¯»å†™æ“作。 - -- 支æŒäº‹ä»¶è¯»å†™è¶…时机制。 +- 事件ä¸ä¸Žä»»åŠ¡ç›¸å…³è”,事件相互独立,一个32ä½çš„无符å·æ•´åž‹å˜é‡ï¼Œç”¨äºŽæ ‡è¯†è¯¥ä»»åŠ¡å‘生的事件类型,其中æ¯ä¸€ä½è¡¨ç¤ºä¸€ç§äº‹ä»¶ç±»åž‹ï¼ˆ0表示该事件类型未å‘生ã€1表示该事件类型已ç»å‘生)。 +- 事件仅用于任务间的åŒæ­¥ï¼Œä¸æ供数æ®ä¼ è¾“功能。 +- 多次å‘任务å‘é€åŒä¸€äº‹ä»¶ç±»åž‹ï¼Œç­‰æ•ˆäºŽåªå‘é€ä¸€æ¬¡ã€‚ +- å…许多个任务对åŒä¸€äº‹ä»¶è¿›è¡Œè¯»å†™æ“作。 +- 支æŒäº‹ä»¶è¯»å†™è¶…时机制。 **事件控制å—** -``` + +``` /** - * @ingroup los_event - * Event control structure - */ + * @ingroup los_event + * Event control structure + */ typedef struct tagEvent { UINT32 uwEventID; /**标识å‘生的事件类型ä½*/ LOS_DL_LIST stEventList; /**读å–事件任务链表*/ -} EVENT_CB_S, *PEVENT_CB_S; -``` -```uwEventID```:用于标识该任务å‘生的事件类型,其中æ¯ä¸€ä½è¡¨ç¤ºä¸€ç§äº‹ä»¶ç±»åž‹ï¼ˆ0表示该事件类型未å‘生ã€1表示该事件类型已ç»å‘生),一共31ç§äº‹ä»¶ç±»åž‹ï¼Œç¬¬25ä½ç³»ç»Ÿä¿ç•™ã€‚ +} EVENT_CB_S, *PEVENT_CB_S; +``` + +uwEventID:用于标识该任务å‘生的事件类型,其中æ¯ä¸€ä½è¡¨ç¤ºä¸€ç§äº‹ä»¶ç±»åž‹ï¼ˆ0表示该事件类型未å‘生ã€1表示该事件类型已ç»å‘生),一共31ç§äº‹ä»¶ç±»åž‹ï¼Œç¬¬25ä½ç³»ç»Ÿä¿ç•™ã€‚ -**事件读å–模å¼** +**事件读å–模å¼** -在读事件时,å¯ä»¥é€‰æ‹©è¯»å–模å¼ã€‚读å–模å¼å¦‚下: +在读事件时,å¯ä»¥é€‰æ‹©è¯»å–模å¼ã€‚读å–模å¼å¦‚下: -- 所有事件(LOS\_WAITMODE\_AND):读å–掩ç ä¸­æ‰€æœ‰äº‹ä»¶ç±»åž‹ï¼Œåªæœ‰è¯»å–的所有事件类型都å‘生了,æ‰èƒ½è¯»å–æˆåŠŸã€‚ +所有事件(LOS\_WAITMODE\_AND):读å–掩ç ä¸­æ‰€æœ‰äº‹ä»¶ç±»åž‹ï¼Œåªæœ‰è¯»å–的所有事件类型都å‘生了,æ‰èƒ½è¯»å–æˆåŠŸã€‚ -- 任一事件(LOS\_WAITMODE\_OR): 读å–掩ç ä¸­ä»»ä¸€äº‹ä»¶ç±»åž‹ï¼Œè¯»å–的事件中任æ„一ç§äº‹ä»¶ç±»åž‹å‘生了,就å¯ä»¥è¯»å–æˆåŠŸã€‚ +任一事件(LOS\_WAITMODE\_OR): 读å–掩ç ä¸­ä»»ä¸€äº‹ä»¶ç±»åž‹ï¼Œè¯»å–的事件中任æ„一ç§äº‹ä»¶ç±»åž‹å‘生了,就å¯ä»¥è¯»å–æˆåŠŸã€‚ -- 清除事件(LOS\_WAITMODE\_CLR):LOS\_WAITMODE\_AND| LOS\_WAITMODE\_CLR或 LOS\_WAITMODE\_OR| LOS\_WAITMODE\_CLR 时表示读å–æˆåŠŸåŽï¼Œå¯¹åº”事件类型ä½ä¼šè‡ªåŠ¨æ¸…除。 +清除事件(LOS\_WAITMODE\_CLR):这是一ç§é™„加读å–模å¼ï¼Œå¯ä»¥ä¸ŽLOS\_WAITMODE\_ANDå’ŒLOS\_WAITMODE\_OR结åˆä½¿ç”¨ã€‚(LOS\_WAITMODE\_AND| LOS\_WAITMODE\_CLR或 LOS\_WAITMODE\_OR| LOS\_WAITMODE\_CLR),设置该模å¼è¯»å–æˆåŠŸåŽï¼Œå¯¹åº”事件类型ä½ä¼šè‡ªåŠ¨æ¸…除。 #### è¿ä½œæœºåˆ¶ -读事件时,å¯ä»¥æ ¹æ®å…¥å‚事件掩ç ç±»åž‹uwEventMask读å–事件的å•ä¸ªæˆ–者多个事件类型。事件读å–æˆåŠŸåŽï¼Œå¦‚果设置LOS\_WAITMODE\_CLR会清除已读å–到的事件类型,å之ä¸ä¼šæ¸…除已读到的事件类型,需显å¼æ¸…除。å¯ä»¥é€šè¿‡å…¥å‚选择读å–模å¼ï¼Œè¯»å–事件掩ç ç±»åž‹ä¸­æ‰€æœ‰äº‹ä»¶è¿˜æ˜¯è¯»å–事件掩ç ç±»åž‹ä¸­ä»»æ„事件。 +读事件时,å¯ä»¥æ ¹æ®å…¥å‚事件掩ç ç±»åž‹uwEventMask读å–事件的å•ä¸ªæˆ–者多个事件类型。事件读å–æˆåŠŸåŽï¼Œå¦‚果设置LOS\_WAITMODE\_CLR会清除已读å–到的事件类型,å之ä¸ä¼šæ¸…除已读到的事件类型,需显å¼æ¸…除。å¯ä»¥é€šè¿‡å…¥å‚选择读å–模å¼ï¼Œè¯»å–事件掩ç ç±»åž‹ä¸­æ‰€æœ‰äº‹ä»¶è¿˜æ˜¯è¯»å–事件掩ç ç±»åž‹ä¸­ä»»æ„事件。 -写事件时,对指定事件写入指定的事件类型,å¯ä»¥ä¸€æ¬¡åŒæ—¶å†™å¤šä¸ªäº‹ä»¶ç±»åž‹ã€‚写事件会触å‘任务调度。 +写事件时,对指定事件写入指定的事件类型,å¯ä»¥ä¸€æ¬¡åŒæ—¶å†™å¤šä¸ªäº‹ä»¶ç±»åž‹ã€‚写事件会触å‘任务调度。 -清除事件时,根æ®å…¥å‚事件和待清除的事件类型,对事件对应ä½è¿›è¡Œæ¸…0æ“作。 +清除事件时,根æ®å…¥å‚事件和待清除的事件类型,对事件对应ä½è¿›è¡Œæ¸…0æ“作。 -事件唤醒任务示æ„图 -![](./meta/DevGuide/pic16.png) +**图 1** 事件唤醒任务示æ„图 +![](figures/事件唤醒任务示æ„图.png "事件唤醒任务示æ„图") ### å¼€å‘指导 @@ -1471,187 +2574,343 @@ typedef struct tagEvent Huawei LiteOS系统中的事件模å—为用户æ供下é¢å‡ ä¸ªæŽ¥å£ã€‚ -| 功能分类 | 接å£å | æè¿° | -|--------------|-------------------|--------------------------------------------------------------------------| -| 事件åˆå§‹åŒ– | LOS\_EventInit | åˆå§‹åŒ–ä¸€ä¸ªäº‹ä»¶æŽ§åˆ¶å— | -| 读事件 | LOS\_EventRead | 读å–指定事件类型,超时时间为相对时间:å•ä½ä¸ºTick | -| 写事件 | LOS\_EventWrite | 写指定的事件类型 | -| 清除事件 | LOS\_EventClear | 清除指定的事件类型 | -| æ ¡éªŒäº‹ä»¶æŽ©ç  | LOS\_EventPoll | æ ¹æ®ç”¨æˆ·ä¼ å…¥çš„事件值ã€äº‹ä»¶æŽ©ç åŠæ ¡éªŒæ¨¡å¼ï¼Œè¿”回用户传入的事件是å¦ç¬¦åˆé¢„期 | -| 销æ¯äº‹ä»¶ | LOS\_EventDestroy | 销æ¯æŒ‡å®šçš„äº‹ä»¶æŽ§åˆ¶å— | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    事件åˆå§‹åŒ–

    +

    LOS_EventInit

    +

    åˆå§‹åŒ–一个事件控制å—。

    +

    读事件

    +

    LOS_EventRead

    +

    读å–指定事件类型,超时时间为相对时间:å•ä½ä¸ºTick。

    +

    写事件

    +

    LOS_EventWrite

    +

    写指定的事件类型。

    +

    清除事件

    +

    LOS_EventClear

    +

    清除指定的事件类型。

    +

    校验事件掩ç 

    +

    LOS_EventPoll

    +

    æ ¹æ®ç”¨æˆ·ä¼ å…¥çš„事件值ã€äº‹ä»¶æŽ©ç åŠæ ¡éªŒæ¨¡å¼ï¼Œè¿”回用户传入的事件是å¦ç¬¦åˆé¢„期。

    +

    销æ¯äº‹ä»¶

    +

    LOS_EventDestroy

    +

    销æ¯æŒ‡å®šçš„事件控制å—。

    +
    #### å¼€å‘æµç¨‹ -使用事件模å—的典型æµç¨‹å¦‚下: +使用事件模å—的典型æµç¨‹å¦‚下: -1. 调用事件åˆå§‹åŒ–LOS\_EventInit接å£ï¼Œåˆå§‹åŒ–事件等待队列。 - -2. 写事件LOS\_EventWrite,é…置事件掩ç ç±»åž‹ã€‚ - -3. 读事件LOS\_EventRead,å¯ä»¥é€‰æ‹©è¯»å–模å¼ã€‚ - -4. 清除事件LOS\_EventClear,清除指定的事件类型。 +1. 调用事件åˆå§‹åŒ–LOS\_EventInit接å£ï¼Œåˆå§‹åŒ–事件等待队列。 +2. 写事件LOS\_EventWrite,é…置事件掩ç ç±»åž‹ã€‚ +3. 读事件LOS\_EventRead,å¯ä»¥é€‰æ‹©è¯»å–模å¼ã€‚ +4. 清除事件LOS\_EventClear,清除指定的事件类型。 #### Eventé”™è¯¯ç  -对事件存在失败的å¯èƒ½æ€§æ“作,包括事件åˆå§‹åŒ–,事件销æ¯ï¼Œäº‹ä»¶è¯»å†™ï¼Œæ—¶é—´æ¸…除。 - -| åºå· | 定义 | 实际值 | æè¿° | å‚考解决方案 | -|------|----------------------------------------|------------|----------------------------------------------------------|--------------------------| -| 1 | LOS\_ERRNO\_EVENT\_SETBIT\_INVALID | 0x02001c00 | 事件ID的第25个bitä¸èƒ½è®¾ç½®ä¸º1,因为该ä½å·²ç»ä½œä¸ºé”™è¯¯ç ä½¿ç”¨ | 事件ID的第25bit置为0 | -| 2 | LOS\_ERRNO\_EVENT\_READ\_TIMEOUT | 0x02001c01 | 读超时 | 增加等待时间或者é‡æ–°è¯»å– | -| 3 | LOS\_ERRNO\_EVENT\_EVENTMASK\_INVALID | 0x02001c02 | å…¥å‚的事件ID是无效的 | 传入有效的事件IDå‚æ•° | -| 4 | LOS\_ERRNO\_EVENT\_READ\_IN\_INTERRUPT | 0x02001c03 | 在中断中读å–事件 | å¯åŠ¨æ–°çš„任务æ¥èŽ·å–事件 | -| 5 | LOS\_ERRNO\_EVENT\_FLAGS\_INVALID | 0x02001c04 | 读å–事件的mode无效 | 传入有效的modeå‚æ•° | -| 6 | LOS\_ERRNO\_EVENT\_READ\_IN\_LOCK | 0x02001c05 | 任务é”ä½ï¼Œä¸èƒ½è¯»å–事件 | 解é”任务,å†è¯»å–事件 | -| 7 | LOS\_ERRNO\_EVENT\_PTR\_NULL | 0x02001c06 | 传入的å‚数为空指针 | ä¼ å…¥éžç©ºå…¥å‚ | - -**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下 +对事件存在失败的å¯èƒ½æ€§æ“作,包括事件åˆå§‹åŒ–,事件销æ¯ï¼Œäº‹ä»¶è¯»å†™ï¼Œäº‹ä»¶æ¸…除。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_EVENT_SETBIT_INVALID

    +

    0x02001c00

    +

    事件ID的第25个bitä¸èƒ½è®¾ç½®ä¸º1,因为该ä½å·²ç»ä½œä¸ºé”™è¯¯ç ä½¿ç”¨

    +

    事件ID的第25bit置为0

    +

    2

    +

    LOS_ERRNO_EVENT_READ_TIMEOUT

    +

    0x02001c01

    +

    读超时

    +

    增加等待时间或者é‡æ–°è¯»å–

    +

    3

    +

    LOS_ERRNO_EVENT_EVENTMASK_INVALID

    +

    0x02001c02

    +

    å…¥å‚的事件ID是无效的

    +

    传入有效的事件IDå‚æ•°

    +

    4

    +

    LOS_ERRNO_EVENT_READ_IN_INTERRUPT

    +

    0x02001c03

    +

    在中断中读å–事件

    +

    å¯åŠ¨æ–°çš„任务æ¥èŽ·å–事件

    +

    5

    +

    LOS_ERRNO_EVENT_FLAGS_INVALID

    +

    0x02001c04

    +

    读å–事件的mode无效

    +

    传入有效的modeå‚æ•°

    +

    6

    +

    LOS_ERRNO_EVENT_READ_IN_LOCK

    +

    0x02001c05

    +

    任务é”ä½ï¼Œä¸èƒ½è¯»å–事件

    +

    解é”任务,å†è¯»å–事件

    +

    7

    +

    LOS_ERRNO_EVENT_PTR_NULL

    +

    0x02001c06

    +

    传入的å‚数为空指针

    +

    ä¼ å…¥éžç©ºå…¥å‚

    +

    8

    +

    LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK

    +

    0x02001c07

    +

    在系统任务中读å–事件,如idle和软件定时器

    +

    å¯åŠ¨æ–°çš„任务æ¥èŽ·å–事件

    +

    9

    +

    LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY

    +

    0x02001c08

    +

    事件链表上ä»æœ‰ä»»åŠ¡ï¼Œæ— æ³•è¢«é”€æ¯

    +

    先检查事件链表是å¦ä¸ºç©º

    +
    + +**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„无符å·æ•´åž‹æ•°å­˜å‚¨å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下所示: ``` #define LOS_ERRNO_OS_ERROR(MID, ERRNO) \ + (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) + LOS_ERRTYPE_ERROR:Define critical OS errors + LOS_ERRNO_OS_ID:OS error code flag + MID:OS_MOUDLE_ID + LOS_MOD_EVENT:Event module ID -ERRNO:error ID number + +ERRNO:error ID number ``` -例如: +例如: ``` -#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) +#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) ``` -#### å¹³å°å·®å¼‚性 -无。 +#### å¹³å°å·®å¼‚性 +无。 ### 注æ„事项 -- 在系统åˆå§‹åŒ–之å‰ä¸èƒ½è°ƒç”¨è¯»å†™äº‹ä»¶æŽ¥å£ã€‚如果调用,则系统è¿è¡Œä¼šä¸æ­£å¸¸ã€‚ - -- 在中断中,å¯ä»¥å¯¹äº‹ä»¶å¯¹è±¡è¿›è¡Œå†™æ“作,但ä¸èƒ½è¯»æ“作。 - -- 在é”任务调度状æ€ä¸‹ï¼Œç¦æ­¢ä»»åŠ¡é˜»å¡žä¸Žè¯»äº‹ä»¶ã€‚ - -- LOS\_EventClear å…¥å‚值是:è¦æ¸…除的指定事件类型的åç ï¼ˆ~uwEvents)。 - -- 事件掩ç çš„第25ä½ä¸èƒ½ä½¿ç”¨ï¼ŒåŽŸå› æ˜¯ä¸ºäº†åŒºåˆ«LOS\_EventRead接å£è¿”回的是事件还是错误ç ã€‚ +- 在系统åˆå§‹åŒ–之å‰ä¸èƒ½è°ƒç”¨è¯»å†™äº‹ä»¶æŽ¥å£ã€‚如果调用,则系统è¿è¡Œä¼šä¸æ­£å¸¸ã€‚ +- 在中断中,å¯ä»¥å¯¹äº‹ä»¶å¯¹è±¡è¿›è¡Œå†™æ“作,但ä¸èƒ½è¯»æ“作。 +- 在é”任务调度状æ€ä¸‹ï¼Œç¦æ­¢ä»»åŠ¡é˜»å¡žä¸Žè¯»äº‹ä»¶ã€‚ +- LOS\_EventClear å…¥å‚值是:è¦æ¸…除的指定事件类型的åç ï¼ˆ\~uwEvents)。 +- 事件掩ç çš„第25ä½ä¸èƒ½ä½¿ç”¨ï¼ŒåŽŸå› æ˜¯ä¸ºäº†åŒºåˆ«LOS\_EventRead接å£è¿”回的是事件还是错误ç ã€‚ ### 编程实例 #### 实例æè¿° -示例中,任务Example\_TaskEntry创建一个任务Example\_Event,Example\_Event读事件阻塞,Example\_TaskEntryå‘该任务写事件。 - -1. 在任务Example\_TaskEntry创建任务Example\_Event,其中任务Example\_Event优先级高于Example\_TaskEntry。 - -2. 在任务Example\_Event中读事件0x00000001,阻塞,å‘生任务切æ¢ï¼Œæ‰§è¡Œä»»åŠ¡Example\_TaskEntry。 - -3. 在任务Example\_TaskEntryå‘任务Example\_Event写事件0x00000001,å‘生任务切æ¢ï¼Œæ‰§è¡Œä»»åŠ¡Example\_Event。 - -4. Example\_Event得以执行,直到任务结æŸã€‚ +示例中,任务Example\_TaskEntry创建一个任务Example\_Event,Example\_Event读事件阻塞,Example\_TaskEntryå‘该任务写事件。 -5. Example\_TaskEntry得以执行,直到任务结æŸã€‚ +1. 在任务Example\_TaskEntry创建任务Example\_Event,其中任务Example\_Event优先级高于Example\_TaskEntry。 +2. 在任务Example\_Event中读事件0x00000001,阻塞,å‘生任务切æ¢ï¼Œæ‰§è¡Œä»»åŠ¡Example\_TaskEntry。 +3. 在任务Example\_TaskEntryå‘任务Example\_Event写事件0x00000001,å‘生任务切æ¢ï¼Œæ‰§è¡Œä»»åŠ¡Example\_Event。 +4. Example\_Event得以执行,直到任务结æŸã€‚ +5. Example\_TaskEntry得以执行,直到任务结æŸã€‚ #### 编程示例 -å¯ä»¥é€šè¿‡æ‰“å°çš„å…ˆåŽé¡ºåºç†è§£äº‹ä»¶æ“作时伴éšçš„任务切æ¢ã€‚ +å¯ä»¥é€šè¿‡æ‰“å°çš„å…ˆåŽé¡ºåºç†è§£äº‹ä»¶æ“作时伴éšçš„任务切æ¢ã€‚ -代ç å®žçŽ°å¦‚下: -``` -/*任务PID*/ -static UINT32 g_TestTaskID; -//static LITE_OS_SEC_BSS UINT32 g_uweventTaskID; -/*事件控制结构体*/ -static EVENT_CB_S example_event; - -/*等待的事件类型*/ -#define event_wait 0x00000001 - -/*用例任务入å£å‡½æ•°*/ -VOID Example_Event(VOID) -{ - UINT32 uwEvent; - UINT32 uwRet = LOS_OK; - - /*超时 等待方å¼è¯»äº‹ä»¶,超时时间为100 Tick - è‹¥100 Tick åŽæœªè¯»å–到指定事件,读事件超时,任务直接唤醒*/ - dprintf("Example_Event wait event 0x%x \n",event_wait); +代ç å®žçŽ°å¦‚下: - uwEvent = LOS_EventRead(&example_event, event_wait, LOS_WAITMODE_AND, 100); - if(uwEvent == event_wait) - { - dprintf("Example_Event,read event :0x%x\n",uwEvent); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_EVENT,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - else - { - dprintf("Example_Event,read event timeout\n"); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_EVENT,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - } - return; +``` +#include "los_event.h" +#include "los_task.h" + +/*任务PID*/ +UINT32 g_TestTaskID01; + +/*事件控制结构体*/ +EVENT_CB_S example_event; + +/*等待的事件类型*/ +#define event_wait 0x00000001 + +/*用例任务入å£å‡½æ•°*/ +VOID Example_Event() +{ + UINT32 uwRet; + UINT32 uwEvent; + + /*超时等待方å¼è¯»äº‹ä»¶,超时时间为100 Tick + è‹¥100 Tick åŽæœªè¯»å–到指定事件,读事件超时,任务直接唤醒*/ + printf("Example_Event wait event 0x%x \n",event_wait); + + uwEvent = LOS_EventRead(&example_event, event_wait, LOS_WAITMODE_AND, 100); + if(uwEvent == event_wait) + { + printf("Example_Event,read event :0x%x\n",uwEvent); + } + else + printf("Example_Event,read event timeout\n"); + return; +} + +UINT32 Example_TaskEntry() +{ + UINT32 uwRet; + TSK_INIT_PARAM_S stTask1; + + /*事件åˆå§‹åŒ–*/ + uwRet = LOS_EventInit(&example_event); + if(uwRet != LOS_OK) + { + printf("init event failed .\n"); + return -1; + } + + /*创建任务*/ + memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; + stTask1.pcName = "EventTsk1"; + stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask1.usTaskPrio = 5; + uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); + if(uwRet != LOS_OK) + { + printf("task create failed .\n"); + return LOS_NOK; + } + + /*写用例任务等待的事件类型*/ + printf("Example_TaskEntry write event .\n"); + + uwRet = LOS_EventWrite(&example_event, event_wait); + if(uwRet != LOS_OK) + { + printf("event write failed .\n"); + return LOS_NOK; + } + + /*清标志ä½*/ + printf("EventMask:%d\n",example_event.uwEventID); + LOS_EventClear(&example_event, ~example_event.uwEventID); + printf("EventMask:%d\n",example_event.uwEventID); + + /*删除任务*/ + uwRet = LOS_TaskDelete(g_TestTaskID01); + if(uwRet != LOS_OK) + { + printf("task delete failed .\n"); + return LOS_NOK; + } + + return LOS_OK; } +``` -UINT32 Example_SndRcvEvent(VOID) -{ - UINT32 uwRet; - TSK_INIT_PARAM_S stTask1; - - /*事件åˆå§‹åŒ–*/ - uwRet = LOS_EventInit(&example_event); - if(uwRet != LOS_OK) - { - dprintf("init event failed .\n"); - return LOS_NOK; - } - - /*创建任务*/ - memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; - stTask1.pcName = "EventTsk1"; - stTask1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - stTask1.usTaskPrio = 5; - uwRet = LOS_TaskCreate(&g_TestTaskID, &stTask1); - if(uwRet != LOS_OK) - { - dprintf("task create failed .\n"); - return LOS_NOK; - } - - /*写用例任务等待的事件类型*/ - dprintf("Example_TaskEntry_Event write event .\n"); - - uwRet = LOS_EventWrite(&example_event, event_wait); - if(uwRet != LOS_OK) - { - dprintf("event write failed .\n"); - return LOS_NOK; - } - /*清标志ä½*/ - dprintf("EventMask:%d\n",example_event.uwEventID); - LOS_EventClear(&example_event, ~example_event.uwEventID); - dprintf("EventMask:%d\n",example_event.uwEventID); +#### ç»“æžœéªŒè¯ - return LOS_OK; -} -``` +编译è¿è¡Œå¾—到的结果为: +``` + Example_Event wait event 0x1 + Example_TaskEntry write event . + Example_Event,read event :0x1 + EventMask:1 + EventMask:0 +``` -#### ç»“æžœéªŒè¯ +#### å®Œæ•´å®žä¾‹ä»£ç  -编译è¿è¡Œå¾—到的结果为: -![](./meta/DevGuide/pic17.png) +[sample\_event.c](resource/sample_event.c) -

    4.6 互斥é”

    +

    4.6 互斥é”

    ### 概述 @@ -1659,265 +2918,453 @@ UINT32 Example_SndRcvEvent(VOID) 互斥é”åˆç§°äº’斥型信å·é‡ï¼Œæ˜¯ä¸€ç§ç‰¹æ®Šçš„二值性信å·é‡ï¼Œç”¨äºŽå®žçŽ°å¯¹å…±äº«èµ„æºçš„独å å¼å¤„ç†ã€‚ -ä»»æ„时刻互斥é”的状æ€åªæœ‰ä¸¤ç§ï¼Œå¼€é”或闭é”。当有任务æŒæœ‰æ—¶ï¼Œäº’æ–¥é”处于闭é”状æ€ï¼Œè¿™ä¸ªä»»åŠ¡èŽ·å¾—该互斥é”的所有æƒã€‚当该任务释放它时,该互斥é”被开é”,任务失去该互斥é”的所有æƒã€‚当一个任务æŒæœ‰äº’æ–¥é”时,其他任务将ä¸èƒ½å†å¯¹è¯¥äº’æ–¥é”进行开é”或æŒæœ‰ã€‚ +ä»»æ„时刻互斥é”的状æ€åªæœ‰ä¸¤ç§ï¼Œå¼€é”或闭é”。当有任务æŒæœ‰æ—¶ï¼Œäº’æ–¥é”处于闭é”状æ€ï¼Œè¿™ä¸ªä»»åŠ¡èŽ·å¾—该互斥é”的所有æƒã€‚当该任务释放它时,该互斥é”被开é”,任务失去该互斥é”的所有æƒã€‚当一个任务æŒæœ‰äº’æ–¥é”时,其他任务将ä¸èƒ½å†å¯¹è¯¥äº’æ–¥é”进行开é”或æŒæœ‰ã€‚ -多任务环境下往往存在多个任务竞争åŒä¸€å…±äº«èµ„æºçš„应用场景,互斥é”å¯è¢«ç”¨äºŽå¯¹å…±äº«èµ„æºçš„ä¿æŠ¤ä»Žè€Œå®žçŽ°ç‹¬å å¼è®¿é—®ã€‚å¦å¤–,互斥é”å¯ä»¥è§£å†³ä¿¡å·é‡å­˜åœ¨çš„优先级翻转问题。 +多任务环境下往往存在多个任务竞争åŒä¸€å…±äº«èµ„æºçš„应用场景,互斥é”å¯è¢«ç”¨äºŽå¯¹å…±äº«èµ„æºçš„ä¿æŠ¤ä»Žè€Œå®žçŽ°ç‹¬å å¼è®¿é—®ã€‚å¦å¤–,互斥é”å¯ä»¥è§£å†³ä¿¡å·é‡å­˜åœ¨çš„优先级翻转问题。 Huawei LiteOSæ供的互斥é”具有如下特点: -- 通过优先级继承算法,解决优先级翻转问题。 +- 通过优先级继承算法,解决优先级翻转问题。 #### è¿ä½œæœºåˆ¶ **互斥é”è¿ä½œåŽŸç†** -多任务环境下会存在多个任务访问åŒä¸€å…¬å…±èµ„æºçš„场景,而有些公共资æºæ˜¯éžå…±äº«çš„,需è¦ä»»åŠ¡è¿›è¡Œç‹¬å å¼å¤„ç†ã€‚互斥é”怎样æ¥é¿å…è¿™ç§å†²çªå‘¢ï¼Ÿ +多任务环境下会存在多个任务访问åŒä¸€å…¬å…±èµ„æºçš„场景,而有些公共资æºæ˜¯éžå…±äº«çš„,需è¦ä»»åŠ¡è¿›è¡Œç‹¬å å¼å¤„ç†ã€‚互斥é”怎样æ¥é¿å…è¿™ç§å†²çªå‘¢ï¼Ÿ -用互斥é”处ç†éžå…±äº«èµ„æºçš„åŒæ­¥è®¿é—®æ—¶ï¼Œå¦‚果有任务访问该资æºï¼Œåˆ™äº’æ–¥é”为加é”状æ€ã€‚此时其他任务如果想访问这个公共资æºåˆ™ä¼šè¢«é˜»å¡žï¼Œç›´åˆ°äº’æ–¥é”被æŒæœ‰è¯¥é”的任务释放åŽï¼Œå…¶ä»–任务æ‰èƒ½é‡æ–°è®¿é—®è¯¥å…¬å…±èµ„æºï¼Œæ­¤æ—¶äº’æ–¥é”å†æ¬¡ä¸Šé”,如此确ä¿åŒä¸€æ—¶åˆ»åªæœ‰ä¸€ä¸ªä»»åŠ¡æ­£åœ¨è®¿é—®è¿™ä¸ªå…¬å…±èµ„æºï¼Œä¿è¯äº†å…¬å…±èµ„æºæ“作的完整性。 +用互斥é”处ç†éžå…±äº«èµ„æºçš„åŒæ­¥è®¿é—®æ—¶ï¼Œå¦‚果有任务访问该资æºï¼Œåˆ™äº’æ–¥é”为加é”状æ€ã€‚此时其他任务如果想访问这个公共资æºåˆ™ä¼šè¢«é˜»å¡žï¼Œç›´åˆ°äº’æ–¥é”被æŒæœ‰è¯¥é”的任务释放åŽï¼Œå…¶ä»–任务æ‰èƒ½é‡æ–°è®¿é—®è¯¥å…¬å…±èµ„æºï¼Œæ­¤æ—¶äº’æ–¥é”å†æ¬¡ä¸Šé”,如此确ä¿åŒä¸€æ—¶åˆ»åªæœ‰ä¸€ä¸ªä»»åŠ¡æ­£åœ¨è®¿é—®è¿™ä¸ªå…¬å…±èµ„æºï¼Œä¿è¯äº†å…¬å…±èµ„æºæ“作的完整性。 -互斥é”è¿ä½œç¤ºæ„图 -![](./meta/DevGuide/pic18.png) +**图 1** 互斥é”è¿ä½œç¤ºæ„图 +![](figures/互斥é”è¿ä½œç¤ºæ„图.png "互斥é”è¿ä½œç¤ºæ„图") ### å¼€å‘指导 #### 使用场景 -互斥é”å¯ä»¥æ供任务之间的互斥机制,用æ¥é˜²æ­¢ä¸¤ä¸ªä»»åŠ¡åœ¨åŒä¸€æ—¶åˆ»è®¿é—®ç›¸åŒçš„共享资æºã€‚ -#### 功能 +互斥é”å¯ä»¥æ供任务之间的互斥机制,用æ¥é˜²æ­¢ä¸¤ä¸ªä»»åŠ¡åœ¨åŒä¸€æ—¶åˆ»è®¿é—®ç›¸åŒçš„共享资æºã€‚ -Huawei LiteOS 系统中的互斥é”模å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ +#### 功能 -| 功能分类 | 接å£å | æè¿° | -|--------------------|----------------|------------------| -| 互斥é”的创建和删除 | LOS\_MuxCreate | åˆ›å»ºäº’æ–¥é” | -| | LOS\_MuxDelete | åˆ é™¤æŒ‡å®šçš„äº’æ–¥é” | -| 互斥é”的申请和释放 | LOS\_MuxPend | ç”³è¯·æŒ‡å®šçš„äº’æ–¥é” | -| | LOS\_MuxPost | é‡Šæ”¾æŒ‡å®šçš„äº’æ–¥é” | +Huawei LiteOS 系统中的互斥é”模å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    互斥é”的创建和删除

    +

    LOS_MuxCreate

    +

    创建互斥é”

    +

    LOS_MuxDelete

    +

    删除指定的互斥é”

    +

    互斥é”的申请和释放

    +

    LOS_MuxPend

    +

    申请指定的互斥é”

    +

    LOS_MuxPost

    +

    释放指定的互斥é”

    +
    #### å¼€å‘æµç¨‹ -互斥é”典型场景的开å‘æµç¨‹ï¼š - -1. 创建互斥é”LOS\_MuxCreate。 - -2. 申请互斥é”LOS\_MuxPend。 - - 申请模å¼æœ‰ä¸‰ç§ï¼šæ— é˜»å¡žæ¨¡å¼ã€æ°¸ä¹…阻塞模å¼ã€å®šæ—¶é˜»å¡žæ¨¡å¼ã€‚ +互斥é”典型场景的开å‘æµç¨‹ï¼š - - 无阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·äº’æ–¥é”,若该互斥é”当å‰æ²¡æœ‰ä»»åŠ¡æŒæœ‰ï¼Œæˆ–者æŒæœ‰è¯¥äº’æ–¥é”的任务和申请该互斥é”的任务为åŒä¸€ä¸ªä»»åŠ¡ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚ +1. 创建互斥é”LOS\_MuxCreate。 +2. 申请互斥é”LOS\_MuxPend。 - - 永久阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·äº’æ–¥é”,若该互斥é”当å‰æ²¡æœ‰è¢«å ç”¨ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œè¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼Œç›´åˆ°æœ‰å…¶ä»–任务释放该互斥é”,阻塞任务æ‰ä¼šé‡æ–°å¾—以执行。 + 申请模å¼æœ‰ä¸‰ç§ï¼šæ— é˜»å¡žæ¨¡å¼ã€æ°¸ä¹…阻塞模å¼ã€å®šæ—¶é˜»å¡žæ¨¡å¼ã€‚ - - 定时阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·äº’æ–¥é”,若该互斥é”当å‰æ²¡æœ‰è¢«å ç”¨ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™è¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼ŒæŒ‡å®šæ—¶é—´è¶…æ—¶å‰æœ‰å…¶ä»–任务释放该互斥é”,或者用户指定时间超时åŽï¼Œé˜»å¡žä»»åŠ¡æ‰ä¼šé‡æ–°å¾—以执行。 + - 无阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·äº’æ–¥é”,若该互斥é”当å‰æ²¡æœ‰ä»»åŠ¡æŒæœ‰ï¼Œæˆ–者æŒæœ‰è¯¥äº’æ–¥é”的任务和申请该互斥é”的任务为åŒä¸€ä¸ªä»»åŠ¡ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚ + - 永久阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·äº’æ–¥é”,若该互斥é”当å‰æ²¡æœ‰è¢«å ç”¨ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œè¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼Œç›´åˆ°æœ‰å…¶ä»–任务释放该互斥é”,阻塞任务æ‰ä¼šé‡æ–°å¾—以执行。 + - 定时阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·äº’æ–¥é”,若该互斥é”当å‰æ²¡æœ‰è¢«å ç”¨ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™è¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼ŒæŒ‡å®šæ—¶é—´è¶…æ—¶å‰æœ‰å…¶ä»–任务释放该互斥é”,或者用户指定时间超时åŽï¼Œé˜»å¡žä»»åŠ¡æ‰ä¼šé‡æ–°å¾—以执行。 -3. 释放互斥é”LOS\_MuxPost。 - - - 如果有任务阻塞于指定互斥é”,则唤醒最早被阻塞的任务,该任务进入就绪æ€ï¼Œå¹¶è¿›è¡Œä»»åŠ¡è°ƒåº¦ï¼› - - - 如果没有任务阻塞于指定互斥é”,则互斥é”释放æˆåŠŸã€‚ +3. 释放互斥é”LOS\_MuxPost。 + - 如果有任务阻塞于指定互斥é”,则唤醒最早被阻塞的任务中优先级最高的,该任务进入就绪æ€ï¼Œå¹¶è¿›è¡Œä»»åŠ¡è°ƒåº¦ã€‚ + - 如果没有任务阻塞于指定互斥é”,则互斥é”释放æˆåŠŸã€‚ 4. 删除互斥é”LOS\_MuxDelete。 #### 互斥é”é”™è¯¯ç  -对互斥é”存在失败的å¯èƒ½æ€§æ“作,包括互斥é”创建,互斥é”删除,互斥é”申请,互斥é”释放。 - -| åºå· | 定义 | 实际数值 | æè¿° | å‚考解决方案 | -|------|----------------------------------|------------|--------------------------------------------|--------------------------------------| -| 1 | LOS\_ERRNO\_MUX\_NO\_MEMORY | 0x02001d00 | 内存请求失败 | å‡å°‘互斥é”é™åˆ¶æ•°é‡çš„ä¸Šé™ | -| 2 | LOS\_ERRNO\_MUX\_INVALID | 0x02001d01 | 互斥é”ä¸å¯ç”¨ | 传入有效的互斥é”çš„ID | -| 3 | LOS\_ERRNO\_MUX\_PTR\_NULL | 0x02001d02 | å…¥å‚为空 | ç¡®ä¿å…¥å‚å¯ç”¨ | -| 4 | LOS\_ERRNO\_MUX\_ALL\_BUSY | 0x02001d03 | 没有互斥é”å¯ç”¨ | 增加互斥é”é™åˆ¶æ•°é‡çš„ä¸Šé™ | -| 5 | LOS\_ERRNO\_MUX\_UNAVAILABLE | 0x02001d04 | é”失败,因为é”被其他线程使用 | 等待其他线程解é”或者设置等待时间 | -| 6 | LOS\_ERRNO\_MUX\_PEND\_INTERR | 0x02001d05 | åœ¨ä¸­æ–­ä¸­ä½¿ç”¨äº’æ–¥é” | 在中断中ç¦æ­¢è°ƒç”¨æ­¤æŽ¥å£ | -| 7 | LOS\_ERRNO\_MUX\_PEND\_IN\_LOCK | 0x02001d06 | 任务调度没有使能,线程等待å¦ä¸€ä¸ªçº¿ç¨‹é‡Šæ”¾é” | 设置PEND为éžé˜»å¡žæ¨¡å¼æˆ–者使能任务调度 | -| 8 | LOS\_ERRNO\_MUX\_TIMEOUT | 0x02001d07 | 互斥é”PEND超时 | å¢žåŠ ç­‰å¾…æ—¶é—´æˆ–è€…è®¾ç½®ä¸€ç›´ç­‰å¾…æ¨¡å¼ | -| 9 | LOS\_ERRNO\_MUX\_OVERFLOW | 0x02001d08 | 暂未使用,待扩展 | æ—  | -| 10 | LOS\_ERRNO\_MUX\_PENDED | 0x02001d09 | åˆ é™¤æ­£åœ¨ä½¿ç”¨çš„é” | 等待解é”å†åˆ é™¤é” | -| 11 | LOS\_ERRNO\_MUX\_GET\_COUNT\_ERR | 0x02001d0a | 暂未使用,待扩展 | æ—  | -| 12 | LOS\_ERRNO\_MUX\_REG\_ERROR | 0x02001d0b | 暂未使用,待扩展 | æ—  | - -**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下 +对互斥é”存在失败的å¯èƒ½æ€§æ“作,包括互斥é”创建,互斥é”删除,互斥é”申请,互斥é”释放。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_MUX_NO_MEMORY

    +

    0x02001d00

    +

    内存请求失败

    +

    å‡å°‘互斥é”é™åˆ¶æ•°é‡çš„上é™

    +

    2

    +

    LOS_ERRNO_MUX_INVALID

    +

    0x02001d01

    +

    互斥é”ä¸å¯ç”¨

    +

    传入有效的互斥é”çš„ID

    +

    3

    +

    LOS_ERRNO_MUX_PTR_NULL

    +

    0x02001d02

    +

    å…¥å‚为空

    +

    ç¡®ä¿å…¥å‚å¯ç”¨

    +

    4

    +

    LOS_ERRNO_MUX_ALL_BUSY

    +

    0x02001d03

    +

    没有互斥é”å¯ç”¨

    +

    增加互斥é”é™åˆ¶æ•°é‡çš„上é™

    +

    5

    +

    LOS_ERRNO_MUX_UNAVAILABLE

    +

    0x02001d04

    +

    é”失败,因为é”被其他线程使用

    +

    等待其他线程解é”或者设置等待时间

    +

    6

    +

    LOS_ERRNO_MUX_PEND_INTERR

    +

    0x02001d05

    +

    在中断中使用互斥é”

    +

    在中断中ç¦æ­¢è°ƒç”¨æ­¤æŽ¥å£

    +

    7

    +

    LOS_ERRNO_MUX_PEND_IN_LOCK

    +

    0x02001d06

    +

    任务调度没有使能,线程等待å¦ä¸€ä¸ªçº¿ç¨‹é‡Šæ”¾é”。

    +

    é”任务调度情况下,ä¸å…许阻塞调度

    +

    设置PEND为éžé˜»å¡žæ¨¡å¼æˆ–者使能任务调度

    +

    8

    +

    LOS_ERRNO_MUX_TIMEOUT

    +

    0x02001d07

    +

    互斥é”PEND超时

    +

    增加等待时间或者设置一直等待模å¼

    +

    9

    +

    LOS_ERRNO_MUX_OVERFLOW

    +

    0x02001d08

    +

    暂未使用,待扩展

    +

    æ— 

    +

    10

    +

    LOS_ERRNO_MUX_PENDED

    +

    0x02001d09

    +

    删除正在使用的é”

    +

    等待解é”å†åˆ é™¤é”

    +

    11

    +

    LOS_ERRNO_MUX_GET_COUNT_ERR

    +

    0x02001d0a

    +

    暂未使用,待扩展

    +

    æ— 

    +

    12

    +

    LOS_ERRNO_MUX_REG_ERROR

    +

    0x02001d0b

    +

    暂未使用,待扩展

    +

    æ— 

    +

    13

    +

    LOS_ERRNO_MUX_PEND_IN_SYSTEM_TASK

    +

    0x02001d0c

    +

    系统任务中获å–mutex,如idle和软件定时器

    +

    ä¸è¦åœ¨ç³»ç»Ÿä»»åŠ¡ä¸­èŽ·å–mutex

    +
    + +**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下所示: ``` #define LOS_ERRNO_OS_ERROR(MID, ERRNO) \ + (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) + LOS_ERRTYPE_ERROR:Define critical OS errors + LOS_ERRNO_OS_ID:OS error code flag + LOS_MOD_MUX:Mutex module ID + MID:OS_MOUDLE_ID -ERRNO:error ID number + +ERRNO:error ID number ``` -例如: +例如: ``` -LOS_ERRNO_MUX_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x07) +LOS_ERRNO_MUX_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x07) ``` #### å¹³å°å·®å¼‚性 -无。 +无。 ### 注æ„事项 -- 两个任务ä¸èƒ½å¯¹åŒä¸€æŠŠäº’æ–¥é”加é”。如果æŸä»»åŠ¡å¯¹å·²è¢«æŒæœ‰çš„互斥é”加é”,则该任务会被挂起,直到æŒæœ‰è¯¥é”的任务对互斥é”解é”,æ‰èƒ½æ‰§è¡Œå¯¹è¿™æŠŠäº’æ–¥é”的加é”æ“作。 - -- 互斥é”ä¸èƒ½åœ¨ä¸­æ–­æœåŠ¡ç¨‹åºä¸­ä½¿ç”¨ã€‚ +- 两个任务ä¸èƒ½å¯¹åŒä¸€æŠŠäº’æ–¥é”加é”。如果æŸä»»åŠ¡å¯¹å·²è¢«æŒæœ‰çš„互斥é”加é”,则该任务会被挂起,直到æŒæœ‰è¯¥é”的任务对互斥é”解é”,æ‰èƒ½æ‰§è¡Œå¯¹è¿™æŠŠäº’æ–¥é”的加é”æ“作。 +- 互斥é”ä¸èƒ½åœ¨ä¸­æ–­æœåŠ¡ç¨‹åºä¸­ä½¿ç”¨ã€‚ -- Huawei LiteOS作为实时æ“作系统需è¦ä¿è¯ä»»åŠ¡è°ƒåº¦çš„实时性,尽é‡é¿å…任务的长时间阻塞,因此在获得互斥é”之åŽï¼Œåº”该尽快释放互斥é”。 - -- æŒæœ‰äº’æ–¥é”的过程中,ä¸å¾—å†è°ƒç”¨LOS\_TaskPriSet等接å£æ›´æ”¹æŒæœ‰äº’æ–¥é”任务的优先级。 +- Huawei LiteOS作为实时æ“作系统需è¦ä¿è¯ä»»åŠ¡è°ƒåº¦çš„实时性,尽é‡é¿å…任务的长时间阻塞,因此在获得互斥é”之åŽï¼Œåº”该尽快释放互斥é”。 +- æŒæœ‰äº’æ–¥é”的过程中,ä¸å¾—å†è°ƒç”¨LOS\_TaskPriSet等接å£æ›´æ”¹æŒæœ‰äº’æ–¥é”任务的优先级。 ### 编程实例 #### 实例æè¿° -本实例实现如下æµç¨‹ã€‚ +本实例实现如下æµç¨‹ã€‚ 1. 任务Example\_TaskEntry创建一个互斥é”,é”任务调度,创建两个任务Example\_MutexTask1ã€Example\_MutexTask2,Example\_MutexTask2优先级高于Example\_MutexTask1,解é”任务调度。 - 2. Example\_MutexTask2被调度,永久申请互斥é”,然åŽä»»åŠ¡ä¼‘眠100Tick,Example\_MutexTask2挂起,Example\_MutexTask1被唤醒。 - 3. Example\_MutexTask1申请互斥é”,等待时间为10Tick,因互斥é”ä»è¢«Example\_MutexTask2æŒæœ‰ï¼ŒExample\_MutexTask1挂起,10TickåŽæœªæ‹¿åˆ°äº’æ–¥é”,Example\_MutexTask1被唤醒,试图以永久等待申请互斥é”,Example\_MutexTask1挂起。 - 4. 100TickåŽExample\_MutexTask2唤醒, 释放互斥é”åŽï¼ŒExample\_MutexTask1被调度è¿è¡Œï¼Œæœ€åŽé‡Šæ”¾äº’æ–¥é”。 - 5. Example\_MutexTask1执行完,300TickåŽä»»åŠ¡Example\_TaskEntry被调度è¿è¡Œï¼Œåˆ é™¤äº’æ–¥é”。 #### 编程示例 å‰ææ¡ä»¶ï¼š -- 在los\_config.h中,将LOSCFG\_BASE\_IPC\_MUXé…置项打开。 - -- é…好LOSCFG\_BASE\_IPC\_MUX\_LIMIT最大的互斥é”个数。 +- 在los\_config.h中,将LOSCFG\_BASE\_IPC\_MUXé…置项打开。 +- é…好LOSCFG\_BASE\_IPC\_MUX\_LIMIT最大的互斥é”个数。 代ç å®žçŽ°å¦‚下: -``` -/*互斥é”å¥æŸ„ID*/ -static UINT32 g_Testmux01; - - -/*任务PID*/ -UINT32 g_TestTaskID01; -UINT32 g_TestTaskID02; - - -static VOID Example_MutexTask1() -{ - UINT32 uwRet; - - dprintf("task1 try to get mutex, wait 10 Tick.\n"); - /*申请互斥é”*/ - uwRet=LOS_MuxPend(g_Testmux01, 10); - - if(uwRet == LOS_OK) - { - dprintf("task1 get mutex g_Testmux01.\n"); - /*释放互斥é”*/ - LOS_MuxPost(g_Testmux01); - return; - } - else if(uwRet == LOS_ERRNO_MUX_TIMEOUT ) - { - dprintf("task1 timeout and try to get mutex, wait forever.\n"); - /*LOS_WAIT_FOREVERæ–¹å¼ç”³è¯·äº’æ–¥é”,获å–ä¸åˆ°æ—¶ç¨‹åºé˜»å¡žï¼Œä¸ä¼šè¿”回*/ - uwRet = LOS_MuxPend(g_Testmux01, LOS_WAIT_FOREVER); - if(uwRet == LOS_OK) - { - dprintf("task1 wait forever,got mutex g_Testmux01 success.\n"); - /*释放互斥é”*/ - LOS_MuxPost(g_Testmux01); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_MUTEX,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return; - } - } - return; -} - -static VOID Example_MutexTask2() -{ - UINT32 uwRet; - dprintf("task2 try to get mutex, wait forever.\n"); - /*申请互斥é”*/ - uwRet=LOS_MuxPend(g_Testmux01, LOS_WAIT_FOREVER); - if(uwRet != LOS_OK) - { - dprintf("task2 LOS_MuxPend failed .\n"); - return; - } - - dprintf("task2 get mutex g_Testmux01 and suspend 100 Tick.\n"); - - /*任务休眠100 Tick*/ - LOS_TaskDelay(100); - - dprintf("task2 resumed and post the g_Testmux01\n"); - /*释放互斥é”*/ - LOS_MuxPost(g_Testmux01); - return; -} - -UINT32 Example_MutexLock(VOID) -{ - UINT32 uwRet; - TSK_INIT_PARAM_S stTask1; - TSK_INIT_PARAM_S stTask2; - - /*创建互斥é”*/ - LOS_MuxCreate(&g_Testmux01); - - /*é”任务调度*/ - LOS_TaskLock(); - - /*创建任务1*/ - memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; - stTask1.pcName = "MutexTsk1"; - stTask1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - stTask1.usTaskPrio = 5; - uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); - if(uwRet != LOS_OK) - { - dprintf("task1 create failed .\n"); - return LOS_NOK; - } - - /*创建任务2*/ - memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S)); - stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; - stTask2.pcName = "MutexTsk2"; - stTask2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - stTask2.usTaskPrio = 4; - uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2); - if(uwRet != LOS_OK) - { - dprintf("task2 create failed .\n"); - return LOS_NOK; - } +``` + #include "los_mux.h" + #include "los_task.h" + + /*互斥é”å¥æŸ„ID*/ + MUX_HANDLE_T g_Testmux01; + /*任务PID*/ + UINT32 g_TestTaskID01; + UINT32 g_TestTaskID02; + + VOID Example_MutexTask1() + { + UINT32 uwRet; + + printf("task1 try to get mutex, wait 10 Tick.\n"); + /*申请互斥é”*/ + uwRet=LOS_MuxPend(g_Testmux01, 10); + + if(uwRet == LOS_OK) + { + printf("task1 get mutex g_Testmux01.\n"); + /*释放互斥é”*/ + LOS_MuxPost(g_Testmux01); + return; + } + else if(uwRet == LOS_ERRNO_MUX_TIMEOUT ) + { + printf("task1 timeout and try to get mutex, wait forever.\n"); + /*申请互斥é”*/ + uwRet = LOS_MuxPend(g_Testmux01, LOS_WAIT_FOREVER); + if(uwRet == LOS_OK) + { + printf("task1 wait forever,get mutex g_Testmux01.\n"); + /*释放互斥é”*/ + LOS_MuxPost(g_Testmux01); + return; + } + } + return; + } + + VOID Example_MutexTask2() + { + UINT32 uwRet; + + printf("task2 try to get mutex, wait forever.\n"); + /*申请互斥é”*/ + uwRet=LOS_MuxPend(g_Testmux01, LOS_WAIT_FOREVER); + + printf("task2 get mutex g_Testmux01 and suspend 100 Tick.\n"); + + /*任务休眠100 Tick*/ + LOS_TaskDelay(100); + + printf("task2 resumed and post the g_Testmux01\n"); + /*释放互斥é”*/ + LOS_MuxPost(g_Testmux01); + return; + + } + + UINT32 Example_TaskEntry() + { + UINT32 uwRet; + TSK_INIT_PARAM_S stTask1; + TSK_INIT_PARAM_S stTask2; + + /*创建互斥é”*/ + LOS_MuxCreate(&g_Testmux01); + + /*é”任务调度*/ + LOS_TaskLock(); + + /*创建任务1*/ + memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; + stTask1.pcName = "MutexTsk1"; + stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask1.usTaskPrio = 5; + uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); + if(uwRet != LOS_OK) + { + printf("task1 create failed .\n"); + return LOS_NOK; + } + + /*创建任务2*/ + memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S)); + stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; + stTask2.pcName = "MutexTsk2"; + stTask2.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask2.usTaskPrio = 4; + uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2); + if(uwRet != LOS_OK) + { + printf("task2 create failed .\n"); + return LOS_NOK; + } + + /*解é”任务调度*/ + LOS_TaskUnlock(); + /*任务休眠300 Tick*/ + LOS_TaskDelay(300); + + /*删除互斥é”*/ + LOS_MuxDelete(g_Testmux01); + + /*删除任务1*/ + uwRet = LOS_TaskDelete(g_TestTaskID01); + if(uwRet != LOS_OK) + { + printf("task1 delete failed .\n"); + return LOS_NOK; + } + /*删除任务2*/ + uwRet = LOS_TaskDelete(g_TestTaskID02); + if(uwRet != LOS_OK) + { + printf("task2 delete failed .\n"); + return LOS_NOK; + } + + return LOS_OK; + } +``` - /*解é”任务调度*/ - LOS_TaskUnlock(); - /*任务休眠300 Tick*/ - LOS_TaskDelay(300); +#### ç»“æžœéªŒè¯ - /*删除互斥é”*/ - LOS_MuxDelete(g_Testmux01); +编译è¿è¡Œå¾—到的结果为: - return LOS_OK; -} -``` +``` +task2 try to get mutex, wait forever. +task2 get mutex g_Testmux01 and suspend 100 ticks. +task1 try to get mutex, wait 10 ticks. +task1 timeout and try to get mutex, wait forever. +task2 resumed and post the g_Testmux01 +task1 wait forever,get mutex g_Testmux01. +``` -#### ç»“æžœéªŒè¯ +#### å®Œæ•´å®žä¾‹ä»£ç  -编译è¿è¡Œå¾—到的结果为: -![](./meta/DevGuide/pic19.png) +[sample\_mutex.c](resource/sample_mutex.c) -

    4.7 ä¿¡å·é‡

    +

    4.7 ä¿¡å·é‡

    ### 概述 @@ -1925,452 +3372,712 @@ UINT32 Example_MutexLock(VOID) ä¿¡å·é‡ï¼ˆSemaphore)是一ç§å®žçŽ°ä»»åŠ¡é—´é€šä¿¡çš„机制,实现任务之间åŒæ­¥æˆ–临界资æºçš„互斥访问。常用于å助一组相互竞争的任务æ¥è®¿é—®ä¸´ç•Œèµ„æºã€‚ -在多任务系统中,å„任务之间需è¦åŒæ­¥æˆ–互斥实现临界资æºçš„ä¿æŠ¤ï¼Œä¿¡å·é‡åŠŸèƒ½å¯ä»¥ä¸ºç”¨æˆ·æ供这方é¢çš„支æŒã€‚ +在多任务系统中,å„任务之间需è¦åŒæ­¥æˆ–互斥实现临界资æºçš„ä¿æŠ¤ï¼Œä¿¡å·é‡åŠŸèƒ½å¯ä»¥ä¸ºç”¨æˆ·æ供这方é¢çš„支æŒã€‚ -通常一个信å·é‡çš„计数值用于对应有效的资æºæ•°ï¼Œè¡¨ç¤ºå‰©ä¸‹çš„å¯è¢«å ç”¨çš„互斥资æºæ•°ã€‚其值的å«ä¹‰åˆ†ä¸¤ç§æƒ…况: +通常一个信å·é‡çš„计数值用于对应有效的资æºæ•°ï¼Œè¡¨ç¤ºå‰©ä¸‹çš„å¯è¢«å ç”¨çš„互斥资æºæ•°ã€‚其值的å«ä¹‰åˆ†ä¸¤ç§æƒ…况: -- 0,表示没有积累下æ¥çš„Postæ“作,且有å¯èƒ½æœ‰åœ¨æ­¤ä¿¡å·é‡ä¸Šé˜»å¡žçš„任务。 +- 0,表示没有积累下æ¥çš„Postæ“作,且有å¯èƒ½æœ‰åœ¨æ­¤ä¿¡å·é‡ä¸Šé˜»å¡žçš„任务。 +- 正值,表示有一个或多个Post下æ¥çš„释放æ“作。 -- 正值,表示有一个或多个Post下æ¥çš„释放æ“作。 +以åŒæ­¥ä¸ºç›®çš„çš„ä¿¡å·é‡å’Œä»¥äº’斥为目的的信å·é‡åœ¨ä½¿ç”¨æœ‰å¦‚下ä¸åŒï¼š -以åŒæ­¥ä¸ºç›®çš„çš„ä¿¡å·é‡å’Œä»¥äº’斥为目的的信å·é‡åœ¨ä½¿ç”¨æœ‰å¦‚下ä¸åŒï¼š - -- 用作互斥时,信å·é‡åˆ›å»ºåŽè®°æ•°æ˜¯æ»¡çš„,在需è¦ä½¿ç”¨ä¸´ç•Œèµ„æºæ—¶ï¼Œå…ˆå–ä¿¡å·é‡ï¼Œä½¿å…¶å˜ç©ºï¼Œè¿™æ ·å…¶ä»–任务需è¦ä½¿ç”¨ä¸´ç•Œèµ„æºæ—¶å°±ä¼šå› ä¸ºæ— æ³•å–到信å·é‡è€Œé˜»å¡žï¼Œä»Žè€Œä¿è¯äº†ä¸´ç•Œèµ„æºçš„安全。 - -- 用作åŒæ­¥æ—¶ï¼Œä¿¡å·é‡åœ¨åˆ›å»ºåŽè¢«ç½®ä¸ºç©ºï¼Œä»»åŠ¡1å–ä¿¡å·é‡è€Œé˜»å¡žï¼Œä»»åŠ¡2在æŸç§æ¡ä»¶å‘生åŽï¼Œé‡Šæ”¾ä¿¡å·é‡ï¼ŒäºŽæ˜¯ä»»åŠ¡1得以进入READY或RUNNINGæ€ï¼Œä»Žè€Œè¾¾åˆ°äº†ä¸¤ä¸ªä»»åŠ¡é—´çš„åŒæ­¥ã€‚ +- 用作互斥时,信å·é‡åˆ›å»ºåŽè®°æ•°æ˜¯æ»¡çš„,在需è¦ä½¿ç”¨ä¸´ç•Œèµ„æºæ—¶ï¼Œå…ˆå–ä¿¡å·é‡ï¼Œä½¿å…¶å˜ç©ºï¼Œè¿™æ ·å…¶ä»–任务需è¦ä½¿ç”¨ä¸´ç•Œèµ„æºæ—¶å°±ä¼šå› ä¸ºæ— æ³•å–到信å·é‡è€Œé˜»å¡žï¼Œä»Žè€Œä¿è¯äº†ä¸´ç•Œèµ„æºçš„安全。 +- 用作åŒæ­¥æ—¶ï¼Œä¿¡å·é‡åœ¨åˆ›å»ºåŽè¢«ç½®ä¸ºç©ºï¼Œä»»åŠ¡1å–ä¿¡å·é‡è€Œé˜»å¡žï¼Œä»»åŠ¡2在æŸç§æ¡ä»¶å‘生åŽï¼Œé‡Šæ”¾ä¿¡å·é‡ï¼ŒäºŽæ˜¯ä»»åŠ¡1得以进入READY或RUNNINGæ€ï¼Œä»Žè€Œè¾¾åˆ°äº†ä¸¤ä¸ªä»»åŠ¡é—´çš„åŒæ­¥ã€‚ #### è¿ä½œæœºåˆ¶ -**ä¿¡å·é‡æŽ§åˆ¶å—** -``` -/** - * @ingroup los_sem - * Semaphore control structure. - */ -typedef struct -{ - UINT16 usSemStat; /**是å¦ä½¿ç”¨æ ‡å¿—ä½*/ - UINT16 uwSemCount; /**ä¿¡å·é‡ç´¢å¼•å·*/ - UINT16 usMaxSemCount; /**ä¿¡å·é‡æœ€å¤§æ•°*/ - UINT16 usSemID; /**ä¿¡å·é‡è®¡æ•°*/ - LOS_DL_LIST stSemList; /**挂接阻塞于该信å·é‡çš„任务*/ -}SEM_CB_S; -``` +**ä¿¡å·é‡æŽ§åˆ¶å—** + +``` + /** + * @ingroup los_sem + * Semaphore control structure. + */ + typedef struct + { + UINT8 semStat; /**是å¦ä½¿ç”¨æ ‡å¿—ä½*/ + UINT16 semCount; /**ä¿¡å·é‡è®¡æ•°*/ + UINT32 semID; /**ä¿¡å·é‡ç´¢å¼•å·*/ + LOS_DL_LIST semList; /**挂接阻塞于该信å·é‡çš„任务*/ + }LosSemCB; +``` **ä¿¡å·é‡è¿ä½œåŽŸç†** -ä¿¡å·é‡åˆå§‹åŒ–,为é…置的N个信å·é‡ç”³è¯·å†…存(N值å¯ä»¥ç”±ç”¨æˆ·è‡ªè¡Œé…置,å—内存é™åˆ¶ï¼‰ï¼Œå¹¶æŠŠæ‰€æœ‰çš„ä¿¡å·é‡åˆå§‹åŒ–æˆæœªä½¿ç”¨ï¼Œå¹¶åŠ å…¥åˆ°æœªä½¿ç”¨é“¾è¡¨ä¸­ä¾›ç³»ç»Ÿä½¿ç”¨ã€‚ +ä¿¡å·é‡åˆå§‹åŒ–,为é…置的N个信å·é‡ç”³è¯·å†…存(N值å¯ä»¥ç”±ç”¨æˆ·è‡ªè¡Œé…置,å—内存é™åˆ¶ï¼‰ï¼Œå¹¶æŠŠæ‰€æœ‰çš„ä¿¡å·é‡åˆå§‹åŒ–æˆæœªä½¿ç”¨ï¼Œå¹¶åŠ å…¥åˆ°æœªä½¿ç”¨é“¾è¡¨ä¸­ä¾›ç³»ç»Ÿä½¿ç”¨ã€‚ -ä¿¡å·é‡åˆ›å»ºï¼Œä»Žæœªä½¿ç”¨çš„ä¿¡å·é‡é“¾è¡¨ä¸­èŽ·å–一个信å·é‡èµ„æºï¼Œå¹¶è®¾å®šåˆå€¼ã€‚ +ä¿¡å·é‡åˆ›å»ºï¼Œä»Žæœªä½¿ç”¨çš„ä¿¡å·é‡é“¾è¡¨ä¸­èŽ·å–一个信å·é‡èµ„æºï¼Œå¹¶è®¾å®šåˆå€¼ã€‚ -ä¿¡å·é‡ç”³è¯·ï¼Œè‹¥å…¶è®¡æ•°å™¨å€¼å¤§äºŽ0,则直接å‡1返回æˆåŠŸã€‚å¦åˆ™ä»»åŠ¡é˜»å¡žï¼Œç­‰å¾…其它任务释放该信å·é‡ï¼Œç­‰å¾…的超时时间å¯è®¾å®šã€‚当任务被一个信å·é‡é˜»å¡žæ—¶ï¼Œå°†è¯¥ä»»åŠ¡æŒ‚到信å·é‡ç­‰å¾…任务队列的队尾。 +ä¿¡å·é‡ç”³è¯·ï¼Œè‹¥å…¶è®¡æ•°å™¨å€¼å¤§äºŽ0,则直接å‡1返回æˆåŠŸã€‚å¦åˆ™ä»»åŠ¡é˜»å¡žï¼Œç­‰å¾…其它任务释放该信å·é‡ï¼Œç­‰å¾…的超时时间å¯è®¾å®šã€‚当任务被一个信å·é‡é˜»å¡žæ—¶ï¼Œå°†è¯¥ä»»åŠ¡æŒ‚到信å·é‡ç­‰å¾…任务队列的队尾。 -ä¿¡å·é‡é‡Šæ”¾ï¼Œè‹¥æ²¡æœ‰ä»»åŠ¡ç­‰å¾…该信å·é‡ï¼Œåˆ™ç›´æŽ¥å°†è®¡æ•°å™¨åŠ 1返回。å¦åˆ™å”¤é†’该信å·é‡ç­‰å¾…任务队列上的第一个任务。 +ä¿¡å·é‡é‡Šæ”¾ï¼Œè‹¥æ²¡æœ‰ä»»åŠ¡ç­‰å¾…该信å·é‡ï¼Œåˆ™ç›´æŽ¥å°†è®¡æ•°å™¨åŠ 1返回。å¦åˆ™å”¤é†’该信å·é‡ç­‰å¾…任务队列上的第一个任务。 -ä¿¡å·é‡åˆ é™¤ï¼Œå°†æ­£åœ¨ä½¿ç”¨çš„ä¿¡å·é‡ç½®ä¸ºæœªä½¿ç”¨ä¿¡å·é‡ï¼Œå¹¶æŒ‚回到未使用链表。 +ä¿¡å·é‡åˆ é™¤ï¼Œå°†æ­£åœ¨ä½¿ç”¨çš„ä¿¡å·é‡ç½®ä¸ºæœªä½¿ç”¨ä¿¡å·é‡ï¼Œå¹¶æŒ‚回到未使用链表。 -ä¿¡å·é‡å…许多个任务在åŒä¸€æ—¶åˆ»è®¿é—®åŒä¸€èµ„æºï¼Œä½†ä¼šé™åˆ¶åŒä¸€æ—¶åˆ»è®¿é—®æ­¤èµ„æºçš„最大任务数目。访问åŒä¸€èµ„æºçš„任务数达到该资æºçš„最大数é‡æ—¶ï¼Œä¼šé˜»å¡žå…¶ä»–试图获å–该资æºçš„任务,直到有任务释放该信å·é‡ã€‚ +ä¿¡å·é‡å…许多个任务在åŒä¸€æ—¶åˆ»è®¿é—®åŒä¸€èµ„æºï¼Œä½†ä¼šé™åˆ¶åŒä¸€æ—¶åˆ»è®¿é—®æ­¤èµ„æºçš„最大任务数目。访问åŒä¸€èµ„æºçš„任务数达到该资æºçš„最大数é‡æ—¶ï¼Œä¼šé˜»å¡žå…¶ä»–试图获å–该资æºçš„任务,直到有任务释放该信å·é‡ã€‚ -ä¿¡å·é‡è¿ä½œç¤ºæ„图 -![](./meta/DevGuide/pic20.png) +**图 1** ä¿¡å·é‡è¿ä½œç¤ºæ„图 +![](figures/ä¿¡å·é‡è¿ä½œç¤ºæ„图.png "ä¿¡å·é‡è¿ä½œç¤ºæ„图") ### å¼€å‘指导 #### 使用场景 -ä¿¡å·é‡æ˜¯ä¸€ç§éžå¸¸çµæ´»çš„åŒæ­¥æ–¹å¼ï¼Œå¯ä»¥è¿ç”¨åœ¨å¤šç§åœºåˆä¸­ï¼Œå®žçŽ°é”ã€åŒæ­¥ã€èµ„æºè®¡æ•°ç­‰åŠŸèƒ½ï¼Œä¹Ÿèƒ½æ–¹ä¾¿çš„用于任务与任务,中断与任务的åŒæ­¥ä¸­ã€‚ +ä¿¡å·é‡æ˜¯ä¸€ç§éžå¸¸çµæ´»çš„åŒæ­¥æ–¹å¼ï¼Œå¯ä»¥è¿ç”¨åœ¨å¤šç§åœºåˆä¸­ï¼Œå®žçŽ°é”ã€åŒæ­¥ã€èµ„æºè®¡æ•°ç­‰åŠŸèƒ½ï¼Œä¹Ÿèƒ½æ–¹ä¾¿çš„用于任务与任务,中断与任务的åŒæ­¥ä¸­ã€‚ #### 功能 Huawei LiteOS 系统中的信å·é‡æ¨¡å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ -| 功能分类 | 接å£å | æè¿° | -|--------------------|----------------------|------------------| -| ä¿¡å·é‡çš„创建和删除 | LOS\_SemCreate | 创建信å·é‡ | -| | LOS\_BinarySemCreate | 创建二进制信å·é‡ | -| | LOS\_SemDelete | 删除指定的信å·é‡ | -| ä¿¡å·é‡çš„申请和释放 | LOS\_SemPend | 申请指定的信å·é‡ | -| | LOS\_SemPost | 释放指定的信å·é‡ | + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    ä¿¡å·é‡çš„创建和删除

    +

    LOS_SemCreate

    +

    创建信å·é‡

    +

    LOS_BinarySemCreate

    +

    创建二进制信å·é‡

    +

    LOS_SemDelete

    +

    删除指定的信å·é‡

    +

    ä¿¡å·é‡çš„申请和释放

    +

    LOS_SemPend

    +

    申请指定的信å·é‡

    +

    LOS_SemPost

    +

    释放指定的信å·é‡

    +
    #### å¼€å‘æµç¨‹ ä¿¡å·é‡çš„å¼€å‘典型æµç¨‹ï¼š -1. 创建信å·é‡LOS\_SemCreate。 - -2. 申请信å·é‡LOS\_SemPend。 - - ä¿¡å·é‡æœ‰ä¸‰ç§ç”³è¯·æ¨¡å¼ï¼šæ— é˜»å¡žæ¨¡å¼ã€æ°¸ä¹…阻塞模å¼ã€å®šæ—¶é˜»å¡žæ¨¡å¼ - - - 无阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·ä¿¡å·é‡ï¼Œè‹¥å½“å‰ä¿¡å·é‡çš„任务数没有到信å·é‡è®¾å®šçš„上é™ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œç«‹å³è¿”回申请失败 +1. 创建信å·é‡LOS\_SemCreate。 +2. 申请信å·é‡LOS\_SemPend。 - - 永久阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·ä¿¡å·é‡ï¼Œè‹¥å½“å‰ä¿¡å·é‡çš„任务数没有到信å·é‡è®¾å®šçš„上é™ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œè¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼Œç›´åˆ°æœ‰å…¶ä»–任务释放该信å·é‡ï¼Œé˜»å¡žä»»åŠ¡æ‰ä¼šé‡æ–°å¾—以执行 + ä¿¡å·é‡æœ‰ä¸‰ç§ç”³è¯·æ¨¡å¼ï¼šæ— é˜»å¡žæ¨¡å¼ã€æ°¸ä¹…阻塞模å¼ã€å®šæ—¶é˜»å¡žæ¨¡å¼ã€‚ - - 定时阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·ä¿¡å·é‡ï¼Œè‹¥å½“å‰ä¿¡å·é‡çš„任务数没有到信å·é‡è®¾å®šçš„上é™ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œè¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼ŒæŒ‡å®šæ—¶é—´è¶…æ—¶å‰æœ‰å…¶ä»–任务释放该信å·é‡ï¼Œæˆ–者用户指定时间超时åŽï¼Œé˜»å¡žä»»åŠ¡æ‰ä¼šé‡æ–°å¾—以执行 + - 无阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·ä¿¡å·é‡ï¼Œè‹¥å½“å‰ä¿¡å·é‡çš„任务数没有到信å·é‡è®¾å®šçš„上é™ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œç«‹å³è¿”回申请失败。 + - 永久阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·ä¿¡å·é‡ï¼Œè‹¥å½“å‰ä¿¡å·é‡çš„任务数没有到信å·é‡è®¾å®šçš„上é™ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œè¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼Œç›´åˆ°æœ‰å…¶ä»–任务释放该信å·é‡ï¼Œé˜»å¡žä»»åŠ¡æ‰ä¼šé‡æ–°å¾—以执行。 + - 定时阻塞模å¼ï¼šä»»åŠ¡éœ€è¦ç”³è¯·ä¿¡å·é‡ï¼Œè‹¥å½“å‰ä¿¡å·é‡çš„任务数没有到信å·é‡è®¾å®šçš„上é™ï¼Œåˆ™ç”³è¯·æˆåŠŸã€‚å¦åˆ™ï¼Œè¯¥ä»»åŠ¡è¿›å…¥é˜»å¡žæ€ï¼Œç³»ç»Ÿåˆ‡æ¢åˆ°å°±ç»ªä»»åŠ¡ä¸­ä¼˜å…ˆçº§æœ€é«˜è€…继续执行。任务进入阻塞æ€åŽï¼ŒæŒ‡å®šæ—¶é—´è¶…æ—¶å‰æœ‰å…¶ä»–任务释放该信å·é‡ï¼Œæˆ–者用户指定时间超时åŽï¼Œé˜»å¡žä»»åŠ¡æ‰ä¼šé‡æ–°å¾—以执行。 3. 释放信å·é‡LOS\_SemPost。 - - - 如果有任务阻塞于指定信å·é‡ï¼Œåˆ™å”¤é†’该信å·é‡é˜»å¡žé˜Ÿåˆ—上的第一个任务。该任务进入就绪æ€ï¼Œå¹¶è¿›è¡Œè°ƒåº¦ - - - 如果没有任务阻塞于指定信å·é‡ï¼Œé‡Šæ”¾ä¿¡å·é‡æˆåŠŸ + - 如果有任务阻塞于指定信å·é‡ï¼Œåˆ™å”¤é†’该信å·é‡é˜»å¡žé˜Ÿåˆ—上的第一个任务。该任务进入就绪æ€ï¼Œå¹¶è¿›è¡Œè°ƒåº¦ã€‚ + - 如果没有任务阻塞于指定信å·é‡ï¼Œé‡Šæ”¾ä¿¡å·é‡æˆåŠŸã€‚ 4. 删除信å·é‡LOS\_SemDelete。 #### ä¿¡å·é‡é”™è¯¯ç  -对å¯èƒ½å¯¼è‡´ä¿¡å·é‡æ“作失败的情况,包括创建信å·é‡ã€ç”³è¯·ä¿¡å·é‡ã€é‡Šæ”¾ä¿¡å·é‡ã€åˆ é™¤ä¿¡å·é‡ç­‰ï¼Œå‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ - -| åºå· | 定义 | 实际数值 | æè¿° | å‚考解决方案 | -|------|---------------------------------|------------|------------------------------|------------------------------------------| -| 1 | LOS\_ERRNO\_SEM\_NO\_MEMORY | 0x02000700 | 内存空间ä¸è¶³ | 分é…更大的内存分区 | -| 2 | LOS\_ERRNO\_SEM\_INVALID | 0x02000701 | éžæ³•ä¼ å‚ | 改å˜ä¼ æ•°ä¸ºåˆæ³•å€¼ | -| 3 | LOS\_ERRNO\_SEM\_PTR\_NULL | 0x02000702 | 传入空指针 | ä¼ å…¥åˆæ³•æŒ‡é’ˆ | -| 4 | LOS\_ERRNO\_SEM\_ALL\_BUSY | 0x02000703 | ä¿¡å·é‡æŽ§åˆ¶å—ä¸å¯ç”¨ | 释放资æºä¿¡å·é‡èµ„æº | -| 5 | LOS\_ERRNO\_SEM\_UNAVAILABLE | 0x02000704 | 定时时间éžæ³• | 传入正确的定时时间 | -| 6 | LOS\_ERRNO\_SEM\_PEND\_INTERR | 0x02000705 | 中断期间éžæ³•è°ƒç”¨LOS\_SemPend | 中断期间ç¦æ­¢è°ƒç”¨LOS\_SemPend | -| 7 | LOS\_ERRNO\_SEM\_PEND\_IN\_LOCK | 0x02000706 | 任务被é”,无法获得信å·é‡ | 在任务被é”时,ä¸èƒ½è°ƒç”¨LOS\_SemPend | -| 8 | LOS\_ERRNO\_SEM\_TIMEOUT | 0x02000707 | 获å–ä¿¡å·é‡æ—¶é—´è¶…æ—¶ | 将时间设置在åˆç†èŒƒå›´å†… | -| 9 | LOS\_ERRNO\_SEM\_OVERFLOW | 0x02000708 | ä¿¡å·é‡å…许pend次数超过最大值 | ä¼ å…¥åˆæ³•çš„值 | -| 10 | LOS\_ERRNO\_SEM\_PENDED | 0x02000709 | 等待信å·é‡çš„任务队列ä¸ä¸ºç©º | 唤醒所有等待该型å·é‡çš„任务åŽåˆ é™¤è¯¥ä¿¡å·é‡ | - -**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下 -``` +对å¯èƒ½å¯¼è‡´ä¿¡å·é‡æ“作失败的情况,包括创建信å·é‡ã€ç”³è¯·ä¿¡å·é‡ã€é‡Šæ”¾ä¿¡å·é‡ã€åˆ é™¤ä¿¡å·é‡ç­‰ï¼Œå‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_SEM_NO_MEMORY

    +

    0x02000700

    +

    内存空间ä¸è¶³ã€‚

    +

    分é…更大的内存分区。

    +

    2

    +

    LOS_ERRNO_SEM_INVALID

    +

    0x02000701

    +

    éžæ³•ä¼ å‚。

    +

    改å˜ä¼ æ•°ä¸ºåˆæ³•å€¼ã€‚

    +

    3

    +

    LOS_ERRNO_SEM_PTR_NULL

    +

    0x02000702

    +

    传入空指针。

    +

    ä¼ å…¥åˆæ³•æŒ‡é’ˆã€‚

    +

    4

    +

    LOS_ERRNO_SEM_ALL_BUSY

    +

    0x02000703

    +

    ä¿¡å·é‡æŽ§åˆ¶å—ä¸å¯ç”¨ã€‚

    +

    释放资æºä¿¡å·é‡èµ„æºã€‚

    +

    5

    +

    LOS_ERRNO_SEM_UNAVAILABLE

    +

    0x02000704

    +

    定时时间éžæ³•ã€‚

    +

    传入正确的定时时间。

    +

    6

    +

    LOS_ERRNO_SEM_PEND_INTERR

    +

    0x02000705

    +

    中断期间éžæ³•è°ƒç”¨LOS_SemPend。

    +

    中断期间ç¦æ­¢è°ƒç”¨LOS_SemPend。

    +

    7

    +

    LOS_ERRNO_SEM_PEND_IN_LOCK

    +

    0x02000706

    +

    任务被é”,无法获得信å·é‡ã€‚

    +

    在任务被é”时,ä¸èƒ½è°ƒç”¨LOS_SemPend。

    +

    8

    +

    LOS_ERRNO_SEM_TIMEOUT

    +

    0x02000707

    +

    获å–ä¿¡å·é‡æ—¶é—´è¶…时。

    +

    将时间设置在åˆç†èŒƒå›´å†…。

    +

    9

    +

    LOS_ERRNO_SEM_OVERFLOW

    +

    0x02000708

    +

    ä¿¡å·é‡å…许pend次数超过最大值。

    +

    ä¼ å…¥åˆæ³•çš„值。

    +

    10

    +

    LOS_ERRNO_SEM_PENDED

    +

    0x02000709

    +

    等待信å·é‡çš„任务队列ä¸ä¸ºç©ºã€‚

    +

    唤醒所有等待该型å·é‡çš„任务åŽåˆ é™¤è¯¥ä¿¡å·é‡ã€‚

    +

    11

    +

    LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK

    +

    0x0200070a

    +

    系统任务中获å–sem,如idle和软件定时器

    +

    ä¸è¦åœ¨ç³»ç»Ÿä»»åŠ¡ä¸­èŽ·å–sem

    +
    + +**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下所示: + +``` #define LOS_ERRNO_OS_NORMAL(MID,ERRNO) \ (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) LOS_ERRTYPE_NORMAL :Define the error level as critical LOS_ERRNO_OS_ID :OS error code flag. MID:OS_MOUDLE_ID -ERRNO:error ID number -``` +ERRNO:error ID number +``` -例如: -``` -LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00)) -``` +例如: + +``` +LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00)) +``` #### å¹³å°å·®å¼‚性 无。 ### 注æ„事项 -- 由于中断ä¸èƒ½è¢«é˜»å¡žï¼Œå› æ­¤åœ¨ç”³è¯·ä¿¡å·é‡æ—¶ï¼Œé˜»å¡žæ¨¡å¼ä¸èƒ½åœ¨ä¸­æ–­ä¸­ä½¿ç”¨ã€‚ +- 由于中断ä¸èƒ½è¢«é˜»å¡žï¼Œå› æ­¤åœ¨ç”³è¯·ä¿¡å·é‡æ—¶ï¼Œé˜»å¡žæ¨¡å¼ä¸èƒ½åœ¨ä¸­æ–­ä¸­ä½¿ç”¨ã€‚ ### 编程实例 #### 实例æè¿° -本实例实现如下功能: +本实例实现如下功能: 1. 测试任务Example\_TaskEntry创建一个信å·é‡ï¼Œé”任务调度,创建两个任务Example\_SemTask1ã€Example\_SemTask2,Example\_SemTask2优先级高于Example\_SemTask1,两个任务中申请åŒä¸€ä¿¡å·é‡ï¼Œè§£é”任务调度åŽä¸¤ä»»åŠ¡é˜»å¡žï¼Œæµ‹è¯•ä»»åŠ¡Example\_TaskEntry释放信å·é‡ã€‚ - 2. Example\_SemTask2得到信å·é‡ï¼Œè¢«è°ƒåº¦ï¼Œç„¶åŽä»»åŠ¡ä¼‘眠20Tick,Example\_SemTask2延迟,Example\_SemTask1被唤醒。 - 3. Example\_SemTask1定时阻塞模å¼ç”³è¯·ä¿¡å·é‡ï¼Œç­‰å¾…时间为10Tick,因信å·é‡ä»è¢«Example\_SemTask2æŒæœ‰ï¼ŒExample\_SemTask1挂起,10TickåŽä»æœªå¾—到信å·é‡ï¼ŒExample\_SemTask1被唤醒,试图以永久阻塞模å¼ç”³è¯·ä¿¡å·é‡ï¼ŒExample\_SemTask1挂起。 - 4. 20TickåŽExample\_SemTask2唤醒, 释放信å·é‡åŽï¼ŒExample\_SemTask1得到信å·é‡è¢«è°ƒåº¦è¿è¡Œï¼Œæœ€åŽé‡Šæ”¾ä¿¡å·é‡ã€‚ - -5. Example\_SemTask1执行完,40TickåŽä»»åŠ¡Example\_TaskEntry被唤醒。 +5. Example\_SemTask1执行完,40TickåŽä»»åŠ¡Example\_TaskEntry被唤醒。执行删除信å·é‡ï¼Œåˆ é™¤ä¸¤ä¸ªä»»åŠ¡ã€‚ #### 编程示例 -å‰ææ¡ä»¶ï¼š +å‰ææ¡ä»¶ï¼š -在los\_config.h中,将LOSCFG\_BASE\_IPC\_SEMé…置为YES。 +- 在los\_config.h中,将LOSCFG\_BASE\_IPC\_SEMé…置为YES。 +- é…置用户定义的LOSCFG\_BASE\_IPC\_SEM\_LIMIT最大的信å·é‡æ•°ï¼Œå¦‚1024。 -é…置用户定义的LOSCFG\_BASE\_IPC\_SEM\_LIMIT最大的信å·é‡æ•°ï¼Œå¦‚1024。 +代ç å®žçŽ°å¦‚下: -代ç å®žçŽ°å¦‚下: -``` -/*测试任务优先级*/ -#define TASK_PRIO_TEST 5 +``` + #include "los_sem.h" + + /*任务PID*/ + static UINT32 g_TestTaskID01,g_TestTaskID02; + /*测试任务优先级*/ + #define TASK_PRIO_TEST 5 + /*ä¿¡å·é‡ç»“构体ID*/ + static SEM_HANDLE_T g_usSemID; + + + VOID Example_SemTask1(void) + { + UINT32 uwRet; + + printf("Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks.\n"); + /*定时阻塞模å¼ç”³è¯·ä¿¡å·é‡ï¼Œå®šæ—¶æ—¶é—´ä¸º10Tick*/ + uwRet = LOS_SemPend(g_usSemID, 10); + + /*申请到信å·é‡*/ + if(LOS_OK == uwRet) + { + LOS_SemPost(g_usSemID); + return; + } + /*定时时间到,未申请到信å·é‡*/ + if(LOS_ERRNO_SEM_TIMEOUT == uwRet) + { + printf("Example_SemTask1 timeout and try get sem g_usSemID wait forever.\n"); + /*永久阻塞模å¼ç”³è¯·ä¿¡å·é‡*/ + uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER); + printf("Example_SemTask1 wait_forever and get sem g_usSemID .\n"); + if(LOS_OK == uwRet) + { + LOS_SemPost(g_usSemID); + return; + } + } + return; + + } + VOID Example_SemTask2(void) + { + UINT32 uwRet; + printf("Example_SemTask2 try get sem g_usSemID wait forever.\n"); + /*永久阻塞模å¼ç”³è¯·ä¿¡å·é‡*/ + uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER); + + if(LOS_OK == uwRet) + printf("Example_SemTask2 get sem g_usSemID and then delay 20ticks .\n"); + + /*任务休眠20 Tick*/ + LOS_TaskDelay(20); + + printf("Example_SemTask2 post sem g_usSemID .\n"); + /*释放信å·é‡*/ + LOS_SemPost(g_usSemID); + + return; + + } + UINT32 Example_TaskEntry() + { + UINT32 uwRet; + TSK_INIT_PARAM_S stTask1; + TSK_INIT_PARAM_S stTask2; + + /*创建信å·é‡*/ + LOS_SemCreate(0,&g_usSemID); + + /*é”任务调度*/ + LOS_TaskLock(); + + /*创建任务1*/ + memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1; + stTask1.pcName = "MutexTsk1"; + stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask1.usTaskPrio = TASK_PRIO_TEST; + uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); + if(uwRet != LOS_OK) + { + printf("task1 create failed .\n"); + return LOS_NOK; + } + + /*创建任务2*/ + memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S)); + stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2; + stTask2.pcName = "MutexTsk2"; + stTask2.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask2.usTaskPrio = (TASK_PRIO_TEST - 1); + uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2); + if(uwRet != LOS_OK) + { + printf("task2 create failed .\n"); + return LOS_NOK; + } + + /*解é”任务调度*/ + LOS_TaskUnlock(); + + uwRet = LOS_SemPost(g_usSemID); + + /*任务休眠40 Tick*/ + LOS_TaskDelay(40); + + /*删除信å·é‡*/ + LOS_SemDelete(g_usSemID); + + /*删除任务1*/ + uwRet = LOS_TaskDelete(g_TestTaskID01); + if(uwRet != LOS_OK) + { + printf("task1 delete failed .\n"); + return LOS_NOK; + } + /*删除任务2*/ + uwRet = LOS_TaskDelete(g_TestTaskID02); + if(uwRet != LOS_OK) + { + printf("task2 delete failed .\n"); + return LOS_NOK; + } + + return LOS_OK; + } +``` -/*任务PID*/ -static UINT32 g_TestTaskID01,g_TestTaskID02; -/*ä¿¡å·é‡ç»“构体ID*/ -static UINT32 g_usSemID; +#### ç»“æžœéªŒè¯ -static VOID Example_SemTask1(void) -{ - UINT32 uwRet; +编译è¿è¡Œå¾—到的结果为: - dprintf("Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks.\n"); - /*定时阻塞模å¼ç”³è¯·ä¿¡å·é‡ï¼Œå®šæ—¶æ—¶é—´ä¸º10Tick*/ - uwRet = LOS_SemPend(g_usSemID, 10); +``` +Example_SemTask2 try get sem g_usSemID wait forever. +Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks. +Example_SemTask2 get sem g_usSemID and then delay 20ticks . +Example_SemTask1 timeout and try get sem g_usSemID wait forever. +Example_SemTask2 post sem g_usSemID . +Example_SemTask1 wait_forever and get sem g_usSemID . +``` - /*申请到信å·é‡*/ - if(LOS_OK == uwRet) - { - LOS_SemPost(g_usSemID); - return; - } - /*定时时间到,未申请到信å·é‡*/ - if(LOS_ERRNO_SEM_TIMEOUT == uwRet) - { - dprintf("Example_SemTask1 timeout and try get sem g_usSemID wait forever.\n"); - /*永久阻塞模å¼ç”³è¯·ä¿¡å·é‡,获å–ä¸åˆ°æ—¶ç¨‹åºé˜»å¡žï¼Œä¸ä¼šè¿”回*/ - uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER); - if(LOS_OK == uwRet) - { - dprintf("Example_SemTask1 wait_forever and got sem g_usSemID success.\n"); - LOS_SemPost(g_usSemID); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SEM,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return; - } - } - return; -} +#### å®Œæ•´å®žä¾‹ä»£ç  -static VOID Example_SemTask2(void) -{ - UINT32 uwRet; - dprintf("Example_SemTask2 try get sem g_usSemID wait forever.\n"); - /*永久阻塞模å¼ç”³è¯·ä¿¡å·é‡*/ - uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER); +[sample\_sem.c](resource/sample_sem.c) - if(LOS_OK == uwRet) - { - dprintf("Example_SemTask2 get sem g_usSemID and then delay 20ticks .\n"); - } +

    4.8 时间管ç†

    - /*任务休眠20 Tick*/ - LOS_TaskDelay(20); +### 概述 - dprintf("Example_SemTask2 post sem g_usSemID .\n"); - /*释放信å·é‡*/ - LOS_SemPost(g_usSemID); +#### 基本概念 - return; -} +时间管ç†ä»¥ç³»ç»Ÿæ—¶é’Ÿä¸ºåŸºç¡€ã€‚时间管ç†æ供给应用程åºæ‰€æœ‰å’Œæ—¶é—´æœ‰å…³çš„æœåŠ¡ã€‚ -UINT32 Example_Semphore(VOID) -{ - UINT32 uwRet = LOS_OK; - TSK_INIT_PARAM_S stTask1; - TSK_INIT_PARAM_S stTask2; - - /*创建信å·é‡*/ - LOS_SemCreate(0,&g_usSemID); - - /*é”任务调度*/ - LOS_TaskLock(); - - /*创建任务1*/ - memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); - stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1; - stTask1.pcName = "MutexTsk1"; - stTask1.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; - stTask1.usTaskPrio = TASK_PRIO_TEST; - uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); - if(uwRet != LOS_OK) - { - dprintf("task1 create failed .\n"); - return LOS_NOK; - } - - /*创建任务2*/ - memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S)); - stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2; - stTask2.pcName = "MutexTsk2"; - stTask2.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; - stTask2.usTaskPrio = (TASK_PRIO_TEST - 1); - uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2); - if(uwRet != LOS_OK) - { - dprintf("task2 create failed .\n"); - - /*删除任务1*/ - if(LOS_OK != LOS_TaskDelete(g_TestTaskID01)) - { - dprintf("task1 delete failed .\n"); - } - - return LOS_NOK; - } - - /*解é”任务调度*/ - LOS_TaskUnlock(); - - uwRet = LOS_SemPost(g_usSemID); - - /*任务休眠40 Tick*/ - LOS_TaskDelay(40); - - /*删除信å·é‡*/ - LOS_SemDelete(g_usSemID); - - return uwRet; -} -``` - - -#### ç»“æžœéªŒè¯ - -编译è¿è¡Œå¾—到的结果为: -![](./meta/DevGuide/pic21.png) - -

    4.8 时间管ç†

    - -### 概述 - -#### 基本概念 - -时间管ç†ä»¥ç³»ç»Ÿæ—¶é’Ÿä¸ºåŸºç¡€ã€‚时间管ç†æ供给应用程åºæ‰€æœ‰å’Œæ—¶é—´æœ‰å…³çš„æœåŠ¡ã€‚ - -系统时钟是由定时/计数器产生的输出脉冲触å‘中断而产生的,一般定义为整数或长整数。输出脉冲的周期å«åšä¸€ä¸ªâ€œæ—¶é’Ÿæ»´ç­”â€ã€‚系统时钟也称为时标或者Tick。一个Tick的时长å¯ä»¥é™æ€é…置。 +系统时钟是由定时/计数器产生的输出脉冲触å‘中断而产生的,一般定义为整数或长整数。输出脉冲的周期å«åšä¸€ä¸ªâ€œæ—¶é’Ÿæ»´ç­”â€ã€‚系统时钟也称为时标或者Tick。一个Tick的时长å¯ä»¥é™æ€é…置。 -用户是以秒ã€æ¯«ç§’为å•ä½è®¡æ—¶ï¼Œè€ŒèŠ¯ç‰‡CPU的计时是以Tick为å•ä½çš„,当用户需è¦å¯¹ç³»ç»Ÿæ“作时,例如任务挂起ã€å»¶æ—¶ç­‰ï¼Œè¾“入秒为å•ä½çš„数值,此时需è¦æ—¶é—´ç®¡ç†æ¨¡å—对二者进行转æ¢ã€‚ +用户是以秒ã€æ¯«ç§’为å•ä½è®¡æ—¶ï¼Œè€Œæ“作系统时钟芯片CPU的计时是以Tick为å•ä½çš„,当用户需è¦å¯¹ç³»ç»Ÿæ“作时,例如任务挂起ã€å»¶æ—¶ç­‰ï¼Œè¾“入秒为å•ä½çš„数值,此时需è¦æ—¶é—´ç®¡ç†æ¨¡å—对二者进行转æ¢ã€‚ -Tick与秒之间的对应关系å¯ä»¥é…置。 +Tick与秒之间的对应关系å¯ä»¥é…置。 -Huawei LiteOS的时间管ç†æ¨¡å—æ供时间转æ¢ã€ç»Ÿè®¡ã€å»¶è¿ŸåŠŸèƒ½ä»¥æ»¡è¶³ç”¨æˆ·å¯¹æ—¶é—´ç›¸å…³éœ€æ±‚的实现。 +Huawei LiteOS的时间管ç†æ¨¡å—æ供时间转æ¢ã€ç»Ÿè®¡ã€å»¶è¿ŸåŠŸèƒ½ä»¥æ»¡è¶³ç”¨æˆ·å¯¹æ—¶é—´ç›¸å…³éœ€æ±‚的实现。 #### 相关概念 -- Cycle +- Cycle -系统最å°çš„计时å•ä½ã€‚Cycle的时长由系统主频决定,系统主频就是æ¯ç§’é’Ÿçš„Cycle数。 +系统最å°çš„计时å•ä½ã€‚Cycle的时长由系统主频决定,系统主频就是æ¯ç§’é’Ÿçš„Cycle数。 -- Tick +- Tick -Tick是æ“作系统的基本时间å•ä½ï¼Œå¯¹åº”的时长由系统主频åŠæ¯ç§’Tick数决定,由用户é…置。 +Tick是æ“作系统的基本时间å•ä½ï¼Œå¯¹åº”的时长由系统主频åŠæ¯ç§’Tick数决定,由用户é…置。 ### å¼€å‘指导 #### 使用场景 -用户需è¦äº†è§£å½“å‰ç³»ç»Ÿè¿è¡Œçš„时间以åŠTick与秒ã€æ¯«ç§’之间的转æ¢å…³ç³»ç­‰ã€‚ +用户需è¦äº†è§£å½“å‰ç³»ç»Ÿè¿è¡Œçš„时间以åŠTick与秒ã€æ¯«ç§’之间的转æ¢å…³ç³»ç­‰ã€‚ #### 功能 -Huawei LiteOS系统中的时间管ç†ä¸»è¦æ供以下两ç§åŠŸèƒ½ï¼š - -- 时间转æ¢ï¼šæ ¹æ®ä¸»é¢‘实现CPU Tick数到毫秒ã€å¾®ç§’的转æ¢ã€‚ - -- 时间统计:获å–系统Tick数。 - -| 功能分类 | 接å£å | æè¿° | -|----------|----------------------|---------------------| -| æ—¶é—´è½¬æ¢ | LOS\_MS2Tick | 毫秒转æ¢æˆTick | -| | LOS\_Tick2MS | Tick转化为毫秒 | -| 时间统计 | LOS\_CyclePerTickGet | æ¯ä¸ªTick多少Cycleæ•° | -| | LOS\_TickCountGet | 获å–当å‰çš„Tickæ•° | +Huawei LiteOS系统中的时间管ç†ä¸»è¦æ供以下两ç§åŠŸèƒ½ï¼š + +- 时间转æ¢ï¼šæ ¹æ®ä¸»é¢‘实现CPU Tick数到毫秒ã€å¾®ç§’的转æ¢ã€‚ +- 时间统计:获å–系统Tick数。 + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    时间转æ¢

    +

    LOS_MS2Tick

    +

    毫秒转æ¢æˆTick。

    +

    LOS_Tick2MS

    +

    Tick转化为毫秒。

    +

    时间统计

    +

    LOS_CyclePerTickGet

    +

    æ¯ä¸ªTick多少Cycle数。

    +

    LOS_TickCountGet

    +

    获å–当å‰çš„Tick数。

    +
    + +## 时间管ç†é”™è¯¯ç  + +时间转æ¢å­˜åœ¨å‡ºé”™çš„å¯èƒ½æ€§ï¼Œéœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_SYS_PTR_NULL

    +

    0x02000010

    +

    å…¥å‚指针为空

    +

    检查入å‚,传入éžç©ºå…¥å‚

    +

    2

    +

    LOS_ERRNO_SYS_CLOCK_INVALID

    +

    0x02000011

    +

    无效的系统时钟é…ç½®

    +

    在los_config.hé…置有效的时钟

    +

    3

    +

    LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID

    +

    0x02000012

    +

    错误ç æš‚时没有使用

    +

    错误ç æš‚时没有使用

    +

    4

    +

    LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID

    +

    0x02000013

    +

    错误ç æš‚时没有使用

    +

    错误ç æš‚时没有使用

    +

    5

    +

    LOS_ERRNO_SYS_HOOK_IS_FULL

    +

    0x02000014

    +

    错误ç æš‚时没有使用

    +

    错误ç æš‚时没有使用

    +
    #### å¼€å‘æµç¨‹ 时间管ç†çš„典型开å‘æµç¨‹ï¼š 1. 确认é…置项LOSCFG\_BASE\_CORE\_TICK\_HW\_TIME为YESå¼€å¯çŠ¶æ€ã€‚ - - 在los\_config.h中é…ç½®æ¯ç§’çš„Tickæ•°LOSCFG\_BASE\_CORE\_TICK\_PER\_SECONDï¼› + - 在los\_config.h中é…ç½®æ¯ç§’çš„Tickæ•°LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND。 2. 调用时钟转æ¢æŽ¥å£ã€‚ - 3. 获å–系统Tick数完æˆæ—¶é—´ç»Ÿè®¡ã€‚ + - 通过LOS\_TickCountGet获å–系统当å‰Tick值。 - 通过LOS\_TickCountGet获å–全局g\_ullTickCount。 ### 注æ„事项 -- 获å–系统Tick数需è¦åœ¨ç³»ç»Ÿæ—¶é’Ÿä½¿èƒ½ä¹‹åŽã€‚ - -- 时间管ç†ä¸æ˜¯å•ç‹¬çš„功能模å—,ä¾èµ–于los\_config.h中的OS\_SYS\_CLOCKå’ŒLOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND两个é…置选项。 - -- 系统的Tick数在关中断的情况下ä¸è¿›è¡Œè®¡æ•°ï¼Œæ•…系统Tickæ•°ä¸èƒ½ä½œä¸ºå‡†ç¡®æ—¶é—´è®¡ç®—。 +- 获å–系统Tick数需è¦åœ¨ç³»ç»Ÿæ—¶é’Ÿä½¿èƒ½ä¹‹åŽã€‚ +- 时间管ç†ä¸æ˜¯å•ç‹¬çš„功能模å—,ä¾èµ–于los\_config.h中的OS\_SYS\_CLOCKå’ŒLOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND两个é…置选项。 +- 系统的Tick数在关中断的情况下ä¸è¿›è¡Œè®¡æ•°ï¼Œæ•…系统Tickæ•°ä¸èƒ½ä½œä¸ºå‡†ç¡®æ—¶é—´è®¡ç®—。 ### 编程实例 #### 实例æè¿° -在下é¢çš„例å­ä¸­ï¼Œä»‹ç»äº†æ—¶é—´ç®¡ç†çš„基本方法,包括: +在下é¢çš„例å­ä¸­ï¼Œä»‹ç»äº†æ—¶é—´ç®¡ç†çš„基本方法,包括: + +1. 时间转æ¢ï¼šå°†æ¯«ç§’数转æ¢ä¸ºTick数,或将Tick数转æ¢ä¸ºæ¯«ç§’数。 +2. 时间统计和时间延迟:统计æ¯ç§’çš„Cycleæ•°ã€Tick数和延迟åŽçš„Tick数。 -1. 时间转æ¢ï¼šå°†æ¯«ç§’数转æ¢ä¸ºTick数,或将Tick数转æ¢ä¸ºæ¯«ç§’数。 + >![](public_sys-resources/icon-note.gif) **说明:** + >示例中系统时钟频率为80MHZ。 -2. 时间统计和时间延迟:统计æ¯ç§’çš„Cycleæ•°ã€Tick数和延迟åŽçš„Tick数。 #### 编程示例 å‰ææ¡ä»¶ï¼š -- é…好LOSCFG\_BASE\_CORE\_TICK\_PER\_SECONDæ¯ç§’çš„Tick数。 +- é…好LOSCFG\_BASE\_CORE\_TICK\_PER\_SECONDæ¯ç§’çš„Tick数。 +- é…好OS\_SYS\_CLOCK 系统时钟,å•ä½: Hz。 -- é…好OS\_SYS\_CLOCK 系统时钟,å•ä½: Hz。 +时间转æ¢ï¼š -时间转æ¢ï¼š -``` +``` VOID Example_TransformTime(VOID) { UINT32 uwMs; UINT32 uwTick; uwTick = LOS_MS2Tick(10000);//10000 ms数转æ¢ä¸ºTickæ•° - printf("uwTick = %d \n",uwTick); + printf("uwTick = %d \n",uwTick); uwMs= LOS_Tick2MS(100);//100 Tick数转æ¢ä¸ºmsæ•° - printf("uwMs = %d \n",uwMs); -} -``` + printf("uwMs = %d \n",uwMs); +} +``` -时间统计和时间延迟: -``` -UINT32 Example_GetTick(VOID) -{ - UINT32 uwRet = LOS_OK; - UINT32 uwcyclePerTick; - UINT64 uwTickCount1,uwTickCount2; +时间统计和时间延迟: - uwcyclePerTick = LOS_CyclePerTickGet();//æ¯ä¸ªTick多少Cycleæ•° - if(0 != uwcyclePerTick) - { - dprintf("LOS_CyclePerTickGet = %d \n", uwcyclePerTick); - } +``` + VOID Example_GetTime(VOID) + { + UINT32 uwcyclePerTick; + UINT64 uwTickCount; + + uwcyclePerTick = LOS_CyclePerTickGet();//æ¯ä¸ªTick多少Cycleæ•° + if(0 != uwcyclePerTick) + { + dprintf("LOS_CyclePerTickGet = %d \n", uwcyclePerTick); + } + + uwTickCount = LOS_TickCountGet();//获å–Tickæ•° + if(0 != uwTickCount) + { + dprintf("LOS_TickCountGet = %d \n", (UINT32)uwTickCount); + } + LOS_TaskDelay(200);//延迟200 Tick + uwTickCount = LOS_TickCountGet(); + if(0 != uwTickCount) + { + dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)uwTickCount); + } + } +``` - uwTickCount1 = LOS_TickCountGet();//获å–Tickæ•° - if(0 != uwTickCount1) - { - dprintf("LOS_TickCountGet = %d \n", (UINT32)uwTickCount1); - } - LOS_TaskDelay(200);//延迟200 Tick - uwTickCount2 = LOS_TickCountGet(); - if(0 != uwTickCount2) - { - dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)uwTickCount2); - } - - if((uwTickCount2 - uwTickCount1) >= 200) - { - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SYSTIC,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return LOS_OK; - } - else - { - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SYSTIC,LOS_INSPECT_STU_ERROR); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } - return LOS_NOK; - } -} -``` +#### ç»“æžœéªŒè¯ + +编译è¿è¡Œå¾—到的结果为: + +时间转æ¢ï¼š + +``` +uwTick = 1000 +uwMs = 1000 +``` + +时间统计和时间延迟: -#### ç»“æžœéªŒè¯ -编译è¿è¡Œå¾—到的结果为: -![](./meta/DevGuide/pic22.png) +``` +LOS_CyclePerTickGet = 495000 +LOS_TickCountGet = 1 +LOS_TickCountGet after delay = 201 +``` -![](./meta/DevGuide/icon_note.png) -示例中系统时钟频率为80MHZ。 +#### å®Œæ•´å®žä¾‹ä»£ç  +[sample\_time.c](resource/sample_time.c) -

    4.9 软件定时器

    +

    4.9 软件定时器

    ### 概述 @@ -2378,311 +4085,554 @@ UINT32 Example_GetTick(VOID) 软件定时器,是基于系统Tick时钟中断且由软件æ¥æ¨¡æ‹Ÿçš„定时器,当ç»è¿‡è®¾å®šçš„Tick时钟计数值åŽä¼šè§¦å‘用户定义的回调函数。定时精度与系统Tick时钟的周期有关。 -硬件定时器å—硬件的é™åˆ¶ï¼Œæ•°é‡ä¸Šä¸è¶³ä»¥æ»¡è¶³ç”¨æˆ·çš„实际需求,因此为了满足用户需求,æ供更多的定时器,Huawei LiteOSæ“作系统æ供软件定时器功能。 +硬件定时器å—硬件的é™åˆ¶ï¼Œæ•°é‡ä¸Šä¸è¶³ä»¥æ»¡è¶³ç”¨æˆ·çš„实际需求,因此为了满足用户需求,æ供更多的定时器,Huawei LiteOSæ“作系统æ供软件定时器功能。 -软件定时器扩展了定时器的数é‡ï¼Œå…许创建更多的定时业务。 +软件定时器扩展了定时器的数é‡ï¼Œå…许创建更多的定时业务。 + +软件定时器功能上支æŒï¼š + +- é™æ€è£å‰ªï¼šèƒ½é€šè¿‡å®å…³é—­è½¯ä»¶å®šæ—¶å™¨åŠŸèƒ½ã€‚ +- 软件定时器创建。 +- 软件定时器å¯åŠ¨ã€‚ +- 软件定时器åœæ­¢ã€‚ +- 软件定时器删除。 +- 软件定时器剩余Tick数获å–。 -软件定时器功能上支æŒï¼š - -- é™æ€è£å‰ªï¼šèƒ½é€šè¿‡å®å…³é—­è½¯ä»¶å®šæ—¶å™¨åŠŸèƒ½ã€‚ - -- 软件定时器创建。 - -- 软件定时器å¯åŠ¨ã€‚ - -- 软件定时器åœæ­¢ã€‚ - -- 软件定时器删除。 - -- 软件定时器剩余Tickæ•°èŽ·å– - #### è¿ä½œæœºåˆ¶ -软件定时器是系统资æºï¼Œåœ¨æ¨¡å—åˆå§‹åŒ–的时候已ç»åˆ†é…了一å—连续的内存,系统支æŒçš„最大定时器个数由los\_config.h中的LOSCFG\_BASE\_CORE\_SWTMR\_LIMITå®é…置。 +软件定时器是系统资æºï¼Œåœ¨æ¨¡å—åˆå§‹åŒ–的时候已ç»åˆ†é…了一å—连续的内存,系统支æŒçš„最大定时器个数由los\_config.h中的LOSCFG\_BASE\_CORE\_SWTMR\_LIMITå®é…置。 -软件定时器使用了系统的一个队列和一个任务资æºï¼Œè½¯ä»¶å®šæ—¶å™¨çš„触å‘éµå¾ªé˜Ÿåˆ—规则,先进先出。定时时间短的定时器总是比定时时间长的é è¿‘队列头,满足优先被触å‘的准则。 +软件定时器使用了系统的一个队列和一个任务资æºï¼Œè½¯ä»¶å®šæ—¶å™¨çš„触å‘éµå¾ªé˜Ÿåˆ—规则,先进先出。定时时间短的定时器总是比定时时间长的é è¿‘队列头,满足优先被触å‘的准则。 -软件定时器以Tick为基本计时å•ä½ï¼Œå½“用户创建并å¯åŠ¨ä¸€ä¸ªè½¯ä»¶å®šæ—¶å™¨æ—¶ï¼ŒHuawei LiteOS会根æ®å½“å‰ç³»ç»ŸTick时间åŠç”¨æˆ·è®¾ç½®çš„定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 +软件定时器以Tick为基本计时å•ä½ï¼Œå½“用户创建并å¯åŠ¨ä¸€ä¸ªè½¯ä»¶å®šæ—¶å™¨æ—¶ï¼ŒHuawei LiteOS会根æ®å½“å‰ç³»ç»ŸTick时间åŠç”¨æˆ·è®¾ç½®çš„定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 -当Tick中断到æ¥æ—¶ï¼Œåœ¨Tick中断处ç†å‡½æ•°ä¸­æ‰«æ软件定时器的计时全局链表,看是å¦æœ‰å®šæ—¶å™¨è¶…时,若有则将超时的定时器记录下æ¥ã€‚ +当Tick中断到æ¥æ—¶ï¼Œåœ¨Tick中断处ç†å‡½æ•°ä¸­æ‰«æ软件定时器的计时全局链表,看是å¦æœ‰å®šæ—¶å™¨è¶…时,若有则将超时的定时器记录下æ¥ã€‚ -Tick中断处ç†å‡½æ•°ç»“æŸåŽï¼Œè½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡ï¼ˆä¼˜å…ˆçº§ä¸ºæœ€é«˜ï¼‰è¢«å”¤é†’,在该任务中调用之å‰è®°å½•ä¸‹æ¥çš„定时器的超时回调函数。 +Tick中断处ç†å‡½æ•°ç»“æŸåŽï¼Œè½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡ï¼ˆä¼˜å…ˆçº§ä¸ºæœ€é«˜ï¼‰è¢«å”¤é†’,在该任务中调用之å‰è®°å½•ä¸‹æ¥çš„定时器的超时回调函数。 **定时器状æ€** -- OS\_SWTMR\_STATUS\_UNUSED(未使用) +- OS\_SWTMR\_STATUS\_UNUSED(未使用) -系统在定时器模å—åˆå§‹åŒ–的时候将系统中所有定时器资æºåˆå§‹åŒ–æˆè¯¥çŠ¶æ€ã€‚ +系统在定时器模å—åˆå§‹åŒ–的时候将系统中所有定时器资æºåˆå§‹åŒ–æˆè¯¥çŠ¶æ€ã€‚ -- OS\_SWTMR\_STATUS\_CREATED(创建未å¯åŠ¨/åœæ­¢ï¼‰ +- OS\_SWTMR\_STATUS\_CREATED(创建未å¯åŠ¨/åœæ­¢ï¼‰ -在未使用状æ€ä¸‹è°ƒç”¨LOS\_SwtmrCreate接å£æˆ–者å¯åŠ¨åŽè°ƒç”¨LOS\_SwtmrStop接å£åŽï¼Œå®šæ—¶å™¨å°†å˜æˆè¯¥çŠ¶æ€ã€‚ +在未使用状æ€ä¸‹è°ƒç”¨LOS\_SwtmrCreate接å£æˆ–者å¯åŠ¨åŽè°ƒç”¨LOS\_SwtmrStop接å£åŽï¼Œå®šæ—¶å™¨å°†å˜æˆè¯¥çŠ¶æ€ã€‚ -- OS\_SWTMR\_STATUS\_TICKING(计数) +- OS\_SWTMR\_STATUS\_TICKING(计数) -在定时器创建åŽè°ƒç”¨LOS\_SwtmrStart接å£ï¼Œå®šæ—¶å™¨å°†å˜æˆè¯¥çŠ¶æ€ï¼Œè¡¨ç¤ºå®šæ—¶å™¨è¿è¡Œæ—¶çš„状æ€ã€‚ +在定时器创建åŽè°ƒç”¨LOS\_SwtmrStart接å£ï¼Œå®šæ—¶å™¨å°†å˜æˆè¯¥çŠ¶æ€ï¼Œè¡¨ç¤ºå®šæ—¶å™¨è¿è¡Œæ—¶çš„状æ€ã€‚ **定时器模å¼** -Huawei LiteOS的软件定时器æ供二类定时器机制: - -- 第一类是å•æ¬¡è§¦å‘定时器,这类定时器在å¯åŠ¨åŽåªä¼šè§¦å‘一次定时器事件,然åŽå®šæ—¶å™¨è‡ªåŠ¨åˆ é™¤ã€‚ +Huawei LiteOS的软件定时器æ供二类定时器机制: -- 第二类是周期触å‘定时器,这类定时器会周期性的触å‘定时器事件,直到用户手动地åœæ­¢å®šæ—¶å™¨ï¼Œå¦åˆ™å°†æ°¸è¿œæŒç»­æ‰§è¡Œä¸‹åŽ»ã€‚ +- 第一类是å•æ¬¡è§¦å‘定时器,这类定时器在å¯åŠ¨åŽåªä¼šè§¦å‘一次定时器事件,然åŽå®šæ—¶å™¨è‡ªåŠ¨åˆ é™¤ã€‚ +- 第二类是周期触å‘定时器,这类定时器会周期性的触å‘定时器事件,直到用户手动地åœæ­¢å®šæ—¶å™¨ï¼Œå¦åˆ™å°†æ°¸è¿œæŒç»­æ‰§è¡Œä¸‹åŽ»ã€‚ +- 第三类也是å•æ¬¡è§¦å‘定时器,但与第一类ä¸åŒä¹‹å¤„在于这类定时器超时åŽä¸ä¼šè‡ªåŠ¨åˆ é™¤ï¼Œéœ€è¦è°ƒç”¨å®šæ—¶å™¨åˆ é™¤æŽ¥å£åˆ é™¤å®šæ—¶å™¨ã€‚ ### å¼€å‘指导 #### 使用场景 -- 创建一个å•æ¬¡è§¦å‘的定时器,超时åŽæ‰§è¡Œç”¨æˆ·è‡ªå®šä¹‰çš„回调函数。 -- 创建一个周期性触å‘的定时器,超时åŽæ‰§è¡Œç”¨æˆ·è‡ªå®šä¹‰çš„回调函数。 +- 创建一个å•æ¬¡è§¦å‘的定时器,超时åŽæ‰§è¡Œç”¨æˆ·è‡ªå®šä¹‰çš„回调函数。 +- 创建一个周期性触å‘的定时器,超时åŽæ‰§è¡Œç”¨æˆ·è‡ªå®šä¹‰çš„回调函数。 #### 功能 -Huawei LiteOS系统中的软件定时器模å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ï¼Œä¸‹é¢å…·ä½“çš„API详è§è½¯ä»¶å®šæ—¶å™¨å¯¹å¤–接å£æ‰‹å†Œã€‚ - -| 功能分类 | 接å£å | æè¿° | -|--------------------------|-------------------|--------------------------| -| 创建ã€åˆ é™¤å®šæ—¶å™¨ | LOS\_SwtmrCreate | 创建定时器 | -| | LOS\_SwtmrDelete | 删除定时器 | -| å¯åŠ¨ã€åœæ­¢å®šæ—¶å™¨ | LOS\_SwtmrStart | å¯åŠ¨å®šæ—¶å™¨ | -| | LOS\_SwtmrStop | åœæ­¢å®šæ—¶å™¨ | -| 获得软件定时器剩余Tickæ•° | LOS\_SwtmrTimeGet | 获得软件定时器剩余Tickæ•° | +Huawei LiteOS系统中的软件定时器模å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ï¼Œä¸‹é¢å…·ä½“çš„API详è§è½¯ä»¶å®šæ—¶å™¨å¯¹å¤–接å£æ‰‹å†Œã€‚ + +**表 1** + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    创建ã€åˆ é™¤å®šæ—¶å™¨

    +

    LOS_SwtmrCreate

    +

    创建定时器

    +

    LOS_SwtmrDelete

    +

    删除定时器

    +

    å¯åŠ¨ã€åœæ­¢å®šæ—¶å™¨

    +

    LOS_SwtmrStart

    +

    å¯åŠ¨å®šæ—¶å™¨

    +

    LOS_SwtmrStop

    +

    åœæ­¢å®šæ—¶å™¨

    +

    获得软件定时器剩余Tick数

    +

    LOS_SwtmrTimeGet

    +

    获得软件定时器剩余Tick数

    +
    #### å¼€å‘æµç¨‹ -软件定时器的典型开å‘æµç¨‹ï¼š - -1. é…置软件定时器。 - - - 确认é…置项LOSCFG\_BASE\_CORE\_SWTMRå’ŒLOSCFG\_BASE\_IPC\_QUEUE为YES打开状æ€ï¼› - - - é…ç½®LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支æŒçš„软件定时器数; - - - é…ç½®OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度; - -2. 创建定时器LOS\_SwtmrCreate。 - - - 创建一个指定计时时长ã€æŒ‡å®šè¶…时处ç†å‡½æ•°ã€æŒ‡å®šè§¦å‘模å¼çš„软件定时器; - - - 返回函数è¿è¡Œç»“果,æˆåŠŸæˆ–失败; +软件定时器的典型开å‘æµç¨‹ï¼š -3. å¯åŠ¨å®šæ—¶å™¨LOS\_SwtmrStart。 +1. é…置软件定时器。 + - 确认é…置项LOSCFG\_BASE\_CORE\_SWTMRå’ŒLOSCFG\_BASE\_IPC\_QUEUE为YES打开状æ€ã€‚ + - é…ç½®LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支æŒçš„软件定时器数。 + - é…ç½®OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 -4. 获得软件定时器剩余Tickæ•°LOS\_SwtmrTimeGet。 +2. 创建定时器LOS\_SwtmrCreate。 + - 创建一个指定计时时长ã€æŒ‡å®šè¶…时处ç†å‡½æ•°ã€æŒ‡å®šè§¦å‘模å¼çš„软件定时器。 + - 返回函数è¿è¡Œç»“果,æˆåŠŸæˆ–失败。 -5. åœæ­¢å®šæ—¶å™¨LOS\_SwtmrStop。 - -6. 删除定时器LOS\_SwtmrDelete。 +3. å¯åŠ¨å®šæ—¶å™¨LOS\_SwtmrStart。 +4. 获得软件定时器剩余Tickæ•°LOS\_SwtmrTimeGet。 +5. åœæ­¢å®šæ—¶å™¨LOS\_SwtmrStop。 +6. 删除定时器LOS\_SwtmrDelete。 #### è½¯ä»¶å®šæ—¶å™¨é”™è¯¯ç  -对软件定时器存在失败å¯èƒ½æ€§çš„æ“作,包括创建ã€åˆ é™¤ã€æš‚åœã€é‡å¯å®šæ—¶å™¨ç­‰ç­‰ï¼Œå‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ - -| åºå· | 定义 | 实际数值 | æè¿° | å‚考解决方案 | -|------|-------------------------------------------|------------|----------------------------------------------|------------------------------------------------------------| -| 1 | LOS\_ERRNO\_SWTMR\_PTR\_NULL | 0x02000300 | 软件定时器回调函数为空 | 定义软件定时器回调函数 | -| 2 | LOS\_ERRNO\_SWTMR\_INTERVAL\_NOT\_SUITED | 0x02000301 | 软件定时器间隔时间为0 | é‡æ–°å®šä¹‰é—´éš”时间 | -| 3 | LOS\_ERRNO\_SWTMR\_MODE\_INVALID | 0x02000302 | ä¸æ­£ç¡®çš„è½¯ä»¶å®šæ—¶å™¨æ¨¡å¼ | 确认软件定时器模å¼ï¼ŒèŒƒå›´ä¸º[0,2] | -| 4 | LOS\_ERRNO\_SWTMR\_RET\_PTR\_NULL | 0x02000303 | 软件定时器ID指针入å‚为NULL | 定义IDå˜é‡ï¼Œä¼ å…¥æŒ‡é’ˆ | -| 5 | LOS\_ERRNO\_SWTMR\_MAXSIZE | 0x02000304 | 软件定时器个数超过最大值 | é‡æ–°å®šä¹‰è½¯ä»¶å®šæ—¶å™¨æœ€å¤§ä¸ªæ•°ï¼Œæˆ–è€…ç­‰å¾…ä¸€ä¸ªè½¯ä»¶å®šæ—¶å™¨é‡Šæ”¾èµ„æº | -| 6 | LOS\_ERRNO\_SWTMR\_ID\_INVALID | 0x02000305 | ä¸æ­£ç¡®çš„软件定时器IDå…¥å‚ | ç¡®ä¿å…¥å‚åˆæ³• | -| 7 | LOS\_ERRNO\_SWTMR\_NOT\_CREATED | 0x02000306 | 软件定时器未创建 | 创建软件定时器 | -| 8 | LOS\_ERRNO\_SWTMR\_NO\_MEMORY | 0x02000307 | 软件定时器链表创建内存ä¸è¶³ | 申请一å—足够大的内存供软件定时器使用 | -| 9 | LOS\_ERRNO\_SWTMR\_MAXSIZE\_INVALID | 0x02000308 | ä¸æ­£ç¡®çš„软件定时器个数最大值 | é‡æ–°å®šä¹‰è¯¥å€¼ | -| 10 | LOS\_ERRNO\_SWTMR\_HWI\_ACTIVE | 0x02000309 | 在中断中使用定时器 | 修改æºä»£ç ç¡®ä¿ä¸åœ¨ä¸­æ–­ä¸­ä½¿ç”¨ | -| 11 | LOS\_ERRNO\_SWTMR\_HANDLER\_POOL\_NO\_MEM | 0x0200030a | membox内存ä¸è¶³ | 扩大内存 | -| 12 | LOS\_ERRNO\_SWTMR\_QUEUE\_CREATE\_FAILED | 0x0200030b | 软件定时器队列创建失败 | 检查用以创建队列的内存是å¦è¶³å¤Ÿ | -| 13 | LOS\_ERRNO\_SWTMR\_TASK\_CREATE\_FAILED | 0x0200030c | 软件定时器任务创建失败 | 检查用以创建软件定时器任务的内存是å¦è¶³å¤Ÿå¹¶é‡æ–°åˆ›å»º | -| 14 | LOS\_ERRNO\_SWTMR\_NOT\_STARTED | 0x0200030d | 未å¯åŠ¨è½¯ä»¶å®šæ—¶å™¨ | å¯åŠ¨è½¯ä»¶å®šæ—¶å™¨ | -| 15 | LOS\_ERRNO\_SWTMR\_STATUS\_INVALID | 0x0200030e | ä¸æ­£ç¡®çš„è½¯ä»¶å®šæ—¶å™¨çŠ¶æ€ | æ£€æŸ¥ç¡®è®¤è½¯ä»¶å®šæ—¶å™¨çŠ¶æ€ | -| 16 | LOS\_ERRNO\_SWTMR\_SORTLIST\_NULL | null | æš‚æ—  | 该错误ç æš‚ä¸ä½¿ç”¨ | -| 17 | LOS\_ERRNO\_SWTMR\_TICK\_PTR\_NULL | 0x02000310 | 用以获å–软件定时器超时tickæ•°çš„å…¥å‚指针为NULL | 创建一个有效的å˜é‡ | - -**错误ç å®šä¹‰ï¼š**错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下 -``` +对软件定时器存在失败å¯èƒ½æ€§çš„æ“作,包括创建ã€åˆ é™¤ã€æš‚åœã€é‡å¯å®šæ—¶å™¨ç­‰ç­‰ï¼Œå‡éœ€è¦è¿”回对应的错误ç ï¼Œä»¥ä¾¿å¿«é€Ÿå®šä½é”™è¯¯åŽŸå› ã€‚ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    åºå·

    +

    定义

    +

    实际数值

    +

    æè¿°

    +

    å‚考解决方案

    +

    1

    +

    LOS_ERRNO_SWTMR_PTR_NULL

    +

    0x02000300

    +

    软件定时器回调函数为空。

    +

    定义软件定时器回调函数。

    +

    2

    +

    LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED

    +

    0x02000301

    +

    软件定时器间隔时间为0。

    +

    é‡æ–°å®šä¹‰é—´éš”时间。

    +

    3

    +

    LOS_ERRNO_SWTMR_MODE_INVALID

    +

    0x02000302

    +

    ä¸æ­£ç¡®çš„软件定时器模å¼ã€‚

    +

    确认软件定时器模å¼ï¼ŒèŒƒå›´ä¸º[0,2]。

    +

    4

    +

    LOS_ERRNO_SWTMR_RET_PTR_NULL

    +

    0x02000303

    +

    软件定时器ID指针入å‚为NULL。

    +

    定义IDå˜é‡ï¼Œä¼ å…¥æŒ‡é’ˆã€‚

    +

    5

    +

    LOS_ERRNO_SWTMR_MAXSIZE

    +

    0x02000304

    +

    软件定时器个数超过最大值。

    +

    é‡æ–°å®šä¹‰è½¯ä»¶å®šæ—¶å™¨æœ€å¤§ä¸ªæ•°ï¼Œæˆ–者等待一个软件定时器释放资æºã€‚

    +

    6

    +

    LOS_ERRNO_SWTMR_ID_INVALID

    +

    0x02000305

    +

    ä¸æ­£ç¡®çš„软件定时器IDå…¥å‚。

    +

    ç¡®ä¿å…¥å‚åˆæ³•ã€‚

    +

    7

    +

    LOS_ERRNO_SWTMR_NOT_CREATED

    +

    0x02000306

    +

    软件定时器未创建。

    +

    创建软件定时器。

    +

    8

    +

    LOS_ERRNO_SWTMR_NO_MEMORY

    +

    0x02000307

    +

    软件定时器链表创建内存ä¸è¶³ã€‚

    +

    申请一å—足够大的内存供软件定时器使用。

    +

    9

    +

    LOS_ERRNO_SWTMR_MAXSIZE_INVALID

    +

    0x02000308

    +

    ä¸æ­£ç¡®çš„软件定时器个数最大值。

    +

    é‡æ–°å®šä¹‰è¯¥å€¼ã€‚

    +

    10

    +

    LOS_ERRNO_SWTMR_HWI_ACTIVE

    +

    0x02000309

    +

    在中断中使用定时器。

    +

    修改æºä»£ç ç¡®ä¿ä¸åœ¨ä¸­æ–­ä¸­ä½¿ç”¨ã€‚

    +

    11

    +

    LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM

    +

    0x0200030a

    +

    membox内存ä¸è¶³ã€‚

    +

    扩大内存。

    +

    12

    +

    LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED

    +

    0x0200030b

    +

    软件定时器队列创建失败。

    +

    检查用以创建队列的内存是å¦è¶³å¤Ÿã€‚

    +

    13

    +

    LOS_ERRNO_SWTMR_TASK_CREATE_FAILED

    +

    0x0200030c

    +

    软件定时器任务创建失败。

    +

    检查用以创建软件定时器任务的内存是å¦è¶³å¤Ÿå¹¶é‡æ–°åˆ›å»ºã€‚

    +

    14

    +

    LOS_ERRNO_SWTMR_NOT_STARTED

    +

    0x0200030d

    +

    未å¯åŠ¨è½¯ä»¶å®šæ—¶å™¨ã€‚

    +

    å¯åŠ¨è½¯ä»¶å®šæ—¶å™¨ã€‚

    +

    15

    +

    LOS_ERRNO_SWTMR_STATUS_INVALID

    +

    0x0200030e

    +

    ä¸æ­£ç¡®çš„软件定时器状æ€ã€‚

    +

    检查确认软件定时器状æ€ã€‚

    +

    16

    +

    LOS_ERRNO_SWTMR_SORTLIST_NULL

    +

    null

    +

    暂无。

    +

    该错误ç æš‚ä¸ä½¿ç”¨ã€‚

    +

    17

    +

    LOS_ERRNO_SWTMR_TICK_PTR_NULL

    +

    0x02000310

    +

    用以获å–软件定时器超时tickæ•°çš„å…¥å‚指针为NULL。

    +

    创建一个有效的å˜é‡ã€‚

    +

    18

    +

    LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED

    +

    0x02000311

    +

    软件定时器链表创建失败

    +

    检查内存是å¦å¤Ÿç”¨ï¼Œç„¶åŽé‡æ–°åˆ›å»ºé“¾è¡¨

    +
    + +**错误ç å®šä¹‰ï¼š** 错误ç æ˜¯ä¸€ä¸ª32ä½çš„存储å•å…ƒï¼Œ31\~24ä½è¡¨ç¤ºé”™è¯¯ç­‰çº§ï¼Œ23\~16ä½è¡¨ç¤ºé”™è¯¯ç æ ‡å¿—,15\~8ä½ä»£è¡¨é”™è¯¯ç æ‰€å±žæ¨¡å—,7\~0ä½è¡¨ç¤ºé”™è¯¯ç åºå·ï¼Œå¦‚下所示: + +``` #define LOS_ERRNO_OS_NORMAL(MID,ERRNO) \ (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) LOS_ERRTYPE_NORMAL :Define the error level as critical LOS_ERRNO_OS_ID :OS error code flag. MID:OS_MOUDLE_ID -ERRNO:error ID number -``` +ERRNO:error ID number +``` -例如: -``` +例如: + +``` #define LOS_ERRNO_SWTMR_PTR_NULL \ -LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00) -``` +LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00) +``` ### 注æ„事项 -- 软件定时器的回调函数中ä¸è¦åšè¿‡å¤šæ“作,ä¸è¦ä½¿ç”¨å¯èƒ½å¼•èµ·ä»»åŠ¡æŒ‚起或者阻塞的接å£æˆ–æ“作。 - -- 软件定时器使用了系统的一个队列和一个任务资æºï¼Œè½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡çš„优先级设定为0,且ä¸å…许修改 。 - -- 系统å¯é…置的软件定时器资æºä¸ªæ•°æ˜¯æŒ‡ï¼šæ•´ä¸ªç³»ç»Ÿå¯ä½¿ç”¨çš„软件定时器资æºæ€»ä¸ªæ•°ï¼Œè€Œå¹¶éžæ˜¯ç”¨æˆ·å¯ä½¿ç”¨çš„软件定时器资æºä¸ªæ•°ã€‚例如:系统软件定时器多å ç”¨ä¸€ä¸ªè½¯ä»¶å®šæ—¶å™¨èµ„æºæ•°ï¼Œé‚£ä¹ˆç”¨æˆ·èƒ½ä½¿ç”¨çš„软件定时器资æºå°±ä¼šå‡å°‘一个。 - -- 创建å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ï¼Œè¯¥å®šæ—¶å™¨è¶…时执行完回调函数åŽï¼Œç³»ç»Ÿä¼šè‡ªåŠ¨åˆ é™¤è¯¥è½¯ä»¶å®šæ—¶å™¨ï¼Œå¹¶å›žæ”¶èµ„æºã€‚ +- 软件定时器的回调函数中ä¸è¦åšè¿‡å¤šæ“作,ä¸è¦ä½¿ç”¨å¯èƒ½å¼•èµ·ä»»åŠ¡æŒ‚起或者阻塞的接å£æˆ–æ“作。 +- 软件定时器使用了系统的一个队列和一个任务资æºï¼Œè½¯ä»¶å®šæ—¶å™¨ä»»åŠ¡çš„优先级设定为0,且ä¸å…许修改 。 +- 系统å¯é…置的软件定时器资æºä¸ªæ•°æ˜¯æŒ‡ï¼šæ•´ä¸ªç³»ç»Ÿå¯ä½¿ç”¨çš„软件定时器资æºæ€»ä¸ªæ•°ï¼Œè€Œå¹¶éžæ˜¯ç”¨æˆ·å¯ä½¿ç”¨çš„软件定时器资æºä¸ªæ•°ã€‚例如:系统软件定时器多å ç”¨ä¸€ä¸ªè½¯ä»¶å®šæ—¶å™¨èµ„æºæ•°ï¼Œé‚£ä¹ˆç”¨æˆ·èƒ½ä½¿ç”¨çš„软件定时器资æºå°±ä¼šå‡å°‘一个。 +- 创建å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ï¼Œè¯¥å®šæ—¶å™¨è¶…时执行完回调函数åŽï¼Œç³»ç»Ÿä¼šè‡ªåŠ¨åˆ é™¤è¯¥è½¯ä»¶å®šæ—¶å™¨ï¼Œå¹¶å›žæ”¶èµ„æºã€‚ +- 创建å•æ¬¡ä¸è‡ªåˆ é™¤å±žæ€§çš„定时器,用户需è¦è°ƒç”¨å®šæ—¶å™¨åˆ é™¤æŽ¥å£åˆ é™¤å®šæ—¶å™¨ï¼Œå›žæ”¶å®šæ—¶å™¨èµ„æºï¼Œé¿å…资æºæ³„露。 ### 编程实例 #### 实例æè¿° -在下é¢çš„例å­ä¸­ï¼Œæ¼”示如下功能: -1. 软件定时器创建ã€å¯åŠ¨ã€åˆ é™¤ã€æš‚åœã€é‡å¯æ“作。 +在下é¢çš„例å­ä¸­ï¼Œæ¼”示如下功能: -2. å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ï¼Œå‘¨æœŸè½¯ä»¶å®šæ—¶å™¨ä½¿ç”¨æ–¹æ³•ã€‚ +1. 软件定时器创建ã€å¯åŠ¨ã€åˆ é™¤ã€æš‚åœã€é‡å¯æ“作。 +2. å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ï¼Œå‘¨æœŸè½¯ä»¶å®šæ—¶å™¨ä½¿ç”¨æ–¹æ³•ã€‚ #### 编程示例 å‰ææ¡ä»¶ï¼š -- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMRé…置项打开。 +- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMRé…置项打开。 +- é…置好LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支æŒçš„软件定时器数。 +- é…置好OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 -- é…置好LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支æŒçš„软件定时器数。 +代ç å®žçŽ°å¦‚下: -- é…置好OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 +``` + void Timer1_Callback(uint32_t arg); // callback fuction + + void Timer2_Callback(uint32_t arg); + + UINT32 g_timercount1 = 0; + UINT32 g_timercount2 = 0; + + void Timer1_Callback(uint32_t arg)//回调函数1 + { + unsigned long tick_last1; + g_timercount1++; + tick_last1=(UINT32)LOS_TickCountGet();//获å–当å‰Tickæ•° + dprintf("g_timercount1=%d\n",g_timercount1); + dprintf("tick_last1=%d\n",tick_last1); + + } + + void Timer2_Callback(uint32_t arg)//回调函数2 + { + unsigned long tick_last2; + tick_last2=(UINT32)LOS_TickCountGet(); + g_timercount2 ++; + dprintf("g_timercount2=%d\n",g_timercount2); + dprintf("tick_last2=%d\n",tick_last2); + } + + void Timer_example (void) { + UINT16 id1; + UINT16 id2;// timer id + UINT32 uwTick; + /*创建å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ï¼ŒTick数为1000,å¯åŠ¨åˆ°1000Tick数时执行回调函数1 */ + LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE,Timer1_Callback,&id1,1); + /*创建周期性软件定时器,æ¯100Tick数执行回调函数2 */ + LOS_SwtmrCreate(100,LOS_SWTMR_MODE_PERIOD,Timer2_Callback,&id2,1); + dprintf("create Timer1 success\n"); + + LOS_SwtmrStart (id1); //å¯åŠ¨å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ + dprintf("start Timer1 sucess\n"); + + LOS_TaskDelay(200);//延时200Tickæ•° + LOS_SwtmrTimeGet(id1,&uwTick);//获得å•æ¬¡è½¯ä»¶å®šæ—¶å™¨å‰©ä½™Tickæ•° + dprintf("uwTick =%d\n",uwTick); + + LOS_SwtmrStop(id1);//åœæ­¢è½¯ä»¶å®šæ—¶å™¨ + dprintf("stop Timer1 sucess\n"); + + LOS_SwtmrStart(id1); + LOS_TaskDelay(1000); + LOS_SwtmrDelete(id1);//删除软件定时器 + dprintf("delete Timer1 sucess\n"); + + LOS_SwtmrStart(id2);//å¯åŠ¨å‘¨æœŸæ€§è½¯ä»¶å®šæ—¶å™¨ + dprintf("start Timer2\n"); + + LOS_TaskDelay(1000); + LOS_SwtmrStop(id2); + LOS_SwtmrDelete(id2); + } +``` -代ç å®žçŽ°å¦‚下: -``` -static void Timer1_Callback (UINT32 arg); // callback fuction -static void Timer2_Callback (UINT32 arg); // callback fuction +#### ç»“æžœéªŒè¯ +得到的结果为: -static UINT32 g_timercount1 = 0; -static UINT32 g_timercount2 = 0; +![](figures/zh-cn_image_0238785960.gif) +#### å®Œæ•´å®žä¾‹ä»£ç  -static void Timer1_Callback(UINT32 arg)//回调函数1 -{ - unsigned long tick_last1; +[sample\_Timer.c](resource/sample_Timer.c) - g_timercount1 ++; - tick_last1=(UINT32)LOS_TickCountGet();//获å–当å‰Tickæ•° - dprintf("g_timercount1=%d\n",g_timercount1); - dprintf("tick_last1=%lu\n",tick_last1); -} +

    4.10 错误处ç†

    -static void Timer2_Callback(UINT32 arg)//回调函数2 -{ - UINT32 uwRet = LOS_OK; - unsigned long tick_last2; - - tick_last2=(UINT32)LOS_TickCountGet(); - g_timercount2 ++; - dprintf("g_timercount2=%d\n",g_timercount2); - dprintf("tick_last2=%lu\n",tick_last2); - uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_TIMER,LOS_INSPECT_STU_SUCCESS); - if (LOS_OK != uwRet) - { - dprintf("Set Inspect Status Err\n"); - } -} +### 概述 -UINT32 Example_swTimer(void) -{ - UINT16 id1; - UINT16 id2;// timer id - UINT32 uwRet = LOS_OK; +#### 基本概念 - /*创建å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ï¼ŒTick数为1000,å¯åŠ¨åˆ°1000Tick数时执行回调函数1 */ - uwRet = LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE,Timer1_Callback,&id1,1); - if(LOS_OK != uwRet) - { - dprintf("create Timer1 failed\n"); - } - else - { - dprintf("create Timer1 success\n"); - } - - /*创建周期性软件定时器,æ¯100Tick数执行回调函数2 */ - uwRet = LOS_SwtmrCreate(100,LOS_SWTMR_MODE_PERIOD,Timer2_Callback,&id2,1); - if(LOS_OK != uwRet) - { - dprintf("create Timer2 failed\n"); - } - else - { - dprintf("create Timer2 success\n"); - } - - uwRet = LOS_SwtmrStart(id1);//å¯åŠ¨å•æ¬¡è½¯ä»¶å®šæ—¶å™¨ - if(LOS_OK != uwRet) - { - dprintf("start Timer1 failed\n"); - } - else - { - dprintf("start Timer1 sucess\n"); - } - - (void)LOS_TaskDelay(200);//延时200Tickæ•° - - uwRet = LOS_SwtmrStop(id1);//åœæ­¢è½¯ä»¶å®šæ—¶å™¨ - if(LOS_OK != uwRet) - { - dprintf("stop Timer1 failed\n"); - } - else - { - dprintf("stop Timer1 sucess\n"); - } - - uwRet = LOS_SwtmrStart(id1); - if(LOS_OK != uwRet) - { - dprintf("start Timer1 failed\n"); - } - - (void)LOS_TaskDelay(1000); - - uwRet = LOS_SwtmrDelete(id1);//删除软件定时器 - if(LOS_OK != uwRet) - { - dprintf("delete Timer1 failed\n"); - } - else - { - dprintf("delete Timer1 sucess\n"); - } - - uwRet = LOS_SwtmrStart(id2);//å¯åŠ¨å‘¨æœŸæ€§è½¯ä»¶å®šæ—¶å™¨ - if(LOS_OK != uwRet) - { - dprintf("start Timer2 failed\n"); - } - else - { - dprintf("start Timer2 success\n"); - } - - (void)LOS_TaskDelay(1000); - - uwRet = LOS_SwtmrStop(id2); - if(LOS_OK != uwRet) - { - dprintf("stop Timer2 failed\n"); - } - - uwRet = LOS_SwtmrDelete(id2); - if(LOS_OK != uwRet) - { - dprintf("delete Timer2 failed\n"); - } - - return LOS_OK; -} -``` +错误处ç†æŒ‡ç”¨æˆ·ä»£ç å‘生错误时,系统调用错误处ç†æ¨¡å—的接å£å‡½æ•°ï¼Œå®Œæˆä¸ŠæŠ¥é”™è¯¯ä¿¡æ¯ï¼Œå¹¶è°ƒç”¨ç”¨æˆ·è‡ªå·±çš„é’©å­å‡½æ•°ï¼Œè¿›è¡Œç‰¹å®šçš„处ç†ã€‚ + +错误处ç†æ¨¡å—实现OS内部错误ç è®°å½•åŠŸèƒ½ã€‚OS内部错误ç æ— æ³•é€šè¿‡æŽ¥å£è¿”回,通常会上报错误处ç†æ¨¡å—进行记录。用户å¯ä»¥é€šè¿‡æŒ‚接错误处ç†çš„é’©å­å‡½æ•°ï¼Œè¿›è¡Œç‰¹å®šçš„处ç†ã€‚如果OS上报的错误是致命错误,系统会进行异常æµç¨‹æŽ¥ç®¡ï¼Œä»Žè€Œå¯ä»¥ä¿å­˜çŽ°åœºä»¥ä¾¿å®šä½é—®é¢˜ã€‚ + +通过错误处ç†ï¼Œæˆ‘们å¯ä»¥æŠŠç”¨æˆ·åœ¨ç¨‹åºä¸­çš„éžæ³•è¾“入进行控制和æ示,以防程åºå´©æºƒã€‚ + +#### è¿ä½œæœºåˆ¶ + +错误处ç†æ˜¯ä¸€ç§æœºåˆ¶ï¼Œç”¨äºŽå¤„ç†å¼‚常状况。当程åºå‡ºçŽ°å¼‚常错误的时候,会显示相应的错误ç ç”¨äºŽæ示用户。此外,如果有相应的错误处ç†ç¨‹åºï¼Œåˆ™ä¼šæ‰§è¡Œè¿™ä¸ªç¨‹åºã€‚ + +**图 1** 错误处ç†ç¤ºæ„图 + + +![](figures/zh-cn_image_0238816605.jpg) + +### å¼€å‘指导 + +#### 功能 + +错误处ç†æ¨¡å—为用户æ供下é¢å‡ ç§åŠŸèƒ½ã€‚ + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    错误处ç†

    +

    LOS_ErrHandle

    +

    æ ¹æ®é”™è¯¯å¤„ç†å‡½æ•°æ¥å¯¹é”™è¯¯è¿›è¡Œå¤„ç†

    +
    + +### 注æ„事项 + +无。 + +### 编程实例 + +#### 实例æè¿° + +在下é¢çš„例å­ä¸­ï¼Œæ¼”示如下功能: + +执行错误处ç†å‡½æ•°ã€‚ + +#### 编程示例 + +代ç å®žçŽ°å¦‚下: + +``` +extern USER_ERR_FUNC_S g_stUserErrFunc; +void err_handler(CHAR *pcFileName,UINT32 uwLineNo, + UINT32 uwErrorNo,UINT32 uwParaLen,VOID *pPara) +{ + printf("err handle ok\n"); +} +UINT32 Example_ErrCaseEntry(VOID) +{ + g_stUserErrFunc.pfnHook = err_handler; + /*执行错误处ç†å‡½æ•°*/ + LOS_ErrHandle(NULL, 0,0,0, NULL); + return LOS_OK; +} +``` #### ç»“æžœéªŒè¯ -得到的结果为: -![](./meta/DevGuide/pic23.png) -

    4.10 åŒå‘链表

    +编译è¿è¡Œå¾—到的结果为: + +``` +Huawei LiteOS # err handle ok +``` + +#### å®Œæ•´å®žä¾‹ä»£ç  + +[sample\_err.c](resource/sample_err.c) + +

    4.11 åŒå‘链表

    ### 概述 @@ -2690,7 +4640,7 @@ UINT32 Example_swTimer(void) åŒå‘链表是指å«æœ‰å¾€å‰å’Œå¾€åŽä¸¤ä¸ªæ–¹å‘的链表,å³æ¯ä¸ªç»“点中除存放下一个节点指针外,还增加一个指å‘å…¶å‰ä¸€ä¸ªèŠ‚点的指针。其头指针head是唯一确定的。 -从åŒå‘链表中的任æ„一个结点开始,都å¯ä»¥å¾ˆæ–¹ä¾¿åœ°è®¿é—®å®ƒçš„å‰é©±ç»“点和åŽç»§ç»“点,这ç§æ•°æ®ç»“æž„å½¢å¼ä½¿å¾—åŒå‘链表在查找时更加方便,特别是大é‡æ•°æ®çš„é历。由于åŒå‘链表具有对称性,能方便地完æˆå„ç§æ’å…¥ã€åˆ é™¤ç­‰æ“作,但需è¦æ³¨æ„å‰åŽæ–¹å‘çš„æ“作。 +从åŒå‘链表中的任æ„一个结点开始,都å¯ä»¥å¾ˆæ–¹ä¾¿åœ°è®¿é—®å®ƒçš„å‰é©±ç»“点和åŽç»§ç»“点,这ç§æ•°æ®ç»“æž„å½¢å¼ä½¿å¾—åŒå‘链表在查找时更加方便,特别是大é‡æ•°æ®çš„é历。由于åŒå‘链表具有对称性,能方便地完æˆå„ç§æ’å…¥ã€åˆ é™¤ç­‰æ“作,但需è¦æ³¨æ„å‰åŽæ–¹å‘çš„æ“作。 ### å¼€å‘指导 @@ -2698,55 +4648,100 @@ UINT32 Example_swTimer(void) Huawei LiteOS系统中的åŒå‘链表模å—为用户æ供下é¢å‡ ä¸ªæŽ¥å£ã€‚ -| 功能分类 | 接å£å | æè¿° | -|----------------------|---------------------|--------------------------| -| åˆå§‹åŒ–链表 | LOS\_ListInit | 对链表进行åˆå§‹åŒ– | -| 增加节点 | LOS\_ListAdd | 将新节点添加到链表中。 | -| 在链表尾端æ’入节点 | LOS\_ListTailInsert | 将节点æ’入到åŒå‘链表尾端 | -| 删除节点 | LOS\_ListDelete | 将指定的节点从链表中删除 | -| 判断åŒå‘链表是å¦ä¸ºç©º | LOS\_ListEmpty | 判断链表是å¦ä¸ºç©º | -| 删除节点并åˆå§‹åŒ–链表 | LOS\_ListDelInit | 将指定的节点从链表中删除,并使用该节点åˆå§‹åŒ–链表 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    功能分类

    +

    接å£å

    +

    æè¿°

    +

    åˆå§‹åŒ–链表

    +

    LOS_ListInit

    +

    对链表进行åˆå§‹åŒ–。

    +

    增加节点

    +

    LOS_ListAdd

    +

    将新节点添加到链表中。

    +

    在链表尾端æ’入节点

    +

    LOS_ListTailInsert

    +

    将节点æ’入到åŒå‘链表尾端。

    +

    在链表头端æ’入节点

    +

    LOS_ListHeadInsert

    +

    将节点æ’入到åŒå‘链表头端

    +

    删除节点

    +

    LOS_ListDelete

    +

    将指定的节点从链表中删除。

    +

    判断åŒå‘链表是å¦ä¸ºç©º

    +

    LOS_ListEmpty

    +

    判断链表是å¦ä¸ºç©ºã€‚

    +

    删除节点并åˆå§‹åŒ–链表

    +

    LOS_ListDelInit

    +

    将指定的节点从链表中删除,使用该节点åˆå§‹åŒ–链表。

    +
    ### å¼€å‘æµç¨‹ åŒå‘链表的典型开å‘æµç¨‹ï¼š 1. 调用LOS\_ListInitåˆå§‹åŒå‘链表。 - 2. 调用LOS\_ListAddå‘链表中增加节点。 - 3. 调用LOS\_ListTailInsertå‘链表尾部æ’入节点。 - 4. 调用LOS\_ListDelete删除指定节点。 - 5. 调用LOS\_ListEmpty判断链表是å¦ä¸ºç©ºã€‚ - 6. 调用LOS\_ListDelInit删除指定节点并以此节点åˆå§‹åŒ–链表。 ### 注æ„事项 -- 需è¦æ³¨æ„节点指针å‰åŽæ–¹å‘çš„æ“作。 +- 需è¦æ³¨æ„节点指针å‰åŽæ–¹å‘çš„æ“作。 ### 编程实例 #### 实例æè¿° -使用åŒå‘链表,首先è¦ç”³è¯·å†…存,删除节点的时候è¦æ³¨æ„释放掉内存。 - -本实例实现如下功能: - -1. 调用函数进行åˆå§‹åŒ–åŒå‘链表。 +使用åŒå‘链表,首先è¦ç”³è¯·å†…存,删除节点的时候è¦æ³¨æ„释放掉内存。 -2. 增加节点。 +本实例实现如下功能: -3. 删除节点。 - -4. 测试æ“作是å¦æˆåŠŸã€‚ +1. 调用函数进行åˆå§‹åŒ–åŒå‘链表。 +2. 增加节点。 +3. 删除节点。 +4. 测试æ“作是å¦æˆåŠŸã€‚ #### 编程示例 -代ç å®žçŽ°å¦‚下: -``` +代ç å®žçŽ°å¦‚下: + +``` #include "stdio.h" #include "los_list.h" @@ -2800,244 +4795,18 @@ static UINT32 DLlist_sample(VOID) #if __cplusplus } #endif /* __cpluscplus */ -#endif /* __cpluscplus */ -``` +#endif /* __cpluscplus */ +``` #### ç»“æžœéªŒè¯ -编译è¿è¡Œå¾—到的结果为: -``` +编译è¿è¡Œå¾—到的结果为: + +``` Initial head Add DLlistNode01 success Tail insert DLlistNode02 success Head insert DLlistNode03 success -Delete success -``` - -

    5.Agent Tiny

    - -### 概述 - -Agent Tiny是部署在具备广域网能力ã€å¯¹åŠŸè€—/存储/计算资æºæœ‰è‹›åˆ»é™åˆ¶çš„终端设备上的轻é‡çº§äº’è”互通中间件,开å‘者åªéœ€è°ƒç”¨å‡ ä¸ªç®€å•çš„API接å£ï¼Œä¾¿å¯å®žçŽ°è®¾å¤‡å¿«é€ŸæŽ¥å…¥åˆ°åŽä¸ºIoT云平å°ï¼ˆOceanConnect)以åŠæ•°æ®ä¸ŠæŠ¥å’Œå‘½ä»¤æŽ¥æ”¶ç­‰åŠŸèƒ½ã€‚ - -以彩ç¯åº”用举例,Agent Tiny工作原ç†å¦‚下: -![](./meta/DevGuide/pic24.png) - -### å¼€å‘指导 - -#### 使用场景 - -å¼€å‘者åªéœ€å®žçŽ°å¹³å°æŠ½è±¡å±‚接å£ï¼Œå³å¯å¯¹æŽ¥OceanConncetå¹³å°ã€‚ - -#### 功能 - -Agent Tiny互è”互通中间件为用户æ供以下几类接å£ï¼š - -| 接å£åˆ†ç±» | 接å£å | æè¿° | -|--------------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Agent Tinyä¾èµ–æŽ¥å£ | atiny\_cmd\_ioctl | Agent Tiny申明和调用,开å‘者实现。该接å£æ˜¯LwM2M标准对象å‘设备下å‘命令的统一入å£ï¼Œæ¯”如读写设备数æ®ï¼Œä¸‹å‘å¤ä½ï¼Œå‡çº§å‘½ä»¤ç­‰ã€‚为了é¿å…æ­»é”,该接å£ä¸­ç¦æ­¢è°ƒç”¨Agent Tinyå¯¹å¤–æŽ¥å£ | -| | atiny\_event\_notify | Agent Tiny申明和调用,开å‘者实现,Agent Tiny把注册过程的关键状æ€ï¼Œä»¥åŠè¿è¡Œè¿‡ç¨‹çš„关键事件通知用户,便于用户根æ®è‡ªèº«çš„应用场景çµæ´»åœ°åšå¯é æ€§å¤„ç†ã€‚此外,为了é¿å…æ­»é”,该接å£ä¸­ç¦æ­¢è°ƒç”¨Agent Tinyå¯¹å¤–æŽ¥å£ | -| Agent Tinyå¯¹å¤–æŽ¥å£ | atiny\_init | Agent Tinyçš„åˆå§‹åŒ–接å£ï¼Œç”±Agent Tiny实现,开å‘者调用 | -| | atiny\_bind | Agent Tiny的主函数体,由Agent Tiny实现,开å‘者调用,调用æˆåŠŸåŽï¼Œä¸ä¼šè¿”回。该接å£æ˜¯Agent Tiny主循环体,实现了LwM2Må议处ç†ï¼Œæ³¨å†ŒçŠ¶æ€æœºï¼Œé‡ä¼ é˜Ÿåˆ—,订阅上报 | -| | atiny\_deinit | Agent Tiny的去åˆå§‹åŒ–接å£ï¼Œç”±Agent Tiny实现,开å‘者调用,该接å£ä¸ºé˜»å¡žå¼æŽ¥å£ï¼Œè°ƒç”¨è¯¥æŽ¥å£æ—¶ï¼Œä¼šç›´åˆ°agent tiny主任务退出,资æºé‡Šæ”¾å®Œæ¯•ï¼Œè¯¥æŽ¥å£æ‰ä¼šé€€å‡º | -| | atiny\_data\_report | Agent Tinyæ•°æ®ä¸ŠæŠ¥æŽ¥å£ï¼Œç”±agent Tiny实现,开å‘者调用,用户APPæ•°æ®ä½¿ç”¨è¯¥æŽ¥å£ä¸ŠæŠ¥ï¼Œè¯¥æŽ¥å£ä¸ºé˜»å¡žæŽ¥å£ï¼Œä¸å…许在中断中使用 | - -#### å¼€å‘æµç¨‹ - -Agent Tiny典型场景的开å‘æµç¨‹ï¼š - -1. æ ¹æ®Agent Tinyæ供的头文件说明,实现atiny\_cmd\_ioctl接å£ã€‚该接å£æœ‰ä¸‰ä¸ªå‚数,å‚æ•°cmd为命令类型,å‚æ•°arg的内存空间由Agent Tiny分é…,其内容填充视cmd而异,如读数æ®ç›¸å…³å‘½ä»¤ï¼Œç”±device侧填充,Agent Tiny使用,如写数æ®å‘½ä»¤ï¼Œåˆ™ç”±agent Tiny填充,device侧使用。å‚æ•°len指arg所指å‘的内存空间长度,device侧填充或读å–时,务必防止溢出。 - -2. æ ¹æ®Agent Tinyæ供的头文件说明,实现atiny\_event\_notify接å£ã€‚该接å£æœ‰ä¸‰ä¸ªå‚数,å‚æ•°stat为事件类型,å‚æ•°arg是 Agent Tinyæ ¹æ®äº‹ä»¶ç±»åž‹ï¼Œä¼ é€’ç»™device侧的具体的事件信æ¯ï¼Œlen为arg长度,device侧使用时务分防止溢出。 - -3. 调用atiny\_initåˆå§‹åŒ–Agent Tiny,获å–对应的Agent Tinyå¥æŸ„,开å‘者应处ç†è¯¥æŽ¥å£è¿”回值,返回错误时,å¥æŸ„无效。 - -4. 创建一个新任务,栈大å°å»ºè®®ä¸å°äºŽ4K,调用atiny\_bind,å¯åŠ¨Agent Tiny。atiny\_bind调用æˆåŠŸåŽä¸å†è¿”回,atiny\_bind内部实现了Agent Tiny的主体任务。 - -5. 如需è¦åœæ­¢Agent Tiny,调用atiny\_deinit,该接å£ç­‰å¾…Agent Tiny退出且释放资æºåŽè¿”回。 - -6. atiny\_data\_reportå¯ä»¥åœ¨å¼€å‘者业务的任何一个任务中调用。 - -#### 互斥é”é”™è¯¯ç  - -Agent Tiny对外接å£å’Œä¾èµ–接å£ï¼Œå¯èƒ½å­˜åœ¨çš„错误,统一用以下错误ç ã€‚ - -| åºå· | 定义 | 实际数值 | æè¿° | å‚考解决方案 | -|------|-------------------------------|----------|--------------------|--------------------------------------------------------------------| -| 1 | ATINY\_OK | 0 | æ­£å¸¸è¿”å›žç  | | -| 2 | ATINY\_ARG\_INVALID | -1 | éžæ³•å‚æ•° | ç¡®ä¿å…¥å‚åˆæ³• | -| 3 | ATINY\_BUF\_OVERFLOW | -2 | 缓冲区溢出 | ç¡®ä¿ç¼“冲区充足 | -| 4 | ATINY\_MSG\_CONGEST | -3 | 消æ¯æ‹¥å¡ž | 暂缓数æ®ä¸ŠæŠ¥ | -| 5 | ATINY\_MALLOC\_FAILED | -4 | 内存申请失败 | 检查内存是å¦æœ‰æ³„æ¼ | -| 6 | ATINY\_RESOURCE\_NOT\_FOUND | -5 | æ•°æ®ä¸ŠæŠ¥ç±»åž‹éžæ³• | 检查数æ®ç±»åž‹æ˜¯å¦æ­£ç¡® | -| 7 | ATINY\_RESOURCE\_NOT\_ENOUGH | -6 | 系统资æºä¸è¶³ | 检查系统资æºï¼Œæ¯”如信å·é‡ï¼Œå¥—接字个数等,是å¦é…置过少,或是å¦æœ‰æ³„æ¼ | -| 8 | ATINY\_CLIENT\_UNREGISTERED | -7 | AgentTiny注册失败 | 检查psk,æœåŠ¡å™¨ä¿¡æ¯ç­‰æ˜¯å¦æ­£ç¡® | -| 9 | ATINY\_SOCKET\_CREATE\_FAILED | -8 | 网络套接字创建失败 | 检查网络é…置和å‚数是å¦æ­£ç¡® | - -#### å¹³å°å·®å¼‚性 -无。 - -### 注æ„事项 - -- atiny\_cmd\_ioctlå’Œatiny\_event\_notifyç¦æ­¢è°ƒç”¨atiny\_deinit,atiny\_data\_report,atiny\_init,atiny\_bind四个Agent Tiny对外接å£ï¼Œå¦åˆ™å¯èƒ½äº§ç”Ÿæ­»é”,或其他异常。 - -- 调用atiny\_deinit之å‰åŠ¡å¿…确认已调用atiny\_bin,å¦åˆ™atiny\_deinit将一直阻塞,调用完atiny\_deinitåŽï¼Œå¯¹åº”çš„Agent Tinyå¥æŸ„将失效,ç¦æ­¢å†ä½¿ç”¨ã€‚ - -- 承载atiny\_bind的任务栈大å°å»ºè®®ä¸å°äºŽ4K,任务优先级视系统情况而定,太低å¯èƒ½ä¼šå¯¼è‡´æŽ¥æ”¶ä¸¢åŒ…,å‘é€å»¶è¿Ÿç­‰çŽ°è±¡ã€‚ - -### 编程实例 - -#### 实例æè¿° - -本实例实现如下æµç¨‹ï¼š - -1. 实现atiny\_cmd\_ioctlå’Œatiny\_event\_notify。 - -2. 创建数æ®ä¸ŠæŠ¥ä»»åŠ¡ã€‚ - -3. 调用atiny\_initåˆå§‹åŒ–AgentTiny。 - -4. 调用atiny\_bindå¯åŠ¨AgentTiny。 - -#### 编程示例 - -**å‰ææ¡ä»¶ï¼š** - -在工程é…置中,WITH\_DTLS编译选项打开。 - -**代ç å®žçŽ°å¦‚下:** -``` -#define MAX_PSK_LEN 16 -#define DEFAULT_SERVER_IPV4 "192.168.0.5" -#define DEFAULT_SERVER_PORT "5684" -#define LWM2M_LIFE_TIME 50000 -char * g_endpoint_name_s = "11110001"; -unsigned char g_psk_value[MAX_PSK_LEN] = {0xef,0xe8,0x18,0x45,0xa3,0x53,0xc1,0x3c,0x0c,0x89,0x92,0xb3,0x1d,0x6b,0x6a,0x33}; - -UINT32 TskHandle; - -static void* g_phandle = NULL; -static atiny_device_info_t g_device_info; -static atiny_param_t g_atiny_params; - - -int atiny_cmd_ioctl(atiny_cmd_e cmd, char* arg, int len) -{ - int result = ATINY_OK; - switch(cmd) - { - case ATINY_DO_DEV_REBOOT: - result = atiny_do_dev_reboot(); - break; - case ATINY_GET_MIN_VOLTAGE: - result = atiny_get_min_voltage((int*)arg); - break; - default: - result = ATINY_RESOURCE_NOT_FOUND; - break; - } - - return result; -} - -void atiny_event_notify(atiny_event_e stat, char* arg, int len) -{ - (void)atiny_printf("notify:stat:%d\r\n", stat); -} - -void ack_callback(atiny_report_type_e type, int cookie, data_send_status_e status) -{ - printf("ack type:%d cookie:%d status:%d\n", type,cookie, status); -} - -void app_data_report(void) -{ - uint8_t buf[5] = {0,1,6,5,9}; - data_report_t report_data; - int cnt = 0; - - report_data.buf = buf; - report_data.callback = ack_callback; - report_data.cookie = 0; - report_data.len = sizeof(buf); - report_data.type = APP_DATA; - while(1) - { - report_data.cookie = cnt; - cnt++; - (void)atiny_data_report(g_phandle, &report_data); - (void)LOS_TaskDelay(2000); - } -} - -UINT32 creat_report_task() -{ - UINT32 uwRet = LOS_OK; - TSK_INIT_PARAM_S task_init_param; - - task_init_param.usTaskPrio = 1; - task_init_param.pcName = "app_data_report"; - task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)app_data_report; - task_init_param.uwStackSize = 0x1000; - - uwRet = LOS_TaskCreate(&TskHandle, &task_init_param); - if(LOS_OK != uwRet) - { - return uwRet; - } - return uwRet; - -} - -void agent_tiny_entry(void) -{ - UINT32 uwRet = LOS_OK; - atiny_param_t* atiny_params; - atiny_security_param_t *security_param = NULL; - atiny_device_info_t *device_info = &g_device_info; - - device_info->endpoint_name = g_endpoint_name_s; - device_info->manufacturer = "test"; - - atiny_params = &g_atiny_params; - atiny_params->server_params.binding = "UQ"; - atiny_params->server_params.life_time = LWM2M_LIFE_TIME; - atiny_params->server_params.storing_cnt = 0; - - security_param = &(atiny_params->security_params[0]); - security_param->is_bootstrap = FALSE; - security_param->server_ip = DEFAULT_SERVER_IPV4; - security_param->server_port = DEFAULT_SERVER_PORT; - security_param->psk_Id = g_endpoint_name_s; - security_param->psk = (char*)g_psk_value; - security_param->psk_len = sizeof(g_psk_value); - - - if(ATINY_OK != atiny_init(atiny_params, &g_phandle)) - { - return; - } - - uwRet = creat_report_task(); - if(LOS_OK != uwRet) - { - return; - } - -(void)atiny_bind(device_info, g_phandle); -} -``` - -#### ç»“æžœéªŒè¯ - -1. 登录OceanConncet测试平å°ï¼š - - - -请在OceanConnectå¹³å°ä¸Šæå‰æ³¨å†Œè´¦å·ã€‚ - -2. 选择查看“设备â€ã€‚ -![](./meta/DevGuide/pic25.png) +Delete success +``` -3. 点击第一个设备,查看其设备标识ç ä¸º11110001,说明设备已ç»æ³¨å†Œã€‚ -![](./meta/DevGuide/pic26.png) diff --git a/doc/LiteOS_Code_Info.md b/doc/LiteOS_Code_Info.md index 1bfa70263..7e83d12b4 100644 --- a/doc/LiteOS_Code_Info.md +++ b/doc/LiteOS_Code_Info.md @@ -5,298 +5,84 @@ LiteOSå…¥å£åœ¨å·¥ç¨‹å¯¹åº”çš„main.c中,基本æµç¨‹å¦‚下: int main(void) - { - UINT32 uwRet = LOS_OK; - HardWare_Init(); - uwRet = LOS_KernelInit(); - + uwRet = OsMain(); if (uwRet != LOS_OK) { return LOS_NOK; } - LOS_Inspect_Entry(); + OsStart(); - LOS_Start(); + return 0; } -1. 首先进行硬件åˆå§‹åŒ– HardWare_Init(); - -2. åˆå§‹åŒ–LiteOS内核 LOS_KernelInit(); -3. åˆå§‹åŒ–内核例程 LOS_Inspect_Entry(); - -4. 最åŽè°ƒç”¨LOS_Start();开始task调度,LiteOS开始正常工作; +首先进行硬件åˆå§‹åŒ–:HardWare_Init(); + +åˆå§‹åŒ–LiteOS内核åŠä¾‹ç¨‹ï¼šOsMain(); + +调用OsStart(),开始task调度,LiteOS开始正常工作。 ## LiteOS的代ç ç›®å½•ç»“构说明 关于代ç æ ‘中å„个目录存放的æºä»£ç çš„相关内容简介如下: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    一级目录二级目录三级目录说明
    archarmarm-mM核中断ã€è°ƒåº¦ã€tick相关代ç 
    commonarm核公用的cmsis core接å£
    componentscmsisLiteOSæ供的cmsis os接å£å®žçŽ°
    connectivityagent_tinyagent_tiny端云互通组件,包括公共头文件ã€ç¤ºä¾‹ä»£ç ã€å®¢æˆ·ç«¯å®žçŽ°ä»£ç ã€æ“作系统适é…层代ç 
    at_frameLiteOS AT框架实现
    lwm2mlwm2må议实现
    nbiotLiteOS NB-IoT API
    paho.mqtt.embedded-c-1.1.0MQTTå¼€æºå议实现
    fota固件å‡çº§ä»£ç 
    fs文件系统,å«VFSã€spiffsã€ramfsã€kifsã€devfs
    liblibcLiteOS libc优化
    netlwip_portlwip驱动åŠOS适é…代ç 
    lwip-2.0.3lwipå议实现
    securitymbedtls/mbedtls_portMBEDTLSçš„OS适é…代ç 
    mbedtls/mbedtl-2.6.0MBEDTLSå议实现
    doc此目录存放的是LiteOS的使用文档和API说明等文档
    examplesAPI供开å‘者测试LiteOS内核的demo示例,此目录存放的是内核功能测试用的相关用例的代ç 
    includeAPI功能头文件存放目录
    kernelbasecoreLiteOS基础内核代ç ï¼ŒåŒ…括队列ã€task调度ã€è½¯timerã€æ—¶é—´ç‰‡è®¡ç®—等功能
    OM与错误处ç†ç›¸å…³çš„文件
    includeLiteOS内核内部使用的头文件
    ipcLiteOS中task间通讯的相关接å£ï¼ŒåŒ…括事件ã€ä¿¡å·é‡ã€æ¶ˆæ¯é˜Ÿåˆ—ã€äº’æ–¥é”ç­‰
    memLiteOS中的内核内存管ç†çš„相关代ç 
    misc内存对é½åŠŸèƒ½ä»¥åŠæ¯«ç§’级休眠sleep功能
    includeLiteOSå¼€æºå†…核头文件
    extendedtickless低功耗框架代ç 
    targetsCloud_NB-IoT_STM32F103RE_OneNET中国移动OneNet NB-IoT 端云demo工程
    Cloud_NXP51U68NXP ARM Cortex M0 ENC28J60以太网LiteOS SDK端云demo
    Cloud_STM32F429IGTx_FIRE野ç«STM32F429(ARM Cortex M4)以太网/ESP8266串å£WiFi/SIM900A GPRS/NB-IoT BC95å››ç§è¿žæŽ¥æ–¹å¼çš„LiteOS SDK端云demo,内部用编译å®åŒºåˆ†ï¼Œå…¶ä¸­wifiã€gprsã€NB-IOT使用LiteOS SDKçš„AT框架实现
    Cloud_STM32L431RxTx_IoTClub物è”网俱ä¹éƒ¨EVB-M1 STM32L431(ARM Cortex M4)ESP8266WiFi/NB-IoT BC95两ç§è¿žæŽ¥æ–¹å¼çš„LiteOS SDK端云demo
    Cloud_STM3210E_EVALSTM3210E(ARM Cortex M3)W5500 以太网LiteOS SDK端云demo
    Cloud_wifi_STM32F429ZI_NUCLEOSTM32F429(ARM Cortex M4)marvell SDIO wifi LiteOS SDK端云demo
    Cloud_wifi_STM32F767ZI_NUCLEOSTM32F767(ARM Cortex M7)esp8266 spi wifi LiteOS SDK端云demo
    Demo_Tutorial_STM32F103VC_TAIBISTM32F103_TAIBI(ARM Cortex M3)LiteOS入门demo,最简å•çš„LED点ç¯ç¤ºä¾‹ç¨‹åº
    Standard_FRDM_KW41ZFRDM(ARM Cortex M0+)Standardå‰ç¼€å‘½å的工程仅为内核移æ¤demo,下åŒï¼ˆå«åŽŸåŽ‚芯片驱动)
    Standard_IMXRT1052_FIREIMXRT1052(ARM Cortex M7)跨界处ç†å™¨NXP IMXRT1052内核移æ¤demo(å«åŽŸåŽ‚芯片驱动)
    Standard_msp430f5438a_taurus_v4.2MSP430(TI 16ä½ä½ŽåŠŸè€—å•ç‰‡æœºï¼‰LiteOS首个16ä½å•ç‰‡æœºå†…核移æ¤demo(å«åŽŸåŽ‚芯片驱动)
    Standard_NRF51822_BLENRF51822(ARM Cortex M0)NRF51822è“牙芯片内核移æ¤demo(å«åŽŸåŽ‚芯片驱动)
    Standard_STM32F0DiscoverySTM32F0Discovery(ARM Cortex M0)STM32F0 内核移æ¤demo,RAM 8KB,资æºè£å‰ªå¯å‚考该工程é…置(å«åŽŸåŽ‚芯片驱动)
    Standard_STM32F103RB_NUCLEOF103(ARM Cortex M3)STM32F103内核移æ¤demo(å«åŽŸåŽ‚芯片驱动)
    Standard_STM32F103VC_TAIBISTM32F103VC_TAIBI(ARM Cortex M3)钛比STM32F103å¼€å‘æ¿å†…核移æ¤demo(å«åŽŸåŽ‚芯片驱动)
    Standard_STM32F746ZG_NUCLEOF746(ARM Cortex M7)STM32F746内核移æ¤demo(å«åŽŸåŽ‚芯片驱动)
    +| 一级目录 | 二级目录 | 三级目录 | 说明 | +| ---------- | ------------------------ | -------------------- | ------------------------------------------------------------ | +| arch | arm | cortex-a | A核内存mmuã€å¼‚常处ç†ã€æ—¶é’Ÿç­‰ç›¸å…³ä»£ç ï¼Œæ–°å¢ž | +| | | cortex-m | M核中断ã€è°ƒåº¦ã€tickç›¸å…³ä»£ç  | +| | | common | arm核公用的cmsis coreæŽ¥å£ | +| | | include | arm头文件 | +| | common | | cmsis头文件 | +| | msp430 | | msp430架构中断ã€è°ƒåº¦ã€tickç›¸å…³ä»£ç  | +| build | | | 预留的一个空的makefile | +| components | connectivity | agent_tiny | agent_tiny端云互通组件,包括公共头文件ã€ç¤ºä¾‹ä»£ç ã€å®¢æˆ·ç«¯å®žçŽ°ä»£ç ã€æ“作系统适é…å±‚ä»£ç  | +| | | lwm2m | lwm2må议实现 | +| | | nb_iot | LiteOS NB-IoT API | +| | | mqtt | MQTTå¼€æºå议实现 | +| | ota | | 固件å‡çº§ä»£ç  | +| | fs | | 文件系统,å«VFSã€spiffsã€ramfsã€kifsã€fatfsã€devfs | +| | lib | libc | LiteOS libc优化 | +| | | libsec | 安全函数库 | +| | | cJSON | c语言json库 | +| | log | | 日志等级控制 | +| | net | at_frame | LiteOS AT框架API | +| | | at_device | AT设备适é…层 | +| | | lwip/lwip_port | lwip驱动åŠOS适é…ä»£ç  | +| | | lwip/lwip-2.0.3 | lwipå议实现 | +| | | lwip/ppp_port | lwipåè®®ppp端å£æ”¯æŒ | +| | | sal | socketé€šè®¯æ”¯æŒ | +| | security | mbedtls/mbedtls_port | mbed TLSçš„OS适é…ä»£ç  | +| | | mbedtls/mbedtl-2.6.0 | mbed TLSå议实现 | +| doc | | | 此目录存放的是LiteOS的使用文档和API说明等文档 | +| demos | kernel | API | 供开å‘者测试LiteOS内核的demoç¤ºä¾‹ï¼Œæ­¤ç›®å½•å­˜æ”¾çš„æ˜¯å†…æ ¸åŠŸèƒ½æµ‹è¯•ç”¨çš„ç›¸å…³ç”¨ä¾‹çš„ä»£ç  | +| | | include | API功能头文件存放目录 | +| | agenttiny_lwm2m | | lwm2måè®® demo | +| | agenttiny_mqtt | | mqtt åè®®demo | +| | dtls_server | | dtlsåè®®demo | +| | fs | | 文件系统demo | +| | ipv6_client | | Ipv6åè®®demo | +| | nbiot_without_atiny | | NB_IoT demo | +| include | | | componentså„个模å—所ä¾èµ–的头文件 | +| kernel | base | core | LiteOS基础内核代ç ï¼ŒåŒ…括队列ã€task调度ã€è½¯timerã€æ—¶é—´ç‰‡è®¡ç®—等功能 | +| | | om | 与错误处ç†ç›¸å…³çš„文件 | +| | | include | LiteOS内核内部使用的头文件 | +| | | ipc | LiteOS中task间通讯的相关接å£ï¼ŒåŒ…括事件ã€ä¿¡å·é‡ã€æ¶ˆæ¯é˜Ÿåˆ—ã€äº’æ–¥é”ç­‰ | +| | | mem | LiteOS中的内核内存管ç†çš„ç›¸å…³ä»£ç  | +| | | misc | 内存对é½åŠŸèƒ½ä»¥åŠæ¯«ç§’级休眠sleep功能 | +| | | mp | 预留多CPUæ”¯æŒ | +| | | sched | ä»»åŠ¡è°ƒåº¦æ”¯æŒ | +| | include | | LiteOSå¼€æºå†…核头文件 | +| | extended | tickless | tickless定时机制实现 | +| osdepends | liteos | cmsis | liteos cmsis_os 1.0å’Œ2.0æ”¯æŒ | +| targets | Cloud_STM32F429IGTx_FIRE | | 野ç«STM32F429(ARM Cortex M4)å¼€å‘æ¿å¯¹åº”的编程åŠå¼€å‘工程æºç åŒ… | +| | Mini_Project | | 最å°å·¥ç¨‹ | +| | NXP_LPC51U68 | | NXP ARM Cortex M0 ENC28J60以太网LiteOS SDK端云demo | +| | STM32F103VET6_NB_GCC | | F103(ARM Cortex M3)内核移æ¤demo,NB-IoT,GCC环境 | +| | bsp | | 通用æ¿çº§æ”¯æŒåŒ… | +| test | | | 内核åŠç³»ç»Ÿåº“çš„å‚è€ƒæµ‹è¯•ä»£ç  | \ No newline at end of file diff --git "a/doc/figures/Huawei-LiteOS-Kernel\347\232\204\345\237\272\346\234\254\346\241\206\346\236\266\345\233\276.png" "b/doc/figures/Huawei-LiteOS-Kernel\347\232\204\345\237\272\346\234\254\346\241\206\346\236\266\345\233\276.png" new file mode 100644 index 000000000..3a69d4dfd Binary files /dev/null and "b/doc/figures/Huawei-LiteOS-Kernel\347\232\204\345\237\272\346\234\254\346\241\206\346\236\266\345\233\276.png" differ diff --git "a/doc/figures/l00167098-\344\270\255\350\275\257\346\254\247\346\213\211\345\274\200\345\217\221\351\203\250-iCOS-image-dd30deb7-1840-4cfc-b51d-e55d71b78f71.png" "b/doc/figures/l00167098-\344\270\255\350\275\257\346\254\247\346\213\211\345\274\200\345\217\221\351\203\250-iCOS-image-dd30deb7-1840-4cfc-b51d-e55d71b78f71.png" new file mode 100644 index 000000000..84b237fa1 Binary files /dev/null and "b/doc/figures/l00167098-\344\270\255\350\275\257\346\254\247\346\213\211\345\274\200\345\217\221\351\203\250-iCOS-image-dd30deb7-1840-4cfc-b51d-e55d71b78f71.png" differ diff --git "a/doc/figures/wwx300029-\344\270\255\350\275\257\346\254\247\346\213\211\345\274\200\345\217\221\351\203\250-iCOS-image-7af87939-8a3f-4948-9de4-4032c6292d6e.png" "b/doc/figures/wwx300029-\344\270\255\350\275\257\346\254\247\346\213\211\345\274\200\345\217\221\351\203\250-iCOS-image-7af87939-8a3f-4948-9de4-4032c6292d6e.png" new file mode 100644 index 000000000..e1f2cc9ac Binary files /dev/null and "b/doc/figures/wwx300029-\344\270\255\350\275\257\346\254\247\346\213\211\345\274\200\345\217\221\351\203\250-iCOS-image-7af87939-8a3f-4948-9de4-4032c6292d6e.png" differ diff --git a/doc/figures/zh-cn_image_0237405366.png b/doc/figures/zh-cn_image_0237405366.png new file mode 100644 index 000000000..b34405b25 Binary files /dev/null and b/doc/figures/zh-cn_image_0237405366.png differ diff --git a/doc/figures/zh-cn_image_0237405378.jpg b/doc/figures/zh-cn_image_0237405378.jpg new file mode 100644 index 000000000..40f82219b Binary files /dev/null and b/doc/figures/zh-cn_image_0237405378.jpg differ diff --git a/doc/figures/zh-cn_image_0237405390.png b/doc/figures/zh-cn_image_0237405390.png new file mode 100644 index 000000000..9bbb3f72f Binary files /dev/null and b/doc/figures/zh-cn_image_0237405390.png differ diff --git a/doc/figures/zh-cn_image_0237405424.jpg b/doc/figures/zh-cn_image_0237405424.jpg new file mode 100644 index 000000000..386d95d8e Binary files /dev/null and b/doc/figures/zh-cn_image_0237405424.jpg differ diff --git a/doc/figures/zh-cn_image_0237405430.png b/doc/figures/zh-cn_image_0237405430.png new file mode 100644 index 000000000..defe48124 Binary files /dev/null and b/doc/figures/zh-cn_image_0237405430.png differ diff --git a/doc/figures/zh-cn_image_0238585887.jpg b/doc/figures/zh-cn_image_0238585887.jpg new file mode 100644 index 000000000..3c4685079 Binary files /dev/null and b/doc/figures/zh-cn_image_0238585887.jpg differ diff --git a/doc/figures/zh-cn_image_0238601438.gif b/doc/figures/zh-cn_image_0238601438.gif new file mode 100644 index 000000000..bfa37167e Binary files /dev/null and b/doc/figures/zh-cn_image_0238601438.gif differ diff --git a/doc/figures/zh-cn_image_0238785960.gif b/doc/figures/zh-cn_image_0238785960.gif new file mode 100644 index 000000000..9ee640450 Binary files /dev/null and b/doc/figures/zh-cn_image_0238785960.gif differ diff --git a/doc/figures/zh-cn_image_0238816605.jpg b/doc/figures/zh-cn_image_0238816605.jpg new file mode 100644 index 000000000..ff494fc6b Binary files /dev/null and b/doc/figures/zh-cn_image_0238816605.jpg differ diff --git a/doc/figures/zh-cn_image_0238925517.jpg b/doc/figures/zh-cn_image_0238925517.jpg new file mode 100644 index 000000000..6936ca073 Binary files /dev/null and b/doc/figures/zh-cn_image_0238925517.jpg differ diff --git "a/doc/figures/\344\272\213\344\273\266\345\224\244\351\206\222\344\273\273\345\212\241\347\244\272\346\204\217\345\233\276.png" "b/doc/figures/\344\272\213\344\273\266\345\224\244\351\206\222\344\273\273\345\212\241\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 000000000..3dcaa1b17 Binary files /dev/null and "b/doc/figures/\344\272\213\344\273\266\345\224\244\351\206\222\344\273\273\345\212\241\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/doc/figures/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/doc/figures/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 000000000..d9054aa4a Binary files /dev/null and "b/doc/figures/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/doc/figures/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" "b/doc/figures/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 000000000..09b80eb75 Binary files /dev/null and "b/doc/figures/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/doc/figures/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/doc/figures/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 000000000..e393f1cdb Binary files /dev/null and "b/doc/figures/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/doc/figures/\351\230\237\345\210\227\350\257\273\345\206\231\346\225\260\346\215\256\346\223\215\344\275\234\347\244\272\346\204\217\345\233\276.png" "b/doc/figures/\351\230\237\345\210\227\350\257\273\345\206\231\346\225\260\346\215\256\346\223\215\344\275\234\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 000000000..6ed031e73 Binary files /dev/null and "b/doc/figures/\351\230\237\345\210\227\350\257\273\345\206\231\346\225\260\346\215\256\346\223\215\344\275\234\347\244\272\346\204\217\345\233\276.png" differ diff --git "a/doc/figures/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" "b/doc/figures/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" new file mode 100644 index 000000000..f99261a36 Binary files /dev/null and "b/doc/figures/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" differ diff --git a/doc/resource/sample_Timer.c b/doc/resource/sample_Timer.c new file mode 100644 index 000000000..63340aff1 --- /dev/null +++ b/doc/resource/sample_Timer.c @@ -0,0 +1,81 @@ +/************************************************************************* + > File Name: it_Timer_example.c + > Author: + > Mail: + > Created Time: Sat 25 Jul 2015 03:42:36 PM CST + ************************************************************************/ + +#include +#include"osTest.h" +#include "los_swtmr.h" +#include "time.h" +#include "los_sys.h" + + +void Timer1_Callback (uint32_t arg); // callback fuction + +void Timer2_Callback (uint32_t arg);//»Øµ÷º¯Êý + + +UINT32 g_timercount1 = 0; +UINT32 g_timercount2 = 0; + + +void Timer1_Callback(uint32_t arg) +{ + + unsigned long tick_last1; + g_timercount1 ++; + tick_last1=(UINT32)LOS_TickCountGet(); + dprintf("g_timercount1=%d\n",g_timercount1); + dprintf("tick_last1=%d\n",tick_last1); + +} + +void Timer2_Callback(uint32_t arg) +{ + + unsigned long tick_last2; + tick_last2=(UINT32)LOS_TickCountGet(); + g_timercount2 ++; + dprintf("g_timercount2=%d\n",g_timercount2); + dprintf("tick_last2=%d\n",tick_last2); +} + + + + +void Timer_example (void) { + UINT16 id1; + UINT16 id2;// timer id + UINT32 uwTick; + // uint32_t timerDelay; // timer value + + LOS_SwTmrCreate (1000, LOS_SWTMR_MODE_ONCE,Timer1_Callback,&id1,1); + LOS_SwTmrCreate(100,LOS_SWTMR_MODE_PERIOD,Timer2_Callback,&id2,1); + dprintf("create Timer1 success\n"); + // timerDelay = 100; + LOS_SwTmrStart (id1); + dprintf("start Timer1 sucess\n"); + LOS_TaskDelay(200); + LOS_SwTmrTimeGet(id1,&uwTick); + dprintf("uwTick =%d\n",uwTick); + LOS_SwTmrStop(id1); + dprintf("stop Timer1 sucess\n"); + LOS_SwTmrStart(id1); + LOS_TaskDelay(1000); + LOS_SwTmrDelete(id1); + dprintf("delete Timer1 sucess\n"); + LOS_SwTmrStart(id2); + dprintf("start Timer2\n"); + LOS_TaskDelay(1000); + LOS_SwTmrStop(id2); + LOS_SwTmrDelete(id2); + + + // Create periodic timer + + //...... +} + + diff --git a/doc/resource/sample_err.c b/doc/resource/sample_err.c new file mode 100644 index 000000000..6a3b6da36 --- /dev/null +++ b/doc/resource/sample_err.c @@ -0,0 +1,37 @@ +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#include "osTest.h" +#include "math.h" +#include "semaphore.h" +#include "pthread.h" +#include "time.h" +#include "fcntl.h" +#include "sys/stat.h" +#include "codes.h" +#include "hal_platform_ints.h" +#include "los_task.h" + +extern USER_ERR_FUNC_S g_stUserErrFunc; +void *err_handler(CHAR *pcFileName, + UINT32 uwLineNo, + UINT32 uwErrorNo, + UINT32 uwParaLen, + VOID *pPara) +{ + printf("err handel ok\n"); +} +UINT32 Example_ErrCaseEntry(VOID) +{ + LOS_ErrHandle(NULL, 0,0,0, NULL); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/doc/resource/sample_event.c b/doc/resource/sample_event.c new file mode 100644 index 000000000..bc54c4608 --- /dev/null +++ b/doc/resource/sample_event.c @@ -0,0 +1,85 @@ +#include "los_event.h" +#include "los_task.h" +//#include "osTest.h" + +/*ÈÎÎñPID*/ +UINT32 g_TestTaskID01; + +/*ʼþ¿ØÖƽṹÌå*/ +EVENT_CB_S example_event; + +/*µÈ´ýµÄʼþÀàÐÍ*/ +#define event_wait 0x00000001 + +/*ÓÃÀýÈÎÎñÈë¿Úº¯Êý*/ +VOID Example_Event() +{ + UINT32 uwRet; + UINT32 uwEvent; + +/*³¬Ê± µÈ´ý·½Ê½¶Áʼþ,³¬Ê±Ê±¼äΪ100 ticks + Èô100 ticks ºóδ¶ÁÈ¡µ½Ö¸¶¨Ê¼þ£¬¶Áʼþ³¬Ê±£¬ÈÎÎñÖ±½Ó»½ÐÑ*/ + printf("Example_Event wait event 0x%x \n",event_wait); + + uwEvent = Los_EventRead(&example_event, event_wait, LOS_WAITMODE_AND, 100); + if(uwEvent == event_wait) + { + printf("Example_Event,read event :0x%x\n",uwEvent); + } + else + printf("Example_Event,read event timeout\n"); + return; +} + +UINT32 Example_TaskEntry() +{ + UINT32 uwRet; + TSK_INIT_PARAM_S stTask1; + + /*ʼþ³õʼ»¯*/ + uwRet = Los_EventInit(&example_event); + if(uwRet != LOS_OK) + { + printf("init event failed .\n"); + return -1; + } + + /*´´½¨ÈÎÎñ*/ + memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; + stTask1.pcName = "EventTsk1"; + stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask1.usTaskPrio = 5; + uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); + if(uwRet != LOS_OK) + { + printf("task create failed .\n"); + return LOS_NOK; + } + + /*дg_TestTaskID01 µÈ´ýʼþ*/ + printf("Example_TaskEntry write event .\n"); + + uwRet = Los_EventWrite(&example_event, event_wait); + if(uwRet != LOS_OK) + { + printf("event write failed .\n"); + return LOS_NOK; + } + + /*Çå±ê־λ*/ + printf("EventMask:%d\n",example_event.uwEventID); + LOS_EventClear(&example_event, ~example_event.uwEventID); + printf("EventMask:%d\n",example_event.uwEventID); + + /*ɾ³ýÈÎÎñ*/ + uwRet = LOS_TaskDelete(g_TestTaskID01); + if(uwRet != LOS_OK) + { + printf("task delete failed .\n"); + return LOS_NOK; + } + + return LOS_OK; +} + diff --git a/doc/resource/sample_hwi.c b/doc/resource/sample_hwi.c new file mode 100644 index 000000000..af74c7a46 --- /dev/null +++ b/doc/resource/sample_hwi.c @@ -0,0 +1,17 @@ +#include "los_hwi.h" +#include "los_typedef.h" +#define HWI_NUM_INT50 50 +void uart_irqhandle(int irq,void *dev) +{ + printf("\n int the func uart_irqhandle \n"); +} +void hwi_test() +{ + int a = 1; + UINTPTR uvIntSave; + uvIntSave = LOS_IntLock(); + LOS_HwiCreate(HWI_NUM_INT50, 0,0,uart_irqhandle,NULL);//创建中断 + hal_interrupt_unmask(HWI_NUM_INT50); + LOS_IntRestore(uvIntSave); + hal_interrupt_mask(HWI_NUM_INT50); +} \ No newline at end of file diff --git a/doc/resource/sample_mem.c b/doc/resource/sample_mem.c new file mode 100644 index 000000000..fc85b9f76 --- /dev/null +++ b/doc/resource/sample_mem.c @@ -0,0 +1,82 @@ +#include "los_config.h" +#include "los_memory.h" +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define TEST_POOL_SIZE (20*1024*1024) +UINT8 m_aucTstPool[TEST_POOL_SIZE]; + +void * pool_ = &m_aucTstPool[0]; +#define POOL_BASE_ADDR &m_aucTstPool[0] +#define RANDOM(x) (rand()%x) + +#define USE_NEW_MEM +#ifdef USE_NEW_MEM +#define LOS_INIT_MEM LOS_DLnkInitMem +#define LOS_ALLOC_MEM LOS_DLnkAllocMem +#define LOS_REALLOC_MEM LOS_DLnkReAllocMem +#define LOS_FREE_MEM LOS_DLnkFreeMem + +#define LOS_GET_MEM_USED_SIZE LOS_DLnkGetTotalMemUsed +#define LOS_GET_MEM_USED_BLKS LOS_DLnkGetMemUsedBlks +#define LOS_GET_MEM_FREE_BLKS LOS_DLnkGetMemFreeBlks +#else +#define LOS_INIT_MEM LOS_SLnkInitMem +#define LOS_ALLOC_MEM LOS_SLnkAllocMem +#define LOS_REALLOC_MEM LOS_SLnkReAllocMem +#define LOS_FREE_MEM LOS_SLnkFreeMem + +#define LOS_GET_MEM_USED_SIZE osGetUsedMem +#define LOS_GET_MEM_USED_BLKS osGetUsedBlks +#define LOS_GET_MEM_FREE_BLKS osGetFreeBlks +#endif +UINT8 *m_aucSysMem_Tmp; +VOID los_memory_test() { + UINT32 *p_num = NULL; + UINT32 uwRet; + uwRet = LOS_MemInit(m_aucSysMem_Tmp, 32); + if (LOS_OK == uwRet) { + dprintf("ÄÚ´æ³Ø³õʼ»¯³É¹¦!\n"); + } + else { + dprintf("ÄÚ´æ³Ø³õʼ»¯Ê§°Ü!\n"); + return; + } + /*·ÖÅäÄÚ´æ*/ + p_num = (int*)LOS_MemAlloc(m_aucSysMem_Tmp, 4); + if (NULL == p_num) { + dprintf("ÄÚ´æ·ÖÅäʧ°Ü!\n"); + return; + } + dprintf("ÄÚ´æ·ÖÅä³É¹¦\n"); + /*¸³Öµ*/ + *p_num = 828; + dprintf("*p_num = %d\n", *p_num); + /*ÊÍ·ÅÄÚ´æ*/ + uwRet = LOS_MemFree(m_aucSysMem_Tmp, p_num); + if (LOS_OK == uwRet) { + dprintf("ÄÚ´æÊͷųɹ¦!\n"); + } + else { + dprintf("ÄÚ´æÊÍ·Åʧ°Ü!\n"); + } + return; +} + +void It_mem_performance(void) +{ + log_memory_test(); + return; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + diff --git a/doc/resource/sample_membox.c b/doc/resource/sample_membox.c new file mode 100644 index 000000000..848891b33 --- /dev/null +++ b/doc/resource/sample_membox.c @@ -0,0 +1,50 @@ +/************************************************************************* + > File Name: it_membox_performance.c + > Author: + > Mail: + > Created Time: Mon 27 Jul 2015 04:55:25 PM CST + ************************************************************************/ + +#include +#include "los_membox.h" + +VOID los_membox_test(void) { + UINT32 *p_num = NULL; + UINT32 uwBlkSize = 10, uwBoxSize = 100; + UINT32 uwRet; + UINT32 pBoxMem[1000]; + uwRet = LOS_MemboxInit( &pBoxMem[0], uwBoxSize, uwBlkSize); + if(uwRet != LOS_OK) + { + dprintf("ÄÚ´æ³Ø³õʼ»¯Ê§°Ü!\n"); + return; + } + else{ + dprintf("ÄÚ´æ³Ø³õʼ»¯³É¹¦!\n"); + } + + /*ÉêÇëÄÚ´æ¿é*/ + p_num = (int*)LOS_MemboxAlloc(pBoxMem); + if (NULL == p_num) { + dprintf("ÄÚ´æ·ÖÅäʧ°Ü!\n"); + return; + } + dprintf("ÄÚ´æ·ÖÅä³É¹¦\n"); + /*¸³Öµ*/ + *p_num = 828; + dprintf("*p_num = %d\n", *p_num); + /*Çå³ýÄÚ´æÄÚÈÝ*/ + LOS_MemboxClr(pBoxMem, p_num); + dprintf("Çå³ýÄÚ´æÄÚÈݳɹ¦\n *p_num = %d\n", *p_num); + /*ÊÍ·ÅÄÚ´æ*/ + uwRet = LOS_MemboxFree(pBoxMem, p_num); + if (LOS_OK == uwRet) { + dprintf("ÄÚ´æÊͷųɹ¦!\n"); + } + else{ + dprintf("ÄÚ´æÊÍ·Åʧ°Ü!\n"); + } + return; +} + + diff --git a/doc/resource/sample_mutex.c b/doc/resource/sample_mutex.c new file mode 100644 index 000000000..16343d6e8 --- /dev/null +++ b/doc/resource/sample_mutex.c @@ -0,0 +1,127 @@ +#include "los_mux.h" +#include "los_task.h" + + + +/*»¥³âËø¾ä±úid*/ +MUX_HANDLE_T g_Testmux01; +/*ÈÎÎñPID*/ +UINT32 g_TestTaskID01; +UINT32 g_TestTaskID02; + +VOID Example_MutexTask1() +{ + UINT32 uwRet; + + printf("task1 try to get mutex, wait 10 ticks.\n"); + /*ÉêÇ뻥³âËø*/ + uwRet=LOS_MuxPend(g_Testmux01, 10); + + if(uwRet == LOS_OK) + { + printf("task1 get mutex g_Testmux01.\n"); + /*ÊÍ·Å»¥³âËø*/ + LOS_MuxPost(g_Testmux01); + return; + } + else if(uwRet == LOS_ERRNO_MUX_TIMEOUT ) + { + printf("task1 timeout and try to get mutex, wait forever.\n"); + /*ÉêÇ뻥³âËø*/ + uwRet=LOS_MuxPend(g_Testmux01, LOS_WAIT_FOREVER); + if(uwRet == LOS_OK) + { + printf("task1 wait forever,get mutex g_Testmux01.\n"); + /*ÊÍ·Å»¥³âËø*/ + LOS_MuxPost(g_Testmux01); + return; + } + } + return; +} + +VOID Example_MutexTask2() +{ + UINT32 uwRet; + + printf("task2 try to get mutex, wait forever.\n"); + /*ÉêÇ뻥³âËø*/ + uwRet=LOS_MuxPend(g_Testmux01, LOS_WAIT_FOREVER); + + printf("task2 get mutex g_Testmux01 and suspend 100 ticks.\n"); + + /*ÈÎÎñÐÝÃß100 ticks*/ + LOS_TaskDelay(100); + + printf("task2 resumed and post the g_Testmux01\n"); + /*ÊÍ·Å»¥³âËø*/ + LOS_MuxPost(g_Testmux01); + return; + +} + +UINT32 Example_TaskEntry() +{ + UINT32 uwRet; + TSK_INIT_PARAM_S stTask1; + TSK_INIT_PARAM_S stTask2; + + /*´´½¨»¥³âËø*/ + LOS_MuxCreate(&g_Testmux01); + + /*ËøÈÎÎñµ÷¶È*/ + LOS_TaskLock(); + + /*´´½¨ÈÎÎñ1*/ + memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; + stTask1.pcName = "MutexTsk1"; + stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask1.usTaskPrio = 5; + uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); + if(uwRet != LOS_OK) + { + printf("task1 create failed .\n"); + return LOS_NOK; + } + + /*´´½¨ÈÎÎñ2*/ + memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S)); + stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; + stTask2.pcName = "MutexTsk2"; + stTask2.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask2.usTaskPrio = 4; + uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2); + if(uwRet != LOS_OK) + { + printf("task2 create failed .\n"); + return LOS_NOK; + } + + /*½âËøÈÎÎñµ÷¶È*/ + LOS_TaskUnlock(); + /*ÈÎÎñÐÝÃß300 ticks*/ + LOS_TaskDelay(300); + + /*ɾ³ý»¥³âËø*/ + LOS_MuxDelete(g_Testmux01); + + /*ɾ³ýÈÎÎñ1*/ + uwRet = LOS_TaskDelete(g_TestTaskID01); + if(uwRet != LOS_OK) + { + printf("task1 delete failed .\n"); + return LOS_NOK; + } + /*ɾ³ýÈÎÎñ2*/ + uwRet = LOS_TaskDelete(g_TestTaskID02); + if(uwRet != LOS_OK) + { + printf("task2 delete failed .\n"); + return LOS_NOK; + } + + return LOS_OK; +} + + diff --git a/doc/resource/sample_queue.c b/doc/resource/sample_queue.c new file mode 100644 index 000000000..2c8ba864f --- /dev/null +++ b/doc/resource/sample_queue.c @@ -0,0 +1,96 @@ +#include "los_base.h" +#include "los_task.h" +#include "los_swtmr.h" +#include "los_hwi.h" +#include "los_queue.h" +#include "los_event.h" +#include "los_typedef.h" + +static UINT32 g_uwQueue; +CHAR abuf[] = "test is message x"; + +void *send_Entry(void *arg) +{ + UINT32 i = 0,uwRet = 0; + UINT32 uwlen = sizeof(abuf); + + while (i <5) + { + abuf[uwlen -2] = '0' + i; + i++; + + uwRet = LOS_QueueWrite(g_uwQueue, abuf, uwlen, 0); + if(uwRet != LOS_OK) + { + dprintf("send message failure,error:%x\n",uwRet); + } + + LOS_TaskDelay(5); + } +} + +void *recv_Entry(void *arg) +{ + UINT32 uwReadbuf; + UINT32 uwRet = 0; + + while (1) + { + + + uwRet = LOS_QueueRead(g_uwQueue, &uwReadbuf, 50, 0); + if(uwRet != LOS_OK) + { + dprintf("recv message failure,error:%x\n",uwRet); + break; + } + + dprintf("recv message:%s\n", (char *)uwReadbuf); + LOS_TaskDelay(5); + } + + while (LOS_OK != LOS_QueueDelete(g_uwQueue)) + { + LOS_TaskDelay(1); + } + + dprintf("delete the queue success!\n"); +} + +int Example_create_task(void) +{ + UINT32 uwRet = 0; + UINT32 uwTask1, uwTask2; + TSK_INIT_PARAM_S stInitParam1; + + stInitParam1.pfnTaskEntry = send_Entry; + stInitParam1.usTaskPrio = 9; + stInitParam1.uwStackSize = 0x400; + stInitParam1.pcName = "sendQueue"; + stInitParam1.uwResved = LOS_TASK_STATUS_DETACHED ; + LOS_TaskLock(); + uwRet = LOS_TaskCreate(&uwTask1, &stInitParam1); + if(uwRet != LOS_OK) + { + dprintf("create task1 failed!,error:%x\n",uwRet); + return uwRet; + } + + stInitParam1.pfnTaskEntry = recv_Entry; + uwRet = LOS_TaskCreate(&uwTask2, &stInitParam1); + if(uwRet != LOS_OK) + { + dprintf("create task2 failed!,error:%x\n",uwRet); + return uwRet; + } + + uwRet = LOS_QueueCreate("queue", 5, &g_uwQueue, 0, 50); + + if(uwRet != LOS_OK) + { + dprintf("create queue failure!,error:%x\n",uwRet); + } + + dprintf("create the queue success!\n"); + LOS_TaskUnlock(); +} diff --git a/doc/resource/sample_sem.c b/doc/resource/sample_sem.c new file mode 100644 index 000000000..f92a471d1 --- /dev/null +++ b/doc/resource/sample_sem.c @@ -0,0 +1,129 @@ +#include "los_sem.h" + + +/*ÈÎÎñPID*/ +static UINT32 g_TestTaskID01,g_TestTaskID02; +/*²âÊÔÈÎÎñÓÅÏȼ¶*/ +#define TASK_PRIO_TEST 5 +/*ÐźÅÁ¿½á¹¹Ìåid*/ +static SEM_HANDLE_T g_usSemID; + + +VOID Example_SemTask1(void) +{ + UINT32 uwRet; + + printf("Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks.\n"); + /*¶¨Ê±×èÈûģʽÉêÇëÐźÅÁ¿£¬¶¨Ê±Ê±¼äΪ10ticks*/ + uwRet = LOS_SemPend(g_usSemID, 10); + + /*ÉêÇëµ½ÐźÅÁ¿*/ + if(LOS_OK == uwRet) + { + LOS_SemPost(g_usSemID); + return; + } + /*¶¨Ê±Ê±¼äµ½£¬Î´ÉêÇëµ½ÐźÅÁ¿*/ + if(LOS_ERRNO_SEM_TIMEOUT == uwRet) + { + printf("Example_SemTask1 timeout and try get sem g_usSemID wait forever.\n"); + /*ÓÀ¾Ã×èÈûģʽÉêÇëÐźÅÁ¿*/ + uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER); + printf("Example_SemTask1 wait_forever and get sem g_usSemID .\n"); + if(LOS_OK == uwRet) + { + LOS_SemPost(g_usSemID); + return; + } + } + return; + +} + VOID Example_SemTask2(void) +{ + UINT32 uwRet; + printf("Example_SemTask2 try get sem g_usSemID wait forever.\n"); + /*ÓÀ¾Ã×èÈûģʽÉêÇëÐźÅÁ¿*/ + uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER); + + if(LOS_OK == uwRet) + printf("Example_SemTask2 get sem g_usSemID and then delay 20ticks .\n"); + + /*ÈÎÎñÐÝÃß20 ticks*/ + LOS_TaskDelay(20); + + printf("Example_SemTask2 post sem g_usSemID .\n"); + /*ÊÍ·ÅÐźÅÁ¿*/ + LOS_SemPost(g_usSemID); + + return; + +} +UINT32 Example_TaskEntry() +{ + UINT32 uwRet; + TSK_INIT_PARAM_S stTask1; + TSK_INIT_PARAM_S stTask2; + + /*´´½¨ÐźÅÁ¿*/ + LOS_SemCreate(0,&g_usSemID); + + /*ËøÈÎÎñµ÷¶È*/ + LOS_TaskLock(); + + /*´´½¨ÈÎÎñ1*/ + memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S)); + stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1; + stTask1.pcName = "MutexTsk1"; + stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask1.usTaskPrio = TASK_PRIO_TEST; + uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1); + if(uwRet != LOS_OK) + { + printf("task1 create failed .\n"); + return LOS_NOK; + } + + /*´´½¨ÈÎÎñ2*/ + memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S)); + stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2; + stTask2.pcName = "MutexTsk2"; + stTask2.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + stTask2.usTaskPrio = (TASK_PRIO_TEST - 1); + uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2); + if(uwRet != LOS_OK) + { + printf("task2 create failed .\n"); + return LOS_NOK; + } + + /*½âËøÈÎÎñµ÷¶È*/ + LOS_TaskUnlock(); + + uwRet = LOS_SemPost(g_usSemID); + + /*ÈÎÎñÐÝÃß40 ticks*/ + LOS_TaskDelay(40); + + /*ɾ³ýÐźÅÁ¿*/ + LOS_SemDelete(g_usSemID); + + /*ɾ³ýÈÎÎñ1*/ + uwRet = LOS_TaskDelete(g_TestTaskID01); + if(uwRet != LOS_OK) + { + printf("task1 delete failed .\n"); + return LOS_NOK; + } + /*ɾ³ýÈÎÎñ2*/ + uwRet = LOS_TaskDelete(g_TestTaskID02); + if(uwRet != LOS_OK) + { + printf("task2 delete failed .\n"); + return LOS_NOK; + } + + return LOS_OK; +} + + diff --git a/doc/resource/sample_task_smp.c b/doc/resource/sample_task_smp.c new file mode 100644 index 000000000..a047b9905 --- /dev/null +++ b/doc/resource/sample_task_smp.c @@ -0,0 +1,110 @@ +UINT32 g_uwTskLoID; +UINT32 g_uwTskHiID; +#define TSK_PRIOR_HI 4 +#define TSK_PRIOR_LO 5 + +UINT32 Example_TaskHi(VOID) +{ + UINT32 uwRet; + UINT32 uwCurrentID; + TSK_INFO_S stTaskInfo; + + printf("[cpu%d] Enter TaskHi Handler.\r\n", osCurrCpuid()); + + /*ÑÓʱ2¸öTick£¬ÑÓʱºó¸ÃÈÎÎñ»á¹ÒÆð£¬Ö´ÐÐÊ£ÓàÈÎÎñÖÐ×î¸ßÓÅÏȼ¶µÄÈÎÎñ(g_uwTskLoIDÈÎÎñ)*/ + uwRet = LOS_TaskDelay(2); + if (uwRet != LOS_OK) + { + printf("Delay Task Failed.\r\n"); + return LOS_NOK; + } + + /*2¸öTickʱ¼äµ½Á˺󣬸ÃÈÎÎñ»Ö¸´£¬¼ÌÐøÖ´ÐÐ*/ + printf("TaskHi LOS_TaskDelay Done.\r\n"); + + /*¹ÒÆð×ÔÉíÈÎÎñ*/ + uwRet = LOS_TaskSuspend(g_uwTskHiID); + if (uwRet != LOS_OK) + { + printf("Suspend TaskHi Failed.\r\n"); + return LOS_NOK; + } + printf("TaskHi LOS_TaskResume Success.\r\n"); +} + +/*µÍÓÅÏȼ¶ÈÎÎñÈë¿Úº¯Êý*/ +UINT32 Example_TaskLo(VOID) +{ + UINT32 uwRet; + UINT32 uwCurrentID; + TSK_INFO_S stTaskInfo; + + printf("[cpu%d] Enter TaskLo Handler.\r\n", osCurrCpuid()); + + /*ÑÓʱ2¸öTick£¬ÑÓʱºó¸ÃÈÎÎñ»á¹ÒÆð£¬Ö´ÐÐÊ£ÓàÈÎÎñÖо͸ßÓÅÏȼ¶µÄÈÎÎñ(±³¾°ÈÎÎñ)*/ + uwRet = LOS_TaskDelay(2); + if (uwRet != LOS_OK) + { + printf("Delay TaskLo Failed.\r\n"); + return LOS_NOK; + } + + printf("TaskHi LOS_TaskDelete Success.\r\n"); +} + +/*ÈÎÎñ²âÊÔÈë¿Úº¯Êý£¬ÔÚÀïÃæ´´½¨ÓÅÏȼ¶²»Ò»ÑùµÄÁ½¸öÈÎÎñ*/ +UINT32 Example_TskCaseEntry(VOID) +{ + UINT32 uwRet; + TSK_INIT_PARAM_S stInitParam = {0}; + + /*ËøÈÎÎñµ÷¶È*/ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success on cpu%d!\r\n", osCurrCpuid()); + + stInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; + stInitParam.usTaskPrio = TSK_PRIOR_HI; + stInitParam.pcName = "HIGH_NAME"; + stInitParam.uwStackSize = 0x700; + stInitParam.uwResved = LOS_TASK_STATUS_DETACHED; + /*°ó¶¨¸ßÓÅÏȼ¶ÈÎÎñµ½CPU1ÔËÐÐ*/ + stInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(osCurrCpuid()); + /*´´½¨¸ßÓÅÏȼ¶ÈÎÎñ£¬ÓÉÓÚCPU1µÄµ÷¶ÈÆ÷±»Ëø£¬ÈÎÎñ´´½¨³É¹¦ºó²»»áÂíÉÏÖ´ÐÐ*/ + uwRet = LOS_TaskCreate(&g_uwTskHiID, &stInitParam); + if (uwRet != LOS_OK) + { + LOS_TaskUnlock(); + + printf("Example_TaskHi create Failed!\r\n"); + return LOS_NOK; + } + + printf("Example_TaskHi create Success!\r\n"); + + stInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; + stInitParam.usTaskPrio = TSK_PRIOR_LO; + stInitParam.pcName = "LOW_NAME"; + stInitParam.uwStackSize = 0x700; + stInitParam.uwResved = LOS_TASK_STATUS_DETACHED; + /*µÍÓÅÏȼ¶ÈÎÎñ²»ÉèÖÃCPUÇ׺ÍÐÔ*/ + stInitParam.usCpuAffiMask = 0; + /*´´½¨µÍÓÅÏȼ¶ÈÎÎñ£¬¾¡¹ÜËøÈÎÎñµ÷¶È£¬µ«ÊÇÓÉÓÚ¸ÃÈÎÎñûÓа󶨸ô¦ÀíÆ÷£¬ÈÎÎñ´´½¨³É¹¦ºó¿ÉÒÔÂíÉÏÔÚÆäËûCPUÖ´ÐÐ*/ + uwRet = LOS_TaskCreate(&g_uwTskLoID, &stInitParam); + if (uwRet != LOS_OK) + { + LOS_TaskUnlock(); + + printf("Example_TaskLo create Failed!\r\n"); + return LOS_NOK; + } + + printf("Example_TaskLo create Success!\r\n"); + + /*½âËøÈÎÎñµ÷¶È£¬´Ëʱ»á·¢ÉúÈÎÎñµ÷¶È£¬Ö´ÐоÍÐ÷ÁбíÖÐ×î¸ßÓÅÏȼ¶ÈÎÎñ*/ + LOS_TaskUnlock(); + + while(1){}; + + return LOS_OK; +} diff --git a/doc/resource/sample_time.c b/doc/resource/sample_time.c new file mode 100644 index 000000000..9764dcdf4 --- /dev/null +++ b/doc/resource/sample_time.c @@ -0,0 +1,38 @@ +#include "los_sys.h" +#include "los_task.h" + +VOID Example_TransformTime(VOID) +{ + UINT32 uwMs; + UINT32 uwTick; + uwTick = LOS_MS2Tick(10000);// 10000 msÊýת»»ÎªtickÊý + dprintf("uwTick = %d \n",uwTick); + uwMs = LOS_Tick2MS(100);// 100 tickÊýת»»ÎªmsÊý + dprintf("uwMs = %d \n",uwMs); +} + + +VOID Example_GetTime(VOID) +{ + UINT32 uwcyclePerTick; + UINT64 uwTickCount; + + uwcyclePerTick = LOS_CyclePerTickGet(); + if(0 != uwcyclePerTick) + { + dprintf("LOS_CyclePerTickGet = %d \n", uwcyclePerTick); + } + + uwTickCount = LOS_TickCountGet(); + if(0 != uwTickCount) + { + dprintf("LOS_TickCountGet = %d \n", (UINT32)uwTickCount); + } + LOS_TaskDelay(200); + uwTickCount = LOS_TickCountGet(); + if(0 != uwTickCount) + { + dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)uwTickCount); + } + +} diff --git a/include/fs/sys/errno.h b/include/fs/sys/errno.h index 425905768..dab1437b2 100644 --- a/include/fs/sys/errno.h +++ b/include/fs/sys/errno.h @@ -39,8 +39,8 @@ extern "C" { #endif -extern int *task_errno(void); -#define errno (*task_errno()) +extern volatile int *__os_errno(void); +#define errno (*__os_errno()) #define EPERM 1 /* Not owner */ #define ENOENT 2 /* No such file or directory */ diff --git a/kernel/Makefile b/kernel/Makefile deleted file mode 100644 index 29ad07ea2..000000000 --- a/kernel/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -objs-y += base -objs-y += extended diff --git a/kernel/base/Makefile b/kernel/base/Makefile index 35987cd73..c520cfa5b 100644 --- a/kernel/base/Makefile +++ b/kernel/base/Makefile @@ -1,5 +1,22 @@ -objs-y += core -objs-y += ipc -objs-y += om -objs-y += misc -objs-y += mem +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := $(notdir $(shell pwd)) + +LOCAL_SRCS := $(wildcard ipc/*.c) $(wildcard core/*.c) $(wildcard mem/membox/*.c) $(wildcard mem/common/*.c) \ + $(wildcard om/*.c)\ + $(wildcard misc/*.c)\ + $(wildcard mem/$(MEM_TYPE)/*.c) \ + $(wildcard mp/*.c) \ + $(wildcard sched/$(SCHED_TYPE)/*.c) + +ifeq ($(LOSCFG_MEM_RECORDINFO), y) +LOCAL_SRCS += $(wildcard mem/common/memrecord/*.c) +endif + +LOCAL_INCLUDE := \ + -I $(LITEOSTOPDIR)/kernel/base/include \ + -I $(LITEOSTOPDIR)/kernel/base/mem + +LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS) + +include $(MODULE) diff --git a/kernel/base/core/Makefile b/kernel/base/core/Makefile deleted file mode 100644 index e2a90327d..000000000 --- a/kernel/base/core/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -objs-y += los_timeslice.o -objs-y += los_tick.o -objs-y += los_swtmr.o -objs-y += los_task.o -objs-y += los_sys.o -objs-y += los_priqueue.o diff --git a/kernel/base/core/los_bitmap.c b/kernel/base/core/los_bitmap.c new file mode 100644 index 000000000..5c030b65c --- /dev/null +++ b/kernel/base/core/los_bitmap.c @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: BitMap + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_bitmap.h" +#include "los_toolchain.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_BITMAP_MASK 0x1FU + +VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos) +{ + if (bitmap == NULL) { + return; + } + + *bitmap |= 1U << (pos & OS_BITMAP_MASK); +} + +VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos) +{ + if (bitmap == NULL) { + return; + } + + *bitmap &= ~(1U << (pos & OS_BITMAP_MASK)); +} + +UINT16 LOS_HighBitGet(UINT32 bitmap) +{ + if (bitmap == 0) { + return LOS_INVALID_BIT_INDEX; + } + + return (OS_BITMAP_MASK - CLZ(bitmap)); +} + +UINT16 LOS_LowBitGet(UINT32 bitmap) +{ + if (bitmap == 0) { + return LOS_INVALID_BIT_INDEX; + } + + return CTZ(bitmap); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/core/los_priqueue.c b/kernel/base/core/los_priqueue.c deleted file mode 100644 index 07de43d52..000000000 --- a/kernel/base/core/los_priqueue.c +++ /dev/null @@ -1,124 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_priqueue.inc" -#include "los_base.ph" -#include "los_task.ph" -#include "los_memory.h" -#include "los_compiler.h" - - -LITE_OS_SEC_BSS LOS_DL_LIST *g_pstLosPriorityQueueList; -static LITE_OS_SEC_BSS UINT32 g_uwPriQueueBitmap = 0; - -#define PRIQUEUE_PRIOR0_BIT (UINT32)0x80000000 - -LITE_OS_SEC_TEXT VOID osPriqueueInit(VOID) -{ - UINT32 uwPri = 0; - UINT32 uwSize = 0; - - uwSize = OS_PRIORITY_QUEUE_PRIORITYNUM * sizeof(LOS_DL_LIST); - g_pstLosPriorityQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, uwSize); - if (NULL == g_pstLosPriorityQueueList) - { - return; - } - - for (uwPri = 0; uwPri < OS_PRIORITY_QUEUE_PRIORITYNUM; ++uwPri) - { - LOS_ListInit(&g_pstLosPriorityQueueList[uwPri]); - } -} - -LITE_OS_SEC_TEXT VOID osPriqueueEnqueue(LOS_DL_LIST *ptrPQItem, UINT32 uwPri) -{ - if (LOS_ListEmpty(&g_pstLosPriorityQueueList[uwPri])) - { - g_uwPriQueueBitmap |= (PRIQUEUE_PRIOR0_BIT >> uwPri); - } - - LOS_ListTailInsert(&g_pstLosPriorityQueueList[uwPri], ptrPQItem); -} - -LITE_OS_SEC_TEXT VOID osPriqueueDequeue(LOS_DL_LIST *ptrPQItem) -{ - LOS_TASK_CB *pstRunTsk; - LOS_ListDelete(ptrPQItem); - - pstRunTsk = LOS_DL_LIST_ENTRY(ptrPQItem, LOS_TASK_CB, stPendList); /*lint !e413*/ - if (LOS_ListEmpty(&g_pstLosPriorityQueueList[pstRunTsk->usPriority])) - { - g_uwPriQueueBitmap &= (~(PRIQUEUE_PRIOR0_BIT >> pstRunTsk->usPriority)); - } -} - -LITE_OS_SEC_TEXT LOS_DL_LIST *osPriqueueTop(VOID) -{ - UINT32 uwPri = 0; - - if (0 != g_uwPriQueueBitmap) - { - uwPri = CLZ(g_uwPriQueueBitmap); - return LOS_DL_LIST_FIRST(&g_pstLosPriorityQueueList[uwPri]); - } - - return (LOS_DL_LIST *)NULL; -} - -LITE_OS_SEC_TEXT UINT32 osPriqueueSize(UINT32 uwPri) -{ - UINT32 uwItemCnt = 0; - LOS_DL_LIST *pstCurPQNode = (LOS_DL_LIST *)NULL; - - LOS_DL_LIST_FOR_EACH(pstCurPQNode, &g_pstLosPriorityQueueList[uwPri]) - { - ++uwItemCnt; - } - - return uwItemCnt; -} - -LITE_OS_SEC_TEXT UINT32 osPriqueueTotalSize(VOID) -{ - UINT32 uwPri = 0; - UINT32 uwTotalSize = 0; - - for (uwPri = 0; uwPri < OS_PRIORITY_QUEUE_PRIORITYNUM; ++uwPri) - { - uwTotalSize += osPriqueueSize(uwPri); - } - - return uwTotalSize; -} diff --git a/kernel/base/core/los_sortlink.c b/kernel/base/core/los_sortlink.c new file mode 100644 index 000000000..99d1f5951 --- /dev/null +++ b/kernel/base/core/los_sortlink.c @@ -0,0 +1,242 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Sort Link + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_sortlink_pri.h" +#include "los_memory.h" +#include "los_exc.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define OS_INVALID_VALUE 0xFFFFFFFF + +LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader) +{ + LOS_DL_LIST *listObject = NULL; + UINT32 index; + + listObject = &sortLinkHeader->sortLink[0]; + + sortLinkHeader->cursor = 0; + for (index = 0; index < OS_TSK_SORTLINK_LEN; index++, listObject++) { + LOS_ListInit(listObject); + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +{ + SortLinkList *listSorted = NULL; + LOS_DL_LIST *listObject = NULL; + UINT32 sortIndex; + UINT32 rollNum; + UINT32 timeout; + + /* + * huge rollnum could cause carry to invalid high bit + * and eventually affect the calculation of sort index. + */ + if (sortList->idxRollNum > OS_TSK_MAX_ROLLNUM) { + SET_SORTLIST_VALUE(sortList, OS_TSK_MAX_ROLLNUM); + } + timeout = sortList->idxRollNum; + sortIndex = timeout & OS_TSK_SORTLINK_MASK; + rollNum = (timeout >> OS_TSK_SORTLINK_LOGLEN) + 1; + if (sortIndex == 0) { + rollNum--; + } + EVALUATE_L(sortList->idxRollNum, rollNum); + sortIndex = sortIndex + sortLinkHeader->cursor; + sortIndex = sortIndex & OS_TSK_SORTLINK_MASK; + EVALUATE_H(sortList->idxRollNum, sortIndex); + + listObject = (LOS_DL_LIST *)sortLinkHeader->sortLink + sortIndex; + if (listObject->pstNext == listObject) { + LOS_ListTailInsert(listObject, &sortList->sortLinkNode); + } else { + listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + do { + if (ROLLNUM(listSorted->idxRollNum) <= ROLLNUM(sortList->idxRollNum)) { + ROLLNUM_SUB(sortList->idxRollNum, listSorted->idxRollNum); + } else { + ROLLNUM_SUB(listSorted->idxRollNum, sortList->idxRollNum); + break; + } + + listSorted = LOS_DL_LIST_ENTRY(listSorted->sortLinkNode.pstNext, SortLinkList, sortLinkNode); + } while (&listSorted->sortLinkNode != listObject); + + LOS_ListTailInsert(&listSorted->sortLinkNode, &sortList->sortLinkNode); + } +} + +LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const LOS_DL_LIST *listNode) +{ + LOS_DL_LIST *tmp = listNode->pstPrev; + + /* recursive check until double link round to itself */ + while (tmp != listNode) { + if (tmp == listHead) { + goto FOUND; + } + tmp = tmp->pstPrev; + } + + /* delete invalid sortlink node */ + PRINT_ERR("the node is not on this sortlink!\n"); + OsBackTrace(); + +FOUND: + return; +} + +LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList) +{ + LOS_DL_LIST *listObject = NULL; + SortLinkList *nextSortList = NULL; + UINT32 sortIndex; + + sortIndex = SORT_INDEX(sortList->idxRollNum); + listObject = (LOS_DL_LIST *)sortLinkHeader->sortLink + sortIndex; + + /* check if pstSortList node is on the right sortlink */ + OsCheckSortLink(listObject, &sortList->sortLinkNode); + + if (listObject != sortList->sortLinkNode.pstNext) { + nextSortList = LOS_DL_LIST_ENTRY(sortList->sortLinkNode.pstNext, SortLinkList, sortLinkNode); + ROLLNUM_ADD(nextSortList->idxRollNum, sortList->idxRollNum); + } + LOS_ListDelete(&sortList->sortLinkNode); +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsCalcExpierTime(UINT32 rollNum, UINT32 sortIndex, UINT16 curSortIndex) +{ + UINT32 expireTime; + + if (sortIndex > curSortIndex) { + sortIndex = sortIndex - curSortIndex; + } else { + sortIndex = OS_TSK_SORTLINK_LEN - curSortIndex + sortIndex; + } + expireTime = ((rollNum - 1) << OS_TSK_SORTLINK_LOGLEN) + sortIndex; + return expireTime; +} + +LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader) +{ + UINT16 cursor; + UINT32 minSortIndex = OS_INVALID_VALUE; + UINT32 minRollNum = OS_TSK_LOW_BITS_MASK; + UINT32 expireTime = OS_INVALID_VALUE; + LOS_DL_LIST *listObject = NULL; + SortLinkList *listSorted = NULL; + UINT32 i; + + cursor = (sortLinkHeader->cursor + 1) & OS_TSK_SORTLINK_MASK; + + for (i = 0; i < OS_TSK_SORTLINK_LEN; i++) { + listObject = (LOS_DL_LIST *)sortLinkHeader->sortLink + ((cursor + i) & OS_TSK_SORTLINK_MASK); + if (!LOS_ListEmpty(listObject)) { + listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + if (minRollNum > ROLLNUM(listSorted->idxRollNum)) { + minRollNum = ROLLNUM(listSorted->idxRollNum); + minSortIndex = (cursor + i) & OS_TSK_SORTLINK_MASK; + } + } + } + + if (minRollNum != OS_TSK_LOW_BITS_MASK) { + expireTime = OsCalcExpierTime(minRollNum, minSortIndex, sortLinkHeader->cursor); + } + + return expireTime; +} + +LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader) +{ + SortLinkList *sortList = NULL; + LOS_DL_LIST *listObject = NULL; + UINT32 i; + UINT32 sortIndex; + UINT32 rollNum; + + if (sleepTicks == 0) { + return; + } + sortIndex = sleepTicks & OS_TSK_SORTLINK_MASK; + rollNum = (sleepTicks >> OS_TSK_SORTLINK_LOGLEN) + 1; + if (sortIndex == 0) { + rollNum--; + sortIndex = OS_TSK_SORTLINK_LEN; + } + + for (i = 0; i < OS_TSK_SORTLINK_LEN; i++) { + listObject = (LOS_DL_LIST *)sortLinkHeader->sortLink + ((sortLinkHeader->cursor + i) & OS_TSK_SORTLINK_MASK); + if (listObject->pstNext != listObject) { + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + ROLLNUM_SUB(sortList->idxRollNum, rollNum - 1); + if ((i > 0) && (i < sortIndex)) { + ROLLNUM_DEC(sortList->idxRollNum); + } + } + } + sortLinkHeader->cursor = (sortLinkHeader->cursor + sleepTicks - 1) % OS_TSK_SORTLINK_LEN; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader, + const SortLinkList *targetSortList) +{ + SortLinkList *listSorted = NULL; + LOS_DL_LIST *listObject = NULL; + UINT32 sortIndex = SORT_INDEX(targetSortList->idxRollNum); + UINT32 rollNum = ROLLNUM(targetSortList->idxRollNum); + + listObject = (LOS_DL_LIST *)sortLinkHeader->sortLink + sortIndex; + + listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + while (listSorted != targetSortList) { + rollNum += ROLLNUM(listSorted->idxRollNum); + listSorted = LOS_DL_LIST_ENTRY((listSorted->sortLinkNode).pstNext, SortLinkList, sortLinkNode); + } + return OsCalcExpierTime(rollNum, sortIndex, sortLinkHeader->cursor); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index 3a87ece7e..b6cc83b26 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* --------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Software Timer Manager * 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 @@ -22,26 +22,21 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "string.h" -#include "los_swtmr.inc" -#include "los_base.ph" -#include "los_membox.ph" -#include "los_memory.ph" -#include "los_queue.ph" -#include "los_task.ph" -#include "los_hwi.h" -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_exc.h" -#endif + * --------------------------------------------------------------------------- */ + +#include "los_swtmr_pri.h" +#include "los_sortlink_pri.h" +#include "los_queue_pri.h" +#include "los_task_pri.h" +#include "los_sys_pri.h" #ifdef __cplusplus #if __cplusplus @@ -50,861 +45,521 @@ extern "C" { #endif /* __cplusplus */ #if (LOSCFG_BASE_CORE_SWTMR == YES) +#define SWTMR_HANDLER_POOL_SIZE LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE) +#if (LOSCFG_BASE_CORE_SWTMR_DYN_MEM == YES) +LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */ +LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler */ +#else +#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0) +#error "swtmr maxnum cannot be zero" +#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */ -LITE_OS_SEC_BSS UINT32 m_uwSwTmrHandlerQueue; /*Software Timer timeout queue ID*/ -LITE_OS_SEC_BSS SWTMR_CTRL_S *m_pstSwtmrCBArray; /*first address in Timer memory space */ -LITE_OS_SEC_BSS SWTMR_CTRL_S *m_pstSwtmrFreeList; /*Free list of Softwaer Timer*/ -LITE_OS_SEC_BSS SWTMR_CTRL_S *m_pstSwtmrSortList; /*The software timer count list*/ - -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) -LITE_OS_SEC_BSS UINT32 m_uwSwTmrAlignID[LOSCFG_BASE_CORE_SWTMR_LIMIT] = {0}; /* store swtmr align */ -LITE_OS_SEC_DATA_INIT static UINT32 m_uwSwtimerRousesTime = 0; // suspend time -LITE_OS_SEC_DATA_INIT static SWTMR_CTRL_S *m_pstRouses = NULL; // first swtmr that can wake up -LITE_OS_SEC_DATA_INIT static SWTMR_CTRL_S *m_pstRousesPrev = NULL; +LITE_OS_SEC_BSS SWTMR_CTRL_S g_swtmrCBArray[LOSCFG_BASE_CORE_SWTMR_LIMIT]; /* First address in Timer memory space */ +LITE_OS_SEC_BSS UINT8 g_swtmrHandlerPool[SWTMR_HANDLER_POOL_SIZE]; /* Pool of Swtmr Handler */ #endif +LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */ -#define CHECK_SWTMRID(usSwTmrID, uvIntSave, usSwTmrCBID, pstSwtmr)\ -{\ - if (usSwTmrID >= OS_SWTMR_MAX_TIMERID)\ - {\ - return LOS_ERRNO_SWTMR_ID_INVALID;\ - }\ - uvIntSave = LOS_IntLock();\ - usSwTmrCBID = usSwTmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;\ - pstSwtmr = m_pstSwtmrCBArray + usSwTmrCBID;\ - if (pstSwtmr->usTimerID != usSwTmrID)\ - {\ - LOS_IntRestore(uvIntSave);\ - return LOS_ERRNO_SWTMR_ID_INVALID;\ - }\ -} - +/* spinlock for swtmr module */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin); +#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state)) +#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state)) +#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) +LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) { - SWTMR_HANDLER_ITEM_S stSwtmrHandle; - UINT32 uwReadSzie; - UINT32 uwRet; - UINT64 ullTick; - uwReadSzie = sizeof(SWTMR_HANDLER_ITEM_S); - for ( ; ; ) - { - uwRet = LOS_QueueReadCopy(m_uwSwTmrHandlerQueue, &stSwtmrHandle, &uwReadSzie, LOS_WAIT_FOREVER); - if (uwRet == LOS_OK && uwReadSzie == sizeof(SWTMR_HANDLER_ITEM_S)) - { - if (stSwtmrHandle.pfnHandler != NULL) - { - ullTick = LOS_TickCountGet(); - stSwtmrHandle.pfnHandler(stSwtmrHandle.uwArg); - ullTick = LOS_TickCountGet()- ullTick; - - if (ullTick >= 2) - { - PRINT_WARN("timer_handler(%p) cost too many ms(%d)\n", stSwtmrHandle.pfnHandler, (UINT32)(ullTick * 1000 /LOSCFG_BASE_CORE_TICK_PER_SECOND)); - } - + SwtmrHandlerItemPtr swtmrHandlePtr = NULL; + SwtmrHandlerItem swtmrHandle; + UINT32 ret, swtmrHandlerQueue; + UINT64 tick; + + swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue; + for (;;) { + ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER); + if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) { + swtmrHandle.handler = swtmrHandlePtr->handler; + swtmrHandle.arg = swtmrHandlePtr->arg; + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr); + 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(0x%p) cost too many ms(%llu)\n", + swtmrHandle.handler, + (UINT64)((tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND)); } } - }//end of for -} - -/***************************************************************************** -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 uwRet; - TSK_INIT_PARAM_S stSwTmrTask; - - (VOID)memset(&stSwTmrTask, 0, sizeof(TSK_INIT_PARAM_S)); - stSwTmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)osSwTmrTask; - stSwTmrTask.uwStackSize = 0x1000; - stSwTmrTask.pcName = "Swt_Task"; - stSwTmrTask.usTaskPrio = 0; - uwRet = LOS_TaskCreate(&g_uwSwtmrTaskID, &stSwTmrTask); - return uwRet; + } } -/***************************************************************************** -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) +LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) { - UINT32 uwSize; - UINT16 usIndex; - UINT32 uwRet; - SWTMR_CTRL_S *pstSwtmr; - SWTMR_CTRL_S *pstTemp; - - if (0 == LOSCFG_BASE_CORE_SWTMR_LIMIT) /*lint !e506*/ - { - return LOS_ERRNO_SWTMR_MAXSIZE_INVALID; - } - -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - (VOID)memset((VOID *)m_uwSwTmrAlignID, 0, LOSCFG_BASE_CORE_SWTMR_LIMIT * sizeof(UINT32)); - #endif + UINT32 ret, swtmrTaskID; + TSK_INIT_PARAM_S swtmrTask; + UINT32 cpuid = ArchCurrCpuid(); - m_pstSwtmrSortList = (SWTMR_CTRL_S *)NULL; - uwSize = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT; - pstSwtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, uwSize); - if (NULL == pstSwtmr) - { - return LOS_ERRNO_SWTMR_NO_MEMORY; - } - - (VOID)memset((VOID *)pstSwtmr, 0, uwSize); - m_pstSwtmrCBArray = pstSwtmr; - m_pstSwtmrFreeList = pstSwtmr; - pstSwtmr->usTimerID = 0; - pstTemp = pstSwtmr; - pstSwtmr++; - for (usIndex = 1; usIndex < LOSCFG_BASE_CORE_SWTMR_LIMIT; usIndex++, pstSwtmr++) - { - pstSwtmr->usTimerID = usIndex; - pstTemp->pstNext = pstSwtmr; - pstTemp = pstSwtmr; - } - - uwRet = LOS_QueueCreate((CHAR *)NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &m_uwSwTmrHandlerQueue, 0, sizeof(SWTMR_HANDLER_ITEM_S)); - if (uwRet != LOS_OK) - { - return LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; - } + (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_DEFAULT_STACK_SIZE; + swtmrTask.pcName = "Swt_Task"; + swtmrTask.usTaskPrio = 0; + swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED; - uwRet = osSwTmrTaskCreate(); - if (LOS_OK != uwRet) - { - return LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; + ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask); + if (ret == LOS_OK) { + g_percpu[cpuid].swtmrTaskID = swtmrTaskID; + OS_TCB_FROM_TID(swtmrTaskID)->taskFlags |= OS_TASK_FLAG_SYSTEM; } - return LOS_OK; + return ret; } -/***************************************************************************** -Function : osSwTmrStart -Description: Start Software Timer -Input : pstSwtmr ---------- Need to start Software Timer -Output : None -Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID osSwTmrStart(SWTMR_CTRL_S *pstSwtmr) +LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) { - SWTMR_CTRL_S *pstPrev = (SWTMR_CTRL_S *)NULL; - SWTMR_CTRL_S *pstCur = (SWTMR_CTRL_S *)NULL; - -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - UINT32 uwCurrSwtmrTimes, uwSwtmrTimes; - UINT32 uwMinInLarge = 0xFFFFFFFF, uwMaxInLitte = 0xFFFFFFFF; - UINT32 uwMinInLargeID = LOSCFG_BASE_CORE_SWTMR_LIMIT; - UINT32 uwMaxInLitteID = LOSCFG_BASE_CORE_SWTMR_LIMIT; - UINT16 usSwTmrCBID; - UINT16 usSwtmrIdIndex; - UINT32 uwCount = 0; -#endif - - pstSwtmr->uwCount = pstSwtmr->uwInterval; - -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - usSwTmrCBID = pstSwtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - if(CHECK_ALIGN_SWTMR_CAN_MULTI_ALIGN(m_uwSwTmrAlignID[usSwTmrCBID])) - { - SET_ALIGN_SWTMR_ALREADY_ALIGNED(m_uwSwTmrAlignID[usSwTmrCBID]); - uwCurrSwtmrTimes = GET_ALIGN_SWTMR_DIVISOR_TIMERS(m_uwSwTmrAlignID[usSwTmrCBID]); - for(usSwtmrIdIndex = 0; usSwtmrIdIndex < LOSCFG_BASE_CORE_SWTMR_LIMIT; usSwtmrIdIndex++) - { - uwSwtmrTimes = GET_ALIGN_SWTMR_DIVISOR_TIMERS(m_uwSwTmrAlignID[usSwtmrIdIndex]); - if(uwSwtmrTimes == 0 //swtmr not creat - || usSwtmrIdIndex == usSwTmrCBID //swtmr is pstSwtmr - || !CHECK_ALIGN_SWTMR_ALREADY_ALIGN(m_uwSwTmrAlignID[usSwtmrIdIndex])) //swtmr not start - { - continue; - } - if(uwSwtmrTimes >= uwCurrSwtmrTimes && uwSwtmrTimes % uwCurrSwtmrTimes == 0) - { - if(uwMinInLarge > uwSwtmrTimes / uwCurrSwtmrTimes) - { - uwMinInLarge = uwSwtmrTimes / uwCurrSwtmrTimes; - uwMinInLargeID = usSwtmrIdIndex; - } - } - else if(uwSwtmrTimes < uwCurrSwtmrTimes && uwCurrSwtmrTimes % uwSwtmrTimes == 0) - { - if(uwMaxInLitte > uwCurrSwtmrTimes / uwSwtmrTimes) - { - uwMaxInLitte = uwCurrSwtmrTimes / uwSwtmrTimes; - uwMaxInLitteID = usSwtmrIdIndex; - } - } + UINT32 ret, swtmrHandlePoolSize; + UINT16 index; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 cpuid = ArchCurrCpuid(); + if (cpuid == 0) { +#if (LOSCFG_BASE_CORE_SWTMR_DYN_MEM == YES) + /* system resident resource */ + swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT); + if (swtmr == NULL) { + return LOS_ERRNO_SWTMR_NO_MEMORY; } - if(uwMinInLargeID != LOSCFG_BASE_CORE_SWTMR_LIMIT) - { - pstCur = m_pstSwtmrSortList; - while (pstCur != NULL) - { - uwCount += pstCur->uwCount; - if (pstCur->usTimerID == ((SWTMR_CTRL_S *)(m_pstSwtmrCBArray + uwMinInLargeID))->usTimerID) - { - break; - } - pstCur = pstCur->pstNext; - } - if(pstCur != NULL) - { - pstSwtmr->uwCount = pstSwtmr->uwInterval - (pstCur->uwInterval - uwCount)% pstSwtmr->uwInterval; - } - } - else if(uwMaxInLitteID != LOSCFG_BASE_CORE_SWTMR_LIMIT) - { - pstSwtmr->uwCount = 0; - pstPrev = m_pstSwtmrCBArray + uwMaxInLitteID; - pstCur = pstPrev->pstNext; - goto Inset_list; - } - } - else if(CHECK_ALIGN_SWTMR_CAN_PERIODIC_ALIGN(m_uwSwTmrAlignID[usSwTmrCBID])) - { - SET_ALIGN_SWTMR_ALREADY_ALIGNED(m_uwSwTmrAlignID[usSwTmrCBID]); - pstCur = m_pstSwtmrSortList; - while (pstCur != NULL) - { - if (pstCur->uwInterval == pstSwtmr->uwInterval - && CHECK_ALIGN_SWTMR_ALREADY_ALIGN(m_uwSwTmrAlignID[pstCur->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT])) - { - break; - } - pstCur = pstCur->pstNext; - } - if(pstCur != NULL) - { - pstSwtmr->uwCount = 0; - pstPrev = pstCur; - pstCur = pstCur->pstNext; - goto Inset_list; - } - } + (VOID)memset_s(swtmr, sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT, + 0, sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT); + g_swtmrCBArray = swtmr; +#else + swtmr = g_swtmrCBArray; #endif - pstCur = m_pstSwtmrSortList; - while (pstCur != NULL) - { - if (pstCur->uwCount > pstSwtmr->uwCount) - { - break; + LOS_ListInit(&g_swtmrFreeList); + for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { + swtmr->usTimerID = index; + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); } - pstSwtmr->uwCount -= pstCur->uwCount; - pstPrev = pstCur; - pstCur = pstCur->pstNext; - } + swtmrHandlePoolSize = SWTMR_HANDLER_POOL_SIZE; -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) -Inset_list: +#if (LOSCFG_BASE_CORE_SWTMR_DYN_MEM == YES) + g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource */ + if (g_swtmrHandlerPool == NULL) { + return LOS_ERRNO_SWTMR_NO_MEMORY; + } #endif - pstSwtmr->pstNext = pstCur; - - if (pstCur != NULL) - { - pstCur->uwCount -= pstSwtmr->uwCount; + ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem)); + if (ret != LOS_OK) { + return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM; + } } - if (pstPrev == NULL) - { - m_pstSwtmrSortList = pstSwtmr; - } - else - { - pstPrev->pstNext = pstSwtmr; + ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &g_percpu[cpuid].swtmrHandlerQueue, 0, sizeof(CHAR *)); + if (ret != LOS_OK) { + return LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; } - pstSwtmr->ucState = OS_SWTMR_STATUS_TICKING; - - return; -} + ret = OsSwtmrTaskCreate(); + if (ret != LOS_OK) { + return LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; + } -/***************************************************************************** -Function : osSwTmrDelete -Description: Delete Software Timer -Input : pstSwtmr --- Need to delete Software Timer, When using, Ensure that it can't be NULL. -Output : None -Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT STATIC_INLINE VOID osSwtmrDelete(SWTMR_CTRL_S *pstSwtmr) -{ - /**insert to free list **/ - pstSwtmr->pstNext = m_pstSwtmrFreeList; - m_pstSwtmrFreeList = pstSwtmr; - pstSwtmr->ucState = OS_SWTMR_STATUS_UNUSED; + ret = OsSortLinkInit(&g_percpu[cpuid].swtmrSortLink); + if (ret != LOS_OK) { + return LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED; + } -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - m_uwSwTmrAlignID[pstSwtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT] = 0; -#endif + return LOS_OK; } -/***************************************************************************** -Function : osSwtmrStop -Description: Stop of Software Timer interface -Input : pstSwtmr -Output : None -Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID osSwtmrStop(SWTMR_CTRL_S *pstSwtmr) +/* + * Description: Start Software Timer + * Input : swtmr --- Need to start software timer + */ +LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) { - SWTMR_CTRL_S *pstPrev = (SWTMR_CTRL_S *)NULL; - SWTMR_CTRL_S *pstCur = (SWTMR_CTRL_S *)NULL; - - if(!m_pstSwtmrSortList) - return; - - pstCur = m_pstSwtmrSortList; - - while (pstCur != pstSwtmr) - { - pstPrev = pstCur; - pstCur = pstCur->pstNext; + if ((swtmr->ucOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) || + (swtmr->ucMode == LOS_SWTMR_MODE_OPP) || + (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) { + SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwExpiry); + } else { + SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwInterval); } - if (pstCur->pstNext != NULL) - { - pstCur->pstNext->uwCount += pstCur->uwCount; - } + OsAdd2SortLink(&OsPercpuGet()->swtmrSortLink, &swtmr->stSortList); - if (pstPrev == NULL) - { - m_pstSwtmrSortList = pstCur->pstNext; - } - else - { - pstPrev->pstNext = pstCur->pstNext; - } + swtmr->ucState = OS_SWTMR_STATUS_TICKING; - pstCur->pstNext = (SWTMR_CTRL_S *)NULL; - pstCur->ucState = OS_SWTMR_STATUS_CREATED; - -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - SET_ALIGN_SWTMR_ALREADY_NOT_ALIGNED(m_uwSwTmrAlignID[pstSwtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT]); -#endif + return; } -/***************************************************************************** -Function : osSwTmrTimeoutHandle -Description: Software Timer time out handler -Input : None -Output : None -Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT static VOID osSwTmrTimeoutHandle(VOID) +/* + * Description: Delete Software Timer + * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL. + */ +STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr) { - SWTMR_CTRL_S *pstSwtmr = m_pstSwtmrSortList; - SWTMR_HANDLER_ITEM_S stSwtmrHandler; - - while (pstSwtmr != NULL && pstSwtmr->uwCount == 0) - { - m_pstSwtmrSortList = pstSwtmr->pstNext; - stSwtmrHandler.pfnHandler = pstSwtmr->pfnHandler; - stSwtmrHandler.uwArg = pstSwtmr->uwArg; - (VOID)LOS_QueueWriteCopy(m_uwSwTmrHandlerQueue, &stSwtmrHandler, sizeof(SWTMR_HANDLER_ITEM_S), LOS_NO_WAIT); - if (pstSwtmr->ucMode == LOS_SWTMR_MODE_ONCE) - { - osSwtmrDelete(pstSwtmr); - if (pstSwtmr->usTimerID < OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT) - pstSwtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; - else - pstSwtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; - } - else if ( pstSwtmr->ucMode == LOS_SWTMR_MODE_PERIOD) - { - osSwTmrStart(pstSwtmr); - } - else if (pstSwtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) - { - pstSwtmr->ucState = OS_SWTMR_STATUS_CREATED; - } - - pstSwtmr = m_pstSwtmrSortList; - } + /* insert to free list */ + LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); + swtmr->ucState = OS_SWTMR_STATUS_UNUSED; } -/***************************************************************************** -Function : osSwtmrScan -Description: Tick interrupt interface module of Software Timer -Input : None -Output : None -Return : LOS_OK on success or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 osSwtmrScan(VOID) +/* + * Description: Tick interrupt interface module of software timer + * Return : LOS_OK on success or error code on failure + */ +LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID) { - if (m_pstSwtmrSortList != NULL) - { - if (--(m_pstSwtmrSortList->uwCount) == 0) - { - osSwTmrTimeoutHandle(); - } + SortLinkList *sortList = NULL; + SWTMR_CTRL_S *swtmr = NULL; + SwtmrHandlerItemPtr swtmrHandler = NULL; + LOS_DL_LIST *listObject = NULL; + SortLinkAttribute* swtmrSortLink = &OsPercpuGet()->swtmrSortLink; + + swtmrSortLink->cursor = (swtmrSortLink->cursor + 1) & OS_TSK_SORTLINK_MASK; + listObject = swtmrSortLink->sortLink + swtmrSortLink->cursor; + + /* + * it needs to be carefully coped with, since the swtmr is in specific sortlink + * while other cores still has the chance to process it, like stop the timer. + */ + LOS_SpinLock(&g_swtmrSpin); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&g_swtmrSpin); + return; } - return LOS_OK; -} + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + ROLLNUM_DEC(sortList->idxRollNum); -/***************************************************************************** -Function : osSwTmrGetNextTimeout -Description: Get next timeout -Input : None -Output : None -Return : Count of the Timer list -*****************************************************************************/ -#if (LOSCFG_KERNEL_TICKLESS == YES) -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) -LITE_OS_SEC_TEXT UINT32 osSwTmrGetNextTimeout(VOID) -{ - SWTMR_CTRL_S *pstCur = NULL; - UINT32 uwTmpTime = 0, uwSleepTime = 0; + while (ROLLNUM(sortList->idxRollNum) == 0) { + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + LOS_ListDelete(&sortList->sortLinkNode); + swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); - pstCur = m_pstSwtmrSortList; + swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool); + if (swtmrHandler != NULL) { + swtmrHandler->handler = swtmr->pfnHandler; + swtmrHandler->arg = swtmr->uwArg; - //find first timer can wakeup the system - while (pstCur != NULL) - { - if(OS_SWTMR_ROUSES_ALLOW == pstCur->ucRouses) - { - m_pstRouses = pstCur; - break; + if (LOS_QueueWrite(OsPercpuGet()->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) { + (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler); + } } - uwTmpTime += pstCur->uwCount; - m_pstRousesPrev = pstCur; - pstCur = pstCur->pstNext; - } - - if(pstCur != NULL) - { - uwSleepTime = pstCur->uwCount + uwTmpTime; - m_uwSwtimerRousesTime = uwSleepTime; - } - else - { - return 0xFFFFFFFF; - } - - return uwSleepTime; -} -#else -LITE_OS_SEC_TEXT UINT32 osSwTmrGetNextTimeout(VOID) -{ - if (m_pstSwtmrSortList == NULL) - { - return 0xFFFFFFFF; - } - return m_pstSwtmrSortList->uwCount; -} -#endif -#endif + if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) { + OsSwtmrDelete(swtmr); -/***************************************************************************** -Function : osSwtimerInsert -Description: Insert a list of swtmr -Input : None -Output : None -Return : None -*****************************************************************************/ -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) -LITE_OS_SEC_TEXT VOID osSwtimerInsert(SWTMR_CTRL_S **pstHead, SWTMR_CTRL_S *pstSwtmr) -{ - SWTMR_CTRL_S *pstPrev = NULL; - SWTMR_CTRL_S *pstNextTmp = pstSwtmr->pstNext; - SWTMR_CTRL_S *pstCur = *pstHead; - - while(pstSwtmr!=NULL) - { - while (pstCur != NULL) - { - if (pstCur->uwCount > pstSwtmr->uwCount) - { - break; + 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; } - - pstSwtmr->uwCount -= pstCur->uwCount; - pstPrev = pstCur; - pstCur = pstCur->pstNext; + } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) { + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + } else { + swtmr->ucOverrun++; + OsSwtmrStart(swtmr); } - pstSwtmr->pstNext = pstCur; - if (pstCur != NULL) - { - pstCur->uwCount -= pstSwtmr->uwCount; - } - if (pstPrev == NULL) - { - *pstHead = pstSwtmr; - } - else - { - pstPrev->pstNext = pstSwtmr; + if (LOS_ListEmpty(listObject)) { + break; } - pstPrev = pstSwtmr; - pstSwtmr = pstNextTmp; - pstNextTmp = pstNextTmp->pstNext; + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); } - return; + LOS_SpinUnlock(&g_swtmrSpin); } -#endif -/***************************************************************************** -Function : osSwTmrAdjust -Description: Adjust Software Timer list -Input : sleep_time -Output : None -Return : None -*****************************************************************************/ -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) -LITE_OS_SEC_TEXT VOID osSwTmrAdjust(UINT32 uwSleepTime) +/* + * Description: Get next timeout + * Return : Count of the Timer list + */ +LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID) { - SWTMR_CTRL_S *pstCur = NULL; - - if(m_pstRouses == NULL) - return; + return OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink); +} - if (uwSleepTime > m_uwSwtimerRousesTime) - { - uwSleepTime = m_uwSwtimerRousesTime; - } +/* + * Description: Stop of Software Timer interface + * Input : swtmr --- the software timer contrl handler + */ +LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr) +{ + SortLinkAttribute *sortLinkHeader = NULL; + sortLinkHeader = &g_percpu[0].swtmrSortLink; + OsDeleteSortLink(sortLinkHeader, &swtmr->stSortList); - if(uwSleepTime <= m_pstRouses->uwCount) - { - m_pstRouses->uwCount -= uwSleepTime; - } - else - { - m_pstRouses->uwCount = m_uwSwtimerRousesTime - uwSleepTime; - - if(m_pstRousesPrev!=NULL) - { - m_pstRousesPrev->pstNext = NULL; - pstCur = m_pstSwtmrSortList; - osSwtimerInsert(&m_pstRouses,pstCur); - m_pstSwtmrSortList = m_pstRouses; - } - } - if (m_pstSwtmrSortList->uwCount == 0) - { - osSwTmrTimeoutHandle(); - } + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + swtmr->ucOverrun = 0; +} - m_pstRouses = NULL; - m_pstRousesPrev = NULL; +/* + * Description: Get next software timer expiretime + * Input : swtmr --- the software timer contrl handler + */ +LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr) +{ + SortLinkAttribute *sortLinkHeader = NULL; + sortLinkHeader = &g_percpu[0].swtmrSortLink; + return OsSortLinkGetTargetExpireTime(sortLinkHeader, &swtmr->stSortList); } -#else -LITE_OS_SEC_TEXT VOID osSwTmrAdjust(UINT32 uwSleepTime) + +LITE_OS_SEC_TEXT VOID OsSwtmrAdjust(UINT32 sleepTime) { - if (m_pstSwtmrSortList == NULL) - { - return ; - } + UINT32 nextTimeout; + SortLinkAttribute *swtmrSortLink = &OsPercpuGet()->swtmrSortLink; - if (uwSleepTime > m_pstSwtmrSortList->uwCount) - { - uwSleepTime = m_pstSwtmrSortList->uwCount; + nextTimeout = OsSortLinkGetNextExpireTime(swtmrSortLink); + if (sleepTime > nextTimeout) { + sleepTime = nextTimeout; } - m_pstSwtmrSortList->uwCount -= uwSleepTime; + OsSortLinkUpdateExpireTime(sleepTime, swtmrSortLink); + OsSwtmrScan(); +} - if (m_pstSwtmrSortList->uwCount == 0) - { - osSwTmrTimeoutHandle(); +LITE_OS_SEC_TEXT VOID LOS_SwtmrAdjust(UINT32 sleepTime) +{ + UINT32 intSave; + if (sleepTime == 0) { + return; } + intSave = LOS_IntLock(); + OsSwtmrAdjust(sleepTime); + LOS_IntRestore(intSave); } -#endif -/***************************************************************************** -Function : osSwtmrTimeGet -Description:Obtain a software timer ticks. -Input : pstSwtmr -Output : None -Return : None -Other : None -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 osSwtmrTimeGet(SWTMR_CTRL_S *pstSwtmr) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrGetNextTimeout(VOID) { - SWTMR_CTRL_S *pstCur = (SWTMR_CTRL_S *)NULL; - UINT32 uwTick = 0; - - pstCur = m_pstSwtmrSortList; - while (1) - { - uwTick += pstCur->uwCount; - if (pstCur == pstSwtmr) - { - break; - } + UINT32 count; + UINT32 intSave; - pstCur = pstCur->pstNext; - } + intSave = LOS_IntLock(); + count = OsSwtmrGetNextTimeout(); + LOS_IntRestore(intSave); - return uwTick; + return count; } -/***************************************************************************** -Function : LOS_SwtmrCreate -Description: Create software timer -Input : uwInterval - usMode - pfnHandler - uwArg -Output : pusSwTmrID -Return : LOS_OK on success or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 uwInterval, UINT8 ucMode, SWTMR_PROC_FUNC pfnHandler, UINT16 *pusSwTmrID, UINT32 uwArg -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - , UINT8 ucRouses, UINT8 ucSensitive -#endif - ) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, + UINT8 mode, + SWTMR_PROC_FUNC handler, + UINT16 *swtmrID, + UINTPTR arg) { - SWTMR_CTRL_S *pstSwtmr; - UINTPTR uvIntSave; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + SortLinkList *sortList = NULL; - if (0 == uwInterval) - { + if (interval == 0) { return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED; } - if ((LOS_SWTMR_MODE_ONCE != ucMode) - && (LOS_SWTMR_MODE_PERIOD != ucMode) - && (LOS_SWTMR_MODE_NO_SELFDELETE != ucMode)) - { + if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) && + (mode != LOS_SWTMR_MODE_NO_SELFDELETE)) { return LOS_ERRNO_SWTMR_MODE_INVALID; } - if (NULL == pfnHandler) - { + if (handler == NULL) { return LOS_ERRNO_SWTMR_PTR_NULL; } - if (NULL == pusSwTmrID) - { + if (swtmrID == NULL) { return LOS_ERRNO_SWTMR_RET_PTR_NULL; } -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - if((OS_SWTMR_ROUSES_IGNORE != ucRouses)&& (OS_SWTMR_ROUSES_ALLOW != ucRouses)) - { - return OS_ERRNO_SWTMR_ROUSES_INVALID; - } - - if((OS_SWTMR_ALIGN_INSENSITIVE != ucSensitive)&& (OS_SWTMR_ALIGN_SENSITIVE != ucSensitive)) - { - return OS_ERRNO_SWTMR_ALIGN_INVALID; - } -#endif - - uvIntSave = LOS_IntLock(); - if (NULL == m_pstSwtmrFreeList) - { - LOS_IntRestore(uvIntSave); + SWTMR_LOCK(intSave); + if (LOS_ListEmpty(&g_swtmrFreeList)) { + SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_MAXSIZE; } - pstSwtmr = m_pstSwtmrFreeList; - m_pstSwtmrFreeList = pstSwtmr->pstNext; - LOS_IntRestore(uvIntSave); - pstSwtmr->pfnHandler = pfnHandler; - pstSwtmr->ucMode = ucMode; - pstSwtmr->uwInterval = uwInterval; - pstSwtmr->pstNext = (SWTMR_CTRL_S *)NULL; - pstSwtmr->uwCount = 0; - pstSwtmr->uwArg = uwArg; -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - pstSwtmr->ucRouses = ucRouses; - pstSwtmr->ucSensitive = ucSensitive; -#endif - pstSwtmr->ucState = OS_SWTMR_STATUS_CREATED; - *pusSwTmrID = pstSwtmr->usTimerID; + sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode); + swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList)); + SWTMR_UNLOCK(intSave); + + swtmr->pfnHandler = handler; + swtmr->ucMode = mode; + swtmr->ucOverrun = 0; + swtmr->uwInterval = interval; + swtmr->uwExpiry = interval; + swtmr->uwArg = arg; + swtmr->ucState = OS_SWTMR_STATUS_CREATED; + SET_SORTLIST_VALUE(&(swtmr->stSortList), 0); + *swtmrID = swtmr->usTimerID; return LOS_OK; } -/***************************************************************************** -Function : LOS_SwtmrStart -Description: Start software timer -Input : usSwTmrID ------- Software timer ID -Output : None -Return : LOS_OK on success or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 usSwTmrID) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) { - SWTMR_CTRL_S *pstSwtmr; - UINTPTR uvIntSave; -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - UINT32 uwTimes; -#endif - UINT32 uwRet = LOS_OK; - UINT16 usSwTmrCBID; - - CHECK_SWTMRID(usSwTmrID, uvIntSave, usSwTmrCBID, pstSwtmr); -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - if( OS_SWTMR_ALIGN_INSENSITIVE == pstSwtmr->ucSensitive && LOS_SWTMR_MODE_PERIOD == pstSwtmr->ucMode ) - { - SET_ALIGN_SWTMR_CAN_ALIGNED(m_uwSwTmrAlignID[pstSwtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT]); - if(pstSwtmr->uwInterval % LOS_COMMON_DIVISOR == 0) - { - SET_ALIGN_SWTMR_CAN_MULTIPLE(m_uwSwTmrAlignID[pstSwtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT]); - uwTimes = pstSwtmr->uwInterval / (LOS_COMMON_DIVISOR); - SET_ALIGN_SWTMR_DIVISOR_TIMERS(m_uwSwTmrAlignID[pstSwtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT], uwTimes); - } + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; } - #endif - - switch (pstSwtmr->ucState) - { - case OS_SWTMR_STATUS_UNUSED: - uwRet = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - case OS_SWTMR_STATUS_TICKING: - osSwtmrStop(pstSwtmr); - case OS_SWTMR_STATUS_CREATED: /*lint !e616*/ - osSwTmrStart(pstSwtmr); - break; - default: - uwRet = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; + + SWTMR_LOCK(intSave); + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; } - LOS_IntRestore(uvIntSave); - return uwRet; + switch (swtmr->ucState) { + case OS_SWTMR_STATUS_UNUSED: + ret = LOS_ERRNO_SWTMR_NOT_CREATED; + break; + /* + * If the status of swtmr is timing, it should stop the swtmr first, + * then start the swtmr again. + */ + 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; + } + + SWTMR_UNLOCK(intSave); + return ret; } -/***************************************************************************** -Function : LOS_SwtmrStop -Description: Stop software timer -Input : usSwTmrID ------- Software timer ID -Output : None -Return : LOS_OK on success or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 usSwTmrID) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) { - SWTMR_CTRL_S *pstSwtmr; - UINTPTR uvIntSave; - UINT16 usSwTmrCBID; - UINT32 uwRet = LOS_OK; - - CHECK_SWTMRID(usSwTmrID, uvIntSave, usSwTmrCBID, pstSwtmr); - switch (pstSwtmr->ucState) - { - case OS_SWTMR_STATUS_UNUSED: - uwRet = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - case OS_SWTMR_STATUS_CREATED: - uwRet = LOS_ERRNO_SWTMR_NOT_STARTED; - break; - case OS_SWTMR_STATUS_TICKING: - osSwtmrStop(pstSwtmr); - break; - default: - uwRet = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; + } + + SWTMR_LOCK(intSave); + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); + return LOS_ERRNO_SWTMR_ID_INVALID; } - LOS_IntRestore(uvIntSave); - return uwRet; + 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; + } + + SWTMR_UNLOCK(intSave); + return ret; } -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 usSwTmrID, UINT32 *uwTick) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) { - SWTMR_CTRL_S *pstSwtmr; - UINTPTR uvIntSave; - UINT32 uwRet = LOS_OK; - UINT16 usSwTmrCBID; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; - if (usSwTmrID >= OS_SWTMR_MAX_TIMERID) - { + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { return LOS_ERRNO_SWTMR_ID_INVALID; } - if (uwTick == NULL) - { + if (tick == NULL) { return LOS_ERRNO_SWTMR_TICK_PTR_NULL; } - uvIntSave = LOS_IntLock(); - usSwTmrCBID = usSwTmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; - pstSwtmr = m_pstSwtmrCBArray + usSwTmrCBID; + SWTMR_LOCK(intSave); + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; - if (pstSwtmr->usTimerID != usSwTmrID) - { - LOS_IntRestore(uvIntSave); + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } - switch (pstSwtmr->ucState) - { - case OS_SWTMR_STATUS_UNUSED: - uwRet = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - case OS_SWTMR_STATUS_CREATED: - uwRet = LOS_ERRNO_SWTMR_NOT_STARTED; - break; - case OS_SWTMR_STATUS_TICKING: - *uwTick = osSwtmrTimeGet(pstSwtmr); - break; - default: - uwRet = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; + 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(uvIntSave); - return uwRet; + SWTMR_UNLOCK(intSave); + return ret; } -/***************************************************************************** -Function : LOS_SwtmrDelete -Description: Delete software timer -Input : usSwTmrID ------- Software timer ID -Output : None -Return : LOS_OK on success or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 usSwTmrID) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) { - SWTMR_CTRL_S *pstSwtmr; - UINTPTR uvIntSave; - UINT32 uwRet = LOS_OK; - UINT16 usSwTmrCBID; - - CHECK_SWTMRID(usSwTmrID, uvIntSave, usSwTmrCBID, pstSwtmr); - switch (pstSwtmr->ucState) - { - case OS_SWTMR_STATUS_UNUSED: - uwRet = LOS_ERRNO_SWTMR_NOT_CREATED; - break; - case OS_SWTMR_STATUS_TICKING: - osSwtmrStop(pstSwtmr); - case OS_SWTMR_STATUS_CREATED: /*lint !e616*/ - osSwtmrDelete(pstSwtmr); - break; - default: - uwRet = LOS_ERRNO_SWTMR_STATUS_INVALID; - break; + SWTMR_CTRL_S *swtmr = NULL; + UINT32 intSave; + UINT32 ret = LOS_OK; + UINT16 swtmrCBID; + + if (swtmrID >= OS_SWTMR_MAX_TIMERID) { + return LOS_ERRNO_SWTMR_ID_INVALID; } - LOS_IntRestore(uvIntSave); - return uwRet; -} + SWTMR_LOCK(intSave); + swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; + swtmr = g_swtmrCBArray + swtmrCBID; + + if (swtmr->usTimerID != swtmrID) { + SWTMR_UNLOCK(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; + } -#endif /*(LOSCFG_BASE_CORE_SWTMR == YES)*/ + SWTMR_UNLOCK(intSave); + return ret; +} +#endif /* (LOSCFG_BASE_CORE_SWTMR == YES) */ #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/core/los_swtmr.inc b/kernel/base/core/los_swtmr.inc deleted file mode 100644 index d7f58e700..000000000 --- a/kernel/base/core/los_swtmr.inc +++ /dev/null @@ -1,194 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_SWTMR_INC -#define _LOS_SWTMR_INC - -#include "los_swtmr.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -extern SWTMR_CTRL_S *m_pstSwtmrFreeList; - -/** - * @ingroup los_swtmr - * Handle function of software timer task . - * - * @par Description: - *
      - *
    • This API is used to handle the overtime software timer.
    • - *
    - * @attention - *
      - *
    • None.
    • - *
    - * - * @param None. - * - * @retval None. - * @par Dependency: - *
    • los_swtmr.inc: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osSwTmrTask(VOID); - -/** - * @ingroup los_swtmr - * Create the task of software timer. - * - * @par Description: - *
      - *
    • This API is used to create the task of software timer.
    • - *
    - * @attention - *
      - *
    • None.
    • - *
    - * - * @param None. - * - * @retval UINT32 Create result. - * @par Dependency: - *
    • los_swtmr.inc: the header file that contains the API declaration.
    - * @see osSwtmrDelete - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osSwTmrTaskCreate(VOID); - -/** - * @ingroup los_swtmr - * Start a software timer. - * - * @par Description: - *
      - *
    • This API is used to start a software timer.
    • - *
    - * @attention - *
      - *
    • None.
    • - *
    - * - * @param pstSwtmr [IN] Type #SWTMR_CTRL_S * pointer to swtmr control block structure. - * - * @retval None. - * @par Dependency: - *
    • los_swtmr.inc: the header file that contains the API declaration.
    - * @see osSwtmrStop - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osSwTmrStart(SWTMR_CTRL_S *pstSwtmr); - -/** - * @ingroup los_swtmr - * Stop a software timer. - * - * @par Description: - *
      - *
    • This API is used to stop a software timer.
    • - *
    - * @attention - *
      - *
    • None.
    • - *
    - * - * @param pstSwtmr [IN] Type #SWTMR_CTRL_S * pointer to swtmr control block structure. - * - * @retval None. - * @par Dependency: - *
    • los_swtmr.inc: the header file that contains the API declaration.
    - * @see osSwTmrStart - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osSwtmrStop(SWTMR_CTRL_S *pstSwtmr); - -/** - * @ingroup los_swtmr - * Insert a software timer to timer list. - * - * @par Description: - *
      - *
    • This API is used to insert a software timer to timer list.
    • - *
    - * @attention - *
      - *
    • None.
    • - *
    - * - * @param pstHead [OUT] Type #SWTMR_CTRL_S * pointer to swtmr control block structure head. - * @param pstSwtmr [IN] Type #SWTMR_CTRL_S * pointer to swtmr control block structure. - * - * @retval None. - * @par Dependency: - *
    • los_swtmr.inc: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osSwtimerInsert(SWTMR_CTRL_S **pstHead, SWTMR_CTRL_S *pstSwtmr); - -/** - * @ingroup los_swtmr - * 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.
    • - *
    - * @attention - *
      - *
    • None.
    • - *
    - * - * @param pstSwtmr [IN] Type #SWTMR_CTRL_S * pointer to swtmr control block structure. - * - * @retval UINT32 Ticks. - * @par Dependency: - *
    • los_swtmr.inc: the header file that contains the API declaration.
    - * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osSwtmrTimeGet(SWTMR_CTRL_S *pstSwtmr); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_SWTMR_INC */ diff --git a/kernel/base/core/los_sys.c b/kernel/base/core/los_sys.c index 88ba3178e..641ab9399 100644 --- a/kernel/base/core/los_sys.c +++ b/kernel/base/core/los_sys.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System time * 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 @@ -22,18 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_sys.inc" -#include "los_tick.ph" +#include "los_sys_pri.h" +#include "los_tick_pri.h" #ifdef __cplusplus #if __cplusplus @@ -41,115 +41,41 @@ 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) +#define OS_MAX_VALUE 0xFFFFFFFF + +LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID) { - return g_ullTickCount; + UINT32 intSave; + UINT64 tick; + + /* + * use core0's tick as system's timeline, + * the tick needs to be atomic. + */ + TICK_LOCK(intSave); + tick = g_tickCount[0]; + TICK_UNLOCK(intSave); + + return tick; } -/***************************************************************************** -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) { - /*lint -e40*/ - return OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND;/*lint !e160*/ - /*lint +e40*/ + return g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; } -/***************************************************************************** -Function : LOS_MS2Tick -Description: milliseconds convert to Tick -Input : milliseconds -Output : None -Return : Tick -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 uwMillisec) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec) { - if (0xFFFFFFFF == uwMillisec) - { - return 0xFFFFFFFF; + if (millisec == OS_MAX_VALUE) { + return OS_MAX_VALUE; } - return ((UINT64)uwMillisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND; + return (UINT32)(((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND); } -/***************************************************************************** -Function : LOS_Tick2MS -Description: Tick convert to milliseconds -Input : TICK -Output : None -Return : milliseconds -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 uwTick) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick) { - return ((UINT64)uwTick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND; -} - -/***************************************************************************** -Function : osCpuTick2MS -Description: cycle convert to milliseconds -Input : uwInterval ---------- cycle -Output : puwUsHi ---------- High 32 milliseconds - puwUsLo ---------- Low 32 milliseconds -Return : LOS_OK on success ,or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 osCpuTick2MS(CPU_TICK *pstCpuTick, UINT32 *puwMsHi, UINT32 *puwMsLo) -{ - UINT64 ullCpuTick; - double dTemp; - - if ( (NULL == pstCpuTick) || (NULL == puwMsHi) || (NULL == puwMsLo) ) - { - return LOS_ERRNO_SYS_PTR_NULL; - } - - ullCpuTick = ((UINT64)pstCpuTick->uwCntHi << OS_SYS_MV_32_BIT) | pstCpuTick->uwCntLo; - dTemp = ullCpuTick / (((double)OS_SYS_CLOCK) / OS_SYS_MS_PER_SECOND); /*lint !e160 !e653 !e40*/ - ullCpuTick = (UINT64)dTemp; - - *puwMsLo = (UINT32)ullCpuTick; - *puwMsHi = (UINT32)(ullCpuTick >> OS_SYS_MV_32_BIT); - - return LOS_OK; -} - -/***************************************************************************** -Function : osCpuTick2US -Description: cycle convert to Microsecond -Input : uwInterval ---------- cycle -Output : puwUsHi ---------- High 32 Microsecond - puwUsLo ---------- Low 32 Microsecond -Return : LOS_OK on success ,or error code on failure -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 osCpuTick2US(CPU_TICK *pstCpuTick, UINT32 *puwUsHi, UINT32 *puwUsLo) -{ - UINT64 ullCpuTick; - double dTemp; - - if ( (NULL == pstCpuTick) || (NULL == puwUsHi) || (NULL == puwUsLo) ) - { - return LOS_ERRNO_SYS_PTR_NULL; - } - - ullCpuTick = ((UINT64)pstCpuTick->uwCntHi << OS_SYS_MV_32_BIT) | pstCpuTick->uwCntLo; - dTemp = ullCpuTick / (((double)OS_SYS_CLOCK) / OS_SYS_US_PER_SECOND); /*lint !e160 !e653 !e40*/ - ullCpuTick = (UINT64)dTemp; - - *puwUsLo = (UINT32)ullCpuTick; - *puwUsHi = (UINT32)(ullCpuTick >> OS_SYS_MV_32_BIT); - - return LOS_OK; + return (UINT32)(((UINT64)tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND); } #ifdef __cplusplus diff --git a/kernel/base/core/los_sys.inc b/kernel/base/core/los_sys.inc deleted file mode 100644 index b4ae9a364..000000000 --- a/kernel/base/core/los_sys.inc +++ /dev/null @@ -1,137 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_SYS_INC -#define _LOS_SYS_INC - -#include "los_sys.ph" - -#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 - *
      - *
    • None.
    • - *
    - * - *@param pstCpuTick [IN] Number of CPU cycles. - *@param puwMsHi [OUT] Upper 32 bits of the number of milliseconds. - *@param puwMsLo [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: - *
    • los_sys.inc: the header file that contains the API declaration.
    - *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osCpuTick2MS(CPU_TICK *pstCpuTick, UINT32 *puwMsHi, UINT32 *puwMsLo); - -/** - *@ingroup los_sys - *@brief Convert cycles to microseconds. - * - *@par Description: - *This API is used to convert cycles to microseconds. - *@attention - *
      - *
    • None.
    • - *
    - * - *@param pstCpuTick [IN] Number of CPU cycles. - *@param puwUsHi [OUT] Upper 32 bits of the number of microseconds. - *@param puwUsLo [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: - *
    • los_sys.inc: the header file that contains the API declaration.
    - *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osCpuTick2US(CPU_TICK *pstCpuTick, UINT32 *puwUsHi, UINT32 *puwUsLo); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_SYS_INC */ diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index fc8bccdd6..90b011844 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Task Module Implementation * 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 @@ -22,33 +22,46 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "string.h" -#include "los_task.inc" -#include "los_base.ph" -#include "los_memory.ph" -#include "los_memstat.ph" -#include "los_priqueue.ph" -#include "los_sem.ph" -#include "los_mux.ph" -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_exc.ph" + * --------------------------------------------------------------------------- */ + +#include "los_task_pri.h" +#include "los_base_pri.h" +#include "los_priqueue_pri.h" +#include "los_sem_pri.h" +#include "los_mux_debug_pri.h" +#include "los_hw_pri.h" +#include "los_exc.h" +#include "los_memstat_pri.h" +#include "los_spinlock.h" +#include "los_percpu_pri.h" + +#if (LOSCFG_KERNEL_TRACE == YES) +#include "los_trace.h" #endif -#if (LOSCFG_KERNEL_TICKLESS == YES) -#include "los_tickless.ph" + +#ifdef LOSCFG_KERNEL_RUNSTOP +#include "los_runstop_pri.h" +#endif +#ifdef LOSCFG_KERNEL_TICKLESS +#include "los_tickless_pri.h" +#endif +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" #endif -#if (LOSCFG_BASE_CORE_CPUP == YES) -#include "los_cpup.ph" +#if (LOSCFG_BASE_CORE_SWTMR == YES) +#include "los_swtmr_pri.h" +#endif +#ifdef LOSCFG_EXC_INTERACTION +#include "los_exc_interaction_pri.h" #endif -#include "los_hw.h" #ifdef __cplusplus #if __cplusplus @@ -56,1546 +69,1214 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -LITE_OS_SEC_BSS LOS_TASK_CB *g_pstTaskCBArray; -LITE_OS_SEC_BSS ST_LOS_TASK g_stLosTask; -LITE_OS_SEC_BSS UINT16 g_usLosTaskLock; -LITE_OS_SEC_BSS UINT32 g_uwTskMaxNum; -LITE_OS_SEC_BSS UINT32 g_uwIdleTaskID; -LITE_OS_SEC_BSS UINT32 g_uwSwtmrTaskID; -LITE_OS_SEC_BSS LOS_DL_LIST g_stTaskTimerList; -LITE_OS_SEC_BSS LOS_DL_LIST g_stLosFreeTask; -LITE_OS_SEC_BSS LOS_DL_LIST g_stTskRecyleList; -LITE_OS_SEC_BSS TSK_SORTLINK_ATTRIBUTE_S g_stTskSortLink; -LITE_OS_SEC_BSS BOOL g_bTaskScheduled; - -LITE_OS_SEC_DATA_INIT TSKSWITCHHOOK g_pfnTskSwitchHook = (TSKSWITCHHOOK)NULL; /*lint !e611*/ -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) -LITE_OS_SEC_DATA_INIT TSKSWITCHHOOK g_pfnTskSwitchImpurePtrHook = (TSKSWITCHHOOK)NULL; /*lint !e611*/ +#if (LOSCFG_BASE_CORE_TASK_DYN_MEM == YES) +LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray; +#else +#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0) +#error "task maxnum cannot be zero" +#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */ + +LITE_OS_SEC_BSS LosTaskCB g_taskCBArray[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; #endif + +LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask; +LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecyleList; +LITE_OS_SEC_BSS UINT32 g_taskMaxNum; +LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores */ + +/* spinlock for task module */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin); + #if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) -LITE_OS_SEC_DATA_INIT TSKSWITCHHOOK g_pfnUsrTskSwitchHook = (TSKSWITCHHOOK)NULL; /*lint !e611*/ +TSKSWITCHHOOK g_pfnUsrTskSwitchHook = NULL; #endif /* LOSCFG_BASE_CORE_TSK_MONITOR == YES */ +STATIC VOID OsConsoleIDSetHook(UINT32 param1, + UINT32 param2) __attribute__((weakref("OsSetConsoleID"))); -#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) -LITE_OS_SEC_BSS OS_TASK_SWITCH_INFO g_astTskSwitchInfo; -#endif +#define OS_CHECK_TASK_BLOCK (OS_TASK_STATUS_DELAY | \ + OS_TASK_STATUS_PEND | \ + OS_TASK_STATUS_SUSPEND) -#define CHECK_TASKID(uwTaskID)\ -{\ - if (uwTaskID == g_uwIdleTaskID)\ - {\ - return LOS_ERRNO_TSK_OPERATE_IDLE;\ - }\ - else if (uwTaskID == g_uwSwtmrTaskID)\ - {\ - return LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED;\ - }\ - else if (OS_TSK_GET_INDEX(uwTaskID) >= g_uwTskMaxNum)\ - {\ - return LOS_ERRNO_TSK_ID_INVALID;\ - }\ -} +#define OS_TASK_ID_CHECK_INVALID(taskID) (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) -#if (LOSCFG_KERNEL_TICKLESS == YES) -LITE_OS_SEC_TEXT_MINOR UINT32 osTaskNextSwitchTimeGet(VOID) -{ - LOS_TASK_CB *pstTaskCB; - UINT32 uwTaskSortLinkTick = 0; - LOS_DL_LIST *pstListObject; - UINT32 uwTempTicks = 0; - UINT32 uwIndex =0; - - for (uwIndex = 0; uwIndex < OS_TSK_SORTLINK_LEN; uwIndex++) - { - pstListObject = g_stTskSortLink.pstSortLink + (g_stTskSortLink.usCursor + uwIndex)%OS_TSK_SORTLINK_LEN; - if (pstListObject->pstNext != pstListObject) - { - pstTaskCB = LOS_DL_LIST_ENTRY((pstListObject)->pstNext, LOS_TASK_CB, stTimerList); - uwTempTicks = (uwIndex == 0) ? OS_TSK_SORTLINK_LEN : uwIndex; - uwTempTicks += (UINT32)(UWROLLNUM(pstTaskCB->uwIdxRollNum) * OS_TSK_SORTLINK_LEN); - if(uwTaskSortLinkTick == 0 || uwTaskSortLinkTick > uwTempTicks) - { - uwTaskSortLinkTick = uwTempTicks; - } - } - } +#define OS_INVALID_VALUE 0xFFFFFFFF - return uwTaskSortLinkTick; -} -#endif +/* temp task blocks for booting procedure */ +LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM]; -/***************************************************************************** - Function : osTskIdleBGD - Description : Idle background. - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT WEAK VOID osIdleTask(VOID) +VOID* OsGetMainTask() { - while (1) - { -#if (LOSCFG_KERNEL_TICKLESS == YES) - osTicklessHandler(); -#else - #if (LOSCFG_KERNEL_RUNSTOP == YES) - osEnterSleep(); - #endif -#endif - } + return (g_mainTask + ArchCurrCpuid()); } -/***************************************************************************** - Function : osTaskPriModify - Description : Change task priority. - Input : pstTaskCB --- task control block - usPriority --- priority - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID osTaskPriModify(LOS_TASK_CB *pstTaskCB, UINT16 usPriority) +VOID OsSetMainTask() { - if (pstTaskCB->usTaskStatus & OS_TASK_STATUS_READY) - { - osPriqueueDequeue(&pstTaskCB->stPendList); - pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_READY); - pstTaskCB->usPriority = usPriority; - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_READY; - osPriqueueEnqueue(&pstTaskCB->stPendList, pstTaskCB->usPriority); - } - else - { - pstTaskCB->usPriority = usPriority; + UINT32 i; + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED; + g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_CONFIG; + g_mainTask[i].priority = OS_TASK_PRIORITY_LOWEST + 1; + g_mainTask[i].taskName = "OsMain"; } } -/***************************************************************************** - Function : osTaskAdd2TimerList - Description : Add task to sorted delay list. - Input : pstTaskCB --- task control block - uwTimeout --- wait time, ticks - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osTaskAdd2TimerList(LOS_TASK_CB *pstTaskCB, UINT32 uwTimeout) +LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) { - LOS_TASK_CB *pstTskDelay; - LOS_DL_LIST *pstListObject; - UINT32 uwSortIndex; - UINT32 uwRollNum; - - uwSortIndex = uwTimeout & OS_TSK_SORTLINK_MASK; - uwRollNum = (uwTimeout >> OS_TSK_SORTLINK_LOGLEN); - (uwSortIndex > 0) ? 0 : (uwRollNum--); - EVALUATE_L(pstTaskCB->uwIdxRollNum, uwRollNum); - uwSortIndex = (uwSortIndex + g_stTskSortLink.usCursor); - uwSortIndex = uwSortIndex & OS_TSK_SORTLINK_MASK; - EVALUATE_H(pstTaskCB->uwIdxRollNum, uwSortIndex); - pstListObject = g_stTskSortLink.pstSortLink + uwSortIndex; - if (pstListObject->pstNext == pstListObject) - { - LOS_ListTailInsert(pstListObject, &pstTaskCB->stTimerList); - } - else - { - pstTskDelay = LOS_DL_LIST_ENTRY((pstListObject)->pstNext, LOS_TASK_CB, stTimerList); /*lint !e413*/ - do - { - if (UWROLLNUM(pstTskDelay->uwIdxRollNum) <= UWROLLNUM(pstTaskCB->uwIdxRollNum)) - { - UWROLLNUMSUB(pstTaskCB->uwIdxRollNum, pstTskDelay->uwIdxRollNum); - } - else - { - UWROLLNUMSUB(pstTskDelay->uwIdxRollNum, pstTaskCB->uwIdxRollNum); - break; - } - - pstTskDelay = LOS_DL_LIST_ENTRY(pstTskDelay->stTimerList.pstNext, LOS_TASK_CB, stTimerList); /*lint !e413*/ - } while (&pstTskDelay->stTimerList != (pstListObject)); + while (1) { +#ifdef LOSCFG_KERNEL_RUNSTOP + if (OsWowSysDoneFlagGet() == OS_STORE_SYSTEM) { + OsStoreSystemInfoBeforeSuspend(); + } +#endif - LOS_ListTailInsert(&pstTskDelay->stTimerList, &pstTaskCB->stTimerList); +#ifdef LOSCFG_KERNEL_TICKLESS + if (OsTickIrqFlagGet()) { + OsTickIrqFlagSet(0); + OsTicklessStart(); + } +#endif + wfi(); } } - -LITE_OS_SEC_TEXT VOID osTimerListDelete(LOS_TASK_CB *pstTaskCB) +/* + * Description : Change task priority. + * Input : taskCB --- task control block + * priority --- priority + */ +LITE_OS_SEC_TEXT_MINOR VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority) { - LOS_DL_LIST *pstListObject; - LOS_TASK_CB *pstNextTask; - UINT32 uwSortIndex; - - uwSortIndex = UWSORTINDEX(pstTaskCB->uwIdxRollNum); - pstListObject = g_stTskSortLink.pstSortLink + uwSortIndex; + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); - if (pstListObject != pstTaskCB->stTimerList.pstNext) - { - pstNextTask = LOS_DL_LIST_ENTRY(pstTaskCB->stTimerList.pstNext, LOS_TASK_CB, stTimerList); /*lint !e413*/ - UWROLLNUMADD(pstNextTask->uwIdxRollNum, pstTaskCB->uwIdxRollNum); + if (taskCB->taskStatus & OS_TASK_STATUS_READY) { + OsPriQueueDequeue(&taskCB->pendList); + taskCB->priority = priority; + OsPriQueueEnqueue(&taskCB->pendList, taskCB->priority); + } else { + taskCB->priority = priority; } +} - LOS_ListDelete(&pstTaskCB->stTimerList); +/* + * Description : Add task to sorted delay list. + * Input : taskCB --- task control block + * timeout --- wait time, ticks + */ +LITE_OS_SEC_TEXT VOID OsTaskAdd2TimerList(LosTaskCB *taskCB, UINT32 timeout) +{ + SET_SORTLIST_VALUE(&(taskCB->sortList), timeout); + OsAdd2SortLink(&OsPercpuGet()->taskSortLink, &taskCB->sortList); } -LITE_OS_SEC_TEXT VOID osTaskScan(VOID) +LITE_OS_SEC_TEXT VOID OsTimerListDelete(LosTaskCB *taskCB) { - LOS_TASK_CB *pstTaskCB; - BOOL bNeedSchedule = FALSE; - LOS_DL_LIST *pstListObject; - UINT16 usTempStatus; - - g_stTskSortLink.usCursor = (g_stTskSortLink.usCursor + 1) % OS_TSK_SORTLINK_LEN; - pstListObject = g_stTskSortLink.pstSortLink + g_stTskSortLink.usCursor; - if (pstListObject->pstNext == pstListObject) - { + SortLinkAttribute *sortLinkHeader = NULL; + sortLinkHeader = &g_percpu[0].taskSortLink; + OsDeleteSortLink(sortLinkHeader, &taskCB->sortList); +} + +LITE_OS_SEC_TEXT VOID OsTaskScan(VOID) +{ + SortLinkList *sortList = NULL; + LosTaskCB *taskCB = NULL; + BOOL needSchedule = FALSE; + UINT16 tempStatus; + LOS_DL_LIST *listObject = NULL; + SortLinkAttribute *taskSortLink = NULL; + + taskSortLink = &OsPercpuGet()->taskSortLink; + taskSortLink->cursor = (taskSortLink->cursor + 1) & OS_TSK_SORTLINK_MASK; + listObject = taskSortLink->sortLink + taskSortLink->cursor; + + /* + * When task is pended with timeout, the task block is on the timeout sortlink + * (per cpu) and ipc(mutex,sem and etc.)'s block at the same time, it can be waken + * up by either timeout or corresponding ipc it's waiting. + * + * Now synchronize sortlink preocedure is used, therefore the whole task scan needs + * to be protected, preventing another core from doing sortlink deletion at same time. + */ + LOS_SpinLock(&g_taskSpin); + + if (LOS_ListEmpty(listObject)) { + LOS_SpinUnlock(&g_taskSpin); return; } - - for (pstTaskCB = LOS_DL_LIST_ENTRY((pstListObject)->pstNext, LOS_TASK_CB, stTimerList);&pstTaskCB->stTimerList != (pstListObject);) /*lint !e413*/ - { - usTempStatus = pstTaskCB->usTaskStatus; - if (UWROLLNUM(pstTaskCB->uwIdxRollNum) > 0) - { - UWROLLNUMDEC(pstTaskCB->uwIdxRollNum); - break; + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); + ROLLNUM_DEC(sortList->idxRollNum); + + while (ROLLNUM(sortList->idxRollNum) == 0) { + LOS_ListDelete(&sortList->sortLinkNode); + taskCB = LOS_DL_LIST_ENTRY(sortList, LosTaskCB, sortList); + taskCB->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_PEND) { + taskCB->taskStatus &= ~OS_TASK_STATUS_PEND; + taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT; + LOS_ListDelete(&taskCB->pendList); + taskCB->taskSem = NULL; + taskCB->taskMux = NULL; + } else { + taskCB->taskStatus &= ~OS_TASK_STATUS_DELAY; } - LOS_ListDelete(&pstTaskCB->stTimerList); - if (OS_TASK_STATUS_PEND & usTempStatus) - { - pstTaskCB->usTaskStatus &= ~(OS_TASK_STATUS_PEND); - LOS_ListDelete(&pstTaskCB->stPendList); - pstTaskCB->pTaskSem = NULL; - pstTaskCB->pTaskMux = NULL; - } - else if (OS_TASK_STATUS_EVENT & usTempStatus) - { - pstTaskCB->usTaskStatus &= ~(OS_TASK_STATUS_EVENT); - } - else if (OS_TASK_STATUS_PEND_QUEUE & usTempStatus) - { - LOS_ListDelete(&pstTaskCB->stPendList); - pstTaskCB->usTaskStatus &= ~(OS_TASK_STATUS_PEND_QUEUE); - } - else - { - pstTaskCB->usTaskStatus &= ~(OS_TASK_STATUS_DELAY); + if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) { + taskCB->taskStatus |= OS_TASK_STATUS_READY; + OsPriQueueEnqueue(&taskCB->pendList, taskCB->priority); + needSchedule = TRUE; } - if (!((OS_TASK_STATUS_SUSPEND) & usTempStatus)) - { - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_READY; - osPriqueueEnqueue(&pstTaskCB->stPendList, pstTaskCB->usPriority); - bNeedSchedule = TRUE; + if (LOS_ListEmpty(listObject)) { + break; } - pstTaskCB = LOS_DL_LIST_ENTRY(pstListObject->pstNext, LOS_TASK_CB, stTimerList); /*lint !e413*/ + sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); } - if (bNeedSchedule) - { + LOS_SpinUnlock(&g_taskSpin); + + if (needSchedule != FALSE) { LOS_Schedule(); } } -/***************************************************************************** - Function : osConvertTskStatus - Description : Convert task status to string. - Input : usTaskStatus --- task status - Output : None - Return : string - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT8 *osConvertTskStatus(UINT16 usTaskStatus) +LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID) { - if (OS_TASK_STATUS_RUNNING & usTaskStatus) - { - return (UINT8 *)"Running"; - } - else if (OS_TASK_STATUS_READY & usTaskStatus) - { - return (UINT8 *)"Ready"; - } - else if (OS_TASK_STATUS_DELAY & usTaskStatus) - { - return (UINT8 *)"Delay"; - } - else if (OS_TASK_STATUS_PEND & usTaskStatus) - { - if (OS_TASK_STATUS_TIMEOUT & usTaskStatus) - { - return (UINT8 *)"PendTimeOut"; - } + UINT32 index; + UINT32 ret; + + /* + * This memory is resident memory and is used to save the system resources + * of task control block and will not be freed. + */ +#if (LOSCFG_BASE_CORE_TASK_DYN_MEM == YES) + UINT32 size; + size = (g_taskMaxNum + 1) * sizeof(LosTaskCB); + g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_taskCBArray == NULL) { + return LOS_ERRNO_TSK_NO_MEMORY; + } + (VOID)memset_s(g_taskCBArray, size, 0, size); +#endif - return (UINT8 *)"Pend"; + 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); } - else if (OS_TASK_STATUS_SUSPEND & usTaskStatus) - { - return (UINT8 *)"Suspend"; + + ret = OsPriQueueInit(); + if (ret != LOS_OK) { + return LOS_ERRNO_TSK_NO_MEMORY; } - else if (OS_TASK_STATUS_PEND_QUEUE& usTaskStatus) - { - if (OS_TASK_STATUS_TIMEOUT & usTaskStatus) - { - return (UINT8 *)"QueuePendTimeOut"; - } - return (UINT8 *)"QueuePend"; + ret = OsMuxDlockCheckInitHook(); + if (ret != LOS_OK) { + return LOS_ERRNO_TSK_NO_MEMORY; } - return (UINT8 *)"Impossible"; + /* init sortlink for each core */ + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + ret = OsSortLinkInit(&g_percpu[index].taskSortLink); + if (ret != LOS_OK) { + return LOS_ERRNO_TSK_NO_MEMORY; + } + } + return LOS_OK; } -LITE_OS_SEC_TEXT_MINOR UINT32 osGetTaskWaterLine(UINT32 uwTaskID) +UINT32 OsGetIdleTaskId(VOID) { - UINT32 *puwStack; - UINT32 uwPeakUsed; - - if (OS_TASK_MAGIC_WORD == *(UINT32 *)(((LOS_TASK_CB *)g_pstTaskCBArray) + uwTaskID)->uwTopOfStack) - { - puwStack = (UINT32 *)((((LOS_TASK_CB *)g_pstTaskCBArray) + uwTaskID)->uwTopOfStack + 4); - while ((puwStack < (UINT32 *)(((LOS_TASK_CB *)g_pstTaskCBArray) + uwTaskID)->pStackPointer) && (*puwStack == 0xCACACACA)) - { - puwStack += 1; - } - uwPeakUsed = ((((LOS_TASK_CB *)g_pstTaskCBArray) + uwTaskID)->uwStackSize - ((UINT32)puwStack - (((LOS_TASK_CB *)g_pstTaskCBArray) + uwTaskID)->uwTopOfStack)); - } - else - { - PRINT_ERR("CURRENT task %s stack overflow!\n", (((LOS_TASK_CB *)g_pstTaskCBArray) + uwTaskID)->pcTaskName); - uwPeakUsed = 0xFFFFFFFF; - } - return uwPeakUsed; + Percpu *perCpu = OsPercpuGet(); + return perCpu->idleTaskID; } -/***************************************************************************** - Function : osGetAllTskInfo - Description : Get all task info. - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 osGetAllTskInfo(VOID) +LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) { - LOS_TASK_CB *pstTaskCB; - UINT32 uwLoop; -#if (LOSCFG_BASE_CORE_CPUP == YES) - CPUP_INFO_S *pstCpu = (CPUP_INFO_S *)NULL; - CPUP_INFO_S *pstCpu10s = (CPUP_INFO_S *)NULL; - CPUP_INFO_S *pstCpu1s = (CPUP_INFO_S *)NULL; -#endif + UINT32 ret; + TSK_INIT_PARAM_S taskInitParam; + Percpu *perCpu = OsPercpuGet(); + UINT32 *idleTaskID = &perCpu->idleTaskID; -#if (LOSCFG_BASE_CORE_CPUP == YES) - pstCpu = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_uwTskMaxNum); - if (pstCpu == NULL) - { - PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__);/*lint !e515*/ - return OS_ERROR; - } - (VOID)memset((VOID *)pstCpu, (int)0, sizeof(CPUP_INFO_S) * g_uwTskMaxNum); - - pstCpu10s = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_uwTskMaxNum); - if (pstCpu10s == NULL) - { - PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__);/*lint !e515*/ - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, pstCpu); - return OS_ERROR; - } - (VOID)memset((VOID *)pstCpu10s, (int)0, sizeof(CPUP_INFO_S) * g_uwTskMaxNum); - - pstCpu1s = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_uwTskMaxNum); - if (pstCpu1s == NULL) - { - PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__);/*lint !e515*/ - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, pstCpu); - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, pstCpu10s); - return OS_ERROR; - } - (VOID)memset((VOID *)pstCpu1s, (int)0, sizeof(CPUP_INFO_S) * g_uwTskMaxNum); - - LOS_TaskLock(); - (VOID)LOS_AllTaskCpuUsage(g_uwTskMaxNum, pstCpu, 0xffff); - (VOID)LOS_AllTaskCpuUsage(g_uwTskMaxNum, pstCpu10s, 0); - (VOID)LOS_AllTaskCpuUsage(g_uwTskMaxNum, pstCpu1s, 1); - LOS_TaskUnlock(); -#endif + (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; - PRINT_ERR("\r\nName TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID");/*lint !e515*/ -#if (LOSCFG_BASE_CORE_CPUP == YES) - PRINT_ERR(" CPUUSE CPUUSE10s CPUUSE1s ");/*lint !e515*/ -#endif /* LOSCFG_BASE_CORE_CPUP */ - PRINT_ERR("\n");/*lint !e515*/ - PRINT_ERR("---- --- -------- -------- --------- ---------- ---------- ---------- --------- -----");/*lint !e515*/ -#if (LOSCFG_BASE_CORE_CPUP == YES) - PRINT_ERR(" ------- --------- ---------");/*lint !e515*/ -#endif /* LOSCFG_BASE_CORE_CPUP */ - PRINT_ERR("\n");/*lint !e515*/ - - for (uwLoop = 0; uwLoop < g_uwTskMaxNum; uwLoop++) - { - //uvIntSave = LOS_IntLock(); - pstTaskCB = (((LOS_TASK_CB *)g_pstTaskCBArray) + uwLoop); - if (pstTaskCB->usTaskStatus & OS_TASK_STATUS_UNUSED) - { - //LOS_IntRestore(uvIntSave); - continue; - } + ret = LOS_TaskCreate(idleTaskID, &taskInitParam); + OS_TCB_FROM_TID(*idleTaskID)->taskFlags |= OS_TASK_FLAG_SYSTEM; - PRINT_ERR("%-30s, 0x%-5x, %-11d, %-13s, 0x%-11x, 0x%-11x, 0x%-10x, 0x%-11x, 0x%-9x", - pstTaskCB->pcTaskName, - pstTaskCB->uwTaskID, - pstTaskCB->usPriority, - osConvertTskStatus(pstTaskCB->usTaskStatus), - pstTaskCB->uwStackSize, - osGetTaskWaterLine(pstTaskCB->uwTaskID), - (UINT32)pstTaskCB->pStackPointer, - pstTaskCB->uwTopOfStack, - pstTaskCB->uwEventMask);/*lint !e515*/ - - if (pstTaskCB->pTaskSem != NULL) - { - PRINT_ERR("0x%-7x", ((SEM_CB_S *)pstTaskCB->pTaskSem)->usSemID);/*lint !e516*/ - } - else - { - PRINT_ERR("0x%-7x", 0xFFFF); - } + return ret; +} -#if (LOSCFG_BASE_CORE_CPUP == YES) - PRINT_ERR("%2d.%-7d" - "%2d.%-9d" - "%2d.%-6d", - pstCpu[pstTaskCB->uwTaskID].uwUsage / LOS_CPUP_PRECISION_MULT, - pstCpu[pstTaskCB->uwTaskID].uwUsage % LOS_CPUP_PRECISION_MULT, - pstCpu10s[pstTaskCB->uwTaskID].uwUsage / LOS_CPUP_PRECISION_MULT, - pstCpu10s[pstTaskCB->uwTaskID].uwUsage % LOS_CPUP_PRECISION_MULT, - pstCpu1s[pstTaskCB->uwTaskID].uwUsage / LOS_CPUP_PRECISION_MULT, - pstCpu1s[pstTaskCB->uwTaskID].uwUsage % LOS_CPUP_PRECISION_MULT);/*lint !e515 !e516*/ -#endif /* LOSCFG_BASE_CORE_CPUP */ - PRINT_ERR("\n");/*lint !e515*/ - } - -#if (LOSCFG_BASE_CORE_CPUP == YES) - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, pstCpu); - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, pstCpu10s); - (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, pstCpu1s); -#endif +/* + * Description : get id of current running task. + * Return : task id + */ +LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); - return LOS_OK; + if (runTask == NULL) { + return LOS_ERRNO_TSK_ID_INVALID; + } + return runTask->taskID; } -/***************************************************************************** - 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) +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) +LITE_OS_SEC_TEXT STATIC VOID OsTaskStackCheck(LosTaskCB *oldTask, LosTaskCB *newTask) { - UINT32 uwSize; - UINT32 uwIndex; - LOS_DL_LIST *pstListObject; - - uwSize = (g_uwTskMaxNum + 1) * sizeof(LOS_TASK_CB); - g_pstTaskCBArray = (LOS_TASK_CB *)LOS_MemAlloc(m_aucSysMem0, uwSize); - if (NULL == g_pstTaskCBArray) - { - return LOS_ERRNO_TSK_NO_MEMORY; + if (!OS_STACK_MAGIC_CHECK(oldTask->topOfStack)) { + LOS_Panic("CURRENT task ID: %s:%d stack overflow!\n", oldTask->taskName, oldTask->taskID); } - (VOID)memset(g_pstTaskCBArray, 0, uwSize); - LOS_ListInit(&g_stTaskTimerList); - LOS_ListInit(&g_stLosFreeTask); - LOS_ListInit(&g_stTskRecyleList); - for (uwIndex = 0; uwIndex <= LOSCFG_BASE_CORE_TSK_LIMIT; uwIndex++) - { - g_pstTaskCBArray[uwIndex].usTaskStatus = OS_TASK_STATUS_UNUSED; - g_pstTaskCBArray[uwIndex].uwTaskID = uwIndex; - LOS_ListTailInsert(&g_stLosFreeTask, &g_pstTaskCBArray[uwIndex].stPendList); - } - - (VOID)memset((VOID *)(&g_stLosTask), 0, sizeof(g_stLosTask)); - g_stLosTask.pstRunTask = &g_pstTaskCBArray[g_uwTskMaxNum]; - g_stLosTask.pstRunTask->uwTaskID = uwIndex; - g_stLosTask.pstRunTask->usTaskStatus = (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_RUNNING); - g_stLosTask.pstRunTask->usPriority = OS_TASK_PRIORITY_LOWEST + 1; - osPriqueueInit(); - uwSize = sizeof(LOS_DL_LIST) * OS_TSK_SORTLINK_LEN; - pstListObject = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, uwSize); - if (NULL == pstListObject) - { - return LOS_ERRNO_TSK_NO_MEMORY; + if (((UINTPTR)(newTask->stackPointer) <= newTask->topOfStack) || + ((UINTPTR)(newTask->stackPointer) > (newTask->topOfStack + newTask->stackSize))) { + LOS_Panic("HIGHEST task ID: %s:%u SP error! StackPointer: %p TopOfStack: %p\n", + newTask->taskName, newTask->taskID, newTask->stackPointer, newTask->topOfStack); } - (VOID)memset((VOID *)pstListObject, 0, uwSize); - g_stTskSortLink.pstSortLink = pstListObject; - g_stTskSortLink.usCursor = 0; - for (uwIndex = 0; uwIndex < OS_TSK_SORTLINK_LEN; uwIndex++, pstListObject++) - { - LOS_ListInit(pstListObject); + if (g_pfnUsrTskSwitchHook != NULL) { + g_pfnUsrTskSwitchHook(); } - -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - osExcRegister((EXC_INFO_TYPE)OS_EXC_TYPE_TSK, (EXC_INFO_SAVE_CALLBACK)LOS_TaskInfoGet, &g_uwTskMaxNum); -#endif - -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) - extern LITE_OS_SEC_TEXT VOID osTaskSwitchImpurePtr(VOID); - g_pfnTskSwitchImpurePtrHook = osTaskSwitchImpurePtr; -#endif - return LOS_OK; } +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMonInit(VOID) +{ + g_pfnUsrTskSwitchHook = NULL; + return; +} +#endif -/***************************************************************************** - 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) +LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskSwitchCheck(LosTaskCB *oldTask, LosTaskCB *newTask) { - UINT32 uwRet; - TSK_INIT_PARAM_S stTaskInitParam; +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) + OsTaskStackCheck(oldTask, newTask); +#endif /* LOSCFG_BASE_CORE_TSK_MONITOR == YES */ - (VOID)memset((VOID *)(&stTaskInitParam), 0, sizeof(TSK_INIT_PARAM_S)); - stTaskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)osIdleTask; - stTaskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; - stTaskInitParam.pcName = "IdleCore000"; - stTaskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; - uwRet = LOS_TaskCreate(&g_uwIdleTaskID, &stTaskInitParam); + OsTaskTimeUpdateHook(oldTask->taskID, LOS_TickCountGet()); - if (uwRet != LOS_OK) - { - return uwRet; - } +#ifdef LOSCFG_KERNEL_CPUP + OsTaskCycleEndStart(newTask); +#endif /* LOSCFG_KERNEL_CPUP */ + +#if (LOSCFG_KERNEL_TRACE == YES) + LOS_Trace(LOS_TRACE_SWITCH, newTask->taskID, oldTask->taskID); +#endif 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) +/* + * Description : All task entry + * Input : taskID --- The ID of the task to be run + */ +LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) { - if (NULL == g_stLosTask.pstRunTask) - { - return LOS_ERRNO_TSK_ID_INVALID; + LosTaskCB *taskCB = NULL; + UINT32 intSave; + + LOS_ASSERT(OS_TSK_GET_INDEX(taskID) < g_taskMaxNum); + + /* + * task scheduler needs to be protected throughout the whole process + * from interrupt and other cores. release task spinlock and enable + * interrupt in sequence at the task entry. + */ + LOS_SpinUnlock(&g_taskSpin); + (VOID)LOS_IntUnLock(); + + taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->threadJoin != NULL) { + taskCB->threadJoinRetval = taskCB->taskEntry(taskCB->args[0], /* 0~3: just for args array index */ + taskCB->args[1], + taskCB->args[2], + taskCB->args[3]); + } else { + (VOID)taskCB->taskEntry(taskCB->args[0], + taskCB->args[1], + taskCB->args[2], + taskCB->args[3]); + } + + if (taskCB->taskFlags & OS_TASK_FLAG_DETACHED) { + intSave = LOS_IntLock(); + OsPercpuGet()->taskLockCnt = 0; + LOS_IntRestore(intSave); + (VOID)LOS_TaskDelete(taskCB->taskID); + } else { /* join mode: waiting for child task done */ + intSave = LOS_IntLock(); + OsPercpuGet()->taskLockCnt = 1; + + if (taskCB->threadJoin != NULL) { + if (LOS_SemPost((UINT32)(((LosSemCB *)taskCB->threadJoin)->semID)) != LOS_OK) { + PRINT_ERR("OsTaskEntry LOS_SemPost fail!\n"); + } + taskCB->threadJoin = NULL; + } + + OsPercpuGet()->taskLockCnt = 0; + + LOS_SpinLock(&g_taskSpin); + OsSchedResched(); + + SCHEDULER_UNLOCK(intSave); } - return g_stLosTask.pstRunTask->uwTaskID; } -/***************************************************************************** - 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) +LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID, + TSK_INIT_PARAM_S *initParam, VOID **pool) { - if (NULL == g_stLosTask.pstNewTask) - { + UINT32 poolSize = OS_SYS_MEM_SIZE; + *pool = (VOID *)m_aucSysMem1; + + if (taskID == NULL) { return LOS_ERRNO_TSK_ID_INVALID; } - return g_stLosTask.pstNewTask->uwTaskID; -} -/***************************************************************************** - 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 *pcTaskName = NULL; + if (initParam == NULL) { + return LOS_ERRNO_TSK_PTR_NULL; + } - if (NULL != g_stLosTask.pstRunTask) - { - pcTaskName = g_stLosTask.pstRunTask->pcTaskName; + if (initParam->pcName == NULL) { + return LOS_ERRNO_TSK_NAME_EMPTY; } - return pcTaskName; -} + if (initParam->pfnTaskEntry == NULL) { + return LOS_ERRNO_TSK_ENTRY_NULL; + } -/***************************************************************************** - 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 ((*(UINT32 *)(g_stLosTask.pstRunTask->uwTopOfStack)) != OS_TASK_MAGIC_WORD) - { - PRINT_ERR("CURRENT task ID: %s:%d stack overflow!\n", g_stLosTask.pstRunTask->pcTaskName, g_stLosTask.pstRunTask->uwTaskID); + if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) { + return LOS_ERRNO_TSK_PRIOR_ERROR; } - if (((UINT32)(g_stLosTask.pstNewTask->pStackPointer) <= g_stLosTask.pstNewTask->uwTopOfStack) || - ((UINT32)(g_stLosTask.pstNewTask->pStackPointer) > g_stLosTask.pstNewTask->uwTopOfStack + g_stLosTask.pstNewTask->uwStackSize)) - { - PRINT_ERR("HIGHEST task ID: %s:%d SP error!\n", g_stLosTask.pstNewTask->pcTaskName, g_stLosTask.pstNewTask->uwTaskID); - PRINT_ERR("HIGHEST task StackPointer: 0x%x TopOfStack: 0x%x\n", (UINT32)(g_stLosTask.pstNewTask->pStackPointer), g_stLosTask.pstNewTask->uwTopOfStack); +#ifdef LOSCFG_EXC_INTERACTION + if (!OsExcInteractionTaskCheck(initParam)) { + *pool = m_aucSysMem0; + poolSize = OS_EXC_INTERACTMEM_SIZE; + } +#endif +#ifdef LOSCFG_TASK_STACK_PROTECT + poolSize = (poolSize > (MMU_4K << 1)) ? (poolSize - (MMU_4K << 1)) : 0; +#endif + if (initParam->uwStackSize > poolSize) { + return LOS_ERRNO_TSK_STKSZ_TOO_LARGE; } -#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) - /* record task switch info */ - g_astTskSwitchInfo.auwPID[g_astTskSwitchInfo.ucIdx] = (UINT16)(g_stLosTask.pstNewTask->uwTaskID); - memcpy(g_astTskSwitchInfo.acName[g_astTskSwitchInfo.ucIdx], g_stLosTask.pstNewTask->pcTaskName, LOS_TASK_NAMELEN); - g_astTskSwitchInfo.acName[g_astTskSwitchInfo.ucIdx][LOS_TASK_NAMELEN -1] = '\0'; - - if (++g_astTskSwitchInfo.ucIdx == OS_TASK_SWITCH_INFO_COUNT) - { - g_astTskSwitchInfo.ucIdx = 0; - g_astTskSwitchInfo.ucIsFull |= 0x80; + if (initParam->uwStackSize == 0) { + initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; } -#endif + initParam->uwStackSize = ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); - if (g_pfnUsrTskSwitchHook != NULL) - { - g_pfnUsrTskSwitchHook(); + if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) { + return LOS_ERRNO_TSK_STKSZ_TOO_SMALL; } -#if (LOSCFG_BASE_CORE_CPUP == YES) - osTskCycleEndStart(); -#endif /* LOSCFG_BASE_CORE_CPUP */ + return LOS_OK; } -LITE_OS_SEC_TEXT_MINOR VOID osTaskMonInit(VOID) +LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBRecyleToFree(VOID) { -#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) - (VOID)memset(&g_astTskSwitchInfo, 0, sizeof(OS_TASK_SWITCH_INFO)); - g_astTskSwitchInfo.ucIsFull = 0x7F & OS_TASK_SWITCH_INFO_COUNT; -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - osExcRegister((EXC_INFO_TYPE)OS_EXC_TYPE_TSK_SWITCH, (EXC_INFO_SAVE_CALLBACK)LOS_TaskSwitchInfoGet, &g_astTskSwitchInfo); + LosTaskCB *taskCB = NULL; + VOID *poolTmp = NULL; +#ifdef LOSCFG_TASK_STACK_PROTECT + UINTPTR MMUProtectAddr; #endif + + while (!LOS_ListEmpty(&g_taskRecyleList)) { + poolTmp = (VOID *)m_aucSysMem1; + 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); +#ifdef LOSCFG_TASK_STACK_PROTECT + MMUProtectAddr = taskCB->topOfStack - MMU_4K; + OsTaskStackProtect(MMUProtectAddr, MMU_4K, ACCESS_PERM_RW_RW); +#ifdef LOSCFG_EXC_INTERACTION + if (MMUProtectAddr < (UINTPTR)m_aucSysMem1) { + poolTmp = (VOID *)m_aucSysMem0; + } #endif - g_pfnTskSwitchHook = osTaskSwitchCheck; - g_pfnUsrTskSwitchHook = (TSKSWITCHHOOK)NULL; /*lint !e611*/ - return ; -} + (VOID)LOS_MemFree(poolTmp, (VOID *)MMUProtectAddr); +#else +#ifdef LOSCFG_EXC_INTERACTION + if (taskCB->topOfStack < (UINTPTR)m_aucSysMem1) { + poolTmp = (VOID *)m_aucSysMem0; + } +#endif + (VOID)LOS_MemFree(poolTmp, (VOID *)taskCB->topOfStack); #endif + taskCB->topOfStack = 0; + } +} -/***************************************************************************** - Function : osTaskEntry - Description : All task entry - Input : uwTaskID --- The ID of the task to be run - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID osTaskEntry(UINT32 uwTaskID) +LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskStackAlloc(VOID **topStack, UINT32 stackSize, VOID *pool) { - LOS_TASK_CB *pstTaskCB; - - OS_TASK_ID_CHECK(uwTaskID); - - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - - (VOID)pstTaskCB->pfnTaskEntry(pstTaskCB->uwArg); - - g_usLosTaskLock = 0; - (VOID)LOS_TaskDelete(pstTaskCB->uwTaskID); +#ifdef LOSCFG_TASK_STACK_PROTECT + UINTPTR MMUProtectAddr; + UINT32 alignStackSize; + + alignStackSize = ALIGN(stackSize, MMU_4K); + MMUProtectAddr = (UINTPTR)LOS_MemAllocAlign(pool, (alignStackSize + MMU_4K), MMU_4K); + if (MMUProtectAddr == 0) { + *topStack = NULL; + } else { + *topStack = (VOID *)(MMUProtectAddr + MMU_4K); + OsTaskStackProtect(MMUProtectAddr, MMU_4K, ACCESS_PERM_RO_RO); + } +#else + *topStack = (VOID *)LOS_MemAllocAlign(pool, stackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); +#endif } -/***************************************************************************** - Function : LOS_TaskCreateOnly - Description : Create a task and suspend - Input : pstInitParam --- Task init parameters - Output : puwTaskID --- Save task ID - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam) +STATIC INLINE UINT32 OsTaskSyncCreate(LosTaskCB *taskCB) { - UINT32 uwTaskID = 0; - UINTPTR uvIntSave; - VOID *pTopStack; - VOID *pStackPtr; - LOS_TASK_CB *pstTaskCB; - UINT32 uwErrRet = OS_ERROR; - - if (NULL == puwTaskID) - { - return LOS_ERRNO_TSK_ID_INVALID; - } + (VOID)taskCB; + return LOS_OK; +} - if (NULL == pstInitParam) - { - return LOS_ERRNO_TSK_PTR_NULL; - } +STATIC INLINE VOID OsTaskSyncDestroy(const LosTaskCB *taskCB) +{ + (VOID)taskCB; +} - if (NULL == pstInitParam->pcName) - { - return LOS_ERRNO_TSK_NAME_EMPTY; - } +STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB) +{ + (VOID)taskCB; + return LOS_OK; +} - if (NULL == pstInitParam->pfnTaskEntry) - { - return LOS_ERRNO_TSK_ENTRY_NULL; - } +STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB) +{ + (VOID)taskCB; +} - if ((pstInitParam->usTaskPrio) > OS_TASK_PRIORITY_LOWEST) - { - return LOS_ERRNO_TSK_PRIOR_ERROR; - } +LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, + VOID *stackPtr, const VOID *topStack) +{ + taskCB->stackPointer = stackPtr; + taskCB->args[0] = initParam->auwArgs[0]; /* 0~3: just for args array index */ + taskCB->args[1] = initParam->auwArgs[1]; + taskCB->args[2] = initParam->auwArgs[2]; + taskCB->args[3] = initParam->auwArgs[3]; + taskCB->topOfStack = (UINTPTR)topStack; + taskCB->stackSize = initParam->uwStackSize; + taskCB->taskSem = NULL; + taskCB->threadJoin = NULL; + taskCB->taskMux = NULL; + taskCB->taskStatus = OS_TASK_STATUS_SUSPEND; + taskCB->priority = initParam->usTaskPrio; + taskCB->priBitMap = 0; + taskCB->taskEntry = initParam->pfnTaskEntry; + taskCB->event.uwEventID = OS_INVALID_VALUE; + taskCB->eventMask = 0; + taskCB->taskName = initParam->pcName; + taskCB->msg = NULL; + + taskCB->taskFlags = ((initParam->uwResved == LOS_TASK_STATUS_DETACHED) ? + OS_TASK_FLAG_DETACHED : 0); /* set the task is detached or joinable */ + taskCB->signal = SIGNAL_NONE; + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + taskCB->timeSlice = 0; +#endif +} - if (((pstInitParam->usTaskPrio) == OS_TASK_PRIORITY_LOWEST) - && (pstInitParam->pfnTaskEntry != OS_IDLE_TASK_ENTRY)) - { - return LOS_ERRNO_TSK_PRIOR_ERROR; - } +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam) +{ + UINT32 tempTaskID, intSave, errRet; + VOID *topStack = NULL; + VOID *stackPtr = NULL; + LosTaskCB *taskCB = NULL; + VOID *pool = NULL; - if (pstInitParam->uwStackSize > OS_SYS_MEM_SIZE) - { - return LOS_ERRNO_TSK_STKSZ_TOO_LARGE; + errRet = OsTaskCreateParamCheck(taskID, initParam, &pool); + if (errRet != LOS_OK) { + return errRet; } - if (0 == pstInitParam->uwStackSize) - { - pstInitParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + SCHEDULER_LOCK(intSave); + OsTaskCBRecyleToFree(); + if (LOS_ListEmpty(&g_losFreeTask)) { + errRet = LOS_ERRNO_TSK_TCB_UNAVAILABLE; + OS_GOTO_ERREND(); } - pstInitParam->uwStackSize = ALIGN(pstInitParam->uwStackSize , LOSCFG_STACK_POINT_ALIGN_SIZE); - if (pstInitParam->uwStackSize < LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE) - { - return LOS_ERRNO_TSK_STKSZ_TOO_SMALL; - } + taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask)); + LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask)); + SCHEDULER_UNLOCK(intSave); - uvIntSave = LOS_IntLock(); - while (!LOS_ListEmpty(&g_stTskRecyleList)) - { - pstTaskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_stTskRecyleList)); /*lint !e413*/ - LOS_ListDelete(LOS_DL_LIST_FIRST(&g_stTskRecyleList)); - LOS_ListAdd(&g_stLosFreeTask, &pstTaskCB->stPendList); - (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)pstTaskCB->uwTopOfStack); - pstTaskCB->uwTopOfStack = (UINT32)NULL; + errRet = OsTaskSyncCreate(taskCB); + if (errRet != LOS_OK) { + goto LOS_ERREND_REWIND_TCB; } - if (LOS_ListEmpty(&g_stLosFreeTask)) - { - uwErrRet = LOS_ERRNO_TSK_TCB_UNAVAILABLE; - OS_GOTO_ERREND(); + tempTaskID = taskCB->taskID; + OsTaskStackAlloc(&topStack, initParam->uwStackSize, pool); + if (topStack == NULL) { + errRet = LOS_ERRNO_TSK_NO_MEMORY; + goto LOS_ERREND_REWIND_SYNC; } - pstTaskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_stLosFreeTask)); /*lint !e413*/ - LOS_ListDelete(LOS_DL_LIST_FIRST(&g_stLosFreeTask)); - (VOID)LOS_IntRestore(uvIntSave); - uwTaskID = pstTaskCB->uwTaskID; + stackPtr = OsTaskStackInit(tempTaskID, initParam->uwStackSize, topStack); + OsTaskCBInit(taskCB, initParam, stackPtr, topStack); - pTopStack = (VOID *)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, pstInitParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE); - - if (NULL == pTopStack) - { - uvIntSave = LOS_IntLock(); - LOS_ListAdd(&g_stLosFreeTask, &pstTaskCB->stPendList); - uwErrRet = LOS_ERRNO_TSK_NO_MEMORY; - OS_GOTO_ERREND(); + if (OsConsoleIDSetHook != NULL) { + OsConsoleIDSetHook(taskCB->taskID, OsCurrTaskGet()->taskID); } - pStackPtr = osTskStackInit(uwTaskID, pstInitParam->uwStackSize, pTopStack); - pstTaskCB->pStackPointer = pStackPtr; - pstTaskCB->uwArg = pstInitParam->uwArg; - pstTaskCB->uwTopOfStack = (UINT32)pTopStack; - pstTaskCB->uwStackSize = pstInitParam->uwStackSize; - pstTaskCB->pTaskSem = NULL; - pstTaskCB->pTaskMux = NULL; - pstTaskCB->usTaskStatus = OS_TASK_STATUS_SUSPEND; - pstTaskCB->usPriority = pstInitParam->usTaskPrio; - pstTaskCB->pfnTaskEntry = pstInitParam->pfnTaskEntry; - pstTaskCB->uwEvent.uwEventID = 0xFFFFFFFF; - pstTaskCB->uwEventMask = 0; - pstTaskCB->pcTaskName = pstInitParam->pcName; - pstTaskCB->puwMsg = NULL; -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) - /* Initialise this task's Newlib reent structure. */ - _REENT_INIT_PTR(&(pstTaskCB->stNewLibReent)); +#ifdef LOSCFG_KERNEL_CPUP + g_cpup[taskCB->taskID].id = taskCB->taskID; + g_cpup[taskCB->taskID].status = taskCB->taskStatus; #endif - *puwTaskID = uwTaskID; + *taskID = tempTaskID; return LOS_OK; +LOS_ERREND_REWIND_SYNC: + OsTaskSyncDestroy(taskCB); +LOS_ERREND_REWIND_TCB: + SCHEDULER_LOCK(intSave); + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); LOS_ERREND: - (VOID)LOS_IntRestore(uvIntSave); - return uwErrRet; + SCHEDULER_UNLOCK(intSave); + return errRet; } - -/***************************************************************************** - Function : LOS_TaskCreate - Description : Create a task - Input : pstInitParam --- Task init parameters - Output : puwTaskID --- Save task ID - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam) { - UINT32 uwRet = LOS_OK; - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB; + UINT32 ret; + UINT32 intSave; + LosTaskCB *taskCB = NULL; - uwRet = LOS_TaskCreateOnly(puwTaskID, pstInitParam); - if (LOS_OK != uwRet) - { - return uwRet; + ret = LOS_TaskCreateOnly(taskID, initParam); + if (ret != LOS_OK) { + return ret; } - pstTaskCB = OS_TCB_FROM_TID(*puwTaskID); + taskCB = OS_TCB_FROM_TID(*taskID); - uvIntSave = LOS_IntLock(); - pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_SUSPEND); - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_READY; + SCHEDULER_LOCK(intSave); -#if (LOSCFG_BASE_CORE_CPUP == YES) - g_pstCpup[pstTaskCB->uwTaskID].uwID = pstTaskCB->uwTaskID; - g_pstCpup[pstTaskCB->uwTaskID].usStatus = pstTaskCB->usTaskStatus; -#endif + taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPEND; + taskCB->taskStatus |= OS_TASK_STATUS_READY; + OsPriQueueEnqueue(&taskCB->pendList, taskCB->priority); - osPriqueueEnqueue(&pstTaskCB->stPendList, pstTaskCB->usPriority); - g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList); /*lint !e413*/ - - if ((g_bTaskScheduled) && (g_usLosTaskLock == 0)) - { - if (g_stLosTask.pstRunTask != g_stLosTask.pstNewTask) - { - if (LOS_CHECK_SCHEDULE) - { - (VOID)LOS_IntRestore(uvIntSave); - osSchedule(); - return LOS_OK; - } - } + SCHEDULER_UNLOCK(intSave); + + /* in case created task not running on this core, + schedule or not depends on other schedulers status. */ + if (OS_SCHEDULER_ACTIVE) { + LOS_Schedule(); } - (VOID)LOS_IntRestore(uvIntSave); return LOS_OK; } -/***************************************************************************** - Function : LOS_TaskResume - Description : Resume suspend task - Input : uwTaskID --- Task ID - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 uwTaskID) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) { - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB; - UINT16 usTempStatus; - UINT32 uwErrRet = OS_ERROR; + UINT32 intSave; + LosTaskCB *taskCB = NULL; + UINT16 tempStatus; + UINT32 errRet; + BOOL needSched = false; - if (uwTaskID > LOSCFG_BASE_CORE_TSK_LIMIT) - { + if (OS_TASK_ID_CHECK_INVALID(taskID)) { return LOS_ERRNO_TSK_ID_INVALID; } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - uvIntSave = LOS_IntLock(); - usTempStatus = pstTaskCB->usTaskStatus; + taskCB = OS_TCB_FROM_TID(taskID); + + SCHEDULER_LOCK(intSave); + + /* clear pending signal */ + taskCB->signal &= ~SIGNAL_SUSPEND; + + tempStatus = taskCB->taskStatus; - if (OS_TASK_STATUS_UNUSED & usTempStatus) - { - uwErrRet = LOS_ERRNO_TSK_NOT_CREATED; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + errRet = LOS_ERRNO_TSK_NOT_CREATED; OS_GOTO_ERREND(); - } - else if (!(OS_TASK_STATUS_SUSPEND & usTempStatus)) - { - uwErrRet = LOS_ERRNO_TSK_NOT_SUSPENDED; + } else if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) { + errRet = LOS_ERRNO_TSK_NOT_SUSPENDED; OS_GOTO_ERREND(); } - pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_SUSPEND); - if (!(OS_CHECK_TASK_BLOCK & pstTaskCB->usTaskStatus) ) - { - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_READY; - osPriqueueEnqueue(&pstTaskCB->stPendList, pstTaskCB->usPriority); - if (g_bTaskScheduled) - { - (VOID)LOS_IntRestore(uvIntSave); - LOS_Schedule(); - return LOS_OK; + 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 (OS_SCHEDULER_ACTIVE) { + needSched = TRUE; } - g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList); /*lint !e413*/ } - (VOID)LOS_IntRestore(uvIntSave); + SCHEDULER_UNLOCK(intSave); + + if (needSched) { + LOS_Schedule(); + } + return LOS_OK; LOS_ERREND: - (VOID)LOS_IntRestore(uvIntSave); - return uwErrRet; + SCHEDULER_UNLOCK(intSave); + return errRet; +} + +/* + * Check if needs to do the suspend operation on the running task. + * Return TRUE, if needs to do the suspension. + * Rerturn FALSE, if meets following circumstances: + * 1. Do the suspension when preemption is disabled + * 2. Do the suspension in hard-irq + * then LOS_TaskSuspend will directly return with 'ret' value. + */ +LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret) +{ + /* init default out return value */ + *ret = LOS_OK; + + if (!OsPreemptableInSched()) { + /* Suspending the current core's running task */ + *ret = LOS_ERRNO_TSK_SUSPEND_LOCKED; + return FALSE; + } + + if (OS_INT_ACTIVE) { + /* suspend running task in interrupt */ + taskCB->signal = SIGNAL_SUSPEND; + return FALSE; + } + + return TRUE; } -/***************************************************************************** - Function : LOS_TaskSuspend - Description : Suspend task - Input : uwTaskID --- Task ID - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 uwTaskID) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID) { - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB; - UINT16 usTempStatus; - UINT32 uwErrRet = OS_ERROR; - - CHECK_TASKID(uwTaskID); - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - uvIntSave = LOS_IntLock(); - usTempStatus = pstTaskCB->usTaskStatus; - if (OS_TASK_STATUS_UNUSED & usTempStatus) - { - uwErrRet = LOS_ERRNO_TSK_NOT_CREATED; + UINT32 intSave; + LosTaskCB *taskCB = NULL; + LosTaskCB *runTask = NULL; + UINT16 tempStatus; + UINT32 errRet; + + if (OS_TASK_ID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskFlags & OS_TASK_FLAG_SYSTEM) { + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; + } + + SCHEDULER_LOCK(intSave); + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + errRet = LOS_ERRNO_TSK_NOT_CREATED; OS_GOTO_ERREND(); } - if (OS_TASK_STATUS_SUSPEND & usTempStatus) - { - uwErrRet = LOS_ERRNO_TSK_ALREADY_SUSPENDED; + if (tempStatus & OS_TASK_STATUS_SUSPEND) { + errRet = LOS_ERRNO_TSK_ALREADY_SUSPENDED; OS_GOTO_ERREND(); } - if ((OS_TASK_STATUS_RUNNING & usTempStatus) && (g_usLosTaskLock != 0)) - { - uwErrRet = LOS_ERRNO_TSK_SUSPEND_LOCKED; + if ((tempStatus & OS_TASK_STATUS_RUNNING) && + !OsTaskSuspendCheckOnRun(taskCB, &errRet)) { OS_GOTO_ERREND(); } - if (OS_TASK_STATUS_READY & usTempStatus) - { - osPriqueueDequeue(&pstTaskCB->stPendList); - pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_READY); + if (tempStatus & OS_TASK_STATUS_READY) { + OsPriQueueDequeue(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; } - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_SUSPEND; - if (uwTaskID == g_stLosTask.pstRunTask->uwTaskID) - { - (VOID)LOS_IntRestore(uvIntSave); - LOS_Schedule(); - return LOS_OK; + taskCB->taskStatus |= OS_TASK_STATUS_SUSPEND; + + runTask = OsCurrTaskGet(); + if (taskID == runTask->taskID) { + OsSchedResched(); } - (VOID)LOS_IntRestore(uvIntSave); + SCHEDULER_UNLOCK(intSave); return LOS_OK; LOS_ERREND: - (VOID)LOS_IntRestore(uvIntSave); - return uwErrRet; + SCHEDULER_UNLOCK(intSave); + return errRet; } -/***************************************************************************** - Function : LOS_TaskDelete - Description : Delete a task - Input : uwTaskID --- Task ID - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 uwTaskID) +LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskDelAction(LosTaskCB *taskCB) { - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB; - UINT16 usTempStatus; - UINT32 uwErrRet = OS_ERROR; + VOID *pool = (VOID *)m_aucSysMem1; + LosTaskCB *runTask = NULL; + UINTPTR taskStack; + + if (OS_TASK_STATUS_RUNNING & taskCB->taskStatus) { + LOS_ListTailInsert(&g_taskRecyleList, &taskCB->pendList); + runTask = &g_taskCBArray[g_taskMaxNum]; + runTask->taskID = taskCB->taskID; + runTask->taskStatus = taskCB->taskStatus; + runTask->topOfStack = taskCB->topOfStack; + runTask->taskName = taskCB->taskName; + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + + return TRUE; + } else { + taskCB->taskStatus = OS_TASK_STATUS_UNUSED; + LOS_ListAdd(&g_losFreeTask, &taskCB->pendList); +#ifdef LOSCFG_TASK_STACK_PROTECT + taskStack = taskCB->topOfStack - MMU_4K; + OsTaskStackProtect(taskStack, MMU_4K, ACCESS_PERM_RW_RW); +#else + taskStack = taskCB->topOfStack; +#endif - CHECK_TASKID(uwTaskID); - uvIntSave = LOS_IntLock(); +#ifdef LOSCFG_EXC_INTERACTION + if (taskStack < (UINTPTR)m_aucSysMem1) { + pool = (VOID *)m_aucSysMem0; + } +#endif + (VOID)LOS_MemFree(pool, (VOID *)taskStack); + taskCB->topOfStack = 0; + return FALSE; + } +} - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); +/* + * Check if needs to do the delete operation on the running task. + * Return TRUE, if needs to do the deletion. + * Rerturn FALSE, if meets following circumstances: + * 1. Do the deletion when preemption is disabled + * 2. Do the deletion in hard-irq + * then LOS_TaskDelete will directly return with 'ret' value. + */ +LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskDeleteCheckOnRun(LosTaskCB *taskCB, UINT32 *ret) +{ + /* init default out return value */ + *ret = LOS_OK; - usTempStatus = pstTaskCB->usTaskStatus; + if (!OsPreemptableInSched()) { + /* If the task is running and scheduler is locked then you can not delete it */ + *ret = LOS_ERRNO_TSK_DELETE_LOCKED; + return FALSE; + } - if (OS_TASK_STATUS_UNUSED & usTempStatus) - { - uwErrRet = LOS_ERRNO_TSK_NOT_CREATED; - OS_GOTO_ERREND(); + if (OS_INT_ACTIVE) { + /* + * delete running task in interrupt. + * mask "kill" signal and later deletion will be handled. + */ + taskCB->signal = SIGNAL_KILL; + return FALSE; } - /* If the task is running and scheduler is locked then you can not delete it */ - if ((OS_TASK_STATUS_RUNNING & usTempStatus) && (g_usLosTaskLock != 0)) - { - PRINT_INFO("In case of task lock, task deletion is not recommended\n"); - g_usLosTaskLock = 0; + return TRUE; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID) +{ + UINT32 intSave, errRet; + UINT16 tempStatus; + LosTaskCB *taskCB = NULL; + + if (OS_TASK_ID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; + } + + taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskFlags & OS_TASK_FLAG_SYSTEM) { + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; } - if (OS_TASK_STATUS_READY & usTempStatus) - { - osPriqueueDequeue(&pstTaskCB->stPendList); - pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_READY); + SCHEDULER_LOCK(intSave); + + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + errRet = LOS_ERRNO_TSK_NOT_CREATED; + OS_GOTO_ERREND(); + } + if ((tempStatus & OS_TASK_STATUS_RUNNING) && + !OsTaskDeleteCheckOnRun(taskCB, &errRet)) { + OS_GOTO_ERREND(); } - else if ((OS_TASK_STATUS_PEND & usTempStatus) || (OS_TASK_STATUS_PEND_QUEUE & usTempStatus)) - { - LOS_ListDelete(&pstTaskCB->stPendList); + + if (tempStatus & OS_TASK_STATUS_READY) { + OsPriQueueDequeue(&taskCB->pendList); + taskCB->taskStatus &= ~OS_TASK_STATUS_READY; + } else if (tempStatus & OS_TASK_STATUS_PEND) { + LOS_ListDelete(&taskCB->pendList); } - if ((OS_TASK_STATUS_DELAY | OS_TASK_STATUS_TIMEOUT) & usTempStatus) - { - osTimerListDelete(pstTaskCB); + if (tempStatus & (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)) { + OsTimerListDelete(taskCB); } - pstTaskCB->usTaskStatus &= (~(OS_TASK_STATUS_SUSPEND)); - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_UNUSED; - pstTaskCB->uwEvent.uwEventID = 0xFFFFFFFF; - pstTaskCB->uwEventMask = 0; -#if (LOSCFG_BASE_CORE_CPUP == YES) - (VOID)memset((VOID *)&g_pstCpup[pstTaskCB->uwTaskID], 0, sizeof(OS_CPUP_S)); + taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPEND; + taskCB->taskStatus |= OS_TASK_STATUS_UNUSED; + taskCB->event.uwEventID = OS_INVALID_VALUE; + taskCB->eventMask = 0; + +#ifdef LOSCFG_KERNEL_CPUP + (VOID)memset_s((VOID *)&g_cpup[taskCB->taskID], sizeof(OsCpupCB), 0, sizeof(OsCpupCB)); #endif - g_stLosTask.pstNewTask = LOS_DL_LIST_ENTRY(osPriqueueTop(), LOS_TASK_CB, stPendList); /*lint !e413*/ - if (OS_TASK_STATUS_RUNNING & pstTaskCB->usTaskStatus) - { - LOS_ListTailInsert(&g_stTskRecyleList, &pstTaskCB->stPendList); - g_stLosTask.pstRunTask = &g_pstTaskCBArray[g_uwTskMaxNum]; - g_stLosTask.pstRunTask->uwTaskID = uwTaskID; - g_stLosTask.pstRunTask->usTaskStatus = pstTaskCB->usTaskStatus; - g_stLosTask.pstRunTask->uwTopOfStack = pstTaskCB->uwTopOfStack; - g_stLosTask.pstRunTask->pcTaskName = pstTaskCB->pcTaskName; - pstTaskCB->usTaskStatus = OS_TASK_STATUS_UNUSED; - (VOID)LOS_IntRestore(uvIntSave); - osSchedule(); - return LOS_OK; - } - else - { - pstTaskCB->usTaskStatus = OS_TASK_STATUS_UNUSED; - LOS_ListAdd(&g_stLosFreeTask, &pstTaskCB->stPendList); - (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)pstTaskCB->uwTopOfStack); - pstTaskCB->uwTopOfStack = (UINT32)NULL; - } - - (VOID)LOS_IntRestore(uvIntSave); + OS_MEM_CLEAR(taskID); + + OsTaskSyncWake(taskCB); + if (OsTaskDelAction(taskCB)) { + OsSchedResched(); + } + + SCHEDULER_UNLOCK(intSave); return LOS_OK; LOS_ERREND: - (VOID)LOS_IntRestore(uvIntSave); - return uwErrRet; + SCHEDULER_UNLOCK(intSave); + return errRet; } -/***************************************************************************** - Function : LOS_TaskDelay - Description : delay the current task - Input : uwTick --- time - Output :None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 uwTick) +LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick) { - UINTPTR uvIntSave; + UINT32 intSave; + LosTaskCB *runTask = NULL; - if (OS_INT_ACTIVE) - { + if (OS_INT_ACTIVE) { + PRINT_ERR("!!!LOS_ERRNO_TSK_DELAY_IN_INT!!!\n"); return LOS_ERRNO_TSK_DELAY_IN_INT; } - if (g_usLosTaskLock != 0) - { + runTask = OsCurrTaskGet(); + if (runTask->taskFlags & OS_TASK_FLAG_SYSTEM) { + OsBackTrace(); + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; + } + + if (!OsPreemptable()) { return LOS_ERRNO_TSK_DELAY_IN_LOCK; } - if (uwTick == 0) - { + if (tick == 0) { return LOS_TaskYield(); - } - else - { - uvIntSave = LOS_IntLock(); - osPriqueueDequeue(&(g_stLosTask.pstRunTask->stPendList)); - g_stLosTask.pstRunTask->usTaskStatus &= (~OS_TASK_STATUS_READY); - osTaskAdd2TimerList((LOS_TASK_CB *)g_stLosTask.pstRunTask, uwTick); - g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_DELAY; - (VOID)LOS_IntRestore(uvIntSave); - LOS_Schedule(); + } else { + SCHEDULER_LOCK(intSave); + OsTaskAdd2TimerList(runTask, tick); + runTask->taskStatus |= OS_TASK_STATUS_DELAY; + OsSchedResched(); + SCHEDULER_UNLOCK(intSave); } return LOS_OK; } -/***************************************************************************** - Function : LOS_TaskPriGet - Description : Get the priority of the task - Input : uwTaskID - Output : None - Return : TSK_PRIOR_T on success or OS_INVALID on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 uwTaskID) +LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID) { - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB; - UINT16 usPriority; + UINT32 intSave; + LosTaskCB *taskCB = NULL; + UINT16 priority; - if (OS_CHECK_TSK_PID_NOIDLE(uwTaskID)) - { - return (UINT16)OS_INVALID; + if (OS_TASK_ID_CHECK_INVALID(taskID)) { + return (UINT16)OS_INVALID; } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); + taskCB = OS_TCB_FROM_TID(taskID); - uvIntSave = LOS_IntLock(); - - if (OS_TASK_STATUS_UNUSED & pstTaskCB->usTaskStatus) - { - (VOID)LOS_IntRestore(uvIntSave); + SCHEDULER_LOCK(intSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); return (UINT16)OS_INVALID; } - usPriority = pstTaskCB->usPriority; - (VOID)LOS_IntRestore(uvIntSave); - return usPriority; + priority = taskCB->priority; + SCHEDULER_UNLOCK(intSave); + return priority; } -/***************************************************************************** - Function : LOS_TaskPriSet - Description : Set the priority of the task - Input : uwTaskID - usTaskPrio - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 uwTaskID, UINT16 usTaskPrio) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio) { - BOOL bIsReady; - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB; - UINT16 usTempStatus; + BOOL isReady = FALSE; + UINT32 intSave; + LosTaskCB *taskCB = NULL; + UINT16 tempStatus; - if (usTaskPrio > OS_TASK_PRIORITY_LOWEST) - { + if (taskPrio > OS_TASK_PRIORITY_LOWEST) { return LOS_ERRNO_TSK_PRIOR_ERROR; } - if (uwTaskID == g_uwIdleTaskID) - { - return LOS_ERRNO_TSK_OPERATE_IDLE; + if (OS_TASK_ID_CHECK_INVALID(taskID)) { + return LOS_ERRNO_TSK_ID_INVALID; } - if (uwTaskID == g_uwSwtmrTaskID) - { - return LOS_ERRNO_TSK_OPERATE_SWTMR; + taskCB = OS_TCB_FROM_TID(taskID); + if (taskCB->taskFlags & OS_TASK_FLAG_SYSTEM) { + return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK; } - if (OS_CHECK_TSK_PID_NOIDLE(uwTaskID)) - { - return LOS_ERRNO_TSK_ID_INVALID; - } + SCHEDULER_LOCK(intSave); - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - uvIntSave = LOS_IntLock(); - usTempStatus = pstTaskCB->usTaskStatus; - if (OS_TASK_STATUS_UNUSED & usTempStatus) - { - (VOID)LOS_IntRestore(uvIntSave); + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_TSK_NOT_CREATED; } /* delete the task and insert with right priority into ready queue */ - bIsReady = (OS_TASK_STATUS_READY & usTempStatus); - if (bIsReady) - { - osPriqueueDequeue(&pstTaskCB->stPendList); - pstTaskCB->usTaskStatus &= (~OS_TASK_STATUS_READY); - pstTaskCB->usPriority = usTaskPrio; - pstTaskCB->usTaskStatus |= OS_TASK_STATUS_READY; - osPriqueueEnqueue(&pstTaskCB->stPendList, pstTaskCB->usPriority); - } - else - { - pstTaskCB->usPriority = usTaskPrio; + isReady = tempStatus & OS_TASK_STATUS_READY; + if (isReady) { + OsPriQueueDequeue(&taskCB->pendList); + taskCB->priority = taskPrio; + OsPriQueueEnqueue(&taskCB->pendList, taskCB->priority); + } else { + taskCB->priority = taskPrio; + if (tempStatus & OS_TASK_STATUS_RUNNING) { + isReady = TRUE; + } } - - (VOID)LOS_IntRestore(uvIntSave); + SCHEDULER_UNLOCK(intSave); /* delete the task and insert with right priority into ready queue */ - if (bIsReady) - { + if (isReady) { LOS_Schedule(); } - return LOS_OK; } -/***************************************************************************** - Function : LOS_CurTaskPriSet - Description : Set the priority of the current task - Input : usTaskPrio - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 usTaskPrio) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio) { - UINT32 uwRet; - uwRet = LOS_TaskPriSet(g_stLosTask.pstRunTask->uwTaskID, usTaskPrio); - return uwRet; + UINT32 ret; + ret = LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio); + return ret; } -/************************************************************************** - Function : osTaskWait - Description : pend a task in pstList - Input : pstList - uwTimeOut -- Expiry time - Output : none - Return : LOS_OK on success or LOS_NOK on failure -**************************************************************************/ -LITE_OS_SEC_TEXT VOID osTaskWait(LOS_DL_LIST *pstList, UINT32 uwTaskStatus, UINT32 uwTimeOut) +/* + * Description : pend a task in list + * Input : list --- wait task list + * taskStatus --- task status + * timeOut --- Expiry time + * Return : LOS_OK on success or LOS_NOK on failure + */ +VOID OsTaskWait(LOS_DL_LIST *list, UINT16 taskStatus, UINT32 timeout) { - LOS_TASK_CB *pstRunTsk; - LOS_DL_LIST *pstPendObj; - - pstRunTsk = g_stLosTask.pstRunTask; - osPriqueueDequeue(&pstRunTsk->stPendList); - pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_READY); - pstPendObj = &pstRunTsk->stPendList; - pstRunTsk->usTaskStatus |= uwTaskStatus; - LOS_ListTailInsert(pstList,pstPendObj); - if (uwTimeOut != LOS_WAIT_FOREVER) - { - pstRunTsk->usTaskStatus |= OS_TASK_STATUS_TIMEOUT; - osTaskAdd2TimerList((LOS_TASK_CB *)pstRunTsk, uwTimeOut); + LosTaskCB *runTask = NULL; + LOS_DL_LIST *pendObj = NULL; + + runTask = OsCurrTaskGet(); + runTask->taskStatus &= ~OS_TASK_STATUS_READY; + pendObj = &runTask->pendList; + runTask->taskStatus |= taskStatus; + LOS_ListTailInsert(list, pendObj); + if (timeout != LOS_WAIT_FOREVER) { + runTask->taskStatus |= OS_TASK_STATUS_PEND_TIME; + OsTaskAdd2TimerList((LosTaskCB *)runTask, timeout); } } -/************************************************************************** - Function : osTaskWake - Description : delete the task from pendlist and also add to the priqueue - Input : pstResumedTask --> resumed task - Output : pstResumedTask - Return : none -**************************************************************************/ -LITE_OS_SEC_TEXT VOID osTaskWake(LOS_TASK_CB *pstResumedTask, UINT32 uwTaskStatus) +/* + * Description : delete the task from pendlist and also add to the priqueue + * Input : resumedTask --- resumed task + * taskStatus --- task status + */ +VOID OsTaskWake(LosTaskCB *resumedTask, UINT16 taskStatus) { - LOS_ListDelete(&pstResumedTask->stPendList); - pstResumedTask->usTaskStatus &= (~uwTaskStatus); - if (pstResumedTask->usTaskStatus & OS_TASK_STATUS_TIMEOUT) - { - osTimerListDelete(pstResumedTask); - pstResumedTask->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); - } - if (!(pstResumedTask->usTaskStatus & OS_TASK_STATUS_SUSPEND)) - { - pstResumedTask->usTaskStatus |= OS_TASK_STATUS_READY; - osPriqueueEnqueue(&pstResumedTask->stPendList, pstResumedTask->usPriority); + LOS_ListDelete(&resumedTask->pendList); + resumedTask->taskStatus &= ~taskStatus; + + if (resumedTask->taskStatus & OS_TASK_STATUS_PEND_TIME) { + OsTimerListDelete(resumedTask); + resumedTask->taskStatus &= ~OS_TASK_STATUS_PEND_TIME; + } + 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 : usTaskPrio - uwNextTask - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) { - UINT32 uwTskCount = 0; - UINTPTR uvIntSave; + UINT32 tskCount; + UINT32 intSave; + LosTaskCB *runTask = NULL; + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_TSK_YIELD_IN_INT; + } + + if (!OsPreemptable()) { + return LOS_ERRNO_TSK_YIELD_IN_LOCK; + } - if(g_stLosTask.pstRunTask->uwTaskID >= g_uwTskMaxNum) - { + runTask = OsCurrTaskGet(); + if (runTask->taskID >= g_taskMaxNum) { return LOS_ERRNO_TSK_ID_INVALID; } - if(!(g_stLosTask.pstRunTask->usTaskStatus & OS_TASK_STATUS_READY)) - { - return LOS_OK; - } - uvIntSave = LOS_IntLock(); - uwTskCount = osPriqueueSize(g_stLosTask.pstRunTask->usPriority); - if (uwTskCount > 1) - { - LOS_ListDelete(&(g_stLosTask.pstRunTask->stPendList)); - g_stLosTask.pstRunTask->usTaskStatus |= OS_TASK_STATUS_READY; - osPriqueueEnqueue(&(g_stLosTask.pstRunTask->stPendList), g_stLosTask.pstRunTask->usPriority); - } - else - { - (VOID)LOS_IntRestore(uvIntSave); + + SCHEDULER_LOCK(intSave); + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + /* reset timeslice of yeilded task */ + runTask->timeSlice = 0; +#endif + + tskCount = OsPriQueueSize(runTask->priority); + if (tskCount > 0) { + runTask->taskStatus |= OS_TASK_STATUS_READY; + OsPriQueueEnqueue(&(runTask->pendList), runTask->priority); + } else { + SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK; } - - (VOID)LOS_IntRestore(uvIntSave); - LOS_Schedule(); + OsSchedResched(); + SCHEDULER_UNLOCK(intSave); 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 uvIntSave; + UINT32 intSave; + UINT32 *losTaskLock = NULL; - uvIntSave = LOS_IntLock(); - g_usLosTaskLock++; - (VOID)LOS_IntRestore(uvIntSave); + intSave = LOS_IntLock(); + losTaskLock = &OsPercpuGet()->taskLockCnt; + (*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 uvIntSave; - - uvIntSave = LOS_IntLock(); - if (g_usLosTaskLock > 0) - { - g_usLosTaskLock--; - if (0 == g_usLosTaskLock) - { - (VOID)LOS_IntRestore(uvIntSave); + UINT32 intSave; + UINT32 *losTaskLock = NULL; + Percpu *percpu = NULL; + + intSave = LOS_IntLock(); + + percpu = OsPercpuGet(); + losTaskLock = &OsPercpuGet()->taskLockCnt; + if (*losTaskLock > 0) { + (*losTaskLock)--; + if ((*losTaskLock == 0) && (percpu->schedFlag == INT_PEND_RESCH) && + OS_SCHEDULER_ACTIVE) { + percpu->schedFlag = INT_NO_RESCH; + LOS_IntRestore(intSave); LOS_Schedule(); return; } } - (VOID)LOS_IntRestore(uvIntSave); + LOS_IntRestore(intSave); } -/***************************************************************************** - Function : LOS_TaskInfoGet - Description : Get the information of the task - Input : uwTaskID - Output : pstTaskInfo - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 uwTaskID, TSK_INFO_S *pstTaskInfo) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo) { - UINT32 uwIntSave; - LOS_TASK_CB *pstTaskCB; - UINT32 * puwStack; + UINT32 intSave; + LosTaskCB *taskCB = NULL; - if (NULL == pstTaskInfo) - { + if (taskInfo == NULL) { return LOS_ERRNO_TSK_PTR_NULL; } - if (OS_CHECK_TSK_PID_NOIDLE(uwTaskID)) - { + if (OS_TASK_ID_CHECK_INVALID(taskID)) { return LOS_ERRNO_TSK_ID_INVALID; } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - uwIntSave = LOS_IntLock(); + taskCB = OS_TCB_FROM_TID(taskID); + SCHEDULER_LOCK(intSave); - if (OS_TASK_STATUS_UNUSED & pstTaskCB->usTaskStatus) - { - (VOID)LOS_IntRestore(uwIntSave); + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_TSK_NOT_CREATED; } - pstTaskInfo->uwSP = (UINT32)pstTaskCB->pStackPointer; - pstTaskInfo->usTaskStatus = pstTaskCB->usTaskStatus; - pstTaskInfo->usTaskPrio = pstTaskCB->usPriority; - pstTaskInfo->uwStackSize = pstTaskCB->uwStackSize; - pstTaskInfo->uwTopOfStack = pstTaskCB->uwTopOfStack; - pstTaskInfo->uwEvent = pstTaskCB->uwEvent; - pstTaskInfo->uwEventMask = pstTaskCB->uwEventMask; - pstTaskInfo->uwSemID = pstTaskCB->pTaskSem != NULL ? ((SEM_CB_S *)(pstTaskCB->pTaskSem))->usSemID : LOSCFG_BASE_IPC_SEM_LIMIT; - pstTaskInfo->uwMuxID = pstTaskCB->pTaskMux != NULL ? ((MUX_CB_S *)(pstTaskCB->pTaskMux))->ucMuxID : LOSCFG_BASE_IPC_MUX_LIMIT; - pstTaskInfo->pTaskSem = pstTaskCB->pTaskSem; - pstTaskInfo->pTaskMux = pstTaskCB->pTaskMux; - pstTaskInfo->uwTaskID = uwTaskID; - - (VOID)strncpy(pstTaskInfo->acName, pstTaskCB->pcTaskName, LOS_TASK_NAMELEN - 1); - pstTaskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0'; - - pstTaskInfo->uwBottomOfStack = TRUNCATE(((UINT32)(pstTaskCB->uwTopOfStack) + (pstTaskCB->uwStackSize)), OS_TASK_STACK_ADDR_ALIGN); - pstTaskInfo->uwCurrUsed = pstTaskInfo->uwBottomOfStack - pstTaskInfo->uwSP; - - if (OS_TASK_MAGIC_WORD == *(UINT32 *)pstTaskInfo->uwTopOfStack) - { - puwStack = (UINT32 *)(pstTaskInfo->uwTopOfStack + 4); - while ((puwStack < (UINT32 *)pstTaskInfo->uwSP) && (*puwStack == 0xCACACACA)) - { - puwStack += 1; - } - - pstTaskInfo->uwPeakUsed = pstTaskCB->uwStackSize - ((UINT32)puwStack - pstTaskInfo->uwTopOfStack); - pstTaskInfo->bOvf = FALSE; - } - else - { - pstTaskInfo->uwPeakUsed = 0xFFFFFFFF; - pstTaskInfo->bOvf = TRUE; - } - - (VOID)LOS_IntRestore(uwIntSave); - - return LOS_OK; -} - -/***************************************************************************** - Function : LOS_TaskStatusGet - Description : Get status of the task - Input : uwTaskID - Output : puwTaskStatus - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskStatusGet(UINT32 uwTaskID, UINT32 *puwTaskStatus) -{ - UINT32 uwIntSave; - LOS_TASK_CB *pstTaskCB; - - if (NULL == puwTaskStatus) - { - return LOS_ERRNO_TSK_PTR_NULL; - } - - if (OS_CHECK_TSK_PID_NOIDLE(uwTaskID)) - { - return LOS_ERRNO_TSK_ID_INVALID; + if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING) || OS_INT_ACTIVE) { + taskInfo->uwSP = (UINTPTR)taskCB->stackPointer; + } else { + taskInfo->uwSP = ArchSPGet(); } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - uwIntSave = LOS_IntLock(); + 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->pTaskSem = taskCB->taskSem; + taskInfo->pTaskMux = taskCB->taskMux; + taskInfo->uwTaskID = taskID; - if (OS_TASK_STATUS_UNUSED & pstTaskCB->usTaskStatus) - { - (VOID)LOS_IntRestore(uwIntSave); - return LOS_ERRNO_TSK_NOT_CREATED; + if (strncpy_s(taskInfo->acName, LOS_TASK_NAMELEN, taskCB->taskName, LOS_TASK_NAMELEN - 1) != EOK) { + PRINT_ERR("Task name copy failed!\n"); } + taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0'; - *puwTaskStatus = pstTaskCB->usTaskStatus; + taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize), + OS_TASK_STACK_ADDR_ALIGN); + taskInfo->uwCurrUsed = taskInfo->uwBottomOfStack - taskInfo->uwSP; - (VOID)LOS_IntRestore(uwIntSave); + taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack, + (const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed); + SCHEDULER_UNLOCK(intSave); return LOS_OK; } -#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == YES) -/***************************************************************************** - Function : LOS_TaskSwitchInfoGet - Description : save the information of the task switch - Input : uwIdx - Output : pTaskSwitchInfo - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskSwitchInfoGet(UINT32 uwIdx, UINT32 *puwTaskSwitchInfo) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMask) { - UINTPTR uvIntSave; - - if (uwIdx >= OS_TASK_SWITCH_INFO_COUNT) - { - uwIdx -= OS_TASK_SWITCH_INFO_COUNT; - } - - if (NULL == puwTaskSwitchInfo) - { - return LOS_ERRNO_TSK_PTR_NULL; - } - - uvIntSave = LOS_IntLock(); - - (*puwTaskSwitchInfo) = g_astTskSwitchInfo.auwPID[uwIdx]; - memcpy((VOID *)(puwTaskSwitchInfo + 1), g_astTskSwitchInfo.acName[uwIdx], LOS_TASK_NAMELEN); - - (VOID)LOS_IntRestore(uvIntSave); + (VOID)taskID; + (VOID)cpuAffiMask; 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) +LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) { - UINT32 uwRet; - - uwRet = osGetAllTskInfo(); - - return uwRet; -} - -/***************************************************************************** - 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_bTaskScheduled; + (VOID)taskID; + return 1; } -/***************************************************************************** - 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) +/* + * Description : Process pending signals tagged by others cores + */ +LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskProcSignal(VOID) { - if (NULL == g_stLosTask.pstNewTask) - { - return LOS_ERRNO_TSK_ID_INVALID; - } - return g_stLosTask.pstNewTask->uwTaskID; -} - -/***************************************************************************** - Function : LOS_TaskNameGet - Description : get Name of current new task. - Input : uwTaskID -----task id - Output : None - Return : task name - *****************************************************************************/ -LITE_OS_SEC_TEXT CHAR* LOS_TaskNameGet(UINT32 uwTaskID) -{ - UINT32 uwIntSave; - LOS_TASK_CB *pstTaskCB; + Percpu *percpu = NULL; + LosTaskCB *runTask = NULL; + UINT32 ret; + + /* + * private and uninterruptable, no protection needed. + * while this task is always running when others cores see it, + * so it keeps recieving signals while follow code excuting. + */ + runTask = OsCurrTaskGet(); + if (runTask->signal == SIGNAL_NONE) { + goto EXIT; + } + + if (runTask->signal & SIGNAL_KILL) { + /* + * clear the signal, and do the task deletion. if the signaled task has been + * scheduled out, then this deletion will wait until next run. + */ + runTask->signal = SIGNAL_NONE; + ret = LOS_TaskDelete(runTask->taskID); + if (ret) { + PRINT_ERR("%s proc task delete failed err:0x%x\n", __FUNCTION__, ret); + } + } else if (runTask->signal & SIGNAL_SUSPEND) { + runTask->signal &= ~SIGNAL_SUSPEND; - if (OS_CHECK_TSK_PID_NOIDLE(uwTaskID)) - { - return NULL; + /* suspend killed task may fail, ignore the result */ + (VOID)LOS_TaskSuspend(runTask->taskID); } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - - uwIntSave = LOS_IntLock(); - if (OS_TASK_STATUS_UNUSED & pstTaskCB->usTaskStatus) - { - (VOID)LOS_IntRestore(uwIntSave); - return NULL; +EXIT: + /* check if needs to schedule */ + percpu = OsPercpuGet(); + if (OsPreemptable() && (percpu->schedFlag == INT_PEND_RESCH)) { + percpu->schedFlag = INT_NO_RESCH; + return INT_PEND_RESCH; } - (VOID)LOS_IntRestore(uwIntSave); - - return pstTaskCB->pcTaskName; -} -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) -/***************************************************************************** - Function : osTaskSwitchImpurePtr - Description : Switch Newlib's _impure_ptr to point to the next run task. - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osTaskSwitchImpurePtr(VOID) -{ - /* Switch Newlib's _impure_ptr variable to point to the _reent - structure specific to next run task. */ - _impure_ptr = &(g_stLosTask.pstNewTask->stNewLibReent); + return INT_NO_RESCH; } -#endif #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ #endif /* __cplusplus */ - diff --git a/kernel/base/core/los_task.inc b/kernel/base/core/los_task.inc deleted file mode 100644 index b8286503c..000000000 --- a/kernel/base/core/los_task.inc +++ /dev/null @@ -1,192 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_TASK_INC -#define _LOS_TASK_INC - -#include "los_task.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -#define EVALUATE_L(UWNUM, VALUE) \ - UWNUM = (((UWNUM) & 0xf8000000) | (VALUE)) - -#define EVALUATE_H(UWNUM, VALUE) \ - UWNUM = (((UWNUM) & 0x07ffffff)| ((VALUE) << 27)) - -#define UWROLLNUMSUB(UWNUM1,UWNUM2) \ - UWNUM1 = ((UWNUM1 & 0xf8000000) | (UWROLLNUM(UWNUM1) - UWROLLNUM(UWNUM2))) - -#define UWROLLNUMADD(UWNUM1,UWNUM2) \ - UWNUM1 = ((UWNUM1 & 0xf8000000) | (UWROLLNUM(UWNUM1) + UWROLLNUM(UWNUM2))) - -#define UWROLLNUM(UWNUM) ((UWNUM) & 0x07ffffff) - -#define UWSORTINDEX(UWNUM) (UWNUM >> 27) - -#define UWROLLNUMDEC(UWNUM) \ - UWNUM = (UWNUM - 1) - -#define OS_TSK_SORTLINK_LEN 32 -#define OS_TSK_SORTLINK_LOGLEN 5 -#define OS_TSK_SORTLINK_MASK (OS_TSK_SORTLINK_LEN - 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)) - -#define OS_TASK_ID_CHECK(uwTaskID) LOS_ASSERT_COND(OS_TSK_GET_INDEX(uwTaskID) < g_uwTskMaxNum) -#define OS_CHECK_TSK_PID_NOIDLE(uwTaskID) (OS_TSK_GET_INDEX(uwTaskID) >= g_uwTskMaxNum) - -typedef struct tagTskSortLinkAttr -{ - LOS_DL_LIST *pstSortLink; - UINT16 usCursor; - UINT16 usUnUsed; -} TSK_SORTLINK_ATTRIBUTE_S; - -/** - * @ingroup los_task - * Task stack information structure. - * - */ -typedef struct tagStackInfo -{ - UINT32 uwTop; /** - *
  • The pstTaskCB should be a correct pointer to task control block structure.
  • - *
- * - * @param pstTaskCB [IN] Type #LOS_TASK_CB * pointer to task control block structure. - * @param uwTimeout [IN] Type #UINT32 wait time, ticks. - * - * @retval None. - * @par Dependency: - *
  • los_task.inc: the header file that contains the API declaration.
- * @see osTimerListDelete - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskAdd2TimerList(LOS_TASK_CB *pstTaskCB, UINT32 uwTimeout); - -/** - * @ingroup los_task - * @brief delete task from sorted delay list. - * - * @par Description: - * This API is used to delete task from sorted delay list. - * - * @attention - *
    - *
  • The pstTaskCB should be a correct pointer to task control block structure.
  • - *
- * - * @param pstTaskCB [IN] Type #LOS_TASK_CB * pointer to task control block structure. - * - * @retval None. - * @par Dependency: - *
  • los_task.inc: the header file that contains the API declaration.
- * @see osTaskAdd2TimerList - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTimerListDelete(LOS_TASK_CB *pstTaskCB); - -/** - * @ingroup los_task - * @brief Convert task status to string. - * - * @par Description: - * This API is used to convert task status to string. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param usTaskStatus [IN] Type #UINT16 task status. - * - * @retval UINT8 * String. - * @par Dependency: - *
  • los_task.inc: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT8 *osConvertTskStatus(UINT16 usTaskStatus); - -/** - * @ingroup los_task - * @brief Get all task information. - * - * @par Description: - * This API is used to get all task information. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param None. - * - * @retval UINT32 All task information. - * @par Dependency: - *
  • los_task.inc: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osGetAllTskInfo(VOID); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_TASK_INC */ diff --git a/kernel/base/core/los_tick.c b/kernel/base/core/los_tick.c index cfb9abe81..362b72fbe 100644 --- a/kernel/base/core/los_tick.c +++ b/kernel/base/core/los_tick.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tick * 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 @@ -22,23 +22,22 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_tick.inc" -#include "los_base.ph" -#include "los_swtmr.ph" -#include "los_task.ph" -#include "los_timeslice.ph" -#if (LOSCFG_KERNEL_TICKLESS == YES) -#include "los_tickless.ph" + * --------------------------------------------------------------------------- */ + +#include "los_tick_pri.h" +#include "los_swtmr_pri.h" +#include "los_task_pri.h" +#include "los_timeslice_pri.h" +#ifdef LOSCFG_KERNEL_TICKLESS +#include "los_tickless_pri.h" #endif #ifdef __cplusplus @@ -47,91 +46,44 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +LITE_OS_SEC_BSS volatile UINT64 g_tickCount[LOSCFG_KERNEL_CORE_NUM] = {0}; +LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; +LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; +LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; -LITE_OS_SEC_BSS UINT64 g_ullTickCount; -LITE_OS_SEC_BSS UINT32 g_uwTicksPerSec; -LITE_OS_SEC_BSS UINT32 g_uwCyclePerSec; -LITE_OS_SEC_BSS UINT32 g_uwCyclesPerTick; -LITE_OS_SEC_BSS UINT32 g_uwSysClock; -LITE_OS_SEC_DATA_INIT BOOL g_bSysTickStart = FALSE; +/* spinlock for task module */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); -#if (LOSCFG_KERNEL_TICKLESS == YES) -/***************************************************************************** - Description : Tick interruption handler - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osTickHandlerLoop(UINT32 uwElapseTicks) +/* + * Description : Tick interruption handler + */ +LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) { - UINT32 uwIndex; - - for (uwIndex = 0; uwIndex < uwElapseTicks; uwIndex++) - { -#if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES) - platform_tick_handler(); -#endif - - g_ullTickCount ++; + UINT32 intSave; -#if(LOSCFG_BASE_CORE_TIMESLICE == YES) - osTimesliceCheck(); -#endif - osTaskScan(); //task timeout scan -#if (LOSCFG_BASE_CORE_SWTMR == YES) - (VOID)osSwtmrScan(); -#endif - } -} + TICK_LOCK(intSave); + g_tickCount[ArchCurrCpuid()]++; + TICK_UNLOCK(intSave); -#endif - -/***************************************************************************** - Description : Tick interruption handler - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osTickHandler(VOID) -{ -#if (LOSCFG_KERNEL_TICKLESS == YES) - if (g_bReloadSysTickFlag) - { - LOS_SysTickReload(OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND); - g_bReloadSysTickFlag = 0; - } - g_bTickIrqFlag = g_bTicklessFlag; - - #if (LOSCFG_PLATFORM_HWI == NO) - if (g_uwSysTickIntFlag == TICKLESS_OS_TICK_INT_WAIT) - { - g_uwSysTickIntFlag = TICKLESS_OS_TICK_INT_SET; - } - #endif +#ifdef LOSCFG_KERNEL_TICKLESS + OsTickIrqFlagSet(OsTicklessFlagGet()); #endif #if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES) - platform_tick_handler(); + HalClockIrqClear(); /* diff from every platform */ #endif - g_ullTickCount ++; - -#if(LOSCFG_BASE_CORE_TIMESLICE == YES) - osTimesliceCheck(); +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + OsTimesliceCheck(); #endif - osTaskScan(); //task timeout scan + OsTaskScan(); /* task timeout scan */ #if (LOSCFG_BASE_CORE_SWTMR == YES) - (VOID)osSwtmrScan(); + OsSwtmrScan(); #endif } -LITE_OS_SEC_TEXT UINT32 LOS_SysClockGet(void) -{ - return g_uwSysClock; -} - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/base/core/los_timeslice.c b/kernel/base/core/los_timeslice.c index 846a94998..833a16756 100644 --- a/kernel/base/core/los_timeslice.c +++ b/kernel/base/core/los_timeslice.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Timeslice * 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 @@ -22,21 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_sys.ph" -#include "los_task.ph" -#include "los_tick.ph" -#include "los_typedef.ph" -#include "los_timeslice.ph" +#include "los_timeslice_pri.h" +#include "los_task_pri.h" #ifdef __cplusplus #if __cplusplus @@ -44,45 +41,16 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#if(LOSCFG_BASE_CORE_TIMESLICE == YES) -LITE_OS_SEC_BSS OS_TASK_ROBIN_S g_stTaskTimeSlice; - -/***************************************************************************** - Function : osTimesliceInit - Description : Initialztion Timeslice - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT VOID osTimesliceInit(VOID) -{ - g_stTaskTimeSlice.pstTask = (LOS_TASK_CB *)NULL; - g_stTaskTimeSlice.usTout = LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT; -} - -/***************************************************************************** - Function : osTimesliceCheck - Description : check Timeslice - Input : None - Output : None - Return : None - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID osTimesliceCheck(VOID) +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) +LITE_OS_SEC_TEXT VOID OsTimesliceCheck(VOID) { - if (g_stTaskTimeSlice.pstTask != g_stLosTask.pstRunTask) - { - g_stTaskTimeSlice.pstTask = g_stLosTask.pstRunTask; - g_stTaskTimeSlice.usTime = (UINT16)g_ullTickCount + g_stTaskTimeSlice.usTout - 1; - } - - if (g_stTaskTimeSlice.usTime == (UINT16)g_ullTickCount) - { - g_stTaskTimeSlice.pstTask = (LOS_TASK_CB *)NULL; - if (LOS_TaskYield() != LOS_OK) - { - PRINT_INFO("%s, %d\n", __FUNCTION__, __LINE__); + LosTaskCB *runTask = OsCurrTaskGet(); + if (runTask->timeSlice != 0) { + runTask->timeSlice--; + if (runTask->timeSlice == 0) { + LOS_Schedule(); } - } /*lint !e548*/ + } } #endif diff --git a/kernel/base/include/los_printf.ph b/kernel/base/include/los_base_pri.h similarity index 76% rename from kernel/base/include/los_printf.ph rename to kernel/base/include/los_base_pri.h index 985fd3643..febf3f096 100644 --- a/kernel/base/include/los_printf.ph +++ b/kernel/base/include/los_base_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Basic definitions * 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 @@ -22,20 +22,20 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_PRINTF_PH -#define _LOS_PRINTF_PH +#ifndef _LOS_BASE_PRI_H +#define _LOS_BASE_PRI_H -#include "los_printf.h" +#include "los_base.h" #ifdef __cplusplus #if __cplusplus @@ -43,10 +43,9 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - -VOID _dprintf(const char *fmt, va_list ap); -int __dprintf(const char *fmt, va_list ap, VOID (*uart_fputc)(unsigned n, VOID *cookie), char *cookie); - +#define OS_GOTO_ERREND() do { \ + goto LOS_ERREND; \ +} while (0) #ifdef __cplusplus #if __cplusplus @@ -54,4 +53,4 @@ int __dprintf(const char *fmt, va_list ap, VOID (*uart_fputc)(unsigned n, VOID * #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* _LOS_PRINTF_PH */ +#endif /* _LOS_BASE_PRI_H */ diff --git a/kernel/base/include/los_binarytree_pri.h b/kernel/base/include/los_binarytree_pri.h new file mode 100644 index 000000000..067815f19 --- /dev/null +++ b/kernel/base/include/los_binarytree_pri.h @@ -0,0 +1,113 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: BinaryTree Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_BINARYTREE_PRI_H +#define _LOS_BINARYTREE_PRI_H + +#include "los_typedef.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct tagBinNode { + struct tagBinNode *left; + struct tagBinNode *right; + UINT32 nodeID; + CHAR keyValue[0]; +} BinNode; + +typedef struct { + BinNode leaf; + UINTPTR linkReg1; + UINTPTR linkReg2; + UINTPTR linkReg3; +} LinkRegNode; + +#define LR_COUNT 4096 +extern LinkRegNode g_linkRegNode[LR_COUNT]; +extern UINT32 g_linkRegNodeIndex; +extern LinkRegNode *g_linkRegRoot; + +typedef struct { + BinNode leaf; + UINTPTR addr; +} AddrNode; + +#define ADDR_COUNT 40960 +extern AddrNode g_addrNode[ADDR_COUNT]; +extern UINT32 g_addrNodeIndex; +extern AddrNode *g_addrRoot; + +typedef struct { + BinNode leaf; + UINT32 reqSize; +} ReqSizeNode; + +#define REQ_SIZE_COUNT 4096 +extern ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT]; +extern UINT32 g_reqSizeNodeIndex; +extern ReqSizeNode *g_reqSizeRoot; + +typedef struct { + BinNode leaf; + UINT32 taskID; +} TaskIDNode; + +#define TASK_ID_COUNT 1024 + +extern UINT32 OsBinTreeInsert(const VOID *node, UINT32 nodeLen, BinNode **leaf, + BinNode *(*GetMyBinNode)(UINT32 *nodeID), + INT32 (*CompareNode)(const VOID *node1, const VOID *node2)); + +extern INT32 OsCompareLRNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetLRBinNode(UINT32 *nodeID); + +extern INT32 OsCompareAddrNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetAddrBinNode(UINT32 *nodeID); + +extern INT32 OsCompareReqSizeNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetReqSizeBinNode(UINT32 *nodeID); + +extern INT32 OsCompareTaskIDNode(const VOID *node1, const VOID *node2); +extern BinNode *OsGetTaskIDBinNode(UINT32 *nodeID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BINARYTREE_PRI_H */ diff --git a/kernel/base/include/los_err.ph b/kernel/base/include/los_err.ph deleted file mode 100644 index 1be81d3d9..000000000 --- a/kernel/base/include/los_err.ph +++ /dev/null @@ -1,140 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_ERR_PH -#define _LOS_ERR_PH - -#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 - *
    - *
  • None.
  • - *
- * - *@param uwErrNo [IN] Error code. - * - *@retval uwErrNo - *@par Dependency: - *
  • los_err.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -#define OS_RETURN_ERROR(uwErrNo) \ - do \ - { \ - (VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, uwErrNo, 0, NULL); \ - return uwErrNo; \ - } 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 - *
    - *
  • None.
  • - *
- * - *@param uwErrLine [IN] Line number of the erroneous line. - *@param uwErrNo [IN] Error code. - * - *@retval uwErrNo - *@par Dependency: - *
  • los_err.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -#define OS_RETURN_ERROR_P2(uwErrLine, uwErrNo) \ - do \ - { \ - (VOID)LOS_ErrHandle("os_unspecific_file", uwErrLine, uwErrNo, 0, NULL); \ - return uwErrNo; \ - } 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 - *
    - *
  • None.
  • - *
- * - *@param uwErrorNo [IN] Error code. - * - *@retval None. - *@par Dependency: - *
  • los_err.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -#define OS_GOTO_ERR_HANDLER(uwErrorNo) \ - do \ - { \ - uwErrNo = uwErrorNo; \ - uwErrLine = OS_ERR_MAGIC_WORD; \ - goto ErrHandler; \ - } while (0) - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_ERR_PH */ diff --git a/kernel/base/include/los_err_pri.h b/kernel/base/include/los_err_pri.h new file mode 100644 index 000000000..376ba603c --- /dev/null +++ b/kernel/base/include/los_err_pri.h @@ -0,0 +1,133 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Error Handling Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#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 + *
    + *
  • None.
  • + *
+ * + * @param errNo [IN] Error code. + * + * @retval errNo + * @par Dependency: + *
  • los_err_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS V100R001C00 + */ +#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 + *
    + *
  • None.
  • + *
+ * + * @param errLine [IN] Line number of the erroneous line. + * @param errNo [IN] Error code. + * + * @retval errNo + * @par Dependency: + *
  • los_err_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS V100R001C00 + */ +#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 + *
    + *
  • None.
  • + *
+ * + * @param errorNo [IN] Error code. + * + * @retval None. + * @par Dependency: + *
  • los_err_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS V100R001C00 + */ +#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 100644 index 000000000..a89211f44 --- /dev/null +++ b/kernel/base/include/los_event_pri.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Event Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_EVENT_PRI_H +#define _LOS_EVENT_PRI_H + +#include "los_event.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_COMPAT_POSIX +typedef struct { + volatile INT32 *realValue; + INT32 value; + UINT32 clearEvent; +} EventCond; + +extern UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, + UINT32 eventMask, UINT32 mode, UINT32 timeout); +#endif + +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.ph b/kernel/base/include/los_heap.ph deleted file mode 100644 index d6a923177..000000000 --- a/kernel/base/include/los_heap.ph +++ /dev/null @@ -1,148 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@defgroup los_heap Heap - * @ingroup kernel - */ - -#ifndef _LOS_HEAP_PH -#define _LOS_HEAP_PH - -#include "los_heap.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct tagHeapStatus { - UINT32 totalSize; - UINT32 usedSize; - UINT32 freeSize; - UINT32 allocCount; - UINT32 freeCount; -}LOS_HEAP_STATUS; - -/** - *@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 - *
    - *
  • None.
  • - *
- *@param pstHeapMan [IN] Type #LOS_HEAP_MANAGER * Pointer to the manager,to distinguish heap. - *@param pstNode [IN] Type #LOS_HEAP_NODE * Size of memory in bytes to allocate. - * - *@retval LOS_HEAP_NODE * Pointer to next memory node. - * - *@par Dependency: - *
  • los_heap.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS - */ -extern struct LOS_HEAP_NODE* osHeapPrvGetNext(struct LOS_HEAP_MANAGER *pstHeapMan, struct LOS_HEAP_NODE* pstNode); - -/** - *@ingroup los_heap - *@brief Obtain the heap information. - * - *@par Description: - *This API is used to obtain the heap information. - *@attention - *
    - *
  • None.
  • - *
- *@param pPool [IN] Type #VOID * A pointer pointed to the heap memory pool. - * - *@retval None. - * - *@par Dependency: - *
  • los_heap.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS - */ -extern VOID osAlarmHeapInfo(VOID *pPool); - -/** - *@ingroup los_heap - *@brief Obtain the heap status. - * - *@par Description: - *This API is used to obtain the heap status. - *@attention - *
    - *
  • None.
  • - *
- *@param pPool [IN] Type #VOID * A pointer pointed to the heap memory pool. - *@param pstStatus [OUT] Type #LOS_HEAP_STATUS * Heap status. - * - *@retval UINT32 Get status result. - * - *@par Dependency: - *
  • los_heap.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS - */ -extern UINT32 osHeapStatisticsGet(VOID *pPool, LOS_HEAP_STATUS *pstStatus); - -/** - *@ingroup los_heap - *@brief Get the max free block size. - * - *@par Description: - *This API is used to Get the max free block size. - *@attention - *
    - *
  • None.
  • - *
- *@param pPool [IN] Type #VOID * A pointer pointed to the heap memory pool. - * - *@retval UINT32 Max free block size. - * - *@par Dependency: - *
  • los_heap.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS - */ -extern UINT32 osHeapGetMaxFreeBlkSize(VOID *pPool); - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/kernel/base/include/los_heap_pri.h b/kernel/base/include/los_heap_pri.h new file mode 100644 index 000000000..0b27378ce --- /dev/null +++ b/kernel/base/include/los_heap_pri.h @@ -0,0 +1,276 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2015. All rights reserved. + * Description: LiteOS memory Module Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/* + * @defgroup los_heap Heap + * @ingroup kernel + */ + +#ifndef _LOS_HEAP_PRI_H +#define _LOS_HEAP_PRI_H + +#include "los_typedef.h" +#include "los_memstat_pri.h" +#include "los_memory_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define ALIGNE(sz) (((sz) + HEAP_ALIGN - 1) & (~(HEAP_ALIGN - 1))) +#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)) + +typedef struct tagLosHeapStatus { + UINT32 totalUsedSize; + UINT32 totalFreeSize; + UINT32 maxFreeNodeSize; + UINT32 usedNodeNum; + UINT32 freeNodeNum; +} LosHeapStatus; +#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 > ((1U << TASKID_BITS) - 1)) +#error task id bits too small! +#endif +#endif + +struct LosHeapNode { + struct LosHeapNode* prev; +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + UINT32 size : SIZE_BITS; + UINT32 taskID : TASKID_BITS; +#else + UINT32 size : 30; +#endif + UINT32 used: 1; + UINT32 align:1; + UINT8 data[0]; +}; + + +/** + * @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 + *
    + *
  • None.
  • + *
+ * @param heapMan [IN] Type #LosMemPoolInfo * Pointer to the manager,to distinguish heap. + * @param node [IN] Type #LosHeapNode * Size of memory in bytes to allocate. + * + * @retval LosHeapNode * Pointer to next memory node. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +extern struct LosHeapNode* OsHeapPrvGetNext(const LosMemPoolInfo *heapMan, struct LosHeapNode* node); + +/** + * @ingroup los_heap + * @brief Obtain the heap information. + * + * @par Description: + * This API is used to obtain the heap information. + * @attention + *
    + *
  • None.
  • + *
+ * @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool. + * + * @retval None. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +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 + *
    + *
  • None.
  • + *
+ * @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: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +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 + *
    + *
  • None.
  • + *
+ * @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool. + * + * @retval UINT32 Max free block size. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +extern UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool); + +/** + * @ingroup OsHeapInit + * @brief Initialize the heap memory pool. + * + * @par Description: + * This API is used to initialize the heap memory and get the begin address and + * size of heap memory,then initialize LosMemPoolInfo . + * @attention + *
    + *
  • None.
  • + *
+ * @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool. + * @param size [IN] Type #UINT32 Size of memory in bytes to initialized. + * + * @retval BOOL Get status return. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +extern BOOL OsHeapInit(VOID *pool, UINT32 size); + +/** + * @ingroup OsHeapAlloc + * @brief Alloc memory block from the heap. + * + * @par Description: + * This API is used to alloc memory block from the heap memory pool. + * @attention + *
    + *
  • None.
  • + *
+ * @param pool [IN] Type #VOID * Pointer to the manager,to distinguish heap + * @param size [IN] Type #UINT32 Size of memory in bytes to alloc. + * + * @retval VOID * Get the address of the memory we alloced or NULL. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +extern VOID* OsHeapAlloc(VOID *pool, UINT32 size); + +/** + * @ingroup OsHeapAllocAlign + * @brief Alloc memory block from the heap with align. + * + * @par Description: + * This API is used to alloc memory block from the heap memory pool with align. + * @attention + *
    + *
  • None.
  • + *
+ * @param pool [IN] Type #VOID * Pointer to the manager,to distinguish heap + * @param size [IN] Type #UINT32 Size of memory in bytes to alloc. + * @param boundary [IN] Type #UINT32 Boundary the heap needs align. + * + * @retval VOID * Get the address of the memory we alloced or NULL. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +extern VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary); + +/** + * @ingroup OsHeapFree + * @brief Free memory block from heap memory pool. + * + * @par Description: + * This API is used to To free the memory block from heap memory pool. + * @attention + *
    + *
  • None.
  • + *
+ * @param pool [IN] Type #VOID * Pointer to the manager,to distinguish heap + * @param ptr [IN] Type #VOID * Pinter of heap memory we want to free. + * + * @retval BOOL Get result return. + * + * @par Dependency: + *
  • los_heap_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS + */ +extern BOOL OsHeapFree(VOID *pool, VOID* ptr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_HEAP_PRI_H */ diff --git a/kernel/base/include/los_ipcdebug_pri.h b/kernel/base/include/los_ipcdebug_pri.h new file mode 100644 index 000000000..402f0f963 --- /dev/null +++ b/kernel/base/include/los_ipcdebug_pri.h @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: IPC Debug Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_IPCDEBUG_PRI_H +#define _LOS_IPCDEBUG_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + CHAR *buf; /**< Control block array total buffer */ + size_t ipcDebugCBSize; /**< Single control block size */ + size_t ipcDebugCBCnt; /**< Number of control blocks */ + UINT32 sortElemOff; /**< The offset of the member to be compared in the control block */ +} IpcSortParam; + +/* Compare the size of the last access time */ +typedef BOOL (*OsCompareFunc)(const IpcSortParam *sortParam, UINT32 left, UINT32 right); + +/* Get the address of the comparison member variable */ +#define SORT_ELEM_ADDR(sortParam, index) \ + ((sortParam)->buf + ((index) * (sortParam)->ipcDebugCBSize) + (sortParam)->sortElemOff) + +/* Sort this index array. */ +extern VOID OsArraySortByTime(UINT32 *sortArray, UINT32 start, UINT32 end, const IpcSortParam *sortParam, + OsCompareFunc compareFunc); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_IPCDEBUG_PRI_H */ diff --git a/arch/arm/arm-m/cortex-m4/los_exc.inc b/kernel/base/include/los_membox_pri.h similarity index 75% rename from arch/arm/arm-m/cortex-m4/los_exc.inc rename to kernel/base/include/los_membox_pri.h index f3f482f81..db636ba22 100644 --- a/arch/arm/arm-m/cortex-m4/los_exc.inc +++ b/kernel/base/include/los_membox_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Membox Private HeadFile * 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 @@ -22,32 +22,31 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#ifndef _LOS_EXC_INC -#define _LOS_EXC_INC + * --------------------------------------------------------------------------- */ -#include "los_exc.ph" -#include "los_sys.ph" +#ifndef _LOS_MEMBOX_PRI_H +#define _LOS_MEMBOX_PRI_H + +#include "los_membox.h" #ifdef __cplusplus #if __cplusplus extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - +#endif /* __cplusplus */ +#endif /* __cplusplus */ #ifdef __cplusplus #if __cplusplus } -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ +#endif /* __cplusplus */ +#endif /* __cplusplus */ -#endif /* _LOS_EXC_INC */ +#endif /* _LOS_MEMBOX_PRI_H */ diff --git a/kernel/base/include/los_memcheck.ph b/kernel/base/include/los_memcheck.ph deleted file mode 100644 index b40b82be1..000000000 --- a/kernel/base/include/los_memcheck.ph +++ /dev/null @@ -1,68 +0,0 @@ -/*---------------------------------------------------------------------------- - * Huawei - LiteOS - *---------------------------------------------------------------------------- - * Name: LOS_MEMCHECK.H - * Purpose: Memory check header file - * Rev.: V1.0.0 - *---------------------------------------------------------------------------- - * - - * Copyright (c) 2014, Huawei Technologies Co., Ltd. - * All rights reserved. - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - - *THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - *WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - *MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - *ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - *WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - *ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - *OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - *----------------------------------------------------------------------------*/ -#ifndef _LOS_MEMCHECK_PH -#define _LOS_MEMCHECK_PH - -#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: - *
    - *
  • This API is used to update the information of the memory.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param pPool [IN/OUT] Type #VOID * Memory pool number. - *@param uwSize [IN] Type #UINT32 Memory size. - *@param type [IN] Type #UINT32 Memory mang type. - * - *@retval UINT32 Updateinformation result. - *@par Dependency: - *
    - *
  • los_memboxcheck.ph: the header file that contains the API declaration.
  • - *
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -UINT32 osMemInfoUpdate(VOID *pPool, UINT32 uwSize, UINT32 uwType); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#endif /* _LOS_MEMCHECK_PH */ diff --git a/kernel/base/include/los_memcheck_pri.h b/kernel/base/include/los_memcheck_pri.h new file mode 100644 index 000000000..fea177c94 --- /dev/null +++ b/kernel/base/include/los_memcheck_pri.h @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2015. All rights reserved. + * Description: LiteOS memory Module Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MEMCHECK_PRI_H +#define _LOS_MEMCHECK_PRI_H + +#include "los_memcheck.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_PLATFORM_EXC == YES) || (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == YES) +#define MEM_INFO_SIZE (sizeof(MEM_INFO) * OS_SYS_MEM_NUM) +extern UINT8 g_memInfoMgr[MEM_INFO_SIZE]; +#endif + +/** + * @ingroup los_memboxcheck + * @brief Update the information of the memory. + * + * @par Description: + *
    + *
  • This API is used to update the information of the memory.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @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 VOID Updateinformation result. + * @par Dependency: + *
    + *
  • los_memboxcheck_pri.h: the header file that contains the API declaration.
  • + *
+ * @see None. + * @since Huawei LiteOS V100R001C00 + */ +VOID OsMemInfoUpdate(VOID *pool, UINT32 size, UINT32 type); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMCHECK_PRI_H */ diff --git a/kernel/base/include/los_memory.ph b/kernel/base/include/los_memory.ph deleted file mode 100644 index e06887668..000000000 --- a/kernel/base/include/los_memory.ph +++ /dev/null @@ -1,117 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MEMORY_PH -#define _LOS_MEMORY_PH - -#include "los_memory.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* -* 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: - *
    - *
  • This API is used to initialization the memory system.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval UINT32 Initialization result. - *@par Dependency: - *
  • los_memory.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osMemSystemInit(VOID); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_MEMORY_PH */ diff --git a/kernel/base/include/los_memory_pri.h b/kernel/base/include/los_memory_pri.h new file mode 100644 index 000000000..10a035008 --- /dev/null +++ b/kernel/base/include/los_memory_pri.h @@ -0,0 +1,119 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Memory Module Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MEMORY_PRI_H +#define _LOS_MEMORY_PRI_H + +#include "los_memory.h" +#include "los_spinlock.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINTPTR g_sys_mem_addr_end; + +extern UINT32 OsMemSystemInit(UINTPTR memStart); + +#ifdef LOSCFG_EXC_INTERACTION +extern UINT32 OsMemExcInteractionInit(UINTPTR memStart); +#endif +#define IS_ALIGNED(value, alignSize) ((((UINTPTR)(value)) & ((UINTPTR)((alignSize) - 1))) == 0) +extern VOID OsDumpMemByte(UINT32 length, UINTPTR addr); + +#ifdef LOSCFG_MEM_LEAKCHECK +extern VOID OsMemUsedNodeShow(VOID *pool); +#endif + +extern VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr); + +extern UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[]); + +/* spinlock for mem module */ +extern SPIN_LOCK_S g_memSpin; +#define MEM_LOCK(state) LOS_SpinLockSave(&g_memSpin, &(state)) +#define MEM_UNLOCK(state) LOS_SpinUnlockRestore(&g_memSpin, (state)) + +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +#define TASK_BLOCK_NUM (LOSCFG_BASE_CORE_TSK_CONFIG + 2) +typedef struct { + UINT32 memUsed; + UINT32 memPeak; +} TaskMemUsedInfo; +#endif + +#if (LOSCFG_KERNEL_MEM_BESTFIT == YES) +/* Memory pool information structure */ +typedef struct { + VOID *pool; /* Starting address of a memory pool */ + UINT32 poolSize; /* Memory pool size */ +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + UINT32 poolWaterLine; /* Maximum usage size in a memory pool */ + UINT32 poolCurUsedSize; /* Current usage size in a memory pool */ +#endif +#ifdef LOSCFG_MEM_MUL_POOL + VOID *nextPool; +#endif +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + TaskMemUsedInfo memStats[TASK_BLOCK_NUM]; +#endif +} LosMemPoolInfo; + +#elif (LOSCFG_KERNEL_MEM_BESTFIT_LITTLE == YES) +typedef struct { + struct LosHeapNode *head; + struct LosHeapNode *tail; + UINT32 size; +#if (LOSCFG_MEM_MUL_POOL == YES) + VOID *nextPool; +#endif +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + TaskMemUsedInfo memStats[TASK_BLOCK_NUM]; +#endif +} LosMemPoolInfo; + +#endif + +#if (LOSCFG_MEM_MUL_POOL == YES) +extern VOID *g_poolHead; +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMORY_PRI_H */ diff --git a/kernel/base/include/los_memrecord_pri.h b/kernel/base/include/los_memrecord_pri.h new file mode 100644 index 000000000..740bb90ee --- /dev/null +++ b/kernel/base/include/los_memrecord_pri.h @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: MemRecord Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MEMRECORD_PRI_H +#define _LOS_MEMRECORD_PRI_H + +#include "los_memory.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define RECORD_LEN 4000 + +typedef struct { + UINT32 addrID; + UINT32 taskID; + UINT32 reqSizeID; + UINT32 allocatedSizeID; + UINT32 actType; + UINT64 sysTick; + UINT32 linkRegID; +} MemRecordInfo; + +#define MEM_RECORDSHOW_TIMEOUT 6000 + +extern VOID OsMemRecordShowSet(UINT32 value); +extern VOID OsMemRecordMalloc(const VOID *ptr, UINT32 size); +extern VOID OsMemRecordFree(const VOID *ptr, UINT32 size); +extern VOID OsMemRecordShowTask(VOID); +extern VOID OsDecTo64F(UINT32 num, CHAR *base64, INT32 base64Len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMRECORD_PRI_H */ \ No newline at end of file diff --git a/kernel/base/include/los_memstat_pri.h b/kernel/base/include/los_memstat_pri.h new file mode 100644 index 000000000..2dcc04d6a --- /dev/null +++ b/kernel/base/include/los_memstat_pri.h @@ -0,0 +1,70 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Memory Module Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MEMSTAT_PRI_H +#define _LOS_MEMSTAT_PRI_H + +#include "los_typedef.h" +#include "los_memory_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + +extern VOID OsTaskMemUsedInc(TaskMemUsedInfo *memStats, UINT32 usedSize, UINT32 taskID); +extern VOID OsTaskMemUsedDec(TaskMemUsedInfo *memStats, UINT32 usedSize, UINT32 taskID); +extern UINT32 OsTaskMemUsage(const TaskMemUsedInfo *memStats, UINT32 taskID); +extern VOID OsTaskMemClear(UINT32 taskID); + +#define OS_MEM_ADD_USED(memStats, usedSize, taskID) OsTaskMemUsedInc(memStats, usedSize, taskID) +#define OS_MEM_REDUCE_USED(memStats, usedSize, taskID) OsTaskMemUsedDec(memStats, usedSize, taskID) +#define OS_MEM_CLEAR(taskID) OsTaskMemClear(taskID) +#else +#define OS_MEM_ADD_USED(memStats, usedSize, taskID) +#define OS_MEM_REDUCE_USED(memStats, usedSize, taskID) +#define OS_MEM_CLEAR(taskID) +#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 100644 index 000000000..565d7d101 --- /dev/null +++ b/kernel/base/include/los_multipledlinkhead_pri.h @@ -0,0 +1,82 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Multipledlinkhead Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MULTIPLE_DLINK_HEAD_PRI_H +#define _LOS_MULTIPLE_DLINK_HEAD_PRI_H + +#include "los_base.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_MULTI_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 *listNodeHead) +{ + LosMultipleDlinkHead *head = (LosMultipleDlinkHead *)headAddr; + + return (&head->listHead[OS_MULTI_DLNK_NUM - 1] == listNodeHead) ? NULL : (listNodeHead + 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.ph b/kernel/base/include/los_mux.ph deleted file mode 100644 index 76f647307..000000000 --- a/kernel/base/include/los_mux.ph +++ /dev/null @@ -1,110 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MUX_PH -#define _LOS_MUX_PH - -#include "los_task.ph" - -#include "los_mux.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C"{ -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -/** - * @ingroup los_mux - * Mutex object. - */ -typedef struct -{ - UINT8 ucMuxStat; /**< State OS_MUX_UNUSED,OS_MUX_USED */ - UINT16 usMuxCount; /**< Times of locking a mutex */ - UINT32 ucMuxID; /**< Handle ID*/ - LOS_DL_LIST stMuxList; /**< Mutex linked list*/ - LOS_TASK_CB *pstOwner; /**< The current thread that is locking a mutex*/ - UINT16 usPriority; /**< Priority of the thread that is locking a mutex */ -} MUX_CB_S; - -/** - * @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 MUX_CB_S *g_pstAllMux; - -/** - * @ingroup los_mux - * Obtain the pointer to a mutex object of the mutex that has a specified handle. - */ -#define GET_MUX(muxid) (((MUX_CB_S *)g_pstAllMux) + (muxid)) - -/** - *@ingroup los_mux - *@brief Initializes the mutex. - * - *@par Description: - *This API is used to initializes the mutex. - *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval UINT32 Initialization result. - *@par Dependency: - *
  • los_mux.ph: the header file that contains the API declaration.
- *@see LOS_MuxDelete - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osMuxInit(VOID); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_MUX_PH */ diff --git a/kernel/base/include/los_mux_debug_pri.h b/kernel/base/include/los_mux_debug_pri.h new file mode 100644 index 000000000..791500cfa --- /dev/null +++ b/kernel/base/include/los_mux_debug_pri.h @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex Debug Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MUX_DEBUG_PRI_H +#define _LOS_MUX_DEBUG_PRI_H + +#include "los_mux_pri.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* Deadlock detection initialization interface */ +extern UINT32 OsMuxDlockCheckInit(VOID); +STATIC INLINE UINT32 OsMuxDlockCheckInitHook(VOID) +{ +#ifdef LOSCFG_DEBUG_DEADLOCK + return OsMuxDlockCheckInit(); +#else + return LOS_OK; +#endif +} + +/* Add holding mutex lock node information */ +extern VOID OsMuxDlockNodeInsert(UINT32 taskID, VOID *muxCB); +STATIC INLINE VOID OsMuxDlockNodeInsertHook(UINT32 taskID, VOID *muxCB) +{ +#ifdef LOSCFG_DEBUG_DEADLOCK + OsMuxDlockNodeInsert(taskID, muxCB); +#endif +} +/* Delete holding mutex lock node information */ +extern VOID OsMuxDlockNodeDelete(UINT32 taskID, const VOID *muxCB); +STATIC INLINE VOID OsMuxDlockNodeDeleteHook(UINT32 taskID, const VOID *muxCB) +{ +#ifdef LOSCFG_DEBUG_DEADLOCK + OsMuxDlockNodeDelete(taskID, muxCB); +#endif +} +/* Update the last time the task was executed */ +extern VOID OsTaskTimeUpdate(UINT32 taskID, UINT64 tickCount); +STATIC INLINE VOID OsTaskTimeUpdateHook(UINT32 taskID, UINT64 tickCount) +{ +#ifdef LOSCFG_DEBUG_DEADLOCK + OsTaskTimeUpdate(taskID, tickCount); +#endif +} + +/* mutex debug initialization interface */ +extern UINT32 OsMuxDbgInit(VOID); +STATIC INLINE UINT32 OsMuxDbgInitHook(VOID) +{ +#ifdef LOSCFG_DEBUG_MUTEX + return OsMuxDbgInit(); +#else + return LOS_OK; +#endif +} +/* Update the last time the mutex was executed */ +extern VOID OsMuxDbgTimeUpdate(UINT32 muxID); +STATIC INLINE VOID OsMuxDbgTimeUpdateHook(UINT32 muxID) +{ +#ifdef LOSCFG_DEBUG_MUTEX + OsMuxDbgTimeUpdate(muxID); +#endif +} +/* Update the MUX_DEBUG_CB of the mutex when created or deleted */ +extern VOID OsMuxDbgUpdate(UINT32 muxID, TSK_ENTRY_FUNC creater); +STATIC INLINE VOID OsMuxDbgUpdateHook(UINT32 muxID, TSK_ENTRY_FUNC creater) +{ +#ifdef LOSCFG_DEBUG_MUTEX + OsMuxDbgUpdate(muxID, creater); +#endif +} +/* check the leak of mutex */ +extern VOID OsMutexCheck(VOID); +STATIC INLINE VOID OsMutexCheckHook(VOID) +{ +#ifdef LOSCFG_DEBUG_MUTEX + OsMutexCheck(); +#endif +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_DEBUG_PRI_H */ diff --git a/kernel/base/include/los_mux_pri.h b/kernel/base/include/los_mux_pri.h new file mode 100644 index 000000000..66af00e8f --- /dev/null +++ b/kernel/base/include/los_mux_pri.h @@ -0,0 +1,142 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MUX_PRI_H +#define _LOS_MUX_PRI_H + +#include "los_mux.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sem + * Configuration item for mux to use dynamic memory + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +#define LOSCFG_BASE_IPC_MUX_DYN_MEM YES +#else +#define LOSCFG_BASE_IPC_MUX_DYN_MEM NO +#endif + +/** + * @ingroup los_mux + * Mutex base object must be the same as the first three member names of LosMuxCB, + * so that pthread_mutex_t can share the kernel mutex mechanism. + */ +typedef struct { + LOS_DL_LIST muxList; /**< Mutex linked list */ + LosTaskCB *owner; /**< The current thread that is locking a mutex */ + UINT16 muxCount; /**< Times of locking a mutex */ +} MuxBaseCB; + +/** + * @ingroup los_mux + * Mutex object. + */ +typedef struct { + LOS_DL_LIST muxList; /**< Mutex linked list */ + LosTaskCB *owner; /**< The current thread that is locking a mutex */ + UINT16 muxCount; /**< Times of locking a mutex */ + UINT8 muxStat; /**< State OS_MUX_UNUSED, OS_MUX_USED */ + UINT32 muxID; /**< Handle ID */ +} 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 + +/** + * @ingroup los_mux + * Mutex global array address, which can be obtained by using a handle ID. + */ +#if (LOSCFG_BASE_IPC_MUX_DYN_MEM == YES) +extern LosMuxCB *g_allMux; +#else +extern LosMuxCB g_allMux[]; +#endif + +/** + * @ingroup los_mux + * COUNT | INDEX split bit + */ +#define MUX_SPLIT_BIT 16 +/** + * @ingroup los_mux + * Set the mutex id + */ +#define SET_MUX_ID(count, muxID) (((count) << MUX_SPLIT_BIT) | (muxID)) + +/** + * @ingroup los_mux + * get the mutex index + */ +#define GET_MUX_INDEX(muxID) ((muxID) & ((1U << MUX_SPLIT_BIT) - 1)) + +/** + * @ingroup los_mux + * get the mutex count + */ +#define GET_MUX_COUNT(muxID) ((muxID) >> MUX_SPLIT_BIT) +/** + * @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) + GET_MUX_INDEX(muxID)) + +extern UINT32 OsMuxInit(VOID); + +#define MUX_SCHEDULE 0x01 +#define MUX_NO_SCHEDULE 0x02 +extern UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UINT32 timeout, UINT32 intSave); +extern UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted); +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MUX_PRI_H */ diff --git a/kernel/base/include/los_percpu_pri.h b/kernel/base/include/los_percpu_pri.h new file mode 100644 index 000000000..54ba85ab7 --- /dev/null +++ b/kernel/base/include/los_percpu_pri.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: Percpu Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_PERCPU_PRI_H +#define _LOS_PERCPU_PRI_H + +#include "los_base.h" +#include "los_hw_cpu.h" +#include "los_sortlink_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + SortLinkAttribute taskSortLink; /* task sort link */ + SortLinkAttribute swtmrSortLink; /* swtmr sort link */ + + UINT32 idleTaskID; /* idle task id */ + UINT32 taskLockCnt; /* task lock flag */ + UINT32 swtmrHandlerQueue; /* software timer timeout queue id */ + UINT32 swtmrTaskID; /* software timer task id */ + + UINT32 schedFlag; /* pending scheduler flag */ +} Percpu; + +/* the kernel per-cpu structure */ +extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; + +STATIC INLINE Percpu *OsPercpuGet(VOID) +{ + return &g_percpu[ArchCurrCpuid()]; +} + +STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid) +{ + return &g_percpu[cpuid]; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PERCPU_PRI_H */ diff --git a/kernel/include/los_slab.h b/kernel/base/include/los_printf_pri.h similarity index 72% rename from kernel/include/los_slab.h rename to kernel/base/include/los_printf_pri.h index e9b51f41e..0e980de1a 100644 --- a/kernel/include/los_slab.h +++ b/kernel/base/include/los_printf_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Printf Private Headfile * 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 @@ -22,24 +22,20 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_slab Slab - * @ingroup kernel - */ +#ifndef _LOS_PRINTF_PRI_H +#define _LOS_PRINTF_PRI_H -#ifndef _LOS_SLAB_H -#define _LOS_SLAB_H - -#include +#include "los_printf.h" #ifdef __cplusplus #if __cplusplus @@ -47,16 +43,13 @@ 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 +extern VOID UartVprintf(const CHAR *fmt, va_list ap); +extern VOID PrintExcInfo(const CHAR *fmt, ...); -#define SLAB_BASIC_NEED_SIZE 0x1000 +extern VOID LkDprintf(const CHAR *fmt, va_list ap); +#ifdef LOSCFG_SHELL_DMESG +extern VOID DmesgPrintf(const CHAR *fmt, va_list ap); +#endif #ifdef __cplusplus #if __cplusplus @@ -64,5 +57,4 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif - +#endif /* _LOS_PRINTF_PRI_H */ diff --git a/kernel/base/include/los_priqueue.ph b/kernel/base/include/los_priqueue.ph deleted file mode 100644 index dfdddfc0e..000000000 --- a/kernel/base/include/los_priqueue.ph +++ /dev/null @@ -1,178 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_PRIQUEUE_PH -#define _LOS_PRIQUEUE_PH - -#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 - *
    - *
  • None.
  • - *
- *@param none. - * - *@retval none. - *@par Dependency: - *
  • los_priqueue.ph: the header file that contains the API declaration.
- *@see none. - *@since Huawei LiteOS V100R001C00 - */ -extern VOID 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 ptrPQItem must point to valid memory.
  • - *
  • Param uwPri rang is [0, OS_PRIORITY_QUEUE_PRIORITYNUM),included 0 and not included LOS_PRIORITY_QUEUE_PRIORITYNUM.
  • - *
- *@param ptrPQItem [IN] The node of item to be inserted. - *@param uwPri [IN] Priority of the item be inserted. - * - *@retval none. - *@par Dependency: - *
  • los_priqueue.ph: the header file that contains the API declaration.
- *@see osPriqueueDequeue. - *@since Huawei LiteOS V100R001C00 - */ -extern VOID osPriqueueEnqueue(LOS_DL_LIST *ptrPQItem, UINT32 uwPri); - -/** - *@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 ptrPQItem must point to valid memory.
  • - *
- *@param ptrPQItem [IN] The node of item to be deleted. - * - *@retval none. - *@par Dependency: - *
  • los_priqueue.ph: the header file that contains the API declaration.
- *@see osPriqueueEnqueue. - *@since Huawei LiteOS V100R001C00 - */ -extern VOID osPriqueueDequeue(LOS_DL_LIST *ptrPQItem); - -/** - *@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 - *
    - *
  • None.
  • - *
- *@param none. - * - *@retval NULL : The priority queue is empty. - *@retval item node : The node of the item with highest priority. - *@par Dependency: - *
  • los_priqueue.ph: the header file that contains the API declaration.
- *@see none. - *@since Huawei LiteOS V100R001C00 - */ -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 uwPri rang is [0, OS_PRIORITY_QUEUE_PRIORITYNUM),included 0 and not included LOS_PRIORITY_QUEUE_PRIORITYNUM.
  • - *
- *@param uwPri [IN] Obtain the number of items with the specified priority of uwPri. - * - *@retval The number of items :The number of items with the specified priority. - *@par Dependency: - *
  • los_priqueue.ph: the header file that contains the API declaration.
- *@see none. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osPriqueueSize(UINT32 uwPri); - -/** - *@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 - *
    - *
  • None.
  • - *
- * - *@retval The number of items: The total number of items in the priority queue. - *@par Dependency: - *
  • los_priqueue.ph: the header file that contains the API declaration.
- *@see none. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osPriqueueTotalSize(VOID); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_PRIQUEUE_PH */ diff --git a/kernel/base/include/los_priqueue_pri.h b/kernel/base/include/los_priqueue_pri.h new file mode 100644 index 000000000..e26a9a07a --- /dev/null +++ b/kernel/base/include/los_priqueue_pri.h @@ -0,0 +1,199 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Priority Queue Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_PRIQUEUE_PRI_H +#define _LOS_PRIQUEUE_PRI_H + +#include "los_list.h" +#include "los_typedef.h" +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_priqueue + * @brief Initialize the priority queue. + * + * @par Description: + * This API is used to initialize the priority queue. + * @attention + *
    + *
  • None.
  • + *
+ * @param none. + * + * @retval #LOS_NOK Insufficient memory for priority queue initialization. + * @retval #LOS_OK The priority queue successfully initialized. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see none. + * @since Huawei LiteOS V100R001C00 + */ +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 must point to valid memory.
  • + *
  • Param priority rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.
  • + *
+ * @param priqueueItem [IN] The node of item to be inserted. + * @param priority [IN] Priority of the item be inserted. + * + * @retval none. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see OsPriQueueDequeue. + * @since Huawei LiteOS V100R001C00 + */ +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 must point to valid memory.
  • + *
+ * @param priqueueItem [IN] The node of item to be deleted. + * + * @retval none. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see OsPriQueueEnqueue. + * @since Huawei LiteOS V100R001C00 + */ +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 + *
    + *
  • None.
  • + *
+ * @param none. + * + * @retval NULL The priority queue is empty. + * @retval item node The node of the item with highest priority. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see none. + * @since Huawei LiteOS V100R001C00 + */ +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 rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.
  • + *
+ * @param priority [IN] Obtain the number of items with the specified priority. + * + * @retval The number of items The number of items with the specified priority. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see none. + * @since Huawei LiteOS V100R001C00 + */ +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 + *
    + *
  • None.
  • + *
+ * + * @retval The number of items The total number of items in the priority queue. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see none. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 OsPriQueueTotalSize(VOID); + +/** + * @ingroup los_priqueue + * @brief Insert a item to the head of priority queue. + * + * @par Description: + * This API is used to insert a item to the head of priority queue according to the priority of this item. + * @attention + *
    + *
  • Param priqueueItem must point to valid memory.
  • + *
  • Param priority rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.
  • + *
+ * @param priqueueItem [IN] The node of item to be inserted. + * @param priority [IN] Priority of the item be inserted. + * + * @retval none. + * @par Dependency: + *
  • los_priqueue_pri.h: the header file that contains the API declaration.
+ * @see OsPriQueueDequeue. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsPriQueueEnqueueHead(LOS_DL_LIST *priqueueItem, UINT32 priority); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PRIQUEUE_PRI_H */ diff --git a/kernel/base/include/los_queue.ph b/kernel/base/include/los_queue.ph deleted file mode 100644 index b31068b38..000000000 --- a/kernel/base/include/los_queue.ph +++ /dev/null @@ -1,216 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_QUEUE_PH -#define _LOS_QUEUE_PH - -#include "los_queue.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -typedef enum enQueueReadWrite -{ - OS_QUEUE_READ = 0, - OS_QUEUE_WRITE = 1, -} QUEUE_READ_WRITE; - -typedef enum enQueueHeadTail -{ - OS_QUEUE_HEAD = 0, - OS_QUEUE_TAIL = 1, -} QUEUE_HEAD_TAIL; - -typedef enum enQueuePointOrNot -{ - OS_QUEUE_NOT_POINT = 0, - OS_QUEUE_POINT = 1, -} QUEUE_HEAD_POINT; - -#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) - - -/** - * @ingroup los_queue - * Queue information block structure - */ -typedef struct tagQueueCB -{ - UINT8 *pucQueue; /**< Pointer to a queue handle */ - UINT16 usQueueState; /**< Queue state */ - UINT16 usQueueLen; /**< Queue length */ - UINT16 usQueueSize; /**< Node size */ - UINT16 usQueueID; /**< usQueueID */ - UINT16 usQueueHead; /**< Node head */ - UINT16 usQueueTail; /**< Node tail */ - UINT16 usReadWriteableCnt[2]; /**< Count of readable or writable resources, 0:readable, 1:writable */ - LOS_DL_LIST stReadWriteList[2]; /**< Pointer to the linked list to be read or written, 0:readlist, 1:writelist */ - LOS_DL_LIST stMemList; /**< Pointer to the memory linked list */ -} QUEUE_CB_S; - -/* 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 QUEUE_CB_S *g_pstAllQueue; - -/** - * @ingroup los_queue - * Obtain a handle of the queue that has a specified ID. - */ -#define GET_QUEUE_HANDLE(QueueID) (((QUEUE_CB_S *)g_pstAllQueue) + (QueueID)) - -/** - * @ingroup los_queue - * Obtain the head node in a queue doubly linked list. - */ -#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, QUEUE_CB_S, stReadWriteList[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 uwQueueID. - *@attention - *
    - *
  • Do not alloc memory in unblocking modes such as interrupt.
  • - *
  • This API cannot be called before the Huawei LiteOS is initialized.
  • - *
  • The argument uwTimeOut is a relative time.
  • - *
- * - *@param uwQueueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pMailPool [IN] The memory poll that stores the mail. - *@param uwTimeOut [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER]. - * - *@retval #NULL The memory allocation is failed. - *@retval #pMem The address of alloc memory. - *@par Dependency: - *
  • los_queue.ph: the header file that contains the API declaration.
- *@see osQueueMailFree - *@since Huawei LiteOS V100R001C00 - */ -extern VOID *osQueueMailAlloc(UINT32 uwQueueID, VOID *pMailPool, UINT32 uwTimeOut); - -/** - *@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 uwQueueID. - *@attention - *
    - *
  • This API cannot be called before the Huawei LiteOS is initialized.
  • - *
- * - *@param uwQueueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pMailPool [IN] The mail memory poll address. - *@param pMailMem [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: - *
  • los_queue.ph: the header file that contains the API declaration.
- *@see osQueueMailAlloc - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osQueueMailFree(UINT32 uwQueueID, VOID *pMailPool, VOID *pMailMem); - -/** - *@ingroup los_queue - *@brief Initialization queue. - * - *@par Description: - *This API is used to initialization queue. - *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval UINT32 Initialization result. - *@par Dependency: - *
  • los_queue.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osQueueInit(VOID); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_QUEUE_PH */ diff --git a/kernel/base/include/los_queue_debug_pri.h b/kernel/base/include/los_queue_debug_pri.h new file mode 100644 index 000000000..59b3fb45b --- /dev/null +++ b/kernel/base/include/los_queue_debug_pri.h @@ -0,0 +1,89 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Queue Debug Pri HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_QUEUE_DEBUG_PRI_H +#define _LOS_QUEUE_DEBUG_PRI_H + +#include "los_config.h" +#include "los_task.h" +#include "los_queue_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* queue debug initialization interface */ +extern UINT32 OsQueueDbgInit(VOID); +STATIC INLINE UINT32 OsQueueDbgInitHook(VOID) +{ +#ifdef LOSCFG_DEBUG_QUEUE + return OsQueueDbgInit(); +#else + return LOS_OK; +#endif +} +/* Update the last time the queue was executed */ +extern VOID OsQueueDbgTimeUpdate(UINT32 queueID); +STATIC INLINE VOID OsQueueDbgTimeUpdateHook(UINT32 queueID) +{ +#ifdef LOSCFG_DEBUG_QUEUE + OsQueueDbgTimeUpdate(queueID); +#endif +} +/* Update the task entry of the queue debug info when created or deleted */ +extern VOID OsQueueDbgUpdate(UINT32 queueID, TSK_ENTRY_FUNC entry); +STATIC INLINE VOID OsQueueDbgUpdateHook(UINT32 queueID, TSK_ENTRY_FUNC entry) +{ +#ifdef LOSCFG_DEBUG_QUEUE + OsQueueDbgUpdate(queueID, entry); +#endif +} +/* check the leak of queue */ +extern VOID OsQueueCheck(VOID); +STATIC INLINE VOID OsQueueCheckHook(VOID) +{ +#ifdef LOSCFG_DEBUG_QUEUE + OsQueueCheck(); +#endif +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_DEBUG_PRI_H */ diff --git a/kernel/base/include/los_queue_pri.h b/kernel/base/include/los_queue_pri.h new file mode 100644 index 000000000..aadde471a --- /dev/null +++ b/kernel/base/include/los_queue_pri.h @@ -0,0 +1,226 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Queue Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_QUEUE_PRI_H +#define _LOS_QUEUE_PRI_H + +#include "los_queue.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_sem + * Configuration item for queue to use dynamic memory + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +#define LOSCFG_BASE_IPC_QUEUE_DYN_MEM YES +#else +#define LOSCFG_BASE_IPC_QUEUE_DYN_MEM NO +#endif + +typedef enum { + OS_QUEUE_READ = 0, + OS_QUEUE_WRITE = 1, + OS_QUEUE_N_RW = 2 +} QueueReadWrite; + +typedef enum { + OS_QUEUE_HEAD = 0, + OS_QUEUE_TAIL = 1 +} QueueHeadTail; + +#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite)) +#define OS_QUEUE_READ_WRITE_GET(type) ((type) & 0x01U) +#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) & 0x03U) +#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) + +/** + * @ingroup los_queue + * Queue information block structure + */ +typedef struct { + UINT8 *queueHandle; /**< Pointer to a queue handle */ + UINT16 queueState; /**< Queue state */ + UINT16 queueLen; /**< Queue length */ + UINT16 queueSize; /**< Node size */ + UINT32 queueID; /**< queueID */ + UINT16 queueHead; /**< Node head */ + UINT16 queueTail; /**< Node tail */ + UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */ + LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< 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 + */ +#if (LOSCFG_BASE_IPC_QUEUE_DYN_MEM == YES) +extern LosQueueCB *g_allQueue; +#else +extern LosQueueCB g_allQueue[]; +#endif + +/** + * @ingroup los_queue + * COUNT | INDEX split bit + */ +#define QUEUE_SPLIT_BIT 16 +/** + * @ingroup los_queue + * Set the queue id + */ +#define SET_QUEUE_ID(count, queueID) (((count) << QUEUE_SPLIT_BIT) | (queueID)) + +/** + * @ingroup los_queue + * get the queue index + */ +#define GET_QUEUE_INDEX(queueID) ((queueID) & ((1U << QUEUE_SPLIT_BIT) - 1)) + +/** + * @ingroup los_queue + * get the queue count + */ +#define GET_QUEUE_COUNT(queueID) ((queueID) >> QUEUE_SPLIT_BIT) + +/** + * @ingroup los_queue + * Obtain a handle of the queue that has a specified ID. + * + */ +#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)g_allQueue) + GET_QUEUE_INDEX(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 + *
    + *
  • Do not alloc memory in unblocking modes such as interrupt.
  • + *
  • This API cannot be called before the Huawei LiteOS is initialized.
  • + *
  • The argument timeout is a relative time.
  • + *
+ * + * @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 #pMem The address of alloc memory. + * @par Dependency: + *
  • los_queue_pri.h: the header file that contains the API declaration.
+ * @see OsQueueMailFree + * @since Huawei LiteOS V100R001C00 + */ +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 + *
    + *
  • This API cannot be called before the Huawei LiteOS is initialized.
  • + *
+ * + * @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: + *
  • los_queue_pri.h: the header file that contains the API declaration.
+ * @see OsQueueMailAlloc + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem); + +extern UINT32 OsQueueInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_QUEUE_PRI_H */ diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h new file mode 100644 index 000000000..9de7e0f4d --- /dev/null +++ b/kernel/base/include/los_sched_pri.h @@ -0,0 +1,140 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: Scheduler Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_SCHED_PRI_H +#define _LOS_SCHED_PRI_H + +#include "los_percpu_pri.h" +#include "los_hwi.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 g_taskScheduled; + +/* + * Schedule flag, one bit represents one core. + * This flag is used to prevent kernel scheduling before OSStartToRun. + */ +#define OS_SCHEDULER_SET(cpuid) do { \ + g_taskScheduled |= (1U << (cpuid)); \ +} while (0); + +#define OS_SCHEDULER_CLR(cpuid) do { \ + g_taskScheduled &= ~(1U << (cpuid)); \ +} while (0); + +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid())) + +typedef enum { + INT_NO_RESCH = 0, /* no needs to schedule */ + INT_PEND_RESCH, /* pending schedule flag */ +} SchedFlag; + +/* Check if preemptable with counter flag */ +STATIC INLINE BOOL OsPreemptable(VOID) +{ + /* + * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable + * is called, needs mannually disable interrupt, to prevent current task from + * being migrated to another core, and get the wrong preeptable status. + */ + UINT32 intSave = LOS_IntLock(); + BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0); + if (!preemptable) { + /* Set schedule flag if preemption is disabled */ + OsPercpuGet()->schedFlag = INT_PEND_RESCH; + } + LOS_IntRestore(intSave); + return preemptable; +} + +STATIC INLINE BOOL OsPreemptableInSched(VOID) +{ + BOOL preemptable = FALSE; + + preemptable = (OsPercpuGet()->taskLockCnt == 0); + if (!preemptable) { + /* Set schedule flag if preemption is disabled */ + OsPercpuGet()->schedFlag = INT_PEND_RESCH; + } + + return preemptable; +} + +/* + * This function simply picks the next task and switches to it. + * Current task needs to already be in the right state or the right + * queues it needs to be in. + */ +extern VOID OsSchedResched(VOID); + +/* + * This function put the current task back to the ready queue and + * try to do the schedule. However, the schedule won't be definitely + * taken place while there're no other higher priority tasks or locked. + */ +extern VOID OsSchedPreempt(VOID); + +/* + * Just like OsSchedPreempt, except this function will do the OS_INT_ACTIVE + * check, in case the schedule taken place in the middle of an interrupt. + */ +STATIC INLINE VOID LOS_Schedule(VOID) +{ +#if (LOSCFG_PLATFORM_HWI == YES) + if (OS_INT_ACTIVE) { + OsPercpuGet()->schedFlag = INT_PEND_RESCH; + return; + } +#endif + + /* + * trigger schedule in task will also do the slice check + * if neccessary, it will give up the timeslice more in time. + * otherwhise, there's no other side effects. + */ + OsSchedPreempt(); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SCHED_PRI_H */ diff --git a/kernel/base/include/los_sem_debug_pri.h b/kernel/base/include/los_sem_debug_pri.h new file mode 100644 index 000000000..384a2882a --- /dev/null +++ b/kernel/base/include/los_sem_debug_pri.h @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Sem Debug Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_SEM_DEBUG_PRI_H +#define _LOS_SEM_DEBUG_PRI_H + +#include "los_config.h" +#include "los_sem_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* semaphore debug initialization interface */ +extern UINT32 OsSemDbgInit(VOID); +STATIC INLINE UINT32 OsSemDbgInitHook(VOID) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + return OsSemDbgInit(); +#else + return LOS_OK; +#endif +} +/* Update the last time the semaphore was executed */ +extern VOID OsSemDbgTimeUpdate(UINT32 semID); +STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semID) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + OsSemDbgTimeUpdate(semID); +#endif + return; +} +/* Update the SEM_DEBUG_CB of the semaphore when created or deleted */ +extern VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count); +STATIC INLINE VOID OsSemDbgUpdateHook(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + OsSemDbgUpdate(semID, creater, count); +#endif + return; +} +/* get the full data of SEM_DFX_CB */ +extern UINT32 OsSemInfoGetFullData(VOID); +STATIC INLINE VOID OsSemInfoGetFullDataHook(VOID) +{ +#ifdef LOSCFG_DEBUG_SEMAPHORE + (VOID)OsSemInfoGetFullData(); +#endif + return; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SEM_DEBUG_PRI_H */ diff --git a/kernel/base/include/los_sem.ph b/kernel/base/include/los_sem_pri.h similarity index 54% rename from kernel/base/include/los_sem.ph rename to kernel/base/include/los_sem_pri.h index 90eaec6a5..b40c1b2fe 100644 --- a/kernel/base/include/los_sem.ph +++ b/kernel/base/include/los_sem_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Semaphore Private HeadFile * 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 @@ -22,20 +22,21 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_SEM_PH -#define _LOS_SEM_PH +#ifndef _LOS_SEM_PRI_H +#define _LOS_SEM_PRI_H #include "los_sem.h" +#include "los_config.h" #ifdef __cplusplus #if __cplusplus @@ -43,68 +44,88 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#define OS_SEM_COUNTING_MAX_COUNT 0xFFFF -#define OS_SEM_BINARY_MAX_COUNT 1 - /** * @ingroup los_sem * Semaphore control structure. */ -typedef struct -{ - UINT16 usSemStat; /**< Semaphore state*/ - UINT16 usSemCount; /**< Number of available semaphores*/ - UINT16 usMaxSemCount; /**< Max number of available semaphores*/ - UINT16 usSemID; /**< Semaphore control structure ID*/ - LOS_DL_LIST stSemList; /**< Queue of tasks that are waiting on a semaphore*/ -} SEM_CB_S; +typedef struct { + UINT8 semStat; /**< Semaphore state */ + UINT16 semCount; /**< Number of available semaphores */ + UINT16 maxSemCount; /**< Max number of available semaphores */ + UINT32 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. + * The semaphore is not in use. * */ -#define OS_SEM_UNUSED 0 +#define OS_SEM_UNUSED 0 /** * @ingroup los_sem - *The semaphore is used. + * The semaphore is used. * */ -#define OS_SEM_USED 1 +#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, SEM_CB_S, stSemList) -extern SEM_CB_S *g_pstAllSem; +#define GET_SEM_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosSemCB, semList) + /** * @ingroup los_sem - * Obtain a semaphore ID. - * + * Configuration item for IPC to use dynamic memory */ -#define GET_SEM(semid) (((SEM_CB_S *)g_pstAllSem) + (semid)) +#if (LOSCFG_LIB_CONFIGURABLE == YES) +#define LOSCFG_BASE_IPC_DYNAMIC_MEM YES +#else +#define LOSCFG_BASE_IPC_DYNAMIC_MEM NO +#endif /** - *@ingroup los_sem - *@brief Initialize the Semaphore doubly linked list. - * - *@par Description: - *This API is used to initialize the Semaphore doubly linked list. - *@attention - *
    - *
  • None.
  • - *
- * - *@param None. + * @ingroup los_sem + * Semaphore information control block + */ +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) +extern LosSemCB *g_allSem; +#else +extern LosSemCB g_allSem[]; +#endif + +/** + * @ingroup los_sem + * COUNT | INDEX split bit + */ +#define SEM_SPLIT_BIT 16 +/** + * @ingroup los_sem + * Set the semaphore id + */ +#define SET_SEM_ID(count, semID) (((count) << SEM_SPLIT_BIT) | (semID)) + +/** + * @ingroup los_sem + * get the semaphore index + */ +#define GET_SEM_INDEX(semID) ((semID) & ((1U << SEM_SPLIT_BIT) - 1)) + +/** + * @ingroup los_sem + * get the semaphore count + */ +#define GET_SEM_COUNT(semID) ((semID) >> SEM_SPLIT_BIT) + +/** + * @ingroup los_sem + * Obtain a semaphore ID. * - *@retval UINT32 Initialization result. - *@par Dependency: - *
  • los_sem.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 */ -extern UINT32 osSemInit(VOID); +#define GET_SEM(semID) (((LosSemCB *)g_allSem) + GET_SEM_INDEX(semID)) + +extern UINT32 OsSemInit(VOID); #ifdef __cplusplus #if __cplusplus @@ -112,4 +133,4 @@ extern UINT32 osSemInit(VOID); #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* _LOS_SEM_PH */ +#endif /* _LOS_SEM_PRI_H */ diff --git a/kernel/base/include/los_slab.ph b/kernel/base/include/los_slab.ph deleted file mode 100644 index 6f0e5311e..000000000 --- a/kernel/base/include/los_slab.ph +++ /dev/null @@ -1,739 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@defgroup los_slab Slab - * @ingroup kernel - */ - -#ifndef _LOS_SLAB_PH -#define _LOS_SLAB_PH - -#include "los_base.h" -#include "los_slab.h" -#include - -typedef struct __s_LOS_SLAB_STATUS { - UINT32 totalSize; - UINT32 usedSize; - UINT32 freeSize; - UINT32 allocCount; - UINT32 freeCount; -}LOS_SLAB_STATUS; - -typedef struct tagOS_SLAB_BLOCK_NODE{ - UINT16 usMagic; - UINT8 ucBlkSz; - UINT8 ucRecordId; -}OS_SLAB_BLOCK_NODE; - -struct AtomicBitset { - UINT32 numBits; - UINT32 words[];/*lint !e43*/ -}; - -typedef struct __s_OS_SLAB_ALLOCATOR { - UINT32 uwItemSz; - UINT8 *ucDataChunks; - struct AtomicBitset *bitset;/*lint !e43*/ -}OS_SLAB_ALLOCATOR; - -typedef struct __s_OS_SLAB_MEM { - UINT32 blkSz; - UINT32 blkCnt; - UINT32 blkUsedCnt; - OS_SLAB_ALLOCATOR *alloc; -}OS_SLAB_MEM; - -struct LOS_SLAB_CONTROL_HEADER{ - OS_SLAB_MEM stSlabClass[SLAB_MEM_COUNT]; -}; - -#define OS_SLAB_MAGIC (0xdede) -#define OS_SLAB_BLOCK_HEAD_GET(pPtr) ((OS_SLAB_BLOCK_NODE *)((UINT8 *)pPtr - sizeof(OS_SLAB_BLOCK_NODE))) -#define OS_SLAB_BLOCK_MAGIC_SET(pstSlabNode) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->usMagic = (UINT16)OS_SLAB_MAGIC) -#define OS_SLAB_BLOCK_MAGIC_GET(pstSlabNode) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->usMagic) -#define OS_SLAB_BLOCK_SIZE_SET(pstSlabNode, uwSize) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->ucBlkSz = uwSize) -#define OS_SLAB_BLOCK_SIZE_GET(pstSlabNode) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->ucBlkSz) -#define OS_SLAB_BLOCK_ID_SET(pstSlabNode, uwId) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->ucRecordId = uwId) -#define OS_SLAB_BLOCK_ID_GET(pstSlabNode) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->ucRecordId) -#define OS_ALLOC_FROM_SLAB_CHECK(pstSlabNode) (((OS_SLAB_BLOCK_NODE *)pstSlabNode)->usMagic == (UINT16)OS_SLAB_MAGIC) - -#define ATOMIC_BITSET_SZ(numbits) (sizeof(struct AtomicBitset) + ((numbits) + 31) / 8) -#define ATOMIC_BITSET_DECL(nam, numbits, extra_keyword) extra_keyword UINT8 _##nam##_store [ATOMIC_BITSET_SZ(numbits)] __attribute__((aligned(4))); extra_keyword struct AtomicBitset *nam = (struct AtomicBitset*)_##nam##_store - -/** - * @ingroup los_slab - * @brief Initialization atomic bitset. - * - * @par Description: - * This API is used to initialization atomic bitset. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN/OUT] Type #AtomicBitset * Atomic bitset. - * @param numBits [IN] Type #UINT32 Bits number. - * - * @retval None. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -VOID osAtomicBitsetInit(struct AtomicBitset *pstSet, UINT32 uwNumBits); - -/** - * @ingroup los_slab - * @brief Get atomic bitset number. - * - * @par Description: - * This API is used to get atomic bitset number. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * - * @retval UINT32 Atomic bitset number. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -UINT32 osAtomicBitsetGetNumBits(const struct AtomicBitset *pstSet); - -/** - * @ingroup los_slab - * @brief Get atomic bitset bit. - * - * @par Description: - * This API is used to get atomic bitset bit. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * @param uwNum [IN] Type #UINT32 Bit number. - * - * @retval BOOL success or failed - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -BOOL osAtomicBitsetGetBit(const struct AtomicBitset *pstSet, UINT32 uwNum); - -/** - * @ingroup los_slab - * @brief Clear the atomic bitset bit. - * - * @par Description: - * This API is used to clear the atomic bitset bit. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * @param uwNum [IN] Type #UINT32 Bit number. - * - * @retval None. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -VOID osAtomicBitsetClearBit(struct AtomicBitset *pstSet, UINT32 uwNum); - -/** - * @ingroup los_slab - * @brief Set the atomic bitset bit. - * - * @par Description: - * This API is used to set the atomic bitset bit. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * @param uwNum [IN] Type #UINT32 Bit number. - * - * @retval None. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -VOID osAtomicBitsetSetBit(struct AtomicBitset *pstSet, UINT32 uwNum); - -/** - * @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 - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * - * @retval INT32 The address of the first available bit. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -INT32 osAtomicBitsetFindClearAndSet(struct AtomicBitset *pstSet); - -/** - * @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 - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * @param wIdx [IN] Type #INT32 * index. - * - * @retval INT32 Index to natural numbers. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -INT32 osAtomicBitsetIdxChgToNatural(struct AtomicBitset *pstBitset, INT32 swIdx); - -/** - * @ingroup los_slab - * @brief Judgment the atomic bitset is empty. - * - * @par Description: - * This API is used to judgment the atomic bitset is empty. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstSet [IN] Type #AtomicBitset * Atomic bitset. - * - * @retval BOOL Judgment result. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -BOOL osAtomicBitsetEmpty(struct AtomicBitset *pstBitset); - -//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 - *
    - *
  • None.
  • - *
- * - * @param pPool [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: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorDestroy - * @since Huawei LiteOS V100R002C00 - */ -OS_SLAB_ALLOCATOR *osSlabAllocatorNew(VOID *pPool, UINT32 uwItemSz, UINT32 uwItemAlign, UINT32 uwNumItems); - -/** - * @ingroup los_slab - * @brief Destroy a slab allocator. - * - * @par Description: - * This API is used to Destroy a slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * @param pstAllocator [IN] a slab allocator. - * - * @retval #VOID - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorNew - * @since Huawei LiteOS V100R002C00 - */ -VOID osSlabAllocatorDestroy(VOID *pPool, OS_SLAB_ALLOCATOR *pstAllocator); - -/** - * @ingroup los_slab - * @brief Allocate a slab page form allocator. - * - * @par Description: - * This API is used to allocate a slab page form allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstAllocator [IN] a slab allocator. - * - * @retval #VOID* return a slab page. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see osSlabAllocatorFree - * @since Huawei LiteOS V100R002C00 - */ -VOID* osSlabAllocatorAlloc(OS_SLAB_ALLOCATOR *pstAllocator); - -/** - * @ingroup los_slab - * @brief Free a slab page. - * - * @par Description: - * This API is used to free a slab page. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstAllocator [IN] a slab allocator. - * @param ptrP [IN] a slab page. - * - * @retval #FALSE Failed to free a slab page. - * @retval #TRUE Succees to free a slab page. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see LOS_SlabAllocatorAlloc - * @since Huawei LiteOS V100R002C00 - */ -BOOL osSlabAllocatorFree(OS_SLAB_ALLOCATOR *pstAllocator, VOID* ptrP); - -/** - * @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 - *
    - *
  • None.
  • - *
- * - * @param pstAllocator [IN] a slab allocator. - * @param uwIdx [IN] index - * - * @retval VOID * - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -VOID* osSlabAllocatorGetNth(OS_SLAB_ALLOCATOR *pstAllocator, UINT32 uwIdx); // -> pointer or NULL if that slot is empty may be not int-safe. YMMV - -/** - * @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 - *
    - *
  • None.
  • - *
- * - * @param pstAllocator [IN] a slab allocator. - * @param uwIdx [IN] index - * - * @retval VOID * - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -VOID* osSlabAllocatorGetIdxP(OS_SLAB_ALLOCATOR *pstAllocator, UINT32 uwIdx); - -/** - * @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 - *
    - *
  • None.
  • - *
- * - * @param allocator [IN] a slab allocator. - * @param ptrP [IN] a slab page. - * - * @retval #-1 Illegal index . - * @retval #UINT32 Succees to get index. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -UINT32 osSlabAllocatorGetIndex(OS_SLAB_ALLOCATOR *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 - *
    - *
  • None.
  • - *
- * - * @param allocator [IN] a slab allocator. - * - * @retval #UINT32 Succees to get the number of slab page. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -UINT32 osSlabAllocatorGetNumItems(OS_SLAB_ALLOCATOR *allocator); - -/** - * @ingroup los_slab - * @brief Check the slab allocator. - * - * @par Description: - * This API is used to check the slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param allocator [IN] a slab allocator. - * - * @retval #FALSE The slab allocator is already used. - * @retval #TRUE The slab allocator is not used. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -BOOL osSlabAllocatorEmpty(OS_SLAB_ALLOCATOR *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 - *
    - *
  • None.
  • - *
- * - * @param allocator [IN] a slab allocator. - * - * @retval #UINT32 The used number of slab page in slab allocator. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -UINT32 osSlabAllocatorGetUsedItemCnt(OS_SLAB_ALLOCATOR *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 - *
    - *
  • None.
  • - *
- * - * @param allocator [IN] a slab allocator. - * @param item_sz [OUT] a slab page size. - * @param item_cnt [OUT] a slab page num. - * @param cur_usage [OUT] a used number of slab page. - * - * @retval #VOID - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -VOID osSlabAllocatorGetSlabInfo(OS_SLAB_ALLOCATOR *allocator, UINT32 *item_sz, UINT32 *item_cnt, UINT32 *cur_usage); - -/** - * @ingroup los_slab - * @brief init slab allocator. - * - * @par Description: - * This API is used to init slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * - * @retval BOOL - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -extern BOOL osSlabMemInit(VOID *pPool); - -/** - * @ingroup los_slab - * @brief alloc mem by slab allocator. - * - * @par Description: - * This API is used to alloc mem by slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [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: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -extern VOID *osSlabMemAlloc(VOID *pPool, UINT32 sz); - -/** - * @ingroup los_slab - * @brief free mem by slab allocator. - * - * @par Description: - * This API is used to free mem by slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [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: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -extern BOOL osSlabMemFree(VOID *pPool, VOID* ptr); - -/** - * @ingroup los_slab - * @brief deinit slab allocator. - * - * @par Description: - * This API is used to deinit slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * - * @retval VOID - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R002C00 - */ -extern VOID osSlabMemDeinit(VOID *pPool); - -/** - * @ingroup los_slab - * @brief Check slab allocator. - * - * @par Description: - * This API is used to check slab allocator. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pstAllocator [IN] a slab allocator. - * @param ptrP [IN] Slab node. - * - * @retval VOID - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -extern BOOL osSlabAllocatorCheck(OS_SLAB_ALLOCATOR *pstAllocator, VOID* ptrP); - -/** - * @ingroup los_slab - * @brief Get SlabCtrlHdr. - * - * @par Description: - * This API is used to get SlabCtrlHdr. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * - * @retval VOID - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -extern VOID *osSlabCtrlHdrGet(VOID *pPool); - -/** - * @ingroup los_slab - * @brief Check the slab memory. - * - * @par Description: - * This API is used to check the slab memory. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * @param pPtr [IN] Slab block head. - * - * @retval UINT32 block size. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -extern UINT32 osSlabMemCheck(VOID *pPool, VOID* pPtr); - -/** - * @ingroup los_slab - * @brief Get the slab status. - * - * @par Description: - * This API is used to get the slab status. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * @param pstStatus [IN/OUT] Slab block status. - * - * @retval UINT32 Get status result. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -extern UINT32 osSlabStatisticsGet(VOID *pPool, LOS_SLAB_STATUS *pstStatus); - -/** - * @ingroup los_slab - * @brief Get the max free block size. - * - * @par Description: - * This API is used to get the max free block size. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * - * @retval UINT32 Max free block size. - * @par Dependency: - *
  • los_slab.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R002C00 - */ -extern UINT32 osSlabGetMaxFreeBlkSize(VOID *pPool); - -#endif - diff --git a/kernel/base/include/los_sortlink_pri.h b/kernel/base/include/los_sortlink_pri.h new file mode 100644 index 000000000..d21747514 --- /dev/null +++ b/kernel/base/include/los_sortlink_pri.h @@ -0,0 +1,111 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Sortlink Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_SORTLINK_PRI_H +#define _LOS_SORTLINK_PRI_H + +#include "los_typedef.h" +#include "los_list.h" +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* + * Sortlink Rollnum Structure: + * ------------------------------------------ + * | 31 | 30 | 29 |.......| 4 | 3 | 2 | 1 | 0 | + * ------------------------------------------ + * |<-High Bits->|<---------Low Bits--------->| + * + * Low Bits : circles + * High Bits : sortlink index + */ +#define OS_TSK_HIGH_BITS 3U +#define OS_TSK_LOW_BITS (32U - OS_TSK_HIGH_BITS) +#define OS_TSK_SORTLINK_LOGLEN OS_TSK_HIGH_BITS +#define OS_TSK_SORTLINK_MASK (OS_TSK_SORTLINK_LEN - 1U) +#define OS_TSK_MAX_ROLLNUM (0xFFFFFFFFU - OS_TSK_SORTLINK_LEN) +#define OS_TSK_HIGH_BITS_MASK (OS_TSK_SORTLINK_MASK << OS_TSK_LOW_BITS) +#define OS_TSK_LOW_BITS_MASK (~OS_TSK_HIGH_BITS_MASK) + +#define EVALUATE_L(NUM, VALUE) NUM = (((NUM) & OS_TSK_HIGH_BITS_MASK) | (VALUE)) + +#define EVALUATE_H(NUM, VALUE) NUM = (((NUM) & OS_TSK_LOW_BITS_MASK) | ((VALUE) << OS_TSK_LOW_BITS)) + +#define ROLLNUM_SUB(NUM1, NUM2) \ + NUM1 = (((NUM1) & OS_TSK_HIGH_BITS_MASK) | \ + (ROLLNUM(NUM1) - ROLLNUM(NUM2))) + +#define ROLLNUM_ADD(NUM1, NUM2) \ + NUM1 = (((NUM1) & OS_TSK_HIGH_BITS_MASK) | \ + (ROLLNUM(NUM1) + ROLLNUM(NUM2))) + +#define ROLLNUM_DEC(NUM) NUM = ((NUM) - 1) + +#define ROLLNUM(NUM) ((NUM) & OS_TSK_LOW_BITS_MASK) + +#define SORT_INDEX(NUM) ((NUM) >> OS_TSK_LOW_BITS) + +#define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->idxRollNum = (value)) + +typedef struct { + LOS_DL_LIST sortLinkNode; + UINT32 idxRollNum; +} SortLinkList; + +typedef struct { + LOS_DL_LIST sortLink[OS_TSK_SORTLINK_LEN]; + UINT16 cursor; + UINT16 reserved; +} SortLinkAttribute; + +extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader); +extern VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList); +extern VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList); +extern UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader); +extern UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader, + const SortLinkList *targetSortList); +extern VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SORTLINK_PRI_H */ diff --git a/kernel/base/include/los_stackinfo_pri.h b/kernel/base/include/los_stackinfo_pri.h new file mode 100644 index 000000000..d670e02b6 --- /dev/null +++ b/kernel/base/include/los_stackinfo_pri.h @@ -0,0 +1,88 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Stack Info Private Headfile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_STACK_INFO_PRI_H +#define _LOS_STACK_INFO_PRI_H + +#include "los_typedef.h" +#include "arch_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef struct { + VOID *stackTop; + UINT32 stackSize; + CHAR *stackName; +} StackInfo; + +#define OS_INVALID_WATERLINE 0xFFFFFFFF +#define OS_STACK_MAGIC_CHECK(topstack) (*(UINTPTR *)(topstack) == OS_STACK_MAGIC_WORD) /* 1:magic valid 0:unvalid */ + +extern VOID OsExcStackInfo(VOID); +extern VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum); +extern VOID OsStackInit(VOID *stacktop, UINT32 stacksize); + +/** + * @ingroup los_task + * @brief Get stack waterline. + * + * @par Description: + * This API is used to get stack waterline size and check stack whether overflow. + * + * @attention None + * + * @param stackBottom [IN] Type #const UINTPTR * pointer to stack bottom. + * @param stackTop [IN] Type #const UINTPTR * pointer to stack top. + * @param peakUsed [OUT] Type #UINT32 * stack waterline. + * + * @retval #LOS_NOK stack overflow + * @retval #LOS_OK stack is normal, not overflow + * @par Dependency: + *
  • los_stackinfo_pri.h: the header file that contains the API declaration.
+ * @see + * @since Huawei LiteOS V200R003C00 + */ +extern UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_STACK_INFO_PRI_H */ \ No newline at end of file diff --git a/kernel/base/include/los_swtmr.ph b/kernel/base/include/los_swtmr.ph deleted file mode 100644 index 2eff71ae4..000000000 --- a/kernel/base/include/los_swtmr.ph +++ /dev/null @@ -1,176 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_SWTMR_PH -#define _LOS_SWTMR_PH - -#include "los_swtmr.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -/** - * @ingroup los_swtmr - * Software timer state - */ -enum enSwTmrState -{ - 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 tagSwTmrHandlerItem -{ - SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ - UINT32 uwArg; /**< Parameter passed in when the callback function that handles software timer timeout is called */ -} SWTMR_HANDLER_ITEM_S; - -/** - * @ingroup los_swtmr - * Type of the pointer to the structure of the callback function that handles software timer timeout - */ -typedef SWTMR_HANDLER_ITEM_S *SWTMR_HANDLER_ITEM_P; - -extern SWTMR_CTRL_S *m_pstSwtmrCBArray; - -#define OS_SWT_FROM_SID(SwTmrID) ((SWTMR_CTRL_S *)m_pstSwtmrCBArray + (SwTmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT)) - -/** - *@ingroup los_swtmr - *@brief Scan a software timer. - * - *@par Description: - *
    - *
  • This API is used to scan a software timer when a Tick interrupt occurs and determine whether the software timer expires.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval None. - *@par Dependency: - *
  • los_swtmr.ph: the header file that contains the API declaration.
- *@see LOS_SwtmrStop - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osSwtmrScan(VOID); - -/** - *@ingroup los_swtmr - *@brief Initialization software timer. - * - *@par Description: - *
    - *
  • This API is used to initialization software.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval None. - *@par Dependency: - *
  • los_swtmr.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osSwTmrInit(VOID); - -/** - *@ingroup los_swtmr - *@brief Get next timeout. - * - *@par Description: - *
    - *
  • This API is used to get next timeout.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param None. - * - *@retval None. - *@par Dependency: - *
  • los_swtmr.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osSwTmrGetNextTimeout(VOID); - -/** - *@ingroup los_swtmr - *@brief Adjust software timer list. - * - *@par Description: - *
    - *
  • This API is used to adjust software timer list.
  • - *
- *@attention - *
    - *
  • None.
  • - *
- * - *@param UINT32 Sleep time. - * - *@retval UINT32 Sleep time. - *@par Dependency: - *
  • los_swtmr.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -extern VOID osSwTmrAdjust(UINT32 uwSleepTime); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_SWTMR_PH */ diff --git a/kernel/base/include/los_swtmr_pri.h b/kernel/base/include/los_swtmr_pri.h new file mode 100644 index 000000000..9b2d87d2b --- /dev/null +++ b/kernel/base/include/los_swtmr_pri.h @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Software Timer Manager Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_SWTMR_PRI_H +#define _LOS_SWTMR_PRI_H + +#include "los_swtmr.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_swtmr_pri + * 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_pri + * Structure of the callback function that handles software timer timeout + */ +typedef struct { + SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */ + UINTPTR arg; /**< Parameter passed in when the callback function + that handles software timer timeout is called */ +} SwtmrHandlerItem; + +/** + * @ingroup los_swtmr_pri + * Type of the pointer to the structure of the callback function that handles software timer timeout + */ +typedef SwtmrHandlerItem *SwtmrHandlerItemPtr; + +/** + * @ingroup los_swtmr + * Configuration item for software timer to use dynamic memory + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +#define LOSCFG_BASE_CORE_SWTMR_DYN_MEM YES +#else +#define LOSCFG_BASE_CORE_SWTMR_DYN_MEM NO +#endif + +#if (LOSCFG_BASE_CORE_SWTMR_DYN_MEM == YES) +extern SWTMR_CTRL_S *g_swtmrCBArray; +#else +extern LITE_OS_SEC_BSS SWTMR_CTRL_S g_swtmrCBArray[LOSCFG_BASE_CORE_SWTMR_LIMIT]; +#endif +extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */ + +#define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT)) + +/** + * @ingroup los_swtmr_pri + * @brief Scan a software timer. + * + * @par Description: + *
    + *
  • This API is used to scan a software timer when a Tick interrupt occurs and determine whether + * the software timer expires.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
+ * + * @param None. + * + * @retval None. + * @par Dependency: + *
  • los_swtmr_pri.h: the header file that contains the API declaration.
+ * @see LOS_SwtmrStop + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsSwtmrScan(VOID); +extern UINT32 OsSwtmrInit(VOID); +extern VOID OsSwtmrTask(VOID); +extern SPIN_LOCK_S g_swtmrSpin; +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SWTMR_PRI_H */ diff --git a/kernel/base/include/los_sys.ph b/kernel/base/include/los_sys.ph deleted file mode 100644 index cfc8c089a..000000000 --- a/kernel/base/include/los_sys.ph +++ /dev/null @@ -1,116 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_SYS_PH -#define _LOS_SYS_PH - -#include "los_base.ph" - -#include "los_sys.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 - *@brief Convert cycles to milliseconds. - * - *@par Description: - *This API is used to convert cycles to milliseconds. - *@attention - *
    - *
  • None.
  • - *
- * - *@param udwCycle [IN] Number of cycles. - * - *@retval Number of milliseconds obtained through the conversion. Cycles are successfully converted to milliseconds. - *@par Dependency: - *
  • los_sys.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -STATIC_INLINE UINT64 osCycle2MS(UINT64 ullCycle) -{ - return (UINT64)((ullCycle / (OS_SYS_CLOCK / 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 - *
    - *
  • None.
  • - *
- * - *@param udwCycle [IN] Number of cycles. - * - *@retval Number of microseconds obtained through the conversion. Cycles are successfully converted to microseconds. - *@par Dependency: - *
  • los_sys.ph: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 - */ -STATIC_INLINE UINT64 osCycle2US(UINT64 ullCycle) -{ - UINT64 ullTmp = OS_SYS_CLOCK / OS_SYS_US_PER_SECOND; - return (UINT64)(ullCycle / ullTmp); -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_SYS_PH */ diff --git a/kernel/base/include/los_sys_pri.h b/kernel/base/include/los_sys_pri.h new file mode 100644 index 000000000..80d132d5d --- /dev/null +++ b/kernel/base/include/los_sys_pri.h @@ -0,0 +1,107 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System time Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_SYS_PRI_H +#define _LOS_SYS_PRI_H + +#include "los_sys.h" +#include "los_base_pri.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 + * Number of nanoseconds in one second. + */ +#define OS_SYS_NS_PER_SECOND 1000000000 + +/** + * @ingroup los_sys + * Number of microseconds in one milliseconds. + */ +#define OS_SYS_US_PER_MS 1000 + +/** + * @ingroup los_sys + * Number of nanoseconds in one milliseconds. + */ +#define OS_SYS_NS_PER_MS 1000000 + +/** + * @ingroup los_sys + * Number of nanoseconds in one microsecond. + */ +#define OS_SYS_NS_PER_US 1000 + +/** + * @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 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SYS_PRI_H */ diff --git a/kernel/base/include/los_task.ph b/kernel/base/include/los_task.ph deleted file mode 100644 index 3427be8ef..000000000 --- a/kernel/base/include/los_task.ph +++ /dev/null @@ -1,606 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_TASK_PH -#define _LOS_TASK_PH - -#include "los_task.h" - -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) -#include -#endif - -#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 or task control block status. - * - * The task is blocked on a mutex. - */ -#define OS_TASK_STATUS_PEND_MUT 0x4000 - -/** - * @ingroup los_task - * Flag that indicates the task or task control block status. - * - * The task is blocked on a semaphore. - */ -#define OS_TASK_STATUS_PEND_SEM 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 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 uwTaskID [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: -*
  • los_task.ph: the header file that contains the API declaration.
-* @see -* @since Huawei LiteOS V100R001C00 -*/ -#define OS_TSK_GET_INDEX(uwTaskID) (uwTaskID) - -/** -* @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: -*
  • los_task.ph: the header file that contains the API declaration.
-* @see -* @since Huawei LiteOS V100R001C00 -*/ -#define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LOS_TASK_CB, stPendList) - -/** -* @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: -*
  • los_task.ph: the header file that contains the API declaration.
-* @see -* @since Huawei LiteOS V100R001C00 -*/ -#define OS_TCB_FROM_TID(TaskID) (((LOS_TASK_CB *)g_pstTaskCBArray) + (TaskID)) -#define OS_IDLE_TASK_ENTRY ((TSK_ENTRY_FUNC)osIdleTask) - -/** - * @ingroup los_task - * Define the task control block structure. - */ -typedef struct tagTaskCB -{ - VOID *pStackPointer; /**< Task stack pointer */ - UINT16 usTaskStatus; - UINT16 usPriority; - UINT32 uwStackSize; /**< Task stack size */ - UINT32 uwTopOfStack; /**< Task stack top */ - UINT32 uwTaskID; /**< Task ID */ - TSK_ENTRY_FUNC pfnTaskEntry; /**< Task entrance function */ - VOID *pTaskSem; /**< Task-held semaphore */ - VOID *pTaskMux; /**< Task-held mutex */ - UINT32 uwArg; /**< Parameter */ - CHAR *pcTaskName; /**< Task name */ - LOS_DL_LIST stPendList; - LOS_DL_LIST stTimerList; - UINT32 uwIdxRollNum; - EVENT_CB_S uwEvent; - UINT32 uwEventMask; /**< Event mask */ - UINT32 uwEventMode; /**< Event mode */ - VOID *puwMsg; /**< Memory allocated to queues */ -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) - struct _reent stNewLibReent; /**< NewLib _reent struct */ -#endif -} LOS_TASK_CB; - -typedef struct stLosTask -{ - LOS_TASK_CB *pstRunTask; - LOS_TASK_CB *pstNewTask; -} ST_LOS_TASK; - -extern ST_LOS_TASK g_stLosTask; - -/** - * @ingroup los_task - * Task lock flag. - * - */ -extern UINT16 g_usLosTaskLock; - -/** - * @ingroup los_task - * Maximum number of tasks. - * - */ -extern UINT32 g_uwTskMaxNum; - -/** - * @ingroup los_task - * Idle task ID. - * - */ -extern UINT32 g_uwIdleTaskID; - -/** - * @ingroup los_task - * Software timer task ID. - * - */ -extern UINT32 g_uwSwtmrTaskID; - -/** - * @ingroup los_task - * Starting address of a task. - * - */ -extern LOS_TASK_CB *g_pstTaskCBArray; - -/** - * @ingroup los_task - * Delayed task linked list. - * - */ -extern LOS_DL_LIST g_stTaskTimerList; - -/** - * @ingroup los_task - * Free task linked list. - * - */ -extern LOS_DL_LIST g_stLosFreeTask; - -/** - * @ingroup los_task - * Circular linked list that stores tasks that are deleted automatically. - * - */ -extern LOS_DL_LIST g_stTskRecyleList; - -/** - * @ingroup los_task - * Time slice structure. - */ -typedef struct tagTaskTimeSlice -{ - LOS_TASK_CB *pstTask; /**< Current running task */ - UINT16 usTime; /**< Expiration time point */ - UINT16 usTout; /**< Expiration duration */ -} OS_TASK_ROBIN_S; - -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 - *
    - *
  • The pstTaskCB should be a correct pointer to task control block structure.
  • - *
  • the usPriority should be in [0, OS_TASK_PRIORITY_LOWEST].
  • - *
- * - * @param pstTaskCB [IN] Type #LOS_TASK_CB * pointer to task control block structure. - * @param usPriority [IN] Type #UINT16 the priority of task. - * - * @retval None. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskPriModify(LOS_TASK_CB *pstTaskCB, UINT16 usPriority); - -/** - * @ingroup los_task - * @brief Scan a task. - * - * @par Description: - * This API is used to scan a task. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param None. - * - * @retval None. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskScan(VOID); - -/** - * @ingroup los_task - * @brief Initialization a task. - * - * @par Description: - * This API is used to initialization a task. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param None. - * - * @retval UINT32 Initialization result. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osTaskInit(VOID); - -/** - * @ingroup los_task - * @brief Create idle task. - * - * @par Description: - * This API is used to create idle task. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param None. - * - * @retval UINT32 Create result. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osIdleTaskCreate(VOID); - -/** - * @ingroup los_task - * @brief Check task switch. - * - * @par Description: - * This API is used to check task switch. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param None. - * - * @retval None. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskSwitchCheck(VOID); - -/** - * @ingroup los_task - * @brief TaskMonInit. - * - * @par Description: - * This API is used to taskMonInit. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param None. - * - * @retval None. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskMonInit(VOID); - -/** - * @ingroup los_task - * @brief Task entry. - * - * @par Description: - * This API is used to task entry. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param uwTaskID [IN] Type #UINT32 task id. - * - * @retval None. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskEntry(UINT32 uwTaskID); - -/** - * @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 - *
    - *
  • The pstList should be a vaild pointer to pendlist.
  • - *
- * - * @param pstList [IN] Type #LOS_DL_LIST * pointer to list which running task will be pended. - * @param uwTaskStatus [IN] Type #UINT32 Task Status. - * @param uwTimeOut [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: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see osTaskWake - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskWait(LOS_DL_LIST *pstList, UINT32 uwTaskStatus, UINT32 uwTimeOut); - -/** - * @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 - *
    - *
  • The pstList should be a vaild pointer to pend list.
  • - *
- * - * @param pstResumedTask [IN] Type #LOS_TASK_CB * pointer to the task which will be add to priqueue. - * @param uwTaskStatus [IN] Type #UINT32 Task Status. - * - * @retval None. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see osTaskWait - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osTaskWake(LOS_TASK_CB *pstResumedTask, UINT32 uwTaskStatus); - -/** - * @ingroup los_task - * @brief Get the task water line. - * - * @par Description: - * This API is used to get the task water line. - * - * @attention - *
    - *
  • None.
  • - *
- * - * @param uwTaskID [IN] Type #UINT32 task id. - * - * @retval UINT32 Task water line. - * @par Dependency: - *
  • los_task.ph: the header file that contains the API declaration.
- * @see None. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osGetTaskWaterLine(UINT32 uwTaskID); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_TASK_PH */ diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h new file mode 100644 index 000000000..9e90181da --- /dev/null +++ b/kernel/base/include/los_task_pri.h @@ -0,0 +1,506 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Task Module Implementation Private HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_TASK_PRI_H +#define _LOS_TASK_PRI_H + +#include "los_task.h" +#include "los_sched_pri.h" +#include "los_sortlink_pri.h" +#include "los_spinlock.h" +#include "los_stackinfo_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_task + * Define task siginal types. + * + * Task siginal types. + */ +#define SIGNAL_NONE 0U +#define SIGNAL_KILL (1U << 0) +#define SIGNAL_SUSPEND (1U << 1) +#define SIGNAL_AFFI (1U << 2) + +/* scheduler lock */ +extern SPIN_LOCK_S g_taskSpin; +#define SCHEDULER_LOCK(state) LOS_SpinLockSave(&g_taskSpin, &(state)) +#define SCHEDULER_UNLOCK(state) LOS_SpinUnlockRestore(&g_taskSpin, state) + +/* default and non-running task's ownership id */ +#define OS_TASK_INVALID_CPUID 0xFFFF + +/** + * @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 0x0001U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is suspended. + */ +#define OS_TASK_STATUS_SUSPEND 0x0002U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is ready. + */ +#define OS_TASK_STATUS_READY 0x0004U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is blocked. + */ +#define OS_TASK_STATUS_PEND 0x0008U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is running. + */ +#define OS_TASK_STATUS_RUNNING 0x0010U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is delayed. + */ +#define OS_TASK_STATUS_DELAY 0x0020U + +/** + * @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 0x0040U + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is pend for a period of time. + */ +#define OS_TASK_STATUS_PEND_TIME 0x0080U + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * The task is automatically deleted. + */ +#define OS_TASK_FLAG_DETACHED 0x0001 + +/** + * @ingroup los_task + * Flag that indicates the task property. + * + * The task is system-level task, like idle, swtmr and etc. + */ +#define OS_TASK_FLAG_SYSTEM 0x0002 + +/** + * @ingroup los_task + * Boundary on which the stack size is aligned. + * + */ +#define OS_TASK_STACK_SIZE_ALIGN 16U + +/** + * @ingroup los_task + * Boundary on which the stack address is aligned. + * + */ +#define OS_TASK_STACK_ADDR_ALIGN 8U + +/** + * @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 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: +*
  • los_task_pri.h: the header file that contains the API declaration.
+* @see +* @since Huawei LiteOS V100R001C00 +*/ +#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: +*
  • los_task_pri.h: the header file that contains the API declaration.
+* @see +* @since Huawei LiteOS V100R001C00 +*/ +#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: +*
  • los_task_pri.h: the header file that contains the API declaration.
+* @see +* @since Huawei LiteOS V100R001C00 +*/ +#define OS_TCB_FROM_TID(taskID) (((LosTaskCB *)g_taskCBArray) + (taskID)) + +#ifndef LOSCFG_STACK_POINT_ALIGN_SIZE +#define LOSCFG_STACK_POINT_ALIGN_SIZE (sizeof(UINTPTR) * 2) +#endif + +/** + * @ingroup los_task + * @brief Dynamic memory init switch + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +#define LOSCFG_BASE_CORE_TASK_DYN_MEM YES +#else +#define LOSCFG_BASE_CORE_TASK_DYN_MEM NO +#endif + + +typedef struct { + VOID *stackPointer; /**< Task stack pointer */ + UINT16 taskStatus; /**< Task status */ + UINT16 priority; /**< Task priority */ + UINT32 taskFlags; /**< Task extend flags */ + UINT32 stackSize; /**< Task stack size */ + UINTPTR topOfStack; /**< Task stack top */ + UINT32 taskID; /**< Task ID */ + TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ + VOID *taskSem; /**< Task-held semaphore */ + VOID *threadJoin; /**< pthread adaption */ + VOID *threadJoinRetval; /**< pthread adaption */ + VOID *taskMux; /**< Task-held mutex */ + UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */ + CHAR *taskName; /**< Task name */ + LOS_DL_LIST pendList; /**< Task pend node */ + SortLinkList sortList; /**< Task sortlink node */ + EVENT_CB_S event; + UINT32 eventMask; /**< Event mask */ + UINT32 eventMode; /**< Event mode */ + VOID *msg; /**< Memory allocated to queues */ + UINT32 priBitMap; /**< BitMap for recording the change of task priority, + the priority can not be greater than 31 */ + UINT32 signal; /**< Task signal */ +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + UINT16 timeSlice; /**< Remaining time slice */ +#endif +} LosTaskCB; + +typedef struct { + LosTaskCB *runTask; + LosTaskCB *newTask; +} LosTask; + + +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; +/** + * @ingroup los_task + * Maximum number of tasks. + * + */ +extern UINT32 g_taskMaxNum; + + +/** + * @ingroup los_task + * Starting address of a task. + * + */ +#if (LOSCFG_BASE_CORE_TASK_DYN_MEM == YES) +extern LosTaskCB *g_taskCBArray; +#else +extern LosTaskCB g_taskCBArray[]; +#endif + +/** + * @ingroup los_task + * Time slice structure. + */ +typedef struct { + LosTaskCB *task; /**< Current running task */ + UINT16 time; /**< Expiration time point */ + UINT16 timeout; /**< Expiration duration */ +} OsTaskRobin; + +STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID) +{ + return (LosTaskCB *)ArchCurrTaskGet(); +} + +STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task) +{ + ArchCurrTaskSet((VOID *)task); +} + +extern VOID OsTaskSchedule(LosTaskCB *, LosTaskCB *); +extern VOID OsStartToRun(LosTaskCB *); +extern VOID OsTaskScan(VOID); +extern VOID OsIdleTask(VOID); +extern UINT32 OsIdleTaskCreate(VOID); +extern UINT32 OsTaskInit(VOID); +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) +extern VOID OsTaskMonInit(VOID); +#endif +extern UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv); + +/* get task info */ +#define OS_ALL_TASK_MASK 0xFFFFFFFF +extern UINT32 OsShellCmdTskInfoGet(UINT32 taskID); + +extern VOID* OsGetMainTask(VOID); +extern VOID OsSetMainTask(VOID); +extern LosTaskCB* OsGetTopTask(VOID); +extern UINT32 OsGetIdleTaskId(VOID); + +/** + * @ingroup los_task + * @brief Modify the priority of task. + * + * @par Description: + * This API is used to modify the priority of task. + * + * @attention + *
    + *
  • The taskCB should be a correct pointer to task control block structure.
  • + *
  • the priority should be in [0, OS_TASK_PRIORITY_LOWEST].
  • + *
+ * + * @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure. + * @param priority [IN] Type #UINT16 the priority of task. + * + * @retval None. + * @par Dependency: + *
  • los_task_pri.h: the header file that contains the API declaration.
+ * @see + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority); + +/** + * @ingroup los_task + * @brief Add task to sorted delay list. + * + * @par Description: + * This API is used to add task to sorted delay list. + * + * @attention + *
    + *
  • The taskCB should be a correct pointer to task control block structure.
  • + *
+ * + * @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure. + * @param timeout [IN] Type #UINT32 wait time, ticks. + * + * @retval None. + * @par Dependency: + *
  • los_task_pri.h: the header file that contains the API declaration.
+ * @see OsTimerListDelete + * @since Huawei LiteOS V100R001C00 + */ +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 + *
    + *
  • The taskCB should be a correct pointer to task control block structure.
  • + *
+ * + * @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure. + * + * @retval None. + * @par Dependency: + *
  • los_task_pri.h: the header file that contains the API declaration.
+ * @see OsTaskAdd2TimerList + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsTimerListDelete(LosTaskCB *taskCB); + +/** + * @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 + *
    + *
  • The list should be a vaild pointer to pendlist.
  • + *
+ * + * @param list [IN] Type #LOS_DL_LIST * pointer to list which running task will be pended. + * @param taskStatus [IN] Type #UINT16 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: + *
  • los_task_pri.h: the header file that contains the API declaration.
+ * @see OsTaskWake + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsTaskWait(LOS_DL_LIST *list, UINT16 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 + *
    + *
  • The resumedTask should be the task which will be add to priqueue.
  • + *
+ * + * @param resumedTask [IN] Type #LosTaskCB * pointer to the task which will be add to priqueue. + * @param taskStatus [IN] Type #UINT16 Task Status. + * + * @retval None. + * @par Dependency: + *
  • los_task_pri.h: the header file that contains the API declaration.
+ * @see OsTaskWait + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsTaskWake(LosTaskCB *resumedTask, UINT16 taskStatus); + +extern VOID OsTaskEntry(UINT32 taskID); +extern SortLinkAttribute *OsTaskSortLinkGet(VOID); +extern UINT32 OsTaskSwitchCheck(LosTaskCB *oldTask, LosTaskCB *newTask); +extern UINT32 OsTaskProcSignal(VOID); +extern VOID OsSchedStatistics(LosTaskCB *runTask, LosTaskCB *newTask); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TASK_PRI_H */ diff --git a/kernel/base/include/los_tick.ph b/kernel/base/include/los_tick_pri.h similarity index 67% rename from kernel/base/include/los_tick.ph rename to kernel/base/include/los_tick_pri.h index 866b7abfa..28917d247 100644 --- a/kernel/base/include/los_tick.ph +++ b/kernel/base/include/los_tick_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tick Private HeadFile * 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 @@ -22,20 +22,22 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_TICK_PH -#define _LOS_TICK_PH +#ifndef _LOS_TICK_PRI_H +#define _LOS_TICK_PRI_H +#include "los_base.h" #include "los_tick.h" +#include "los_spinlock.h" #ifdef __cplusplus #if __cplusplus @@ -43,29 +45,23 @@ 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_uwTicksPerSec; +/* spinlock for tick */ +extern SPIN_LOCK_S g_tickSpin; +#define TICK_LOCK(state) LOS_SpinLockSave(&g_tickSpin, &(state)) +#define TICK_UNLOCK(state) LOS_SpinUnlockRestore(&g_tickSpin, (state)) /** * @ingroup los_tick - * Cycles per Second + * Count of Ticks */ -extern UINT32 g_uwCyclePerSec; +extern volatile UINT64 g_tickCount[]; /** * @ingroup los_tick - * Cycles per Tick + * Cycle to nanosecond scale */ -extern UINT32 g_uwCyclesPerTick; +extern DOUBLE g_cycle2NsScale; /** * @ingroup los_tick @@ -83,15 +79,22 @@ extern UINT32 g_uwCyclesPerTick; * * @retval None. * @par Dependency: -*
  • los_tick.ph: the header file that contains the API declaration.
+*
  • los_tick.h: the header file that contains the API declaration.
* @see None. * @since Huawei LiteOS V100R001C00 */ -extern VOID osTickHandler(VOID); +extern VOID OsTickHandler(VOID); -#if (LOSCFG_KERNEL_TICKLESS == YES) -LITE_OS_SEC_TEXT VOID osTickHandlerLoop(UINT32 uwElapseTicks); -#endif +/** + * @ingroup los_tick + * Convert from the cycle count to nanosecond. + */ +#define CYCLE_TO_NS(cycles) ((cycles) * g_cycle2NsScale) + +/** + * Current system timer register is 32 bit, therefore TIMER_MAXLOAD define just in order to avoid ambiguity. + */ +#define TIMER_MAXLOAD 0xffffffff #ifdef __cplusplus #if __cplusplus @@ -99,4 +102,4 @@ LITE_OS_SEC_TEXT VOID osTickHandlerLoop(UINT32 uwElapseTicks); #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* _LOS_TICK_PH */ +#endif /* _LOS_TICK_PRI_H */ diff --git a/kernel/base/ipc/los_sem.inc b/kernel/base/include/los_timeslice_pri.h similarity index 64% rename from kernel/base/ipc/los_sem.inc rename to kernel/base/include/los_timeslice_pri.h index 698ef540a..394d47411 100644 --- a/kernel/base/ipc/los_sem.inc +++ b/kernel/base/include/los_timeslice_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Timeslice Private HeadFile * 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 @@ -22,20 +22,25 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_SEM_INC -#define _LOS_SEM_INC +/** + * @defgroup los_timeslice Timeslice + * @ingroup kernel + */ -#include "los_sem.ph" +#ifndef _LOS_TIMESLICE_PRI_H +#define _LOS_TIMESLICE_PRI_H + +#include "los_typedef.h" #ifdef __cplusplus #if __cplusplus @@ -43,30 +48,29 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -extern SEM_CB_S *g_pstAllSem; - /** - *@ingroup los_sem - *@brief Create Semaphore. + * @ingroup los_timeslice + * @brief Check time slices. * - *@par Description: - *This API is used to create Semaphore. - *@attention - *
    - *
  • None.
  • - *
+ * @par Description: + *
    + *
  • This API is used to check time slices. If the number of Ticks equals to the time for task switch, + * tasks are switched. Otherwise, the Tick counting continues.
  • + *
+ * @attention + *
    + *
  • None.
  • + *
* - *@param usCount [IN]Type #UINT16 Semaphore count. - *@param usMaxCount [IN]Type #UINT16 Max semaphore count. - *@param puwSemHandle [OUT]Type #UINT32 * Index of semaphore. + * @param None. * - *@retval UINT32 Create result. - *@par Dependency: - *
  • los_sem.inc: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 + * @retval None. + * @par Dependency: + *
  • los_timeslice_pri.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS V100R001C00 */ -UINT32 osSemCreate (UINT16 usCount, UINT16 usMaxCount, UINT32 *puwSemHandle); +extern VOID OsTimesliceCheck(VOID); #ifdef __cplusplus #if __cplusplus @@ -74,4 +78,4 @@ UINT32 osSemCreate (UINT16 usCount, UINT16 usMaxCount, UINT32 *puwSemHandle); #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* _LOS_SEM_INC */ +#endif /* _LOS_TIMESLICE_PRI_H */ diff --git a/kernel/base/include/los_list.ph b/kernel/base/include/los_typedef_pri.h similarity index 77% rename from kernel/base/include/los_list.ph rename to kernel/base/include/los_typedef_pri.h index 289ac8948..11947349b 100644 --- a/kernel/base/include/los_list.ph +++ b/kernel/base/include/los_typedef_pri.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Base Definitions Private HeadFile * 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 @@ -22,19 +22,19 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_LIST_PH -#define _LOS_LIST_PH +#ifndef _LOS_TYPEDEF_PRI_H +#define _LOS_TYPEDEF_PRI_H -#include "los_list.h" +#include "los_typedef.h" -#endif /* _LOS_LIST_PH */ +#endif /* _LOS_TYPEDEF_PRI_H */ diff --git a/kernel/base/ipc/Makefile b/kernel/base/ipc/Makefile deleted file mode 100644 index 599bd9994..000000000 --- a/kernel/base/ipc/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -objs-y += los_sem.o -objs-y += los_mux.o -objs-y += los_queue.o -objs-y += los_event.o diff --git a/kernel/base/ipc/los_event.c b/kernel/base/ipc/los_event.c index a1dc31ff7..f0657463d 100644 --- a/kernel/base/ipc/los_event.c +++ b/kernel/base/ipc/los_event.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Event * 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 @@ -22,246 +22,327 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_priqueue.ph" -#include "los_task.ph" -#include "los_hw.h" -#include "los_hwi.h" -#include "los_event.inc" +#include "los_event_pri.h" +#include "los_task_pri.h" +#include "los_spinlock.h" + +#if (LOSCFG_BASE_CORE_SWTMR == YES) +#include "los_exc.h" +#endif #ifdef __cplusplus #if __cplusplus -extern "C"{ +extern "C" { #endif #endif /* __cplusplus */ - -LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S pstEventCB) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB) { - if (pstEventCB == NULL) - { + UINT32 intSave; + + if (eventCB == NULL) { return LOS_ERRNO_EVENT_PTR_NULL; } - pstEventCB->uwEventID = 0; - LOS_ListInit(&pstEventCB->stEventList); - return LOS_OK; -} -LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *uwEventID, UINT32 uwEventMask, UINT32 uwMode) -{ - UINT32 uwRet = 0; - UINTPTR uvIntSave; - - uvIntSave = LOS_IntLock(); - if (uwMode & LOS_WAITMODE_OR) - { - if (0 != (*uwEventID & uwEventMask)) - { - uwRet = *uwEventID & uwEventMask; - } - } - else - { - if ((uwEventMask != 0) && (uwEventMask == (*uwEventID & uwEventMask))) - { - uwRet = *uwEventID & uwEventMask; - } - } - - if (uwRet && (LOS_WAITMODE_CLR & uwMode)) - { - *uwEventID = *uwEventID & ~(uwRet); - } - - LOS_IntRestore(uvIntSave); - return uwRet; + intSave = LOS_IntLock(); + eventCB->uwEventID = 0; + LOS_ListInit(&eventCB->stEventList); + LOS_IntRestore(intSave); + return LOS_OK; } -LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S pstEventCB, UINT32 uwEventMask, UINT32 uwMode, UINT32 uwTimeOut) +LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode) { - UINT32 uwRet = 0; - UINTPTR uvIntSave; - LOS_TASK_CB *pstRunTsk; - - if (pstEventCB == NULL) - { + if (ptr == NULL) { return LOS_ERRNO_EVENT_PTR_NULL; } - if ((pstEventCB->stEventList.pstNext == NULL) || (pstEventCB->stEventList.pstPrev == NULL)) - { - return LOS_ERRNO_EVENT_NOT_INITIALIZED; - } - - if (uwEventMask == 0) - { + if (eventMask == 0) { return LOS_ERRNO_EVENT_EVENTMASK_INVALID; } - if (uwEventMask & LOS_ERRTYPE_ERROR) - { + if (eventMask & LOS_ERRTYPE_ERROR) { return LOS_ERRNO_EVENT_SETBIT_INVALID; } - if (((uwMode & LOS_WAITMODE_OR) && (uwMode & LOS_WAITMODE_AND)) || - uwMode & ~(LOS_WAITMODE_OR | LOS_WAITMODE_AND | LOS_WAITMODE_CLR) || - !(uwMode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) - { + 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; +} - if (OS_INT_ACTIVE) - { - return LOS_ERRNO_EVENT_READ_IN_INTERRUPT; - } +LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) +{ + UINT32 ret = 0; - uvIntSave = LOS_IntLock(); - uwRet = LOS_EventPoll(&(pstEventCB->uwEventID), uwEventMask, uwMode); + LOS_ASSERT(OsIntLocked()); + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); - if (uwRet == 0) - { - if (uwTimeOut == 0) - { - (VOID)LOS_IntRestore(uvIntSave); - return uwRet; + if (mode & LOS_WAITMODE_OR) { + if ((*eventID & eventMask) != 0) { + ret = *eventID & eventMask; } - - if (g_usLosTaskLock) - { - (VOID)LOS_IntRestore(uvIntSave); - return LOS_ERRNO_EVENT_READ_IN_LOCK; + } else { + if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) { + ret = *eventID & eventMask; } + } - pstRunTsk = g_stLosTask.pstRunTask; - pstRunTsk->uwEventMask = uwEventMask; - pstRunTsk->uwEventMode = uwMode; - osTaskWait(&pstEventCB->stEventList, OS_TASK_STATUS_PEND, uwTimeOut); - (VOID)LOS_IntRestore(uvIntSave); - LOS_Schedule(); + if (ret && (mode & LOS_WAITMODE_CLR)) { + *eventID = *eventID & ~ret; + } - if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) - { - uvIntSave = LOS_IntLock(); - pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); - (VOID)LOS_IntRestore(uvIntSave); - return LOS_ERRNO_EVENT_READ_TIMEOUT; - } + return ret; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode) +{ + UINT32 ret; + LosTaskCB *runTask = NULL; - uvIntSave = LOS_IntLock(); - uwRet = LOS_EventPoll(&pstEventCB->uwEventID,uwEventMask,uwMode); - (VOID)LOS_IntRestore(uvIntSave); + ret = OsEventParamCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; } - else - { - (VOID)LOS_IntRestore(uvIntSave); + + if (OS_INT_ACTIVE) { + return LOS_ERRNO_EVENT_READ_IN_INTERRUPT; } - return uwRet; + runTask = OsCurrTaskGet(); + if (runTask->taskFlags & OS_TASK_FLAG_SYSTEM) { + return LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK; + } + return LOS_OK; } -LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S pstEventCB, UINT32 uwEvents) +LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, + UINT32 timeout, UINT32 intSave) { - LOS_TASK_CB *pstResumedTask; - LOS_TASK_CB *pstNextTask = (LOS_TASK_CB *)NULL; - UINTPTR uvIntSave; - UINT8 ucExitFlag = 0; + LosTaskCB *runTask = OsCurrTaskGet(); - if (pstEventCB == NULL) - { - return LOS_ERRNO_EVENT_PTR_NULL; + if (timeout == 0) { + return LOS_OK; } - if ((pstEventCB->stEventList.pstNext == NULL) || (pstEventCB->stEventList.pstPrev == NULL)) - { - return LOS_ERRNO_EVENT_NOT_INITIALIZED; + if (!OsPreemptableInSched()) { + return LOS_ERRNO_EVENT_READ_IN_LOCK; } - if (uwEvents & LOS_ERRTYPE_ERROR) - { - return LOS_ERRNO_EVENT_SETBIT_INVALID; + runTask->eventMask = eventMask; + runTask->eventMode = mode; + + OsTaskWait(&eventCB->stEventList, OS_TASK_STATUS_PEND, timeout); + + /* + * it will immediately do the scheduling, so there's no need to release the + * task spinlock. when this task's been rescheduled, it will be holding the spinlock. + */ + OsSchedResched(); + + SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); + + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + return LOS_ERRNO_EVENT_READ_TIMEOUT; } - uvIntSave = LOS_IntLock(); + return OsEventPoll(&eventCB->uwEventID, eventMask, mode); +} - pstEventCB->uwEventID |= uwEvents; - if (!LOS_ListEmpty(&pstEventCB->stEventList)) - { - for (pstResumedTask = LOS_DL_LIST_ENTRY((&pstEventCB->stEventList)->pstNext, LOS_TASK_CB, stPendList);/*lint !e413*/ - &pstResumedTask->stPendList != (&pstEventCB->stEventList);) - { - pstNextTask = LOS_DL_LIST_ENTRY(pstResumedTask->stPendList.pstNext, LOS_TASK_CB, stPendList); /*lint !e413*/ +LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout, + BOOL once) +{ + UINT32 ret; + UINT32 intSave; - if (((pstResumedTask->uwEventMode & LOS_WAITMODE_OR) && (pstResumedTask->uwEventMask & uwEvents) != 0) || - ((pstResumedTask->uwEventMode & LOS_WAITMODE_AND) && (pstResumedTask->uwEventMask & pstEventCB->uwEventID) == pstResumedTask->uwEventMask)) - { - ucExitFlag = 1; + ret = OsEventReadCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } - osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND); - } - pstResumedTask = pstNextTask; + SCHEDULER_LOCK(intSave); + if (!once) { + ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); + if (ret != 0) { + goto OUT; } + } + ret = OsEventReadImp(eventCB, eventMask, mode, timeout, intSave); +OUT: + SCHEDULER_UNLOCK(intSave); + return ret; +} - if (ucExitFlag == 1) - { - (VOID)LOS_IntRestore(uvIntSave); - LOS_Schedule(); - return LOS_OK; +LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT_CB_S eventCB, UINT32 events) +{ + UINT8 exitFlag = 0; + + 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); + } + + return exitFlag; +} + +LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once) +{ + LosTaskCB *resumedTask = NULL; + LosTaskCB *nextTask = NULL; + UINT32 intSave; + UINT8 exitFlag = 0; + + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; + } + + if (events & LOS_ERRTYPE_ERROR) { + return LOS_ERRNO_EVENT_SETBIT_INVALID; + } + + SCHEDULER_LOCK(intSave); + + 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 (OsEventResume(resumedTask, eventCB, events)) { + exitFlag = 1; + } + if (once == TRUE) { + break; + } + resumedTask = nextTask; } } - (VOID)LOS_IntRestore(uvIntSave); + SCHEDULER_UNLOCK(intSave); + + if (exitFlag == 1) { + LOS_Schedule(); + } return LOS_OK; } -LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestory(PEVENT_CB_S pstEventCB) +LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode) { - UINTPTR uvIntSave; + UINT32 ret; + UINT32 intSave; - if (pstEventCB == NULL) - { - return LOS_ERRNO_EVENT_PTR_NULL; + ret = OsEventParamCheck((VOID *)eventID, eventMask, mode); + if (ret != LOS_OK) { + return ret; } - uvIntSave = LOS_IntLock(); + SCHEDULER_LOCK(intSave); + ret = OsEventPoll(eventID, eventMask, mode); + SCHEDULER_UNLOCK(intSave); + return ret; +} - if (!LOS_ListEmpty(&pstEventCB->stEventList)) - { - (VOID)LOS_IntRestore(uvIntSave); - return LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY; +LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout) +{ + return OsEventRead(eventCB, eventMask, mode, timeout, FALSE); +} + +LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) +{ + return OsEventWrite(eventCB, events, FALSE); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, + UINT32 timeout) +{ + return OsEventRead(eventCB, eventMask, mode, timeout, TRUE); +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events) +{ + return OsEventWrite(eventCB, events, TRUE); +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) +{ + UINT32 intSave; + + if (eventCB == NULL) { + return LOS_ERRNO_EVENT_PTR_NULL; } - pstEventCB->stEventList.pstNext = (LOS_DL_LIST *)NULL; - pstEventCB->stEventList.pstPrev = (LOS_DL_LIST *)NULL; + SCHEDULER_LOCK(intSave); + if (!LOS_ListEmpty(&eventCB->stEventList)) { + SCHEDULER_UNLOCK(intSave); + return LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY; + } - (VOID)LOS_IntRestore(uvIntSave); + eventCB->uwEventID = 0; + LOS_ListDelInit(&eventCB->stEventList); + SCHEDULER_UNLOCK(intSave); return LOS_OK; } -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S pstEventCB, UINT32 uwEvents) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events) { - UINTPTR uvIntSave; + UINT32 intSave; - if (pstEventCB == NULL) - { + if (eventCB == NULL) { return LOS_ERRNO_EVENT_PTR_NULL; } - uvIntSave = LOS_IntLock(); - pstEventCB->uwEventID &= uwEvents; - (VOID)LOS_IntRestore(uvIntSave); + SCHEDULER_LOCK(intSave); + eventCB->uwEventID &= events; + SCHEDULER_UNLOCK(intSave); return LOS_OK; } +#ifdef LOSCFG_COMPAT_POSIX +LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB, + UINT32 eventMask, UINT32 mode, UINT32 timeout) +{ + UINT32 ret; + UINT32 intSave; + + ret = OsEventReadCheck(eventCB, eventMask, mode); + if (ret != LOS_OK) { + return ret; + } + + SCHEDULER_LOCK(intSave); + + if (*cond->realValue != cond->value) { + eventCB->uwEventID &= cond->clearEvent; + goto OUT; + } + + ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode); + if (ret != LOS_OK) { + goto OUT; + } + ret = OsEventReadImp(eventCB, eventMask, mode, timeout, intSave); +OUT: + SCHEDULER_UNLOCK(intSave); + return ret; +} +#endif #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/ipc/los_event.inc b/kernel/base/ipc/los_event.inc deleted file mode 100644 index a0e8d1a3f..000000000 --- a/kernel/base/ipc/los_event.inc +++ /dev/null @@ -1,40 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_EVENT_INC -#define _LOS_EVENT_INC - -#include "los_event.ph" - -#endif /* _LOS_EVENT_INC */ diff --git a/kernel/base/include/los_multipledlinkhead.ph b/kernel/base/ipc/los_ipcdebug.c similarity index 53% rename from kernel/base/include/los_multipledlinkhead.ph rename to kernel/base/ipc/los_ipcdebug.c index ed9e8b21c..32b8fe838 100644 --- a/kernel/base/include/los_multipledlinkhead.ph +++ b/kernel/base/ipc/los_ipcdebug.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: IPC Debug * 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 @@ -22,61 +22,73 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_MULTIPLE_DLINK_HEAD_PH -#define _LOS_MULTIPLE_DLINK_HEAD_PH +#include "los_ipcdebug_pri.h" +#include "sys_config.h" #ifdef __cplusplus #if __cplusplus extern "C" { +#endif #endif /* __cplusplus */ -#endif /* __cplusplus */ - -#include "los_list.h" -#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_DLnkInitHead LOS_DLnkInitMultiHead -#define OS_DLnkHead LOS_DLnkMultiHead -#define OS_DLnkNextHead LOS_DLnkNextMultiHead -#define OS_DLnkFirstHead LOS_DLnkFirstMultiHead -#define OS_MULTI_DLNK_HEAD_SIZE sizeof(LOS_MULTIPLE_DLNK_HEAD) +#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_DEBUG_MUTEX) || defined(LOSCFG_DEBUG_QUEUE) -typedef struct +VOID OsArraySortByTime(UINT32 *sortArray, UINT32 start, UINT32 end, const IpcSortParam *sortParam, + OsCompareFunc compareFunc) { - LOS_DL_LIST stListHead[OS_MULTI_DLNK_NUM]; -} LOS_MULTIPLE_DLNK_HEAD; + UINT32 left = start; + UINT32 right = end; + UINT32 idx = start; + UINT32 pivot = sortArray[start]; -LITE_OS_SEC_ALW_INLINE STATIC_INLINE LOS_DL_LIST *LOS_DLnkNextMultiHead(VOID *pHeadAddr, LOS_DL_LIST *pstListHead) -{ - LOS_MULTIPLE_DLNK_HEAD *head = (LOS_MULTIPLE_DLNK_HEAD *)pHeadAddr; + while (left < right) { + while ((left < right) && (sortArray[right] < sortParam->ipcDebugCBCnt) && (pivot < sortParam->ipcDebugCBCnt) && + compareFunc(sortParam, sortArray[right], pivot)) { + right--; + } - return (&(head->stListHead[OS_MULTI_DLNK_NUM - 1]) == pstListHead) ? NULL : (pstListHead + 1); -} + if (left < right) { + sortArray[left] = sortArray[right]; + idx = right; + left++; + } -LITE_OS_SEC_ALW_INLINE STATIC_INLINE LOS_DL_LIST *LOS_DLnkFirstMultiHead(VOID *pHeadAddr) -{ - return (LOS_DL_LIST *)pHeadAddr; + while ((left < right) && (sortArray[left] < sortParam->ipcDebugCBCnt) && (pivot < sortParam->ipcDebugCBCnt) && + compareFunc(sortParam, pivot, sortArray[left])) { + left++; + } + + if (left < right) { + sortArray[right] = sortArray[left]; + idx = left; + right--; + } + } + + sortArray[idx] = pivot; + + if (start < idx) { + OsArraySortByTime(sortArray, start, idx - 1, sortParam, compareFunc); + } + if (idx < end) { + OsArraySortByTime(sortArray, idx + 1, end, sortParam, compareFunc); + } } -extern VOID LOS_DLnkInitMultiHead(VOID *pHeadAddr); -extern LOS_DL_LIST *LOS_DLnkMultiHead(VOID *pHeadAddr, UINT32 uwSize); +#endif #ifdef __cplusplus #if __cplusplus } +#endif #endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_MULTIPLE_DLINK_HEAD_PH */ diff --git a/kernel/base/ipc/los_mux.c b/kernel/base/ipc/los_mux.c index 5008cd430..7acc0b715 100644 --- a/kernel/base/ipc/los_mux.c +++ b/kernel/base/ipc/los_mux.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex * 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 @@ -22,319 +22,401 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_mux.inc" -#include "los_err.ph" -#include "los_memory.ph" -#include "los_priqueue.ph" -#include "los_task.ph" -#if (LOSCFG_PLATFORM_EXC == YES) + * --------------------------------------------------------------------------- */ +#include "los_mux_pri.h" +#include "los_mux_debug_pri.h" +#include "los_bitmap.h" #include "los_exc.h" -#endif -#include "los_hw.h" +#include "los_err_pri.h" #ifdef __cplusplus #if __cplusplus -extern "C"{ +extern "C" { #endif #endif /* __cplusplus */ - #if (LOSCFG_BASE_IPC_MUX == YES) -LITE_OS_SEC_BSS MUX_CB_S *g_pstAllMux; -LITE_OS_SEC_BSS LOS_DL_LIST g_stUnusedMuxList; +#if (LOSCFG_BASE_IPC_MUX_DYN_MEM == YES) +LITE_OS_SEC_BSS LosMuxCB *g_allMux = NULL; +#else +#if (LOSCFG_BASE_IPC_MUX_LIMIT <= 0) +#error "mux maxnum cannot be zero" +#endif /* LOSCFG_BASE_IPC_MUX_LIMIT <= 0 */ +LITE_OS_SEC_BSS LosMuxCB g_allMux[LOSCFG_BASE_IPC_MUX_LIMIT]; +#endif +LITE_OS_SEC_DATA_INIT STATIC 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) +/* + * Description : Initializes the mutex + * Return : LOS_OK on success, or error code on failure + */ +LITE_OS_SEC_TEXT UINT32 OsMuxInit(VOID) { - MUX_CB_S *pstMuxNode; - UINT32 uwIndex; + LosMuxCB *muxNode = NULL; + UINT32 index; - LOS_ListInit(&g_stUnusedMuxList); +#if (LOSCFG_BASE_IPC_MUX_DYN_MEM == YES) + UINT32 size; - if (LOSCFG_BASE_IPC_MUX_LIMIT == 0) /*lint !e506*/ - { - return LOS_ERRNO_MUX_MAXNUM_ZERO; + size = LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(LosMuxCB); + /* system resident memory, don't free */ + g_allMux = (LosMuxCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_allMux == NULL) { + return LOS_ERRNO_MUX_NO_MEMORY; } + (VOID)memset_s(g_allMux, size, 0, size); +#endif - g_pstAllMux = (MUX_CB_S *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(MUX_CB_S))); - if (NULL == g_pstAllMux) - { - return LOS_ERRNO_MUX_NO_MEMORY; + LOS_ListInit(&g_unusedMuxList); + + for (index = 0; index < LOSCFG_BASE_IPC_MUX_LIMIT; index++) { + muxNode = g_allMux + index; + muxNode->muxID = index; + muxNode->muxStat = OS_MUX_UNUSED; + LOS_ListTailInsert(&g_unusedMuxList, &muxNode->muxList); } - for (uwIndex = 0; uwIndex < LOSCFG_BASE_IPC_MUX_LIMIT; uwIndex++) - { - pstMuxNode = ((MUX_CB_S *)g_pstAllMux) + uwIndex; - pstMuxNode->ucMuxID = uwIndex; - pstMuxNode->ucMuxStat = OS_MUX_UNUSED; - LOS_ListTailInsert(&g_stUnusedMuxList, &pstMuxNode->stMuxList); + if (OsMuxDbgInitHook() != LOS_OK) { + return LOS_ERRNO_MUX_NO_MEMORY; } return LOS_OK; } -/***************************************************************************** - Function : LOS_MuxCreate - Description : Create a mutex, - Input : None - Output : puwMuxHandle ------ Mutex operation handle - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MuxCreate (UINT32 *puwMuxHandle) +LITE_OS_SEC_TEXT UINT32 LOS_MuxCreate(UINT32 *muxHandle) { - UINT32 uwIntSave; - MUX_CB_S *pstMuxCreated; - LOS_DL_LIST *pstUnusedMux; - UINT32 uwErrNo; - UINT32 uwErrLine; - - if (NULL == puwMuxHandle) - { + UINT32 intSave; + LosMuxCB *muxCreated = NULL; + LOS_DL_LIST *unusedMux = NULL; + UINT32 errNo; + UINT32 errLine; + + if (muxHandle == NULL) { return LOS_ERRNO_MUX_PTR_NULL; } - uwIntSave = LOS_IntLock(); - if (LOS_ListEmpty(&g_stUnusedMuxList)) - { - LOS_IntRestore(uwIntSave); + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&g_unusedMuxList)) { + SCHEDULER_UNLOCK(intSave); + OsMutexCheckHook(); OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_ALL_BUSY); } - pstUnusedMux = LOS_DL_LIST_FIRST(&(g_stUnusedMuxList)); - LOS_ListDelete(pstUnusedMux); - pstMuxCreated = (GET_MUX_LIST(pstUnusedMux)); /*lint !e413*/ - pstMuxCreated->usMuxCount = 0; - pstMuxCreated->ucMuxStat = OS_MUX_USED; - pstMuxCreated->usPriority = 0; - pstMuxCreated->pstOwner = (LOS_TASK_CB *)NULL; - LOS_ListInit(&pstMuxCreated->stMuxList); - *puwMuxHandle = (UINT32)pstMuxCreated->ucMuxID; - LOS_IntRestore(uwIntSave); + unusedMux = LOS_DL_LIST_FIRST(&g_unusedMuxList); + LOS_ListDelete(unusedMux); + muxCreated = LOS_DL_LIST_ENTRY(unusedMux, LosMuxCB, muxList); + muxCreated->muxCount = 0; + muxCreated->muxStat = OS_MUX_USED; + muxCreated->owner = NULL; + LOS_ListInit(&muxCreated->muxList); + *muxHandle = muxCreated->muxID; + + OsMuxDbgUpdateHook(muxCreated->muxID, OsCurrTaskGet()->taskEntry); + + SCHEDULER_UNLOCK(intSave); return LOS_OK; -ErrHandler: - OS_RETURN_ERROR_P2(uwErrLine, uwErrNo); + +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); } -/***************************************************************************** - Function : LOS_MuxDelete - Description : Delete a mutex, - Input : uwMuxHandle------Mutex operation handle - Output : None - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MuxDelete(UINT32 uwMuxHandle) +LITE_OS_SEC_TEXT UINT32 LOS_MuxDelete(UINT32 muxHandle) { - UINT32 uwIntSave; - MUX_CB_S *pstMuxDeleted; - UINT32 uwErrNo; - UINT32 uwErrLine; + UINT32 intSave; + LosMuxCB *muxDeleted = NULL; + UINT32 errNo; + UINT32 errLine; - if (uwMuxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) - { + if (GET_MUX_INDEX(muxHandle) >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) { OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_INVALID); } - pstMuxDeleted = GET_MUX(uwMuxHandle); - uwIntSave = LOS_IntLock(); - if (OS_MUX_UNUSED == pstMuxDeleted->ucMuxStat) - { - LOS_IntRestore(uwIntSave); + muxDeleted = GET_MUX(muxHandle); + SCHEDULER_LOCK(intSave); + if ((muxDeleted->muxID != muxHandle) || (muxDeleted->muxStat == OS_MUX_UNUSED)) { + SCHEDULER_UNLOCK(intSave); OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_INVALID); } - if (!LOS_ListEmpty(&pstMuxDeleted->stMuxList) || pstMuxDeleted->usMuxCount) - { - LOS_IntRestore(uwIntSave); + if (!LOS_ListEmpty(&muxDeleted->muxList) || muxDeleted->muxCount) { + SCHEDULER_UNLOCK(intSave); OS_GOTO_ERR_HANDLER(LOS_ERRNO_MUX_PENDED); } - LOS_ListAdd(&g_stUnusedMuxList, &pstMuxDeleted->stMuxList); - pstMuxDeleted->ucMuxStat = OS_MUX_UNUSED; + LOS_ListTailInsert(&g_unusedMuxList, &muxDeleted->muxList); + muxDeleted->muxStat = OS_MUX_UNUSED; + muxDeleted->muxID = SET_MUX_ID(GET_MUX_COUNT(muxDeleted->muxID) + 1, GET_MUX_INDEX(muxDeleted->muxID)); + + OsMuxDbgUpdateHook(muxDeleted->muxID, NULL); - LOS_IntRestore(uwIntSave); + SCHEDULER_UNLOCK(intSave); return LOS_OK; -ErrHandler: - OS_RETURN_ERROR_P2(uwErrLine, uwErrNo); + +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); } -/***************************************************************************** - Function : LOS_MuxPend - Description : Specify the mutex P operation, - Input : uwMuxHandle ------ Mutex operation handleone, - uwTimeOut ------- waiting time, - Output : None - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 uwMuxHandle, UINT32 uwTimeout) +LITE_OS_SEC_TEXT STATIC UINT32 OsMuxParaCheck(const LosMuxCB *muxCB, UINT32 muxHandle) { - UINT32 uwIntSave; - MUX_CB_S *pstMuxPended; - UINT32 uwRetErr; - LOS_TASK_CB *pstRunTsk; - - if (uwMuxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) - { + if ((muxCB->muxStat == OS_MUX_UNUSED) || (muxCB->muxID != muxHandle)) { OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); } - pstMuxPended = GET_MUX(uwMuxHandle); - uwIntSave = LOS_IntLock(); - if (OS_MUX_UNUSED == pstMuxPended->ucMuxStat) - { - LOS_IntRestore(uwIntSave); - OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); - } + OsMuxDbgTimeUpdateHook(muxCB->muxID); - if (OS_INT_ACTIVE) - { - LOS_IntRestore(uwIntSave); + if (OS_INT_ACTIVE) { return LOS_ERRNO_MUX_PEND_INTERR; } + return LOS_OK; +} - pstRunTsk = (LOS_TASK_CB *)g_stLosTask.pstRunTask; - if (pstMuxPended->usMuxCount == 0) - { - pstMuxPended->usMuxCount++; - pstMuxPended->pstOwner = pstRunTsk; - pstMuxPended->usPriority = pstRunTsk->usPriority; - LOS_IntRestore(uwIntSave); - return LOS_OK; +LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapSet(const LosTaskCB *runTask, const MuxBaseCB *muxPended) +{ + if (muxPended->owner->priority > runTask->priority) { + LOS_BitmapSet(&(muxPended->owner->priBitMap), muxPended->owner->priority); + OsTaskPriModify(muxPended->owner, runTask->priority); } +} - if (pstMuxPended->pstOwner == pstRunTsk) - { - pstMuxPended->usMuxCount++; - LOS_IntRestore(uwIntSave); - return LOS_OK; +LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapRestore(const LosTaskCB *runTask, const MuxBaseCB *muxPended) +{ + UINT16 bitMapPri; + + if (muxPended->owner->priority >= runTask->priority) { + bitMapPri = LOS_LowBitGet(muxPended->owner->priBitMap); + if (bitMapPri != LOS_INVALID_BIT_INDEX) { + LOS_BitmapClr(&(muxPended->owner->priBitMap), bitMapPri); + OsTaskPriModify(muxPended->owner, bitMapPri); + } + } else { + if (LOS_HighBitGet(muxPended->owner->priBitMap) != runTask->priority) { + LOS_BitmapClr(&(muxPended->owner->priBitMap), runTask->priority); + } } +} - if (!uwTimeout) - { - LOS_IntRestore(uwIntSave); - return LOS_ERRNO_MUX_UNAVAILABLE; +LITE_OS_SEC_TEXT STATIC LOS_DL_LIST *OsMuxPendFindPosSub(const LosTaskCB *runTask, const MuxBaseCB *muxPended) +{ + LosTaskCB *pendedTask = NULL; + LOS_DL_LIST *node = NULL; + + LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, &(muxPended->muxList), LosTaskCB, pendList) { + if (pendedTask->priority < runTask->priority) { + continue; + } else if (pendedTask->priority > runTask->priority) { + node = &pendedTask->pendList; + break; + } else { + node = pendedTask->pendList.pstNext; + break; + } } - if (g_usLosTaskLock) - { - uwRetErr = LOS_ERRNO_MUX_PEND_IN_LOCK; - PRINT_ERR("!!!LOS_ERRNO_MUX_PEND_IN_LOCK!!!\n"); -#if (LOSCFG_PLATFORM_EXC == YES) - osBackTrace(); -#endif - goto errre_uniMuxPend; + return node; +} + +LITE_OS_SEC_TEXT STATIC LOS_DL_LIST *OsMuxPendFindPos(const LosTaskCB *runTask, MuxBaseCB *muxPended) +{ + LosTaskCB *pendedTask1 = NULL; + LosTaskCB *pendedTask2 = NULL; + LOS_DL_LIST *node = NULL; + + if (LOS_ListEmpty(&muxPended->muxList)) { + node = &muxPended->muxList; + } else { + pendedTask1 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&muxPended->muxList)); + pendedTask2 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_LAST(&muxPended->muxList)); + if ((pendedTask1 != NULL) && (pendedTask1->priority > runTask->priority)) { + node = muxPended->muxList.pstNext; + } else if ((pendedTask2 != NULL) && (pendedTask2->priority <= runTask->priority)) { + node = &muxPended->muxList; + } else { + node = OsMuxPendFindPosSub(runTask, muxPended); + } + } + + return node; +} + +LITE_OS_SEC_TEXT UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UINT32 timeout, + UINT32 intSave) +{ + LOS_DL_LIST *node = NULL; + UINT32 ret = LOS_OK; + + runTask->taskMux = (VOID *)muxPended; + node = OsMuxPendFindPos(runTask, muxPended); + + OsTaskWait(node, OS_TASK_STATUS_PEND, timeout); + OsSchedResched(); + + SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); + + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + ret = LOS_ERRNO_MUX_TIMEOUT; } - pstRunTsk->pTaskMux = (VOID *)pstMuxPended; + if (timeout != LOS_WAIT_FOREVER) { + OsMuxBitmapRestore(runTask, muxPended); + } + return ret; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout) +{ + UINT32 ret; + UINT32 intSave; + LosMuxCB *muxPended = NULL; + LosTaskCB *runTask = NULL; - if (pstMuxPended->pstOwner->usPriority > pstRunTsk->usPriority) - { - osTaskPriModify(pstMuxPended->pstOwner, pstRunTsk->usPriority); + if (GET_MUX_INDEX(muxHandle) >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) { + OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); } - osTaskWait(&pstMuxPended->stMuxList, OS_TASK_STATUS_PEND, uwTimeout); + muxPended = GET_MUX(muxHandle); + SCHEDULER_LOCK(intSave); - (VOID)LOS_IntRestore(uwIntSave); - LOS_Schedule(); + ret = OsMuxParaCheck(muxPended, muxHandle); + if (ret != LOS_OK) { + goto OUT_UNLOCK; + } - if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) - { - uwIntSave = LOS_IntLock(); - pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); - (VOID)LOS_IntRestore(uwIntSave); - uwRetErr = LOS_ERRNO_MUX_TIMEOUT; - goto error_uniMuxPend; + runTask = OsCurrTaskGet(); + if (runTask->taskFlags & OS_TASK_FLAG_SYSTEM) { + ret = LOS_ERRNO_MUX_PEND_IN_SYSTEM_TASK; + goto OUT_UNLOCK; } - return LOS_OK; + if (muxPended->muxCount == 0) { + OsMuxDlockNodeInsertHook(runTask->taskID, muxPended); + muxPended->muxCount++; + muxPended->owner = runTask; + goto OUT_UNLOCK; + } -errre_uniMuxPend: - (VOID)LOS_IntRestore(uwIntSave); -error_uniMuxPend: - OS_RETURN_ERROR(uwRetErr); + if (muxPended->owner == runTask) { + muxPended->muxCount++; + goto OUT_UNLOCK; + } + + if (!timeout) { + ret = LOS_ERRNO_MUX_UNAVAILABLE; + goto OUT_UNLOCK; + } + + if (!OsPreemptableInSched()) { + ret = LOS_ERRNO_MUX_PEND_IN_LOCK; + goto OUT_UNLOCK; + } + + OsMuxBitmapSet(runTask, (MuxBaseCB *)muxPended); + ret = OsMuxPendOp(runTask, (MuxBaseCB *)muxPended, timeout, intSave); + +OUT_UNLOCK: + SCHEDULER_UNLOCK(intSave); + return ret; } -/***************************************************************************** - Function : LOS_MuxPost - Description : Specify the mutex V operation, - Input : uwMuxHandle ------ Mutex operation handle, - Output : None - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 uwMuxHandle) +LITE_OS_SEC_TEXT STATIC VOID OsMuxPostOpSub(LosTaskCB *runTask, MuxBaseCB *muxPosted) { - UINT32 uwIntSave; - MUX_CB_S *pstMuxPosted = GET_MUX(uwMuxHandle); - LOS_TASK_CB *pstResumedTask; - LOS_TASK_CB *pstRunTsk; + LosTaskCB *pendedTask = NULL; + UINT16 bitMapPri; + + if (!LOS_ListEmpty(&muxPosted->muxList)) { + bitMapPri = LOS_HighBitGet(runTask->priBitMap); + LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, (&muxPosted->muxList), LosTaskCB, pendList) { + if (bitMapPri != pendedTask->priority) { + LOS_BitmapClr(&runTask->priBitMap, pendedTask->priority); + } + } + } + bitMapPri = LOS_LowBitGet(runTask->priBitMap); + LOS_BitmapClr(&runTask->priBitMap, bitMapPri); + OsTaskPriModify(muxPosted->owner, bitMapPri); +} - uwIntSave = LOS_IntLock(); +LITE_OS_SEC_TEXT UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted) +{ + LosTaskCB *resumedTask = NULL; - if ((uwMuxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) || - (OS_MUX_UNUSED == pstMuxPosted->ucMuxStat)) - { - LOS_IntRestore(uwIntSave); - OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); + if (LOS_ListEmpty(&muxPosted->muxList)) { + muxPosted->owner = NULL; + OsMuxDlockNodeDeleteHook(runTask->taskID, muxPosted); + return MUX_NO_SCHEDULE; } - pstRunTsk = (LOS_TASK_CB *)g_stLosTask.pstRunTask; - if ((pstMuxPosted->usMuxCount == 0) || (pstMuxPosted->pstOwner != pstRunTsk)) - { - LOS_IntRestore(uwIntSave); - OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(muxPosted->muxList))); + if (resumedTask->priority > runTask->priority) { + if (LOS_HighBitGet(runTask->priBitMap) != resumedTask->priority) { + LOS_BitmapClr(&runTask->priBitMap, resumedTask->priority); + } + } else if (runTask->priBitMap != 0) { + OsMuxPostOpSub(runTask, muxPosted); } - if (--(pstMuxPosted->usMuxCount) != 0) - { - LOS_IntRestore(uwIntSave); - return LOS_OK; - } + muxPosted->muxCount = 1; + muxPosted->owner = resumedTask; + resumedTask->taskMux = NULL; + OsMuxDlockNodeDeleteHook(runTask->taskID, muxPosted); + OsMuxDlockNodeInsertHook(resumedTask->taskID, muxPosted); + + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND); + + return MUX_SCHEDULE; +} + +LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 muxHandle) +{ + UINT32 ret; + LosTaskCB *runTask = NULL; + LosMuxCB *muxPosted = GET_MUX(muxHandle); + UINT32 intSave; - if ((pstMuxPosted->pstOwner->usPriority) != pstMuxPosted->usPriority) - { - osTaskPriModify(pstMuxPosted->pstOwner, pstMuxPosted->usPriority); + if (GET_MUX_INDEX(muxHandle) >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) { + OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); } - if (!LOS_ListEmpty(&pstMuxPosted->stMuxList)) - { - pstResumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(pstMuxPosted->stMuxList))); /*lint !e413*/ + SCHEDULER_LOCK(intSave); - pstMuxPosted->usMuxCount = 1; - pstMuxPosted->pstOwner = pstResumedTask; - pstMuxPosted->usPriority = pstResumedTask->usPriority; - pstResumedTask->pTaskMux = NULL; + ret = OsMuxParaCheck(muxPosted, muxHandle); + if (ret != LOS_OK) { + SCHEDULER_UNLOCK(intSave); + return ret; + } - osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND); + runTask = OsCurrTaskGet(); + if ((muxPosted->muxCount == 0) || (muxPosted->owner != runTask)) { + SCHEDULER_UNLOCK(intSave); + OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); + } - (VOID)LOS_IntRestore(uwIntSave); - LOS_Schedule(); + if (--muxPosted->muxCount != 0) { + SCHEDULER_UNLOCK(intSave); + return LOS_OK; } - else - { - (VOID)LOS_IntRestore(uwIntSave); + + ret = OsMuxPostOp(runTask, (MuxBaseCB *)muxPosted); + SCHEDULER_UNLOCK(intSave); + if (ret == MUX_SCHEDULE) { + LOS_Schedule(); } return LOS_OK; } -#endif /*(LOSCFG_BASE_IPC_MUX == YES)*/ +#endif /* (LOSCFG_BASE_IPC_MUX == YES) */ #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/ipc/los_mux.inc b/kernel/base/ipc/los_mux.inc deleted file mode 100644 index c159969be..000000000 --- a/kernel/base/ipc/los_mux.inc +++ /dev/null @@ -1,66 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MUX_INC -#define _LOS_MUX_INC - -#include "los_mux.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C"{ -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -/** - * @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, MUX_CB_S, stMuxList) - -/** - * @ingroup los_mux - * Mutex global array address, which can be obtained by using a handle ID. - */ -extern MUX_CB_S *g_pstAllMux; - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_MUX_INC */ diff --git a/kernel/base/ipc/los_mux_debug.c b/kernel/base/ipc/los_mux_debug.c new file mode 100644 index 000000000..26e494ce1 --- /dev/null +++ b/kernel/base/ipc/los_mux_debug.c @@ -0,0 +1,429 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex Debug + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_mux_debug_pri.h" +#include "los_typedef.h" +#include "los_task.h" +#include "los_hw_pri.h" +#include "los_ipcdebug_pri.h" +#include "los_exc_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#ifdef LOSCFG_DEBUG_MUTEX + +typedef struct { + TSK_ENTRY_FUNC creater; /* The task entry who created this mutex */ + UINT64 lastAccessTime; /* The last access time */ +} MuxDebugCB; + +#if (LOSCFG_BASE_IPC_MUX_DYN_MEM == YES) +STATIC MuxDebugCB *g_muxDebugArray = NULL; +#else +STATIC MuxDebugCB g_muxDebugArray[LOSCFG_BASE_IPC_MUX_LIMIT]; +#endif + +STATIC BOOL MuxCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right) +{ + return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > + *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); +} + +UINT32 OsMuxDbgInit(VOID) +{ +#if (LOSCFG_BASE_IPC_MUX_DYN_MEM == YES) + UINT32 size = LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(MuxDebugCB); + /* system resident memory, don't free */ + g_muxDebugArray = (MuxDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_muxDebugArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } + (VOID)memset_s(g_muxDebugArray, size, 0, size); +#endif + return LOS_OK; +} + +VOID OsMuxDbgTimeUpdate(UINT32 muxID) +{ + MuxDebugCB *muxDebug = &g_muxDebugArray[GET_MUX_INDEX(muxID)]; + muxDebug->lastAccessTime = LOS_TickCountGet(); +} + +VOID OsMuxDbgUpdate(UINT32 muxID, TSK_ENTRY_FUNC creater) +{ + MuxDebugCB *muxDebug = &g_muxDebugArray[GET_MUX_INDEX(muxID)]; + muxDebug->creater = creater; + muxDebug->lastAccessTime = LOS_TickCountGet(); +} + +STATIC VOID SortMuxIndexArray(UINT32 *indexArray, UINT32 count) +{ + LosMuxCB muxNode = {0}; + MuxDebugCB muxDebugNode = {0}; + UINT32 index, intSave; + IpcSortParam muxSortParam; + muxSortParam.buf = (CHAR *)g_muxDebugArray; + muxSortParam.ipcDebugCBSize = sizeof(MuxDebugCB); + muxSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_MUX_LIMIT; + muxSortParam.sortElemOff = OFFSET_OF_FIELD(MuxDebugCB, lastAccessTime); + + if (count > 0) { + SCHEDULER_LOCK(intSave); + OsArraySortByTime(indexArray, 0, count - 1, &muxSortParam, MuxCompareValue); + SCHEDULER_UNLOCK(intSave); + for (index = 0; index < count; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&muxNode, sizeof(LosMuxCB), + GET_MUX(indexArray[index]), sizeof(LosMuxCB)); + (VOID)memcpy_s(&muxDebugNode, sizeof(MuxDebugCB), + &g_muxDebugArray[indexArray[index]], sizeof(MuxDebugCB)); + SCHEDULER_UNLOCK(intSave); + if ((muxNode.muxStat != OS_MUX_USED) || + ((muxNode.muxStat == OS_MUX_USED) && (muxDebugNode.creater == NULL))) { + continue; + } + PRINTK("Mutex ID <0x%x> may leak, TaskID of owner:0x%x, TaskEntry of owner: %p," + "TaskEntry of creater: %p,Latest operation time: 0x%llx\n", + muxNode.muxID, muxNode.owner->taskID, muxNode.owner->taskEntry, muxDebugNode.creater, + muxDebugNode.lastAccessTime); + } + } + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray); +} + +VOID OsMutexCheck(VOID) +{ + LosMuxCB muxNode = {0}; + MuxDebugCB muxDebugNode = {0}; + UINT32 index, intSave; + UINT32 count = 0; + + /* + * This return value does not need to be judged immediately, + * and the following code logic has already distinguished the return value from null and non-empty, + * and there is no case of accessing the null pointer. + */ + UINT32 *indexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(UINT32)); + + for (index = 0; index < LOSCFG_BASE_IPC_MUX_LIMIT; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&muxNode, sizeof(LosMuxCB), GET_MUX(index), sizeof(LosMuxCB)); + (VOID)memcpy_s(&muxDebugNode, sizeof(MuxDebugCB), &g_muxDebugArray[index], sizeof(MuxDebugCB)); + SCHEDULER_UNLOCK(intSave); + + if ((muxNode.muxStat != OS_MUX_USED) || + ((muxNode.muxStat == OS_MUX_USED) && (muxDebugNode.creater == NULL))) { + continue; + } else if ((muxNode.muxStat == OS_MUX_USED) && (muxNode.owner == NULL)) { + PRINTK("Mutex ID <0x%x> may leak, Owner is null, TaskEntry of creater: %p," + "Latest operation time: 0x%llx\n", + muxNode.muxID, muxDebugNode.creater, muxDebugNode.lastAccessTime); + } else { + if (indexArray != NULL) { + *(indexArray + count) = index; + count++; + } else { + PRINTK("Mutex ID <0x%x> may leak, TaskID of owner:0x%x, TaskEntry of owner: %p," + "TaskEntry of creater: %p,Latest operation time: 0x%llx\n", + muxNode.muxID, muxNode.owner->taskID, muxNode.owner->taskEntry, muxDebugNode.creater, + muxDebugNode.lastAccessTime); + } + } + } + + if (indexArray != NULL) { + SortMuxIndexArray(indexArray, count); + } +} + +#ifdef LOSCFG_SHELL +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMuxInfoGet(UINT32 argc, const CHAR **argv) +{ + if (argc > 0) { + PRINTK("\nUsage: mutex\n"); + return OS_ERROR; + } + PRINTK("used mutexs information: \n"); + OsMutexCheck(); + return LOS_OK; +} +SHELLCMD_ENTRY(mutex_shellcmd, CMD_TYPE_EX, "mutex", 0, (CmdCallBackFunc)OsShellCmdMuxInfoGet); +#endif /* LOSCFG_SHELL */ +#endif /* LOSCFG_DEBUG_MUTEX */ + +#ifdef LOSCFG_DEBUG_DEADLOCK +typedef struct { + LOS_DL_LIST muxListHead; /* Task-held mutexs list */ + UINT64 lastAccessTime; /* The last operation time */ +} MuxDLinkCB; + +typedef struct { + LOS_DL_LIST muxList; /* Insert mutex into the owner task CB */ + VOID *muxCB; /* The Mutex CB pointer */ +} MuxDLinkNode; + +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) +STATIC MuxDLinkCB *g_muxDeadlockCBArray; +#else +STATIC MuxDLinkCB g_muxDeadlockCBArray[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; +#endif + + +/* + * Mutex deadlock detection time threshold, will print out task information + * that has not been scheduled within this time. + * The unit is tick. + */ +#define OS_MUX_DEADLOCK_CHECK_THRESHOLD 60000 + +UINT32 OsMuxDlockCheckInit(VOID) +{ + UINT32 index; + + /* system resident memory, don't free */ +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) + UINT32 size = (g_taskMaxNum + 1) * sizeof(MuxDLinkCB); + g_muxDeadlockCBArray = (MuxDLinkCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_muxDeadlockCBArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } +#endif + + for (index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + g_muxDeadlockCBArray[index].lastAccessTime = 0; + LOS_ListInit(&g_muxDeadlockCBArray[index].muxListHead); + } + return LOS_OK; +} + +VOID OsMuxDlockNodeInsert(UINT32 taskID, VOID *muxCB) +{ + MuxDLinkNode *muxDLNode = NULL; + + if ((taskID > LOSCFG_BASE_CORE_TSK_LIMIT) || (muxCB == NULL)) { + PRINT_ERR("%s: Argument is invalid!\n", __FUNCTION__); + return; + } + + muxDLNode = (MuxDLinkNode *)LOS_MemAlloc(m_aucSysMem1, sizeof(MuxDLinkNode)); + if (muxDLNode == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return; + } + (VOID)memset_s(muxDLNode, sizeof(MuxDLinkNode), 0, sizeof(MuxDLinkNode)); + muxDLNode->muxCB = muxCB; + + LOS_ListTailInsert(&g_muxDeadlockCBArray[taskID].muxListHead, &muxDLNode->muxList); +} + +VOID OsMuxDlockNodeDelete(UINT32 taskID, const VOID *muxCB) +{ + MuxDLinkCB *muxDLCB = NULL; + LOS_DL_LIST *list = NULL; + MuxDLinkNode *muxDLNode = NULL; + + if ((taskID > LOSCFG_BASE_CORE_TSK_LIMIT) || (muxCB == NULL)) { + PRINT_ERR("%s: Argument is invalid!\n", __FUNCTION__); + return; + } + + muxDLCB = &g_muxDeadlockCBArray[taskID]; + LOS_DL_LIST_FOR_EACH(list, &muxDLCB->muxListHead) { + muxDLNode = LOS_DL_LIST_ENTRY(list, MuxDLinkNode, muxList); + if (muxDLNode->muxCB == muxCB) { + LOS_ListDelete(&muxDLNode->muxList); + (VOID)LOS_MemFree(m_aucSysMem1, muxDLNode); + return; + } + } + + PRINT_ERR("%s: find mutex deadlock node failed!\n", __FUNCTION__); +} + +VOID OsTaskTimeUpdate(UINT32 taskID, UINT64 tickCount) +{ + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + g_muxDeadlockCBArray[taskID].lastAccessTime = tickCount; +} + +STATIC VOID OsDeadlockBackTrace(const LosTaskCB *taskCB) +{ + UINTPTR FP; + TaskContext *context = NULL; + + PRINTK("*******backtrace begin*******\n"); + context = (TaskContext *)taskCB->stackPointer; +#ifdef __LP64__ + FP = context->X[29]; /* X29:FP */ +#else + FP = context->R[11]; /* R11:FP */ +#endif + PRINTK("pc = %p lr = %p\n", context->PC, context->LR); + + BackTraceSub(FP); + + PRINTK("********backtrace end********\n"); + return; +} + +STATIC VOID OsMutexPendTaskList(LOS_DL_LIST *list) +{ + LOS_DL_LIST *listTmp = NULL; + LosTaskCB *pendedTask = NULL; + CHAR *name = NULL; + UINT32 index = 0; + UINT32 id, intSave; + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(list) == TRUE) { + SCHEDULER_UNLOCK(intSave); + PRINTK("Pended Task: null\n"); + return; + } + + LOS_DL_LIST_FOR_EACH(listTmp, list) { + pendedTask = OS_TCB_FROM_PENDLIST(listTmp); + name = pendedTask->taskName; + id = pendedTask->taskID; + SCHEDULER_UNLOCK(intSave); + if (index == 0) { + PRINTK("Pended task: %u. name:%-15s, id:0x%-5x\n", index, name, id); + } else { + PRINTK(" %u. name:%-15s, id:0x%-5x\n", index, name, id); + } + index++; + SCHEDULER_LOCK(intSave); + } + SCHEDULER_UNLOCK(intSave); +} + +STATIC VOID OsTaskHoldMutexList(MuxDLinkCB *muxDLCB) +{ + UINT32 index = 0; + MuxDLinkNode *muxDLNode = NULL; + CHAR *ownerName = NULL; + LosMuxCB *muxCB = NULL; + LOS_DL_LIST *list = NULL; + LOS_DL_LIST *listTmp = NULL; + UINT32 count, intSave; + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&muxDLCB->muxListHead) == TRUE) { + SCHEDULER_UNLOCK(intSave); + PRINTK("null\n"); + } else { + LOS_DL_LIST_FOR_EACH(list, &muxDLCB->muxListHead) { + muxDLNode = LOS_DL_LIST_ENTRY(list, MuxDLinkNode, muxList); + muxCB = (LosMuxCB *)muxDLNode->muxCB; + count = muxCB->muxCount; + ownerName = muxCB->owner->taskName; + SCHEDULER_UNLOCK(intSave); + PRINTK("\n", index); + PRINTK("Ptr handle:%p\n", muxCB); + PRINTK("Owner:%s\n", ownerName); + PRINTK("Count:%u\n", count); + + listTmp = &muxCB->muxList; + OsMutexPendTaskList(listTmp); + + index++; + SCHEDULER_LOCK(intSave); + } + SCHEDULER_UNLOCK(intSave); + } +} + +VOID OsMutexDlockCheck(VOID) +{ + UINT32 loop, intSave; + UINT32 taskID; + CHAR *name = NULL; + LosTaskCB *taskCB = NULL; + MuxDLinkCB *muxDLCB = NULL; + + SCHEDULER_LOCK(intSave); + for (loop = 0; loop < g_taskMaxNum; loop++) { + taskCB = (LosTaskCB *)g_taskCBArray + loop; + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + + muxDLCB = &g_muxDeadlockCBArray[taskCB->taskID]; + if ((LOS_TickCountGet() - muxDLCB->lastAccessTime) > OS_MUX_DEADLOCK_CHECK_THRESHOLD) { + name = taskCB->taskName; + taskID = taskCB->taskID; + SCHEDULER_UNLOCK(intSave); + PRINTK("Task_name:%s, ID:0x%x, holds the Mutexs below:\n", name, taskID); + OsTaskHoldMutexList(muxDLCB); + OsDeadlockBackTrace(taskCB); + PRINTK("\n"); + SCHEDULER_LOCK(intSave); + } + } + SCHEDULER_UNLOCK(intSave); +} + +#ifdef LOSCFG_SHELL +UINT32 OsShellCmdMuxDeadlockCheck(UINT32 argc, const CHAR **argv) +{ + if (argc > 0) { + PRINTK("\nUsage: dlock\n"); + return OS_ERROR; + } + PRINTK("Start mutexs deadlock check: \n"); + OsMutexDlockCheck(); + PRINTK("-----------End-----------\n"); + return LOS_OK; +} +SHELLCMD_ENTRY(deadlock_shellcmd, CMD_TYPE_EX, "dlock", 0, (CmdCallBackFunc)OsShellCmdMuxDeadlockCheck); +#endif /* LOSCFG_SHELL */ +#endif /* LOSCFG_DEBUG_DEADLOCK */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/ipc/los_queue.c b/kernel/base/ipc/los_queue.c index 03d91658a..47b4284b0 100644 --- a/kernel/base/ipc/los_queue.c +++ b/kernel/base/ipc/los_queue.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Queue * 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 @@ -22,774 +22,615 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "string.h" -#include "los_queue.ph" -#include "los_membox.ph" -#include "los_memory.ph" -#include "los_priqueue.ph" -#include "los_task.ph" -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_exc.ph" -#endif + * --------------------------------------------------------------------------- */ +#include "los_queue_pri.h" +#include "los_queue_debug_pri.h" +#include "los_task_pri.h" #ifdef __cplusplus #if __cplusplus -extern "C"{ +extern "C" { #endif #endif /* __cplusplus */ #if (LOSCFG_BASE_IPC_QUEUE == YES) -/*lint -save -e64*/ -LITE_OS_SEC_BSS QUEUE_CB_S *g_pstAllQueue; -LITE_OS_SEC_BSS LOS_DL_LIST g_stFreeQueueList; -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) -LITE_OS_SEC_BSS UINT32 g_uwExcQueueMaxNum; +#if (LOSCFG_BASE_IPC_QUEUE_DYN_MEM == YES) +LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL; +#else +#if (LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0) +#error "queue maxnum cannot be zero" +#endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */ +LITE_OS_SEC_BSS LosQueueCB g_allQueue[LOSCFG_BASE_IPC_QUEUE_LIMIT]; #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) +LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList; + +/* + * Description : queue initial + * Return : LOS_OK on success or error code on failure + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) { - QUEUE_CB_S *pstQueueNode; - UINT16 usIndex; + LosQueueCB *queueNode = NULL; + UINT32 index; - if (0 == LOSCFG_BASE_IPC_QUEUE_LIMIT) /*lint !e506*/ - { - return LOS_ERRNO_QUEUE_MAXNUM_ZERO; - } +#if (LOSCFG_BASE_IPC_QUEUE_DYN_MEM == YES) + UINT32 size; - g_pstAllQueue = (QUEUE_CB_S *)LOS_MemAlloc(m_aucSysMem0, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(QUEUE_CB_S)); - if (NULL == g_pstAllQueue) - { + size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB); + /* system resident memory, don't free */ + g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_allQueue == NULL) { return LOS_ERRNO_QUEUE_NO_MEMORY; } + (VOID)memset_s(g_allQueue, size, 0, size); +#endif - (VOID)memset(g_pstAllQueue, 0, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(QUEUE_CB_S)); + LOS_ListInit(&g_freeQueueList); - LOS_ListInit(&g_stFreeQueueList); - for (usIndex = 0; usIndex < LOSCFG_BASE_IPC_QUEUE_LIMIT; usIndex++) - { - pstQueueNode = ((QUEUE_CB_S *)g_pstAllQueue) + usIndex; - pstQueueNode->usQueueID = usIndex; - LOS_ListTailInsert(&g_stFreeQueueList, &pstQueueNode->stReadWriteList[OS_QUEUE_WRITE]); + 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) && (LOSCFG_SAVE_EXC_INFO == YES)) - g_uwExcQueueMaxNum = LOSCFG_BASE_IPC_QUEUE_LIMIT; - osExcRegister(OS_EXC_TYPE_QUE, (EXC_INFO_SAVE_CALLBACK)LOS_QueueInfoGet, &g_uwExcQueueMaxNum); -#endif - + if (OsQueueDbgInitHook() != LOS_OK) { + return LOS_ERRNO_QUEUE_NO_MEMORY; + } return LOS_OK; } -/***************************************************************************** - Function : LOS_QueueCreate - Description : Create a queue - Input : pcQueueName --- Queue name, less than 4 characters - usLen --- Queue lenth - uwFlags --- Queue type, FIFO or PRIO - usMaxMsgSize --- Maximum message size in byte - Output : puwQueueID --- Queue ID - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *pcQueueName, - UINT16 usLen, - UINT32 *puwQueueID, - UINT32 uwFlags, - UINT16 usMaxMsgSize ) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(const CHAR *queueName, UINT16 len, UINT32 *queueID, + UINT32 flags, UINT16 maxMsgSize) { - QUEUE_CB_S *pstQueueCB; - UINTPTR uvIntSave; - LOS_DL_LIST *pstUnusedQueue; - UINT8 *pucQueue; - UINT16 usMsgSize = usMaxMsgSize + sizeof(UINT32); + LosQueueCB *queueCB = NULL; + UINT32 intSave; + LOS_DL_LIST *unusedQueue = NULL; + UINT8 *queue = NULL; + UINT16 msgSize; - (VOID)pcQueueName; - (VOID)uwFlags; + (VOID)queueName; + (VOID)flags; - if (NULL == puwQueueID) - { + if (queueID == NULL) { return LOS_ERRNO_QUEUE_CREAT_PTR_NULL; } - if(usMaxMsgSize > OS_NULL_SHORT -4) - { + if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) { return LOS_ERRNO_QUEUE_SIZE_TOO_BIG; } - if ((0 == usLen) || (0 == usMaxMsgSize)) - { + if ((len == 0) || (maxMsgSize == 0)) { return LOS_ERRNO_QUEUE_PARA_ISZERO; } - /* Memory allocation is time-consuming, to shorten the time of disable interrupt, - move the memory allocation to here. */ - pucQueue = (UINT8 *)LOS_MemAlloc(m_aucSysMem0, usLen * usMsgSize); - if (NULL == pucQueue) - { + 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_aucSysMem1, (UINT32)len * msgSize); + if (queue == NULL) { return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY; } - uvIntSave = LOS_IntLock(); - if (LOS_ListEmpty(&g_stFreeQueueList)) - { - LOS_IntRestore(uvIntSave); - (VOID)LOS_MemFree(m_aucSysMem0, pucQueue); + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&g_freeQueueList)) { + SCHEDULER_UNLOCK(intSave); + OsQueueCheckHook(); + (VOID)LOS_MemFree(m_aucSysMem1, queue); return LOS_ERRNO_QUEUE_CB_UNAVAILABLE; } - pstUnusedQueue = LOS_DL_LIST_FIRST(&(g_stFreeQueueList)); - LOS_ListDelete(pstUnusedQueue); - pstQueueCB = (GET_QUEUE_LIST(pstUnusedQueue)); - pstQueueCB->usQueueLen = usLen; - pstQueueCB->usQueueSize = usMsgSize; - pstQueueCB->pucQueue = pucQueue; - pstQueueCB->usQueueState = OS_QUEUE_INUSED; - pstQueueCB->usReadWriteableCnt[OS_QUEUE_READ] = 0; - pstQueueCB->usReadWriteableCnt[OS_QUEUE_WRITE] = usLen; - pstQueueCB->usQueueHead = 0; - pstQueueCB->usQueueTail = 0; - LOS_ListInit(&pstQueueCB->stReadWriteList[OS_QUEUE_READ]); - LOS_ListInit(&pstQueueCB->stReadWriteList[OS_QUEUE_WRITE]); - LOS_ListInit(&pstQueueCB->stMemList); - LOS_IntRestore(uvIntSave); - - *puwQueueID = pstQueueCB->usQueueID; - + unusedQueue = LOS_DL_LIST_FIRST(&g_freeQueueList); + LOS_ListDelete(unusedQueue); + queueCB = GET_QUEUE_LIST(unusedQueue); + queueCB->queueLen = len; + queueCB->queueSize = msgSize; + queueCB->queueHandle = 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); + + OsQueueDbgUpdateHook(queueCB->queueID, OsCurrTaskGet()->taskEntry); + SCHEDULER_UNLOCK(intSave); + + *queueID = queueCB->queueID; return LOS_OK; } -LITE_OS_SEC_TEXT static INLINE UINT32 osQueueReadParameterCheck(UINT32 uwQueueID, VOID *pBufferAddr, UINT32 *puwBufferSize, UINT32 uwTimeOut) +STATIC LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, const VOID *bufferAddr, + const UINT32 *bufferSize, UINT32 timeout) { - if (uwQueueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) - { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { return LOS_ERRNO_QUEUE_INVALID; } - if ((NULL == pBufferAddr) || (NULL == puwBufferSize)) - { + if ((bufferAddr == NULL) || (bufferSize == NULL)) { return LOS_ERRNO_QUEUE_READ_PTR_NULL; } - if (0 == *puwBufferSize) - { - return LOS_ERRNO_QUEUE_READSIZE_ISZERO; + if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) { + return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID; } - if (LOS_NO_WAIT != uwTimeOut) - { - if (OS_INT_ACTIVE) - { + OsQueueDbgTimeUpdateHook(queueID); + + if (timeout != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT; } } return LOS_OK; } - -LITE_OS_SEC_TEXT static INLINE UINT32 osQueueWriteParameterCheck(UINT32 uwQueueID, VOID *pBufferAddr, UINT32 *puwBufferSize, UINT32 uwTimeOut) +STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const VOID *bufferAddr, + const UINT32 *bufferSize, UINT32 timeout) { - if (uwQueueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) - { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { return LOS_ERRNO_QUEUE_INVALID; } - if (NULL == pBufferAddr) - { + if (bufferAddr == NULL) { return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; } - if (0 == *puwBufferSize) - { + if (*bufferSize == 0) { return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO; } - if (LOS_NO_WAIT != uwTimeOut) - { - if (OS_INT_ACTIVE) - { + OsQueueDbgTimeUpdateHook(queueID); + + if (timeout != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { return LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT; } } return LOS_OK; } -LITE_OS_SEC_TEXT static INLINE VOID osQueueBufferOperate(QUEUE_CB_S *pstQueueCB, UINT32 uwOperateType, VOID *pBufferAddr, UINT32 *puwBufferSize) +STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize) { - UINT8 *pucQueueNode; - UINT32 uwMsgDataSize = 0; - UINT16 usQueuePosion = 0; + UINT8 *queueNode = NULL; + UINT32 msgDataSize; + UINT16 queuePosion; /* get the queue position */ - switch (OS_QUEUE_OPERATE_GET(uwOperateType)) - { + switch (OS_QUEUE_OPERATE_GET(operateType)) { case OS_QUEUE_READ_HEAD: - usQueuePosion = pstQueueCB->usQueueHead; - (pstQueueCB->usQueueHead + 1 == pstQueueCB->usQueueLen) ? (pstQueueCB->usQueueHead = 0) : (pstQueueCB->usQueueHead++); + queuePosion = queueCB->queueHead; + ((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++); break; - case OS_QUEUE_WRITE_HEAD: - (0 == pstQueueCB->usQueueHead) ? (pstQueueCB->usQueueHead = pstQueueCB->usQueueLen - 1) : (--pstQueueCB->usQueueHead); - usQueuePosion = pstQueueCB->usQueueHead; + (queueCB->queueHead == 0) ? (queueCB->queueHead = queueCB->queueLen - 1) : (--queueCB->queueHead); + queuePosion = queueCB->queueHead; break; - - case OS_QUEUE_WRITE_TAIL : - usQueuePosion = pstQueueCB->usQueueTail; - (pstQueueCB->usQueueTail + 1 == pstQueueCB->usQueueLen) ? (pstQueueCB->usQueueTail = 0) : (pstQueueCB->usQueueTail++); + case OS_QUEUE_WRITE_TAIL: + queuePosion = queueCB->queueTail; + ((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++); break; - - default: //read tail , reserved. + default: /* read tail, reserved. */ PRINT_ERR("invalid queue operate type!\n"); return; } - pucQueueNode = &(pstQueueCB->pucQueue[(usQueuePosion * (pstQueueCB->usQueueSize))]); + queueNode = &(queueCB->queueHandle[(queuePosion * (queueCB->queueSize))]); - if(OS_QUEUE_IS_POINT(uwOperateType)) - { - if(OS_QUEUE_IS_READ(uwOperateType)) - { - *(UINT32 *)pBufferAddr = *(UINT32 *)pucQueueNode; + if (OS_QUEUE_IS_READ(operateType)) { + if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32), + sizeof(UINT32)) != EOK) { + PRINT_ERR("get msgdatasize failed\n"); + return; } - else - { - *(UINT32 *)pucQueueNode = *(UINT32 *)pBufferAddr;//change to pp when calling osQueueOperate + if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) { + PRINT_ERR("copy message to buffer failed\n"); + return; } - } - else - { - if(OS_QUEUE_IS_READ(uwOperateType)) - { - memcpy((VOID *)&uwMsgDataSize, (VOID *)(pucQueueNode + pstQueueCB->usQueueSize - sizeof(UINT32)), sizeof(UINT32)); - memcpy((VOID *)pBufferAddr, (VOID *)pucQueueNode, uwMsgDataSize); - *puwBufferSize = uwMsgDataSize; + + *bufferSize = msgDataSize; + } else { + if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) { + PRINT_ERR("store message failed\n"); + return; } - else - { - memcpy((VOID *)pucQueueNode, (VOID *)pBufferAddr, *puwBufferSize); - memcpy((VOID *)(pucQueueNode + pstQueueCB->usQueueSize - sizeof(UINT32)), puwBufferSize, sizeof(UINT32)); + if (memcpy_s(queueNode + queueCB->queueSize - sizeof(UINT32), sizeof(UINT32), bufferSize, + sizeof(UINT32)) != EOK) { + PRINT_ERR("store message size failed\n"); + return; } } } - -LITE_OS_SEC_TEXT UINT32 osQueueOperate(UINT32 uwQueueID, UINT32 uwOperateType, VOID *pBufferAddr, UINT32 *puwBufferSize, UINT32 uwTimeOut) +STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID, + UINT32 operateType, const UINT32 *bufferSize) { - QUEUE_CB_S *pstQueueCB; - LOS_TASK_CB *pstRunTsk; - UINTPTR uvIntSave; - LOS_TASK_CB *pstResumedTask; - UINT32 uwRet = LOS_OK; - UINT32 uwReadWrite = OS_QUEUE_READ_WRITE_GET(uwOperateType); - - uvIntSave = LOS_IntLock(); - - pstQueueCB = (QUEUE_CB_S *)GET_QUEUE_HANDLE(uwQueueID); - if (OS_QUEUE_UNUSED == pstQueueCB->usQueueState) - { - uwRet = LOS_ERRNO_QUEUE_NOT_CREATE; - goto QUEUE_END; - + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + return LOS_ERRNO_QUEUE_NOT_CREATE; } - if(OS_QUEUE_IS_READ(uwOperateType) && (*puwBufferSize < pstQueueCB->usQueueSize - sizeof(UINT32))) - { - uwRet = LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL; - goto QUEUE_END; + 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; } - else if(OS_QUEUE_IS_WRITE(uwOperateType) && (*puwBufferSize > pstQueueCB->usQueueSize - sizeof(UINT32))) - { - uwRet = 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 *resumedTask = NULL; + UINT32 ret; + UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType); + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize); + if (ret != LOS_OK) { goto QUEUE_END; } - if (0 == pstQueueCB->usReadWriteableCnt[uwReadWrite]) - { - if (LOS_NO_WAIT == uwTimeOut) - { - uwRet = OS_QUEUE_IS_READ(uwOperateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL; + 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_usLosTaskLock) - { - uwRet = LOS_ERRNO_QUEUE_PEND_IN_LOCK; + if (!OsPreemptableInSched()) { + ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK; goto QUEUE_END; } - pstRunTsk = (LOS_TASK_CB *)g_stLosTask.pstRunTask; - osTaskWait(&pstQueueCB->stReadWriteList[uwReadWrite], OS_TASK_STATUS_PEND_QUEUE, uwTimeOut); - LOS_IntRestore(uvIntSave); - LOS_Schedule(); + OsTaskWait(&queueCB->readWriteList[readWrite], OS_TASK_STATUS_PEND, timeout); - uvIntSave = LOS_IntLock(); + OsSchedResched(); + SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); - if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) - { - pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); - uwRet = LOS_ERRNO_QUEUE_TIMEOUT; + if (OsCurrTaskGet()->taskStatus & OS_TASK_STATUS_TIMEOUT) { + OsCurrTaskGet()->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + ret = LOS_ERRNO_QUEUE_TIMEOUT; goto QUEUE_END; } - } - else - { - pstQueueCB->usReadWriteableCnt[uwReadWrite]--; + } else { + queueCB->readWriteableCnt[readWrite]--; } - osQueueBufferOperate(pstQueueCB, uwOperateType, pBufferAddr, puwBufferSize); + OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize); - if (!LOS_ListEmpty(&pstQueueCB->stReadWriteList[!uwReadWrite])) /*lint !e514*/ - { - pstResumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&pstQueueCB->stReadWriteList[!uwReadWrite])); /*lint !e413 !e514*/ - osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND_QUEUE); - LOS_IntRestore(uvIntSave); + if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite])); + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND); + SCHEDULER_UNLOCK(intSave); LOS_Schedule(); return LOS_OK; - } - else - { - pstQueueCB->usReadWriteableCnt[!uwReadWrite]++; /*lint !e514*/ + } else { + queueCB->readWriteableCnt[!readWrite]++; } QUEUE_END: - LOS_IntRestore(uvIntSave); - return uwRet; + SCHEDULER_UNLOCK(intSave); + return ret; } -/***************************************************************************** - Function : LOS_QueueReadCopy - Description : Read queue - Input : uwQueueID - puwBufferSize - uwTimeOut - Output : pBufferAddr - puwBufferSize - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 uwQueueID, - VOID * pBufferAddr, - UINT32 * puwBufferSize, - UINT32 uwTimeOut) +LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 *bufferSize, + UINT32 timeout) { - UINT32 uwRet; - UINT32 uwOperateType; + UINT32 ret; + UINT32 operateType; - uwRet = osQueueReadParameterCheck(uwQueueID, pBufferAddr, puwBufferSize, uwTimeOut); - if(uwRet != LOS_OK) - { - return uwRet; + ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout); + if (ret != LOS_OK) { + return ret; } - uwOperateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD,OS_QUEUE_NOT_POINT); - return osQueueOperate(uwQueueID, uwOperateType, pBufferAddr, puwBufferSize, uwTimeOut); + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD); + return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout); } -/***************************************************************************** - Function : LOS_QueueWriteHeadCopy - Description : Write queue head - Input : uwQueueID - pBufferAddr - uwBufferSize - uwTimeOut - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 uwQueueID, - VOID * pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut ) +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout) { - UINT32 uwRet; - UINT32 uwOperateType; + UINT32 ret; + UINT32 operateType; - uwRet = osQueueWriteParameterCheck(uwQueueID, pBufferAddr, &uwBufferSize, uwTimeOut); - if(uwRet != LOS_OK) - { - return uwRet; + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout); + if (ret != LOS_OK) { + return ret; } - uwOperateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD,OS_QUEUE_NOT_POINT); - return osQueueOperate(uwQueueID, uwOperateType, pBufferAddr, &uwBufferSize, uwTimeOut); + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout); } -/***************************************************************************** - Function : LOS_QueueWriteCopy - Description : Write queue tail - Input : uwQueueID - pBufferAddr - uwBufferSize - uwTimeOut - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy( UINT32 uwQueueID, - VOID * pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut ) +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout) { - UINT32 uwRet; - UINT32 uwOperateType; + UINT32 ret; + UINT32 operateType; - uwRet = osQueueWriteParameterCheck(uwQueueID, pBufferAddr, &uwBufferSize, uwTimeOut); - if(uwRet != LOS_OK) - { - return uwRet; + ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout); + if (ret != LOS_OK) { + return ret; } - uwOperateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL, OS_QUEUE_NOT_POINT); - return osQueueOperate(uwQueueID, uwOperateType, pBufferAddr, &uwBufferSize, uwTimeOut); + operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL); + return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout); } -/***************************************************************************** - Function : LOS_QueueRead - Description : read queue - Input : uwQueueID - uwBufferSize - uwTimeOut - Output : pBufferAddr - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 uwQueueID, VOID *pBufferAddr, UINT32 uwBufferSize, UINT32 uwTimeOut) +LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) { - UINT32 uwRet; - UINT32 uwOperateType; - - uwRet = osQueueReadParameterCheck(uwQueueID, pBufferAddr, &uwBufferSize, uwTimeOut); - if(uwRet != LOS_OK) - { - return uwRet; - } - - uwOperateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD, OS_QUEUE_POINT); - return osQueueOperate(uwQueueID, uwOperateType, pBufferAddr, &uwBufferSize, uwTimeOut); + return LOS_QueueReadCopy(queueID, bufferAddr, &bufferSize, timeout); } -/***************************************************************************** - Function : LOS_QueueWrite - Description : Write queue tail - Input : uwQueueID - pBufferAddr - uwBufferSize - uwTimeOut - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 uwQueueID, VOID *pBufferAddr, UINT32 uwBufferSize, UINT32 uwTimeOut) +LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout) { - UINT32 uwRet; - UINT32 uwOperateType; - - uwBufferSize = sizeof(UINT32*); - - uwRet = osQueueWriteParameterCheck(uwQueueID, pBufferAddr, &uwBufferSize, uwTimeOut); - if(uwRet != LOS_OK) - { - return uwRet; + if (bufferAddr == NULL) { + return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; } - - uwOperateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL, OS_QUEUE_POINT); - return osQueueOperate(uwQueueID, uwOperateType, &pBufferAddr, &uwBufferSize, uwTimeOut); + bufferSize = sizeof(CHAR *); + return LOS_QueueWriteCopy(queueID, &bufferAddr, bufferSize, timeout); } -/***************************************************************************** - Function : LOS_QueueWriteHead - Description : write queue head - Input : uwQueueID - pBufferAddr - uwBufferSize - uwTimeOut - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead( UINT32 uwQueueID, - VOID * pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut ) +LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID, + VOID *bufferAddr, + UINT32 bufferSize, + UINT32 timeout) { - if(pBufferAddr == NULL) - { + if (bufferAddr == NULL) { return LOS_ERRNO_QUEUE_WRITE_PTR_NULL; } - uwBufferSize = sizeof(UINT32*); - return LOS_QueueWriteHeadCopy(uwQueueID, &pBufferAddr, uwBufferSize, uwTimeOut); + bufferSize = sizeof(CHAR *); + return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, bufferSize, timeout); } -/***************************************************************************** - Function : osQueueMailAlloc - Description : Mail allocate memory - Input : uwQueueID --- QueueID - : pMailPool --- MailPool - : uwTimeOut --- TimeOut - Output : None - Return : pointer if success otherwise NULL - *****************************************************************************/ -LITE_OS_SEC_TEXT VOID *osQueueMailAlloc(UINT32 uwQueueID, VOID* pMailPool, UINT32 uwTimeOut) +#if (LOSCFG_COMPAT_CMSIS == YES) +/* + * Description : Mail allocate memory + * Input : queueID --- QueueID + * : mailPool --- The memory poll that stores the mail + * : timeout --- Expiry time. The value range is [0,LOS_WAIT_FOREVER] + * Return : pointer if success otherwise NULL + */ +LITE_OS_SEC_TEXT VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeout) { - VOID *pMem = (VOID *)NULL; - UINTPTR uvIntSave; - QUEUE_CB_S *pstQueueCB = (QUEUE_CB_S *)NULL; - LOS_TASK_CB *pstRunTsk = (LOS_TASK_CB *)NULL; + VOID *mem = NULL; + UINT32 intSave; + LosQueueCB *queueCB = NULL; + LosTaskCB *runTask = NULL; - if (uwQueueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) - { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { return NULL; } - if (pMailPool == NULL) - { + if (mailPool == NULL) { return NULL; } - if (LOS_NO_WAIT != uwTimeOut) - { - if (OS_INT_ACTIVE) - { + queueCB = GET_QUEUE_HANDLE(queueID); + + OsQueueDbgTimeUpdateHook(queueID); + + if (timeout != LOS_NO_WAIT) { + if (OS_INT_ACTIVE) { return NULL; } } - uvIntSave = LOS_IntLock(); - pstQueueCB = GET_QUEUE_HANDLE(uwQueueID); - if (OS_QUEUE_UNUSED == pstQueueCB->usQueueState) - { + SCHEDULER_LOCK(intSave); + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { goto END; } - pMem = LOS_MemboxAlloc(pMailPool); - if (NULL == pMem) - { - if (uwTimeOut == LOS_NO_WAIT) - { + mem = LOS_MemboxAlloc(mailPool); + if (mem == NULL) { + if (timeout == LOS_NO_WAIT) { goto END; } - pstRunTsk = (LOS_TASK_CB *)g_stLosTask.pstRunTask; - osTaskWait(&pstQueueCB->stMemList, OS_TASK_STATUS_PEND_QUEUE, uwTimeOut); - LOS_IntRestore(uvIntSave); - LOS_Schedule(); + runTask = OsCurrTaskGet(); + OsTaskWait(&queueCB->memList, OS_TASK_STATUS_PEND, timeout); + + OsSchedResched(); - uvIntSave = LOS_IntLock(); - if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) - { - pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); + SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; goto END; - } - else - { - /* When enters the current branch, means the current task already got a available membox, - * so the pstRunTsk->puwMsg can not be NULL. + } else { + /* + * When enters the current branch, means the current task already got a available membox, + * so the runTsk->msg can not be NULL. */ - pMem = pstRunTsk->puwMsg; - pstRunTsk->puwMsg = NULL; + mem = runTask->msg; + runTask->msg = NULL; } } END: - LOS_IntRestore(uvIntSave); - return pMem; + SCHEDULER_UNLOCK(intSave); + return mem; } -/***************************************************************************** - Function : osQueueMailFree - Description : Mail free memory - Input : uwQueueID --- QueueID - : pMailPool --- MailPool - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 osQueueMailFree(UINT32 uwQueueID, VOID* pMailPool, VOID* pMailMem) +/* + * Description : Mail free memory + * Input : queueID --- QueueID + * : mailPool --- The mail memory poll address + * : mailMem --- The mail memory block address + * Return : LOS_OK on success or error code on failure + */ +LITE_OS_SEC_TEXT UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem) { - VOID *pMem = (VOID *)NULL; - UINTPTR uvIntSave; - QUEUE_CB_S *pstQueueCB = (QUEUE_CB_S *)NULL; - LOS_TASK_CB *pstResumedTask = (LOS_TASK_CB *)NULL; + VOID *mem = NULL; + UINT32 intSave; + LosQueueCB *queueCB = NULL; + LosTaskCB *resumedTask = NULL; - if (uwQueueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) - { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { return LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID; } - if (pMailPool == NULL) - { + if (mailPool == NULL) { return LOS_ERRNO_QUEUE_MAIL_PTR_INVALID; } - uvIntSave = LOS_IntLock(); + SCHEDULER_LOCK(intSave); - if (LOS_MemboxFree(pMailPool, pMailMem)) - { - LOS_IntRestore(uvIntSave); + if (LOS_MemboxFree(mailPool, mailMem)) { + SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_QUEUE_MAIL_FREE_ERROR; } - pstQueueCB = GET_QUEUE_HANDLE(uwQueueID); - if (OS_QUEUE_UNUSED == pstQueueCB->usQueueState) - { - LOS_IntRestore(uvIntSave); + queueCB = GET_QUEUE_HANDLE(queueID); + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_QUEUE_NOT_CREATE; } - if (!LOS_ListEmpty(&pstQueueCB->stMemList)) - { - pstResumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&pstQueueCB->stMemList)); /*lint !e413*/ - osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND_QUEUE); - pMem = LOS_MemboxAlloc(pMailPool); - /* At the state of LOS_IntLock, the allocation can not be failed after releasing succefully. */ + OsQueueDbgTimeUpdateHook(queueID); - pstResumedTask->puwMsg = pMem; - LOS_IntRestore(uvIntSave); + if (!LOS_ListEmpty(&queueCB->memList)) { + resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->memList)); + OsTaskWake(resumedTask, OS_TASK_STATUS_PEND); + mem = LOS_MemboxAlloc(mailPool); + /* At the state of LOS_IntLock, the allocation can not be failed after releasing succefully. */ + resumedTask->msg = mem; + SCHEDULER_UNLOCK(intSave); LOS_Schedule(); - } - else - { - LOS_IntRestore(uvIntSave); + } else { + SCHEDULER_UNLOCK(intSave); } return LOS_OK; } +#endif -/***************************************************************************** - Function : LOS_QueueDelete - Description : Delete a queue - Input : puwQueueID --- QueueID - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 uwQueueID) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID) { - QUEUE_CB_S *pstQueueCB; - UINT8 *pucQueue = NULL; - UINTPTR uvIntSave; - UINT32 uwRet; + LosQueueCB *queueCB = NULL; + UINT8 *queue = NULL; + UINT32 intSave; + UINT32 ret; - if (uwQueueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) - { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { return LOS_ERRNO_QUEUE_NOT_FOUND; } - uvIntSave = LOS_IntLock(); - pstQueueCB = (QUEUE_CB_S *)GET_QUEUE_HANDLE(uwQueueID); - if (OS_QUEUE_UNUSED == pstQueueCB->usQueueState) - { - uwRet = LOS_ERRNO_QUEUE_NOT_CREATE; + SCHEDULER_LOCK(intSave); + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + ret = LOS_ERRNO_QUEUE_NOT_CREATE; goto QUEUE_END; } - if (!LOS_ListEmpty(&pstQueueCB->stReadWriteList[OS_QUEUE_READ])) - { - uwRet = LOS_ERRNO_QUEUE_IN_TSKUSE; + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; goto QUEUE_END; } - if (!LOS_ListEmpty(&pstQueueCB->stReadWriteList[OS_QUEUE_WRITE])) - { - uwRet = LOS_ERRNO_QUEUE_IN_TSKUSE; + if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; goto QUEUE_END; } - if (!LOS_ListEmpty(&pstQueueCB->stMemList)) - { - uwRet = LOS_ERRNO_QUEUE_IN_TSKUSE; + if (!LOS_ListEmpty(&queueCB->memList)) { + ret = LOS_ERRNO_QUEUE_IN_TSKUSE; goto QUEUE_END; } - if ((pstQueueCB->usReadWriteableCnt[OS_QUEUE_WRITE] + pstQueueCB->usReadWriteableCnt[OS_QUEUE_READ]) != pstQueueCB->usQueueLen) - { - uwRet = LOS_ERRNO_QUEUE_IN_TSKWRITE; + if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) != + queueCB->queueLen) { + ret = LOS_ERRNO_QUEUE_IN_TSKWRITE; goto QUEUE_END; } - pucQueue = pstQueueCB->pucQueue; - pstQueueCB->pucQueue = (UINT8 *)NULL; - pstQueueCB->usQueueState = OS_QUEUE_UNUSED; - LOS_ListAdd(&g_stFreeQueueList, &pstQueueCB->stReadWriteList[OS_QUEUE_WRITE]); - LOS_IntRestore(uvIntSave); + queue = queueCB->queueHandle; + queueCB->queueHandle = NULL; + queueCB->queueState = OS_QUEUE_UNUSED; + queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID)); + OsQueueDbgUpdateHook(queueCB->queueID, NULL); + + LOS_ListTailInsert(&g_freeQueueList, &queueCB->readWriteList[OS_QUEUE_WRITE]); + SCHEDULER_UNLOCK(intSave); - uwRet = LOS_MemFree(m_aucSysMem0, (VOID *)pucQueue); - return uwRet; + ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue); + return ret; QUEUE_END: - LOS_IntRestore(uvIntSave); - return uwRet; + SCHEDULER_UNLOCK(intSave); + return ret; } -/***************************************************************************** - Function : LOS_QueueInfoGet - Description : Get queue infomation - Input : puwQueueID --- QueueID - Output : pstQueueInfo - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 uwQueueID, QUEUE_INFO_S *pstQueueInfo) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo) { - UINTPTR uvIntSave; - UINT32 uwRet = LOS_OK; - QUEUE_CB_S *pstQueueCB; - LOS_TASK_CB *pstTskCB; + UINT32 intSave; + UINT32 ret = LOS_OK; + LosQueueCB *queueCB = NULL; + LosTaskCB *tskCB = NULL; - if (NULL == pstQueueInfo) - { + if (queueInfo == NULL) { return LOS_ERRNO_QUEUE_PTR_NULL; } - if (uwQueueID >= LOSCFG_BASE_IPC_QUEUE_LIMIT) - { + if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) { return LOS_ERRNO_QUEUE_INVALID; } - (VOID)memset((VOID *)pstQueueInfo, 0, sizeof(QUEUE_INFO_S)); - uvIntSave = LOS_IntLock(); - - pstQueueCB = (QUEUE_CB_S *)GET_QUEUE_HANDLE(uwQueueID); + (VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S)); + SCHEDULER_LOCK(intSave); - if (OS_QUEUE_UNUSED == pstQueueCB->usQueueState) - { - uwRet = LOS_ERRNO_QUEUE_NOT_CREATE; + queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID); + if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) { + ret = LOS_ERRNO_QUEUE_NOT_CREATE; goto QUEUE_END; } - pstQueueInfo->uwQueueID = uwQueueID; - pstQueueInfo->usQueueLen = pstQueueCB->usQueueLen; - pstQueueInfo->usQueueSize = pstQueueCB->usQueueSize; - pstQueueInfo->usQueueHead = pstQueueCB->usQueueHead; - pstQueueInfo->usQueueTail = pstQueueCB->usQueueTail; - pstQueueInfo->usReadableCnt = pstQueueCB->usReadWriteableCnt[OS_QUEUE_READ]; - pstQueueInfo->usWritableCnt = pstQueueCB->usReadWriteableCnt[OS_QUEUE_WRITE]; + queueInfo->uwQueueID = queueID; + queueInfo->usQueueLen = queueCB->queueLen; + queueInfo->usQueueSize = queueCB->queueSize; + queueInfo->usQueueHead = queueCB->queueHead; + queueInfo->usQueueTail = queueCB->queueTail; + queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ]; + queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE]; - LOS_DL_LIST_FOR_EACH_ENTRY(pstTskCB, &pstQueueCB->stReadWriteList[OS_QUEUE_READ], LOS_TASK_CB, stPendList) /*lint !e413*/ - { - pstQueueInfo->uwWaitReadTask |= (1 << pstTskCB->uwTaskID); + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) { + queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID; } - LOS_DL_LIST_FOR_EACH_ENTRY(pstTskCB, &pstQueueCB->stReadWriteList[OS_QUEUE_WRITE], LOS_TASK_CB, stPendList) /*lint !e413*/ - { - pstQueueInfo->uwWaitWriteTask |= (1 << pstTskCB->uwTaskID); + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) { + queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID; } - LOS_DL_LIST_FOR_EACH_ENTRY(pstTskCB, &pstQueueCB->stMemList, LOS_TASK_CB, stPendList) /*lint !e413*/ - { - pstQueueInfo->uwWaitMemTask |= (1 << pstTskCB->uwTaskID); + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) { + queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID; } QUEUE_END: - LOS_IntRestore(uvIntSave); - return uwRet; + SCHEDULER_UNLOCK(intSave); + return ret; } -#endif /*(LOSCFG_BASE_IPC_QUEUE == YES)*/ +#endif /* (LOSCFG_BASE_IPC_QUEUE == YES) */ #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/ipc/los_queue_debug.c b/kernel/base/ipc/los_queue_debug.c new file mode 100644 index 000000000..be78738e2 --- /dev/null +++ b/kernel/base/ipc/los_queue_debug.c @@ -0,0 +1,219 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Queue Debug + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_queue_debug_pri.h" +#include "los_hw_pri.h" +#include "los_ipcdebug_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#ifdef LOSCFG_DEBUG_QUEUE + +typedef struct { + TSK_ENTRY_FUNC creater; /* The task entry who created this queue */ + UINT64 lastAccessTime; /* The last access time */ +} QueueDebugCB; + +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) +STATIC QueueDebugCB *g_queueDebugArray = NULL; +#else +STATIC QueueDebugCB g_queueDebugArray[LOSCFG_BASE_IPC_QUEUE_LIMIT]; +#endif + +STATIC BOOL QueueCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right) +{ + return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > + *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); +} + +UINT32 OsQueueDbgInit(VOID) +{ +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) + UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(QueueDebugCB); + /* system resident memory, don't free */ + g_queueDebugArray = (QueueDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_queueDebugArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } + (VOID)memset_s(g_queueDebugArray, size, 0, size); +#endif + + return LOS_OK; +} + +VOID OsQueueDbgTimeUpdate(UINT32 queueID) +{ + QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueID)]; + queueDebug->lastAccessTime = LOS_TickCountGet(); + return; +} + +VOID OsQueueDbgUpdate(UINT32 queueID, TSK_ENTRY_FUNC entry) +{ + QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueID)]; + queueDebug->creater = entry; + queueDebug->lastAccessTime = LOS_TickCountGet(); + return; +} + +STATIC INLINE VOID OsQueueInfoOutPut(const LosQueueCB *node) +{ + PRINTK("Queue ID <0x%x> may leak, queue len is 0x%x, " + "readable cnt:0x%x, writeable cnt:0x%x, ", + node->queueID, + node->queueLen, + node->readWriteableCnt[OS_QUEUE_READ], + node->readWriteableCnt[OS_QUEUE_WRITE]); +} + +STATIC INLINE VOID OsQueueOpsOutput(const QueueDebugCB *node) +{ + PRINTK("TaskEntry of creater:0x%p, Latest operation time: 0x%llx\n", + node->creater, node->lastAccessTime); +} + +STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count) +{ + LosQueueCB queueNode = {0}; + QueueDebugCB queueDebugNode = {0}; + UINT32 index, intSave; + IpcSortParam queueSortParam; + queueSortParam.buf = (CHAR *)g_queueDebugArray; + queueSortParam.ipcDebugCBSize = sizeof(QueueDebugCB); + queueSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT; + queueSortParam.sortElemOff = OFFSET_OF_FIELD(QueueDebugCB, lastAccessTime); + + if (count > 0) { + SCHEDULER_LOCK(intSave); + OsArraySortByTime(indexArray, 0, count - 1, &queueSortParam, QueueCompareValue); + SCHEDULER_UNLOCK(intSave); + for (index = 0; index < count; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&queueNode, sizeof(LosQueueCB), + GET_QUEUE_HANDLE(indexArray[index]), sizeof(LosQueueCB)); + (VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB), + &g_queueDebugArray[indexArray[index]], sizeof(QueueDebugCB)); + SCHEDULER_UNLOCK(intSave); + if (queueNode.queueState == OS_QUEUE_UNUSED) { + continue; + } + OsQueueInfoOutPut(&queueNode); + OsQueueOpsOutput(&queueDebugNode); + } + } + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray); +} + +VOID OsQueueCheck(VOID) +{ + LosQueueCB queueNode = {0}; + QueueDebugCB queueDebugNode = {0}; + UINT32 index, intSave; + UINT32 count = 0; + + /* + * This return value does not need to be judged immediately, + * and the following code logic has already distinguished the return value from null and non-empty, + * and there is no case of accessing the null pointer. + */ + UINT32 *indexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(UINT32)); + + for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&queueNode, sizeof(LosQueueCB), + GET_QUEUE_HANDLE(index), sizeof(LosQueueCB)); + (VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB), + &g_queueDebugArray[index], sizeof(QueueDebugCB)); + SCHEDULER_UNLOCK(intSave); + if ((queueNode.queueState == OS_QUEUE_UNUSED) || + ((queueNode.queueState == OS_QUEUE_INUSED) && (queueDebugNode.creater == NULL))) { + continue; + } + if ((queueNode.queueState == OS_QUEUE_INUSED) && + (queueNode.queueLen == queueNode.readWriteableCnt[OS_QUEUE_WRITE]) && + LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_READ]) && + LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_WRITE]) && + LOS_ListEmpty(&queueNode.memList)) { + PRINTK("Queue ID <0x%x> may leak, No task uses it, " + "QueueLen is 0x%x, ", + queueNode.queueID, + queueNode.queueLen); + OsQueueOpsOutput(&queueDebugNode); + } else { + if (indexArray != NULL) { + *(indexArray + count) = index; + count++; + } else { + OsQueueInfoOutPut(&queueNode); + OsQueueOpsOutput(&queueDebugNode); + } + } + } + + if (indexArray != NULL) { + SortQueueIndexArray(indexArray, count); + } + + return; +} + +#ifdef LOSCFG_SHELL +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdQueueInfoGet(UINT32 argc, const CHAR **argv) +{ + if (argc > 0) { + PRINTK("\nUsage: queue\n"); + return OS_ERROR; + } + PRINTK("used queues information: \n"); + OsQueueCheck(); + return LOS_OK; +} + +SHELLCMD_ENTRY(queue_shellcmd, CMD_TYPE_EX, "queue", 0, (CmdCallBackFunc)OsShellCmdQueueInfoGet); +#endif /* LOSCFG_SHELL */ +#endif /* LOSCFG_DEBUG_QUEUE */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/ipc/los_sem.c b/kernel/base/ipc/los_sem.c index 2f593a6ae..4fdb69fca 100644 --- a/kernel/base/ipc/los_sem.c +++ b/kernel/base/ipc/los_sem.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Semaphore * 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 @@ -22,321 +22,279 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_sem.inc" -#include "los_base.ph" -#include "los_err.ph" -#include "los_memory.ph" -#include "los_priqueue.ph" -#include "los_sys.ph" -#include "los_task.ph" -#if (LOSCFG_PLATFORM_EXC == YES) + * --------------------------------------------------------------------------- */ + +#include "los_sem_pri.h" +#include "los_sem_debug_pri.h" +#include "los_err_pri.h" +#include "los_task_pri.h" #include "los_exc.h" -#endif #ifdef __cplusplus #if __cplusplus -extern "C"{ +extern "C" { #endif #endif /* __cplusplus */ - #if (LOSCFG_BASE_IPC_SEM == YES) -LITE_OS_SEC_BSS LOS_DL_LIST g_stUnusedSemList; -LITE_OS_SEC_BSS SEM_CB_S *g_pstAllSem; - -/***************************************************************************** - 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) +LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList; + +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) +LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL; +#else +#if (LOSCFG_BASE_IPC_SEM_LIMIT <= 0) +#error "sem maxnum cannot be zero" +#endif /* LOSCFG_BASE_IPC_SEM_LIMIT <= 0 */ +LITE_OS_SEC_BSS LosSemCB g_allSem[LOSCFG_BASE_IPC_SEM_LIMIT]; +#endif + +/* + * Description : Initialize the semaphore doubly linked list + * Return : LOS_OK on success, or error code on failure + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID) { - SEM_CB_S *pstSemNode; - UINT16 uwIndex; + LosSemCB *semNode = NULL; + UINT32 index; - LOS_ListInit(&g_stUnusedSemList); +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) + UINT32 size; - if (LOSCFG_BASE_IPC_SEM_LIMIT == 0) /*lint !e506*/ - { - return LOS_ERRNO_SEM_MAXNUM_ZERO; + size = g_semLimit * sizeof(LosSemCB); + /* system resident memory, don't free */ + g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_allSem == NULL) { + return LOS_ERRNO_SEM_NO_MEMORY; } + (VOID)memset_s(g_allSem, size, 0, size); +#endif - g_pstAllSem = (SEM_CB_S *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(SEM_CB_S))); - if (NULL == g_pstAllSem) - { - return LOS_ERRNO_SEM_NO_MEMORY; + LOS_ListInit(&g_unusedSemList); + + for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) { + semNode = ((LosSemCB *)g_allSem) + index; + semNode->semID = SET_SEM_ID(0, index); + semNode->semStat = OS_SEM_UNUSED; + LOS_ListTailInsert(&g_unusedSemList, &semNode->semList); } - /* Connect all the ECBs in a doubly linked list. */ - for (uwIndex = 0; uwIndex < LOSCFG_BASE_IPC_SEM_LIMIT; uwIndex++) - { - pstSemNode = ((SEM_CB_S *)g_pstAllSem) + uwIndex; - pstSemNode->usSemID = uwIndex; - pstSemNode->usSemStat = OS_SEM_UNUSED; - LOS_ListTailInsert(&g_stUnusedSemList, &pstSemNode->stSemList); + if (OsSemDbgInitHook() != LOS_OK) { + return LOS_ERRNO_SEM_NO_MEMORY; } return LOS_OK; } - -/***************************************************************************** - Function : osSemCreate - Description : create the Semaphore - Input : None, - Output : None, - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 osSemCreate (UINT16 usCount, UINT16 usMaxCount, UINT32 *puwSemHandle) +/* + * Description : Create a semaphore, + * Input : count --- semaphore count, + * maxCount --- Max number of available semaphores, + * 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 uwIntSave; - SEM_CB_S *pstSemCreated; - LOS_DL_LIST *pstUnusedSem; - UINT32 uwErrNo; - UINT32 uwErrLine; - - if (NULL == puwSemHandle) - { + UINT32 intSave; + LosSemCB *semCreated = NULL; + LOS_DL_LIST *unusedSem = NULL; + UINT32 errNo; + UINT32 errLine; + + if (semHandle == NULL) { return LOS_ERRNO_SEM_PTR_NULL; } - if (usCount > usMaxCount) - { + if (count > maxCount) { OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW); } - uwIntSave = LOS_IntLock(); + SCHEDULER_LOCK(intSave); - if (LOS_ListEmpty(&g_stUnusedSemList)) - { - LOS_IntRestore(uwIntSave); + if (LOS_ListEmpty(&g_unusedSemList)) { + SCHEDULER_UNLOCK(intSave); + OsSemInfoGetFullDataHook(); OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY); } - pstUnusedSem = LOS_DL_LIST_FIRST(&(g_stUnusedSemList)); - LOS_ListDelete(pstUnusedSem); - pstSemCreated = (GET_SEM_LIST(pstUnusedSem)); /*lint !e413*/ - pstSemCreated->usSemCount = usCount; - pstSemCreated->usSemStat = OS_SEM_USED; - pstSemCreated->usMaxSemCount = usMaxCount; - LOS_ListInit(&pstSemCreated->stSemList); - *puwSemHandle = (UINT32)pstSemCreated->usSemID; - LOS_IntRestore(uwIntSave); + 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 = semCreated->semID; + + OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count); + + SCHEDULER_UNLOCK(intSave); return LOS_OK; -ErrHandler: - OS_RETURN_ERROR_P2(uwErrLine, uwErrNo); +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); } -/***************************************************************************** - Function : LOS_SemCreate - Description : Create a semaphore, - Input : uwCount--------- semaphore count, - Output : puwSemHandle-----Index of semaphore, - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate (UINT16 usCount, UINT32 *puwSemHandle) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle) { - return osSemCreate(usCount, OS_SEM_COUNTING_MAX_COUNT, puwSemHandle); + return OsSemCreate(count, OS_SEM_COUNT_MAX, semHandle); } -/***************************************************************************** - Function : LOS_BinarySemCreate - Description : Create a binary semaphore, - Input : uwCount--------- semaphore count, - Output : puwSemHandle-----Index of semaphore, - Return : LOS_OK on success ,or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate (UINT16 usCount, UINT32 *puwSemHandle) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle) { - return osSemCreate(usCount, OS_SEM_BINARY_MAX_COUNT, puwSemHandle); + return OsSemCreate(count, OS_SEM_BINARY_COUNT_MAX, semHandle); } -/***************************************************************************** - Function : LOS_SemDelete - Description : Delete a semaphore, - Input : uwSemHandle--------- semaphore operation handle, - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 uwSemHandle) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle) { - UINT32 uwIntSave; - SEM_CB_S *pstSemDeleted; - UINT32 uwErrNo; - UINT32 uwErrLine; + UINT32 intSave; + LosSemCB *semDeleted = NULL; + UINT32 errNo; + UINT32 errLine; - if (uwSemHandle >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) - { + if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); } - pstSemDeleted = GET_SEM(uwSemHandle); - uwIntSave = LOS_IntLock(); - if (OS_SEM_UNUSED == pstSemDeleted->usSemStat) - { - LOS_IntRestore(uwIntSave); + semDeleted = GET_SEM(semHandle); + + SCHEDULER_LOCK(intSave); + + if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) { + SCHEDULER_UNLOCK(intSave); OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID); } - if (!LOS_ListEmpty(&pstSemDeleted->stSemList)) - { - LOS_IntRestore(uwIntSave); + if (!LOS_ListEmpty(&semDeleted->semList)) { + SCHEDULER_UNLOCK(intSave); OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED); } - LOS_ListAdd(&g_stUnusedSemList, &pstSemDeleted->stSemList); - pstSemDeleted->usSemStat = OS_SEM_UNUSED; - LOS_IntRestore(uwIntSave); + LOS_ListTailInsert(&g_unusedSemList, &semDeleted->semList); + semDeleted->semStat = OS_SEM_UNUSED; + semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID)); + + OsSemDbgUpdateHook(semDeleted->semID, NULL, 0); + + SCHEDULER_UNLOCK(intSave); return LOS_OK; -ErrHandler: - OS_RETURN_ERROR_P2(uwErrLine, uwErrNo); + +ERR_HANDLER: + OS_RETURN_ERROR_P2(errLine, errNo); } -/***************************************************************************** - Function : LOS_SemPend - Description : Specified semaphore P operation, - Input : uwSemHandle--------- semaphore operation handle, - uwTimeout ---------- waitting time - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 uwSemHandle, UINT32 uwTimeout) +LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout) { - UINT32 uwIntSave; - SEM_CB_S *pstSemPended; - UINT32 uwRetErr; - LOS_TASK_CB *pstRunTsk; + UINT32 intSave; + LosSemCB *semPended = GET_SEM(semHandle); + UINT32 retErr = LOS_OK; + LosTaskCB *runTask = NULL; - if (uwSemHandle >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) - { + if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) { OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); } - pstSemPended = GET_SEM(uwSemHandle); - uwIntSave = LOS_IntLock(); - if (OS_SEM_UNUSED == pstSemPended->usSemStat) - { - LOS_IntRestore(uwIntSave); - OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); + if (OS_INT_ACTIVE) { + return LOS_ERRNO_SEM_PEND_INTERR; } - if (pstSemPended->usSemCount > 0) - { - pstSemPended->usSemCount--; - LOS_IntRestore(uwIntSave); - return LOS_OK; + runTask = OsCurrTaskGet(); + if (runTask->taskFlags & OS_TASK_FLAG_SYSTEM) { + return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK; } - if (!uwTimeout) - { - uwRetErr = LOS_ERRNO_SEM_UNAVAILABLE; - goto errre_uniSemPend; - } + SCHEDULER_LOCK(intSave); - if (OS_INT_ACTIVE) - { - uwRetErr = LOS_ERRNO_SEM_PEND_INTERR; - PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n"); -#if (LOSCFG_PLATFORM_EXC == YES) - osBackTrace(); -#endif - goto errre_uniSemPend; + if ((semPended->semStat == OS_SEM_UNUSED) || (semPended->semID != semHandle)) { + retErr = LOS_ERRNO_SEM_INVALID; + goto OUT; } - if (g_usLosTaskLock) - { - uwRetErr = LOS_ERRNO_SEM_PEND_IN_LOCK; - PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); -#if (LOSCFG_PLATFORM_EXC == YES) - osBackTrace(); -#endif - goto errre_uniSemPend; + /* Update the operate time, no matter the actual Pend success or not */ + OsSemDbgTimeUpdateHook(semHandle); + + if (semPended->semCount > 0) { + semPended->semCount--; + goto OUT; + } else if (!timeout) { + retErr = LOS_ERRNO_SEM_UNAVAILABLE; + goto OUT; } - pstRunTsk = (LOS_TASK_CB *)g_stLosTask.pstRunTask; - pstRunTsk->pTaskSem = (VOID *)pstSemPended; - osTaskWait(&pstSemPended->stSemList, OS_TASK_STATUS_PEND, uwTimeout); - (VOID)LOS_IntRestore(uwIntSave); - LOS_Schedule(); - - if (pstRunTsk->usTaskStatus & OS_TASK_STATUS_TIMEOUT) - { - uwIntSave = LOS_IntLock(); - pstRunTsk->usTaskStatus &= (~OS_TASK_STATUS_TIMEOUT); - uwRetErr = LOS_ERRNO_SEM_TIMEOUT; - goto errre_uniSemPend; + if (!OsPreemptableInSched()) { + retErr = LOS_ERRNO_SEM_PEND_IN_LOCK; + goto OUT; } - return LOS_OK; + runTask->taskSem = (VOID *)semPended; + OsTaskWait(&semPended->semList, OS_TASK_STATUS_PEND, timeout); + + /* + * it will immediately do the scheduling, so there's no need to release the + * task spinlock. when this task's been rescheduled, it will be holding the spinlock. + */ + OsSchedResched(); + + SCHEDULER_UNLOCK(intSave); + SCHEDULER_LOCK(intSave); + if (runTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { + runTask->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; + retErr = LOS_ERRNO_SEM_TIMEOUT; + goto OUT; + } -errre_uniSemPend: - (VOID)LOS_IntRestore(uwIntSave); - OS_RETURN_ERROR(uwRetErr); +OUT: + SCHEDULER_UNLOCK(intSave); + return retErr; } -/***************************************************************************** - Function : LOS_SemPend - Description : Specified semaphore V operation, - Input : uwSemHandle--------- semaphore operation handle, - Output : None - Return : LOS_OK on success or error code on failure - *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 uwSemHandle) +LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle) { - UINT32 uwIntSave; - SEM_CB_S *pstSemPosted = GET_SEM(uwSemHandle); - LOS_TASK_CB *pstResumedTask; + UINT32 intSave; + LosSemCB *semPosted = GET_SEM(semHandle); + LosTaskCB *resumedTask = NULL; - if (uwSemHandle >= LOSCFG_BASE_IPC_SEM_LIMIT) - { + if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) { return LOS_ERRNO_SEM_INVALID; } - uwIntSave = LOS_IntLock(); + SCHEDULER_LOCK(intSave); - if (OS_SEM_UNUSED == pstSemPosted->usSemStat) - { - LOS_IntRestore(uwIntSave); + if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) { + SCHEDULER_UNLOCK(intSave); OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID); } - if (pstSemPosted->usMaxSemCount == pstSemPosted->usSemCount) - { - (VOID)LOS_IntRestore(uwIntSave); + /* Update the operate time, no matter the actual Post success or not */ + OsSemDbgTimeUpdateHook(semHandle); + + if (semPosted->semCount == OS_SEM_COUNT_MAX) { + SCHEDULER_UNLOCK(intSave); OS_RETURN_ERROR(LOS_ERRNO_SEM_OVERFLOW); } - if (!LOS_ListEmpty(&pstSemPosted->stSemList)) - { - pstResumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(pstSemPosted->stSemList))); /*lint !e413*/ - pstResumedTask->pTaskSem = NULL; - osTaskWake(pstResumedTask, OS_TASK_STATUS_PEND); + 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); - (VOID)LOS_IntRestore(uwIntSave); + SCHEDULER_UNLOCK(intSave); LOS_Schedule(); - } - else - { - pstSemPosted->usSemCount++; - (VOID)LOS_IntRestore(uwIntSave); + } else { + semPosted->semCount++; + SCHEDULER_UNLOCK(intSave); } return LOS_OK; } -#endif /*(LOSCFG_BASE_IPC_SEM == YES)*/ +#endif /* (LOSCFG_BASE_IPC_SEM == YES) */ #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/ipc/los_sem_debug.c b/kernel/base/ipc/los_sem_debug.c new file mode 100644 index 000000000..f80248d1e --- /dev/null +++ b/kernel/base/ipc/los_sem_debug.c @@ -0,0 +1,322 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Sem Debug + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_sem_debug_pri.h" +#include "stdlib.h" +#include "los_typedef.h" +#include "los_task_pri.h" +#include "los_ipcdebug_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define OS_ALL_SEM_MASK 0xffffffff + +#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_SHELL) +STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode) +{ + LosTaskCB *tskCB = NULL; + CHAR *nameArr[LOSCFG_BASE_CORE_TSK_CONFIG] = {0}; + UINT32 i, intSave; + UINT32 num = 0; + + SCHEDULER_LOCK(intSave); + if ((semNode->semStat == OS_SEM_UNUSED) || (LOS_ListEmpty(&semNode->semList))) { + SCHEDULER_UNLOCK(intSave); + return; + } + + LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &semNode->semList, LosTaskCB, pendList) { + nameArr[num++] = tskCB->taskName; + if (num == LOSCFG_BASE_CORE_TSK_CONFIG) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + + PRINTK("Pended task list : "); + for (i = 0; i < num; i++) { + if (i == 0) { + PRINTK("%s\n", nameArr[i]); + } else { + PRINTK(", %s", nameArr[i]); + } + } + PRINTK("\n"); +} +#endif + +#ifdef LOSCFG_DEBUG_SEMAPHORE + +typedef struct { + UINT16 origSemCount; /* Number of orignal available semaphores */ + UINT64 lastAccessTime; /* The last operation time */ + TSK_ENTRY_FUNC creater; /* The task entry who created this sem */ +} SemDebugCB; + +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) +STATIC SemDebugCB *g_semDebugArray = NULL; +#else +STATIC SemDebugCB g_semDebugArray[LOSCFG_BASE_IPC_SEM_LIMIT]; +#endif + +STATIC BOOL SemCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right) +{ + return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > + *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); +} + +UINT32 OsSemDbgInit(VOID) +{ + UINT32 size = LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(SemDebugCB); +#if (LOSCFG_BASE_IPC_DYNAMIC_MEM == YES) + /* system resident memory, don't free */ + g_semDebugArray = (SemDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_semDebugArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } +#endif + (VOID)memset_s(g_semDebugArray, size, 0, size); + + return LOS_OK; +} + +VOID OsSemDbgTimeUpdate(UINT32 semID) +{ + SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)]; + semDebug->lastAccessTime = LOS_TickCountGet(); + return; +} + +VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count) +{ + SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)]; + semDebug->creater = creater; + semDebug->lastAccessTime = LOS_TickCountGet(); + semDebug->origSemCount = count; + return; +} + +STATIC VOID OsSemSort(UINT32 *semIndexArray, UINT32 usedCount) +{ + UINT32 i, intSave; + LosSemCB *semCB = NULL; + LosSemCB semNode = {0}; + SemDebugCB semDebug = {0}; + IpcSortParam semSortParam; + semSortParam.buf = (CHAR *)g_semDebugArray; + semSortParam.ipcDebugCBSize = sizeof(SemDebugCB); + semSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT; + semSortParam.sortElemOff = OFFSET_OF_FIELD(SemDebugCB, lastAccessTime); + + /* It will Print out ALL the Used Semaphore List. */ + PRINTK("Used Semaphore List: \n"); + PRINTK("\r\n SemID Count OriginalCount Creater(TaskEntry) LastAccessTime\n"); + PRINTK(" ------ ------ ------------- ------------------ -------------- \n"); + + SCHEDULER_LOCK(intSave); + OsArraySortByTime(semIndexArray, 0, usedCount - 1, &semSortParam, SemCompareValue); + SCHEDULER_UNLOCK(intSave); + for (i = 0; i < usedCount; i++) { + semCB = GET_SEM(semIndexArray[i]); + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); + (VOID)memcpy_s(&semDebug, sizeof(SemDebugCB), &g_semDebugArray[semIndexArray[i]], sizeof(SemDebugCB)); + SCHEDULER_UNLOCK(intSave); + if ((semNode.semStat != OS_SEM_USED) || (semDebug.creater == NULL)) { + continue; + } + PRINTK(" 0x%-07x0x%-07u0x%-14u%-22p0x%llx\n", semNode.semID, semDebug.origSemCount, + semNode.semCount, semDebug.creater, semDebug.lastAccessTime); + if (!LOS_ListEmpty(&semNode.semList)) { + OsSemPendedTaskNamePrint(semCB); + } + } +} + +UINT32 OsSemInfoGetFullData(VOID) +{ + UINT32 usedSemCnt = 0; + LosSemCB *semNode = NULL; + SemDebugCB *semDebug = NULL; + UINT32 i; + UINT32 *semIndexArray = NULL; + UINT32 count, intSave; + + SCHEDULER_LOCK(intSave); + /* Get the used semaphore count. */ + for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { + semNode = GET_SEM(i); + semDebug = &g_semDebugArray[i]; + if ((semNode->semStat == OS_SEM_USED) && (semDebug->creater != NULL)) { + usedSemCnt++; + } + } + SCHEDULER_UNLOCK(intSave); + + if (usedSemCnt > 0) { + semIndexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, usedSemCnt * sizeof(UINT32)); + if (semIndexArray == NULL) { + PRINTK("LOS_MemAlloc failed in %s \n", __func__); + return LOS_NOK; + } + + /* Fill the semIndexArray with the real index. */ + count = 0; + + SCHEDULER_LOCK(intSave); + for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { + semNode = GET_SEM(i); + semDebug = &g_semDebugArray[i]; + if ((semNode->semStat != OS_SEM_USED) || (semDebug->creater == NULL)) { + continue; + } + *(semIndexArray + count) = i; + count++; + /* if the count is touched usedSemCnt break. */ + if (count >= usedSemCnt) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + OsSemSort(semIndexArray, count); + + /* free the index array. */ + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, semIndexArray); + } + return LOS_OK; +} +#endif /* LOSCFG_DEBUG_SEMAPHORE */ + +#ifdef LOSCFG_SHELL +STATIC UINT32 OsSemInfoOutput(size_t semID) +{ + UINT32 loop, semCnt, intSave; + LosSemCB *semCB = NULL; + LosSemCB semNode = {0}; + + if (semID == OS_ALL_SEM_MASK) { + for (loop = 0, semCnt = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) { + semCB = GET_SEM(loop); + SCHEDULER_LOCK(intSave); + if (semCB->semStat == OS_SEM_USED) { + (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); + SCHEDULER_UNLOCK(intSave); + semCnt++; + PRINTK("\r\n SemID Count\n ---------- -----\n"); + PRINTK(" 0x%08x %u\n", semNode.semID, semNode.semCount); + continue; + } + SCHEDULER_UNLOCK(intSave); + } + PRINTK(" SemUsingNum : %u\n\n", semCnt); + return LOS_OK; + } else { + if (GET_SEM_INDEX(semID) >= LOSCFG_BASE_IPC_SEM_LIMIT) { + PRINTK("\nInvalid semphore id!\n"); + return LOS_OK; + } + + semCB = GET_SEM(semID); + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); + SCHEDULER_UNLOCK(intSave); + if ((semNode.semID != semID) || (semNode.semStat != OS_SEM_USED)) { + PRINTK("\nThe semphore is not in use!\n"); + return LOS_OK; + } + + PRINTK("\r\n SemID Count\n ---------- -----\n"); + PRINTK(" 0x%08x 0x%u\n", semNode.semID, semNode.semCount); + + if (LOS_ListEmpty(&semNode.semList)) { + PRINTK("No task is pended on this semphore!\n"); + return LOS_OK; + } else { + OsSemPendedTaskNamePrint(semCB); + } + } + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSemInfoGet(UINT32 argc, const CHAR **argv) +{ + size_t semID; + CHAR *endPtr = NULL; + UINT32 ret; + + if (argc > 1) { +#ifdef LOSCFG_DEBUG_SEMAPHORE + PRINTK("\nUsage: sem [fulldata|ID]\n"); +#else + PRINTK("\nUsage: sem [ID]\n"); +#endif + return OS_ERROR; + } + + if (argc == 0) { + semID = OS_ALL_SEM_MASK; + } else { +#ifdef LOSCFG_DEBUG_SEMAPHORE + if (strcmp(argv[0], "fulldata") == 0) { + ret = OsSemInfoGetFullData(); + return ret; + } +#endif + semID = strtoul(argv[0], &endPtr, 0); + if ((endPtr == NULL) || (*endPtr != 0)) { + PRINTK("\nsem ID can't access %s.\n", argv[0]); + return 0; + } + } + + ret = OsSemInfoOutput(semID); + return ret; +} + +SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/mem/Makefile b/kernel/base/mem/Makefile deleted file mode 100644 index 088680927..000000000 --- a/kernel/base/mem/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -objs-y += common -objs-y += bestfit_little -#objs-y += bestfit diff --git a/kernel/base/mem/bestfit/los_memory.c b/kernel/base/mem/bestfit/los_memory.c index e3d00f01b..03f34f85c 100644 --- a/kernel/base/mem/bestfit/los_memory.c +++ b/kernel/base/mem/bestfit/los_memory.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Mem Module Implementation * 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 @@ -22,29 +22,31 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/*ISP_LINT*/ -/*lint -e7 - -esym(7,*)*/ -/*lint -e826 -e834 -e835 -e845 -e838 - -esym(826,*) -esym(834,*) -esym(835,*) -esym(845,*) -esym(838,*)*/ -#include "string.h" -#include "los_memory.h" -#include "los_memory.inc" -#include "los_task.ph" + * --------------------------------------------------------------------------- */ + +#include "los_memory_pri.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdio.h" +#endif +#include "los_multipledlinkhead_pri.h" +#include "los_memstat_pri.h" +#ifdef LOSCFG_MEM_RECORDINFO +#include "los_memrecord_pri.h" +#endif +#include "los_task_pri.h" #include "los_exc.h" +#include "los_spinlock.h" -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) -#include "los_memstat.inc" +#ifdef LOSCFG_SHELL_EXCINFO +#include "los_excinfo_pri.h" #endif #ifdef __cplusplus @@ -53,1288 +55,2515 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/** - * @ingroup los_memory - * Memory linked list node structure - */ -typedef struct tagLOS_MEM_DYN_NODE -{ - LOS_DL_LIST stFreeNodeInfo; /**selfNode.freeNodeInfo.pstNext + * the low 16 bits is the taskID and the high 16bits is the moduleID + */ +STATIC VOID OsMemNodeSave(LosMemDynNode *node); +#define OS_MEM_TASKID_SET(node, ID) do { \ + UINTPTR tmp_ = (UINTPTR)(((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext); \ + tmp_ &= 0xffff0000U; \ + tmp_ |= (ID); \ + ((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext = (LOS_DL_LIST *)tmp_; \ + OsMemNodeSave((LosMemDynNode *)(node)); \ +} while (0) +#else +#define OS_MEM_TASKID_SET(node, ID) do { \ + UINTPTR tmp_ = (UINTPTR)(((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext); \ + tmp_ &= 0xffff0000U; \ + tmp_ |= (ID); \ + ((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext = (LOS_DL_LIST *)tmp_; \ +} while (0) +#endif +#define OS_MEM_TASKID_GET(node) ((UINTPTR)(((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext) & 0xffffU) + +#ifdef LOSCFG_MEM_MUL_MODULE +#define BITS_NUM_OF_TYPE_SHORT 16 +#ifdef LOSCFG_MEM_HEAD_BACKUP +#define OS_MEM_MODID_SET(node, ID) do { \ + UINTPTR tmp_ = (UINTPTR)(((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext); \ + tmp_ &= 0xffffU; \ + tmp_ |= (ID) << BITS_NUM_OF_TYPE_SHORT; \ + ((LosMemDynNode *)node)->selfNode.freeNodeInfo.pstNext = (LOS_DL_LIST *)tmp_; \ + OsMemNodeSave((LosMemDynNode *)(node)); \ +} while (0) +#else +#define OS_MEM_MODID_SET(node, ID) do { \ + UINTPTR tmp_ = (UINTPTR)(((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext); \ + tmp_ &= 0xffffU; \ + tmp_ |= (ID) << BITS_NUM_OF_TYPE_SHORT; \ + ((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext = (LOS_DL_LIST *)tmp_; \ +} while (0) +#endif +#define OS_MEM_MODID_GET(node) \ + (((UINTPTR)(((LosMemDynNode *)(node))->selfNode.freeNodeInfo.pstNext) >> BITS_NUM_OF_TYPE_SHORT) & 0xffffU) +#endif + +#define OS_MEM_ALIGN(p, alignSize) (((UINTPTR)(p) + (alignSize) - 1) & ~((UINTPTR)((alignSize) - 1))) +#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(LosMemPoolInfo)) +#define IS_POW_TWO(value) ((((UINTPTR)(value)) & ((UINTPTR)(value) - 1)) == 0) +#define POOL_ADDR_ALIGNSIZE 64 +#ifdef LOSCFG_AARCH64 +#define OS_MEM_ALIGN_SIZE 8 +#else +#define OS_MEM_ALIGN_SIZE 4 +#endif +#define OS_MEM_NODE_USED_FLAG 0x80000000U +#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U +#define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG) + +#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_ALIGNED_AND_USED_FLAG) +#define OS_MEM_HEAD(pool, size) \ + OsDLnkMultiHead(OS_MEM_HEAD_ADDR(pool), size) +#define OS_MEM_HEAD_ADDR(pool) \ + ((VOID *)((UINTPTR)(pool) + sizeof(LosMemPoolInfo))) +#define OS_MEM_NEXT_NODE(node) \ + ((LosMemDynNode *)(VOID *)((UINT8 *)(node) + OS_MEM_NODE_GET_SIZE((node)->selfNode.sizeAndFlag))) +#define OS_MEM_FIRST_NODE(pool) \ + ((LosMemDynNode *)(VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE)) +#define OS_MEM_END_NODE(pool, size) \ + ((LosMemDynNode *)(VOID *)(((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)&(value) ^ (UINTPTR)(-1)) +#define OS_MEM_MAGIC_VALID(value) \ + (((UINTPTR)(value) ^ (UINTPTR)&(value)) == (UINTPTR)(-1)) + +UINT8 *m_aucSysMem0 = NULL; +UINT8 *m_aucSysMem1 = NULL; + +__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end; +__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0; +#ifdef LOSCFG_BASE_MEM_NODE_SIZE_CHECK +STATIC UINT8 g_memCheckLevel = LOS_MEM_CHECK_LEVEL_DEFAULT; +#endif + +#ifdef LOSCFG_MEM_MUL_MODULE +UINT32 g_moduleMemUsedSize[MEM_MODULE_MAX + 1] = { 0 }; #endif -LITE_OS_SEC_DATA_INIT MALLOC_HOOK g_MALLOC_HOOK = (MALLOC_HOOK)NULL; /*lint !e611*/ +MALLOC_HOOK g_MALLOC_HOOK = NULL; -VOID *osMemFindNodeCtrl(VOID *pPtr); -#ifdef OS_MEM_CHECK_DEBUG -LITE_OS_SEC_DATA static UINT8 ucCheckMemLevel = (UINT8)LOS_MEM_CHECK_LEVEL_DEFAULT; +VOID OsMemInfoPrint(VOID *pool); +#ifdef LOSCFG_BASE_MEM_NODE_SIZE_CHECK +const VOID *OsMemFindNodeCtrl(const VOID *pool, const VOID *ptr); #endif +#ifdef LOSCFG_MEM_HEAD_BACKUP +#define CHECKSUM_MAGICNUM 0xDEADBEEF +#define OS_MEM_NODE_CHECKSUN_CALCULATE(ctlNode) \ + (((UINTPTR)(ctlNode)->freeNodeInfo.pstPrev) ^ \ + ((UINTPTR)(ctlNode)->freeNodeInfo.pstNext) ^ \ + ((UINTPTR)(ctlNode)->preNode) ^ \ + (ctlNode)->gapSize ^ \ + (ctlNode)->sizeAndFlag ^ \ + CHECKSUM_MAGICNUM) + +STATIC INLINE VOID OsMemDispCtlNode(const LosMemCtlNode *ctlNode) +{ + UINTPTR checksum; + + checksum = OS_MEM_NODE_CHECKSUN_CALCULATE(ctlNode); + + PRINTK("node:%p checksum=%p[%p] freeNodeInfo.pstPrev=%p " + "freeNodeInfo.pstNext=%p preNode=%p gapSize=0x%x sizeAndFlag=0x%x\n", + ctlNode, + ctlNode->checksum, + checksum, + ctlNode->freeNodeInfo.pstPrev, + ctlNode->freeNodeInfo.pstNext, + ctlNode->preNode, + ctlNode->gapSize, + ctlNode->sizeAndFlag); +} -LITE_OS_SEC_TEXT_MINOR VOID LOS_MemFreeNodeCheck(VOID *pPool, LOS_MEM_DYN_NODE *pstNode) +STATIC INLINE VOID OsMemDispMoreDetails(const LosMemDynNode *node) { - LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; - LOS_MULTIPLE_DLNK_HEAD *pstHeadAddr = (LOS_MULTIPLE_DLNK_HEAD *)((UINT32)pPool + sizeof(LOS_MEM_POOL_INFO)); - UINT32 uwSized = pstNode->uwSizeAndFlag & 0x3fffffff; - UINT32 uwIdx = (UINT32)(31 - __builtin_clz(uwSized) - OS_MIN_MULTI_DLNK_LOG2); - LOS_TASK_CB *pstTaskCB; - UINT32 uwTaskID; - UINT32 uwflag = 0; + UINT32 taskID; + LosTaskCB *taskCB = NULL; - if (OS_MEM_NODE_GET_USED_FLAG(pstNode->uwSizeAndFlag)) + PRINT_ERR("************************************************\n"); + OsMemDispCtlNode(&node->selfNode); + PRINT_ERR("the address of node :%p\n", node); + + if (!OS_MEM_NODE_GET_USED_FLAG(node->selfNode.sizeAndFlag)) { + PRINT_ERR("this is a FREE node\n"); + PRINT_ERR("************************************************\n\n"); return; - pstListHead = pstHeadAddr->stListHead[uwIdx].pstNext; - if (pstListHead == pstNode->stFreeNodeInfo.pstPrev) - uwflag = 1; - while (pstListHead != &(pstHeadAddr->stListHead[uwIdx]) && (uwflag == 0)) - { - pstListHead = pstListHead->pstNext; - if (pstListHead == pstNode->stFreeNodeInfo.pstPrev) - { - uwflag = 1; - } } - if (uwflag == 0) - { - uwTaskID = (UINT32)(pstNode->pstPreNode->stFreeNodeInfo.pstNext); - if (uwTaskID >= g_uwTskMaxNum) - { - LOS_Panic("///////[LOS_MemFreeNodeCheck] Task ID %d in pre node is invalid!////////\n", uwTaskID); - } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - - if ((pstTaskCB->usTaskStatus & OS_TASK_STATUS_UNUSED) || - (pstTaskCB->pfnTaskEntry == NULL) || - (pstTaskCB->pcTaskName == NULL)) - { - LOS_Panic("\r\n[LOS_MemFreeNodeCheck] Task ID %d in pre node is not created!\n", uwTaskID); - } - LOS_Panic("[LOS_MemFreeNodeCheck] cur node: 0x%x\n" - "pre node: 0x%x\n" - "pre node was allocated by task:%s\n", - pstNode, pstNode->pstPreNode, pstTaskCB->pcTaskName);/*lint !e515 !e516*/ - } -} - -/***************************************************************************** - Function : osMemFindSuitableFreeBlock - Description : find suitable free block use "best fit" algorithm - Input : pPool --- Pointer to memory pool - uwAllocSize --- Size of memory in bytes which note need allocate - Output : None - Return :NULL--no suitable block found - pstTem--pointer a suitable free block -*****************************************************************************/ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE LOS_MEM_DYN_NODE *osMemFindSuitableFreeBlock(VOID *pPool, UINT32 uwAllocSize) -{ - LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; - - for (pstListHead = OS_MEM_HEAD(pPool, uwAllocSize); pstListHead != NULL; pstListHead = LOS_DLnkNextMultiHead(OS_MEM_HEAD_ADDR(pPool), pstListHead)) - { - LOS_MEM_DYN_NODE *pstTmp = (LOS_MEM_DYN_NODE *)NULL; - LOS_DL_LIST_FOR_EACH_ENTRY(pstTmp, pstListHead, LOS_MEM_DYN_NODE, stFreeNodeInfo) /*lint !e413*/ - { - if (pstTmp->uwSizeAndFlag >= uwAllocSize) - { - return pstTmp; - } + taskID = OS_MEM_TASKID_GET(node); + if (taskID >= g_taskMaxNum) { + PRINT_ERR("The task [ID: 0x%x] is ILLEGAL\n", taskID); + if (taskID == g_taskMaxNum) { + PRINT_ERR("PROBABLY alloc by SYSTEM INIT, NOT IN ANY TASK\n"); } + PRINT_ERR("************************************************\n\n"); + return; } - return (LOS_MEM_DYN_NODE *)NULL; -} - -/***************************************************************************** - Function : osMemClearNode - Description : clear a mem Node , set every member to NULL - Input : pstNode --- Pointer to the mem node which will be cleared up - Output : None - Return : None -*****************************************************************************/ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID osMemClearNode(LOS_MEM_DYN_NODE *pstNode) -{ - pstNode->stFreeNodeInfo.pstPrev = (LOS_DL_LIST *)NULL; - pstNode->stFreeNodeInfo.pstNext = (LOS_DL_LIST *)NULL; - pstNode->pstPreNode = (LOS_MEM_DYN_NODE *)NULL; -} - -/***************************************************************************** - Function : osMemMergeNode - Description : merge this node and pre node ,then clear this node info - Input : pstNode --- Pointer to node which will be merged - Output : None - Return : None -*****************************************************************************/ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID osMemMergeNode(LOS_MEM_DYN_NODE *pstNode) -{ - LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL; - - pstNode->pstPreNode->uwSizeAndFlag += pstNode->uwSizeAndFlag; - pstNextNode = (LOS_MEM_DYN_NODE *)((UINT32)pstNode + pstNode->uwSizeAndFlag); - pstNextNode->pstPreNode = pstNode->pstPreNode; - osMemClearNode(pstNode); -} - -/***************************************************************************** - Function : osMemSpitNode - Description : spit new node from pstAllocNode, and merge remainder mem if necessary - Input : pPool --Pointer to memory pool - pstAllocNode --the source node which new node be spit from to. - After pick up it's node info, change to point the new node - uwAllocSize -- the size of new node - Output : pstAllocNode -- save new node addr - Return : None -*****************************************************************************/ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID osMemSpitNode(VOID *pPool, - LOS_MEM_DYN_NODE *pstAllocNode, UINT32 uwAllocSize) -{ - LOS_MEM_DYN_NODE *pstNewFreeNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; - - pstNewFreeNode = (LOS_MEM_DYN_NODE *)((UINT8 *)pstAllocNode + uwAllocSize); - pstNewFreeNode->pstPreNode = pstAllocNode; - pstNewFreeNode->uwSizeAndFlag = pstAllocNode->uwSizeAndFlag - uwAllocSize; - pstAllocNode->uwSizeAndFlag = uwAllocSize; - pstNextNode = OS_MEM_NEXT_NODE(pstNewFreeNode); - pstNextNode->pstPreNode = pstNewFreeNode; - if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) - { - LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); - osMemMergeNode(pstNextNode); - } - - pstListHead = OS_MEM_HEAD(pPool, pstNewFreeNode->uwSizeAndFlag); - if (NULL == pstListHead) - { - PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); + taskCB = OS_TCB_FROM_TID(taskID); + if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) || + (taskCB->taskEntry == NULL) || + (taskCB->taskName == NULL)) { + PRINT_ERR("The task [ID: 0x%x] is NOT CREATED(ILLEGAL)\n", taskID); + PRINT_ERR("************************************************\n\n"); return; } - LOS_ListAdd(pstListHead,&(pstNewFreeNode->stFreeNodeInfo)); -} - -/***************************************************************************** - Function : osMemFreeNode - Description : free the node from memory & if there are free node beside, merger them. - at last update "pstListHead' which saved all free node control head - Input : pstNode -- the node which need be freed - pPool --Pointer to memory pool - Output : None - Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT STATIC_INLINE VOID osMemFreeNode(LOS_MEM_DYN_NODE *pstNode, VOID *pPool) -{ - LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; - -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_REDUCE_USED(OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag)); -#endif - pstNode->uwSizeAndFlag = OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag); - if ((pstNode->pstPreNode != NULL) && - (!OS_MEM_NODE_GET_USED_FLAG(pstNode->pstPreNode->uwSizeAndFlag))) - { - LOS_MEM_DYN_NODE *pstPreNode = pstNode->pstPreNode; - osMemMergeNode(pstNode); - pstNextNode = OS_MEM_NEXT_NODE(pstPreNode); - if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) - { -#ifdef OS_MEM_ENABLE_ALLOC_CHECK - LOS_MemFreeNodeCheck(pPool, pstNextNode);//fjg -#endif - LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); - osMemMergeNode(pstNextNode); - } - - LOS_ListDelete(&(pstPreNode->stFreeNodeInfo)); - pstListHead = OS_MEM_HEAD(pPool, pstPreNode->uwSizeAndFlag); - if (NULL == pstListHead) - { - PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); - return; - } - - LOS_ListAdd(pstListHead,&(pstPreNode->stFreeNodeInfo)); - } - else - { - pstNextNode = OS_MEM_NEXT_NODE(pstNode); - if (!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) - { -#ifdef OS_MEM_ENABLE_ALLOC_CHECK - LOS_MemFreeNodeCheck(pPool, pstNextNode);//fjg + PRINT_ERR("allocated by task: %s [ID = 0x%x]\n", taskCB->taskName, taskID); +#ifdef LOSCFG_MEM_MUL_MODULE + PRINT_ERR("allocated by moduleID: %lu\n", OS_MEM_MODID_GET(node)); #endif - LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); - osMemMergeNode(pstNextNode); - } - - pstListHead = OS_MEM_HEAD(pPool, pstNode->uwSizeAndFlag); - if (NULL == pstListHead) - { - PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); - return; - } - LOS_ListAdd(pstListHead,&(pstNode->stFreeNodeInfo)); - } + PRINT_ERR("************************************************\n\n"); } -/***************************************************************************** - Function : osMemCheckUsedNode - Description : check the result if pointer memory node belongs to pointer memory pool - Input : pPool --Pointer to memory pool - pstNode -- the node which need be checked - Output : None - Return : LOS_OK or LOS_NOK -*****************************************************************************/ -#ifdef LOS_DLNK_SAFE_CHECK -LITE_OS_SEC_TEXT_MINOR STATIC_INLINE UINT32 osMemCheckUsedNode(VOID *pPool, LOS_MEM_DYN_NODE *pstNode) +STATIC INLINE VOID OsMemDispWildPointerMsg(const LosMemDynNode *node, const VOID *ptr) { - LOS_MEM_DYN_NODE *pstTmp = NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - LOS_MEM_DYN_NODE *pstEnd = OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - - for (pstTmp = OS_MEM_FIRST_NODE(pPool); pstTmp < pstEnd; pstTmp = OS_MEM_NEXT_NODE(pstTmp )) - { - if ((pstTmp == pstNode) && - OS_MEM_NODE_GET_USED_FLAG(pstTmp->uwSizeAndFlag)) - { - return LOS_OK; - } - else if (pstTmp > pstNode) - { - return LOS_NOK; - } - } - - return LOS_NOK; + PRINT_ERR("*****************************************************\n"); + PRINT_ERR("find an control block at: %p, gap size: 0x%x, sizeof(LosMemDynNode): 0x%x\n", node, + node->selfNode.gapSize, sizeof(LosMemDynNode)); + PRINT_ERR("the pointer should be: %p\n", + ((UINTPTR)node + node->selfNode.gapSize + sizeof(LosMemDynNode))); + PRINT_ERR("the pointer given is: %p\n", ptr); + PRINT_ERR("PROBABLY A WILD POINTER\n"); + OsBackTrace(); + PRINT_ERR("*****************************************************\n\n"); } -#elif defined(LOS_DLNK_SIMPLE_CHECK) -LITE_OS_SEC_TEXT_MINOR STATIC_INLINE UINT32 osMemCheckUsedNode(VOID *pPool, LOS_MEM_DYN_NODE *pstNode) +STATIC INLINE VOID OsMemChecksumSet(LosMemCtlNode *ctlNode) { - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - LOS_MEM_DYN_NODE *pstStartNode = OS_MEM_FIRST_NODE(pPool); - LOS_MEM_DYN_NODE *pstEndNode = OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pstStartNode, pstNode, pstEndNode)) - { - return LOS_NOK; - } - - if (!OS_MEM_NODE_GET_USED_FLAG(pstNode->uwSizeAndFlag)) - { - return LOS_NOK; - } - - if ((!OS_MEM_MAGIC_VALID(pstNode->stFreeNodeInfo.pstPrev)) - //|| (!OS_MEM_MAGIC_VALID(pstNode->stFreeNodeInfo.pstNext)) - ) - { - return LOS_NOK; - } + ctlNode->checksum = OS_MEM_NODE_CHECKSUN_CALCULATE(ctlNode); +} - return LOS_OK; +STATIC INLINE BOOL OsMemChecksumVerify(const LosMemCtlNode *ctlNode) +{ + return ctlNode->checksum == OS_MEM_NODE_CHECKSUN_CALCULATE(ctlNode); } -#else -LITE_OS_SEC_ALW_INLINE STATIC_INLINE BOOL osMemIsNodeValid(const LOS_MEM_DYN_NODE *pstNode, const LOS_MEM_DYN_NODE *pstStartNode, const LOS_MEM_DYN_NODE *pstEndNode, - const UINT8 *pucStartPool, const UINT8 *pucEndPool) +STATIC INLINE VOID OsMemBackupSetup(const LosMemDynNode *node) { - if (!OS_MEM_MIDDLE_ADDR(pstStartNode, pstNode, pstEndNode)) - { - return FALSE; + LosMemDynNode *nodePre = node->selfNode.preNode; + if (nodePre != NULL) { + nodePre->backupNode.freeNodeInfo.pstNext = node->selfNode.freeNodeInfo.pstNext; + nodePre->backupNode.freeNodeInfo.pstPrev = node->selfNode.freeNodeInfo.pstPrev; + nodePre->backupNode.preNode = node->selfNode.preNode; + nodePre->backupNode.checksum = node->selfNode.checksum; + nodePre->backupNode.gapSize = node->selfNode.gapSize; +#ifdef LOSCFG_MEM_RECORDINFO + nodePre->backupNode.originSize = node->selfNode.originSize; +#endif + nodePre->backupNode.sizeAndFlag = node->selfNode.sizeAndFlag; } +} - if (OS_MEM_NODE_GET_USED_FLAG(pstNode->uwSizeAndFlag)) - { - if ((!OS_MEM_MAGIC_VALID(pstNode->stFreeNodeInfo.pstPrev)) - // || (!OS_MEM_MAGIC_VALID(pstNode->stFreeNodeInfo.pstNext)) - ) - { - return FALSE; - } - return TRUE; - } +LosMemDynNode *OsMemNodeNextGet(const VOID *pool, const LosMemDynNode *node) +{ + const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; - if ((!OS_MEM_MIDDLE_ADDR_OPEN_END(pucStartPool, pstNode->stFreeNodeInfo.pstPrev, pucEndPool)) - // || (!OS_MEM_MIDDLE_ADDR_OPEN_END(pucStartPool, pstNode->stFreeNodeInfo.pstNext, pucEndPool)) - ) - { - return FALSE; + if (node == OS_MEM_END_NODE(pool, poolInfo->poolSize)) { + return OS_MEM_FIRST_NODE(pool); + } else { + return OS_MEM_NEXT_NODE(node); } - - return TRUE; } -LITE_OS_SEC_TEXT_MINOR STATIC_INLINE UINT32 osMemCheckUsedNode(VOID *pPool, LOS_MEM_DYN_NODE *pstNode) +STATIC INLINE UINT32 OsMemBackupSetup4Next(const VOID *pool, LosMemDynNode *node) { - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - LOS_MEM_DYN_NODE *pstStartNode = OS_MEM_FIRST_NODE(pPool); - LOS_MEM_DYN_NODE *pstEndNode = OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - UINT8 *pucEndPool = (UINT8 *)pPool + pstPoolInfo->uwPoolSize; - const LOS_MEM_DYN_NODE *pstNextNode = (const LOS_MEM_DYN_NODE *)NULL; - if (!osMemIsNodeValid(pstNode, pstStartNode, pstEndNode, (UINT8 *)pPool, pucEndPool)) - { - return LOS_NOK; - } - - if (!OS_MEM_NODE_GET_USED_FLAG(pstNode->uwSizeAndFlag)) - - { - return LOS_NOK; - } + LosMemDynNode *nodeNext = OsMemNodeNextGet(pool, node); - pstNextNode = OS_MEM_NEXT_NODE(pstNode); - if (!osMemIsNodeValid(pstNextNode, pstStartNode, pstEndNode, (UINT8 *)pPool, pucEndPool)) - { - return LOS_NOK; - } + if (!OsMemChecksumVerify(&nodeNext->selfNode)) { + PRINT_ERR("[%s]the next node is broken!!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodeNext->selfNode)); + PRINT_ERR("Current node details:\n"); + OsMemDispMoreDetails(node); - if (pstNextNode->pstPreNode != pstNode) - { return LOS_NOK; } - if (pstNode != pstStartNode) - { - if (!osMemIsNodeValid(pstNode->pstPreNode, pstStartNode, pstEndNode, (UINT8 *)pPool, pucEndPool)) - { - return LOS_NOK; - } - - if (OS_MEM_NEXT_NODE(pstNode->pstPreNode) != pstNode) - { - return LOS_NOK; - } + if (!OsMemChecksumVerify(&node->backupNode)) { + node->backupNode.freeNodeInfo.pstNext = nodeNext->selfNode.freeNodeInfo.pstNext; + node->backupNode.freeNodeInfo.pstPrev = nodeNext->selfNode.freeNodeInfo.pstPrev; + node->backupNode.preNode = nodeNext->selfNode.preNode; + node->backupNode.checksum = nodeNext->selfNode.checksum; + node->backupNode.gapSize = nodeNext->selfNode.gapSize; +#ifdef LOSCFG_MEM_RECORDINFO + node->backupNode.originSize = nodeNext->selfNode.originSize; +#endif + node->backupNode.sizeAndFlag = nodeNext->selfNode.sizeAndFlag; } - return LOS_OK; } -#endif - -/***************************************************************************** - Function : osMemSetMagicNumAndTaskid - Description : set magic & taskid - Input : pstNode -- the node which will be set magic & taskid - Output : None - Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR STATIC_INLINE VOID osMemSetMagicNumAndTaskid(LOS_MEM_DYN_NODE *pstNode) +UINT32 OsMemBackupDoRestore(VOID *pool, const LosMemDynNode *nodePre, LosMemDynNode *node) { - OS_MEM_SET_MAGIC(pstNode->stFreeNodeInfo.pstPrev); - - /* In the process of dynamic memory initialization,direct use of uninitialized global variablewhich initialized in task initialization. - Need to exclude this scene, make the value of pstNode->stFreeNodeInfo.pstNext to 0xffffffff */ - if (g_stLosTask.pstRunTask != NULL) - { - pstNode->stFreeNodeInfo.pstNext = (LOS_DL_LIST *)(g_stLosTask.pstRunTask->uwTaskID); - } - else - { - /* If the task mode does not initialize, the field is the 0xffffffff */ - pstNode->stFreeNodeInfo.pstNext = (LOS_DL_LIST *)0xffffffff; - /* TODO: the commend task-MEMUSE is not include system initialization malloc */ - } -} - -/***************************************************************************** - Function : LOS_MemIntegrityCheck - Description : memory pool integrity checking - Input : pPool --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 *pPool) -{ - LOS_MEM_DYN_NODE *pstTmpNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_DYN_NODE *pstPreNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - UINT8 *pucEndPool; - LOS_TASK_CB *pstTaskCB; - UINT32 uwTaskID; - UINTPTR uvIntSave; - - if (pPool == NULL) - { + if (node == NULL) { + PRINT_ERR("the node is NULL.\n"); return LOS_NOK; } + PRINT_ERR("the backup node information of current node in previous node:\n"); + OsMemDispCtlNode(&nodePre->backupNode); + PRINT_ERR("the detailed information of previous node:\n"); + OsMemDispMoreDetails(nodePre); + + node->selfNode.freeNodeInfo.pstNext = nodePre->backupNode.freeNodeInfo.pstNext; + node->selfNode.freeNodeInfo.pstPrev = nodePre->backupNode.freeNodeInfo.pstPrev; + node->selfNode.preNode = nodePre->backupNode.preNode; + node->selfNode.checksum = nodePre->backupNode.checksum; + node->selfNode.gapSize = nodePre->backupNode.gapSize; +#ifdef LOSCFG_MEM_RECORDINFO + node->selfNode.originSize = nodePre->backupNode.originSize; +#endif + node->selfNode.sizeAndFlag = nodePre->backupNode.sizeAndFlag; - pucEndPool = (UINT8 *)pPool + pstPoolInfo->uwPoolSize; - - uvIntSave = LOS_IntLock(); - pstPreNode = OS_MEM_FIRST_NODE(pPool); - for (pstTmpNode = OS_MEM_FIRST_NODE(pPool); pstTmpNode < OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - pstTmpNode = OS_MEM_NEXT_NODE(pstTmpNode)) - { - - if (OS_MEM_NODE_GET_USED_FLAG(pstTmpNode->uwSizeAndFlag)) - { - if (!OS_MEM_MAGIC_VALID(pstTmpNode->stFreeNodeInfo.pstPrev)) - { - PRINT_ERR("[%s], %d, memory check error!\n" - "memory used but magic num wrong, stFreeNodeInfo.pstPrev(magic num):0x%x \n", - __FUNCTION__, __LINE__, pstTmpNode->stFreeNodeInfo.pstPrev); /*lint !e626 !e515*/ - goto errout; - } - } - else //is free node, check free node range - { - if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pPool, pstTmpNode->stFreeNodeInfo.pstPrev, pucEndPool)) - { - PRINT_ERR("[%s], %d, memory check error!\n" - "stFreeNodeInfo.pstPrev:0x%x is out of legal mem range[0x%x, 0x%x]\n", - __FUNCTION__, __LINE__, pstTmpNode->stFreeNodeInfo.pstPrev, pPool, pucEndPool); /*lint !e626 !e515*/ - goto errout; - } - if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pPool, pstTmpNode->stFreeNodeInfo.pstNext, pucEndPool)) - { - PRINT_ERR("[%s], %d, memory check error!\n" - "stFreeNodeInfo.pstNext:0x%x is out of legal mem range[0x%x, 0x%x]\n", - __FUNCTION__, __LINE__, pstTmpNode->stFreeNodeInfo.pstNext, pPool, pucEndPool); /*lint !e626 !e515*/ - goto errout; - } - - LOS_MemFreeNodeCheck(pPool, pstTmpNode);//fjg - } - - pstPreNode = pstTmpNode; - } - LOS_IntRestore(uvIntSave); - return LOS_OK; - -errout: - LOS_IntRestore(uvIntSave); - PRINT_ERR("<------- ERR Node Pre 0x%x byte\n", OS_EXC_ERR_NODE_RANGE);/*lint !e515 !e516*/ - print_hex((unsigned int *)(pstTmpNode - OS_EXC_ERR_NODE_RANGE), OS_EXC_ERR_NODE_RANGE / 4); - PRINT_ERR("ERR Node Next 0x%x byte ------->\n", OS_EXC_ERR_NODE_RANGE);/*lint !e515 !e516*/ - print_hex((unsigned int *)pstTmpNode, OS_EXC_ERR_NODE_RANGE / 4); - uwTaskID = (UINT32)(pstPreNode->stFreeNodeInfo.pstNext); - if (uwTaskID >= g_uwTskMaxNum) - { - LOS_Panic("Task ID %d in pre node is invalid!\n", uwTaskID); - } - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - - if ((pstTaskCB->usTaskStatus & OS_TASK_STATUS_UNUSED) || - (pstTaskCB->pfnTaskEntry == NULL) || - (pstTaskCB->pcTaskName == NULL)) - { - LOS_Panic("\r\nTask ID %d in pre node is not created!\n", uwTaskID); - } - LOS_Panic("cur node: 0x%x\n" - "pre node: 0x%x\n" - "pre node was allocated by task:%s\n", - pstTmpNode, pstPreNode, pstTaskCB->pcTaskName);/*lint !e515 !e516*/ - return LOS_NOK; + /* we should re-setup next node's backup on current node */ + return OsMemBackupSetup4Next(pool, node); } -/***************************************************************************** - Function : osMemAllocWithCheck - Description : Allocate node from Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - Output : None - Return : Pointer to allocated memory -*****************************************************************************/ -LITE_OS_SEC_TEXT STATIC_INLINE VOID *osMemAllocWithCheck(VOID *pPool, UINT32 uwSize) +STATIC LosMemDynNode *OsMemFirstNodePrevGet(const LosMemPoolInfo *poolInfo) { - LOS_MEM_DYN_NODE *pstAllocNode = (LOS_MEM_DYN_NODE *)NULL; - UINT32 uwAllocSize; - - if (g_MALLOC_HOOK != NULL) - g_MALLOC_HOOK(); - -#ifdef OS_MEM_ENABLE_ALLOC_CHECK - (VOID)LOS_MemIntegrityCheck(pPool); -#endif - - uwAllocSize = OS_MEM_ALIGN(uwSize + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); - pstAllocNode = osMemFindSuitableFreeBlock(pPool, uwAllocSize); - if (pstAllocNode == NULL) - { - PRINT_ERR("[%s] No suitable free block\n", __FUNCTION__);/*lint !e515*/ - return NULL; - } - if ((uwAllocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= pstAllocNode->uwSizeAndFlag) - { - osMemSpitNode(pPool, pstAllocNode, uwAllocSize); - } - LOS_ListDelete(&(pstAllocNode->stFreeNodeInfo)); - osMemSetMagicNumAndTaskid(pstAllocNode); - OS_MEM_NODE_SET_USED_FLAG(pstAllocNode->uwSizeAndFlag); -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_ADD_USED(OS_MEM_NODE_GET_SIZE(pstAllocNode->uwSizeAndFlag)); -#endif - return (pstAllocNode + 1); - -} - -/***************************************************************************** - Function : osMemReAllocSmaller - Description : reAlloc a smaller memory node - Input : pPool --- Pointer to memory pool - uwAllocSize --- the size of new node which will be alloced - pstNode --the node which wille be realloced - uwNodeSize -- the size of old node - Output : pstNode -- pointer to the new node after realloc - Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR STATIC_INLINE VOID osMemReAllocSmaller(VOID *pPool, UINT32 uwAllocSize, LOS_MEM_DYN_NODE *pstNode, UINT32 uwNodeSize) -{ - if ((uwAllocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= uwNodeSize) - { - pstNode->uwSizeAndFlag = uwNodeSize; - osMemSpitNode(pPool, pstNode, uwAllocSize); - OS_MEM_NODE_SET_USED_FLAG(pstNode->uwSizeAndFlag); -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_REDUCE_USED(uwNodeSize - uwAllocSize); -#endif - } -} - -/***************************************************************************** - Function : osMemMergeNodeForReAllocBigger - Description : reAlloc a Bigger memory node after merge pstNode and nextNode - Input : pPool --- Pointer to memory pool - uwAllocSize --- the size of new node which will be alloced - pstNode --the node which wille be realloced - uwNodeSize -- the size of old node - pstNextNode -- pointer next node which will be merged - Output : pstNode -- pointer to the new node after realloc - Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR STATIC_INLINE VOID osMemMergeNodeForReAllocBigger(VOID *pPool, UINT32 uwAllocSize, LOS_MEM_DYN_NODE *pstNode, UINT32 uwNodeSize, LOS_MEM_DYN_NODE *pstNextNode) -{ - pstNode->uwSizeAndFlag = uwNodeSize; - LOS_ListDelete(&(pstNextNode->stFreeNodeInfo)); - osMemMergeNode(pstNextNode); -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_ADD_USED(pstNode->uwSizeAndFlag - uwNodeSize); -#endif - if ((uwAllocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= pstNode->uwSizeAndFlag) - { -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_REDUCE_USED(pstNode->uwSizeAndFlag - uwAllocSize); -#endif - osMemSpitNode(pPool, pstNode, uwAllocSize); - } - OS_MEM_NODE_SET_USED_FLAG(pstNode->uwSizeAndFlag); -} - -/***************************************************************************** - Function : LOS_MemInit - Description : Initialize Dynamic Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - Output : None - Return : LOS_OK - Ok, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pPool, UINT32 uwSize) -{ - LOS_MEM_DYN_NODE *pstNewNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_DYN_NODE *pstEndNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)NULL; - UINTPTR uvIntSave; - LOS_DL_LIST *pstListHead = (LOS_DL_LIST *)NULL; - - if ((pPool == NULL) || (uwSize < (OS_MEM_MIN_POOL_SIZE))) - { - return LOS_NOK; + LosMemDynNode *nodePre = NULL; + + nodePre = OS_MEM_END_NODE(poolInfo, poolInfo->poolSize); + if (!OsMemChecksumVerify(&(nodePre->selfNode))) { + PRINT_ERR("the current node is THE FIRST NODE !\n"); + PRINT_ERR("[%s]: the node information of previous node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodePre->selfNode)); + return nodePre; } - - uvIntSave = LOS_IntLock(); - - pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - pstPoolInfo->pPoolAddr = pPool; - pstPoolInfo->uwPoolSize = uwSize; - LOS_DLnkInitMultiHead(OS_MEM_HEAD_ADDR(pPool)); - pstNewNode = OS_MEM_FIRST_NODE(pPool); - pstNewNode->uwSizeAndFlag = ((uwSize - ((UINT32)pstNewNode - (UINT32)pPool)) - OS_MEM_NODE_HEAD_SIZE); - pstNewNode->pstPreNode = (LOS_MEM_DYN_NODE *)NULL; - pstListHead = OS_MEM_HEAD(pPool, pstNewNode->uwSizeAndFlag); - if (NULL == pstListHead) - { - PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); - LOS_IntRestore(uvIntSave); - return LOS_NOK; + if (!OsMemChecksumVerify(&(nodePre->backupNode))) { + PRINT_ERR("the current node is THE FIRST NODE !\n"); + PRINT_ERR("[%s]: the backup node information of current node in previous Node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodePre->backupNode)); + return nodePre; } - LOS_ListTailInsert(pstListHead,&(pstNewNode->stFreeNodeInfo)); - pstEndNode = (LOS_MEM_DYN_NODE *)OS_MEM_END_NODE(pPool, uwSize); - memset(pstEndNode, 0 ,sizeof(*pstEndNode)); - pstEndNode->pstPreNode = pstNewNode; - pstEndNode->uwSizeAndFlag = OS_MEM_NODE_HEAD_SIZE; - OS_MEM_NODE_SET_USED_FLAG(pstEndNode->uwSizeAndFlag); - osMemSetMagicNumAndTaskid(pstEndNode); - LOS_IntRestore(uvIntSave); - - return LOS_OK; + return NULL; } -/***************************************************************************** - Function : LOS_MemAlloc - Description : Allocate Memory from Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - Output : None - Return : Pointer to allocated memory -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemAlloc (VOID *pPool, UINT32 uwSize) +LosMemDynNode *OsMemNodePrevGet(VOID *pool, const LosMemDynNode *node) { - VOID *pPtr = NULL; - UINTPTR uvIntSave = LOS_IntLock(); - - do - { - if ((pPool == NULL) || (uwSize == 0)) - { - break; - } - - if (OS_MEM_NODE_GET_USED_FLAG(uwSize)) - { - break; - } - - pPtr = osMemAllocWithCheck(pPool, uwSize); - } while (0); + LosMemDynNode *nodeCur = NULL; + LosMemDynNode *nodePre = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; - LOS_IntRestore(uvIntSave); - return pPtr; -} - -/***************************************************************************** - Function : LOS_MemAllocAlign - Description : align size then allocate node from Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - uwBoundary --- align form - Output : None - Return : Pointer to allocated memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pPool, UINT32 uwSize, UINT32 uwBoundary) -{ - UINT32 uwUseSize = 0; - UINT32 uwGapSize = 0; - VOID *pPtr = NULL; - VOID *pAlignedPtr = NULL; - UINTPTR uvIntSave = LOS_IntLock(); - - do - { - if ((pPool == NULL) || (uwSize == 0)) - { - break; - } - - uwUseSize = uwSize + uwBoundary + 4; /* 4bytes stores offset between alignedPtr and ptr */ + if (node == OS_MEM_FIRST_NODE(pool)) { + return OsMemFirstNodePrevGet(poolInfo); + } - if (OS_MEM_NODE_GET_USED_FLAG(uwUseSize)) - { - break; - } + for (nodeCur = OS_MEM_FIRST_NODE(pool); + nodeCur < OS_MEM_END_NODE(pool, poolInfo->poolSize); + nodeCur = OS_MEM_NEXT_NODE(nodeCur)) { + if (!OsMemChecksumVerify(&(nodeCur->selfNode))) { + PRINT_ERR("[%s]: the node information of current node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodeCur->selfNode)); - pPtr = osMemAllocWithCheck(pPool, uwUseSize); + if (nodePre == NULL) { + return NULL; + } - pAlignedPtr = (VOID *)OS_MEM_ALIGN(pPtr, uwBoundary); + PRINT_ERR("the detailed information of previous node:\n"); + OsMemDispMoreDetails(nodePre); - if (pPtr == pAlignedPtr) - { - break; + /* due to the every step's checksum verify, nodePre is trustful */ + if (OsMemBackupDoRestore(pool, nodePre, nodeCur) != LOS_OK) { + return NULL; + } } - /* store gapSize in address (ptr -4), it will be checked while free */ - uwGapSize = (UINT32)pAlignedPtr - (UINT32)pPtr; - OS_MEM_NODE_SET_ALIGNED_FLAG(uwGapSize); - *((UINT32 *)((UINT32)pAlignedPtr - 4)) = uwGapSize; - - pPtr = pAlignedPtr; - - } while (0); - - LOS_IntRestore(uvIntSave); - - return pPtr; -} + if (!OsMemChecksumVerify(&(nodeCur->backupNode))) { + PRINT_ERR("[%s]: the backup node information in current node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodeCur->backupNode)); -/***************************************************************************** - Function : LOS_MemFree - Description : Free Memory and return it to Memory pool - Input : pPool --- Pointer to memory pool - pMem --- Pointer to memory to free - Output : None - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pPool, VOID *pMem) -{ - UINT32 uwRet = LOS_NOK; - UINT32 uwGapSize = 0; - UINTPTR uvIntSave = LOS_IntLock(); - - do - { - LOS_MEM_DYN_NODE *pstNode = (LOS_MEM_DYN_NODE *)NULL; + if (nodePre != NULL) { + PRINT_ERR("the detailed information of previous node:\n"); + OsMemDispMoreDetails(nodePre); + } - if ((pPool == NULL) || (pMem == NULL)) - { - break; + if (OsMemBackupSetup4Next(pool, nodeCur) != LOS_OK) { + return NULL; + } } - uwGapSize = *((UINT32 *)((UINT32)pMem - 4)); - if (OS_MEM_NODE_GET_ALIGNED_FLAG(uwGapSize)) - { - uwGapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(uwGapSize); - pMem = (VOID *)((UINT32)pMem - uwGapSize); + if (OS_MEM_NEXT_NODE(nodeCur) == node) { + return nodeCur; } - pstNode = (LOS_MEM_DYN_NODE *)((UINT32)pMem - OS_MEM_NODE_HEAD_SIZE); - uwRet = osMemCheckUsedNode(pPool, pstNode); - if (uwRet == LOS_OK) - { - osMemFreeNode(pstNode, pPool); + if (OS_MEM_NEXT_NODE(nodeCur) > node) { + break; } - } while(0); + nodePre = nodeCur; + } - LOS_IntRestore(uvIntSave); - return uwRet; + return NULL; } -/***************************************************************************** - Function : LOS_MemRealloc - Description : realloc memory from Memory pool - Input : pPool --- Pointer to memory pool - pPtr --- Pointer to memory - uwSize --- new size - Output : None - Return : Pointer to allocated memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID *LOS_MemRealloc (VOID *pPool, VOID *pPtr, UINT32 uwSize) +LosMemDynNode *OsMemNodePrevTryGet(VOID *pool, LosMemDynNode **node, const VOID *ptr) { - UINTPTR uvIntSave; - UINT32 uwGapSize = 0; - VOID *pNewPtr = NULL; + UINTPTR nodeShoudBe = 0; + LosMemDynNode *nodeCur = NULL; + LosMemDynNode *nodePre = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; - if((int)uwSize < 0) - return NULL; + if (ptr == OS_MEM_FIRST_NODE(pool)) { + return OsMemFirstNodePrevGet(poolInfo); + } - uvIntSave = LOS_IntLock(); + for (nodeCur = OS_MEM_FIRST_NODE(pool); + nodeCur < OS_MEM_END_NODE(pool, poolInfo->poolSize); + nodeCur = OS_MEM_NEXT_NODE(nodeCur)) { + if (!OsMemChecksumVerify(&(nodeCur->selfNode))) { + PRINT_ERR("[%s]: the node information of current node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodeCur->selfNode)); - do - { - LOS_MEM_DYN_NODE *pstNode = (LOS_MEM_DYN_NODE *)NULL; - UINT32 uwRet; - UINT32 uwAllocSize; - UINT32 uwNodeSize; - LOS_MEM_DYN_NODE *pstNextNode = (LOS_MEM_DYN_NODE *)NULL; + if (nodePre == NULL) { + return NULL; + } - if (pPtr == NULL) - { - pNewPtr = LOS_MemAlloc((VOID *)pPool, (UINT32)uwSize); - break; - } + PRINT_ERR("the detailed information of previous node:\n"); + OsMemDispMoreDetails(nodePre); - if (uwSize == 0) - { - if (LOS_MemFree((VOID *)pPool, (VOID *)pPtr) != LOS_OK) - PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); - break; + /* due to the every step's checksum verify, nodePre is trustful */ + if (OsMemBackupDoRestore(pool, nodePre, nodeCur) != LOS_OK) { + return NULL; + } } - uwGapSize = *((UINT32 *)((UINT32)pPtr - 4)); - if (OS_MEM_NODE_GET_ALIGNED_FLAG(uwGapSize)) - { - uwGapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(uwGapSize); - pPtr = (VOID *)((UINT32)pPtr - uwGapSize); - } - pstNode = (LOS_MEM_DYN_NODE *)((UINT32)pPtr - OS_MEM_NODE_HEAD_SIZE); - uwRet = osMemCheckUsedNode(pPool, pstNode); - if (uwRet != LOS_OK) - { - break; - } + if (!OsMemChecksumVerify(&(nodeCur->backupNode))) { + PRINT_ERR("[%s]: the backup node information in current node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&(nodeCur->backupNode)); - uwAllocSize = OS_MEM_ALIGN(uwSize + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); - uwNodeSize = OS_MEM_NODE_GET_SIZE(pstNode->uwSizeAndFlag); - if (uwNodeSize >= uwAllocSize) - { - osMemReAllocSmaller(pPool, uwAllocSize, pstNode, uwNodeSize); - pNewPtr = pPtr; - break; + if (nodePre != NULL) { + PRINT_ERR("the detailed information of previous node:\n"); + OsMemDispMoreDetails(nodePre); + } + + if (OsMemBackupSetup4Next(pool, nodeCur) != LOS_OK) { + return NULL; + } } - pstNextNode = OS_MEM_NEXT_NODE(pstNode); - if ((!OS_MEM_NODE_GET_USED_FLAG(pstNextNode->uwSizeAndFlag)) && - ((pstNextNode->uwSizeAndFlag + uwNodeSize) >= uwAllocSize)) - { - osMemMergeNodeForReAllocBigger(pPool, uwAllocSize, pstNode, uwNodeSize, pstNextNode); - pNewPtr = pPtr; - break; + nodeShoudBe = (UINTPTR)nodeCur + nodeCur->selfNode.gapSize + sizeof(LosMemDynNode); + if (nodeShoudBe == (UINTPTR)ptr) { + *node = nodeCur; + return nodePre; } - pNewPtr = osMemAllocWithCheck(pPool, uwSize); - if (pNewPtr != NULL) - { - memcpy(pNewPtr, pPtr, uwNodeSize - OS_MEM_NODE_HEAD_SIZE); - osMemFreeNode(pstNode, pPool); + if (OS_MEM_NEXT_NODE(nodeCur) > (LosMemDynNode *)ptr) { + OsMemDispWildPointerMsg(nodeCur, ptr); + break; } - } while (0); + nodePre = nodeCur; + } - LOS_IntRestore(uvIntSave); - return pNewPtr; + return NULL; } -/***************************************************************************** - Function : LOS_MemTotalUsedGet - Description : figure the pointer memory pool for it's total mem used - Input : pPool --- Pointer to memory pool - Output : None - Return : the size of the pool has been used -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pPool) +STATIC INLINE UINT32 OsMemBackupTryRestore(VOID *pool, LosMemDynNode **node, const VOID *ptr) { - LOS_MEM_DYN_NODE *pstTmpNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - UINT32 uwMemUsed = 0; - UINTPTR uvIntSave; - - if (pPool == NULL) - { + LosMemDynNode *nodeHead = NULL; + LosMemDynNode *nodePre = OsMemNodePrevTryGet(pool, &nodeHead, ptr); + if (nodePre == NULL) { return LOS_NOK; } - uvIntSave = LOS_IntLock(); + *node = nodeHead; + return OsMemBackupDoRestore(pool, nodePre, *node); +} - for (pstTmpNode = OS_MEM_FIRST_NODE(pPool); pstTmpNode <= OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - pstTmpNode = OS_MEM_NEXT_NODE(pstTmpNode)) - { - if (OS_MEM_NODE_GET_USED_FLAG(pstTmpNode->uwSizeAndFlag)) - { - uwMemUsed += OS_MEM_NODE_GET_SIZE(pstTmpNode->uwSizeAndFlag); - } +STATIC INLINE UINT32 OsMemBackupRestore(VOID *pool, LosMemDynNode *node) +{ + LosMemDynNode *nodePre = OsMemNodePrevGet(pool, node); + if (nodePre == NULL) { + return LOS_NOK; } - LOS_IntRestore(uvIntSave); - - return uwMemUsed; + return OsMemBackupDoRestore(pool, nodePre, node); } -/***************************************************************************** - Function : LOS_MemLastUsedGet - Description : get the size of last node(except end node which size is zero) - Input : pPool --- Pointer to memory pool - Output : None - Return : the size of the last node -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemLastUsedGet(VOID *pPool) +STATIC INLINE VOID OsMemSetGapSize(LosMemCtlNode *ctlNode, UINT32 gapSize) { - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; + ctlNode->gapSize = gapSize; +} - if (pPool == NULL) - { - return LOS_NOK; - } +STATIC VOID OsMemNodeSave(LosMemDynNode *node) +{ + OsMemSetGapSize(&node->selfNode, 0); + OsMemChecksumSet(&node->selfNode); + OsMemBackupSetup(node); +} - return ((UINT32)(OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize)->pstPreNode) + sizeof(LOS_MEM_DYN_NODE)); +STATIC VOID OsMemNodeSaveWithGapSize(LosMemDynNode *node, UINT32 gapSize) +{ + OsMemSetGapSize(&node->selfNode, gapSize); + OsMemChecksumSet(&node->selfNode); + OsMemBackupSetup(node); } -/***************************************************************************** - Function : LOS_MemUsedBlksGet - Description : get the number of used node - Input : pPool --- Pointer to memory pool - Output : None - Return : the number of used node -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemUsedBlksGet(VOID *pPool) +STATIC VOID OsMemListDelete(LOS_DL_LIST *node, const VOID *firstNode) { - LOS_MEM_DYN_NODE *pstTmpNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - UINT32 uwBlkNums = 0; - UINTPTR uvIntSave; + LosMemDynNode *dynNode = NULL; - if (pPool == NULL) - { - return LOS_NOK; - } + node->pstNext->pstPrev = node->pstPrev; + node->pstPrev->pstNext = node->pstNext; - uvIntSave = LOS_IntLock(); + if ((VOID *)(node->pstNext) >= firstNode) { + dynNode = LOS_DL_LIST_ENTRY(node->pstNext, LosMemDynNode, selfNode.freeNodeInfo); + OsMemNodeSave(dynNode); + } - for (pstTmpNode = OS_MEM_FIRST_NODE(pPool); pstTmpNode <= OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - pstTmpNode= OS_MEM_NEXT_NODE(pstTmpNode)) - { - if (OS_MEM_NODE_GET_USED_FLAG(pstTmpNode->uwSizeAndFlag)) - { - uwBlkNums++; - } + if ((VOID *)(node->pstPrev) >= firstNode) { + dynNode = LOS_DL_LIST_ENTRY(node->pstPrev, LosMemDynNode, selfNode.freeNodeInfo); + OsMemNodeSave(dynNode); } - LOS_IntRestore(uvIntSave); + node->pstNext = NULL; + node->pstPrev = NULL; - return uwBlkNums; + dynNode = LOS_DL_LIST_ENTRY(node, LosMemDynNode, selfNode.freeNodeInfo); + OsMemNodeSave(dynNode); } -/***************************************************************************** - Function :LOS_MemTaskIdGet - Description : get a memory node's taskID if pointer node is "used node" - Input : pPtr --- 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(VOID *pPtr) +STATIC VOID OsMemListAdd(LOS_DL_LIST *listNode, LOS_DL_LIST *node, const VOID *firstNode) { - LOS_MEM_DYN_NODE *pstTmpNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)OS_SYS_MEM_ADDR; - UINTPTR uvIntSave; - - if (pPtr == NULL || - pPtr < (VOID *)OS_MEM_FIRST_NODE(OS_SYS_MEM_ADDR) || - pPtr > (VOID *)OS_MEM_END_NODE(OS_SYS_MEM_ADDR, pstPoolInfo->uwPoolSize)) - { - PRINT_ERR("input ptr 0x%x is out of system memory range[0x%x, 0x%x]\n", (UINT32)pPtr, OS_MEM_FIRST_NODE(OS_SYS_MEM_ADDR), - OS_MEM_END_NODE(OS_SYS_MEM_ADDR, pstPoolInfo->uwPoolSize));/*lint !e515 !e516*/ - return OS_INVALID; - } + LosMemDynNode *dynNode = NULL; - uvIntSave= LOS_IntLock(); + node->pstNext = listNode->pstNext; + node->pstPrev = listNode; - for (pstTmpNode = OS_MEM_FIRST_NODE(OS_SYS_MEM_ADDR); pstTmpNode <= OS_MEM_END_NODE(OS_SYS_MEM_ADDR, pstPoolInfo->uwPoolSize); - pstTmpNode = OS_MEM_NEXT_NODE(pstTmpNode)) - { + dynNode = LOS_DL_LIST_ENTRY(node, LosMemDynNode, selfNode.freeNodeInfo); + OsMemNodeSave(dynNode); - if ((UINT32)pPtr < (UINT32)pstTmpNode) - { - if (OS_MEM_NODE_GET_USED_FLAG(pstTmpNode->pstPreNode->uwSizeAndFlag)) - { - LOS_IntRestore(uvIntSave); - return (UINT32)(pstTmpNode->pstPreNode->stFreeNodeInfo.pstNext); - } - else - { - LOS_IntRestore(uvIntSave); - PRINT_ERR("input ptr 0x%x is belong to a free mem node\n", pPtr); /*lint !e626 !e515*/ - return OS_INVALID; - } - } + listNode->pstNext->pstPrev = node; + if ((VOID *)(listNode->pstNext) >= firstNode) { + dynNode = LOS_DL_LIST_ENTRY(listNode->pstNext, LosMemDynNode, selfNode.freeNodeInfo); + OsMemNodeSave(dynNode); } - LOS_IntRestore(uvIntSave); - return OS_INVALID; + listNode->pstNext = node; } -/***************************************************************************** - 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 *pPool) +VOID LOS_MemBadNodeShow(VOID *pool) { - LOS_MEM_DYN_NODE *pstTmpNode = (LOS_MEM_DYN_NODE *)NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - UINT32 uwBlkNums = 0; - UINTPTR uvIntSave; + LosMemDynNode *nodePre = NULL; + LosMemDynNode *tmpNode = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT32 intSave; - if (pPool == NULL) - { - return LOS_NOK; + if (pool == NULL) { + return; } - uvIntSave = LOS_IntLock(); + MEM_LOCK(intSave); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + OsMemDispCtlNode(&tmpNode->selfNode); - for (pstTmpNode = OS_MEM_FIRST_NODE(pPool); pstTmpNode <= OS_MEM_END_NODE(pPool, pstPoolInfo->uwPoolSize); - pstTmpNode = OS_MEM_NEXT_NODE(pstTmpNode)) - { - if (!OS_MEM_NODE_GET_USED_FLAG(pstTmpNode->uwSizeAndFlag)) - { - uwBlkNums++; + if (OsMemChecksumVerify(&tmpNode->selfNode)) { + continue; + } + + nodePre = OsMemNodePrevGet(pool, tmpNode); + if (nodePre == NULL) { + PRINT_ERR("the current node is invalid, but cannot find its previous Node\n"); + continue; } - } - LOS_IntRestore(uvIntSave); + PRINT_ERR("the detailed information of previous node:\n"); + OsMemDispMoreDetails(nodePre); + } - return uwBlkNums; + MEM_UNLOCK(intSave); + PRINTK("check finish\n"); } -/***************************************************************************** - 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 LOS_MEM_DYN_NODE *osMemResetEndNode(VOID) -{ - LOS_MEM_DYN_NODE *pstEndNode = (LOS_MEM_DYN_NODE *)OS_MEM_END_NODE(OS_SYS_MEM_ADDR, OS_SYS_MEM_SIZE); - memset(pstEndNode, 0, sizeof(*pstEndNode)); - pstEndNode->pstPreNode = (LOS_MEM_DYN_NODE *)NULL; - pstEndNode->uwSizeAndFlag = OS_MEM_NODE_HEAD_SIZE; - OS_MEM_NODE_SET_USED_FLAG(pstEndNode->uwSizeAndFlag); +#else /* without LOSCFG_MEM_HEAD_BACKUP */ - return pstEndNode; +STATIC VOID OsMemListDelete(LOS_DL_LIST *node, const VOID *firstNode) +{ + (VOID)firstNode; + node->pstNext->pstPrev = node->pstPrev; + node->pstPrev->pstNext = node->pstNext; + node->pstNext = NULL; + node->pstPrev = NULL; } -/***************************************************************************** - Function : LOS_MemPoolSizeGet - Description : get the memory pool's size - Input : pPool --- Pointer to memory pool - Output : LOS_NOK & Other value -- The size of the memory pool. - Return : the size of the memory pool -*****************************************************************************/ - LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(VOID *pPool) +STATIC VOID OsMemListAdd(LOS_DL_LIST *listNode, LOS_DL_LIST *node, const VOID *firstNode) { - if (pPool == NULL) - { - return LOS_NOK; - } - return ((LOS_MEM_POOL_INFO *)pPool)->uwPoolSize; + (VOID)firstNode; + node->pstNext = listNode->pstNext; + node->pstPrev = listNode; + listNode->pstNext->pstPrev = node; + listNode->pstNext = node; } -/***************************************************************************** - Function : LOS_MemGetUsed - Description : figure the system memory pool for it's total mem used - Input : None - Output : None - Return : the size of the system memory pool has been used -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemGetUsed(VOID) +#endif + +#ifdef LOSCFG_EXC_INTERACTION +LITE_OS_SEC_TEXT_INIT UINT32 OsMemExcInteractionInit(UINTPTR memStart) { - return LOS_MemTotalUsedGet(OS_SYS_MEM_ADDR); + UINT32 ret; + UINT32 poolSize; + m_aucSysMem0 = (UINT8 *)((memStart + (POOL_ADDR_ALIGNSIZE - 1)) & ~((UINTPTR)(POOL_ADDR_ALIGNSIZE - 1))); + poolSize = OS_EXC_INTERACTMEM_SIZE; + ret = LOS_MemInit(m_aucSysMem0, poolSize); + PRINT_INFO("LiteOS kernel exc interaction memory address:%p,size:0x%x\n", m_aucSysMem0, poolSize); + return ret; } +#endif -/***************************************************************************** - Function : LOS_MemGetTotal - Description : get the system memory pool's size - Input : None - Output : None - Return : the size of the system memory pool -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemGetTotal(VOID) +LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart) { - return ((LOS_MEM_POOL_INFO *)OS_SYS_MEM_ADDR)->uwPoolSize; + UINT32 ret; + UINT32 poolSize; + + m_aucSysMem1 = (UINT8 *)((memStart + (POOL_ADDR_ALIGNSIZE - 1)) & ~((UINTPTR)(POOL_ADDR_ALIGNSIZE - 1))); + poolSize = OS_SYS_MEM_SIZE; + ret = LOS_MemInit(m_aucSysMem1, poolSize); + PRINT_INFO("LiteOS system heap memory address:%p,size:0x%x\n", m_aucSysMem1, poolSize); +#ifndef LOSCFG_EXC_INTERACTION + m_aucSysMem0 = m_aucSysMem1; +#endif + return ret; } -#ifdef OS_MEM_CHECK_DEBUG - -/***************************************************************************** - Function: LOS_MemNodeSizeCheck - Description: get a pNode's(pPtr) size ,include total size and available size - Input :pPool --which pPool doesn't your pPtr belong to - pPtr --point to source node - Output :puwTotalSize -- save total size - puwAvailSize -- save availabe size - Return : errorID or LOS_OK -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemNodeSizeCheck(VOID *pPool, VOID *pPtr, UINT32 *puwTotalSize, UINT32 *puwAvailSize) +#ifdef LOSCFG_MEM_LEAKCHECK +STATIC INLINE VOID OsMemLinkRegisterRecord(LosMemDynNode *node) { - VOID *pHead = NULL; - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - UINT8 *pucEndPool; - - if ( ucCheckMemLevel == LOS_MEM_CHECK_LEVEL_DISABLE) - { - return OS_ERRNO_MEMCHECK_DISABLED; + UINT32 count = 0; + UINT32 index = 0; + UINTPTR framePtr, tmpFramePtr, linkReg; + + (VOID)memset_s(node->selfNode.linkReg, (LOS_RECORD_LR_CNT * sizeof(UINTPTR)), 0, + (LOS_RECORD_LR_CNT * sizeof(UINTPTR))); + framePtr = Get_Fp(); + while ((framePtr > OS_SYS_FUNC_ADDR_START) && (framePtr < OS_SYS_FUNC_ADDR_END)) { + tmpFramePtr = framePtr; +#ifdef __LP64__ + framePtr = *(UINTPTR *)framePtr; + linkReg = *(UINTPTR *)(tmpFramePtr + sizeof(UINTPTR)); +#else + linkReg = *(UINTPTR *)framePtr; + framePtr = *(UINTPTR *)(tmpFramePtr - sizeof(UINTPTR)); +#endif + if (index >= LOS_OMIT_LR_CNT) { + node->selfNode.linkReg[count++] = linkReg; + if (count == LOS_RECORD_LR_CNT) { + break; + } + } + index++; } + return; +} +#endif - if ( NULL == pPool) - { - return OS_ERRNO_MEMCHECK_NOT_INIT; - } - if (pPtr == NULL) - { - return OS_ERRNO_MEMCHECK_PARA_NULL; - } +#define OS_CHECK_NULL_RETURN(param) do { \ + if ((param) == NULL) { \ + PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__); \ + return; \ + } \ +} while (0); + +/* + * 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 + * Return : NULL --- no suitable block found + * tmpNode --- pointer a suitable free block + */ +STATIC INLINE LosMemDynNode *OsMemFindSuitableFreeBlock(VOID *pool, UINT32 allocSize) +{ + LOS_DL_LIST *listNodeHead = NULL; + LosMemDynNode *tmpNode = NULL; + UINT32 maxCount = (((LosMemPoolInfo *)pool)->poolSize / allocSize) << 1; + UINT32 count; +#ifdef LOSCFG_MEM_HEAD_BACKUP + UINT32 ret = LOS_OK; +#endif + for (listNodeHead = OS_MEM_HEAD(pool, allocSize); listNodeHead != NULL; + listNodeHead = OsDLnkNextMultiHead(OS_MEM_HEAD_ADDR(pool), listNodeHead)) { + count = 0; + LOS_DL_LIST_FOR_EACH_ENTRY(tmpNode, listNodeHead, LosMemDynNode, selfNode.freeNodeInfo) { + if (count++ >= maxCount) { + PRINT_ERR("[%s:%d]node: %p execute too much time\n", __FUNCTION__, __LINE__, tmpNode); + break; + } - pucEndPool = (UINT8 *)pPool + pstPoolInfo->uwPoolSize; - if ( !( OS_MEM_MIDDLE_ADDR_OPEN_END(pPool, (UINT8 *)pPtr, pucEndPool))) - { - return OS_ERRNO_MEMCHECK_OUTSIDE; - } +#ifdef LOSCFG_MEM_HEAD_BACKUP + if (!OsMemChecksumVerify(&tmpNode->selfNode)) { + PRINT_ERR("[%s]: the node information of current node is bad !!\n", __FUNCTION__); + OsMemDispCtlNode(&tmpNode->selfNode); + ret = OsMemBackupRestore(pool, tmpNode); + } + if (ret != LOS_OK) { + break; + } +#endif - if ( ucCheckMemLevel == LOS_MEM_CHECK_LEVEL_HIGH) - { - pHead = osMemFindNodeCtrl(pPtr); - if ((pHead == NULL) || ((((LOS_MEM_DYN_NODE *)pHead)->uwSizeAndFlag & (~OS_MEM_NODE_USED_FLAG)) < ((UINT32)pPtr - (UINT32)pHead))) - { - return OS_ERRNO_MEMCHECK_NO_HEAD; - } - *puwTotalSize = (((LOS_MEM_DYN_NODE *)pHead)->uwSizeAndFlag - sizeof(LOS_MEM_DYN_NODE)) & (~OS_MEM_NODE_USED_FLAG); - *puwAvailSize = (((LOS_MEM_DYN_NODE *)pHead)->uwSizeAndFlag - ((UINT32)pPtr - (UINT32)pHead)) & (~OS_MEM_NODE_USED_FLAG); - return LOS_OK; - } - if ( ucCheckMemLevel == LOS_MEM_CHECK_LEVEL_LOW) - { - if (pPtr != (VOID *)OS_MEM_ALIGN(pPtr, OS_MEM_ALIGN_SIZE)) - { - return OS_ERRNO_MEMCHECK_NO_HEAD; - } - pHead = (VOID *)((UINT32)pPtr - sizeof(LOS_MEM_DYN_NODE)); - if (OS_MEM_MAGIC_VALID(((LOS_MEM_DYN_NODE *)pHead)->stFreeNodeInfo.pstPrev)) - { - *puwTotalSize = (((LOS_MEM_DYN_NODE *)pHead)->uwSizeAndFlag - sizeof(LOS_MEM_DYN_NODE)) & (~OS_MEM_NODE_USED_FLAG); - *puwAvailSize = (((LOS_MEM_DYN_NODE *)pHead)->uwSizeAndFlag - sizeof(LOS_MEM_DYN_NODE)) & (~OS_MEM_NODE_USED_FLAG); - return LOS_OK; - } - else - { - return OS_ERRNO_MEMCHECK_NO_HEAD; + if (((UINTPTR)tmpNode < (UINTPTR)pool) || + ((UINTPTR)tmpNode > ((UINTPTR)pool + ((LosMemPoolInfo *)pool)->poolSize)) || + (((UINTPTR)tmpNode & (OS_MEM_ALIGN_SIZE - 1)) != 0)) { + LOS_Panic("[%s:%d]Mem node data error:OS_MEM_HEAD_ADDR(pool)=%p, listNodeHead:%p," + "allocSize=%u, tmpNode=%p\n", + __FUNCTION__, __LINE__, OS_MEM_HEAD_ADDR(pool), listNodeHead, allocSize, tmpNode); + break; + } + if (tmpNode->selfNode.sizeAndFlag >= allocSize) { + return tmpNode; + } } } - return OS_ERRNO_MEMCHECK_WRONG_LEVEL; + return NULL; } -/***************************************************************************** -Function : osMemFindNodeCtrl -Description : get a pool's memCtrl -Input :pPtr -- point to source pPtr -Output :None -Return : search forward for pPtr's memCtrl or "NULL" -@attention : this func couldn't ensure the return memCtrl belongs to pPtr -it just find forward the most nearly one -*******************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID *osMemFindNodeCtrl(VOID *pPtr) +/* + * Description : clear a mem node, set every member to NULL + * Input : node --- Pointer to the mem node which will be cleared up + */ +STATIC INLINE VOID OsMemClearNode(LosMemDynNode *node) { - UINT8 *pucHead = (UINT8 *)pPtr; - - if( pPtr == NULL ) - { - return NULL; - } + (VOID)memset_s((VOID *)node, sizeof(LosMemDynNode), 0, sizeof(LosMemDynNode)); +} - pucHead = (UINT8 *)OS_MEM_ALIGN((VOID *)pucHead, OS_MEM_ALIGN_SIZE); - while (!OS_MEM_MAGIC_VALID(((LOS_MEM_DYN_NODE *)pucHead)->stFreeNodeInfo.pstPrev)) - { - pucHead -= 4; - } - return pucHead; +/* + * Description : merge this node and pre node, then clear this node info + * Input : node --- Pointer to node which will be merged + */ +STATIC INLINE VOID OsMemMergeNode(LosMemDynNode *node) +{ + LosMemDynNode *nextNode = NULL; + + node->selfNode.preNode->selfNode.sizeAndFlag += node->selfNode.sizeAndFlag; + nextNode = (LosMemDynNode *)((UINTPTR)node + node->selfNode.sizeAndFlag); + nextNode->selfNode.preNode = node->selfNode.preNode; +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(node->selfNode.preNode); + OsMemNodeSave(nextNode); +#endif + OsMemClearNode(node); } -/***************************************************************************** - Function : LOS_MemCheckLevelSet - Description : setting ucCheckMemLevel which decide the manner of memcheck - Input : ucLevel -- 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 ucLevel) +/* + * Description : split 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 + */ +STATIC INLINE VOID OsMemSplitNode(VOID *pool, + LosMemDynNode *allocNode, UINT32 allocSize) { - if ( ucLevel == LOS_MEM_CHECK_LEVEL_LOW) - { - PRINTK("%s: LOS_MEM_CHECK_LEVEL_LOW \n", __FUNCTION__); + LosMemDynNode *newFreeNode = NULL; + LosMemDynNode *nextNode = NULL; + LOS_DL_LIST *listNodeHead = NULL; + const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); + + newFreeNode = (LosMemDynNode *)(VOID *)((UINT8 *)allocNode + allocSize); + newFreeNode->selfNode.preNode = allocNode; + newFreeNode->selfNode.sizeAndFlag = allocNode->selfNode.sizeAndFlag - allocSize; + allocNode->selfNode.sizeAndFlag = allocSize; + nextNode = OS_MEM_NEXT_NODE(newFreeNode); + nextNode->selfNode.preNode = newFreeNode; + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->selfNode.sizeAndFlag)) { + OsMemListDelete(&nextNode->selfNode.freeNodeInfo, firstNode); + OsMemMergeNode(nextNode); + } +#ifdef LOSCFG_MEM_HEAD_BACKUP + else { + OsMemNodeSave(nextNode); + } +#endif + listNodeHead = OS_MEM_HEAD(pool, newFreeNode->selfNode.sizeAndFlag); + OS_CHECK_NULL_RETURN(listNodeHead); + + OsMemListAdd(listNodeHead, &newFreeNode->selfNode.freeNodeInfo, firstNode); +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(newFreeNode); +#endif +} + +/* + * Description : free the node from memory & if there are free node beside, merger them. + * at last update "listNodeHead' which saved all free node control head + * Input : node -- the node which need be freed + * pool -- Pointer to memory pool + */ +STATIC INLINE VOID OsMemFreeNode(LosMemDynNode *node, VOID *pool) +{ + LosMemDynNode *nextNode = NULL; + LOS_DL_LIST *listNodeHead = NULL; + const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->poolCurUsedSize -= OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag); +#endif + OS_MEM_REDUCE_USED(poolInfo->memStats, OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag), OS_MEM_TASKID_GET(node)); + node->selfNode.sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag); +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(node); +#endif +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(node); +#endif + if ((node->selfNode.preNode != NULL) && + !OS_MEM_NODE_GET_USED_FLAG(node->selfNode.preNode->selfNode.sizeAndFlag)) { + LosMemDynNode *preNode = node->selfNode.preNode; + OsMemMergeNode(node); + nextNode = OS_MEM_NEXT_NODE(preNode); + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->selfNode.sizeAndFlag)) { + OsMemListDelete(&nextNode->selfNode.freeNodeInfo, firstNode); + OsMemMergeNode(nextNode); + } + + OsMemListDelete(&(preNode->selfNode.freeNodeInfo), firstNode); + listNodeHead = OS_MEM_HEAD(pool, preNode->selfNode.sizeAndFlag); + OS_CHECK_NULL_RETURN(listNodeHead); + + OsMemListAdd(listNodeHead, &preNode->selfNode.freeNodeInfo, firstNode); + } else { + nextNode = OS_MEM_NEXT_NODE(node); + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->selfNode.sizeAndFlag)) { + OsMemListDelete(&nextNode->selfNode.freeNodeInfo, firstNode); + OsMemMergeNode(nextNode); + } + + listNodeHead = OS_MEM_HEAD(pool, node->selfNode.sizeAndFlag); + OS_CHECK_NULL_RETURN(listNodeHead); + + OsMemListAdd(listNodeHead, &node->selfNode.freeNodeInfo, firstNode); + } +} + +/* + * 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 + * Return : LOS_OK or LOS_NOK + */ +#ifdef LOS_DLNK_SAFE_CHECK +STATIC INLINE UINT32 OsMemCheckUsedNode(const VOID *pool, const LosMemDynNode *node) +{ + LosMemDynNode *tmpNode = NULL; + const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; + const LosMemDynNode *endNode = (const LosMemDynNode *)OS_MEM_END_NODE(pool, poolInfo->poolSize); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if ((tmpNode == node) && + OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.sizeAndFlag)) { + return LOS_OK; + } else if (tmpNode > node) { + return LOS_NOK; + } + } + + return LOS_NOK; +} + +#elif defined(LOS_DLNK_SIMPLE_CHECK) +STATIC INLINE UINT32 OsMemCheckUsedNode(const VOID *pool, const LosMemDynNode *node) +{ + const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; + const LosMemDynNode *startNode = (const LosMemDynNode *)OS_MEM_FIRST_NODE(pool); + const LosMemDynNode *endNode = (const LosMemDynNode *)OS_MEM_END_NODE(pool, poolInfo->poolSize); + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(startNode, node, endNode)) { + return LOS_NOK; + } + + if (!OS_MEM_NODE_GET_USED_FLAG(node->selfNode.sizeAndFlag)) { + return LOS_NOK; + } + + if (!OS_MEM_MAGIC_VALID(node->selfNode.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->selfNode.sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID(node->selfNode.freeNodeInfo.pstPrev)) { + return FALSE; + } + return TRUE; + } + + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(startPool, node->selfNode.freeNodeInfo.pstPrev, endPool)) { + return FALSE; + } + + return TRUE; +} + +STATIC INLINE UINT32 OsMemCheckUsedNode(const VOID *pool, const LosMemDynNode *node) +{ + const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; + const LosMemDynNode *startNode = (const LosMemDynNode *)OS_MEM_FIRST_NODE(pool); + const LosMemDynNode *endNode = (const LosMemDynNode *)OS_MEM_END_NODE(pool, poolInfo->poolSize); + const UINT8 *endPool = (const UINT8 *)pool + poolInfo->poolSize; + const LosMemDynNode *nextNode = NULL; + if (!OsMemIsNodeValid(node, startNode, endNode, (UINT8 *)pool, endPool)) { + return LOS_NOK; + } + + if (!OS_MEM_NODE_GET_USED_FLAG(node->selfNode.sizeAndFlag)) { + return LOS_NOK; + } + + nextNode = OS_MEM_NEXT_NODE(node); + if (!OsMemIsNodeValid(nextNode, startNode, endNode, (UINT8 *)pool, endPool)) { + return LOS_NOK; + } + + if (nextNode->selfNode.preNode != node) { + return LOS_NOK; + } + + if (node != startNode) { + if (!OsMemIsNodeValid(node->selfNode.preNode, startNode, endNode, (UINT8 *)pool, endPool)) { + return LOS_NOK; + } + + if (OS_MEM_NEXT_NODE(node->selfNode.preNode) != node) { + return LOS_NOK; + } + } + + return LOS_OK; +} + +#endif + +/* + * Description : set magic & taskid + * Input : node -- the node which will be set magic & taskid + */ +STATIC INLINE VOID OsMemSetMagicNumAndTaskID(LosMemDynNode *node) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + + OS_MEM_SET_MAGIC(node->selfNode.freeNodeInfo.pstPrev); + + /* + * If the operation occured before task initialization(runTask was not assigned) + * or in interrupt,make the value of taskid of node to 0xffffffff + */ + if ((runTask != NULL) && OS_INT_INACTIVE) { + OS_MEM_TASKID_SET(node, runTask->taskID); + } else { + /* If the task mode does not initialize, the field is the 0xffffffff */ + node->selfNode.freeNodeInfo.pstNext = (LOS_DL_LIST *)OS_NULL_INT; + } +} + +LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsMemPoolDlinkcheck(const LosMemPoolInfo *pool, LOS_DL_LIST listHead) +{ + if (((UINTPTR)listHead.pstPrev < (UINTPTR)(pool + 1)) || + ((UINTPTR)listHead.pstPrev >= ((UINTPTR)pool + pool->poolSize)) || + ((UINTPTR)listHead.pstNext < (UINTPTR)(pool + 1)) || + ((UINTPTR)listHead.pstNext >= ((UINTPTR)pool + pool->poolSize)) || + !IS_ALIGNED(listHead.pstPrev, sizeof(VOID *)) || + !IS_ALIGNED(listHead.pstNext, sizeof(VOID *))) { + return LOS_NOK; + } + + return LOS_OK; +} + +/* + * Description : show mem pool header info + * Input : pool --Pointer to memory pool + */ +LITE_OS_SEC_TEXT_MINOR VOID OsMemPoolHeadInfoPrint(const VOID *pool) +{ + const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; + UINT32 dlinkNum; + UINT32 flag = 0; + const LosMultipleDlinkHead *dlinkHead = NULL; + + if (!IS_ALIGNED(poolInfo, sizeof(VOID *))) { + PRINT_ERR("wrong mem pool addr: %p, func:%s,line:%d\n", poolInfo, __FUNCTION__, __LINE__); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("wrong mem pool addr: %p, func:%s,line:%d\n", poolInfo, __FUNCTION__, __LINE__); +#endif + return; + } + + dlinkHead = (const LosMultipleDlinkHead *)(VOID *)(poolInfo + 1); + for (dlinkNum = 0; dlinkNum < OS_MULTI_DLNK_NUM; dlinkNum++) { + if (OsMemPoolDlinkcheck(pool, dlinkHead->listHead[dlinkNum])) { + flag = 1; + PRINT_ERR("DlinkHead[%u]: pstPrev:%p, pstNext:%p\n", + dlinkNum, dlinkHead->listHead[dlinkNum].pstPrev, dlinkHead->listHead[dlinkNum].pstNext); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("DlinkHead[%u]: pstPrev:%p, pstNext:%p\n", + dlinkNum, dlinkHead->listHead[dlinkNum].pstPrev, dlinkHead->listHead[dlinkNum].pstNext); +#endif + } + } + if (flag) { + PRINTK("mem pool info: poolAddr:%p, poolSize:0x%x\n", poolInfo->pool, poolInfo->poolSize); +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + PRINTK("mem pool info: poolWaterLine:0x%x, poolCurUsedSize:0x%x\n", poolInfo->poolWaterLine, + poolInfo->poolCurUsedSize); +#endif + +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("mem pool info: poolAddr:%p, poolSize:0x%x\n", poolInfo->pool, poolInfo->poolSize); +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + WriteExcInfoToBuf("mem pool info: poolWaterLine:0x%x, poolCurUsedSize:0x%x\n", + poolInfo->poolWaterLine, poolInfo->poolCurUsedSize); +#endif +#endif + } +} + +STATIC UINT32 OsMemIntegrityCheck(const VOID *pool, + LosMemDynNode **tmpNode, + LosMemDynNode **preNode) +{ + const LosMemPoolInfo *poolInfo = (const LosMemPoolInfo *)pool; + const UINT8 *endPool = (const UINT8 *)pool + poolInfo->poolSize; + + OsMemPoolHeadInfoPrint(pool); + + *preNode = OS_MEM_FIRST_NODE(pool); + for (*tmpNode = OS_MEM_FIRST_NODE(pool); *tmpNode < OS_MEM_END_NODE(pool, poolInfo->poolSize); + *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG((*tmpNode)->selfNode.sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID((*tmpNode)->selfNode.freeNodeInfo.pstPrev)) { + PRINT_ERR("[%s], %d, memory check error!\n" + "memory used but magic num wrong, freeNodeInfo.pstPrev(magic num):%p \n", + __FUNCTION__, __LINE__, (*tmpNode)->selfNode.freeNodeInfo.pstPrev); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("[%s], %d, memory check error!\n" + "memory used but magic num wrong, freeNodeInfo.pstPrev(magic num):%p \n", + __FUNCTION__, __LINE__, (*tmpNode)->selfNode.freeNodeInfo.pstPrev); +#endif + return LOS_NOK; + } + } else { /* is free node, check free node range */ + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pool, (*tmpNode)->selfNode.freeNodeInfo.pstPrev, endPool)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " freeNodeInfo.pstPrev:%p is out of legal mem range[%p, %p]\n", + __FUNCTION__, __LINE__, (*tmpNode)->selfNode.freeNodeInfo.pstPrev, pool, endPool); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("[%s], %d, memory check error!\n" + " freeNodeInfo.pstPrev:%p is out of legal mem range[%p, %p]\n", + __FUNCTION__, __LINE__, (*tmpNode)->selfNode.freeNodeInfo.pstPrev, pool, endPool); +#endif + return LOS_NOK; + } + if (!OS_MEM_MIDDLE_ADDR_OPEN_END(pool, (*tmpNode)->selfNode.freeNodeInfo.pstNext, endPool)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " freeNodeInfo.pstNext:%p is out of legal mem range[%p, %p]\n", + __FUNCTION__, __LINE__, (*tmpNode)->selfNode.freeNodeInfo.pstNext, pool, endPool); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("[%s], %d, memory check error!\n" + " freeNodeInfo.pstNext:%p is out of legal mem range[%p, %p]\n", + __FUNCTION__, __LINE__, (*tmpNode)->selfNode.freeNodeInfo.pstNext, pool, endPool); +#endif + return LOS_NOK; + } + } + + *preNode = *tmpNode; + } + return LOS_OK; +} + +#ifdef LOSCFG_MEM_LEAKCHECK +STATIC VOID OsMemNodeBacktraceInfo(const LosMemDynNode *tmpNode, + const LosMemDynNode *preNode) +{ + int i; + PRINTK("\n broken node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + PRINTK(" LR[%d]:%p\n", i, tmpNode->selfNode.linkReg[i]); + } + PRINTK("\n pre node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + PRINTK(" LR[%d]:%p\n", i, preNode->selfNode.linkReg[i]); + } + +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("\n broken node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + WriteExcInfoToBuf("LR[%d]:%p\n", tmpNode->selfNode.linkReg[i]); + } + WriteExcInfoToBuf("\n pre node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + WriteExcInfoToBuf("LR[%d]:%p\n", preNode->selfNode.linkReg[i]); + } +#endif +} +#endif + +STATIC VOID OsMemNodeInfo(const LosMemDynNode *tmpNode, + const LosMemDynNode *preNode) +{ + if (tmpNode == preNode) { + PRINTK("\n the broken node is the first node\n"); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("\n the broken node is the first node\n"); +#endif + } + PRINTK("\n broken node head: %p %p %p 0x%x, pre node head: %p %p %p 0x%x\n", + tmpNode->selfNode.freeNodeInfo.pstPrev, tmpNode->selfNode.freeNodeInfo.pstNext, + tmpNode->selfNode.preNode, tmpNode->selfNode.sizeAndFlag, + preNode->selfNode.freeNodeInfo.pstPrev, preNode->selfNode.freeNodeInfo.pstNext, + preNode->selfNode.preNode, preNode->selfNode.sizeAndFlag); + +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("\n broken node head: %p %p %p 0x%x, pre node head: %p %p %p 0x%x\n", + tmpNode->selfNode.freeNodeInfo.pstPrev, tmpNode->selfNode.freeNodeInfo.pstNext, + tmpNode->selfNode.preNode, tmpNode->selfNode.sizeAndFlag, + preNode->selfNode.freeNodeInfo.pstPrev, preNode->selfNode.freeNodeInfo.pstNext, + preNode->selfNode.preNode, preNode->selfNode.sizeAndFlag); +#endif +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemNodeBacktraceInfo(tmpNode, preNode); +#endif + + PRINTK("\n---------------------------------------------\n"); + PRINTK(" dump mem tmpNode:0x%x ~ 0x%x\n", tmpNode, ((UINTPTR)tmpNode + NODEDUMPSIZE)); + OsDumpMemByte(NODEDUMPSIZE, (UINTPTR)tmpNode); + PRINTK("\n---------------------------------------------\n"); + if (preNode != tmpNode) { + PRINTK(" dump mem :0x%x ~ tmpNode:0x%x\n", ((UINTPTR)tmpNode - NODEDUMPSIZE), tmpNode); + OsDumpMemByte(NODEDUMPSIZE, ((UINTPTR)tmpNode - NODEDUMPSIZE)); + PRINTK("\n---------------------------------------------\n"); + } +} + +STATIC VOID OsMemIntegrityCheckError(const LosMemDynNode *tmpNode, + const LosMemDynNode *preNode, + UINT32 intSave) +{ + LosTaskCB *taskCB = NULL; + UINT32 taskID; + + OsMemNodeInfo(tmpNode, preNode); + + taskID = OS_MEM_TASKID_GET(preNode); + if (taskID >= g_taskMaxNum) { +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("Task ID %u in pre node is invalid!\n", taskID); +#endif + MEM_UNLOCK(intSave); + LOS_Panic("Task ID %u in pre node is invalid!\n", taskID); + return; + } + + taskCB = OS_TCB_FROM_TID(taskID); + if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) || + (taskCB->taskEntry == NULL) || (taskCB->taskName == NULL)) { +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("\r\nTask ID %u in pre node is not created or deleted!\n", taskID); +#endif + MEM_UNLOCK(intSave); + LOS_Panic("\r\nTask ID %u in pre node is not created!\n", taskID); + return; + } +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcInfoToBuf("cur node: %p\npre node: %p\npre node was allocated by task:%s\n", + tmpNode, preNode, taskCB->taskName); +#endif + MEM_UNLOCK(intSave); + LOS_Panic("cur node: %p\npre node: %p\npre node was allocated by task:%s\n", + tmpNode, preNode, taskCB->taskName); + return; +} + +/* + * Description : memory pool integrity checking + * Input : pool --Pointer to memory pool + * Return : LOS_OK --memory pool integrate or LOS_NOK--memory pool impaired + */ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) +{ + LosMemDynNode *tmpNode = NULL; + LosMemDynNode *preNode = NULL; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + MEM_LOCK(intSave); + if (OsMemIntegrityCheck(pool, &tmpNode, &preNode)) { + goto ERROR_OUT; + } + MEM_UNLOCK(intSave); + return LOS_OK; + +ERROR_OUT: + OsMemIntegrityCheckError(tmpNode, preNode, intSave); + return LOS_NOK; +} + +STATIC INLINE VOID OsMemNodeDebugOperate(VOID *pool, LosMemDynNode *allocNode, UINT32 size) +{ +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + poolInfo->poolCurUsedSize += OS_MEM_NODE_GET_SIZE(allocNode->selfNode.sizeAndFlag); + if (poolInfo->poolCurUsedSize > poolInfo->poolWaterLine) { + poolInfo->poolWaterLine = poolInfo->poolCurUsedSize; + } +#endif + +#ifdef LOSCFG_MEM_RECORDINFO + allocNode->selfNode.originSize = size; +#endif + +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(allocNode); +#endif + +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(allocNode); +#endif +} + +/* + * Description : Allocate node from Memory pool + * Input : pool --- Pointer to memory pool + * size --- Size of memory in bytes to allocate + * Return : Pointer to allocated memory + */ +STATIC INLINE VOID *OsMemAllocWithCheck(VOID *pool, UINT32 size, UINT32 intSave) +{ + LosMemDynNode *allocNode = NULL; + UINT32 allocSize; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; +#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK + LosMemDynNode *tmpNode = NULL; + LosMemDynNode *preNode = NULL; +#endif + const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); + + if (g_MALLOC_HOOK != NULL) { + g_MALLOC_HOOK(); + } + +#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK + if (OsMemIntegrityCheck(pool, &tmpNode, &preNode)) { + OsMemIntegrityCheckError(tmpNode, preNode, intSave); + return NULL; + } +#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"); + MEM_UNLOCK(intSave); + OsMemInfoPrint(pool); + MEM_LOCK(intSave); + 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->selfNode.sizeAndFlag) { + OsMemSplitNode(pool, allocNode, allocSize); + } + OsMemListDelete(&allocNode->selfNode.freeNodeInfo, firstNode); + OsMemSetMagicNumAndTaskID(allocNode); + OS_MEM_NODE_SET_USED_FLAG(allocNode->selfNode.sizeAndFlag); + OS_MEM_ADD_USED(poolInfo->memStats, OS_MEM_NODE_GET_SIZE(allocNode->selfNode.sizeAndFlag), + OS_MEM_TASKID_GET(allocNode)); + OsMemNodeDebugOperate(pool, allocNode, size); + return (allocNode + 1); +} + +/* + * 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 + */ +STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, LosMemDynNode *node, UINT32 nodeSize) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= nodeSize) { + node->selfNode.sizeAndFlag = nodeSize; + OsMemSplitNode(pool, node, allocSize); + OS_MEM_NODE_SET_USED_FLAG(node->selfNode.sizeAndFlag); +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(node); +#endif + OS_MEM_REDUCE_USED(poolInfo->memStats, nodeSize - allocSize, OS_MEM_TASKID_GET(node)); +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->poolCurUsedSize -= nodeSize - allocSize; +#endif + } +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(node); +#endif +} + +/* + * 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 + */ +STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, LosMemDynNode *node, + UINT32 nodeSize, LosMemDynNode *nextNode) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + const VOID *firstNode = (const VOID *)((UINT8 *)OS_MEM_HEAD_ADDR(pool) + OS_DLNK_HEAD_SIZE); + + node->selfNode.sizeAndFlag = nodeSize; + OsMemListDelete(&nextNode->selfNode.freeNodeInfo, firstNode); + OsMemMergeNode(nextNode); + if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_ALIGN_SIZE) <= node->selfNode.sizeAndFlag) { + OsMemSplitNode(pool, node, allocSize); + } +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->poolCurUsedSize += (node->selfNode.sizeAndFlag - nodeSize); + if (poolInfo->poolCurUsedSize > poolInfo->poolWaterLine) { + poolInfo->poolWaterLine = poolInfo->poolCurUsedSize; + } +#endif + OS_MEM_ADD_USED(poolInfo->memStats, node->selfNode.sizeAndFlag - nodeSize, OS_MEM_TASKID_GET(node)); + OS_MEM_NODE_SET_USED_FLAG(node->selfNode.sizeAndFlag); +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(node); +#endif +#ifdef LOSCFG_MEM_LEAKCHECK + OsMemLinkRegisterRecord(node); +#endif +} + +#ifdef LOSCFG_MEM_MUL_POOL +STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) +{ + VOID *nextPool = g_poolHead; + VOID *curPool = g_poolHead; + UINTPTR poolEnd; + while (nextPool != NULL) { + poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); + if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || + (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { + PRINT_ERR("pool [%p, %p) conflict with pool [%p, %p)\n", + pool, (UINTPTR)pool + size, + nextPool, (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool)); + return LOS_NOK; + } + curPool = nextPool; + nextPool = ((LosMemPoolInfo *)nextPool)->nextPool; + } + + if (g_poolHead == NULL) { + g_poolHead = pool; + } else { + ((LosMemPoolInfo *)curPool)->nextPool = pool; + } + + ((LosMemPoolInfo *)pool)->nextPool = NULL; + return LOS_OK; +} +#endif + +STATIC UINT32 OsMemInit(VOID *pool, UINT32 size) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + LosMemDynNode *newNode = NULL; + LosMemDynNode *endNode = NULL; + LOS_DL_LIST *listNodeHead = NULL; +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + UINT32 statSize; +#endif + poolInfo->pool = pool; + poolInfo->poolSize = size; +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + statSize = sizeof(TaskMemUsedInfo) * TASK_BLOCK_NUM; + (VOID)memset_s(poolInfo->memStats, statSize, 0, statSize); +#endif + OsDLnkInitMultiHead(OS_MEM_HEAD_ADDR(pool)); + newNode = OS_MEM_FIRST_NODE(pool); + newNode->selfNode.sizeAndFlag = (size - ((UINTPTR)newNode - (UINTPTR)pool) - OS_MEM_NODE_HEAD_SIZE); + newNode->selfNode.preNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, size); + listNodeHead = OS_MEM_HEAD(pool, newNode->selfNode.sizeAndFlag); + if (listNodeHead == NULL) { + return LOS_NOK; + } + + LOS_ListTailInsert(listNodeHead, &(newNode->selfNode.freeNodeInfo)); + endNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, size); + (VOID)memset_s(endNode, sizeof(*endNode), 0, sizeof(*endNode)); + endNode->selfNode.preNode = newNode; + endNode->selfNode.sizeAndFlag = OS_MEM_NODE_HEAD_SIZE; + OS_MEM_NODE_SET_USED_FLAG(endNode->selfNode.sizeAndFlag); + OsMemSetMagicNumAndTaskID(endNode); +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolInfo->poolCurUsedSize = sizeof(LosMemPoolInfo) + OS_MULTI_DLNK_HEAD_SIZE + + OS_MEM_NODE_GET_SIZE(endNode->selfNode.sizeAndFlag); + poolInfo->poolWaterLine = poolInfo->poolCurUsedSize; +#endif +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(newNode); + OsMemNodeSave(endNode); +#endif + + return LOS_OK; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size) +{ + UINT32 intSave; + + if ((pool == NULL) || (size < OS_MEM_MIN_POOL_SIZE)) { + return OS_ERROR; + } + + if (!IS_ALIGNED(size, OS_MEM_ALIGN_SIZE)) { + PRINT_WARN("pool [%p, %p) size 0x%x sholud be aligned with OS_MEM_ALIGN_SIZE\n", + pool, (UINTPTR)pool + size, size); + size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE) - OS_MEM_ALIGN_SIZE; + } + + MEM_LOCK(intSave); +#ifdef LOSCFG_MEM_MUL_POOL + if (OsMemPoolAdd(pool, size)) { + MEM_UNLOCK(intSave); + return OS_ERROR; + } +#endif + + if (OsMemInit(pool, size)) { +#ifdef LOSCFG_MEM_MUL_POOL + (VOID)LOS_MemDeInit(pool); +#endif + MEM_UNLOCK(intSave); + return OS_ERROR; + } + + MEM_UNLOCK(intSave); + return LOS_OK; +} + +#ifdef LOSCFG_MEM_MUL_POOL +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pool) +{ + UINT32 intSave; + UINT32 ret = LOS_NOK; + VOID *nextPool = NULL; + VOID *curPool = NULL; + + MEM_LOCK(intSave); + do { + if (pool == NULL) { + break; + } + + if (pool == g_poolHead) { + g_poolHead = ((LosMemPoolInfo *)g_poolHead)->nextPool; + ret = LOS_OK; + break; + } + + curPool = g_poolHead; + nextPool = g_poolHead; + while (nextPool != NULL) { + if (pool == nextPool) { + ((LosMemPoolInfo *)curPool)->nextPool = ((LosMemPoolInfo *)nextPool)->nextPool; + ret = LOS_OK; + break; + } + curPool = nextPool; + nextPool = ((LosMemPoolInfo *)nextPool)->nextPool; + } + } while (0); + + MEM_UNLOCK(intSave); + return ret; +} + +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemPoolList(VOID) +{ + VOID *nextPool = g_poolHead; + UINT32 index = 0; + while (nextPool != NULL) { + PRINTK("pool%u :\n", index); + index++; + OsMemInfoPrint(nextPool); + nextPool = ((LosMemPoolInfo *)nextPool)->nextPool; + } + return index; +} +#endif + +LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) +{ + VOID *ptr = NULL; + UINT32 intSave; + + if ((pool == NULL) || (size == 0)) { + return NULL; + } + + MEM_LOCK(intSave); + do { + if (OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { + break; + } + + ptr = OsMemAllocWithCheck(pool, size, intSave); + } while (0); +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordMalloc(ptr, size); +#endif + MEM_UNLOCK(intSave); + return ptr; +} + +LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) +{ + UINT32 useSize; + UINT32 gapSize; + VOID *ptr = NULL; + VOID *alignedPtr = NULL; + LosMemDynNode *allocNode = NULL; + UINT32 intSave; + + if ((pool == NULL) || (size == 0) || (boundary == 0) || !IS_POW_TWO(boundary) || + !IS_ALIGNED(boundary, sizeof(VOID *))) { + return NULL; + } + + MEM_LOCK(intSave); + do { + /* + * sizeof(gapSize) bytes stores offset between alignedPtr and ptr, + * the ptr has been OS_MEM_ALIGN_SIZE(4 or 8) aligned, so maximum + * offset between alignedPtr and ptr is boundary - OS_MEM_ALIGN_SIZE + */ + if ((boundary - sizeof(gapSize)) > ((UINT32)(-1) - size)) { + break; + } + + useSize = (size + boundary) - sizeof(gapSize); + if (OS_MEM_NODE_GET_USED_FLAG(useSize) || OS_MEM_NODE_GET_ALIGNED_FLAG(useSize)) { + break; + } + + ptr = OsMemAllocWithCheck(pool, useSize, intSave); + + alignedPtr = (VOID *)OS_MEM_ALIGN(ptr, boundary); + if (ptr == alignedPtr) { + break; + } + + /* store gapSize in address (ptr -4), it will be checked while free */ + gapSize = (UINT32)((UINTPTR)alignedPtr - (UINTPTR)ptr); + allocNode = (LosMemDynNode *)ptr - 1; + OS_MEM_NODE_SET_ALIGNED_FLAG(allocNode->selfNode.sizeAndFlag); +#ifdef LOSCFG_MEM_RECORDINFO + allocNode->selfNode.originSize = size; +#endif +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSaveWithGapSize(allocNode, gapSize); +#endif + + OS_MEM_NODE_SET_ALIGNED_FLAG(gapSize); + *(UINT32 *)((UINTPTR)alignedPtr - sizeof(gapSize)) = gapSize; + + ptr = alignedPtr; + } while (0); +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordMalloc(ptr, size); +#endif + MEM_UNLOCK(intSave); + + return ptr; +} + +LITE_OS_SEC_TEXT STATIC INLINE UINT32 OsDoMemFree(VOID *pool, const VOID *ptr, LosMemDynNode *node) +{ + UINT32 ret = OsMemCheckUsedNode(pool, node); + if (ret == LOS_OK) { +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(ptr, node->selfNode.originSize); +#endif + OsMemFreeNode(node, pool); + } + return ret; +} + +#ifdef LOSCFG_MEM_HEAD_BACKUP +LITE_OS_SEC_TEXT STATIC INLINE UINT32 OsMemBackupCheckAndRetore(VOID *pool, VOID *ptr, LosMemDynNode *node) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + LosMemDynNode *startNode = OS_MEM_FIRST_NODE(pool); + LosMemDynNode *endNode = OS_MEM_END_NODE(pool, poolInfo->poolSize); + + if (OS_MEM_MIDDLE_ADDR(startNode, node, endNode)) { + /* GapSize is bad or node is broken, we need to verify & try to restore */ + if (!OsMemChecksumVerify(&(node->selfNode))) { + node = (LosMemDynNode *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + return OsMemBackupTryRestore(pool, &node, ptr); + } + } + return LOS_OK; +} +#endif + +LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *ptr) +{ + UINT32 ret = LOS_NOK; + UINT32 gapSize; + UINT32 intSave; + LosMemDynNode *node = NULL; + + if ((pool == NULL) || (ptr == NULL) || + !IS_ALIGNED(pool, sizeof(VOID *)) || !IS_ALIGNED(ptr, sizeof(VOID *))) { + return LOS_NOK; + } + + MEM_LOCK(intSave); + do { + gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + goto OUT; + } + + node = (LosMemDynNode *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE))) { + PRINT_ERR("illegal gapSize: 0x%x\n", gapSize); + break; + } + node = (LosMemDynNode *)((UINTPTR)ptr - gapSize - OS_MEM_NODE_HEAD_SIZE); + } +#ifndef LOSCFG_MEM_HEAD_BACKUP + ret = OsDoMemFree(pool, ptr, node); +#endif + } while (0); +#ifdef LOSCFG_MEM_HEAD_BACKUP + ret = OsMemBackupCheckAndRetore(pool, ptr, node); + if (!ret) { + ret = OsDoMemFree(pool, ptr, node); + } +#endif +OUT: +#ifdef LOSCFG_MEM_RECORDINFO + if (ret == LOS_NOK) { + OsMemRecordFree(ptr, 0); + } +#endif + MEM_UNLOCK(intSave); + return ret; +} + +STATIC VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) +{ + VOID *realPtr = ptr; + UINT32 gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32))); + + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(ptr, 0); +#endif + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || + (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE - (UINTPTR)pool))) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(ptr, 0); +#endif + return NULL; + } + realPtr = (VOID *)((UINTPTR)ptr - (UINTPTR)gapSize); + } + return realPtr; +} + +#ifdef LOSCFG_MEM_RECORDINFO +STATIC INLINE VOID OsMemReallocNodeRecord(LosMemDynNode *node, UINT32 size, const VOID *ptr) +{ + node->selfNode.originSize = size; +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(node); +#endif + OsMemRecordMalloc(ptr, size); +} +#endif + +STATIC VOID *OsMemRealloc(VOID *pool, const VOID *ptr, LosMemDynNode *node, UINT32 size, UINT32 intSave) +{ + LosMemDynNode *nextNode = NULL; + UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); + UINT32 nodeSize = OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag); + VOID *tmpPtr = NULL; +#ifdef LOSCFG_MEM_RECORDINFO + const VOID *originPtr = ptr; +#endif + + if (nodeSize >= allocSize) { +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(originPtr, node->selfNode.originSize); +#endif + OsMemReAllocSmaller(pool, allocSize, node, nodeSize); +#ifdef LOSCFG_MEM_RECORDINFO + OsMemReallocNodeRecord(node, size, ptr); +#endif + return (VOID *)ptr; + } + + nextNode = OS_MEM_NEXT_NODE(node); + if (!OS_MEM_NODE_GET_USED_FLAG(nextNode->selfNode.sizeAndFlag) && + ((nextNode->selfNode.sizeAndFlag + nodeSize) >= allocSize)) { +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(originPtr, node->selfNode.originSize); +#endif + OsMemMergeNodeForReAllocBigger(pool, allocSize, node, nodeSize, nextNode); +#ifdef LOSCFG_MEM_RECORDINFO + OsMemReallocNodeRecord(node, size, ptr); +#endif + return (VOID *)ptr; + } + + tmpPtr = OsMemAllocWithCheck(pool, size, intSave); + if (tmpPtr != NULL) { +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordMalloc(tmpPtr, size); +#endif + if (memcpy_s(tmpPtr, size, ptr, (nodeSize - OS_MEM_NODE_HEAD_SIZE)) != EOK) { + MEM_UNLOCK(intSave); + (VOID)LOS_MemFree((VOID *)pool, (VOID *)tmpPtr); + MEM_LOCK(intSave); + return NULL; + } +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(originPtr, node->selfNode.originSize); +#endif + OsMemFreeNode(node, pool); + } + return tmpPtr; +} + +LITE_OS_SEC_TEXT_MINOR VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) +{ + UINT32 intSave; + VOID *newPtr = NULL; + LosMemDynNode *node = NULL; +#ifdef LOSCFG_MEM_RECORDINFO + VOID *originPtr = ptr; +#endif + + if (OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size) || (pool == NULL)) { + return NULL; + } + + if (ptr == NULL) { + newPtr = LOS_MemAlloc(pool, size); + goto OUT; + } + + if (size == 0) { + (VOID)LOS_MemFree(pool, ptr); + goto OUT; + } + + MEM_LOCK(intSave); + + ptr = OsGetRealPtr(pool, ptr); + if (ptr == NULL) { + goto OUT_UNLOCK; + } + + node = (LosMemDynNode *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); + if (OsMemCheckUsedNode(pool, node) != LOS_OK) { +#ifdef LOSCFG_MEM_RECORDINFO + OsMemRecordFree(originPtr, 0); +#endif + goto OUT_UNLOCK; + } + + newPtr = OsMemRealloc(pool, ptr, node, size, intSave); + +OUT_UNLOCK: + MEM_UNLOCK(intSave); +OUT: + return newPtr; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) +{ + LosMemDynNode *tmpNode = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT32 memUsed = 0; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; } - else if(ucLevel == LOS_MEM_CHECK_LEVEL_HIGH) - { - PRINTK("%s: LOS_MEM_CHECK_LEVEL_HIGH \n", __FUNCTION__); + + MEM_LOCK(intSave); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.sizeAndFlag)) { + memUsed += OS_MEM_NODE_GET_SIZE(tmpNode->selfNode.sizeAndFlag); + } } - else if (ucLevel == LOS_MEM_CHECK_LEVEL_DISABLE) - { - PRINTK("%s: LOS_MEM_CHECK_LEVEL_DISABLE \n", __FUNCTION__); + + MEM_UNLOCK(intSave); + + return memUsed; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemUsedBlksGet(VOID *pool) +{ + LosMemDynNode *tmpNode = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT32 blkNums = 0; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + MEM_LOCK(intSave); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.sizeAndFlag)) { + blkNums++; + } + } + + MEM_UNLOCK(intSave); + + return blkNums; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTaskIdGet(VOID *ptr) +{ + LosMemDynNode *tmpNode = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)(VOID *)m_aucSysMem1; + UINT32 intSave; +#ifdef LOSCFG_EXC_INTERACTION + if (ptr < (VOID *)m_aucSysMem1) { + poolInfo = (LosMemPoolInfo *)(VOID *)m_aucSysMem0; + } +#endif + if ((ptr == NULL) || + (ptr < (VOID *)OS_MEM_FIRST_NODE(poolInfo)) || + (ptr > (VOID *)OS_MEM_END_NODE(poolInfo, poolInfo->poolSize))) { + PRINT_ERR("input ptr %p is out of system memory range[%p, %p]\n", ptr, OS_MEM_FIRST_NODE(poolInfo), + OS_MEM_END_NODE(poolInfo, poolInfo->poolSize)); + return OS_INVALID; + } + + MEM_LOCK(intSave); + + for (tmpNode = OS_MEM_FIRST_NODE(poolInfo); tmpNode <= OS_MEM_END_NODE(poolInfo, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if ((UINTPTR)ptr < (UINTPTR)tmpNode) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.preNode->selfNode.sizeAndFlag)) { + MEM_UNLOCK(intSave); + return (UINT32)((UINTPTR)(tmpNode->selfNode.preNode->selfNode.freeNodeInfo.pstNext)); + } else { + MEM_UNLOCK(intSave); + PRINT_ERR("input ptr %p is belong to a free mem node\n", ptr); + return OS_INVALID; + } + } + } + + MEM_UNLOCK(intSave); + return OS_INVALID; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeBlksGet(VOID *pool) +{ + LosMemDynNode *tmpNode = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT32 blkNums = 0; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; + } + + MEM_LOCK(intSave); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.sizeAndFlag)) { + blkNums++; + } + } + + MEM_UNLOCK(intSave); + + return blkNums; +} + +LITE_OS_SEC_TEXT_MINOR UINTPTR LOS_MemLastUsedGet(VOID *pool) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + LosMemDynNode *node = NULL; + + if (pool == NULL) { + return LOS_NOK; + } + + node = OS_MEM_END_NODE(pool, poolInfo->poolSize)->selfNode.preNode; + if (OS_MEM_NODE_GET_USED_FLAG(node->selfNode.sizeAndFlag)) { + return (UINTPTR)((CHAR *)node + OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag) + sizeof(LosMemDynNode)); + } else { + return (UINTPTR)((CHAR *)node + sizeof(LosMemDynNode)); + } +} + +/* + * Description : reset "end node" + * Input : pool --- Pointer to memory pool + * preAddr --- Pointer to the pre Pointer of end node + * Output : endNode --- pointer to "end node" + * Return : the number of free node + */ +LITE_OS_SEC_TEXT_MINOR VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr) +{ + LosMemDynNode *endNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, ((LosMemPoolInfo *)pool)->poolSize); + endNode->selfNode.sizeAndFlag = OS_MEM_NODE_HEAD_SIZE; + if (preAddr != 0) { + endNode->selfNode.preNode = (LosMemDynNode *)(preAddr - sizeof(LosMemDynNode)); + } + OS_MEM_NODE_SET_USED_FLAG(endNode->selfNode.sizeAndFlag); + OsMemSetMagicNumAndTaskID(endNode); + +#ifdef LOSCFG_MEM_HEAD_BACKUP + OsMemNodeSave(endNode); +#endif +} + +UINT32 LOS_MemPoolSizeGet(const VOID *pool) +{ + if (pool == NULL) { + return LOS_NOK; + } + return ((LosMemPoolInfo *)pool)->poolSize; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsMemInfoPrint(VOID *pool) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + LOS_MEM_POOL_STATUS status = {0}; + + if (LOS_MemInfoGet(pool, &status) == LOS_NOK) { + 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"); + PRINTK("--------------- -------- ------- -------- " + "-------------- ------------- ------------ ------------\n"); + PRINTK("%-16p 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x 0x%-13x\n", + poolInfo->pool, poolInfo->poolSize, status.uwTotalUsedSize, + status.uwTotalFreeSize, status.uwMaxFreeNodeSize, status.uwUsedNodeNum, + status.uwFreeNodeNum, status.uwUsageWaterLine); + +#else + PRINTK("pool addr pool size used size free size " + "max free node size used node num free node num\n"); + PRINTK("--------------- -------- ------- -------- " + "-------------- ------------- ------------\n"); + PRINTK("%-16p 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n", + poolInfo->pool, poolInfo->poolSize, status.uwTotalUsedSize, + status.uwTotalFreeSize, status.uwMaxFreeNodeSize, status.uwUsedNodeNum, + status.uwFreeNodeNum); +#endif +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) +{ + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + LosMemDynNode *tmpNode = NULL; + UINT32 totalUsedSize = 0; + UINT32 totalFreeSize = 0; + UINT32 maxFreeNodeSize = 0; + UINT32 usedNodeNum = 0; + UINT32 freeNodeNum = 0; + UINT32 intSave; + + if (poolStatus == NULL) { + PRINT_ERR("can't use NULL addr to save info\n"); + return LOS_NOK; + } + + if ((poolInfo == NULL) || ((UINTPTR)pool != (UINTPTR)poolInfo->pool)) { + PRINT_ERR("wrong mem pool addr: %p, line:%d\n", poolInfo, __LINE__); + return LOS_NOK; + } + + tmpNode = (LosMemDynNode *)OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = (LosMemDynNode *)OS_MEM_ALIGN(tmpNode, OS_MEM_ALIGN_SIZE); + + if (!OS_MEM_MAGIC_VALID(tmpNode->selfNode.freeNodeInfo.pstPrev)) { + PRINT_ERR("wrong mem pool addr: %p\n, line:%d", poolInfo, __LINE__); + return LOS_NOK; } - else - { - PRINTK("%s: wrong para, setting failed !! \n", __FUNCTION__); - return OS_ERRNO_MEMCHECK_WRONG_LEVEL; + + MEM_LOCK(intSave); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (!OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.sizeAndFlag)) { + ++freeNodeNum; + totalFreeSize += OS_MEM_NODE_GET_SIZE(tmpNode->selfNode.sizeAndFlag); + if (maxFreeNodeSize < OS_MEM_NODE_GET_SIZE(tmpNode->selfNode.sizeAndFlag)) { + maxFreeNodeSize = OS_MEM_NODE_GET_SIZE(tmpNode->selfNode.sizeAndFlag); + } + } else { + ++usedNodeNum; + totalUsedSize += OS_MEM_NODE_GET_SIZE(tmpNode->selfNode.sizeAndFlag); + } } - ucCheckMemLevel = ucLevel; + + MEM_UNLOCK(intSave); + + poolStatus->uwTotalUsedSize = totalUsedSize; + poolStatus->uwTotalFreeSize = totalFreeSize; + poolStatus->uwMaxFreeNodeSize = maxFreeNodeSize; + poolStatus->uwUsedNodeNum = usedNodeNum; + poolStatus->uwFreeNodeNum = freeNodeNum; +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + poolStatus->uwUsageWaterLine = poolInfo->poolWaterLine; +#endif return LOS_OK; } -LITE_OS_SEC_TEXT_MINOR UINT8 LOS_MemCheckLevelGet(VOID) +STATIC INLINE VOID OsShowFreeNode(UINT32 index, UINT32 length, const UINT32 *countNum) { - return ucCheckMemLevel; + UINT32 count = 0; + PRINTK("\n block size: "); + while (count < length) { + PRINTK("2^%-5u", (index + OS_MIN_MULTI_DLNK_LOG2 + count)); + count++; + } + PRINTK("\n node number: "); + count = 0; + while (count < length) { + PRINTK(" %-5u", countNum[count + index]); + count++; + } } -#endif /* OS_MEM_CHECK_DEBUG */ +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemFreeNodeShow(VOID *pool) +{ + LOS_DL_LIST *listNodeHead = NULL; + LosMultipleDlinkHead *headAddr = (LosMultipleDlinkHead *)((UINTPTR)pool + sizeof(LosMemPoolInfo)); + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT32 linkHeadIndex; + UINT32 countNum[OS_MULTI_DLNK_NUM] = { 0 }; + UINT32 intSave; + + if ((poolInfo == NULL) || ((UINTPTR)pool != (UINTPTR)poolInfo->pool)) { + PRINT_ERR("wrong mem pool addr: %p, line:%d\n", poolInfo, __LINE__); + return LOS_NOK; + } + + PRINTK("\n ************************ left free node number**********************"); + MEM_LOCK(intSave); + + for (linkHeadIndex = 0; linkHeadIndex <= (OS_MULTI_DLNK_NUM - 1); + linkHeadIndex++) { + listNodeHead = headAddr->listHead[linkHeadIndex].pstNext; + while (listNodeHead != &(headAddr->listHead[linkHeadIndex])) { + listNodeHead = listNodeHead->pstNext; + countNum[linkHeadIndex]++; + } + } + + linkHeadIndex = 0; + while (linkHeadIndex < OS_MULTI_DLNK_NUM) { + if (linkHeadIndex + COLUMN_NUM < OS_MULTI_DLNK_NUM) { + OsShowFreeNode(linkHeadIndex, COLUMN_NUM, countNum); + linkHeadIndex += COLUMN_NUM; + } else { + OsShowFreeNode(linkHeadIndex, (OS_MULTI_DLNK_NUM - 1 - linkHeadIndex), countNum); + break; + } + } + + MEM_UNLOCK(intSave); + PRINTK("\n ********************************************************************\n\n"); -LITE_OS_SEC_TEXT_MINOR UINT32 osMemSysNodeCheck(VOID *pDst, VOID *pSrc, UINT32 uwLength, UINT8 ucPos) + return LOS_OK; +} +#ifdef LOSCFG_MEM_LEAKCHECK +LITE_OS_SEC_TEXT_MINOR VOID OsMemUsedNodeShow(VOID *pool) { -#ifdef OS_MEM_CHECK_DEBUG - UINT32 uwRet = 0; - UINT32 uwTotalSize=0; - UINT32 uwAvailSize=0; + LosMemDynNode *tmpNode = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT32 intSave; + UINT32 count; - if (ucPos == 0) /* if this func was called by memset */ - { - uwRet = LOS_MemNodeSizeCheck(m_aucSysMem0, pDst, &uwTotalSize, &uwAvailSize); - if (uwRet == LOS_OK && uwLength > uwAvailSize) - { - PRINT_ERR("---------------------------------------------\n");/*lint !e515*/ - PRINT_ERR("memset: dst inode uwAvailSize is not enough" - " uwAvailSize = 0x%x uwLength = 0x%x\n", uwAvailSize, uwLength);/*lint !e515 !e516*/ - osBackTrace(); - PRINT_ERR("---------------------------------------------\n");/*lint !e515*/ - return LOS_NOK; + if (pool == NULL) { + PRINTK("input param is NULL\n"); + return; + } + if (LOS_MemIntegrityCheck(pool)) { + PRINTK("LOS_MemIntegrityCheck error\n"); + return; + } + MEM_LOCK(intSave); +#ifdef __LP64__ + PRINTK("node "); +#else + PRINTK("node "); +#endif + for (count = 0; count < LOS_RECORD_LR_CNT; count++) { +#ifdef __LP64__ + PRINTK(" LR[%u] ", count); +#else + PRINTK(" LR[%u] ", count); +#endif + } + PRINTK("\n"); + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < OS_MEM_END_NODE(pool, poolInfo->poolSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->selfNode.sizeAndFlag)) { +#ifdef __LP64__ + PRINTK("%018p: ", tmpNode); +#else + PRINTK("%010p: ", tmpNode); +#endif + for (count = 0; count < LOS_RECORD_LR_CNT; count++) { +#ifdef __LP64__ + PRINTK(" %018p ", tmpNode->selfNode.linkReg[count]); +#else + PRINTK(" %010p ", tmpNode->selfNode.linkReg[count]); +#endif + } + PRINTK("\n"); + } + } + MEM_UNLOCK(intSave); + return; +} +#endif + +#ifdef LOSCFG_BASE_MEM_NODE_SIZE_CHECK + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemNodeSizeCheck(VOID *pool, VOID *ptr, UINT32 *totalSize, UINT32 *availSize) +{ + const VOID *head = NULL; + LosMemPoolInfo *poolInfo = (LosMemPoolInfo *)pool; + UINT8 *endPool = NULL; + + if (g_memCheckLevel == LOS_MEM_CHECK_LEVEL_DISABLE) { + return LOS_ERRNO_MEMCHECK_DISABLED; + } + + if ((pool == NULL) || (ptr == NULL) || (totalSize == NULL) || (availSize == NULL)) { + return LOS_ERRNO_MEMCHECK_PARA_NULL; + } + + endPool = (UINT8 *)pool + poolInfo->poolSize; + if (!(OS_MEM_MIDDLE_ADDR_OPEN_END(pool, ptr, endPool))) { + return LOS_ERRNO_MEMCHECK_OUTSIDE; + } + + if (g_memCheckLevel == LOS_MEM_CHECK_LEVEL_HIGH) { + head = OsMemFindNodeCtrl(pool, ptr); + if ((head == NULL) || + (OS_MEM_NODE_GET_SIZE(((LosMemDynNode *)head)->selfNode.sizeAndFlag) < ((UINTPTR)ptr - (UINTPTR)head))) { + return LOS_ERRNO_MEMCHECK_NO_HEAD; + } + *totalSize = OS_MEM_NODE_GET_SIZE(((LosMemDynNode *)head)->selfNode.sizeAndFlag - sizeof(LosMemDynNode)); + *availSize = OS_MEM_NODE_GET_SIZE(((LosMemDynNode *)head)->selfNode.sizeAndFlag - ((UINTPTR)ptr - + (UINTPTR)head)); + return LOS_OK; + } + if (g_memCheckLevel == LOS_MEM_CHECK_LEVEL_LOW) { + if (ptr != (VOID *)OS_MEM_ALIGN(ptr, OS_MEM_ALIGN_SIZE)) { + return LOS_ERRNO_MEMCHECK_NO_HEAD; + } + head = (const VOID *)((UINTPTR)ptr - sizeof(LosMemDynNode)); + if (OS_MEM_MAGIC_VALID(((LosMemDynNode *)head)->selfNode.freeNodeInfo.pstPrev)) { + *totalSize = OS_MEM_NODE_GET_SIZE(((LosMemDynNode *)head)->selfNode.sizeAndFlag - sizeof(LosMemDynNode)); + *availSize = OS_MEM_NODE_GET_SIZE(((LosMemDynNode *)head)->selfNode.sizeAndFlag - sizeof(LosMemDynNode)); + return LOS_OK; + } else { + return LOS_ERRNO_MEMCHECK_NO_HEAD; + } + } + + return LOS_ERRNO_MEMCHECK_WRONG_LEVEL; +} + +/* + * Description : get a pool's memCtrl + * Input : ptr -- point to source ptr + * Return : search forward for ptr'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 const VOID *OsMemFindNodeCtrl(const VOID *pool, const VOID *ptr) +{ + const VOID *head = ptr; + + if (ptr == NULL) { + return NULL; + } + + head = (const VOID *)OS_MEM_ALIGN(head, OS_MEM_ALIGN_SIZE); + while (!OS_MEM_MAGIC_VALID(((LosMemDynNode *)head)->selfNode.freeNodeInfo.pstPrev)) { + head = (const VOID *)((UINT8 *)head - sizeof(CHAR *)); + if (head <= pool) { + return NULL; } } - else if (ucPos == 1) /* if this func was called by memcpy */ - { - uwRet = LOS_MemNodeSizeCheck(m_aucSysMem0, pDst, &uwTotalSize, &uwAvailSize); - if (uwRet == LOS_OK && uwLength > uwAvailSize) - { - PRINT_ERR("---------------------------------------------\n");/*lint !e515*/ - PRINT_ERR("memcpy: dst inode uwAvailSize is not enough" - " uwAvailSize = 0x%x uwLength = 0x%x\n", uwAvailSize, uwLength);/*lint !e515 !e516*/ - osBackTrace(); - PRINT_ERR("---------------------------------------------\n");/*lint !e515*/ + return head; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemCheckLevelSet(UINT8 checkLevel) +{ + if (checkLevel == LOS_MEM_CHECK_LEVEL_LOW) { + PRINTK("%s: LOS_MEM_CHECK_LEVEL_LOW \n", __FUNCTION__); + } else if (checkLevel == LOS_MEM_CHECK_LEVEL_HIGH) { + PRINTK("%s: LOS_MEM_CHECK_LEVEL_HIGH \n", __FUNCTION__); + } else if (checkLevel == LOS_MEM_CHECK_LEVEL_DISABLE) { + PRINTK("%s: LOS_MEM_CHECK_LEVEL_DISABLE \n", __FUNCTION__); + } else { + PRINTK("%s: wrong param, setting failed !! \n", __FUNCTION__); + return LOS_ERRNO_MEMCHECK_WRONG_LEVEL; + } + g_memCheckLevel = checkLevel; + return LOS_OK; +} + +LITE_OS_SEC_TEXT_MINOR UINT8 LOS_MemCheckLevelGet(VOID) +{ + return g_memCheckLevel; +} + + +UINT32 OsMemSysNodeCheck(VOID *dstAddr, VOID *srcAddr, UINT32 nodeLength, UINT8 pos) +{ + UINT32 ret; + UINT32 totalSize = 0; + UINT32 availSize = 0; + UINT8 *pool = m_aucSysMem1; +#ifdef LOSCFG_EXC_INTERACTION + if ((UINTPTR)dstAddr < ((UINTPTR)m_aucSysMem0 + g_excInteractMemSize)) { + pool = m_aucSysMem0; + } +#endif + if (pos == 0) { /* if this func was called by memset */ + ret = LOS_MemNodeSizeCheck(pool, dstAddr, &totalSize, &availSize); + if ((ret == LOS_OK) && (nodeLength > availSize)) { + PRINT_ERR("---------------------------------------------\n"); + PRINT_ERR("memset: dst inode availSize is not enough" + " availSize = 0x%x, memset length = 0x%x\n", availSize, nodeLength); + OsBackTrace(); + PRINT_ERR("---------------------------------------------\n"); return LOS_NOK; } - uwRet = LOS_MemNodeSizeCheck(m_aucSysMem0, pSrc, &uwTotalSize, &uwAvailSize); - if (uwRet == LOS_OK && uwLength > uwAvailSize) - { - PRINT_ERR("---------------------------------------------\n");/*lint !e515*/ - PRINT_ERR("memcpy: src inode uwAvailSize is not enough" - " uwAvailSize = 0x%x uwLength = 0x%x\n", uwAvailSize, uwLength);/*lint !e515 !e516*/ - osBackTrace(); - PRINT_ERR("---------------------------------------------\n");/*lint !e515*/ + } else if (pos == 1) { /* if this func was called by memcpy */ + ret = LOS_MemNodeSizeCheck(pool, dstAddr, &totalSize, &availSize); + if ((ret == LOS_OK) && (nodeLength > availSize)) { + PRINT_ERR("---------------------------------------------\n"); + PRINT_ERR("memcpy: dst inode availSize is not enough" + " availSize = 0x%x, memcpy length = 0x%x\n", availSize, nodeLength); + OsBackTrace(); + PRINT_ERR("---------------------------------------------\n"); return LOS_NOK; } - } +#ifdef LOSCFG_EXC_INTERACTION + if ((UINTPTR)srcAddr < ((UINTPTR)m_aucSysMem0 + g_excInteractMemSize)) { + pool = m_aucSysMem0; + } else { + pool = m_aucSysMem1; + } #endif + ret = LOS_MemNodeSizeCheck(pool, srcAddr, &totalSize, &availSize); + if ((ret == LOS_OK) && (nodeLength > availSize)) { + PRINT_ERR("---------------------------------------------\n"); + PRINT_ERR("memcpy: src inode availSize is not enough" + " availSize = 0x%x, memcpy length = 0x%x\n", + availSize, nodeLength); + OsBackTrace(); + PRINT_ERR("---------------------------------------------\n"); + return LOS_NOK; + } + } + return LOS_OK; +} +#endif /* LOSCFG_BASE_MEM_NODE_SIZE_CHECK */ + +#ifdef LOSCFG_MEM_MUL_MODULE +STATIC INLINE UINT32 OsMemModCheck(UINT32 moduleID) +{ + if (moduleID > MEM_MODULE_MAX) { + PRINT_ERR("error module ID input!\n"); + return LOS_NOK; + } return LOS_OK; } +STATIC INLINE VOID *OsMemPtrToNode(VOID *ptr) +{ + UINT32 gapSize; + + if ((UINTPTR)ptr & (OS_MEM_ALIGN_SIZE - 1)) { + PRINT_ERR("[%s:%d]ptr:%p not align by 4byte\n", __FUNCTION__, __LINE__, ptr); + return NULL; + } + + gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32))); + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); + if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE))) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + + ptr = (VOID *)((UINTPTR)ptr - gapSize); + } + + return (VOID *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); +} + +STATIC INLINE UINT32 OsMemNodeSizeGet(VOID *ptr) +{ + LosMemDynNode *node = (LosMemDynNode *)OsMemPtrToNode(ptr); + if (node == NULL) { + return 0; + } + + return OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag); +} + +VOID *LOS_MemMalloc(VOID *pool, UINT32 size, UINT32 moduleID) +{ + UINT32 intSave; + VOID *ptr = NULL; + VOID *node = NULL; + if (OsMemModCheck(moduleID) == LOS_NOK) { + return NULL; + } + ptr = LOS_MemAlloc(pool, size); + if (ptr != NULL) { + MEM_LOCK(intSave); + g_moduleMemUsedSize[moduleID] += OsMemNodeSizeGet(ptr); + node = OsMemPtrToNode(ptr); + if (node != NULL) { + OS_MEM_MODID_SET(node, moduleID); + } + MEM_UNLOCK(intSave); + } + return ptr; +} + +VOID *LOS_MemMallocAlign(VOID *pool, UINT32 size, UINT32 boundary, UINT32 moduleID) +{ + UINT32 intSave; + VOID *ptr = NULL; + VOID *node = NULL; + if (OsMemModCheck(moduleID) == LOS_NOK) { + return NULL; + } + ptr = LOS_MemAllocAlign(pool, size, boundary); + if (ptr != NULL) { + MEM_LOCK(intSave); + g_moduleMemUsedSize[moduleID] += OsMemNodeSizeGet(ptr); + node = OsMemPtrToNode(ptr); + if (node != NULL) { + OS_MEM_MODID_SET(node, moduleID); + } + MEM_UNLOCK(intSave); + } + return ptr; +} + +UINT32 LOS_MemMfree(VOID *pool, VOID *ptr, UINT32 moduleID) +{ + UINT32 intSave; + UINT32 ret; + UINT32 size; + LosMemDynNode *node = NULL; + + if ((OsMemModCheck(moduleID) == LOS_NOK) || (ptr == NULL) || (pool == NULL)) { + return LOS_NOK; + } + + node = (LosMemDynNode *)OsMemPtrToNode(ptr); + if (node == NULL) { + return LOS_NOK; + } + + size = OS_MEM_NODE_GET_SIZE(node->selfNode.sizeAndFlag); + + if (moduleID != OS_MEM_MODID_GET(node)) { + PRINT_ERR("node[%p] alloced in module %lu, but free in module %u\n node's taskID: 0x%x\n", + ptr, OS_MEM_MODID_GET(node), moduleID, OS_MEM_TASKID_GET(node)); + moduleID = OS_MEM_MODID_GET(node); + } + + ret = LOS_MemFree(pool, ptr); + if (ret == LOS_OK) { + MEM_LOCK(intSave); + g_moduleMemUsedSize[moduleID] -= size; + MEM_UNLOCK(intSave); + } + return ret; +} + +VOID *LOS_MemMrealloc(VOID *pool, VOID *ptr, UINT32 size, UINT32 moduleID) +{ + VOID *newPtr = NULL; + UINT32 oldNodeSize; + UINT32 intSave; + LosMemDynNode *node = NULL; + UINT32 oldModuleID = moduleID; + + if ((OsMemModCheck(moduleID) == LOS_NOK) || (pool == NULL)) { + return NULL; + } + + if (ptr == NULL) { + return LOS_MemMalloc(pool, size, moduleID); + } + + node = (LosMemDynNode *)OsMemPtrToNode(ptr); + if (node == NULL) { + return NULL; + } + + if (moduleID != OS_MEM_MODID_GET(node)) { + PRINT_ERR("a node[%p] alloced in module %lu, but realloc in module %u\n node's taskID: %lu\n", + ptr, OS_MEM_MODID_GET(node), moduleID, OS_MEM_TASKID_GET(node)); + oldModuleID = OS_MEM_MODID_GET(node); + } + + if (size == 0) { + (VOID)LOS_MemMfree(pool, ptr, oldModuleID); + return NULL; + } + + oldNodeSize = OsMemNodeSizeGet(ptr); + newPtr = LOS_MemRealloc(pool, ptr, size); + if (newPtr != NULL) { + MEM_LOCK(intSave); + g_moduleMemUsedSize[moduleID] += OsMemNodeSizeGet(newPtr); + g_moduleMemUsedSize[oldModuleID] -= oldNodeSize; + node = (LosMemDynNode *)OsMemPtrToNode(newPtr); + OS_MEM_MODID_SET(node, moduleID); + MEM_UNLOCK(intSave); + } + return newPtr; +} + +UINT32 LOS_MemMusedGet(UINT32 moduleID) +{ + if (OsMemModCheck(moduleID) == LOS_NOK) { + return OS_NULL_INT; + } + return g_moduleMemUsedSize[moduleID]; +} +#endif #ifdef __cplusplus #if __cplusplus diff --git a/kernel/base/mem/bestfit/los_memory.inc b/kernel/base/mem/bestfit/los_memory.inc deleted file mode 100644 index cc3e7c823..000000000 --- a/kernel/base/mem/bestfit/los_memory.inc +++ /dev/null @@ -1,79 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MEMORY_INC -#define _LOS_MEMORY_INC - -#include "los_memory.ph" -#include "los_multipledlinkhead.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#define OS_MEM_ALIGN(p, alignSize) (((unsigned int)(p) + alignSize -1) &(~ (alignSize -1))) -#define OS_MEM_NODE_HEAD_SIZE sizeof(LOS_MEM_DYN_NODE) -#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_EXC_ERR_NODE_RANGE 0x40 - -#define OS_MEM_NODE_GET_ALIGNED_FLAG(uwSizeAndFlag) ((uwSizeAndFlag) & OS_MEM_NODE_ALIGNED_FLAG) -#define OS_MEM_NODE_SET_ALIGNED_FLAG(uwSizeAndFlag) (uwSizeAndFlag = ((uwSizeAndFlag) | OS_MEM_NODE_ALIGNED_FLAG)) -#define OS_MEM_NODE_GET_ALIGNED_GAPSIZE(uwSizeAndFlag) ((uwSizeAndFlag) & (~OS_MEM_NODE_ALIGNED_FLAG)) -#define OS_MEM_NODE_GET_USED_FLAG(uwSizeAndFlag) ((uwSizeAndFlag) & OS_MEM_NODE_USED_FLAG) -#define OS_MEM_NODE_SET_USED_FLAG(uwSizeAndFlag) (uwSizeAndFlag = ((uwSizeAndFlag) | OS_MEM_NODE_USED_FLAG)) -#define OS_MEM_NODE_GET_SIZE(uwSizeAndFlag) ((uwSizeAndFlag) & (~OS_MEM_NODE_USED_FLAG)) -#define OS_MEM_IS_NODE_NEXT_EXIST(pstNode, pstPoolInfo) (((UINT32)(pstNode) + (pstNode)->uwSizeAndFlag) < ((UINT32)(pstPoolInfo) + (pstPoolInfo)->uwPoolSize)) -#define OS_MEM_HEAD(pPool, uwSize) OS_DLnkHead(OS_MEM_HEAD_ADDR(pPool), uwSize) -#define OS_MEM_HEAD_ADDR(pPool) ((VOID *)((UINT32)(pPool) + sizeof(LOS_MEM_POOL_INFO))) -#define OS_MEM_NEXT_NODE(pstNode) ((LOS_MEM_DYN_NODE *)((UINT8 *)(pstNode) + OS_MEM_NODE_GET_SIZE((pstNode)->uwSizeAndFlag))) -#define OS_MEM_FIRST_NODE(pPool) ((LOS_MEM_DYN_NODE *) ((UINT8 *)OS_MEM_HEAD_ADDR(pPool) + OS_DLNK_HEAD_SIZE)) -#define OS_MEM_END_NODE(pPool, uwSize) ((LOS_MEM_DYN_NODE *)(((UINT8 *)(pPool) + (uwSize)) - 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 *)((UINT32)(&(value)) ^ 0xffffffff) -#define OS_MEM_MAGIC_VALID(value) ((((UINT32)(value)) ^ ((UINT32)(&(value)))) == 0xffffffff) - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_MEMORY_INC */ diff --git a/kernel/base/mem/bestfit/los_multipledlinkhead.c b/kernel/base/mem/bestfit/los_multipledlinkhead.c index f1098ee5e..ad5ac1c90 100644 --- a/kernel/base/mem/bestfit/los_multipledlinkhead.c +++ b/kernel/base/mem/bestfit/los_multipledlinkhead.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Mem Module Implementation * 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 @@ -22,87 +22,56 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_multipledlinkhead.inc" +#include "los_multipledlinkhead_pri.h" +#include "los_bitmap.h" -#define IF_ELSE(mask, if_do, else_do) if(uwSize & (mask)){if_do}else{else_do} -// cppcheck-suppress * -#define BIT_NUM(num) return num; -#define BIT_NONE BIT_NUM(0xfffffff) +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE UINT32 LOS_Log2(UINT32 uwSize) +STATIC INLINE UINT32 OsLog2(UINT32 size) { - IF_ELSE(0x80000000, \ - BIT_NONE, \ - IF_ELSE(0x7fff0000, \ - IF_ELSE(0x7f000000,\ - IF_ELSE(0x70000000,\ - IF_ELSE(0x40000000,\ - BIT_NUM(30),\ - IF_ELSE(0x20000000, BIT_NUM(29), BIT_NUM(28))), \ - IF_ELSE(0x0c000000, \ - IF_ELSE(0x08000000, BIT_NUM(27), BIT_NUM(26)), \ - IF_ELSE(0x02000000, BIT_NUM(25), BIT_NUM(24)))), \ - IF_ELSE(0x00f00000, \ - IF_ELSE(0x00c00000, \ - IF_ELSE(0x00800000, BIT_NUM(23), BIT_NUM(22)), \ - IF_ELSE(0x00200000, BIT_NUM(21), BIT_NUM(20))), \ - IF_ELSE(0x000c0000,\ - IF_ELSE(0x00080000, BIT_NUM(19), BIT_NUM(18)), \ - IF_ELSE(0x00020000, BIT_NUM(17), BIT_NUM(16))))), \ - IF_ELSE(0x0000ff00, \ - IF_ELSE(0x0000f000, \ - IF_ELSE(0x0000c000, \ - IF_ELSE(0x00008000, BIT_NUM(15), BIT_NUM(14)), \ - IF_ELSE(0x00002000, BIT_NUM(13), BIT_NUM(12))), \ - IF_ELSE(0x00000c00, \ - IF_ELSE(0x00000800, BIT_NUM(11), BIT_NUM(10)), \ - IF_ELSE(0x00000200, BIT_NUM(9), BIT_NUM(8)))), \ - IF_ELSE(0x000000f0, \ - IF_ELSE(0x000000c0, \ - IF_ELSE(0x00000080, BIT_NUM(7), BIT_NUM(6)), \ - IF_ELSE(0x00000020, BIT_NUM(5), BIT_NUM(4))), \ - IF_ELSE(0x0000000c, \ - IF_ELSE(0x00000008, BIT_NUM(3), BIT_NUM(2)), \ - IF_ELSE(0x00000002, BIT_NUM(1), BIT_NUM(0)))))))\ - + return (size > 0) ? (UINT32)LOS_HighBitGet(size) : 0; } -LITE_OS_SEC_TEXT_INIT VOID LOS_DLnkInitMultiHead(VOID *pHeadAddr) +LITE_OS_SEC_TEXT_INIT VOID OsDLnkInitMultiHead(VOID *headAddr) { - LOS_MULTIPLE_DLNK_HEAD *pstHead = (LOS_MULTIPLE_DLNK_HEAD *)pHeadAddr; - LOS_DL_LIST *pstListHead = pstHead->stListHead; - UINT32 uwIdx; + LosMultipleDlinkHead *dlinkHead = (LosMultipleDlinkHead *)headAddr; + LOS_DL_LIST *listNodeHead = dlinkHead->listHead; + UINT32 index; - for (uwIdx = 0; uwIdx < OS_MULTI_DLNK_NUM; ++uwIdx, ++pstListHead) - { - LOS_ListInit(pstListHead); + for (index = 0; index < OS_MULTI_DLNK_NUM; ++index, ++listNodeHead) { + LOS_ListInit(listNodeHead); } } -LITE_OS_SEC_TEXT_MINOR LOS_DL_LIST *LOS_DLnkMultiHead(VOID *pHeadAddr, UINT32 uwSize) +LITE_OS_SEC_TEXT_MINOR LOS_DL_LIST *OsDLnkMultiHead(VOID *headAddr, UINT32 size) { - LOS_MULTIPLE_DLNK_HEAD *pstHead = (LOS_MULTIPLE_DLNK_HEAD *)pHeadAddr; - UINT32 uwIdx = LOS_Log2(uwSize); - - if(uwIdx > OS_MAX_MULTI_DLNK_LOG2) - { - return (LOS_DL_LIST *)NULL; + LosMultipleDlinkHead *dlinkHead = (LosMultipleDlinkHead *)headAddr; + UINT32 index = OsLog2(size); + if (index > OS_MAX_MULTI_DLNK_LOG2) { + return NULL; + } else if (index <= OS_MIN_MULTI_DLNK_LOG2) { + index = OS_MIN_MULTI_DLNK_LOG2; } - if(uwIdx <= OS_MIN_MULTI_DLNK_LOG2) - { - uwIdx = OS_MIN_MULTI_DLNK_LOG2; - } + return dlinkHead->listHead + (index - OS_MIN_MULTI_DLNK_LOG2); +} - return pstHead->stListHead + (uwIdx - OS_MIN_MULTI_DLNK_LOG2); +#ifdef __cplusplus +#if __cplusplus } +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/mem/bestfit/los_multipledlinkhead.inc b/kernel/base/mem/bestfit/los_multipledlinkhead.inc deleted file mode 100644 index 32096a2c7..000000000 --- a/kernel/base/mem/bestfit/los_multipledlinkhead.inc +++ /dev/null @@ -1,40 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MULTIPLE_DLINK_HEAD_INC -#define _LOS_MULTIPLE_DLINK_HEAD_INC - -#include "los_multipledlinkhead.ph" - -#endif /* _LOS_MULTIPLE_DLINK_HEAD_INC */ diff --git a/kernel/base/mem/bestfit_little/Makefile b/kernel/base/mem/bestfit_little/Makefile deleted file mode 100644 index 64a898289..000000000 --- a/kernel/base/mem/bestfit_little/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -objs-y += los_membox.o -objs-y += los_memcheck.o -objs-y += los_memory.o -objs-y += los_heap.o diff --git a/kernel/base/mem/bestfit_little/los_heap.c b/kernel/base/mem/bestfit_little/los_heap.c index 04db4fed3..f38b8cd6a 100644 --- a/kernel/base/mem/bestfit_little/los_heap.c +++ b/kernel/base/mem/bestfit_little/los_heap.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Mem Module Implementation * 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 @@ -22,396 +22,504 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@defgroup los_heap Heap - * @ingroup kernel - */ -#include -#include -#include -#include -#include - -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) -#include "los_memstat.inc" -#endif - -LITE_OS_SEC_DATA_INIT static UINT32 g_uwAllocCount = 0; -LITE_OS_SEC_DATA_INIT static UINT32 g_uwFreeCount = 0; + * --------------------------------------------------------------------------- */ + +#include "los_heap_pri.h" +#include "string.h" +#include "securec.h" +#include "los_hwi.h" +#include "los_config.h" +#include "los_typedef.h" +#include "los_task_pri.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +static UINT32 g_memAllocCount = 0; +static UINT32 g_memFreeCount = 0; #if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) -LITE_OS_SEC_DATA_INIT static UINT32 g_uwCurHeapUsed = 0; -LITE_OS_SEC_DATA_INIT static UINT32 g_uwMaxHeapUsed = 0; +static UINT32 g_memCurHeapUsed = 0; +static UINT32 g_memMaxHeapUsed = 0; #endif #define HEAP_CAST(t, exp) ((t)(exp)) #define HEAP_ALIGN 4 -#define ALIGNE(sz) (sz + HEAP_ALIGN - 1) & ~(HEAP_ALIGN - 1) - -/***************************************************************************** - Function : osHeapPrvGetNext - Description : look up the next memory node according to one memory node in the memory block list. - Input : struct LOS_HEAP_MANAGER *pHeapMan --- Pointer to the manager,to distinguish heap - struct LOS_HEAP_NODE* node --- Size of memory in bytes to allocate - Output : None - Return : Pointer to next memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT struct LOS_HEAP_NODE* osHeapPrvGetNext(struct LOS_HEAP_MANAGER *pstHeapMan, struct LOS_HEAP_NODE* pstNode) +#define MALLOC_MAXSIZE (0xFFFFFFFF - HEAP_ALIGN + 1) +/* + * Description : look up the next memory node according to one memory node in the memory block list. + * Input : struct LosMemPoolInfo *heapMan --- Pointer to the manager,to distinguish heap + * struct LosHeapNode *node --- Size of memory in bytes to allocate + * Return : Pointer to next memory node + */ +struct LosHeapNode* OsHeapPrvGetNext(const LosMemPoolInfo *heapMan, struct LosHeapNode *node) { - return (pstHeapMan->pstTail == pstNode) ? NULL : (struct LOS_HEAP_NODE*)(pstNode->ucData + pstNode->uwSize); + return (heapMan->tail == node) ? NULL : (struct LosHeapNode *)(UINTPTR)(node->data + node->size); } -/***************************************************************************** - Function : osHeapInit - Description : To initialize the heap memory and get the begin address and size of heap memory,then initialize LOS_HEAP_MANAGER . - Input : struct LOS_HEAP_MANAGER *pHeapMan --- Pointer to the manager,to distinguish heap - VOID *pPool --- begin address of the heap memory pool - UITN32 uwSz --- size of the heap memory pool - Output : None - Return : 1:success 0:error -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT BOOL osHeapInit(VOID *pPool, UINT32 uwSz) +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +VOID OsHeapSetTaskId(struct LosHeapNode *node) { - struct LOS_HEAP_NODE* pstNode; - struct LOS_HEAP_MANAGER *pstHeapMan = HEAP_CAST(struct LOS_HEAP_MANAGER *, pPool); - - if (!pstHeapMan || (uwSz <= (sizeof(struct LOS_HEAP_NODE) + sizeof(struct LOS_HEAP_MANAGER)))) + if ((OsCurrTaskGet() != NULL) && OS_INT_INACTIVE) { + /* + * after OsTaskInit, OsCurrTaskGet() is not null, but id is the same + * as (LOSCFG_BASE_CORE_TSK_LIMIT + 1), so it will be recorded into + * the last one of the array. + */ + node->taskID = LOS_CurTaskIDGet(); + } else { + node->taskID = TASK_BLOCK_NUM - 1; + } +} +#endif +/* + * Description : To initialize the heap memory and get the begin address and size of heap memory, + * then initialize LosMemPoolInfo. + * Input : VOID *pool --- begin address of the heap memory pool + * UITN32 size --- size of the heap memory pool + * Return : 1:success 0:error + */ +BOOL OsHeapInit(VOID *pool, UINT32 size) +{ +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + UINT32 memStatsSize; +#endif + struct LosHeapNode *node = NULL; + LosMemPoolInfo *heapMan = HEAP_CAST(LosMemPoolInfo *, pool); + if ((heapMan == NULL) || (size <= (sizeof(struct LosHeapNode) + sizeof(LosMemPoolInfo)))) { return FALSE; + } - memset(pPool, 0, uwSz); + /* Ignore the return code when matching CSEC rule 6.6(2). */ + (VOID)memset_s(pool, size, 0, size); - pstHeapMan->uwSize = uwSz; + heapMan->size = size; - pstNode = pstHeapMan->pstHead = (struct LOS_HEAP_NODE*)((UINT8*)pPool + sizeof(struct LOS_HEAP_MANAGER)); + node = heapMan->head = (struct LosHeapNode *)((UINT8*)pool + sizeof(LosMemPoolInfo)); - pstHeapMan->pstTail = pstNode; + heapMan->tail = node; - pstNode->uwUsed = 0; - pstNode->pstPrev = NULL; - pstNode->uwSize = uwSz - sizeof(struct LOS_HEAP_NODE) - sizeof(struct LOS_HEAP_MANAGER); + node->used = 0; + node->prev = NULL; + node->size = size - sizeof(struct LosHeapNode) - sizeof(LosMemPoolInfo); +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + if (size > ((1U << (SIZE_BITS)) - 1)) { + PRINT_ERR("heap node size bits too small!\n"); + } + + memStatsSize = sizeof(TaskMemUsedInfo) * TASK_BLOCK_NUM; + (VOID)memset_s(heapMan->memStats, memStatsSize, 0, memStatsSize); +#endif return TRUE; } -/***************************************************************************** - Function : osHeapAlloc - Description : To alloc memory block from the heap memory poll - Input : VOID *pPool --- Pointer to the manager,to distinguish heap - UINT32 uwSz --- size of the heap memory pool - Output : None - Return : NULL:error other value:the address of the memory we alloced -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID* osHeapAlloc(VOID *pPool, UINT32 uwSz) +/* + * Description : update used size + * Input : size --- alloc memory size + * ptr --- memory chunk + */ +VOID OsHeapUpdateUsedSize(UINT32 size, const VOID *ptr) { - struct LOS_HEAP_NODE *pstNode, *pstT, *pstBest = NULL; - VOID* pRet = NULL; - UINT32 uvIntSave; +#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) + g_memCurHeapUsed += (size + sizeof(struct LosHeapNode)); + if (g_memCurHeapUsed > g_memMaxHeapUsed) { + g_memMaxHeapUsed = g_memCurHeapUsed; + } +#else + (VOID)size; +#endif - struct LOS_HEAP_MANAGER *pstHeapMan = HEAP_CAST(struct LOS_HEAP_MANAGER *, pPool); - if (!pstHeapMan) - { - return NULL; + if (ptr != NULL) { + g_memAllocCount++; } +} - uvIntSave = LOS_IntLock(); +STATIC VOID OsHeapSplitNode(struct LosHeapNode *best, UINT32 alignSize, LosMemPoolInfo *heapMan) +{ + /* hole divide into 2 */ + struct LosHeapNode *node = (struct LosHeapNode*)(UINTPTR)(best->data + alignSize); + struct LosHeapNode *next = NULL; + node->used = 0; + node->size = best->size - alignSize - sizeof(struct LosHeapNode); + node->prev = best; + + if (best != heapMan->tail) { + next = OsHeapPrvGetNext(heapMan, node); + if (next != NULL) { + next->prev = node; + } + } else { + heapMan->tail = node; + } - uwSz = ALIGNE(uwSz); - pstNode = pstHeapMan->pstTail; + best->size = alignSize; +} - while (pstNode) - { - if (!pstNode->uwUsed && pstNode->uwSize >= uwSz && (!pstBest || pstBest->uwSize > pstNode->uwSize)) - { - pstBest = pstNode; - if (pstBest->uwSize == uwSz) - { +/* + * Description : To alloc memory block from the heap memory poll + * Input : VOID *pool --- Pointer to the manager,to distinguish heap + * UINT32 size --- size of the heap memory pool + * Return : NULL:error, other value:the address of the memory we alloced + */ +VOID *OsHeapAlloc(VOID *pool, UINT32 size) +{ +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + UINT32 blockSize; +#endif + struct LosHeapNode *node = NULL; + struct LosHeapNode *best = NULL; + VOID *ptr = NULL; + UINT32 alignSize; + + LosMemPoolInfo *heapMan = HEAP_CAST(LosMemPoolInfo *, pool); + if ((heapMan == NULL) || (size > MALLOC_MAXSIZE)) { + return NULL; + } + + alignSize = ALIGNE(size); + node = heapMan->tail; + while (node != NULL) { + if ((node->used == 0) && (node->size >= alignSize) && + ((best == NULL) || (best->size > node->size))) { + best = node; + if (best->size == alignSize) { goto SIZE_MATCH; } } - pstNode = pstNode->pstPrev; + node = node->prev; } - if (!pstBest) /*alloc failed*/ - { - PRINT_ERR("there's not enough whole to alloc %x Bytes!\n",uwSz); - goto out; + /* alloc failed */ + if (best == NULL) { + PRINT_ERR("there's not enough whole to alloc 0x%x Bytes!\n", alignSize); + goto OUT; } - if (pstBest->uwSize - uwSz > sizeof(struct LOS_HEAP_NODE)) - { - /* hole divide into 2 */ - pstNode = (struct LOS_HEAP_NODE*)(pstBest->ucData + uwSz); - - pstNode->uwUsed = 0; - pstNode->uwSize = pstBest->uwSize - uwSz- sizeof(struct LOS_HEAP_NODE); - pstNode->pstPrev = pstBest; - - pstT = osHeapPrvGetNext(pstHeapMan, pstBest); - - if (pstT == NULL) - { - pstHeapMan->pstTail = pstNode; /* pstBest is tail */ - } - else - { - pstT->pstPrev = pstNode; - } - - pstBest->uwSize = uwSz; + if ((best->size - alignSize) > sizeof(struct LosHeapNode)) { + OsHeapSplitNode(best, alignSize, heapMan); } SIZE_MATCH: - pstBest->uwAlign = 0; - pstBest->uwUsed = 1; - pRet = pstBest->ucData; -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_ADD_USED(pstBest->uwSize); + best->align = 0; + best->used = 1; + ptr = best->data; + + OsHeapUpdateUsedSize(alignSize, ptr); +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + blockSize = sizeof(struct LosHeapNode) + best->size; + OsHeapSetTaskId(best); + OsTaskMemUsedInc(heapMan->memStats, blockSize, best->taskID); #endif -#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) - g_uwCurHeapUsed += (uwSz + sizeof(struct LOS_HEAP_NODE)); - if(g_uwCurHeapUsed > g_uwMaxHeapUsed) - { - g_uwMaxHeapUsed = g_uwCurHeapUsed; - } -#endif - - g_uwAllocCount++; - -out: - if (pstHeapMan->pstTail->uwSize < 1024) - osAlarmHeapInfo(pstHeapMan); - - LOS_IntRestore(uvIntSave); - - return pRet; +OUT: + return ptr; } -/***************************************************************************** - Function : osHeapAllocAlign - Description : To alloc memory block from the heap memory poll with - Input : VOID *pPool --- Pointer to the manager,to distinguish heap - UINT32 uwSz --- size of the heap memory pool - UINT32 uwBoundary --- boundary the heap needs align - Output : None - Return : NULL:error other value:the address of the memory we alloced -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID* osHeapAllocAlign(VOID *pPool, UINT32 uwSz, UINT32 uwBoundary) +/* + * Description : To alloc memory block from the heap memory poll with + * Input : VOID *pool --- Pointer to the manager,to distinguish heap + * UINT32 size --- size of the heap memory pool + * UINT32 boundary --- boundary the heap needs align + * Return : NULL:error, other value:the address of the memory we alloced + */ +VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { - VOID *pRet = NULL; - UINT32 uwUseSize; - UINT32 uwGapSize; - VOID *pAlignedPtr; + UINT32 useSize; + UINT32 gapSize; + VOID *ptr = NULL; + VOID *alignedPtr = NULL; - if ((NULL == pPool) || (0 == uwSz) || (uwBoundary < sizeof(VOID *)) || !IS_ALIGNED(uwBoundary)) - { + if ((pool == NULL) || (size == 0) || (boundary < sizeof(VOID *)) || !IS_ALIGNED(boundary, boundary)) { return NULL; } /* worst case is that the node happen to be 4 bytes ahead of the boundary */ - uwUseSize = uwSz + uwBoundary - sizeof(void*); - pRet = osHeapAlloc(pPool, uwUseSize); - - if (pRet) - { - pAlignedPtr = (VOID *)OS_MEM_ALIGN(pRet, uwBoundary); - if (pRet == pAlignedPtr) - { - goto out; + useSize = (size + boundary) - sizeof(VOID*); + if (useSize < size) { + return NULL; + } + + ptr = OsHeapAlloc(pool, useSize); + if (ptr != NULL) { + alignedPtr = (VOID *)(UINTPTR)OS_MEM_ALIGN(ptr, boundary); + if (ptr == alignedPtr) { + goto OUT; } - uwGapSize = (UINT32)pAlignedPtr - (UINT32)pRet; - OS_MEM_SET_ALIGN_FLAG(uwGapSize); - *((UINT32 *)((UINT32)pAlignedPtr - 4)) = uwGapSize; + gapSize = (UINTPTR)alignedPtr - (UINTPTR)ptr; + OS_MEM_SET_ALIGN_FLAG(gapSize); + *((UINT32 *)((UINTPTR)alignedPtr - (sizeof(UINTPTR) / sizeof(UINT8)))) = gapSize; - pRet = pAlignedPtr; + ptr = alignedPtr; } -out: - return pRet; +OUT: + return ptr; } -/***************************************************************************** - Function : osHeapFree - Description : To free the memory block from heap memory poll - Input : VOID* pPool --- Pointer to the manager,to distinguish heap - VOID* pPtr: --- the pointer of heap memory we want to free - Output : None - Return : 1:success 0:error -*****************************************************************************/ -LITE_OS_SEC_TEXT BOOL osHeapFree(VOID *pPool, VOID* pPtr) +STATIC VOID OsDoHeapFree(LosMemPoolInfo *heapMan, struct LosHeapNode *curNode) { - struct LOS_HEAP_NODE *pstNode, *pstT; - UINT32 uvIntSave, uwGapSize; - BOOL bRet = TRUE; - - struct LOS_HEAP_MANAGER *pstHeapMan = HEAP_CAST(struct LOS_HEAP_MANAGER *, pPool); + struct LosHeapNode *node = curNode; + struct LosHeapNode *next = NULL; + /* set to unused status */ + node->used = 0; - if (!pstHeapMan || !pPtr) - { - return LOS_NOK; +#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) + if (g_memCurHeapUsed >= (node->size + sizeof(struct LosHeapNode))) { + g_memCurHeapUsed -= (node->size + sizeof(struct LosHeapNode)); } +#endif - /* find the real ptr through gap size */ - uwGapSize = *((UINT32 *)((UINT32)pPtr - 4)); - if (OS_MEM_GET_ALIGN_FLAG(uwGapSize)) - { - uwGapSize = OS_MEM_GET_ALIGN_GAPSIZE(uwGapSize); - pPtr = (VOID *)((UINT32)pPtr - uwGapSize); +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) + OsTaskMemUsedDec(heapMan->memStats, sizeof(struct LosHeapNode) + node->size, node->taskID); +#endif + + /* unused region before and after combination */ + while (node->prev && !node->prev->used) { + node = node->prev; } - if ((UINT32)pPtr < (UINT32)pstHeapMan->pstHead - || (UINT32)pPtr > ((UINT32)pstHeapMan->pstTail + sizeof(struct LOS_HEAP_NODE))) - { - PRINT_ERR("0x%x out of range!\n", (UINT32)pPtr); - return FALSE; + next = OsHeapPrvGetNext(heapMan, node); + while (next != NULL) { + if (next->used) { + next->prev = node; + break; + } + node->size += sizeof(struct LosHeapNode) + next->size; + if (heapMan->tail == next) { + heapMan->tail = node; + } + next = OsHeapPrvGetNext(heapMan, node); } +} - uvIntSave = LOS_IntLock(); +/* + * Description : To free the memory block from heap memory poll + * Input : VOID* pool --- Pointer to the manager,to distinguish heap + * VOID* ptr --- the pointer of heap memory we want to free + * Return : 1:success 0:error + */ +BOOL OsHeapFree(VOID *pool, VOID *ptr) +{ + struct LosHeapNode *node = NULL; - pstNode = ((struct LOS_HEAP_NODE*)pPtr) - 1; + UINT32 gapSize; + BOOL ret = TRUE; - /* check if the address is a node of the heap memory list*/ - if ((pstNode->uwUsed == 0) || (!((UINT32)pstNode == (UINT32)pstHeapMan->pstHead) - && ((UINT32)pstNode->pstPrev < (UINT32)pstHeapMan->pstHead - || (UINT32)pstNode->pstPrev > ((UINT32)pstHeapMan->pstTail + sizeof(struct LOS_HEAP_NODE)) - || ((UINT32)osHeapPrvGetNext(pstHeapMan, pstNode->pstPrev) != (UINT32)pstNode) - ))) - { - bRet = FALSE; - goto out; + LosMemPoolInfo *heapMan = HEAP_CAST(LosMemPoolInfo *, pool); + if ((heapMan == NULL) || (ptr == NULL)) { + return LOS_NOK; } - /* set to unused status */ - pstNode->uwUsed = 0; -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_REDUCE_USED(pstNode->uwSize); -#endif - -#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) - if (g_uwCurHeapUsed >= (pstNode->uwSize + sizeof(struct LOS_HEAP_NODE))) - { - g_uwCurHeapUsed -= (pstNode->uwSize + sizeof(struct LOS_HEAP_NODE)); + /* find the real ptr through gap size */ + gapSize = *((UINT32 *)((UINTPTR)ptr - (sizeof(UINTPTR) / sizeof(UINT8)))); + if (OS_MEM_GET_ALIGN_FLAG(gapSize)) { + gapSize = OS_MEM_GET_ALIGN_GAPSIZE(gapSize); + ptr = (VOID *)((UINTPTR)ptr - gapSize); } -#endif - - /* unused region before and after combination */ - while (pstNode->pstPrev && !pstNode->pstPrev->uwUsed) - pstNode = pstNode->pstPrev; - while (((pstT = osHeapPrvGetNext(pstHeapMan, pstNode)) != NULL) && !pstT->uwUsed) - { - pstNode->uwSize += sizeof(struct LOS_HEAP_NODE) + pstT->uwSize; - if (pstHeapMan->pstTail == pstT) - pstHeapMan->pstTail = pstNode; + if (((UINTPTR)ptr < (UINTPTR)heapMan->head) || + ((UINTPTR)ptr > ((UINTPTR)heapMan->tail + sizeof(struct LosHeapNode)))) { + PRINT_ERR("0x%x out of range!\n", (UINTPTR)ptr); + return FALSE; } - if ((pstT = osHeapPrvGetNext(pstHeapMan, pstNode)) != NULL) - pstT->pstPrev = pstNode; + node = ((struct LosHeapNode *)ptr) - 1; + /* check if the address is a node of the heap memory list */ + if ((node->used == 0) || (!((UINTPTR)node == (UINTPTR)heapMan->head) && + (((UINTPTR)node->prev < (UINTPTR)heapMan->head) || + ((UINTPTR)node->prev > ((UINTPTR)heapMan->tail + sizeof(struct LosHeapNode))) || + ((UINTPTR)OsHeapPrvGetNext(heapMan, node->prev) != (UINTPTR)node)))) { + ret = FALSE; + goto OUT; + } - g_uwFreeCount++; + OsDoHeapFree(heapMan, node); -out: - LOS_IntRestore(uvIntSave); +OUT: + if (ret == TRUE) { + g_memFreeCount++; + } - return bRet; + return ret; } -LITE_OS_SEC_TEXT_MINOR VOID osAlarmHeapInfo(VOID *pPool) +/* + * Description : print heap information + * Input : pool --- Pointer to the manager, to distinguish heap + */ +VOID OsAlarmHeapInfo(VOID *pool) { - struct LOS_HEAP_MANAGER *pstHeapMan = HEAP_CAST(struct LOS_HEAP_MANAGER *, pPool); - LOS_HEAP_STATUS stStatus = {0}; - if (LOS_NOK == osHeapStatisticsGet(pPool, &stStatus)) + LosMemPoolInfo *heapMan = HEAP_CAST(LosMemPoolInfo *, pool); + LosHeapStatus status = {0}; + (VOID)heapMan; + + if (OsHeapStatisticsGet(pool, &status) == LOS_NOK) { return; + } - PRINT_INFO("pool addr pool size total size used size free size alloc Count free Count\n0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n", - pPool, pstHeapMan->uwSize, stStatus.totalSize, stStatus.usedSize, stStatus.freeSize, stStatus.allocCount, stStatus.freeCount); - (void)pstHeapMan; + PRINT_INFO("pool addr pool size used size free size max free alloc Count free Count\n"); + PRINT_INFO("0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-8x\n", + pool, heapMan->size, status.totalUsedSize, status.totalFreeSize, status.maxFreeNodeSize, + status.usedNodeNum, status.freeNodeNum); } -LITE_OS_SEC_TEXT_MINOR UINT32 osHeapStatisticsGet(VOID *pPool, LOS_HEAP_STATUS *pstStatus) +/* + * Description : collect heap statistics + * Input : pool --- Pointer to the manager, to distinguish heap + * Output : status --- heap statistics + * Return : LOS_OK on success or error code on failure + */ +UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status) { - UINT32 uwHeapUsed = 0; - struct LOS_HEAP_NODE *pstNode = NULL; - struct LOS_HEAP_MANAGER *pstRamHeap = HEAP_CAST(struct LOS_HEAP_MANAGER *, pPool); - - if (!pstRamHeap) - { + UINT32 heapUsed = 0; + UINT32 maxFreeNodeSize = 0; + UINT32 freeNodeNum = 0; + UINT32 usedNodeNum = 0; + + struct LosHeapNode *node = NULL; + LosMemPoolInfo *ramHeap = HEAP_CAST(LosMemPoolInfo *, pool); + VOID *heapEnd = NULL; + if (ramHeap == NULL) { return LOS_NOK; } - - if (NULL == pstStatus) - { + heapEnd = (VOID *)((UINTPTR)pool + ramHeap->size); + if (status == NULL) { return LOS_NOK; } - pstNode = pstRamHeap->pstTail; - while (pstNode) - { - if (pstNode->uwUsed) - { - uwHeapUsed += (pstNode->uwSize + sizeof(struct LOS_HEAP_NODE)); + /* heap mannager header use heap space */ + heapUsed += sizeof(LosMemPoolInfo); + + node = ramHeap->tail; + while (node != NULL) { + if ((node <= (struct LosHeapNode *)pool) || + (node >= (struct LosHeapNode *)heapEnd)) { + return LOS_NOK; } - pstNode = pstNode->pstPrev; + if (node->used) { + heapUsed += (node->size + sizeof(struct LosHeapNode)); + usedNodeNum++; + } else { + if (node->size > maxFreeNodeSize) { + maxFreeNodeSize = node->size; + } + freeNodeNum++; + } + node = node->prev; } - if (pstRamHeap->uwSize < uwHeapUsed) - { + if (ramHeap->size < heapUsed) { return LOS_NOK; } - pstStatus->usedSize = uwHeapUsed; - pstStatus->totalSize = pstRamHeap->uwSize; - pstStatus->freeSize = pstStatus->totalSize - pstStatus->usedSize; - pstStatus->allocCount = g_uwAllocCount; - pstStatus->freeCount = g_uwFreeCount; + status->totalUsedSize = heapUsed; + status->maxFreeNodeSize = maxFreeNodeSize; + status->totalFreeSize = ramHeap->size - status->totalUsedSize; + status->usedNodeNum = usedNodeNum; + status->freeNodeNum = freeNodeNum; return LOS_OK; } #if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) -LITE_OS_SEC_TEXT_MINOR UINT32 osHeapGetHeapMemoryPeak(VOID) +UINT32 LOS_HeapGetHeapMemoryPeak(VOID) { - return g_uwMaxHeapUsed; + return g_memMaxHeapUsed; } #endif -LITE_OS_SEC_TEXT_MINOR UINT32 osHeapGetMaxFreeBlkSize(VOID *pPool) +/* + * Description : get max free block size + * Input : pool --- Pointer to the manager, to distinguish heap + * Return : max free block size + */ +UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool) { - UINT32 uwSize = 0; - UINT32 uwTemp = 0; - struct LOS_HEAP_NODE *pstNode = NULL; + UINT32 size = 0; + UINT32 temp; + struct LosHeapNode *node = NULL; + LosMemPoolInfo *ramHeap = HEAP_CAST(LosMemPoolInfo *, pool); - struct LOS_HEAP_MANAGER *pstRamHeap = HEAP_CAST(struct LOS_HEAP_MANAGER *, pPool); - - if (!pstRamHeap) - { + if (ramHeap == NULL) { return LOS_NOK; } - pstNode = pstRamHeap->pstTail; - - while (pstNode) - { - if (!(pstNode->uwUsed)) - { - uwTemp = pstNode->uwSize; - if (uwTemp > uwSize) - { - uwSize = uwTemp; + node = ramHeap->tail; + while (node != NULL) { + if (!(node->used)) { + temp = node->size; + if (temp > size) { + size = temp; } } - pstNode = pstNode->pstPrev; + node = node->prev; } - return uwSize; + return size; } +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +VOID LOS_HeapDumpMemoryStats(VOID *pool) +{ + LosMemPoolInfo *heapMan = NULL; + TaskMemUsedInfo *memStats = NULL; + LosHeapStatus status = {0}; + UINT32 intSave; + /* heap mannager header use heap space */ + UINT32 peak = sizeof(LosMemPoolInfo); + UINT32 i; + + if (pool == NULL) { + return; + } + + /* dump memory basic info */ + heapMan = (LosMemPoolInfo *)pool; + MEM_LOCK(intSave); + if (OsHeapStatisticsGet(heapMan, &status) == LOS_NOK) { + MEM_UNLOCK(intSave); + return; + } + + PRINT_INFO("Pool Addr : 0x%-8x\n", heapMan); + PRINT_INFO("Pool Size : %-8u\n", heapMan->size); + PRINT_INFO("Pool Used : %-8u\n", status.totalUsedSize); + PRINT_INFO("Pool Free : %-8u\n", status.totalFreeSize); + + /* dump memory peak usage */ + i = 0; + memStats = heapMan->memStats; + while (i < TASK_BLOCK_NUM) { + peak += memStats[i].memPeak; + i++; + } + PRINT_INFO("Pool Peak : %-8d\n", peak); + + /* dump memory usage by tasks */ + PRINT_INFO("Memory Usage By Tasks:\n"); + i = 0; + while (i < TASK_BLOCK_NUM - 1) { + if (g_taskCBArray[i].taskStatus != OS_TASK_STATUS_UNUSED) { + PRINT_INFO(" task %3d use:%6d peak:%6d\n", i, memStats[i].memUsed, memStats[i].memPeak); + } + i++; + } + PRINT_INFO(" init/irq use:%6d peak:%6d\n", memStats[i].memUsed, memStats[i].memPeak); + MEM_UNLOCK(intSave); +} +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/mem/bestfit_little/los_memcheck.c b/kernel/base/mem/bestfit_little/los_memcheck.c new file mode 100644 index 000000000..dfa6540d2 --- /dev/null +++ b/kernel/base/mem/bestfit_little/los_memcheck.c @@ -0,0 +1,122 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2015. All rights reserved. + * Description: LiteOS memory Module Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_memcheck_pri.h" +#include "securec.h" +#include "los_memory_pri.h" +#include "los_membox_pri.h" +#include "los_heap_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_PLATFORM_EXC == YES) +UINT8 g_memInfoMgr[MEM_INFO_SIZE]; + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemExcInfoGet(UINT32 memNum, MEM_INFO_S *memExcInfo) +{ + UINT32 maxBlk = 0; + UINT32 blkCnt = 0; + UINT32 blkSize = 0; + LOS_MEM_POOL_STATUS status; + MEM_INFO *memInfo = NULL; + + if ((memNum >= OS_SYS_MEM_NUM) || (memExcInfo == NULL)) { + return LOS_NOK; + } + + (VOID)memset_s(memExcInfo, sizeof(MEM_INFO_S), 0, sizeof(MEM_INFO_S)); + memInfo = (MEM_INFO *)(VOID *)g_memInfoMgr + memNum; + memExcInfo->uwType = memInfo->uwType; + memExcInfo->uwStartAddr = memInfo->uwStartAddr; + memExcInfo->uwSize = memInfo->uwSize; + + if (memInfo->uwType == MEM_MANG_MEMBOX) { + (VOID)LOS_MemboxStatisticsGet((VOID *)(UINTPTR)(memInfo->uwStartAddr), &maxBlk, &blkCnt, &blkSize); + memExcInfo->uwBlockSize = blkSize; + memExcInfo->uwSize = maxBlk; /* Block num */ + memExcInfo->uwFree = maxBlk - blkCnt; + } else if (memInfo->uwType == MEM_MANG_MEMORY) { + (VOID)LOS_MemInfoGet((VOID *)(UINTPTR)(memInfo->uwStartAddr), &status); + + memExcInfo->uwSize = status.uwTotalUsedSize; + memExcInfo->uwFree = status.uwTotalFreeSize; + } else { + PRINT_ERR("%s:the type of 0x%x is MEM_MANG_EMPTY !\n", __func__, memInfo->uwStartAddr); + } + + return LOS_OK; +} + +VOID OsMemInfoUpdate(VOID *pool, UINT32 size, UINT32 type) +{ + MEM_INFO *memInfo = (MEM_INFO *)(VOID *)g_memInfoMgr; + UINTPTR intSave; + UINT8 loop; + + intSave = LOS_IntLock(); + for (loop = 0; loop < OS_SYS_MEM_NUM; loop++) { + if (type == MEM_MANG_EMPTY) { + if (memInfo->uwStartAddr == (UINTPTR)pool) { + memInfo->uwType = MEM_MANG_EMPTY; + LOS_IntRestore(intSave); + return; + } + } else if (memInfo->uwStartAddr == (UINTPTR)pool) { + break; + } else if (memInfo->uwType == MEM_MANG_EMPTY) { + break; + } + memInfo++; + } + if ((loop < OS_SYS_MEM_NUM) && (type != MEM_MANG_EMPTY)) { + memInfo->uwType = type; + memInfo->uwStartAddr = (UINTPTR)pool; + memInfo->uwSize = size; + } else { + PRINT_ERR("MemInfo recorded up to max num or the input pool to empty not recorded before\n"); + } + + LOS_IntRestore(intSave); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ \ No newline at end of file diff --git a/kernel/base/mem/bestfit_little/los_memory.c b/kernel/base/mem/bestfit_little/los_memory.c index e0fa3a795..cbc21adb0 100644 --- a/kernel/base/mem/bestfit_little/los_memory.c +++ b/kernel/base/mem/bestfit_little/los_memory.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2017>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Mem Module Implementation * 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 @@ -22,386 +22,333 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "string.h" + * --------------------------------------------------------------------------- */ +#include "los_memory_pri.h" +#include "securec.h" #include "los_typedef.h" -#include "los_memory.ph" -#if (LOSCFG_KERNEL_MEM_SLAB == YES) -#include "los_slab.ph" -#endif -#include "los_heap.ph" +#include "los_heap_pri.h" #include "los_hwi.h" -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_exc.ph" -#endif -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_memcheck.ph" -#endif +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define POOL_ADDR_ALIGNSIZE 64 #if (LOSCFG_MEM_MUL_POOL == YES) -VOID *g_pPoolHead = NULL; +VOID *g_poolHead = NULL; #endif -#define OS_SLAB_CAST(_t, _exp) ((_t)(_exp)) -#define OS_MEM_POOL_BASE_ALIGN 4 -#define IS_POOL_ALIGNED(value, alignSize) (0 == (((UINT32)(value)) & ((UINT32)(alignSize - 1)))) +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memSpin); -LITE_OS_SEC_TEXT_MINOR VOID *osSlabCtrlHdrGet(VOID *pPool) -{ -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - return (&(OS_SLAB_CAST(struct LOS_HEAP_MANAGER *, pPool)->stSlabCtrlHdr)); -#else - return NULL; -#endif -} +UINT8 *m_aucSysMem0 = (UINT8 *)NULL; +UINT8 *m_aucSysMem1 = (UINT8 *)NULL; +__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end; +__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0; -/***************************************************************************** - Function : LOS_MemInit - Description : Initialize Dynamic Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - Output : None - Return : LOS_OK - Ok, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pPool, UINT32 uwSize) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size) { - BOOL bRet = TRUE; - UINTPTR uvIntSave; -#if (LOSCFG_MEM_MUL_POOL == YES) - VOID *pNext = g_pPoolHead; - VOID * pCur = g_pPoolHead; - UINT32 uwPoolEnd; + BOOL ret = TRUE; + UINT32 intSave; +#ifdef LOSCFG_MEM_MUL_POOL + VOID *next = g_poolHead; + VOID *cur = g_poolHead; + UINT32 poolEnd; #endif - if (!pPool || uwSize <= sizeof(struct LOS_HEAP_MANAGER)) - return LOS_NOK; - - if (!IS_POOL_ALIGNED(pPool, OS_MEM_POOL_BASE_ALIGN)) - return LOS_NOK; + if ((pool == NULL) || (size <= sizeof(LosMemPoolInfo))) { + return OS_ERROR; + } - uvIntSave = LOS_IntLock(); + MEM_LOCK(intSave); -#if (LOSCFG_MEM_MUL_POOL == YES) - while (pNext != NULL) - { - uwPoolEnd = (UINT32)pNext + ((struct LOS_HEAP_MANAGER *)pNext)->uwSize; - if ((pPool <= pNext && ((UINT32)pPool + uwSize) > (UINT32)pNext) || - ((UINT32)pPool < uwPoolEnd && ((UINT32)pPool + uwSize) >= uwPoolEnd)) - { +#ifdef LOSCFG_MEM_MUL_POOL + while (next != NULL) { + poolEnd = (UINT32)(UINTPTR)next + ((LosMemPoolInfo *)next)->size; + if (((pool <= next) && (((UINT32)(UINTPTR)pool + size) > (UINT32)(UINTPTR)next)) || + (((UINT32)(UINTPTR)pool < poolEnd) && (((UINT32)(UINTPTR)pool + size) >= poolEnd))) { PRINT_ERR("pool [%p, 0x%x) conflict with pool [%p, 0x%x)\n", - pPool, (UINT32)pPool + uwSize, - pNext, (UINT32)pNext + ((struct LOS_HEAP_MANAGER *)pNext)->uwSize); + pool, (UINT32)(UINTPTR)pool + size, + next, (UINT32)(UINTPTR)next + ((LosMemPoolInfo *)next)->size); - LOS_IntRestore(uvIntSave); - return LOS_NOK; + MEM_UNLOCK(intSave); + return OS_ERROR; } - pCur = pNext; - pNext = ((struct LOS_HEAP_MANAGER *)pNext)->pNextPool; + cur = next; + next = ((LosMemPoolInfo *)next)->nextPool; } #endif - bRet = osHeapInit(pPool, uwSize); - if(!bRet) - { - LOS_IntRestore(uvIntSave); - return LOS_NOK; - } -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - if (uwSize >= SLAB_BASIC_NEED_SIZE)//if size of pool is small than size of slab need, don`t init slab - { - bRet = osSlabMemInit(pPool); - if(!bRet) - { - LOS_IntRestore(uvIntSave); - return LOS_NOK; - } + ret = OsHeapInit(pool, size); + if (!ret) { + MEM_UNLOCK(intSave); + return OS_ERROR; } -#endif -#if (LOSCFG_MEM_MUL_POOL == YES) - if (g_pPoolHead == NULL) - { - g_pPoolHead = pPool; - } - else - { - ((struct LOS_HEAP_MANAGER *)pCur)->pNextPool = pPool; +#ifdef LOSCFG_MEM_MUL_POOL + if (g_poolHead == NULL) { + g_poolHead = pool; + } else { + ((LosMemPoolInfo *)cur)->nextPool = pool; } - ((struct LOS_HEAP_MANAGER *)pPool)->pNextPool = NULL; + ((LosMemPoolInfo *)pool)->nextPool = NULL; #endif -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - osMemInfoUpdate(pPool, uwSize, MEM_MANG_MEMORY); -#endif - - LOS_IntRestore(uvIntSave); + MEM_UNLOCK(intSave); return LOS_OK; } -LITE_OS_SEC_TEXT_INIT UINT32 osMemSystemInit(VOID) +/* + * Description : Initialize Dynamic Memory pool + * Return : LOS_OK on success or error code on failure + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart) { - UINT32 uwRet = LOS_OK; - - uwRet = LOS_MemInit((VOID *)OS_SYS_MEM_ADDR, OS_SYS_MEM_SIZE); - -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - osExcRegister(OS_EXC_TYPE_MEM, (EXC_INFO_SAVE_CALLBACK)LOS_MemExcInfoGet, g_aucMemMang); + UINT32 ret; + UINT32 memSize; + + m_aucSysMem1 = (UINT8 *)((memStart + (POOL_ADDR_ALIGNSIZE - 1)) & ~((UINTPTR)(POOL_ADDR_ALIGNSIZE - 1))); + memSize = OS_SYS_MEM_SIZE; + ret = LOS_MemInit((VOID *)m_aucSysMem1, memSize); +#ifndef LOSCFG_EXC_INTERACTION + m_aucSysMem0 = m_aucSysMem1; #endif - return uwRet; + return ret; } -#if (LOSCFG_MEM_MUL_POOL == YES) -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pPool) +#ifdef LOSCFG_MEM_MUL_POOL +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pool) { - UINTPTR uvIntSave, uvRet = LOS_NOK; - VOID *pNext, *pCur; + UINT32 intSave; + UINT32 ret = LOS_NOK; + VOID *next = NULL; + VOID *cur = NULL; - if (NULL == pPool) - { - return uvRet; + if (pool == NULL) { + return ret; } - uvIntSave = LOS_IntLock(); - do - { - if (pPool == g_pPoolHead) - { - g_pPoolHead = ((struct LOS_HEAP_MANAGER *)g_pPoolHead)->pNextPool; - uvRet = LOS_OK; + MEM_LOCK(intSave); + do { + if (pool == g_poolHead) { + g_poolHead = ((LosMemPoolInfo *)g_poolHead)->nextPool; + ret = LOS_OK; break; } - pCur = g_pPoolHead; - pNext = g_pPoolHead; - - while (pNext != NULL) - { - if (pPool == pNext) - { - ((struct LOS_HEAP_MANAGER *)pCur)->pNextPool = ((struct LOS_HEAP_MANAGER *)pNext)->pNextPool; - uvRet = LOS_OK; + cur = g_poolHead; + next = g_poolHead; + while (next != NULL) { + if (pool == next) { + ((LosMemPoolInfo *)cur)->nextPool = ((LosMemPoolInfo *)next)->nextPool; + ret = LOS_OK; break; } - pCur = pNext; - pNext = ((struct LOS_HEAP_MANAGER *)pNext)->pNextPool; + cur = next; + next = ((LosMemPoolInfo *)next)->nextPool; } - }while(0); + } while (0); -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - if (uvRet == LOS_OK) - osMemInfoUpdate(pPool, 0, MEM_MANG_EMPTY); -#endif -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - osSlabMemDeinit(pPool); -#endif - LOS_IntRestore(uvIntSave); - return uvRet; + MEM_UNLOCK(intSave); + return ret; } LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemPoolList(VOID) { - VOID *pNext = g_pPoolHead; - UINT32 uwIndex = 0; - - while (pNext != NULL) - { - uwIndex++; - osAlarmHeapInfo(pNext); - pNext = ((struct LOS_HEAP_MANAGER *)pNext)->pNextPool; + VOID *next = g_poolHead; + UINT32 index = 0; + UINT32 intSave; + + while (next != NULL) { + index++; + MEM_LOCK(intSave); + OsAlarmHeapInfo(next); + MEM_UNLOCK(intSave); + next = ((LosMemPoolInfo *)next)->nextPool; } - return uwIndex; + return index; } #endif -/***************************************************************************** - Function : LOS_MemAlloc - Description : Allocate Memory from Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - Output : None - Return : Pointer to allocated memory -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemAlloc (VOID *pPool, UINT32 uwSize) +LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { - VOID *pRet = NULL; + VOID *ptr = NULL; + UINT32 intSave; - if ((NULL == pPool) || (0 == uwSize)) - { - return pRet; + if ((pool == NULL) || (size == 0)) { + return NULL; } -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - pRet = osSlabMemAlloc(pPool, uwSize); - if(pRet == NULL) -#endif - pRet = osHeapAlloc(pPool, uwSize); + MEM_LOCK(intSave); + ptr = OsHeapAlloc(pool, size); + MEM_UNLOCK(intSave); - return pRet; + return ptr; } -/***************************************************************************** - Function : LOS_MemAllocAlign - Description : align size then allocate node from Memory pool - Input : pPool --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - uwBoundary --- align form - Output : None - Return : Pointer to allocated memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pPool, UINT32 uwSize, UINT32 uwBoundary) + +LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { - return osHeapAllocAlign(pPool, uwSize, uwBoundary); + VOID *ptr = NULL; + UINT32 intSave; + + MEM_LOCK(intSave); + ptr = OsHeapAllocAlign(pool, size, boundary); + MEM_UNLOCK(intSave); + + return ptr; } -/***************************************************************************** - Function : LOS_MemRealloc - Description : realloc memory from Memory pool - Input : pPool --- Pointer to memory pool - pPtr --- Pointer to memory - uwSize --- new size - Output : None - Return : Pointer to allocated memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID *LOS_MemRealloc(VOID *pPool, VOID *pPtr, UINT32 uwSize) +VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { - VOID *p = NULL; - UINTPTR uvIntSave; - struct LOS_HEAP_NODE *pstNode; - UINT32 uwCpySize = 0; -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - UINT32 uwOldSize = (UINT32)-1; -#endif - UINT32 uwGapSize = 0; - - if ((int)uwSize < 0) - { - return NULL; - } - uvIntSave = LOS_IntLock(); + VOID *retPtr = NULL; + VOID *freePtr = NULL; + struct LosHeapNode *node = NULL; + UINT32 cpySize = 0; + UINT32 gapSize = 0; + errno_t rc; /* Zero-size requests are treated as free. */ - if ((NULL != pPtr) && (0 == uwSize)) - { - (VOID)LOS_MemFree(pPool, pPtr); - } - /* Requests with NULL pointers are treated as malloc. */ - else if (NULL == pPtr) - { - p = LOS_MemAlloc(pPool, uwSize); - } - else - { -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - uwOldSize = osSlabMemCheck(pPool, pPtr); - if (uwOldSize != (UINT32)-1) - { - uwCpySize = uwSize > uwOldSize ? uwOldSize : uwSize; + if ((ptr != NULL) && (size == 0)) { + if (LOS_MemFree(pool, ptr) != LOS_OK) { + PRINT_ERR("LOS_MemFree error, pool[%p], ptr[%p]\n", pool, ptr); } - else -#endif - { - /* find the real ptr through gap size */ - uwGapSize = *((UINT32 *)((UINT32)pPtr - 4)); - if (OS_MEM_GET_ALIGN_FLAG(uwGapSize)) - { - return NULL; - } - - pstNode = ((struct LOS_HEAP_NODE *)pPtr) - 1; - uwCpySize = uwSize > pstNode->uwSize ? pstNode->uwSize : uwSize; + } else if (ptr == NULL) { /* Requests with NULL pointers are treated as malloc */ + retPtr = LOS_MemAlloc(pool, size); + } else { + /* find the real ptr through gap size */ + gapSize = *((UINTPTR *)((UINTPTR)ptr - sizeof(UINTPTR) / sizeof(UINT8))); + if (OS_MEM_GET_ALIGN_FLAG(gapSize)) { + return NULL; } - p = LOS_MemAlloc(pPool, uwSize); - if (p != NULL) - { - (VOID)memcpy(p, pPtr, uwCpySize); - (VOID)LOS_MemFree(pPool, pPtr); + node = ((struct LosHeapNode *)ptr) - 1; + cpySize = (size > node->size) ? node->size : size; + + retPtr = LOS_MemAlloc(pool, size); + if (retPtr != NULL) { + rc = memcpy_s(retPtr, size, ptr, cpySize); + if (rc == EOK) { + freePtr = ptr; + } else { + freePtr = retPtr; + retPtr = NULL; + } + + if (LOS_MemFree(pool, freePtr) != LOS_OK) { + PRINT_ERR("LOS_MemFree error, pool[%p], ptr[%p]\n", pool, freePtr); + } } } - LOS_IntRestore(uvIntSave); - return p; + return retPtr; } -/***************************************************************************** - Function : LOS_MemFree - Description : Free Memory and return it to Memory pool - Input : pPool --- Pointer to memory pool - pMem --- Pointer to memory to free - Output : None - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_MemFree (VOID *pPool, VOID *pMem) +LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *mem) { - BOOL bRet = FALSE; + BOOL ret = FALSE; + UINT32 intSave; - if ((NULL == pPool) || (NULL == pMem)) - { + if ((pool == NULL) || (mem == NULL)) { return LOS_NOK; } -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - bRet = osSlabMemFree(pPool, pMem); - if(bRet != TRUE) -#endif - bRet = osHeapFree(pPool, pMem); + MEM_LOCK(intSave); + ret = OsHeapFree(pool, mem); + MEM_UNLOCK(intSave); - return (bRet == TRUE ? LOS_OK : LOS_NOK); + return ((ret == TRUE) ? LOS_OK : LOS_NOK); } -LITE_OS_SEC_TEXT UINT32 LOS_MemStatisticsGet(VOID *pPool, LOS_MEM_STATUS *pstStatus) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *status) { - LOS_HEAP_STATUS stHeapStatus; -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - LOS_SLAB_STATUS stSlabStatus; -#endif - UINT32 uwErr; + LosHeapStatus heapStatus; + UINT32 err; + UINT32 intSave; - uwErr = osHeapStatisticsGet(pPool, &stHeapStatus); - if (uwErr != LOS_OK) - { + if ((pool == NULL) || (status == NULL)) { return LOS_NOK; } - pstStatus->totalSize = stHeapStatus.totalSize; - pstStatus->usedSize = stHeapStatus.usedSize; - pstStatus->freeSize = stHeapStatus.freeSize; - pstStatus->allocCount = stHeapStatus.allocCount; - pstStatus->freeCount = stHeapStatus.freeCount; + MEM_LOCK(intSave); -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - uwErr = osSlabStatisticsGet(pPool, &stSlabStatus); - if (uwErr != LOS_OK) - { + err = OsHeapStatisticsGet(pool, &heapStatus); + if (err != LOS_OK) { + MEM_UNLOCK(intSave); return LOS_NOK; } - pstStatus->totalSize = stHeapStatus.totalSize; - pstStatus->usedSize = stHeapStatus.usedSize - stSlabStatus.freeSize; //all slab region inside of heap used region - pstStatus->freeSize = stHeapStatus.freeSize + stSlabStatus.freeSize; - pstStatus->allocCount = stHeapStatus.allocCount + stSlabStatus.allocCount; - pstStatus->freeCount = stHeapStatus.freeCount + stSlabStatus.freeCount; -#endif + status->uwTotalUsedSize = heapStatus.totalUsedSize; + status->uwTotalFreeSize = heapStatus.totalFreeSize; + status->uwMaxFreeNodeSize = heapStatus.maxFreeNodeSize; + status->uwUsedNodeNum = heapStatus.usedNodeNum; + status->uwFreeNodeNum = heapStatus.freeNodeNum; + + MEM_UNLOCK(intSave); return LOS_OK; } -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemGetMaxFreeBlkSize(VOID *pPool) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool) { - UINT32 uwMaxFreeSize = osHeapGetMaxFreeBlkSize(pPool); - UINT32 uwMaxSlabFreeSize = 0; -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - uwMaxSlabFreeSize = osSlabGetMaxFreeBlkSize(pPool); -#endif + LosHeapStatus heapStatus; + UINT32 err; + UINT32 intSave; -#ifndef MAX -#define MAX(x,y) (x)>(y)?(x):(y) -#endif - return MAX(uwMaxFreeSize, uwMaxSlabFreeSize); + if (pool == NULL) { + return OS_NULL_INT; + } + + MEM_LOCK(intSave); + err = OsHeapStatisticsGet(pool, &heapStatus); + MEM_UNLOCK(intSave); + if (err != LOS_OK) { + return OS_NULL_INT; + } + + return heapStatus.totalUsedSize; +} + +UINT32 LOS_MemGetMaxFreeBlkSize(VOID *pool) +{ + UINT32 maxFreeBlkSize; + UINT32 intSave; + if (pool == NULL) { + return 0; + } + MEM_LOCK(intSave); + maxFreeBlkSize = OsHeapGetMaxFreeBlkSize(pool); + MEM_UNLOCK(intSave); + return maxFreeBlkSize; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(const VOID *pool) +{ + LosMemPoolInfo *heapManager = (LosMemPoolInfo *)pool; + if (heapManager == NULL) { + return 0; + } + return heapManager->size; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool) +{ + (VOID)pool; + PRINT_ERR("[%s:%d] not Implement!!\n", __FUNCTION__, __LINE__); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus } +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/mem/common/Makefile b/kernel/base/mem/common/Makefile deleted file mode 100644 index fb41837c0..000000000 --- a/kernel/base/mem/common/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -objs-y += los_slab.o -objs-y += los_slabmem.o diff --git a/kernel/base/mem/common/los_memcheck.c b/kernel/base/mem/common/los_memcheck.c deleted file mode 100644 index 82f3163fe..000000000 --- a/kernel/base/mem/common/los_memcheck.c +++ /dev/null @@ -1,180 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "los_memcheck.ph" -#include "los_memory.ph" -#include "los_membox.ph" -#if (LOSCFG_KERNEL_MEM_SLAB == YES) -#include "los_slab.ph" -#endif -#include "los_heap.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ -UINT32 memexc_count = 0; - -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) -LITE_OS_SEC_BSS UINT8 g_aucMemMang[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 uwMemNum, MEM_INFO_S *pstMemExcInfo) -{ - UINT32 uwItemSz; - UINT32 uwItemCnt; - UINT32 uwCurUsage; - UINT32 uwIdx; - UINT32 uwMaxBlk = 0; - UINT32 uwBlkCnt = 0; - UINT32 uwBlkSize = 0; - LOS_MEM_STATUS stStatus; - MEM_INFO *pstMemInfo = NULL; -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - OS_SLAB_MEM *pstSlabAlloc; -#endif - - if(uwMemNum >= *(UINT32 *)g_aucMemMang || pstMemExcInfo == NULL) - { - return LOS_NOK; - } - pstMemInfo = (MEM_INFO *)(g_aucMemMang + sizeof(UINT32)) + uwMemNum; - pstMemExcInfo->uwType = pstMemInfo->uwType; - pstMemExcInfo->uwStartAddr = pstMemInfo->uwStartAddr; - pstMemExcInfo->uwSize = pstMemInfo->uwSize; - pstMemExcInfo->uwFree = 0; - pstMemExcInfo->uwBlockSize = 0; - pstMemExcInfo->uwErrorAddr = 0; - pstMemExcInfo->uwErrorLen = 0; - pstMemExcInfo->uwErrorOwner = 0; - - if (pstMemInfo->uwType == MEM_MANG_MEMBOX) - { - (VOID)LOS_MemboxStatisticsGet((VOID *)(pstMemInfo->uwStartAddr), &uwMaxBlk, &uwBlkCnt, &uwBlkSize); - pstMemExcInfo->uwBlockSize = uwBlkSize; - pstMemExcInfo->uwSize = uwMaxBlk;//Block num - pstMemExcInfo->uwFree = uwMaxBlk - uwBlkCnt; - } - else if(pstMemInfo->uwType == MEM_MANG_MEMORY) - { - -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = osSlabCtrlHdrGet((VOID *)pstMemExcInfo->uwStartAddr); - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - if(pstSlabAlloc->alloc) - { - osSlabAllocatorGetSlabInfo(pstSlabAlloc->alloc, &uwItemSz, &uwItemCnt, &uwCurUsage); - - pstMemExcInfo->stSlabInfo[uwIdx].cur_usage = uwCurUsage; - pstMemExcInfo->stSlabInfo[uwIdx].item_cnt = uwItemCnt; - pstMemExcInfo->stSlabInfo[uwIdx].item_sz = uwItemSz; - } - else - { - pstMemExcInfo->stSlabInfo[uwIdx].cur_usage = 0; - pstMemExcInfo->stSlabInfo[uwIdx].item_cnt = 0; - pstMemExcInfo->stSlabInfo[uwIdx].item_sz = 0; - } - } -#endif - (VOID)LOS_MemStatisticsGet((VOID *)(pstMemInfo->uwStartAddr), &stStatus); - - pstMemExcInfo->uwSize = stStatus.totalSize; - pstMemExcInfo->uwFree = stStatus.freeSize; - } - else { - PRINT_ERR("%s:the type of %x is MEM_MANG_EMPTY !\n", __func__, pstMemInfo->uwStartAddr); - } - - return LOS_OK; -} - -LITE_OS_SEC_TEXT UINT32 osMemInfoUpdate(VOID *pPool, UINT32 uwSize, UINT32 uwType) -{ - UINT32 *puwMemCount = (UINT32 *)g_aucMemMang; - MEM_INFO *pstMemInfo = (MEM_INFO *)(g_aucMemMang + sizeof(UINT32)); - UINTPTR uvIntSave; - UINT8 ucLoop; - UINT32 uwRet = LOS_OK; - - uvIntSave = LOS_IntLock(); - for (ucLoop = 0; ucLoop < *puwMemCount; ucLoop++) - { - if (uwType == MEM_MANG_EMPTY) - { - if (pstMemInfo->uwStartAddr == (UINT32)pPool) - { - pstMemInfo->uwType = MEM_MANG_EMPTY; - LOS_IntRestore(uvIntSave); - return LOS_OK; - } - } - else if (pstMemInfo->uwStartAddr == (UINT32)pPool ) - { - (*puwMemCount)--; - uwRet = LOS_NOK; - break; - } - else if (pstMemInfo->uwType == MEM_MANG_EMPTY) - { - (*puwMemCount)--; - break; - } - pstMemInfo++; - } - if(*puwMemCount < OS_SYS_MEM_NUM && uwType != MEM_MANG_EMPTY) - { - pstMemInfo->uwType = uwType; - pstMemInfo->uwStartAddr = (UINT32)pPool; - pstMemInfo->uwSize = uwSize; - (*puwMemCount)++; - } - LOS_IntRestore(uvIntSave); - return uwRet; -} -#endif - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ diff --git a/kernel/base/mem/common/los_memstat.c b/kernel/base/mem/common/los_memstat.c index ff5095ff4..029104c38 100644 --- a/kernel/base/mem/common/los_memstat.c +++ b/kernel/base/mem/common/los_memstat.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Task Mem Implementation * 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 @@ -22,19 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_memstat.inc" -#include "los_task.ph" -#include "los_config.h" +#include "los_memstat_pri.h" +#include "los_task_pri.h" #ifdef __cplusplus #if __cplusplus @@ -42,81 +41,70 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) +#define MIN_TASK_ID(x, y) ((x) > (y) ? (y) : (x)) +#define MAX_MEM_USE(x, y) ((x) > (y) ? (x) : (y)) -typedef struct { - UINT32 uwMemUsed; -} TSK_MEM_USED_INFO; - -LITE_OS_SEC_BSS_MINOR TSK_MEM_USED_INFO g_TskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; - -LITE_OS_SEC_TEXT_MINOR VOID osTaskMemUsedInc(UINT32 uwUsedSize) +#if (LOSCFG_KERNEL_MEM_STATISTICS == YES) +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(TaskMemUsedInfo *memStats, UINT32 usedSize, UINT32 taskID) { - UINT32 uwTaskId; - - if (NULL == g_stLosTask.pstRunTask) - { - return; - } - - if (OS_INT_ACTIVE) - { - return; - } - - uwTaskId = (UINT32) g_stLosTask.pstRunTask->uwTaskID; - - if (uwTaskId > LOSCFG_BASE_CORE_TSK_LIMIT) - { - return; - } - - g_TskMemUsedInfo[uwTaskId].uwMemUsed += uwUsedSize; + UINT32 record = MIN_TASK_ID(taskID, TASK_BLOCK_NUM - 1); + memStats[record].memUsed += usedSize; + memStats[record].memPeak = MAX_MEM_USE(memStats[record].memPeak, memStats[record].memUsed); } -LITE_OS_SEC_TEXT_MINOR VOID osTaskMemUsedDec(UINT32 uwUsedSize) +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(TaskMemUsedInfo *memStats, UINT32 usedSize, UINT32 taskID) { - UINT32 uwTaskId; + UINT32 record = MIN_TASK_ID(taskID, TASK_BLOCK_NUM - 1); - if (NULL == g_stLosTask.pstRunTask) - { + if (memStats[record].memUsed < usedSize) { + PRINT_INFO("mem used of current task '%s':0x%x, decrease size:0x%x\n", + OsCurrTaskGet()->taskName, memStats[record].memUsed, usedSize); return; } - uwTaskId = (UINT32) g_stLosTask.pstRunTask->uwTaskID; - - if (uwTaskId > LOSCFG_BASE_CORE_TSK_LIMIT) - { - return; - } - - if (OS_INT_ACTIVE) - { - return; - } - - g_TskMemUsedInfo[uwTaskId].uwMemUsed -= uwUsedSize; + memStats[record].memUsed -= usedSize; } -LITE_OS_SEC_TEXT_MINOR UINT32 osTaskMemUsage(UINT32 uwTaskId) +LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(const TaskMemUsedInfo *memStats, UINT32 taskID) { - if ((UINT32)uwTaskId > LOSCFG_BASE_CORE_TSK_LIMIT) - { - return LOS_NOK; - } - - return g_TskMemUsedInfo[(UINT32)uwTaskId].uwMemUsed; + UINT32 record = MIN_TASK_ID(taskID, TASK_BLOCK_NUM - 1); + return memStats[record].memUsed; } -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskMemUsage(UINT32 uwTaskId) +LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID) { - return osTaskMemUsage(uwTaskId); + UINT32 record = MIN_TASK_ID(taskID, TASK_BLOCK_NUM - 1); +#if (LOSCFG_MEM_MUL_POOL == YES) + TaskMemUsedInfo *memStats = NULL; + LosMemPoolInfo *pool = (LosMemPoolInfo *)g_poolHead; + while (pool != NULL) { + memStats = (TaskMemUsedInfo *)(((LosMemPoolInfo *)pool)->memStats); + if (memStats[taskID].memUsed != 0) { + if (OS_TSK_GET_INDEX(taskID) < g_taskMaxNum) { + PRINT_INFO("mem used of task '%s' is:0x%x, not zero when task being deleted\n", + OS_TCB_FROM_TID(taskID)->taskName, memStats[record].memUsed); + } + } + memStats[record].memUsed = 0; + memStats[record].memPeak = 0; + pool = pool->nextPool; + } +#else + TaskMemUsedInfo *memStats = (TaskMemUsedInfo *)(((LosMemPoolInfo *)m_aucSysMem1)->memStats); + if (memStats[taskID].memUsed != 0) { + if (OS_TSK_GET_INDEX(taskID) < g_taskMaxNum) { + PRINT_INFO("mem used of task '%s' is:0x%x, not zero when task being deleted\n", + OS_TCB_FROM_TID(taskID)->taskName, memStats[record].memUsed); + } + } + memStats[record].memUsed = 0; + memStats[record].memPeak = 0; +#endif } - -#endif /*(LOSCFG_MEM_TASK_USED_STATISTICS == YES)*/ +#endif #ifdef __cplusplus #if __cplusplus } -#endif +#endif /* __cplusplus */ #endif /* __cplusplus */ diff --git a/kernel/base/mem/common/los_memstat.inc b/kernel/base/mem/common/los_memstat.inc deleted file mode 100644 index 83f06a726..000000000 --- a/kernel/base/mem/common/los_memstat.inc +++ /dev/null @@ -1,43 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_MEMSTAT_INC -#define _LOS_MEMSTAT_INC - -#include "los_memstat.ph" - -#define OS_MEM_ADD_USED(arg) osTaskMemUsedInc(arg) -#define OS_MEM_REDUCE_USED(arg) osTaskMemUsedDec(arg) - -#endif /* _LOS_MEMSTAT_INC */ diff --git a/kernel/base/mem/common/los_slab.c b/kernel/base/mem/common/los_slab.c deleted file mode 100644 index 842eb7044..000000000 --- a/kernel/base/mem/common/los_slab.c +++ /dev/null @@ -1,270 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2017>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include -#include -#include - -extern VOID* osHeapAlloc(VOID *pPool, UINT32 uwSz); -extern BOOL osHeapFree(VOID *pPool, VOID* pPtr); - -VOID osAtomicBitsetInit(struct AtomicBitset *pstSet, UINT32 uwNumBits) -{ - pstSet->numBits = uwNumBits; - memset(pstSet->words, 0, (uwNumBits + 31) / 8); - if (uwNumBits & 31) //mark all high bits so that osAtomicBitsetFindClearAndSet() is simpler - { - pstSet->words[uwNumBits / 32] = ((UINT32)((INT32)-1LL)) << (uwNumBits & 31); - } -} - -inline UINT32 osAtomicBitsetGetNumBits(const struct AtomicBitset *pstSet) -{ - return pstSet->numBits; -} - -BOOL osAtomicBitsetGetBit(const struct AtomicBitset *pstSet, UINT32 uwNum) -{ - if (uwNum >= pstSet->numBits) /* any value is as good as the next */ - { - return FALSE; - } - return !!((pstSet->words[uwNum / 32]) & (1UL << (uwNum & 31))); -} - -VOID osAtomicBitsetClearBit(struct AtomicBitset *pstSet, UINT32 uwNum) -{ - UINT32 *puwWordPtr = pstSet->words + uwNum / 32; - - if (uwNum >= pstSet->numBits) - { - return; - } - (*puwWordPtr) &= ~(1UL << (uwNum & 31)); -} - -/* find from the high bit to high bit£¬return the address of the first available bit */ -INT32 osAtomicBitsetFindClearAndSet(struct AtomicBitset *pstSet) -{ - UINT32 uwIdx, uwNumWords = (pstSet->numBits + 31) / 32; - UINT32 *puwWordPtr = pstSet->words; - UINT32 uwTmpWord; - INT32 swCnt = 0; - - for (uwIdx = 0; uwIdx < uwNumWords; uwIdx++, puwWordPtr++) - { - if (*puwWordPtr == 0xFFFFFFFF) - { - continue; - } - - uwTmpWord = ~(*puwWordPtr); - - while(uwTmpWord) - { - uwTmpWord = uwTmpWord >> 1UL; - swCnt++; - } - - *puwWordPtr |= (1UL << (swCnt - 1)); - - return (INT32)(uwIdx * 32 + swCnt - 1); - } - - return -1; -} - -/* change the order of the output idx of osAtomicBitsetFindClearAndSet to order of natural numbers */ -INT32 osAtomicBitsetIdxChgToNatural(struct AtomicBitset *pstBitset, INT32 swIdx) -{ - UINT32 uwRet, uwB; - if (swIdx < 0) - { - return swIdx; - } - uwB = 31 + (swIdx & ~31); - if (uwB > pstBitset->numBits - 1) - { - uwB = pstBitset->numBits - 1; - } - uwRet = uwB - (swIdx & 31); - return uwRet; -} - -BOOL osAtomicBitsetEmpty(struct AtomicBitset *pstBitset) -{ - UINT32 uwIdx = 0; - for (uwIdx = 0; uwIdx < pstBitset->numBits / 32;) - { - if (pstBitset->words[uwIdx] != 0) - { - return FALSE; - } - uwIdx++; - } - if (pstBitset->numBits & 31) - { - if (pstBitset->words[uwIdx] & ~(0xFFFFFFFF << (pstBitset->numBits & 31))) - { - return FALSE; - } - } - return TRUE; -} - -OS_SLAB_ALLOCATOR* osSlabAllocatorNew(VOID *pPool, UINT32 uwItemSz, UINT32 uwItemAlign, UINT32 uwNumItems) -{ - OS_SLAB_ALLOCATOR *pstAllocator; - UINT32 uwBitsetSz, uwDataSz; - - /* calcualte size */ - uwBitsetSz = ATOMIC_BITSET_SZ(uwNumItems); - - uwBitsetSz = (uwBitsetSz + uwItemAlign - 1) & ~(uwItemAlign - 1); - uwItemSz = (uwItemSz + uwItemAlign - 1) & ~(uwItemAlign - 1); - uwDataSz = uwItemSz * uwNumItems; - - pstAllocator = (OS_SLAB_ALLOCATOR*)osHeapAlloc(pPool, sizeof(OS_SLAB_ALLOCATOR) + uwBitsetSz + uwDataSz); - - if (pstAllocator) - { - pstAllocator->uwItemSz = uwItemSz; - - pstAllocator->bitset = (struct AtomicBitset *)((UINT8*)pstAllocator + sizeof(OS_SLAB_ALLOCATOR)); - pstAllocator->ucDataChunks = ((UINT8*)pstAllocator->bitset) + uwBitsetSz; - osAtomicBitsetInit(pstAllocator->bitset, uwNumItems); - } - - return pstAllocator; -} - - -VOID osSlabAllocatorDestroy(VOID *pPool, OS_SLAB_ALLOCATOR *pstAllocator) -{ - (VOID)osHeapFree(pPool, pstAllocator); -} - -VOID* osSlabAllocatorAlloc(OS_SLAB_ALLOCATOR *pstAllocator) -{ - INT32 swItemIdx = osAtomicBitsetFindClearAndSet(pstAllocator->bitset); - if (swItemIdx < 0) - return NULL; - - return pstAllocator->ucDataChunks + pstAllocator->uwItemSz * swItemIdx; -} - -BOOL osSlabAllocatorFree(OS_SLAB_ALLOCATOR *pstAllocator, VOID* ptrP) -{ - UINT8 *ptr = (UINT8*)ptrP; - UINT32 uwItemOffset = ptr - pstAllocator->ucDataChunks; - UINT32 uwItemIdx = uwItemOffset / pstAllocator->uwItemSz; - - //check for invalid inputs - if ((uwItemOffset % pstAllocator->uwItemSz) || (uwItemIdx >= osAtomicBitsetGetNumBits(pstAllocator->bitset)) || !osAtomicBitsetGetBit(pstAllocator->bitset, uwItemIdx)) - return FALSE; - - osAtomicBitsetClearBit(pstAllocator->bitset, uwItemIdx); - return TRUE; -} - -VOID* osSlabAllocatorGetNth(OS_SLAB_ALLOCATOR *pstAllocator, UINT32 uwIdx) -{ - if (!osAtomicBitsetGetBit(pstAllocator->bitset, uwIdx)) - return NULL; - - return pstAllocator->ucDataChunks + pstAllocator->uwItemSz * uwIdx; -} - -VOID* osSlabAllocatorGetIdxP(OS_SLAB_ALLOCATOR *pstAllocator, UINT32 uwIdx) -{ - return pstAllocator->ucDataChunks + pstAllocator->uwItemSz * uwIdx; -} - -UINT32 osSlabAllocatorGetIndex(OS_SLAB_ALLOCATOR *pstAllocator, VOID* ptrP) -{ - UINT8 *ptr = (UINT8*)ptrP; - UINT32 uwItemOffset = ptr - pstAllocator->ucDataChunks; - UINT32 uwItemIdx = uwItemOffset / pstAllocator->uwItemSz; - - if ((uwItemOffset % pstAllocator->uwItemSz) || (uwItemIdx >= osAtomicBitsetGetNumBits(pstAllocator->bitset)) || !osAtomicBitsetGetBit(pstAllocator->bitset, uwItemIdx)) - return (UINT32)(-1); - - return uwItemIdx; -} - -UINT32 osSlabAllocatorGetNumItems(OS_SLAB_ALLOCATOR *pstAllocator) -{ - return osAtomicBitsetGetNumBits(pstAllocator->bitset); -} - -BOOL osSlabAllocatorEmpty(OS_SLAB_ALLOCATOR *pstAllocator) -{ - return osAtomicBitsetEmpty(pstAllocator->bitset); -} - -UINT32 osSlabAllocatorGetUsedItemCnt(OS_SLAB_ALLOCATOR *pstAllocator) -{ - UINT32 uwUsed, uwIdx; - struct AtomicBitset *p_bitset = pstAllocator->bitset; - for (uwUsed = 0, uwIdx = 0; uwIdx < p_bitset->numBits; uwIdx++) - { - if (osAtomicBitsetGetBit(p_bitset, uwIdx)) - { - uwUsed ++; - } - } - return uwUsed; -} - -VOID osSlabAllocatorGetSlabInfo(OS_SLAB_ALLOCATOR *pstAllocator, UINT32 *puwItemSz, UINT32 *puwItemCnt, UINT32 *puwCurUsage) -{ - *puwItemSz = pstAllocator->uwItemSz; - *puwItemCnt = osAtomicBitsetGetNumBits(pstAllocator->bitset); - *puwCurUsage = osSlabAllocatorGetUsedItemCnt(pstAllocator); -} - -BOOL osSlabAllocatorCheck(OS_SLAB_ALLOCATOR *pstAllocator, VOID* ptrP) -{ - UINT8 *ptr = (UINT8*)ptrP; - UINT32 uwItemOffset = ptr - pstAllocator->ucDataChunks; - UINT32 uwItemIdx = uwItemOffset / pstAllocator->uwItemSz; - - //check for invalid inputs - - if ((uwItemOffset % pstAllocator->uwItemSz) || (uwItemIdx >= osAtomicBitsetGetNumBits(pstAllocator->bitset)) - || !osAtomicBitsetGetBit(pstAllocator->bitset, uwItemIdx)) - return FALSE; - - return TRUE; -} - diff --git a/kernel/base/mem/common/los_slabmem.c b/kernel/base/mem/common/los_slabmem.c deleted file mode 100644 index 28698be20..000000000 --- a/kernel/base/mem/common/los_slabmem.c +++ /dev/null @@ -1,321 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2017>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#define _LOS_SLAB_MEM_C_ - -#include -#include -#include - -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) -#include "los_memstat.inc" -#endif - -VOID *osSlabBlockHeadFill(OS_SLAB_BLOCK_NODE *pstSlabNode, UINT32 uwBlkSz) -{ - OS_SLAB_BLOCK_MAGIC_SET(pstSlabNode); - OS_SLAB_BLOCK_SIZE_SET(pstSlabNode, uwBlkSz); - OS_SLAB_BLOCK_ID_SET(pstSlabNode, 0);//now undefine how to use ID - return (VOID *)(pstSlabNode + 1); -} - -/***************************************************************************** - Function : osSlabMemInit - Description : To initialize the slab memory management - Input : None - Output : None - Return : None -*****************************************************************************/ -BOOL osSlabMemInit(VOID *pPool) -{ - struct LOS_SLAB_CONTROL_HEADER *pstSlabMemHead = osSlabCtrlHdrGet(pPool); - UINT32 uwIdx = 0; - UINT32 uwTmp = 0; - UINT32 uwBlkSz = 0; - UINT32 uwBlkCnt = 0; - - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - uwBlkSz = (SLAB_MEM_CALSS_STEP_SIZE << uwIdx); - uwBlkCnt = SLAB_MEM_ALLOCATOR_SIZE / uwBlkSz; - pstSlabMemHead->stSlabClass[uwIdx].blkSz = uwBlkSz; - pstSlabMemHead->stSlabClass[uwIdx].blkCnt = uwBlkCnt; - pstSlabMemHead->stSlabClass[uwIdx].blkUsedCnt = 0; - if (NULL != pstSlabMemHead->stSlabClass[uwIdx].alloc) - { - PRINT_WARN("SlabMemAllocator[%d] inited before\n", uwIdx); - uwTmp++; - } - else - { - pstSlabMemHead->stSlabClass[uwIdx].alloc = osSlabAllocatorNew(pPool, uwBlkSz + sizeof(OS_SLAB_BLOCK_NODE), (UINT32)sizeof(VOID *), uwBlkCnt); - } - } - - return ((0 == uwTmp) ? TRUE : FALSE); -} - -/***************************************************************************** - Function : osSlabMemAlloc - Description : To alloc memory block - Input : UITN32 sz --- size of the memory we want to alloc - Output : None - Return : pointer :the address of the memory we alloced -*****************************************************************************/ -VOID *osSlabMemAlloc(VOID *pPool, UINT32 uwSz) -{ - VOID *pRet = NULL; - UINTPTR uvIntSave; - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = osSlabCtrlHdrGet(pPool); - OS_SLAB_MEM *pstSlabAlloc = NULL; - UINT32 uwIdx = 0; - - if (uwSz > (SLAB_MEM_CALSS_STEP_SIZE << (SLAB_MEM_COUNT - 1))) - { - return NULL; - } - - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - if (uwSz<= pstSlabMem->stSlabClass[uwIdx].blkSz) - { - uvIntSave = LOS_IntLock(); - - if (pstSlabMem->stSlabClass[uwIdx].blkUsedCnt >= pstSlabMem->stSlabClass[uwIdx].blkCnt) - { - (VOID)LOS_IntRestore(uvIntSave); - return NULL; - } - - if (NULL == pstSlabMem->stSlabClass[uwIdx].alloc) - { - (VOID)LOS_IntRestore(uvIntSave); - return NULL; - } - - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - pRet = osSlabAllocatorAlloc(pstSlabAlloc->alloc); - if (NULL != pRet) - { - /* alloc success */ - pRet = osSlabBlockHeadFill((OS_SLAB_BLOCK_NODE *)pRet, pstSlabMem->stSlabClass[uwIdx].blkSz); - pstSlabMem->stSlabClass[uwIdx].blkUsedCnt++; -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_ADD_USED(pstSlabMem->stSlabClass[uwIdx].blkSz); -#endif - } - - (VOID)LOS_IntRestore(uvIntSave); - return pRet; - } - } - - return NULL; -} - -/***************************************************************************** - Function : osSlabMemFree - Description : To free the memory block - Input : VOID* pPtr: the pointer of heap memory we want to free - Output : None - Return : TRUE:success FALSE:error -*****************************************************************************/ -BOOL osSlabMemFree(VOID *pPool, VOID* pPtr) -{ - UINTPTR uvIntSave; - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = osSlabCtrlHdrGet(pPool); - BOOL bRet = FALSE; - OS_SLAB_MEM *pstSlabAlloc; - UINT32 uwIdx = 0; - OS_SLAB_BLOCK_NODE *pstSlabNode = OS_SLAB_BLOCK_HEAD_GET(pPtr); - - if (!OS_ALLOC_FROM_SLAB_CHECK(pstSlabNode)) - { - return FALSE; - } - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - if (OS_SLAB_BLOCK_SIZE_GET(pstSlabNode) <= pstSlabMem->stSlabClass[uwIdx].blkSz) - { - uvIntSave = LOS_IntLock(); - - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - if (TRUE == osSlabAllocatorFree(pstSlabAlloc->alloc, pstSlabNode)) - { - bRet = TRUE; - pstSlabMem->stSlabClass[uwIdx].blkUsedCnt--; -#if (LOSCFG_MEM_TASK_USED_STATISTICS == YES) - OS_MEM_REDUCE_USED(pstSlabMem->stSlabClass[uwIdx].blkSz); -#endif - } - - (VOID)LOS_IntRestore(uvIntSave); - return bRet; - } - } - return FALSE; -} - -/***************************************************************************** - Function : osSlabMemDeinit - Description : deinitialize the slab memory ,set back to the original status - Input : None - Output : None - Return : None -*****************************************************************************/ -VOID osSlabMemDeinit(VOID *pPool) -{ - UINT32 uwIdx; - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = NULL; - OS_SLAB_MEM *pstSlabAlloc; - UINT32 uwBlkSz; - UINT32 uwBlkCnt; - - if (NULL == pPool) - { - return ; - } - pstSlabMem = osSlabCtrlHdrGet(pPool); - - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - uwBlkSz = (0x10 << uwIdx); - uwBlkCnt = SLAB_MEM_ALLOCATOR_SIZE / uwBlkSz; - pstSlabMem->stSlabClass[uwIdx].blkSz = uwBlkSz; - pstSlabMem->stSlabClass[uwIdx].blkCnt = uwBlkCnt; - if (NULL != pstSlabMem->stSlabClass[uwIdx].alloc) - { - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - osSlabAllocatorDestroy(pPool, pstSlabAlloc->alloc); - pstSlabMem->stSlabClass[uwIdx].alloc = NULL; - } - } - return ; -} - -UINT32 osSlabMemCheck(VOID *pPool, VOID* pPtr) -{ - UINTPTR uvIntSave; - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = osSlabCtrlHdrGet(pPool); - UINT32 uwRetBlkSz = (UINT32)-1; - OS_SLAB_MEM *pstSlabAlloc; - UINT32 uwIdx = 0; - OS_SLAB_BLOCK_NODE *pstSlabNode = OS_SLAB_BLOCK_HEAD_GET(pPtr); - - if ((!OS_ALLOC_FROM_SLAB_CHECK(pstSlabNode)) - || (OS_SLAB_BLOCK_SIZE_GET(pstSlabNode) > pstSlabMem->stSlabClass[SLAB_MEM_COUNT - 1].blkSz)) - { - return uwRetBlkSz; - } - - uvIntSave = LOS_IntLock(); - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - if (osSlabAllocatorCheck(pstSlabAlloc->alloc, pstSlabNode) == TRUE) - { - uwRetBlkSz = pstSlabMem->stSlabClass[uwIdx].blkSz; - } - } - (VOID)LOS_IntRestore(uvIntSave); - - return uwRetBlkSz; -} - -UINT32 osSlabStatisticsGet(VOID *pPool, LOS_SLAB_STATUS *pstStatus) -{ - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = NULL; - OS_SLAB_MEM *pstSlabAlloc; - UINT32 uwItemSz = 0; - UINT32 uwItemCnt = 0; - UINT32 uwCurUsage = 0; - UINT32 uwTotalUsage = 0; - UINT32 uwTotalMem = 0; - UINT32 uwTotalallocCount = 0; - UINT32 uwTotalfreeCount = 0; - UINT32 uwIdx = 0; - - if ((NULL == pstStatus) || (NULL == pPool)) - { - return LOS_NOK; - } - pstSlabMem = osSlabCtrlHdrGet(pPool); - - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - - osSlabAllocatorGetSlabInfo(pstSlabAlloc->alloc, &uwItemSz, &uwItemCnt, &uwCurUsage); - uwTotalUsage += (uwCurUsage * uwItemSz); - uwTotalMem += (uwItemCnt * uwItemSz); - uwTotalallocCount += pstSlabMem->stSlabClass[uwIdx].blkUsedCnt; - uwTotalfreeCount += pstSlabMem->stSlabClass[uwIdx].blkCnt - pstSlabMem->stSlabClass[uwIdx].blkUsedCnt; - } - - if (uwTotalMem < uwTotalUsage) - { - return LOS_NOK; - } - - pstStatus->totalSize = uwTotalMem; - pstStatus->usedSize = uwTotalUsage; - pstStatus->freeSize = pstStatus->totalSize - pstStatus->usedSize; - pstStatus->allocCount = uwTotalallocCount; - pstStatus->freeCount = uwTotalfreeCount; - return LOS_OK; -} - -UINT32 osSlabGetMaxFreeBlkSize(VOID *pPool) -{ - struct LOS_SLAB_CONTROL_HEADER *pstSlabMem = osSlabCtrlHdrGet(pPool); - OS_SLAB_MEM *pstSlabAlloc; - UINT32 uwItemSz = 0; - UINT32 uwItemCnt = 0; - UINT32 uwCurUsage = 0; - int uwIdx = 0; - - for (uwIdx = SLAB_MEM_COUNT - 1; uwIdx >= 0; uwIdx--) - { - pstSlabAlloc = &(pstSlabMem->stSlabClass[uwIdx]); - if (pstSlabAlloc->alloc) - { - osSlabAllocatorGetSlabInfo(pstSlabAlloc->alloc, &uwItemSz, &uwItemCnt, &uwCurUsage); - if (uwCurUsage != uwItemCnt) - { - return uwItemSz; - } - } - } - - return 0; -} diff --git a/kernel/base/mem/common/memrecord/los_binarytree.c b/kernel/base/mem/common/memrecord/los_binarytree.c new file mode 100644 index 000000000..6cb577c7d --- /dev/null +++ b/kernel/base/mem/common/memrecord/los_binarytree.c @@ -0,0 +1,252 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS BinTree Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#include "los_config.h" + +#ifdef LOSCFG_MEM_RECORDINFO +#include "los_binarytree_pri.h" +#include "los_typedef.h" +#include "los_memory.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +UINT32 OsBinTreeInsert(const VOID *node, UINT32 nodeLen, BinNode **leaf, + BinNode *(*GetMyBinNode)(UINT32 *nodeID), + INT32 (*CompareNode)(const VOID *node1, const VOID *node2)) +{ + UINT32 nodeID; + INT32 result; + BinNode **currentNode = leaf; + + if (leaf == NULL) { + return OS_INVALID; + } + + do { + if (*currentNode != NULL) { + result = CompareNode(node, (const VOID *)(*currentNode)); + if (result == 0) { + return (*currentNode)->nodeID; + } else if (result < 0) { + currentNode = (BinNode **)(&((*currentNode)->left)); + } else { + currentNode = (BinNode **)(&((*currentNode)->right)); + } + } else { + (*currentNode) = GetMyBinNode(&nodeID); + if (*currentNode == NULL) { + return OS_INVALID; + } + + (VOID)memcpy_s((*currentNode)->keyValue, (nodeLen - sizeof(BinNode)), + ((BinNode *)node)->keyValue, (nodeLen - sizeof(BinNode))); + (*currentNode)->nodeID = nodeID; + /* initialize the children to NULL */ + (*currentNode)->left = NULL; + (*currentNode)->right = NULL; + + return (*currentNode)->nodeID; + } + } while (1); +} + +/* LRNODE */ +LinkRegNode g_linkRegNode[LR_COUNT]; +UINT32 g_linkRegNodeIndex = 0; +LinkRegNode *g_linkRegRoot = NULL; +INT32 OsCompareLRNode(const VOID *node1, const VOID *node2) +{ + LinkRegNode *linkRegNode1 = (LinkRegNode *)node1; + LinkRegNode *linkRegNode2 = (LinkRegNode *)node2; + if (linkRegNode1->linkReg1 < linkRegNode2->linkReg1) { + return -1; + } else if ((linkRegNode1->linkReg1 == linkRegNode2->linkReg1) && + (linkRegNode1->linkReg2 < linkRegNode2->linkReg2)) { + return -1; + } else if ((linkRegNode1->linkReg1 == linkRegNode2->linkReg1) && + (linkRegNode1->linkReg2 == linkRegNode2->linkReg2) && + (linkRegNode1->linkReg3 < linkRegNode2->linkReg3)) { + return -1; + } else if ((linkRegNode1->linkReg1 == linkRegNode2->linkReg1) && + (linkRegNode1->linkReg2 == linkRegNode2->linkReg2) && + (linkRegNode1->linkReg3 == linkRegNode2->linkReg3)) { + return 0; + } else { + return 1; + } +} + +BinNode *OsGetLRBinNode(UINT32 *nodeID) +{ + if (g_linkRegNodeIndex < LR_COUNT) { + *nodeID = g_linkRegNodeIndex; + return (BinNode *)(&g_linkRegNode[g_linkRegNodeIndex++]); + } else { + *nodeID = (UINT32)-1; + return NULL; + } +} + +/* ADDRNODE */ +AddrNode g_addrNode[ADDR_COUNT]; +UINT32 g_addrNodeIndex = 0; +AddrNode *g_addrRoot = NULL; +INT32 OsCompareAddrNode(const VOID *node1, const VOID *node2) +{ + AddrNode *addrNode1 = (AddrNode *)node1; + AddrNode *addrNode2 = (AddrNode *)node2; + if (addrNode1->addr < addrNode2->addr) { + return -1; + } else if (addrNode1->addr == addrNode2->addr) { + return 0; + } else { + return 1; + } +} + +BinNode *OsGetAddrBinNode(UINT32 *nodeID) +{ + if (g_addrNodeIndex < ADDR_COUNT) { + *nodeID = g_addrNodeIndex; + return (BinNode *)(&g_addrNode[g_addrNodeIndex++]); + } else { + *nodeID = (UINT32)-1; + return NULL; + } +} + +/* REQSIZENODE */ +ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT]; +UINT32 g_reqSizeNodeIndex = 0; +ReqSizeNode *g_reqSizeRoot = NULL; + +INT32 OsCompareReqSizeNode(const VOID *node1, const VOID *node2) +{ + ReqSizeNode *reqSizeNode1 = (ReqSizeNode *)node1; + ReqSizeNode *reqSizeNode2 = (ReqSizeNode *)node2; + if (reqSizeNode1->reqSize < reqSizeNode2->reqSize) { + return -1; + } else if (reqSizeNode1->reqSize == reqSizeNode2->reqSize) { + return 0; + } else { + return 1; + } +} + +BinNode *OsGetReqSizeBinNode(UINT32 *nodeID) +{ + if (g_reqSizeNodeIndex < REQ_SIZE_COUNT) { + *nodeID = g_reqSizeNodeIndex; + return (BinNode *)(&g_reqSizeNode[g_reqSizeNodeIndex++]); + } else { + *nodeID = (UINT32)-1; + return NULL; + } +} + +/* TASKIDNODE */ +STATIC TaskIDNode g_taskIDNode[TASK_ID_COUNT]; +STATIC UINT32 g_taskIDNodeIndex = 0; +STATIC TaskIDNode *g_taskIDRoot = NULL; +INT32 OsCompareTaskIDNode(const VOID *node1, const VOID *node2) +{ + TaskIDNode *taskIDNode1 = (TaskIDNode *)node1; + TaskIDNode *taskIDNode2 = (TaskIDNode *)node2; + if (taskIDNode1->taskID < taskIDNode2->taskID) { + return -1; + } else if (taskIDNode1->taskID == taskIDNode2->taskID) { + return 0; + } else { + return 1; + } +} + +BinNode *OsGetTaskIDBinNode(UINT32 *nodeID) +{ + if (g_taskIDNodeIndex < TASK_ID_COUNT) { + *nodeID = g_taskIDNodeIndex; + return (BinNode *)(&g_taskIDNode[g_taskIDNodeIndex++]); + } else { + *nodeID = (UINT32)-1; + return NULL; + } +} +#define BINARYTREE_TASKID_COUNT 11 +#define BINARYTREE_REQSIZE_COUNT 4 +STATIC const UINT32 g_binaryTreeTaskID[BINARYTREE_TASKID_COUNT] = { 33, 10, 20, 9, 42, 34, 45, 47, 46, 50, 49 }; +STATIC const UINT32 g_binaryTreeReqSize[BINARYTREE_REQSIZE_COUNT] = { 616, 136, 1708, 1580 }; + +VOID OsBinaryTreeInit(VOID) +{ + INT32 index; + LinkRegNode linkRegNode; + AddrNode node; + TaskIDNode taskNode; + ReqSizeNode reqNode; + + /* equal to the middle address of __text_start and __text_end */ + linkRegNode.linkReg1 = (UINTPTR)(((&__text_end - &__text_start) / 2) + &__text_start); + linkRegNode.linkReg2 = linkRegNode.linkReg1; + linkRegNode.linkReg3 = linkRegNode.linkReg1; + (VOID)OsBinTreeInsert(&linkRegNode, sizeof(LinkRegNode), (BinNode **)&g_linkRegRoot, + OsGetLRBinNode, OsCompareLRNode); + + /* equal to the middle address of __bss_end and g_sys_mem_addr_end */ + node.addr = ((g_sys_mem_addr_end - (UINTPTR)(&__bss_end)) / 2) + (UINTPTR)(&__bss_end); + (VOID)OsBinTreeInsert(&node, sizeof(AddrNode), (BinNode **)&g_addrRoot, + OsGetAddrBinNode, OsCompareAddrNode); + + for (index = 0; index < BINARYTREE_TASKID_COUNT; index++) { + taskNode.taskID = g_binaryTreeTaskID[index]; + (VOID)OsBinTreeInsert(&taskNode, sizeof(TaskIDNode), (BinNode **)&g_taskIDRoot, + OsGetTaskIDBinNode, OsCompareTaskIDNode); + } + + for (index = 0; index < BINARYTREE_REQSIZE_COUNT; index++) { + reqNode.reqSize = g_binaryTreeReqSize[index]; + (VOID)OsBinTreeInsert(&reqNode, sizeof(ReqSizeNode), (BinNode **)&g_reqSizeRoot, + OsGetReqSizeBinNode, OsCompareReqSizeNode); + } +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/kernel/base/mem/common/memrecord/los_interto64radix.c b/kernel/base/mem/common/memrecord/los_interto64radix.c new file mode 100644 index 000000000..6e6fea444 --- /dev/null +++ b/kernel/base/mem/common/memrecord/los_interto64radix.c @@ -0,0 +1,89 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Inter to 64radix Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_typedef.h" +#include "los_printf.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* array used for 64 binary conversion, include 64 characters */ +const CHAR g_base64Array[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', + 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '~', '!' +}; + +#define LOGARITHM 6 /* the logarithm of 64 to base 2 */ +#define BASE64_MARK ((1U << LOGARITHM) - 1) + +VOID OsDecTo64F(UINT32 num, CHAR *base64, INT32 base64Len) +{ + INT32 len = base64Len - 1; + UINT32 tempNum = num; + if (base64 == NULL) { + PRINT_ERR("%s:%d input null buf\n", __FUNCTION__, __LINE__); + return; + } + + if (base64Len <= 0) { + PRINT_ERR("%s:%d input illegal Len\n", __FUNCTION__, __LINE__); + return; + } + + while (num) { + if (len < 0) { + PRINT_ERR("Len[%d] is too short, input num: %u\n", base64Len, tempNum); + break; + } + base64[len--] = g_base64Array[num & BASE64_MARK]; + num >>= LOGARITHM; + } + for (; len >= 0; len--) { + base64[len] = '0'; + } + base64[base64Len] = '\0'; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/mem/common/memrecord/los_memrecord.c b/kernel/base/mem/common/memrecord/los_memrecord.c new file mode 100644 index 000000000..ad89e2c16 --- /dev/null +++ b/kernel/base/mem/common/memrecord/los_memrecord.c @@ -0,0 +1,355 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Mem Record Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#include "los_memrecord_pri.h" +#include "stdio.h" +#include "los_memory.h" +#include "los_binarytree_pri.h" +#include "los_event.h" +#include "los_exc.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +enum MemActType { + OS_MEM_VALIDFREE, + OS_MEM_INVALIDFREE, + OS_MEM_ALLOC +}; + +STATIC MemRecordInfo g_memRecord1[RECORD_LEN] = {0}; +STATIC MemRecordInfo g_memRecord2[RECORD_LEN] = {0}; +STATIC MemRecordInfo *g_saveMemRecord = g_memRecord1; +STATIC MemRecordInfo *g_printMemRecord = NULL; +STATIC MemRecordInfo *g_curPtr = NULL; + +STATIC volatile UINT32 g_memRecordIndex = 0; +STATIC volatile UINT32 g_memLastEndIndex = 0; +STATIC EVENT_CB_S g_memShowEvent; + +UINT32 g_memRecordShowEnable = 1; +STATIC UINT32 g_lastAddrNodeIndex = 0; +STATIC UINT32 g_lastReqSizeNodeIndex = 0; +STATIC UINT32 g_lastlinkRegNodeIndex = 0; + +#define INDEX_LENGTH 2 +#define ADDR_ID_LENGTH 3 +#define REQSIZE_ID_LENGTH 2 +#define ACTTYPE_LENGTH 4 +#define TASK_ID_LENGTH 2 +#define SYS_TICK_LENGTH 6 +#define LINK_REG_ID_LENGTH 2 +#define INFO_STR_LENGTH 20 +#define PRINT_STR_LENGTH 32 +#define NODE_VALUE_LENGTH 7 +#define READ_EVENT_MASK 0xFFF +#define WRITE_EVENT 0x112 + +STATIC VOID OsMemRecordCompressInfo(VOID) +{ + UINT32 count; + CHAR infoStr[INFO_STR_LENGTH]; + + UINT32 currentIndex = g_addrNodeIndex; + for (count = g_lastAddrNodeIndex; count < currentIndex; count++) { + OsDecTo64F(g_addrNode[count].leaf.nodeID, infoStr, ADDR_ID_LENGTH); + printf("~^%s%x^~\n", infoStr, g_addrNode[count].addr); + } + g_lastAddrNodeIndex = currentIndex; + + currentIndex = g_reqSizeNodeIndex; + for (count = g_lastReqSizeNodeIndex; count < currentIndex; count++) { + OsDecTo64F(g_reqSizeNode[count].leaf.nodeID, infoStr, REQSIZE_ID_LENGTH); + printf("*^%s%u^*\n", infoStr, g_reqSizeNode[count].reqSize); + } + g_lastReqSizeNodeIndex = currentIndex; + + currentIndex = g_linkRegNodeIndex; + for (count = g_lastlinkRegNodeIndex; count < currentIndex; count++) { + OsDecTo64F(g_linkRegNode[count].leaf.nodeID, infoStr, LINK_REG_ID_LENGTH); + printf("$^%s%x%x%x^$\n", infoStr, g_linkRegNode[count].linkReg1, g_linkRegNode[count].linkReg2, + g_linkRegNode[count].linkReg3); + } + g_lastlinkRegNodeIndex = currentIndex; +} + +STATIC VOID PrintPtrAssign(CHAR *printStr, UINT32 strLen, UINT32 startIndex, UINT32 index) +{ + CHAR nodeValue[NODE_VALUE_LENGTH]; + UINT32 tmpIndex = 0; + + /* 3 bytes for ending "!~" and '\0'. */ + if (strLen < (INDEX_LENGTH + ADDR_ID_LENGTH + REQSIZE_ID_LENGTH + ACTTYPE_LENGTH + + TASK_ID_LENGTH + SYS_TICK_LENGTH + LINK_REG_ID_LENGTH + index + 3)) { + PRINT_ERR("printStr is not big enough\n"); + return; + } + + OsDecTo64F(startIndex, nodeValue, INDEX_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + tmpIndex = 0; + OsDecTo64F(g_curPtr[startIndex].addrID, nodeValue, ADDR_ID_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + tmpIndex = 0; + OsDecTo64F(g_curPtr[startIndex].reqSizeID, nodeValue, REQSIZE_ID_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + tmpIndex = 0; + OsDecTo64F(g_curPtr[startIndex].actType, nodeValue, ACTTYPE_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + tmpIndex = 0; + OsDecTo64F(g_curPtr[startIndex].taskID, nodeValue, TASK_ID_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + tmpIndex = 0; + OsDecTo64F(g_curPtr[startIndex].sysTick, nodeValue, SYS_TICK_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + tmpIndex = 0; + OsDecTo64F(g_curPtr[startIndex].linkRegID, nodeValue, LINK_REG_ID_LENGTH); + printStr[index++] = nodeValue[tmpIndex++]; + printStr[index++] = nodeValue[tmpIndex]; + + printStr[index++] = '!'; + printStr[index++] = '~'; + printStr[index++] = '\0'; + + printf("%s\n", printStr); +} + +STATIC VOID OsMemRecordShow(VOID) +{ + UINT32 index = 0; + UINT32 startIndex = g_memLastEndIndex; + UINT32 endIndex; + MemRecordInfo *printMemRecord = g_printMemRecord; + CHAR printStr[PRINT_STR_LENGTH]; + + if (g_curPtr == NULL) { + g_curPtr = g_printMemRecord; + } + + OsMemRecordCompressInfo(); + + if (g_curPtr != NULL) { + printStr[index++] = '~'; + printStr[index++] = '!'; + if (g_curPtr == printMemRecord) { + while (startIndex < RECORD_LEN) { + PrintPtrAssign(printStr, PRINT_STR_LENGTH, startIndex, index); + startIndex++; + } + g_memLastEndIndex = 0; + } + } + + startIndex = g_memLastEndIndex; + endIndex = g_memRecordIndex; + if ((g_curPtr == g_saveMemRecord) && (g_printMemRecord != NULL) && (startIndex >= endIndex)) { + printf("Rec:error:the printf speed is low,Rnd\n"); + startIndex = 0; + } + + g_curPtr = g_saveMemRecord; + index = 0; + printStr[index++] = '~'; + printStr[index++] = '!'; + while (startIndex < endIndex) { + PrintPtrAssign(printStr, PRINT_STR_LENGTH, startIndex, index); + startIndex++; + } + + g_memLastEndIndex = endIndex; +} + +STATIC VOID OsMemRecordExchange(VOID) +{ + if (g_saveMemRecord == g_memRecord1) { + g_saveMemRecord = g_memRecord2; + g_printMemRecord = g_memRecord1; + } else { + g_saveMemRecord = g_memRecord1; + g_printMemRecord = g_memRecord2; + } + g_memRecordIndex = 0; + (VOID)LOS_EventWrite(&g_memShowEvent, WRITE_EVENT); +} + +#define LINK_REG1_INDEX 1 +#define LINK_REG2_INDEX 2 +#define LINK_REG3_INDEX 3 +#define LINK_REG_NUM 3 + +STATIC INLINE VOID OsMemRecordLR(LinkRegNode *linkRegNode) +{ + UINTPTR framePtr, framePtrTmp; + UINT32 index = 0; + + linkRegNode->linkReg1 = 0; + linkRegNode->linkReg2 = 0; + linkRegNode->linkReg3 = 0; + + framePtr = Get_Fp(); + while ((framePtr > OS_SYS_FUNC_ADDR_START) && + (framePtr < OS_SYS_FUNC_ADDR_END) && + ((framePtr % sizeof(CHAR *)) == 0)) { + framePtrTmp = framePtr; + if (index == LINK_REG1_INDEX) { + linkRegNode->linkReg1 = *((UINTPTR *)(framePtrTmp)); + } else if (index == LINK_REG2_INDEX) { + linkRegNode->linkReg2 = *((UINTPTR *)(framePtrTmp)); + } else if (index == LINK_REG3_INDEX) { + linkRegNode->linkReg3 = *((UINTPTR *)(framePtrTmp)); + } + framePtr = *((UINTPTR *)(framePtrTmp - sizeof(UINTPTR *))); + index++; + if (index == (LINK_REG_NUM + 1)) { + break; + } + } +} + +STATIC VOID OsMemRecordTaskID(VOID) +{ + LosTaskCB *runTask = OsCurrTaskGet(); + if (runTask != NULL) { + g_saveMemRecord[g_memRecordIndex].taskID = LOS_CurTaskIDGet(); + } else { + g_saveMemRecord[g_memRecordIndex].taskID = 0; + } +} + +STATIC INLINE VOID OsMemRecord(const VOID *ptr, UINT32 size) +{ + UINT64 tickCount = LOS_TickCountGet(); + UINT32 nodeID; + LinkRegNode linkRegNode; + AddrNode node; + ReqSizeNode reqNode; + + OsMemRecordLR(&linkRegNode); + nodeID = OsBinTreeInsert(&linkRegNode, sizeof(linkRegNode), (BinNode **)&g_linkRegRoot, OsGetLRBinNode, + OsCompareLRNode); + if (nodeID == OS_INVALID) { + PRINT_WARN("LIST g_linkRegRoot insert linkRegNode failed!\n"); + } + g_saveMemRecord[g_memRecordIndex].linkRegID = nodeID; + + node.addr = (UINTPTR)ptr; + nodeID = OsBinTreeInsert(&node, sizeof(AddrNode), (BinNode **)&g_addrRoot, OsGetAddrBinNode, + OsCompareAddrNode); + if (nodeID == OS_INVALID) { + PRINT_WARN("LIST g_addrRoot insert addrNode failed!\n"); + } + g_saveMemRecord[g_memRecordIndex].addrID = nodeID; + g_saveMemRecord[g_memRecordIndex].sysTick = tickCount; + + OsMemRecordTaskID(); + + reqNode.reqSize = size; + nodeID = OsBinTreeInsert(&reqNode, sizeof(ReqSizeNode), (BinNode **)&g_reqSizeRoot, OsGetReqSizeBinNode, + OsCompareReqSizeNode); + if (nodeID == OS_INVALID) { + PRINT_WARN("LIST g_reqSizeRoot insert reqSizeNode failed!\n"); + } + g_saveMemRecord[g_memRecordIndex].reqSizeID = nodeID; + + g_memRecordIndex++; + if (g_memRecordIndex == RECORD_LEN) { + OsMemRecordExchange(); + } +} + +VOID OsMemRecordMalloc(const VOID *ptr, UINT32 size) +{ + if (g_memRecordShowEnable == 0) { + return; + } + + OsMemRecord(ptr, size); + g_saveMemRecord[g_memRecordIndex].actType = OS_MEM_ALLOC; +} + +VOID OsMemRecordFree(const VOID *ptr, UINT32 size) +{ + UINT32 actType; + if (g_memRecordShowEnable == 0) { + return; + } + actType = (size == 0) ? OS_MEM_INVALIDFREE : OS_MEM_VALIDFREE; + OsMemRecord(ptr, size); + g_saveMemRecord[g_memRecordIndex].actType = actType; +} + +VOID OsMemRecordShowTask(VOID) +{ + (VOID)LOS_EventInit(&g_memShowEvent); + while (1) { + (VOID)LOS_EventRead(&g_memShowEvent, READ_EVENT_MASK, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, MEM_RECORDSHOW_TIMEOUT); + if (g_memRecordShowEnable) { + OsMemRecordShow(); + } + } +} + +VOID OsMemRecordShowSet(UINT32 value) +{ + g_memRecordShowEnable = value; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/base/mem/membox/los_membox.c b/kernel/base/mem/membox/los_membox.c index 689604754..c3f30de80 100644 --- a/kernel/base/mem/membox/los_membox.c +++ b/kernel/base/mem/membox/los_membox.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS memory Module Implementation * 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 @@ -22,23 +22,19 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_typedef.h" +#include "los_membox.h" #include "los_hwi.h" -#include "los_membox.ph" - -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_memcheck.ph" -#endif +#include "los_spinlock.h" #ifdef __cplusplus #if __cplusplus @@ -46,243 +42,189 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/** - * The address of the static memory pool must be aligned to the boundary of 4. - */ -#define OS_BOXMEM_BASE_ALIGN 4 -#define IS_BOXMEM_ALIGNED(value, alignSize) (0 == (((UINT32)(value)) & ((UINT32)(alignSize - 1)))) - -/** - * Get the address of the next memory node in the static memory pool. - */ -#define OS_MEMBOX_NODE_NEXT(addr, uwBlkSize) (LOS_MEMBOX_NODE *)((UINT8 *)(addr) + (uwBlkSize)) - -/** - * The magic word of the memory box. - */ -#ifdef LOS_MEMBOX_MAGIC_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) +#ifdef LOSCFG_AARCH64 +#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 #else -#define OS_MEMBOX_SET_MAGIC(addr) -#define OS_MEMBOX_CHECK_MAGIC(addr) LOS_OK +#define OS_MEMBOX_MAGIC 0xa55a5aa5 #endif - -/** - * Get the address of memory block according to the magic word information. - */ -#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)) - - -/***************************************************************************** - Function : osCheckBoxMem - Description : Check whether the memory block is valid - Input : pstBoxInfo --- Pointer to the memory pool - pstNode --- Pointer to the memory block that will be checked - Output : None - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT static INLINE UINT32 osCheckBoxMem(const LOS_MEMBOX_INFO *pstBoxInfo, const VOID *pstNode) +#define OS_MEMBOX_SET_MAGIC(addr) \ + ((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC +#define OS_MEMBOX_CHECK_MAGIC(addr) \ + ((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) + +#define OS_MEMBOX_USER_ADDR(addr) \ + ((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) +#define OS_MEMBOX_NODE_ADDR(addr) \ + ((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) +/* spinlock for mem module */ +LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin); +#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state)) +#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state)) + +STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node) { - UINT32 uwOffSet; + UINT32 offset; - if (pstBoxInfo->uwBlkSize == 0) - { + if (boxInfo->uwBlkSize == 0) { return LOS_NOK; } - uwOffSet = (UINT32)pstNode - (UINT32)(pstBoxInfo + 1); - if ((uwOffSet % pstBoxInfo->uwBlkSize) != 0) - { + offset = (UINTPTR)node - (UINTPTR)(boxInfo + 1); + if ((offset % boxInfo->uwBlkSize) != 0) { return LOS_NOK; } - if ((uwOffSet / pstBoxInfo->uwBlkSize) >= pstBoxInfo->uwBlkNum) - { + if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { return LOS_NOK; } - return OS_MEMBOX_CHECK_MAGIC(pstNode); + return OS_MEMBOX_CHECK_MAGIC(node); } -/***************************************************************************** - Function : LOS_MemboxInit - Description : Initialize Static Memory pool - Input : pBoxMem --- Pointer to the memory pool - uwBoxSize --- Size of the memory pool - uwBlkSize --- Size of the memory block - Output : None - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pBoxMem, UINT32 uwBoxSize, UINT32 uwBlkSize) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize) { - LOS_MEMBOX_INFO *pstBoxInfo = (LOS_MEMBOX_INFO *)pBoxMem; - LOS_MEMBOX_NODE *pstNode = NULL; - UINT32 i; - UINTPTR uvIntSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + UINT32 index; + UINT32 intSave; - if (pBoxMem == NULL || uwBlkSize == 0 || uwBoxSize < sizeof(LOS_MEMBOX_INFO)) - { + if (pool == NULL) { return LOS_NOK; } - if (!IS_BOXMEM_ALIGNED(pBoxMem, OS_BOXMEM_BASE_ALIGN)) - { + if (blkSize == 0) { return LOS_NOK; } - uvIntSave = LOS_IntLock(); - - /* - * The node size is aligned to the next 4 boundary. - * Memory that is not enough for one node size in the memory pool will be ignored. - */ - pstBoxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(uwBlkSize + LOS_MEMBOX_MAGIC_SIZE); - pstBoxInfo->uwBlkNum = (uwBoxSize - sizeof(LOS_MEMBOX_INFO)) / pstBoxInfo->uwBlkSize; - pstBoxInfo->uwBlkCnt = 0; + if (poolSize < sizeof(LOS_MEMBOX_INFO)) { + return LOS_NOK; + } - if (pstBoxInfo->uwBlkNum == 0) - { - LOS_IntRestore(uvIntSave); + MEMBOX_LOCK(intSave); + boxInfo->uwBlkSize = LOS_MEMBOX_ALLIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); + boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize; + boxInfo->uwBlkCnt = 0; + if (boxInfo->uwBlkNum == 0) { + MEMBOX_UNLOCK(intSave); return LOS_NOK; } - pstNode = (LOS_MEMBOX_NODE *)(pstBoxInfo + 1); - pstBoxInfo->stFreeList.pstNext = pstNode; + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); - for (i = 0; i < pstBoxInfo->uwBlkNum - 1; ++i) - { - pstNode->pstNext = OS_MEMBOX_NODE_NEXT(pstNode, pstBoxInfo->uwBlkSize); - pstNode = pstNode->pstNext; + boxInfo->stFreeList.pstNext = node; + + for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) { + node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize); + node = node->pstNext; } - pstNode->pstNext = (LOS_MEMBOX_NODE *)NULL; /* The last node */ -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - osMemInfoUpdate(pBoxMem, uwBoxSize, MEM_MANG_MEMBOX); -#endif + node->pstNext = NULL; - (VOID)LOS_IntRestore(uvIntSave); + MEMBOX_UNLOCK(intSave); return LOS_OK; } -/***************************************************************************** - Function : LOS_MemboxAlloc - Description : Allocate Memory block from Static Memory pool - Input : pBoxMem --- Pointer to memory pool - Output : None - Return : Pointer to allocated memory block -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pBoxMem) +LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool) { - LOS_MEMBOX_INFO *pstBoxInfo = (LOS_MEMBOX_INFO *)pBoxMem; - LOS_MEMBOX_NODE *pstNode = NULL; - LOS_MEMBOX_NODE *pRet = NULL; - UINTPTR uvIntSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + LOS_MEMBOX_NODE *nodeTmp = NULL; + UINT32 intSave; - if (pBoxMem == NULL) - { + if (pool == NULL) { return NULL; } - uvIntSave = LOS_IntLock(); - - pstNode = &pstBoxInfo->stFreeList; - if (pstNode->pstNext != NULL) - { - pRet = pstNode->pstNext; - pstNode->pstNext = pRet->pstNext; - OS_MEMBOX_SET_MAGIC(pRet); - pstBoxInfo->uwBlkCnt++; + MEMBOX_LOCK(intSave); + node = &(boxInfo->stFreeList); + if (node->pstNext != NULL) { + nodeTmp = node->pstNext; + node->pstNext = nodeTmp->pstNext; + OS_MEMBOX_SET_MAGIC(nodeTmp); + boxInfo->uwBlkCnt++; } + MEMBOX_UNLOCK(intSave); - (VOID)LOS_IntRestore(uvIntSave); - - return pRet == NULL ? NULL : OS_MEMBOX_USER_ADDR(pRet); + return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp); } -/***************************************************************************** - Function : LOS_MemboxFree - Description : Free Memory block and return it to Static Memory pool - Input : pBoxMem --- Pointer to memory pool - pBox --- Pointer to memory block to free - Output : None - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pBoxMem, VOID *pBox) +LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box) { - LOS_MEMBOX_INFO *pstBoxInfo = (LOS_MEMBOX_INFO *)pBoxMem; - UINT32 uwRet = LOS_NOK; - UINTPTR uvIntSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + UINT32 ret = LOS_NOK; + UINT32 intSave; - if (pBoxMem == NULL || pBox == NULL) - { + if ((pool == NULL) || (box == NULL)) { return LOS_NOK; } - uvIntSave = LOS_IntLock(); - - do - { - LOS_MEMBOX_NODE *pstNode = OS_MEMBOX_NODE_ADDR(pBox); - - if (osCheckBoxMem(pstBoxInfo, pstNode) != LOS_OK) - { + MEMBOX_LOCK(intSave); + do { + LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box); + if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { break; } - pstNode->pstNext = pstBoxInfo->stFreeList.pstNext; - pstBoxInfo->stFreeList.pstNext = pstNode; - pstBoxInfo->uwBlkCnt--; - uwRet = LOS_OK; + node->pstNext = boxInfo->stFreeList.pstNext; + boxInfo->stFreeList.pstNext = node; + boxInfo->uwBlkCnt--; + ret = LOS_OK; } while (0); + MEMBOX_UNLOCK(intSave); + + return ret; +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - (VOID)LOS_IntRestore(uvIntSave); + if ((pool == NULL) || (box == NULL)) { + return; + } - return uwRet; + (VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0, + (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE)); } -/***************************************************************************** - Function : LOS_MemboxClr - Description : Clear the memory block - Input : pBoxMem --- Pointer to memory pool - pBox --- Pointer to memory block to clear - Output : None - Return : None -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pBoxMem, VOID *pBox) +LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool) { - LOS_MEMBOX_INFO *pstBoxInfo = (LOS_MEMBOX_INFO *)pBoxMem; + UINT32 index; + UINT32 intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; - if (pBoxMem == NULL || pBox == NULL) - { + if (pool == NULL) { return; } + MEMBOX_LOCK(intSave); + PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); + PRINT_INFO("free node list:\r\n"); - memset(pBox, 0, pstBoxInfo->uwBlkSize - LOS_MEMBOX_MAGIC_SIZE); + for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; + node = node->pstNext, ++index) { + PRINT_INFO("(%u,%p)\r\n", index, node); + } + + PRINT_INFO("all node list:\r\n"); + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) { + PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext); + } + MEMBOX_UNLOCK(intSave); } -/***************************************************************************** - Function : LOS_MemboxStatisticsGet - Description : Get information about membox - Input : pBoxMem --- Pointer to the calculate membox - Output : puwMaxBlk --- Record the total number of membox - puwBlkCnt --- Record the number of the allocated blocks of membox - puwBlkSize --- Record the block size of membox - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(VOID *pBoxMem, UINT32 *puwMaxBlk, UINT32 *puwBlkCnt, UINT32 *puwBlkSize) +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, + UINT32 *blkCnt, UINT32 *blkSize) { - if ((NULL == pBoxMem) || (NULL == puwMaxBlk) || (NULL == puwBlkCnt) || (NULL == puwBlkSize)) - { + if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { return LOS_NOK; } - *puwMaxBlk = ((LOS_MEMBOX_INFO *)pBoxMem)->uwBlkNum; /* Total number of blocks */ - *puwBlkCnt = ((LOS_MEMBOX_INFO *)pBoxMem)->uwBlkCnt; /* The number of allocated blocks */ - *puwBlkSize = ((LOS_MEMBOX_INFO *)pBoxMem)->uwBlkSize; /* Block size */ + *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; + *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; + *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; return LOS_OK; } diff --git a/kernel/base/mem/tlsf/Makefile b/kernel/base/mem/tlsf/Makefile deleted file mode 100644 index a6dcebc81..000000000 --- a/kernel/base/mem/tlsf/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -objs-y += los_memory.o - diff --git a/kernel/base/mem/tlsf/los_memory.c b/kernel/base/mem/tlsf/los_memory.c deleted file mode 100644 index 43ebeeda2..000000000 --- a/kernel/base/mem/tlsf/los_memory.c +++ /dev/null @@ -1,1424 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2017>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#include "string.h" -#include "los_typedef.h" -#include "los_memory.ph" -#include "los_compiler.h" - -#if (LOSCFG_KERNEL_MEM_SLAB == YES) -#include "los_slab.ph" -#endif - -#include "los_hwi.h" -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_exc.ph" -#endif - -#include "los_task.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -LITE_OS_SEC_DATA_INIT static UINT32 g_uwTlsf_AllocCount = 0; -LITE_OS_SEC_DATA_INIT static UINT32 g_uwTlsf_FreeCount = 0; - - -extern ST_LOS_TASK g_stLosTask; - -#define AARCHPTR UINT32 - -LITE_OS_SEC_ALW_INLINE static inline INT32 __log2(UINT32 uwWord) -{ - return uwWord ? (sizeof(uwWord) * 8 - CLZ(uwWord) - 1) : 0; -} - -LITE_OS_SEC_TEXT static inline INT32 tlsf_ffs(UINT32 uwWord) -{ - return __log2(uwWord & (UINT32)(-(UINT32)uwWord)); /*lint !e501*/ -} - -LITE_OS_SEC_TEXT static inline INT32 tlsf_fls(UINT32 uwWord) -{ - const INT32 swBit = uwWord ? 32 - CLZ(uwWord) : 0; - return swBit - 1; -} - -#define tlsf_fls_sizet tlsf_fls - -/* - * Block header structure. - * - * There are several implementation subtleties involved: - * - The prev_phys_block field is only valid if the previous pNode is free. - * - The prev_phys_block field is actually stored at the end of the - * previous pNode. It appears at the beginning of this structure only to - * simplify the implementation. - * - The pNext_free / pPrev_free fields are only valid if the pNode is free. - */ -typedef struct LOS_MEM_DYN_NODE { - /* Points to the previous physical pNode. */ - struct LOS_MEM_DYN_NODE *pstPreNode; - /* The size of this pNode, excluding the pNode header. */ - UINT32 uwSize; - /* Next and previous free blocks. */ - struct LOS_MEM_DYN_NODE *pNext_free; - struct LOS_MEM_DYN_NODE *pPrev_free; -} LOS_MEM_DYN_NODE; - -enum tlsf_public { - SL_INDEX_COUNT_LOG2 = 2, -}; - -enum tlsf_private { - /* All allocation sizes and addresses are aligned to 4 bytes. */ - ALIGN_SIZE_LOG2 = 2, - ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), - FL_INDEX_MAX = 30, - SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), - FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), - FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), - SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), -}; - -#if (LOSCFG_MEM_MUL_POOL == YES) -VOID *g_pPoolHead = NULL; -#endif - -typedef struct LOS_MEM_POOL_INFO { - LOS_MEM_DYN_NODE stBlock_null; -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - struct LOS_SLAB_CONTROL_HEADER stSlabCtrlHdr; -#endif - UINT32 uwPoolSize; - UINT32 fl_bitmap; - UINT32 sl_bitmap[FL_INDEX_COUNT]; - LOS_MEM_DYN_NODE *pstBlocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; - -#if (LOSCFG_MEM_MUL_POOL == YES) - VOID *pNextPool; -#endif -} LOS_MEM_POOL_INFO; - -/* pool_t: a pNode of memory that TLSF can manage. */ -typedef VOID *pool_t; - -/* Add/remove memory pools. */ -pool_t osMemPoolAdd(VOID *tlsf, VOID *pPool, UINT32 uwBytes); - -/* Overheads/limits of internal structures. */ -UINT32 osMemHeadSize(VOID); - -/* Debugging. */ -#define TSLF_CONFIG_DEBUG - -#ifdef TLSF_CONFIG_ASSERT -#include -#define tlsf_assert(expr) assert(expr) -#define alignCheck(align) tlsf_assert(0 == ((align) & ((align) - 1)) && "must align to a power of two"); -#else -#define tlsf_assert(expr) (VOID)(0) -#define alignCheck(align) -#endif - -/* - * Cast and min/max macros. - */ -#define tlsf_cast(t, exp) ((t)(exp)) -#define tlsf_min(a, b) ((a) < (b) ? (a) : (b)) -#define tlsf_max(a, b) ((a) > (b) ? (a) : (b)) - -#define tlsf_offset(a,b) LOS_OFF_SET_OF(a, b) - -LITE_OS_SEC_TEXT VOID *osSlabCtrlHdrGet(VOID *pPool) -{ -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - return (&(tlsf_cast(LOS_MEM_POOL_INFO *, pPool)->stSlabCtrlHdr)); -#else - return NULL; -#endif -} - - -/* - * Since pNode sizes are always at least a multiple of 4, the two least - * significant bits of the size field are used to store the pNode status: - * - bit 0: whether pNode is busy or free - * - bit 1: whether previous pNode is busy or free - */ -static const UINT32 block_header_free_bit = 1 << 0; -static const UINT32 block_header_prev_free_bit = 1 << 1; - -#define DEBUG_SPACE 4 - -/* - * The size of the pNode header exposed to used blocks is the size field. - * The pstPreNode field is stored *inside* the previous free pNode. - */ -static const UINT32 block_header_overhead = tlsf_offset(LOS_MEM_DYN_NODE, uwSize); - -/* User data starts directly after the size field in a used pNode. */ -static const UINT32 block_start_offset = - tlsf_offset(LOS_MEM_DYN_NODE, uwSize) + sizeof(UINT32) + DEBUG_SPACE; /*lint !e413*/ - -/* - * A free pNode must be large enough to store its header minus the size of - * the pstPreNode field, and no larger than the number of addressable - * bits for FL_INDEX. - */ -static const UINT32 block_size_min = - sizeof(LOS_MEM_DYN_NODE) - sizeof(LOS_MEM_DYN_NODE *); -static const UINT32 block_size_max = tlsf_cast(UINT32, 1) << FL_INDEX_MAX; - -#define control_t LOS_MEM_POOL_INFO - -#define OS_MEM_TASKID_SET(node, ID) \ - do \ - { \ - AARCHPTR uwTmp = (AARCHPTR)(((LOS_MEM_DYN_NODE *)node)->pNext_free); \ - uwTmp &= 0xffff0000; \ - uwTmp |= ID; \ - ((LOS_MEM_DYN_NODE *)node)->pNext_free = (LOS_MEM_DYN_NODE *)uwTmp; \ - }while(0) - -#define OS_MEM_TASKID_GET(node) ((AARCHPTR)(((LOS_MEM_DYN_NODE *)node)->pNext_free) & 0xffff) - -VOID osMemInfoPrint(pool_t pPool); -#define IS_ALIGNED(value, alignSize) (0 == (((AARCHPTR)(value)) & ((AARCHPTR)(alignSize - 1)))) -/* - * LOS_MEM_DYN_NODE member functions. - */ -LITE_OS_SEC_TEXT static VOID osMemNodeSizeSet(LOS_MEM_DYN_NODE *pNode, UINT32 uwSize) -{ - pNode->uwSize = uwSize | (pNode->uwSize & (block_header_free_bit | block_header_prev_free_bit)); -} - -LITE_OS_SEC_TEXT static UINT32 osMemNodeSizeGet(const LOS_MEM_DYN_NODE *pNode) -{ - return pNode->uwSize & ~(block_header_free_bit | block_header_prev_free_bit); -} - -LITE_OS_SEC_TEXT static INT32 osMemEndCheck(const LOS_MEM_DYN_NODE *pNode) -{ - return osMemNodeSizeGet(pNode) == 0; -} - -LITE_OS_SEC_TEXT static INT32 osMemFreeCheck(const LOS_MEM_DYN_NODE *pNode) -{ - return tlsf_cast(INT32, pNode->uwSize & block_header_free_bit); -} - -LITE_OS_SEC_TEXT static VOID osMemFreeMark(LOS_MEM_DYN_NODE *pNode) -{ - pNode->uwSize |= block_header_free_bit; -} - -LITE_OS_SEC_TEXT static VOID osMemUsedMark(LOS_MEM_DYN_NODE *pNode) -{ - pNode->uwSize &= ~block_header_free_bit; -} - -LITE_OS_SEC_TEXT static INT32 osMemPreFreeCheck(const LOS_MEM_DYN_NODE *pNode) -{ - return tlsf_cast(INT32, pNode->uwSize & block_header_prev_free_bit); -} - -LITE_OS_SEC_TEXT static VOID osMemPreFreeMark(LOS_MEM_DYN_NODE *pNode) -{ - pNode->uwSize |= block_header_prev_free_bit; -} - -LITE_OS_SEC_TEXT static VOID osMemPreUsedMark(LOS_MEM_DYN_NODE *pNode) -{ - pNode->uwSize &= ~block_header_prev_free_bit; -} - -LITE_OS_SEC_TEXT LOS_MEM_DYN_NODE *osMemPtrToNode(const VOID *pPtr) -{ - return tlsf_cast(LOS_MEM_DYN_NODE *, - tlsf_cast(UINT8*, pPtr) - block_start_offset); -} - -LITE_OS_SEC_TEXT static VOID *osMemNodeToPtr(const LOS_MEM_DYN_NODE *pNode) -{ - return tlsf_cast(VOID *, - tlsf_cast(UINT8 *, pNode) + block_start_offset); -} - -/* Return location of next pNode after pNode of given size. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemPtrOffset(const VOID *pPtr, INT32 swSize) -{ - return tlsf_cast(LOS_MEM_DYN_NODE *, tlsf_cast(AARCHPTR, pPtr) + swSize); -} - -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE * osMemFirstNode(VOID *pPool) -{ - return osMemPtrOffset((const VOID *)((AARCHPTR)pPool + osMemHeadSize()), -(INT32)block_header_overhead); /*lint !e570*/ -} - -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemEndNode(pool_t pPool) -{ - return (LOS_MEM_DYN_NODE *)((AARCHPTR)pPool + ((control_t *)pPool)->uwPoolSize - block_start_offset); -} - -LITE_OS_SEC_TEXT static AARCHPTR osMemEndPtr(pool_t pPool) -{ - return (AARCHPTR)pPool + ((control_t *)pPool)->uwPoolSize; -} - -/* Return location of previous pNode. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemNodePre(const LOS_MEM_DYN_NODE *pNode) -{ - tlsf_assert(osMemPreFreeCheck(pNode) && "previous pNode must be free"); - return pNode->pstPreNode; -} - -/* Return location of next existing pNode. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemNodeNext(const LOS_MEM_DYN_NODE *pNode) -{ - LOS_MEM_DYN_NODE *pNext = osMemPtrOffset( - tlsf_cast(VOID *, pNode), (INT32)osMemNodeSizeGet(pNode)); - tlsf_assert(!osMemEndCheck(pNode)); - return pNext; -} - -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemNextLink(LOS_MEM_DYN_NODE *pNode) -{ - LOS_MEM_DYN_NODE *pNext = osMemNodeNext(pNode); - pNext->pstPreNode = pNode; - return pNext; -} - -LITE_OS_SEC_TEXT static VOID osMemFreeSet(LOS_MEM_DYN_NODE *pNode) -{ - /* Link the pNode to the next pNode, first. */ - LOS_MEM_DYN_NODE *pNext = osMemNextLink(pNode); - osMemPreFreeMark(pNext); - osMemFreeMark(pNode); -} - -LITE_OS_SEC_TEXT static VOID osMemUsedSet(LOS_MEM_DYN_NODE *pNode) -{ - LOS_MEM_DYN_NODE *pNext = osMemNodeNext(pNode); - osMemPreUsedMark(pNext); - osMemUsedMark(pNode); -} - -LITE_OS_SEC_TEXT static AARCHPTR osMemAlignDown(AARCHPTR uwData, UINT32 uwAlign) -{ - alignCheck(uwAlign); - return uwData - (uwData & (uwAlign - 1)); -} - -LITE_OS_SEC_TEXT static AARCHPTR osMemAlignUp(AARCHPTR uwData, UINT32 uwAlign) -{ - alignCheck(uwAlign); - return (uwData + (AARCHPTR)(uwAlign - 1)) & ~((AARCHPTR)(uwAlign - 1)); -} - -LITE_OS_SEC_TEXT static VOID *osMemAlignPtr(const VOID *pPtr, UINT32 uwAlign) -{ - const AARCHPTR uwAligned = (tlsf_cast(AARCHPTR, pPtr) + (AARCHPTR)(uwAlign - 1)) & ~((AARCHPTR)(uwAlign - 1)); - alignCheck(uwAlign); - return tlsf_cast(VOID *, uwAligned); -} - -LITE_OS_SEC_TEXT static UINT32 osMemReqSizeAdjust(UINT32 uwSize, UINT32 uwAlign) -{ - UINT32 uwAdjust = 0; - if (uwSize && uwSize < block_size_max) - { - const UINT32 uwAligned = osMemAlignUp(uwSize, uwAlign) + block_start_offset; - uwAdjust = tlsf_max(uwAligned, block_size_min); - } - return uwAdjust; -} - -LITE_OS_SEC_TEXT static VOID osMemMapInsert(UINT32 uwSize, INT32 *pFli, INT32 *pSli) -{ - INT32 swFl, swSl; - if (uwSize < SMALL_BLOCK_SIZE) - { - /* Store small blocks in first list. */ - swFl = 0; - swSl = tlsf_cast(INT32, uwSize) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT); - } - else - { - swFl = tlsf_fls_sizet(uwSize); - swSl = tlsf_cast(INT32, uwSize >> (swFl - SL_INDEX_COUNT_LOG2)) ^ - (1 << SL_INDEX_COUNT_LOG2); - swFl -= (FL_INDEX_SHIFT - 1); - } - - *pFli = swFl; - *pSli = swSl; - //PRINT_ERR("FL = %d, SL = %d\n", swFl,swSl); -} - -LITE_OS_SEC_TEXT static VOID osMemMapSearch(UINT32 uwSize, INT32 *pFli, INT32 *pSli) -{ - if (uwSize >= SMALL_BLOCK_SIZE) { - const UINT32 uwRound = (1 << (tlsf_fls_sizet(uwSize) - SL_INDEX_COUNT_LOG2)) - 1; - uwSize += uwRound; - } - osMemMapInsert(uwSize, pFli, pSli); -} - -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemSuitableNodeSearch(control_t *control, - INT32 *pFli, INT32 *pSli) -{ - INT32 swFl = *pFli; - INT32 swSl = *pSli; - UINT32 swSl_map = control->sl_bitmap[swFl] & (((UINT32)~0) << swSl); - if (!swSl_map) { - /* No pNode exists. Search in the next largest first-level list. */ - const UINT32 swFl_map = control->fl_bitmap & (((UINT32)~0) << (swFl + 1)); - if (!swFl_map) { - /* No free blocks available, memory has been exhausted. */ - return NULL; - } - - swFl = tlsf_ffs(swFl_map); - *pFli = swFl; - swSl_map = control->sl_bitmap[swFl]; - } - tlsf_assert(swSl_map && "internal error - second level bitmap is null"); - swSl = tlsf_ffs(swSl_map); - *pSli = swSl; - - /* Return the first pNode in the free list. */ - return control->pstBlocks[swFl][swSl]; -} - -LITE_OS_SEC_TEXT static VOID osMemFreeNodeRemove(control_t *control, - LOS_MEM_DYN_NODE *pNode, - INT32 swFl, INT32 swSl) -{ - LOS_MEM_DYN_NODE *pPrev = pNode->pPrev_free; - LOS_MEM_DYN_NODE *pNext = pNode->pNext_free; - tlsf_assert(pPrev && "pPrev_free field can not be null"); - tlsf_assert(pNext && "pNext_free field can not be null"); - pNext->pPrev_free = pPrev; - pPrev->pNext_free = pNext; - /* If this pNode is the head of the free list, set new head. */ - if (control->pstBlocks[swFl][swSl] == pNode) { - control->pstBlocks[swFl][swSl] = pNext; - /* If the new head is null, clear the bitmap. */ - if (pNext == &control->stBlock_null) { - control->sl_bitmap[swFl] &= ~(1 << swSl); /*lint !e502*/ - - /* If the second bitmap is now empty, clear the fl bitmap. */ - if (!control->sl_bitmap[swFl]) { - control->fl_bitmap &= ~(1 << swFl); /*lint !e502*/ - } - } - } -} - -/* Insert a free pNode into the free pNode list. */ -LITE_OS_SEC_TEXT static VOID osMemFreeNodeInsert(control_t *control, - LOS_MEM_DYN_NODE *pNode, - INT32 swFl, INT32 swSl) -{ - LOS_MEM_DYN_NODE *pstCurrent = control->pstBlocks[swFl][swSl]; - //tlsf_assert(pstCurrent && "free list cannot have a null entry"); - //tlsf_assert(pNode && "cannot insert a null entry into the free list"); - - pNode->pNext_free = pstCurrent; - pNode->pPrev_free = &control->stBlock_null; - pstCurrent->pPrev_free = pNode; - - tlsf_assert(osMemNodeToPtr(pNode) == - osMemAlignPtr(osMemNodeToPtr(pNode), ALIGN_SIZE) && - "pNode not aligned properly"); - /* - * Insert the new pNode at the head of the list, and mark the first- - * and second-level bitmaps appropriately. - */ - - control->pstBlocks[swFl][swSl] = pNode; - control->fl_bitmap |= (1 << swFl); - control->sl_bitmap[swFl] |= (1 << swSl); -} - -/* Remove a given pNode from the free list. */ -LITE_OS_SEC_TEXT static VOID osMemNodeRemove(control_t *control, LOS_MEM_DYN_NODE *pNode) -{ - INT32 swFl, swSl; - osMemMapInsert(osMemNodeSizeGet(pNode), &swFl, &swSl); - osMemFreeNodeRemove(control, pNode, swFl, swSl); -} - -/* Insert a given pNode into the free list. */ -LITE_OS_SEC_TEXT static VOID osMemNodeInsert(control_t *control, LOS_MEM_DYN_NODE *pNode) -{ - INT32 swFl, swSl; - osMemMapInsert(osMemNodeSizeGet(pNode), &swFl, &swSl); - osMemFreeNodeInsert(control, pNode, swFl, swSl); -} - -LITE_OS_SEC_TEXT static INT32 osMemNodeSpitCheck(LOS_MEM_DYN_NODE *pNode, UINT32 uwSize) -{ - return osMemNodeSizeGet(pNode) >= sizeof(LOS_MEM_DYN_NODE) + uwSize; -} - -/* Split a pNode into two, the second of which is free. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemNodeSpit(LOS_MEM_DYN_NODE *pNode, UINT32 uwSize) -{ - /* Calculate the amount of space left in the remaining pNode. */ - LOS_MEM_DYN_NODE *remaining = osMemPtrOffset((VOID *)pNode, (INT32)uwSize); - - const UINT32 remain_size = osMemNodeSizeGet(pNode) - (uwSize); - - tlsf_assert(osMemNodeToPtr(remaining) == osMemAlignPtr(osMemNodeToPtr(remaining), - ALIGN_SIZE) && - "remaining pNode not aligned properly"); - - tlsf_assert(osMemNodeSizeGet(pNode) == - remain_size + uwSize); - osMemNodeSizeSet(remaining, remain_size); - tlsf_assert(osMemNodeSizeGet(remaining) >= block_size_min && - "pNode split with invalid size"); - - osMemNodeSizeSet(pNode, uwSize); - osMemFreeSet(remaining); - - return remaining; -} - -/* Absorb a free pNode's storage into an adjacent previous free pNode. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemNodeAbsorb(LOS_MEM_DYN_NODE *pPrev, LOS_MEM_DYN_NODE *pNode) -{ - tlsf_assert(!osMemEndCheck(pPrev) && "previous pNode can't be last"); - /* Note: Leaves flags untouched. */ - pPrev->uwSize += osMemNodeSizeGet(pNode); - (VOID)osMemNextLink(pPrev); - return pPrev; -} - -/* Merge a just-freed pNode with an adjacent previous free pNode. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemPreNodeMerge(control_t *control, - LOS_MEM_DYN_NODE *pNode) -{ - if (osMemPreFreeCheck(pNode)) { - LOS_MEM_DYN_NODE *pPrev = osMemNodePre(pNode); - tlsf_assert(pPrev && "prev physical pNode can't be null"); - tlsf_assert(osMemFreeCheck(pPrev) && - "prev pNode is not free though marked as such"); - osMemNodeRemove(control, pPrev); - pNode = osMemNodeAbsorb(pPrev, pNode); - } - - return pNode; -} - -/* Merge a just-freed pNode with an adjacent free pNode. */ -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemNextNodeMerge(control_t *control, - LOS_MEM_DYN_NODE *pNode) -{ - LOS_MEM_DYN_NODE *pNext = osMemNodeNext(pNode); - tlsf_assert(pNext && "next physical pNode can't be null"); - - if (osMemFreeCheck(pNext)) { - tlsf_assert(!osMemEndCheck(pNode) && "previous pNode can't be last"); - osMemNodeRemove(control, pNext); - pNode = osMemNodeAbsorb(pNode, pNext); - } - - return pNode; -} - -/* Trim any trailing pNode space off the end of a pNode, return to pool. */ -LITE_OS_SEC_TEXT static VOID osMemFreeNodeTrim(control_t *control, - LOS_MEM_DYN_NODE *pNode, - UINT32 uwSize) -{ - tlsf_assert(osMemFreeCheck(pNode) && "pNode must be free"); - if (osMemNodeSpitCheck(pNode, uwSize)) - { - LOS_MEM_DYN_NODE *remaining_block = osMemNodeSpit(pNode, uwSize); - (VOID)osMemNextLink(pNode); - osMemPreFreeMark(remaining_block); - osMemNodeInsert(control, remaining_block); - } -} - -/* Trim any trailing pNode space off the end of a used pNode, return to pool. */ -LITE_OS_SEC_TEXT_MINOR static VOID osMemUsedNodeTrim(control_t *control, - LOS_MEM_DYN_NODE *pNode, - UINT32 uwSize) -{ - tlsf_assert(!osMemFreeCheck(pNode) && "pNode must be used"); - if (osMemNodeSpitCheck(pNode, uwSize)) { - /* If the next pNode is free, we must coalesce. */ - LOS_MEM_DYN_NODE *remaining_block = osMemNodeSpit(pNode, uwSize); - osMemPreUsedMark(remaining_block); - remaining_block->pstPreNode = pNode; - - remaining_block = osMemNextNodeMerge(control, remaining_block); - osMemNodeInsert(control, remaining_block); - } -} - -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemFreeNodeTrimLeading(control_t *control, - LOS_MEM_DYN_NODE *pNode, - UINT32 uwSize) -{ - LOS_MEM_DYN_NODE *remaining_block = pNode; - if (osMemNodeSpitCheck(pNode, uwSize)) { - /* We want the 2nd pNode. */ - remaining_block = osMemNodeSpit(pNode, uwSize); - osMemPreFreeMark(remaining_block); - - (VOID)osMemNextLink(pNode); - osMemNodeInsert(control, pNode); - } - - return remaining_block; -} - -LITE_OS_SEC_TEXT static LOS_MEM_DYN_NODE *osMemFreeNodeLocate(control_t *control, UINT32 uwSize) -{ - INT32 swFl = 0, swSl = 0; - LOS_MEM_DYN_NODE *pNode = NULL; - - if (uwSize) { - osMemMapInsert(uwSize, &swFl, &swSl); - pNode = osMemSuitableNodeSearch(control, &swFl, &swSl); - } - - if (pNode) { - if (osMemNodeSizeGet(pNode) >= uwSize) - goto EXIT; - while (pNode->pNext_free != &control->stBlock_null) - { - pNode = pNode->pNext_free; - if (osMemNodeSizeGet(pNode) >= uwSize) - goto EXIT; - } - osMemMapSearch(uwSize, &swFl, &swSl); - pNode = osMemSuitableNodeSearch(control, &swFl, &swSl); - if (pNode == NULL || osMemNodeSizeGet(pNode) < uwSize) - return NULL; -EXIT: - osMemFreeNodeRemove(control, pNode, swFl, swSl); - } - - if (pNode && !pNode->uwSize) - pNode = NULL; - - return pNode; -} - -LITE_OS_SEC_TEXT static VOID *osMemUsedNodePrepare(control_t *control, LOS_MEM_DYN_NODE *pNode, UINT32 uwSize) -{ - VOID *pPtr = NULL; - if (pNode) - { - tlsf_assert(uwSize && "size must be non-zero"); - osMemFreeNodeTrim(control, pNode, uwSize); - osMemUsedSet(pNode); - - /* If the operation occured before task initialization(g_stLosTask.pstRunTask was not assigned) - or in interrupt,make the value of taskid of pNode to oxffffffff*/ - if (g_stLosTask.pstRunTask != NULL && OS_INT_INACTIVE) - { - OS_MEM_TASKID_SET(pNode, g_stLosTask.pstRunTask->uwTaskID); - } - else - { - /* If the task mode does not initialize, the field is the 0xffffffff */ - OS_MEM_TASKID_SET(pNode, OS_NULL_INT); - /* TODO: the commend task-MEMUSE is not include system initialization malloc */ - } - pPtr = osMemNodeToPtr(pNode); - } - else - { - PRINT_INFO("-----------------------------------------------------------------------------------------------------------\n"); - osMemInfoPrint((pool_t)control); - PRINT_ERR("No suitable free block, require free node size: 0x%x\n", uwSize); - PRINT_INFO("-----------------------------------------------------------------------------------------------------------\n"); - return NULL; - } - return pPtr; -} - -/* Clear structure and point all empty lists at the null pNode. */ -LITE_OS_SEC_TEXT_INIT static VOID osMemControlClear(control_t *control, UINT32 uwBytes) -{ - UINT32 uwFlIndex, uwSlIndex; - - control->stBlock_null.pNext_free = &control->stBlock_null; - control->stBlock_null.pPrev_free = &control->stBlock_null; - - control->uwPoolSize = uwBytes; - - control->fl_bitmap = 0; - for (uwFlIndex = 0; uwFlIndex < FL_INDEX_COUNT; ++uwFlIndex) { - control->sl_bitmap[uwFlIndex] = 0; - for (uwSlIndex = 0; uwSlIndex < SL_INDEX_COUNT; ++uwSlIndex) { - control->pstBlocks[uwFlIndex][uwSlIndex] = &control->stBlock_null; - } - } -} - -/* - * Debugging utilities. - */ -#ifdef TSLF_CONFIG_DEBUG -LITE_OS_SEC_TEXT static UINT32 osMemNodeInsideCheck(pool_t pPool, VOID *pPtr) -{ - if (((AARCHPTR)pPtr < (AARCHPTR)osMemFirstNode(pPool)) || - ((AARCHPTR)pPtr > (AARCHPTR)osMemEndNode(pPool))) - return LOS_NOK; - else - return LOS_OK; -} - -LITE_OS_SEC_TEXT INT32 osMemMagicCheck(pool_t pPool, VOID *pPtr) -{ - const LOS_MEM_DYN_NODE *pNode = NULL; - - if(pPtr == NULL || !IS_ALIGNED(pPtr, sizeof(VOID *))) - { - return LOS_NOK; - } - else - { - pNode = osMemPtrToNode(pPtr); - } - - if (pNode == osMemFirstNode(pPool)) - return LOS_OK; - else if ((AARCHPTR)pNode->pstPreNode & (ALIGN_SIZE - 1)) - return LOS_NOK; - else if(osMemNodeInsideCheck(pPool, pNode->pstPreNode) == LOS_NOK) - return LOS_NOK; - else if ((AARCHPTR)pNode == (AARCHPTR)osMemNodeNext(pNode->pstPreNode)) - return LOS_OK; - else - return LOS_NOK; -} - -LITE_OS_SEC_TEXT UINT32 osMemInfoGet(pool_t pPool, LOS_MEM_STATUS *pstStatus) -{ - LOS_MEM_DYN_NODE *pNode = osMemFirstNode(pPool); - UINT32 uwTotalUsedSize = 0, uwTotalFreeSize = 0, uwMaxFreeNodeSize = 0; - UINT32 uwTmpSize = 0; - UINTPTR uvIntSave; - - if (pstStatus == NULL) - { - return LOS_NOK; - } - - if (pPool == NULL) - { - PRINT_ERR("wrong mem pool addr: 0x%x\n", (UINT32)pPool); - return LOS_NOK; - } - - if (osMemMagicCheck(pPool, (VOID *)osMemEndPtr(pPool)) == LOS_NOK) - { - PRINT_ERR("wrong mem pool addr: 0x%x\n", (UINT32)pPool); - return LOS_NOK; - } - - uvIntSave = LOS_IntLock(); - - while (pNode && !osMemEndCheck(pNode)) { - uwTmpSize = osMemNodeSizeGet(pNode); - if (osMemFreeCheck(pNode)) - { - uwTotalFreeSize += uwTmpSize; - if (uwTmpSize > uwMaxFreeNodeSize) - uwMaxFreeNodeSize = uwTmpSize; - } - else - { - uwTotalUsedSize += uwTmpSize; - } - pNode = osMemNodeNext(pNode); - } - - pstStatus->usedSize = uwTotalUsedSize + block_start_offset; - pstStatus->freeSize = uwTotalFreeSize; - pstStatus->totalSize = uwMaxFreeNodeSize; - pstStatus->allocCount = g_uwTlsf_AllocCount; - pstStatus->freeCount = g_uwTlsf_FreeCount; - - LOS_IntRestore(uvIntSave); - - return LOS_OK; - -} - -LITE_OS_SEC_TEXT VOID osMemInfoPrint(pool_t pPool) -{ - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - LOS_MEM_STATUS stStatus = {0}; - if (LOS_NOK == osMemInfoGet(pPool, &stStatus)) - return; - - PRINT_ERR("pool addr pool size total size used size free size alloc Count free Count\n 0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-16x 0x%-13x 0x%-13x\n", - (UINT32)pPool, pstPoolInfo->uwPoolSize, stStatus.totalSize, stStatus.usedSize, stStatus.freeSize, stStatus.allocCount, stStatus.freeCount); /*lint !e515*/ - return; -} - -LITE_OS_SEC_TEXT_INIT UINT32 osMemPoolSizeGet(VOID * tlsf) -{ - control_t *control = tlsf_cast(control_t *, tlsf); - if (tlsf == NULL) - return LOS_NOK; - - return control->uwPoolSize; -} -#endif /* TLSF_CONFIG_DEBUG */ - -LITE_OS_SEC_TEXT_INIT UINT32 osMemHeadSize(VOID) -{ - return sizeof(control_t); -} - -LITE_OS_SEC_TEXT_INIT pool_t osMemPoolAdd(VOID *tlsf, VOID *pPool, UINT32 uwBytes) -{ - LOS_MEM_DYN_NODE *pNode; - LOS_MEM_DYN_NODE *pNext; - - const UINT32 uwPoolBytes = osMemAlignDown(uwBytes - block_start_offset, ALIGN_SIZE) + block_header_overhead; - - if (((AARCHPTR)pPool % ALIGN_SIZE) != 0) { - PRINT_ERR("Memory must be aligned by %u bytes.\n", (INT32)ALIGN_SIZE); - return NULL; - } - - if (uwPoolBytes < block_size_min || uwPoolBytes > block_size_max) - { - PRINT_ERR("Memory size must be between 0x%x and 0x%x bytes.\n", - (INT32)(block_start_offset + block_size_min), - (INT32)(block_start_offset + block_size_max));/*lint !e515*/ - - return NULL; - } - - /* - * Create the main free pNode. Offset the start of the pNode slightly - * so that the pstPreNode field falls outside of the pool - - * it will never be used. - */ - pNode = osMemPtrOffset(pPool, -(INT32)block_header_overhead); /*lint !e570*/ - osMemNodeSizeSet(pNode, uwPoolBytes); - osMemFreeMark(pNode); - osMemPreUsedMark(pNode); - osMemNodeInsert(tlsf_cast(control_t *, tlsf), pNode); - /* Split the pNode to create a zero-size sentinel pNode. */ - pNext = osMemNextLink(pNode); - osMemNodeSizeSet(pNext, 0); - osMemUsedMark(pNext); - osMemPreFreeMark(pNext); - - return pPool; -} - -/* - * TLSF main interface. - */ - -LITE_OS_SEC_TEXT_INIT VOID * osMemPoolCreat(VOID *pPool, UINT32 uwBytes) -{ - if (((AARCHPTR)pPool % ALIGN_SIZE) != 0) - { - PRINT_ERR("Memory must be aligned to %u bytes.\n", (UINT32)ALIGN_SIZE); - return NULL; - } - - osMemControlClear(tlsf_cast(control_t *, pPool), uwBytes); - - return tlsf_cast(VOID *, pPool); -} - -/***************************************************************************** - Function : LOS_MemInit - Description : Initialize Dynamic Memory pool - Input : pPool --- Pointer to memory pool - uwBytes --- Size of memory in bytes to allocate - Output : None - Return : LOS_OK - Ok, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pPool, UINT32 uwBytes) -{ - VOID *tlsf; - UINTPTR uvIntSave; - -#if (LOSCFG_MEM_MUL_POOL == YES) - VOID *pNext = g_pPoolHead; - VOID * pCur; - UINT32 uwPoolEnd; -#endif - - if (!pPool || uwBytes <= osMemHeadSize()) - { - return LOS_NOK; - } - - uvIntSave = LOS_IntLock(); - - if(!IS_ALIGNED(uwBytes, ALIGN_SIZE)) - { - PRINT_ERR("pool [0x%x, 0x%x) size 0x%x sholud be aligned with ALIGN_SIZE\n", - (UINT32)pPool, (AARCHPTR)pPool + uwBytes, uwBytes);/*lint !e515*/ - uwBytes = osMemAlignDown(uwBytes, ALIGN_SIZE); - } - -#if (LOSCFG_MEM_MUL_POOL == YES) - while (pNext != NULL) - { - uwPoolEnd = (AARCHPTR)pNext + osMemPoolSizeGet(pNext); - if ((pPool <= pNext && ((AARCHPTR)pPool + uwBytes) > (AARCHPTR)pNext) || - ((AARCHPTR)pPool < uwPoolEnd && ((AARCHPTR)pPool + uwBytes) >= uwPoolEnd)) - { - PRINT_ERR("pool [0x%x, 0x%x) conflict with pool 0x%x, 0x%x)\n", - (UINT32)pPool, (AARCHPTR)pPool + uwBytes, - (UINT32)pNext, (AARCHPTR)pNext + osMemPoolSizeGet(pNext));/*lint !e515*/ - LOS_IntRestore(uvIntSave); - return LOS_NOK; - } - pCur = pNext; - pNext = ((LOS_MEM_POOL_INFO *)pNext)->pNextPool; - } -#endif - - tlsf = osMemPoolCreat(pPool, uwBytes); - if (osMemPoolAdd(tlsf, (UINT8 *)pPool + osMemHeadSize(), uwBytes - osMemHeadSize()) == 0) - { - LOS_IntRestore(uvIntSave); - return LOS_NOK; - } - -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - if (uwBytes >= SLAB_BASIC_NEED_SIZE)//if size of pool is small than size of slab need, don`t init slab - { - UINT32 uwIdx = 0; - struct LOS_SLAB_CONTROL_HEADER *pstSlabMemHead = osSlabCtrlHdrGet(pPool); - - for (uwIdx = 0; uwIdx < SLAB_MEM_COUNT; uwIdx++) - { - pstSlabMemHead->stSlabClass[uwIdx].alloc = NULL; - } - - if (osSlabMemInit(pPool) == FALSE) - { - LOS_IntRestore(uvIntSave); - return LOS_NOK; - } - } -#endif - -#if (LOSCFG_MEM_MUL_POOL == YES) - if (g_pPoolHead == NULL) - { - g_pPoolHead = pPool; - } - else - { - ((LOS_MEM_POOL_INFO *)pCur)->pNextPool = pPool; - } - - ((LOS_MEM_POOL_INFO *)pPool)->pNextPool = NULL; -#endif - - LOS_IntRestore(uvIntSave); - return LOS_OK; -} - -#if (LOSCFG_MEM_MUL_POOL == YES) -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pPool) -{ - UINTPTR uvIntSave, uwRet = LOS_NOK; - VOID *pNext, *pCur; - - uvIntSave = LOS_IntLock(); -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - osSlabMemDeinit(pPool); -#endif - do - { - if (pPool == NULL) - break; - - if (pPool == g_pPoolHead) - { - g_pPoolHead = ((LOS_MEM_POOL_INFO *)g_pPoolHead)->pNextPool; - uwRet = LOS_OK; - break; - } - - pCur = g_pPoolHead; - pNext = g_pPoolHead; - - while (pNext != NULL) - { - if (pPool == pNext) - { - ((LOS_MEM_POOL_INFO *)pCur)->pNextPool = ((LOS_MEM_POOL_INFO *)pNext)->pNextPool; - uwRet = LOS_OK; - break; - } - pCur = pNext; - pNext = ((LOS_MEM_POOL_INFO *)pNext)->pNextPool; - } - }while(0); - - LOS_IntRestore(uvIntSave); - return uwRet; -} - -LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemPoolList(VOID) -{ - VOID *pNext = g_pPoolHead; - UINT32 uwIndex = 0; - while (pNext != NULL) - { - PRINT_ERR("pool%d :\n", uwIndex++); - osMemInfoPrint(pNext); - pNext = ((LOS_MEM_POOL_INFO *)pNext)->pNextPool; - } - return uwIndex; -} -#endif - -LITE_OS_SEC_TEXT VOID *osHeapAlloc(VOID *tlsf, UINT32 uwSize) -{ - UINT32 adjust; - LOS_MEM_DYN_NODE *pNode; - VOID *pPtr = NULL; - control_t *control = tlsf_cast(control_t *, tlsf); - - adjust = osMemReqSizeAdjust(uwSize, ALIGN_SIZE); - if(0 == adjust) - { - PRINT_ERR("require node size 0x%x is too large\n",uwSize); - return NULL; - } - pNode = osMemFreeNodeLocate(control, adjust); - pPtr = osMemUsedNodePrepare(control, pNode, adjust); - - if (NULL != pPtr) - { - g_uwTlsf_AllocCount++; - } - - return pPtr; -} - -/***************************************************************************** - Function : LOS_MemAlloc - Description : Allocate Memory from Memory pool - Input : tlsf --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - Output : None - Return : Pointer to allocated memory -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID * tlsf, UINT32 uwSize) -{ - VOID *pPtr = NULL; - UINTPTR uvIntSave; - - if ((0 == uwSize) || (NULL == tlsf) || (uwSize > block_size_max)) - { - return NULL; - } - uvIntSave = LOS_IntLock(); - -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - if (uwSize <= (SLAB_MEM_ALLOCATOR_SIZE/SLAB_MEM_COUNT)) - { - pPtr = osSlabMemAlloc(tlsf, uwSize); - } - - if (pPtr == NULL) -#endif - { - pPtr = osHeapAlloc(tlsf, uwSize); - } - LOS_IntRestore(uvIntSave); - return pPtr; -} - -/***************************************************************************** - Function : LOS_MemAllocAlign - Description : align size then allocate node from Memory pool - Input : tlsf --- Pointer to memory pool - uwSize --- Size of memory in bytes to allocate - uwAlign --- align form - Output : None - Return : Pointer to allocated memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID * tlsf, UINT32 uwSize, UINT32 uwAlign) -{ - control_t *control = tlsf_cast(control_t *, tlsf); - UINT32 adjust; - UINT32 gap_minimum; - UINT32 size_with_gap; - UINT32 aligned_size; - LOS_MEM_DYN_NODE *pNode; - VOID *pPtr; - UINTPTR uvIntSave; - - if (uwSize == 0 || !tlsf || uwSize > block_size_max || uwAlign == 0 || !IS_ALIGNED(uwAlign, sizeof(VOID *))) - { - return NULL; - } - - uvIntSave = LOS_IntLock(); - - uwSize += 4; - adjust = osMemReqSizeAdjust(uwSize, ALIGN_SIZE); - if(0 == adjust) - { - PRINT_ERR("require node size 0x%x is too large\n",uwSize); - LOS_IntRestore(uvIntSave); - return NULL; - } - /* - * We must allocate an additional minimum pNode size bytes so that if - * our free pNode will leave an alignment gap which is smaller, we can - * trim a leading free pNode and release it back to the pool. We must - * do this because the previous physical pNode is in use, therefore - * the pstPreNode field is not valid, and we can't simply adjust - * the size of that pNode. - */ - gap_minimum = sizeof(LOS_MEM_DYN_NODE); - if (((adjust + gap_minimum) > (((UINT32)-1) - uwAlign)) || ((uwAlign + gap_minimum) > (((UINT32)-1) - adjust))) - { - LOS_IntRestore(uvIntSave); - return NULL; - } - size_with_gap = osMemReqSizeAdjust(adjust + uwAlign + gap_minimum, ALIGN_SIZE); - if(0 == size_with_gap) - { - PRINT_ERR("require node size 0x%x is too large\n",uwSize); - LOS_IntRestore(uvIntSave); - return NULL; - } - /* - * If alignment is less than or equals base alignment, we're done. - * If we requested 0 bytes, return null, as tlsf_malloc(0) does. - */ - aligned_size = (adjust && uwAlign > ALIGN_SIZE) ? size_with_gap : adjust; - - pNode = osMemFreeNodeLocate(control, aligned_size); - - if (pNode) { - VOID *aligned; - UINT32 gap; - pPtr = osMemNodeToPtr(pNode); - aligned = osMemAlignPtr(pPtr, uwAlign); - gap = tlsf_cast( - UINT32, tlsf_cast(AARCHPTR, aligned) - tlsf_cast(AARCHPTR, pPtr)); - - /* If gap size is too small, offset to next aligned boundary. */ - if (gap && gap < gap_minimum) - { - const UINT32 gap_remain = gap_minimum - gap; - const UINT32 offset = tlsf_max(gap_remain, uwAlign); - const VOID *next_aligned = - tlsf_cast(VOID *, tlsf_cast(AARCHPTR, aligned) + offset); - - aligned = osMemAlignPtr(next_aligned, uwAlign); - gap = tlsf_cast(UINT32, tlsf_cast(AARCHPTR, aligned) - - tlsf_cast(AARCHPTR, pPtr)); - } - - if (gap) - { - tlsf_assert(gap >= gap_minimum && "gap size too small"); - pNode = osMemFreeNodeTrimLeading(control, pNode, gap); - } - } - - pPtr = osMemUsedNodePrepare(control, pNode, adjust); - - LOS_IntRestore(uvIntSave); - return pPtr; -} - -LITE_OS_SEC_TEXT BOOL osHeapFree(VOID * tlsf, VOID *pPtr) -{ - control_t *control; - - LOS_MEM_DYN_NODE *pNode; - - control = (LOS_MEM_POOL_INFO *)tlsf; - pNode = osMemPtrToNode(pPtr); - - if (osMemFreeCheck(pNode)) - { - return FALSE; - } - - if (osMemMagicCheck(tlsf, pPtr) == LOS_NOK) - { - return FALSE; - } - - osMemFreeSet(pNode); - pNode = osMemPreNodeMerge(control, pNode); - pNode = osMemNextNodeMerge(control, pNode); - osMemNodeInsert(control, pNode); - - g_uwTlsf_FreeCount++; - return TRUE; -} - -/***************************************************************************** - Function : LOS_MemFree - Description : Free Memory and return it to Memory pool - Input : tlsf --- Pointer to memory pool - pPtr --- Pointer to memory to free - Output : None - Return : LOS_OK - OK, LOS_NOK - Error -*****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID * tlsf, VOID *pPtr) -{ - UINTPTR uvIntSave; - BOOL uwRet; - - - if ((NULL == tlsf) || (NULL == pPtr)) - { - return LOS_NOK; - } - uvIntSave = LOS_IntLock(); -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - uwRet = osSlabMemFree(tlsf, pPtr); - if (uwRet == FALSE) -#endif - { - { - uwRet = osHeapFree(tlsf,pPtr); - } - } - LOS_IntRestore(uvIntSave); - return (uwRet == TRUE ? LOS_OK : LOS_NOK); -} - -/* - * The TLSF pNode information provides us with enough information to - * provide a reasonably intelligent implementation of realloc, growing or - * shrinking the currently allocated pNode as required. - * - * This routine handles the somewhat esoteric edge cases of realloc: - * - a non-zero size with a null pointer will behave like malloc - * - a zero size with a non-null pointer will behave like free - * - a request that cannot be satisfied will leave the original buffer - * untouched - * - an extended buffer size will leave the newly-allocated area with - * contents undefined - */ -LITE_OS_SEC_TEXT_MINOR VOID *osHeapRealloc(VOID * tlsf, VOID *pPtr, UINT32 uwSize) -{ - VOID *pNewPtr = NULL; - control_t *control = tlsf_cast(control_t *, tlsf); - LOS_MEM_DYN_NODE *pNode = osMemPtrToNode(pPtr); - LOS_MEM_DYN_NODE *pNext = osMemNodeNext(pNode); - - const size_t cursize = osMemNodeSizeGet(pNode); - const size_t combined = cursize + osMemNodeSizeGet(pNext); - const size_t adjust = osMemReqSizeAdjust(uwSize, ALIGN_SIZE); - if(0 == adjust) - { - PRINT_ERR("require node size 0x%x is too large\n",uwSize); - return NULL; - } - if (osMemFreeCheck(pNode)) - { - PRINTK("block already marked as free\n"); - return NULL; - } - - /* - * If the next block is used, or when combined with the current - * block, does not offer enough space, we must reallocate and copy. - */ - if (adjust > cursize && (!osMemFreeCheck(pNext) || adjust > combined)) - { - pNewPtr = LOS_MemAlloc(tlsf, uwSize); - if (pNewPtr) - { - const size_t minsize = tlsf_min((cursize - block_start_offset), uwSize); - memcpy(pNewPtr, pPtr, minsize); - (VOID)LOS_MemFree(tlsf, pPtr); - } - } else - { - /* Do we need to expand to the next block? */ - if (adjust > cursize) - { - (VOID)osMemNextNodeMerge(control, pNode); - osMemUsedSet(pNode); - } - - /* Trim the resulting block and return the original pointer. */ - osMemUsedNodeTrim(control, pNode, adjust); - - pNewPtr = pPtr; - } - - return pNewPtr; -} - -/***************************************************************************** - Function : LOS_MemRealloc - Description : realloc memory from Memory pool - Input : tlsf --- Pointer to memory pool - pPtr --- Pointer to memory - uwSize --- new size - Output : None - Return : Pointer to allocated memory node -*****************************************************************************/ -LITE_OS_SEC_TEXT_MINOR VOID *LOS_MemRealloc(VOID * tlsf, VOID *pPtr, UINT32 uwSize) -{ - VOID *pRetPtr = NULL; - UINTPTR uvIntSave; - -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - UINT32 uwMinSize = 0; - UINT32 uwOldSize = 0; -#endif - - if ((INT32)uwSize < 0) - { - return NULL; - } - - uvIntSave = LOS_IntLock(); - - /* Zero-size requests are treated as free. */ - if (pPtr && uwSize == 0) - { - (VOID)LOS_MemFree(tlsf, pPtr); - } - /* Requests with NULL pointers are treated as malloc. */ - else if (pPtr == NULL) - { - pRetPtr = LOS_MemAlloc(tlsf, uwSize); - } - else - { -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - uwOldSize = osSlabMemCheck(tlsf, pPtr); - - if (uwOldSize != (UINT32)-1) - { - uwMinSize = uwSize > uwOldSize ? uwOldSize : uwSize; - } - pRetPtr = LOS_MemAlloc(tlsf, uwSize); - - if (pRetPtr != NULL) - { - (VOID)memcpy(pRetPtr, pPtr, uwMinSize); - (VOID)LOS_MemFree(tlsf, pPtr); - } - else -#endif - { - pRetPtr = osHeapRealloc(tlsf, pPtr, uwSize); - } - } - LOS_IntRestore(uvIntSave); - return pRetPtr; -} - -LITE_OS_SEC_TEXT_INIT UINT32 osMemSystemInit(VOID) -{ - UINT32 uwRet = LOS_OK; - - uwRet = LOS_MemInit((VOID *)OS_SYS_MEM_ADDR, OS_SYS_MEM_SIZE); - -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) - osExcRegister(OS_EXC_TYPE_MEM, (EXC_INFO_SAVE_CALLBACK)LOS_MemExcInfoGet, g_aucMemMang); -#endif - osMemInfoPrint((VOID *)OS_SYS_MEM_ADDR); - - return uwRet; -} - -LITE_OS_SEC_TEXT UINT32 LOS_MemStatisticsGet(VOID *pPool, LOS_MEM_STATUS *pstStatus) -{ -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - LOS_SLAB_STATUS stSlabStatus; - UINT32 uwErr; -#endif - LOS_MEM_POOL_INFO *pstPoolInfo = (LOS_MEM_POOL_INFO *)pPool; - LOS_MEM_STATUS stStatus; - if (LOS_NOK == osMemInfoGet(pPool, &stStatus)) - { - return LOS_NOK; - } - - pstStatus->totalSize = stStatus.totalSize; - pstStatus->usedSize = stStatus.usedSize; - pstStatus->freeSize = stStatus.freeSize; - pstStatus->allocCount = stStatus.allocCount; - pstStatus->freeCount = stStatus.freeCount; - -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - uwErr = osSlabStatisticsGet(pPool, &stSlabStatus); - if (uwErr != LOS_OK) - { - return LOS_NOK; - } - - pstStatus->totalSize = stStatus.totalSize; - pstStatus->usedSize = stStatus.usedSize - stSlabStatus.freeSize; //all slab region inside of heap used region - pstStatus->freeSize = stStatus.freeSize + stSlabStatus.freeSize; - pstStatus->allocCount = stStatus.allocCount + stSlabStatus.allocCount; - pstStatus->freeCount = stStatus.freeCount + stSlabStatus.freeCount; -#endif - return LOS_OK; -} - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - diff --git a/kernel/base/misc/Makefile b/kernel/base/misc/Makefile deleted file mode 100644 index d19ccae11..000000000 --- a/kernel/base/misc/Makefile +++ /dev/null @@ -1 +0,0 @@ -objs-y += los_misc.o diff --git a/kernel/base/misc/los_misc.c b/kernel/base/misc/los_misc.c index 180617b14..f01ae13e7 100644 --- a/kernel/base/misc/los_misc.c +++ b/kernel/base/misc/los_misc.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Misc Functions * 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 @@ -22,66 +22,51 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_base.ph" -#include "los_sys.ph" -#include "los_task.ph" -#include "los_hwi.h" +#include "los_task_pri.h" -LITE_OS_SEC_TEXT UINT32 LOS_Align(UINT32 uwAddr, UINT32 uwBoundary) +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary) { - if (uwAddr + uwBoundary - 1 > uwAddr) { - return (uwAddr + uwBoundary - 1) & ~(uwBoundary - 1); + if ((addr + boundary - 1) > addr) { + return (addr + boundary - 1) & ~((UINTPTR)(boundary - 1)); } else { - return uwAddr & ~(uwBoundary - 1); + return addr & ~((UINTPTR)(boundary - 1)); } } -LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 uwMsecs) +LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs) { - UINT32 uwInterval = 0; + UINT32 interval; - if (OS_INT_ACTIVE) - { - return; - } - - if (uwMsecs == 0) - { - uwInterval = 0; - } - else - { - uwInterval = LOS_MS2Tick(uwMsecs); - if (uwInterval == 0) - { - uwInterval = 1; + if (msecs == 0) { + interval = 0; + } else { + interval = LOS_MS2Tick(msecs); + if (interval == 0) { + interval = 1; } } - (VOID)LOS_TaskDelay(uwInterval); + (VOID)LOS_TaskDelay(interval); } -#if defined (__ICC430__) || defined (__TI_COMPILER_VERSION__) -static const uint8_t clz_table_4bit[16] = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; -int __clz ( unsigned long x ) -{ - int n; - if ((x & 0xFFFF0000) == 0) {n = 16; x <<= 16;} else {n = 0;} - if ((x & 0xFF000000) == 0) {n += 8; x <<= 8;} - if ((x & 0xF0000000) == 0) {n += 4; x <<= 4;} - n += (int)clz_table_4bit[x >> (32-4)]; - return n; +#ifdef __cplusplus +#if __cplusplus } - #endif - +#endif /* __cplusplus */ \ No newline at end of file diff --git a/kernel/base/misc/los_stackinfo.c b/kernel/base/misc/los_stackinfo.c new file mode 100644 index 000000000..db949a967 --- /dev/null +++ b/kernel/base/misc/los_stackinfo.c @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Stack Info Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_stackinfo_pri.h" +#include "los_printf_pri.h" +#include "los_base.h" +#include "los_hw_cpu.h" + +const StackInfo *g_stackInfo = NULL; +UINT32 g_stackNum; + +UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed) +{ + UINT32 size; + const UINTPTR *tmp = NULL; + if (*stackTop == OS_STACK_MAGIC_WORD) { + tmp = stackTop + 1; + while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) { + tmp++; + } + size = (UINTPTR)stackBottom - (UINTPTR)tmp; + *peakUsed = (size == 0) ? size : (size + sizeof(CHAR *)); + return LOS_OK; + } else { + *peakUsed = OS_INVALID_WATERLINE; + return LOS_NOK; + } +} + +VOID OsExcStackCheck(VOID) +{ + UINT32 index; + UINT32 cpuid; + UINTPTR *stackTop = NULL; + + if (g_stackInfo == NULL) { + return; + } + for (index = 0; index < g_stackNum; index++) { + for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize); + if (*stackTop != OS_STACK_MAGIC_WORD) { + PRINT_ERR("cpu:%u %s overflow , magic word changed to 0x%x\n", + LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, g_stackInfo[index].stackName, *stackTop); + } + } + } +} + +VOID OsExcStackInfo(VOID) +{ + UINT32 index; + UINT32 cpuid; + UINT32 size; + UINTPTR *stackTop = NULL; + UINTPTR *stack = NULL; + + if (g_stackInfo == NULL) { + return; + } + + PrintExcInfo("\n stack name cpu id stack addr total size used size\n" + " ---------- ------ --------- -------- --------\n"); + + for (index = 0; index < g_stackNum; index++) { + for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { + stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize); + stack = (UINTPTR *)((UINTPTR)stackTop + g_stackInfo[index].stackSize); + (VOID)OsStackWaterLineGet(stack, stackTop, &size); + + PrintExcInfo("%11s %-5d %-10p 0x%-8x 0x%-4x\n", g_stackInfo[index].stackName, + LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, stackTop, g_stackInfo[index].stackSize, size); + } + } + + OsExcStackCheck(); +} + +VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum) +{ + g_stackInfo = stackInfo; + g_stackNum = stackNum; +} + +VOID OsStackInit(VOID *stacktop, UINT32 stacksize) +{ + /* initialize the task stack, write magic num to stack top */ + (VOID)memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize); + *((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD; +} diff --git a/kernel/base/include/los_membox.ph b/kernel/base/mp/los_percpu.c similarity index 80% rename from kernel/base/include/los_membox.ph rename to kernel/base/mp/los_percpu.c index d28acdeae..cff4e12ce 100644 --- a/kernel/base/include/los_membox.ph +++ b/kernel/base/mp/los_percpu.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: Per-cpu * 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 @@ -22,20 +22,17 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_MEMBOX_PH -#define _LOS_MEMBOX_PH - -#include "los_membox.h" +#include "los_percpu_pri.h" #ifdef __cplusplus #if __cplusplus @@ -43,11 +40,10 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ #endif /* __cplusplus */ - -#endif /* _LOS_MEMBOX_PH */ diff --git a/kernel/base/om/Makefile b/kernel/base/om/Makefile deleted file mode 100644 index 7ef757494..000000000 --- a/kernel/base/om/Makefile +++ /dev/null @@ -1 +0,0 @@ -objs-y += los_err.o diff --git a/kernel/base/om/los_err.c b/kernel/base/om/los_err.c index 57a85324e..f69759f64 100644 --- a/kernel/base/om/los_err.c +++ b/kernel/base/om/los_err.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Error Handling * 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 @@ -22,17 +22,17 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_err.inc" +#include "los_err.h" #ifdef __cplusplus #if __cplusplus @@ -40,35 +40,13 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -LITE_OS_SEC_BSS USER_ERR_FUNC_S g_stUserErrFunc; +LITE_OS_SEC_BSS USER_ERR_FUNC_S g_stUserErrFunc; -/***************************************************************************** -Function : LOS_ErrHandle -Description: Error handle -Input : pcFileName - uwLineNo -- error line number - uwErrorNo -- user defined error number - uwParaLen -- length of pPara - pPara -- user description of error -Output : -Return : uwErrorNo -- user defined error number -Other : None -*****************************************************************************/ -LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle( CHAR *pcFileName, - UINT32 uwLineNo, - UINT32 uwErrorNo, - UINT32 uwParaLen, - VOID *pPara) +LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo, + UINT32 paraLen, VOID *para) { - - if (NULL != g_stUserErrFunc.pfnHook) - { - g_stUserErrFunc.pfnHook(pcFileName, uwLineNo, uwErrorNo, uwParaLen, pPara); - } - - if (OS_ERR_MAGIC_WORD != uwLineNo) - { - return LOS_OK; + if (g_stUserErrFunc.pfnHook != NULL) { + g_stUserErrFunc.pfnHook(fileName, lineNo, errorNo, paraLen, para); } return LOS_OK; diff --git a/kernel/base/sched/sched_sq/los_priqueue.c b/kernel/base/sched/sched_sq/los_priqueue.c new file mode 100644 index 000000000..6d52806fe --- /dev/null +++ b/kernel/base/sched/sched_sq/los_priqueue.c @@ -0,0 +1,157 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Priority Queue + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_priqueue_pri.h" +#include "los_task_pri.h" +#include "los_memory.h" +#include "los_toolchain.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define PRIQUEUE_PRIOR0_BIT 0x80000000U + +LITE_OS_SEC_BSS LOS_DL_LIST g_priQueueList[OS_PRIORITY_QUEUE_NUM]; + +STATIC LITE_OS_SEC_BSS UINT32 g_priQueueBitmap; + +UINT32 OsPriQueueInit(VOID) +{ + UINT32 priority; + + for (priority = 0; priority < OS_PRIORITY_QUEUE_NUM; ++priority) { + LOS_ListInit(&g_priQueueList[priority]); + } + return LOS_OK; +} + +VOID OsPriQueueEnqueueHead(LOS_DL_LIST *priqueueItem, UINT32 priority) +{ + /* + * Task control blocks are inited as zero. And when task is deleted, + * and at the same time would be deleted from priority queue or + * other lists, task pend node will restored as zero. + */ + LOS_ASSERT(priqueueItem->pstNext == NULL); + + if (LOS_ListEmpty(&g_priQueueList[priority])) { + g_priQueueBitmap |= PRIQUEUE_PRIOR0_BIT >> priority; + } + + LOS_ListHeadInsert(&g_priQueueList[priority], priqueueItem); +} + +VOID OsPriQueueEnqueue(LOS_DL_LIST *priqueueItem, UINT32 priority) +{ + /* + * Task control blocks are inited as zero. And when task is deleted, + * and at the same time would be deleted from priority queue or + * other lists, task pend node will restored as zero. + */ + LOS_ASSERT(priqueueItem->pstNext == NULL); + + if (LOS_ListEmpty(&g_priQueueList[priority])) { + g_priQueueBitmap |= PRIQUEUE_PRIOR0_BIT >> priority; + } + + LOS_ListTailInsert(&g_priQueueList[priority], priqueueItem); +} + +VOID OsPriQueueDequeue(LOS_DL_LIST *priqueueItem) +{ + LosTaskCB *runTask = NULL; + LOS_ListDelete(priqueueItem); + + runTask = LOS_DL_LIST_ENTRY(priqueueItem, LosTaskCB, pendList); + if (LOS_ListEmpty(&g_priQueueList[runTask->priority])) { + g_priQueueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> runTask->priority); + } +} + +LOS_DL_LIST *OsPriQueueTop(VOID) +{ + UINT32 priority; + + if (g_priQueueBitmap != 0) { + priority = CLZ(g_priQueueBitmap); + return LOS_DL_LIST_FIRST(&g_priQueueList[priority]); + } + + return NULL; +} + +UINT32 OsPriQueueSize(UINT32 priority) +{ + UINT32 itemCnt = 0; + LOS_DL_LIST *curNode = NULL; + + LOS_ASSERT(OsIntLocked()); + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + + LOS_DL_LIST_FOR_EACH(curNode, &g_priQueueList[priority]) { + ++itemCnt; + } + + return itemCnt; +} + +LITE_OS_SEC_TEXT_MINOR LosTaskCB *OsGetTopTask(VOID) +{ + UINT32 priority; + UINT32 bitmap; + LosTaskCB *newTask = NULL; + bitmap = g_priQueueBitmap; + + while (bitmap) { + priority = CLZ(bitmap); + LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &g_priQueueList[priority], LosTaskCB, pendList) { + OsPriQueueDequeue(&newTask->pendList); + goto OUT; + } + bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1)); + } + +OUT: + return newTask; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/kernel/base/sched/sched_sq/los_sched.c b/kernel/base/sched/sched_sq/los_sched.c new file mode 100644 index 000000000..0158e78fb --- /dev/null +++ b/kernel/base/sched/sched_sq/los_sched.c @@ -0,0 +1,124 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: Scheduler + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_base.h" +#include "los_task_pri.h" +#include "los_priqueue_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +VOID OsSchedResched(VOID) +{ + LosTaskCB *runTask = NULL; + LosTaskCB *newTask = NULL; + + LOS_ASSERT(LOS_SpinHeld(&g_taskSpin)); + + if (!OsPreemptableInSched()) { + return; + } + + runTask = OsCurrTaskGet(); + newTask = OsGetTopTask(); + + /* always be able to get one task */ + LOS_ASSERT(newTask != NULL); + + newTask->taskStatus &= ~OS_TASK_STATUS_READY; + + if (runTask == newTask) { + return; + } + + runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING; + newTask->taskStatus |= OS_TASK_STATUS_RUNNING; + + (VOID)OsTaskSwitchCheck(runTask, newTask); + + PRINT_TRACE("cpu%d (%s) status: %x -> (%s) status:%x\n", ArchCurrCpuid(), + runTask->taskName, runTask->taskStatus, + newTask->taskName, newTask->taskStatus); + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + if (newTask->timeSlice == 0) { + newTask->timeSlice = LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT; + } +#endif + + OsCurrTaskSet(newTask); + + /* do the task context switch */ + OsTaskSchedule(newTask, runTask); +} + +VOID OsSchedPreempt(VOID) +{ + LosTaskCB *runTask = NULL; + UINT32 intSave; + + if (!OsPreemptable()) { + return; + } + + SCHEDULER_LOCK(intSave); + + /* add run task back to ready queue */ + runTask = OsCurrTaskGet(); + runTask->taskStatus |= OS_TASK_STATUS_READY; + +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + if (runTask->timeSlice == 0) { + OsPriQueueEnqueue(&runTask->pendList, runTask->priority); + } else { +#endif + OsPriQueueEnqueueHead(&runTask->pendList, runTask->priority); +#if (LOSCFG_BASE_CORE_TIMESLICE == YES) + } +#endif + + /* reschedule to new thread */ + OsSchedResched(); + + SCHEDULER_UNLOCK(intSave); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/extended/Makefile b/kernel/extended/Makefile deleted file mode 100644 index 8443b29a9..000000000 --- a/kernel/extended/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -objs-y += cpup -objs-y += mpu diff --git a/kernel/extended/include/los_tickless.ph b/kernel/extended/include/los_tickless.ph deleted file mode 100644 index 809649aeb..000000000 --- a/kernel/extended/include/los_tickless.ph +++ /dev/null @@ -1,63 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_TICKLESS_PH -#define _LOS_TICKLESS_PH - -#include "los_tickless.h" -#include "los_hw_tick.h" -#include "los_config.h" - -#if (LOSCFG_PLATFORM_HWI == NO) -enum TICKLESS_OS_TICK_INT_FLAG -{ - TICKLESS_OS_TICK_INT_INIT = 0, - TICKLESS_OS_TICK_INT_WAIT = 1, /* tickless start, waiting for the next tick interrupt to happen */ - TICKLESS_OS_TICK_INT_SET = 2, /* tick interrupt happened */ -}; -extern enum TICKLESS_OS_TICK_INT_FLAG g_uwSysTickIntFlag; -#endif - -extern BOOL g_bTickIrqFlag; -extern BOOL g_bReloadSysTickFlag; -extern volatile UINT32 g_uwSleepTicks; -extern BOOL g_bTicklessFlag; -extern VOID tick_timer_reload(UINT32 period); -extern VOID osSysTimeUpdate(UINT32 uwSleepTicks); -extern VOID osTicklessStart(VOID); -#if (LOSCFG_KERNEL_TICKLESS == YES) -extern inline VOID osUpdateKernelTickCount(UINT32 uwHwiIndex); -#endif -extern VOID osTicklessHandler(VOID); -#endif /* _LOS_TICKLESS_PH */ diff --git a/kernel/extended/include/los_tickless_pri.h b/kernel/extended/include/los_tickless_pri.h new file mode 100644 index 000000000..85dc03d3b --- /dev/null +++ b/kernel/extended/include/los_tickless_pri.h @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tickless HeadFile + * Author: zhangfanfan + * Create: 2013-01-01 + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_TICKLESS_PRI_H +#define _LOS_TICKLESS_PRI_H + +#include "los_tickless.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID OsTickTimerReload(UINT32 period); +extern VOID OsSysTimeUpdate(UINT32 sleepTicks); +extern VOID OsTicklessStart(VOID); +extern BOOL OsTickIrqFlagGet(VOID); +extern VOID OsTickIrqFlagSet(BOOL tickIrqFlag); +extern BOOL OsTicklessFlagGet(VOID); +extern UINT32 OsTicklessSleepTickGet(VOID); +extern VOID OsTicklessSleepTickSet(UINT32 sleeptick); +extern VOID OsTicklessUpdate(UINT32 irqNum); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TICKLESS_PRI_H */ diff --git a/kernel/extended/tickless/los_tickless.c b/kernel/extended/tickless/los_tickless.c index addfa0ef1..4b2b057d9 100644 --- a/kernel/extended/tickless/los_tickless.c +++ b/kernel/extended/tickless/los_tickless.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tickless * 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 @@ -22,24 +22,21 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - - -#include "los_hwi.h" -#include "los_tick.ph" -#include "los_tickless.inc" -#include "los_hw.h" -#include "los_task.h" - -#if (LOSCFG_KERNEL_TICKLESS == YES) + * --------------------------------------------------------------------------- */ +#include "los_tickless_pri.h" +#include "los_hwi_pri.h" +#include "los_tick_pri.h" +#include "los_sortlink_pri.h" +#include "los_swtmr_pri.h" +#include "los_task_pri.h" #ifdef __cplusplus #if __cplusplus @@ -47,178 +44,156 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -BOOL g_bTicklessFlag = 1; -BOOL g_bTickIrqFlag = 0; -BOOL g_bReloadSysTickFlag = 0; -#if (LOSCFG_PLATFORM_HWI == NO) -enum TICKLESS_OS_TICK_INT_FLAG g_uwSysTickIntFlag = TICKLESS_OS_TICK_INT_INIT; -#endif - -volatile UINT32 g_uwSleepTicks = 0; - -extern UINT32 osTaskNextSwitchTimeGet(VOID); -extern UINT32 osSwTmrGetNextTimeout(VOID); +STATIC BOOL g_ticklessFlag = FALSE; +STATIC BOOL g_tickIrqFlag[LOSCFG_KERNEL_CORE_NUM] = {FALSE}; +STATIC volatile UINT32 g_sleepTicks[LOSCFG_KERNEL_CORE_NUM] = {0}; +#define OS_GET_CYCLECOMPENSATE(cyclesPre,cyclesCur) (((cyclesPre) > (cyclesCur)) ? \ + ((g_sysClock / g_tickPerSecond) - (cyclesCur)) : (((g_sysClock / g_tickPerSecond) << 1) - (cyclesCur))) LITE_OS_SEC_TEXT VOID LOS_TicklessEnable(VOID) { - g_bTicklessFlag = 1; + g_ticklessFlag = TRUE; } LITE_OS_SEC_TEXT VOID LOS_TicklessDisable(VOID) { - g_bTicklessFlag = 0; + g_ticklessFlag = FALSE; } -static inline UINT32 osSleepTicksGet(VOID) +LITE_OS_SEC_TEXT BOOL OsTicklessFlagGet(VOID) { - UINT32 uwTskSortLinkTicks = 0; - UINT32 uwSwtmrSortLinkTicks = 0; - UINT32 uwSleepTicks = 0; - - /** Context guarantees that the interrupt has been closed */ - uwTskSortLinkTicks = osTaskNextSwitchTimeGet(); - uwSwtmrSortLinkTicks = osSwTmrGetNextTimeout(); - - uwSleepTicks = (uwTskSortLinkTicks < uwSwtmrSortLinkTicks) ? uwTskSortLinkTicks : uwSwtmrSortLinkTicks; - return uwSleepTicks; + return g_ticklessFlag; } -inline VOID osUpdateKernelTickCount(UINT32 uwHwiIndex) +LITE_OS_SEC_TEXT BOOL OsTickIrqFlagGet(VOID) { - /** this function must be called in interrupt context */ - if (g_uwSleepTicks > 1) - { - UINT32 uwCyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; - UINT32 uwCurrSysCycles, uwElapseSysCycles, uwElapseTicks, uwRemainSysCycles; - - g_bReloadSysTickFlag = 0; - #if (LOSCFG_PLATFORM_HWI == YES) - if (uwHwiIndex == (SysTick_IRQn + OS_SYS_VECTOR_CNT)) - #else - if (g_uwSysTickIntFlag == TICKLESS_OS_TICK_INT_SET) /* OS tick interrupt */ - #endif - { - uwElapseTicks = (g_uwSleepTicks - 1); - LOS_SysTickReload(OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND); - } - else - { - uwCurrSysCycles = LOS_SysTickCurrCycleGet(); - #if (LOSCFG_SYSTICK_CNT_DIR_DECREASE == YES) - uwElapseSysCycles = ((g_uwSleepTicks * uwCyclesPerTick) - uwCurrSysCycles); - #else - uwElapseSysCycles = uwCurrSysCycles; - #endif - uwElapseTicks = uwElapseSysCycles / uwCyclesPerTick; - uwRemainSysCycles = uwElapseSysCycles % uwCyclesPerTick; - if (uwRemainSysCycles > 0) - { - LOS_SysTickReload(uwRemainSysCycles); - g_bReloadSysTickFlag = 1; - } - else - { - LOS_SysTickReload(uwCyclesPerTick); - } - } - osTickHandlerLoop(uwElapseTicks); - g_uwSleepTicks = 0; - #if (LOSCFG_PLATFORM_HWI == NO) - g_uwSysTickIntFlag = TICKLESS_OS_TICK_INT_INIT; - #endif - } + return g_tickIrqFlag[ArchCurrCpuid()]; } -VOID osTicklessStart(VOID) +LITE_OS_SEC_TEXT VOID OsTickIrqFlagSet(BOOL tickIrqFlag) { - UINT32 uwCyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; - UINT32 uwMaxTicks = LOSCFG_SYSTICK_LOAD_RELOAD_MAX / uwCyclesPerTick; - UINTPTR uvIntSave = 0; - UINT32 uwSleepTicks = 0; - - uvIntSave = LOS_IntLock(); - LOS_SysTickStop(); - if (LOS_SysTickGetIntStatus()) /* SysTick interrupt pend */ - { - goto out; - } + g_tickIrqFlag[ArchCurrCpuid()] = tickIrqFlag; +} - uwSleepTicks = osSleepTicksGet(); - if (uwSleepTicks > 1) - { - UINT32 uwSleepCycles, uwCurrSysCycles; - if (uwSleepTicks >= uwMaxTicks) - { - uwSleepTicks = uwMaxTicks; - } +LITE_OS_SEC_TEXT UINT32 OsTicklessSleepTickGet(VOID) +{ + return g_sleepTicks[ArchCurrCpuid()]; +} - uwSleepCycles = uwSleepTicks * uwCyclesPerTick; - uwCurrSysCycles = LOS_SysTickCurrCycleGet(); - #if (LOSCFG_SYSTICK_CNT_DIR_DECREASE == YES) - LOS_SysTickReload(uwSleepCycles - uwCyclesPerTick + uwCurrSysCycles); - #else - LOS_SysTickReload(uwSleepCycles - uwCurrSysCycles); - #endif - g_uwSleepTicks = uwSleepTicks; - #if (LOSCFG_PLATFORM_HWI == NO) - if (g_uwSysTickIntFlag == TICKLESS_OS_TICK_INT_INIT) - { - g_uwSysTickIntFlag = TICKLESS_OS_TICK_INT_WAIT; - } - #endif - } -out: - LOS_SysTickStart(); - LOS_IntRestore(uvIntSave); +LITE_OS_SEC_TEXT VOID OsTicklessSleepTickSet(UINT32 sleeptick) +{ + g_sleepTicks[ArchCurrCpuid()] = sleeptick; +} - return; +STATIC INLINE UINT32 OsSleepTicksGet(VOID) +{ + UINT32 tskSortLinkTicks, swtmrSortLinkTicks, sleepTicks; + + UINT32 intSave = LOS_IntLock(); + LOS_SpinLock(&g_taskSpin); + tskSortLinkTicks = OsSortLinkGetNextExpireTime(&OsPercpuGet()->taskSortLink); + LOS_SpinUnlock(&g_taskSpin); + LOS_SpinLock(&g_swtmrSpin); + swtmrSortLinkTicks = OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink); + LOS_SpinUnlock(&g_swtmrSpin); + sleepTicks = (tskSortLinkTicks < swtmrSortLinkTicks) ? tskSortLinkTicks : swtmrSortLinkTicks; + LOS_IntRestore(intSave); + return sleepTicks; } -VOID osTicklessHandler(VOID) +LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks) { -#if (LOSCFG_PLATFORM_HWI == YES) + UINT32 intSave; - if (g_bTickIrqFlag) - { - g_bTickIrqFlag = 0; - osTicklessStart(); + if (sleepTicks == 0) { + return; } - osEnterSleep(); - -#else - - if (g_bTickIrqFlag) - { - UINTPTR uvIntSave; - uvIntSave = LOS_IntLock(); - LOS_TaskLock(); + intSave = LOS_IntLock(); + g_tickCount[ArchCurrCpuid()] += (sleepTicks - 1); + LOS_SpinLock(&g_taskSpin); + OsSortLinkUpdateExpireTime(sleepTicks, &OsPercpuGet()->taskSortLink); + LOS_SpinUnlock(&g_taskSpin); + LOS_SpinLock(&g_swtmrSpin); + OsSortLinkUpdateExpireTime(sleepTicks, &OsPercpuGet()->swtmrSortLink); + LOS_SpinUnlock(&g_swtmrSpin); + LOS_IntRestore(intSave); +} - g_bTickIrqFlag = 0; - osTicklessStart(); +VOID OsTicklessUpdate(UINT32 irqnum) +{ + UINT32 cycles, ticks; + UINT32 cyclesPertick; + UINT32 sleepTicks; + UINT32 intSave = LOS_IntLock(); + + sleepTicks = OsTicklessSleepTickGet(); + if (sleepTicks == 0) { + LOS_IntRestore(intSave); + return; + } - osEnterSleep(); - LOS_IntRestore(uvIntSave); + cyclesPertick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; + if (irqnum == OS_TICK_INT_NUM) { + OsSysTimeUpdate(sleepTicks); + } else { + cycles = HalClockGetTickTimerCycles(); + cycles = (sleepTicks * cyclesPertick) - cycles; + ticks = cycles / cyclesPertick; + if (ticks < sleepTicks) { + cycles = cycles % cyclesPertick; + OsSysTimeUpdate(ticks + 1); + HalClockTickTimerReload(cyclesPertick - cycles); + } else { + /* + * If ticks is greater or equal to sleepTicks, it means the tick has already + * arrived, it should compensate with the sleepTicks just as that will be done + * in tick handler. + */ + OsSysTimeUpdate(sleepTicks); + } + } + OsTicklessSleepTickSet(0); - /* - * Here: Handling interrupts. However, because the task scheduler is locked, - * there will be no task switching, after the interrupt exit, the CPU returns - * here to continue excuting the following code. - */ + LOS_IntRestore(intSave); +} - uvIntSave = LOS_IntLock(); - osUpdateKernelTickCount(0); /* param: 0 - invalid */ - LOS_TaskUnlock(); - LOS_IntRestore(uvIntSave); - } - else - { - /* Waiting for g_bTickIrqFlag setup, at most one tick time, sleep directly */ - osEnterSleep(); +VOID OsTicklessStart(VOID) +{ + UINT32 intSave; + /* + * The system has already started, the g_sysClock is non-zero and greater or equal to + * LOSCFG_BASE_CORE_TICK_PER_SECOND (see OsTickInit). So the cyclesPerTick won't be zero. + */ + UINT32 cyclesPerTick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; + UINT32 maxTicks = OS_NULL_INT / cyclesPerTick; + UINT32 sleepTicks; + UINT32 cycles, cyclesPre, cyclesCur, cycleCompensate; + + intSave = LOS_IntLock(); + /* + * The sleep tick may be changed afterwards, cause interrupt has been disabled, the sleep tick + * may increase but cannot decrease. Thus there's no need to spin here. + */ + sleepTicks = OsSleepTicksGet(); + cyclesPre = HalClockGetTickTimerCycles(); + + if (sleepTicks > 1) { + if (sleepTicks >= maxTicks) { + sleepTicks = maxTicks; + } + cycles = sleepTicks * cyclesPerTick; + cyclesCur = HalClockGetTickTimerCycles(); + cycleCompensate = OS_GET_CYCLECOMPENSATE(cyclesPre, cyclesCur); + HalClockTickTimerReload(cycles - cycleCompensate); + OsTicklessSleepTickSet(sleepTicks); + LOS_IntRestore(intSave); + + return; } - -#endif + LOS_IntRestore(intSave); + return; } #ifdef __cplusplus @@ -226,6 +201,3 @@ VOID osTicklessHandler(VOID) } #endif /* __cplusplus */ #endif /* __cplusplus */ - -#endif /* end of #if (LOSCFG_KERNEL_TICKLESS == YES) */ - diff --git a/kernel/extended/tickless/los_tickless.inc b/kernel/extended/tickless/los_tickless.inc deleted file mode 100644 index c2a7efa0d..000000000 --- a/kernel/extended/tickless/los_tickless.inc +++ /dev/null @@ -1,44 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_TICKLESS_INC -#define _LOS_TICKLESS_INC - -#include "los_tick.ph" -#include "los_tickless.ph" - -#define OS_GET_CYCLECOMPENSATE(uwCyclesPre,uwCyclesCur) ((uwCyclesPre > uwCyclesCur) ? \ - (g_uwSysClock / g_uwTickPerSecond - uwCyclesCur) : ((g_uwSysClock / g_uwTickPerSecond) * 2 - uwCyclesCur)) - -#endif /* _LOS_TICKLESS_INC */ diff --git a/kernel/include/los_base.h b/kernel/include/los_base.h index 8d7eeb722..8829a725d 100644 --- a/kernel/include/los_base.h +++ b/kernel/include/los_base.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Basic definitions * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup kernel Kernel +/** + * @defgroup kernel Kernel * @defgroup los_base Basic definitions * @ingroup kernel */ @@ -40,17 +41,18 @@ #ifndef _LOS_BASE_H #define _LOS_BASE_H -#ifdef LOSCFG_LIB_LIBCMINI -#include "libcmini.h" -#endif #include "los_builddef.h" #include "los_typedef.h" #include "los_config.h" #include "los_printf.h" #include "los_list.h" +#include "los_err.h" #include "los_errno.h" -#include "los_compiler.h" - +#include "los_hw.h" +#include "securec.h" +#ifdef LOSCFG_LIB_LIBCMINI +#include "stdarg.h" +#endif #ifdef __cplusplus #if __cplusplus extern "C" { @@ -58,9 +60,9 @@ extern "C" { #endif /* __cplusplus */ -#define SIZE(a) (a) +#define SIZE(a) (a) -#define LOS_ASSERT_COND(expression) +#define LOS_ASSERT_COND(expression) LOS_ASSERT(expression) /** * @ingroup los_base @@ -76,191 +78,156 @@ extern "C" { /** * @ingroup los_base - * Align the beginning of the object with the base address uwAddr, with uwBoundary bytes being the smallest unit of alignment. + * Align the beginning of the object with the base address addr, with boundary bytes being the smallest unit of + * alignment. */ #ifndef ALIGN -#define ALIGN(uwAddr, uwBoundary) LOS_Align(uwAddr, uwBoundary) +#define ALIGN(addr, boundary) LOS_Align(addr, boundary) #endif + /** * @ingroup los_base - * Align the tail of the object with the base address uwAddr, with uwSize bytes being the smallest unit of alignment. + * Align the tail of the object with the base address addr, with size bytes being the smallest unit of alignment. */ -#define TRUNCATE(uwAddr, uwSize) ((uwAddr) & ~((uwSize) - 1)) +#define TRUNCATE(addr, size) ((UINTPTR)(addr) & ~((size) - 1)) /** * @ingroup los_base - * Read a UINT8 value from ucAddr and stroed in ucValue. + * Read a UINT8 value from addr and stroed in value. */ -#define READ_UINT8(ucValue, ucAddr) ((ucValue) = *((volatile UINT8 *)(ucAddr))) +#define READ_UINT8(value, addr) ({ (value) = *((volatile UINT8 *)((UINTPTR)(addr))); dsb(); }) + /** * @ingroup los_base - * Read a UINT16 value from usAddr and stroed in usAddr. + * Read a UINT16 value from addr and stroed in addr. */ -#define READ_UINT16(usValue, usAddr) ((usValue) = *((volatile UINT16 *)(usAddr))) +#define READ_UINT16(value, addr) ({ (value) = *((volatile UINT16 *)((UINTPTR)(addr))); dsb(); }) + /** * @ingroup los_base - * Read a UINT32 value from uwAddr and stroed in uwValue. + * Read a UINT32 value from addr and stroed in value. */ -#define READ_UINT32(uwValue, uwAddr) ((uwValue) = *((volatile UINT32 *)(uwAddr))) +#define READ_UINT32(value, addr) ({ (value) = *((volatile UINT32 *)((UINTPTR)(addr))); dsb(); }) + /** * @ingroup los_base - * Read a UINT64 value from ullAddr and stroed in ullValue. + * Read a UINT64 value from addr and stroed in value. */ -#define READ_UINT64(ullValue, ullAddr) ((ullValue) = *((volatile UINT64 *)(ullAddr))) - +#define READ_UINT64(value, addr) ({ (value) = *((volatile UINT64 *)((UINTPTR)(addr))); dsb(); }) /** * @ingroup los_base - * Get a UINT8 value from ucAddr. + * Write a UINT8 value to addr. */ -#define GET_UINT8(ucAddr) (*((volatile UINT8 *)(ucAddr))) +#define WRITE_UINT8(value, addr) ({ dsb(); *((volatile UINT8 *)((UINTPTR)(addr))) = (value); }) + /** * @ingroup los_base - * Get a UINT16 value from usAddr. + * Write a UINT16 value to addr. */ -#define GET_UINT16(usAddr) (*((volatile UINT16 *)(usAddr))) +#define WRITE_UINT16(value, addr) ({ dsb(); *((volatile UINT16 *)((UINTPTR)(addr))) = (value); }) + /** * @ingroup los_base - * Get a UINT32 value from uwAddr. + * Write a UINT32 value to addr. */ -#define GET_UINT32(uwAddr) (*((volatile UINT32 *)(uwAddr))) +#define WRITE_UINT32(value, addr) ({ dsb(); *((volatile UINT32 *)((UINTPTR)(addr))) = (value); }) + /** * @ingroup los_base - * Get a UINT64 value from ullAddr. + * Write a UINT64 addr to addr. */ -#define GET_UINT64(ullAddr) (*((volatile UINT64 *)(ullAddr))) +#define WRITE_UINT64(value, addr) ({ dsb(); *((volatile UINT64 *)((UINTPTR)(addr))) = (value); }) /** * @ingroup los_base - * Write a UINT8 ucValue to ucAddr. + * Get a UINT8 value from addr. */ -#define WRITE_UINT8(ucValue, ucAddr) (*((volatile UINT8 *)(ucAddr)) = (ucValue)) +#define GET_UINT8(addr) ({ UINT8 r = *((volatile UINT8 *)((UINTPTR)(addr))); dsb(); r; }) + /** * @ingroup los_base - * Write a UINT16 usValue to usAddr. + * Get a UINT16 value from addr. */ -#define WRITE_UINT16(usValue, usAddr) (*((volatile UINT16 *)(usAddr)) = (usValue)) +#define GET_UINT16(addr) ({ UINT16 r = *((volatile UINT16 *)((UINTPTR)(addr))); dsb(); r; }) + /** * @ingroup los_base - * Write a UINT32 uwValue to uwAddr. + * Get a UINT32 value from addr. */ -#define WRITE_UINT32(uwValue, uwAddr) (*((volatile UINT32 *)(uwAddr)) = (uwValue)) +#define GET_UINT32(addr) ({ UINT32 r = *((volatile UINT32 *)((UINTPTR)(addr))); dsb(); r; }) + /** * @ingroup los_base - * Write a UINT64 ullAddr to ullAddr. + * Get a UINT64 value from addr. */ -#define WRITE_UINT64(ullValue, ullAddr) (*((volatile UINT64 *)(ullAddr)) = (ullValue)) +#define GET_UINT64(addr) ({ UINT64 r = *((volatile UINT64 *)((UINTPTR)(addr))); dsb(); r; }) -/*lint -e40*/ #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) +#define LOS_ASSERT(judge) do { \ + if ((UINT32)(judge) == 0) { \ + (VOID)LOS_IntLock(); \ + PRINT_ERR("ASSERT ERROR! %s, %d, %s\n", __FILE__, __LINE__, __FUNCTION__); \ + while (1) {} \ + } \ +} while (0) #endif -/*lint +e40*/ + +#define STATIC_ASSERT _Static_assert /** - *@ingroup los_base - *@brief Align the value (uwAddr) by some bytes (uwBoundary) you specify. + * @ingroup los_base + * @brief Align the value (addr) by some bytes (boundary) you specify. * * @par Description: - * This API is used to align the value (uwAddr) by some bytes (uwBoundary) you specify. + * This API is used to align the value (addr) by some bytes (boundary) you specify. * * @attention *
    - *
  • the value of uwBoundary usually is 4,8,16,32.
  • + *
  • the value of boundary usually is 4,8,16,32.
  • *
* - *@param uwAddr [IN] The variable what you want to align. - *@param uwBoundary [IN] The align size what you want to align. + * @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 - *@since Huawei LiteOS V100R001C00 + * @retval #UINTPTR The variable what have been aligned. + * @par Dependency: + *
  • los_base.h: the header file that contains the API declaration.
+ * @see + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_Align(UINT32 uwAddr, UINT32 uwBoundary); +extern UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary); /** - *@ingroup los_base - *@brief Sleep the current task. + * @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. + * 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.
  • + *
  • 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 uwMsecs [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 - *@since Huawei LiteOS V100R001C00 - */ -extern VOID LOS_Msleep(UINT32 uwMsecs); - -/** - *@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 - *@since Huawei LiteOS V100R001C00 - */ -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. + * @param msecs [IN] Type #UINT32 Number of MS for which the task is delayed. * - *@par Dependency: - *
  • los_config.h: the header file that contains the API declaration.
- *@see - *@since Huawei LiteOS V100R001C00 + * @retval None + * @par Dependency: + *
  • los_base.h: the header file that contains the API declaration.
+ * @see None + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_KernelInit(VOID); +extern VOID LOS_Msleep(UINT32 msecs); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_bitmap.h b/kernel/include/los_bitmap.h new file mode 100644 index 000000000..192ef7fd7 --- /dev/null +++ b/kernel/include/los_bitmap.h @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: BitMap HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_bitmap Bitmap + * @ingroup kernel + */ + +#ifndef _LOS_BITMAP_H +#define _LOS_BITMAP_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_bitmap + * Flag that indicates the invalid bit index. + * + * The effective bit index is from 0 to 31. + */ +#define LOS_INVALID_BIT_INDEX 32 + +/** + * @ingroup los_bitmap + * @brief Set one bit. + * + * @par Description: + * This API is used to set one bit of variable according to the parameter. + * @attention + *
    + *
  • When the value of pos is greater than 31, the bit (pos & 0x1f) of bitmap will be set.
  • + *
+ * @param bitmap [IN] The bitmap variable pointer. + * @param pos [IN] The number bit to be set. + * + * @retval None + * @par Dependency: + *
  • los_bitmap.h: the header file that contains the API declaration.
+ * @see LOS_BitmapClr + * @since Huawei LiteOS V100R001C00 + */ +VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos); + +/** + * @ingroup los_bitmap + * @brief Clear one bit. + * + * @par Description: + * This API is used to clear one bit of variable according to the parameter. + * @attention + *
    + *
  • When the value of pos is greater than 31, the bit (pos & 0x1f) of bitmap will be clear.
  • + *
+ * @param bitmap [IN] The bitmap variable pointer. + * @param pos [IN] The number bit to be cleared. + * + * @retval none. + * @par Dependency: + *
  • los_bitmap.h: the header file that contains the API declaration.
+ * @see LOS_BitmapSet. + * @since Huawei LiteOS V100R001C00 + */ +VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos); + +/** + * @ingroup los_bitmap + * @brief Find the lowest one bit that is set. + * + * @par Description: + * This API is used to find the lowest one bit that is set and return the bit index. + * @attention + *
    + *
  • None
  • + *
+ * @param bitmap [IN] The bitmap variable. + * + * @retval UINT16 The bit index of the lowest one bit that is set. + * @par Dependency: + *
  • los_bitmap.h: the header file that contains the API declaration.
+ * @see LOS_HighBitGet + * @since Huawei LiteOS V100R001C00 + */ +UINT16 LOS_LowBitGet(UINT32 bitmap); + +/** + * @ingroup los_bitmap + * @brief Find the highest one bit that is set. + * + * @par Description: + * This API is used to find the highest one bit that is set and return the bit index. + * @attention + *
    + *
  • None
  • + *
+ * @param bitmap [IN] The bitmap variable. + * + * @retval UINT16 The bit index of the highest one bit that is set. + * @par Dependency: + *
  • los_bitmap.h: the header file that contains the API declaration.
+ * @see LOS_LowBitGet + * @since Huawei LiteOS V100R001C00 + */ +UINT16 LOS_HighBitGet(UINT32 bitmap); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BITMAP_H */ diff --git a/kernel/include/los_compiler.h b/kernel/include/los_compiler.h deleted file mode 100644 index 352d79af6..000000000 --- a/kernel/include/los_compiler.h +++ /dev/null @@ -1,190 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef __LOS_COMPILER_H -#define __LOS_COMPILER_H - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -#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 __CLZ - #endif - -#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 - -#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 - -#elif defined (__ICC430__) - -#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 -#endif - -#ifndef WEAK - #define WEAK -#endif - -#ifndef CLZ - extern int __clz (unsigned long); - #define CLZ __clz -#endif - -#elif defined (__TI_COMPILER_VERSION__) - -#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 -#endif - -#ifndef WEAK - #define WEAK -#endif - -#ifndef CLZ - extern int __clz (unsigned long); - #define CLZ __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 deleted file mode 100644 index 3924a37ed..000000000 --- a/kernel/include/los_config.h +++ /dev/null @@ -1,1132 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@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 - -/*============================================================================= - 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 - * 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 - -/*============================================================================= - 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_sys_mem_addr_end; - - -/** - * @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 - * 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 &m_aucSysNoCacheMem0[0] -#endif - -/** - * @ingroup los_config - * Configuration module tailoring of the total amount of memory used for tasks - */ -#ifndef LOSCFG_MEM_TASK_USED_STATISTICS -#define LOSCFG_MEM_TASK_USED_STATISTICS NO -#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 item for saveing exception info tailoring - */ -#ifndef LOSCFG_SAVE_EXC_INFO -#define LOSCFG_SAVE_EXC_INFO NO -#endif - -#if (LOSCFG_PLATFORM_EXC == YES) - -/** - * @ingroup los_config - * Configuration exception call stack analysis max depth - */ -#ifndef LOSCFG_EXC_CALL_STACK_ANALYSIS_MAX_DEPTH -#define LOSCFG_EXC_CALL_STACK_ANALYSIS_MAX_DEPTH 16 -#endif - -/** - * @ingroup los_config - * Configuration code start address and code size, msp start address and size - * - * NOTE: Users must reconfigure these macros, otherwise, the invocation relationship - * can not be correctly analyzed. - */ -#ifndef LOSCFG_EXC_CODE_START_ADDR -#define LOSCFG_EXC_CODE_START_ADDR (0x08000000) /* invalid, Please reconfigure it */ -#endif -#ifndef LOSCFG_EXC_CODE_SIZE -#define LOSCFG_EXC_CODE_SIZE (0x00100000) /* invalid, Please reconfigure it */ -#endif -#ifndef LOSCFG_EXC_MSP_START_ADDR -#define LOSCFG_EXC_MSP_START_ADDR (0x20000000) /* invalid, Please reconfigure it */ -#endif -#ifndef LOSCFG_EXC_MSP_SIZE -#define LOSCFG_EXC_MSP_SIZE (0x00080000) /* invalid, Please reconfigure it */ -#endif - -#endif /* LOSCFG_PLATFORM_EXC == YES */ - -#if(LOSCFG_PLATFORM_EXC == NO && LOSCFG_SAVE_EXC_INFO == YES) - #error "save exception info need support platform exception, should make LOSCFG_PLATFORM_EXC = YES" -#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 - */ -#ifndef LOSCFG_TEST -#define LOSCFG_TEST NO -#endif - - -/*============================================================================= - LiteOS kernel version configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Version number - */ -#ifndef LITEOS_VER -#define LITEOS_VER "Huawei LiteOS Kernel V200R001c50" -#endif - -/** - * @ingroup los_config - * Configuration CMSIS_OS_VER - */ -#ifndef CMSIS_OS_VER -#define CMSIS_OS_VER 1 -#endif - - -/*============================================================================= - LIB module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * newlib struct _reent - */ -#ifndef LOSCFG_LIB_LIBC_NEWLIB_REENT -#define LOSCFG_LIB_LIBC_NEWLIB_REENT NO -#endif - - -/*============================================================================= - VFS module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for enabling LiteOS VFS - */ -#ifndef LOSCFG_ENABLE_VFS -#define LOSCFG_ENABLE_VFS NO -#endif - - -/** - * @ingroup los_config - * Configuration item for enabling LiteOS KIFS (kernel info fs) - */ -#ifndef LOSCFG_ENABLE_KIFS -#define LOSCFG_ENABLE_KIFS NO -#endif - - -/*============================================================================= - DEVFS module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for enabling LiteOS DEVFS - */ -#ifndef LOSCFG_ENABLE_DEVFS -#define LOSCFG_ENABLE_DEVFS NO -#else -#if (LOSCFG_ENABLE_DEVFS == YES) -#undef LOSCFG_ENABLE_VFS -#define LOSCFG_ENABLE_VFS YES -#undef LOSCFG_ENABLE_KIFS -#define LOSCFG_ENABLE_KIFS YES -#endif -#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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 los_TestInit(VOID); - - -/** - * @ingroup los_config - * @brief: User application Task init function. - * - * @par Description: - * This API is used to initialize User application Task module. - * - * @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. - * @since Huawei LiteOS V100R001C00 - */ -//extern UINT32 osAppInit(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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -extern VOID osHwInit(VOID); - - -/** - *@ingroup los_config - *@brief Configure Tick Interrupt Start. - * - *@par Description: - *This API is used to configure Tick Interrupt Start. - * - *@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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 osTickStart(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 - *@since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -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. - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 osCpupInit(VOID); - - -extern LITE_OS_SEC_TEXT_INIT UINT32 LOS_Start(void); - - -extern LITE_OS_SEC_TEXT_INIT int 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 100644 index 000000000..27157d67a --- /dev/null +++ b/kernel/include/los_cppsupport.h @@ -0,0 +1,104 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Cpp Support HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @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 + * If LOS_CppSystemInit() is called in the first stage of scatter load, + * this flag should be passed as the third parameter + */ +#define BEFORE_SCATTER 0 + +/** + * @ingroup los_cppsupport + * If LOS_CppSystemInit() is called in the second stage of scatter load, + * this flag should be passed as the third parameter + */ +#define AFTER_SCATTER 1 + +/** + * @ingroup los_cppsupport + * If scatter load is disabled, this flag should be passed as the third parameter when LOS_CppSystemInit() is called. + */ +#define NO_SCATTER 2 + +/** + * @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.
  • + *
+ * + * @param initArrayStart [IN] Start address of init_array section. + * @param initArrayEnd [IN] End address of init_array section. + * @param flag [IN] Under what circumstances when LOS_CppSystemInit() is called, + * BEFORE_SCATTER, AFTER_SCATTER or NO_SCATTER. + * + * @retval 0 always return 0. + * @par Dependency: + *
  • los_cppsupport.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd, INT32 flag); + +#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 100644 index 000000000..4a549e4fb --- /dev/null +++ b/kernel/include/los_cpup.h @@ -0,0 +1,300 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description : LiteOS Cpu Usage Calculation Module Headfile For User + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @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 + * 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_cpup + * Query the CPU usage of the system. + */ +enum { + CPUP_LAST_TEN_SECONDS = 0, /**< Display CPU usage in the last ten seconds. */ + CPUP_LAST_ONE_SECONDS = 1, /**< Display CPU usage in the last one seconds. */ + CPUP_ALL_TIME = 0xffff /**< Display CPU usage from system startup to now. */ +}; + +/** + * @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_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 all time will be obtained. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #UINT32 [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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_HistorySysCpuUsage(UINT16 mode); + +/** + * @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 #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #LOS_ERRNO_CPUP_TSK_ID_INVALID The target task ID is invalid. + * @retval #LOS_ERRNO_CPUP_THREAD_NO_CREATED The target thread is not created. + * @retval #UINT32 [0,100], CPU usage of the specified task. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode); + +/** + * @ingroup los_cpup + * @brief Obtain the CPU usage of tasks and hwi. + * + * @par Description: + * This API is used to obtain the CPU usage of tasks and hwi according to the passed-in maximum number and usFlag + * which indicate obtain the cpup usage of task or hwi. + * @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, and the maximum number must be usable. Otherwise, the CPU usage + * fails to be obtained.
  • + *
  • The input parameter pointer should point to the structure array whose size be greater than + * (maxNum * sizeof (CPUP_INFO_S)).
  • + *
+ * + * @param maxNum [IN] UINT16. The Maximum number of threads or hwis. + * @param cpupInfo [OUT]Type. CPUP_INFO_S* Pointer to the CPUP information structure to be obtained. + * @param mode [IN] UINT16. Time 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 all time will be + * obtained. + * @param flag [IN] UINT16. The parameter value 0 indicates that the CPU usage of hwi. Other values indicate that + * the CPU usage of task. + * + * @retval #LOS_ERRNO_CPUP_NO_INIT The CPU usage is not initialized. + * @retval #LOS_ERRNO_CPUP_TASK_PTR_NULL The input parameter pointer is NULL. + * @retval #LOS_ERRNO_CPUP_MAXNUM_INVALID The maximum number of threads or hwi is invalid. + * @retval #LOS_OK The CPU usage of all tasks or hwi is successfully obtained. + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT16 mode, UINT16 flag); + +/** + * @ingroup los_cpup + * @brief Reset the data of CPU usage. + * + * @par Description: + * This API is used to reset the data of CPU usage. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param None. + * + * @retval #None. + * + * @par Dependency: + *
  • los_cpup.h: the header file that contains the API declaration.
+ * @see + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_CpupReset(VOID); + +/** + * @ingroup los_cpup + * @brief Obtain CPU usage history of certain task or system. + * + * @par Description: + * This API is used to obtain CPU usage history of certain task or system. + * @attention + *
    + *
  • This API can be called only after the CPU usage is initialized. Otherwise, -1 will be returned.
  • + *
  • Only in SYS_CPU_USAGE type, taskID is unused.
  • + *
+ * + * @param type [IN] cpup type, SYS_CPU_USAGE or TASK_CPU_USAGE + * @param mode [IN] mode,CPUP_LAST_TEN_SECONDS = usage in 10s,CPUP_LAST_ONE_SECONDS = usage in last 1s, + * CPUP_ALL_TIME = usage form system startup, if the inpuit mode is none of them, it will be as CPUP_ALL_TIME. + * @param taskID [IN] task ID, Only in SYS_CPU_USAGE type, taskID is unused + * + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, UINT16 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 index 551547571..1c6a7860f 100644 --- a/kernel/include/los_err.h +++ b/kernel/include/los_err.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Error Handling * 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 @@ -22,24 +22,25 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_err Error handling +/** + * @defgroup los_err Error handling * @ingroup kernel */ #ifndef _LOS_ERR_H #define _LOS_ERR_H -#include "los_base.h" +#include "los_typedef.h" #ifdef __cplusplus #if __cplusplus @@ -47,119 +48,116 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** - *@ingroup los_err - *@brief Define the pointer to the error handling function. + * @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.
  • - *
+ * @par Description: + * This API is used to define the pointer to the error handling function. + * @attention + *
    + *
  • None.
  • + *
* - *@param pcFileName [IN] Log file that stores error information. - *@param uwLineNo [IN] Line number of the erroneous line. - *@param uwErrorNo [IN] Error code. - *@param uwParaLen [IN] Length of the input parameter pPara. - *@param pPara [IN] User label of the error. + * @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. - *@since Huawei LiteOS V100R001C00 + * @retval None. + * @par Dependency: + *
  • los_err.h: the header file that contains the API declaration.
+ * @see None. + * @since Huawei LiteOS V100R001C00 */ -typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *pcFileName, - UINT32 uwLineNo, /**< Line number of the erroneous line.*/ - UINT32 uwErrorNo, /**< Error code. */ - UINT32 uwParaLen, /**< Length of the input parameter pPara.*/ - VOID *pPara); +typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName, + UINT32 lineNo, + UINT32 errorNo, + UINT32 paraLen, + VOID *para); /** - *@ingroup los_err - *@brief Error handling function. + * @ingroup los_err + * @brief Error handling function. * - *@par Description: - *This API is used to perform different operations according to error types. - *@attention - *
    - *
  • None
  • - *
+ * @par Description: + * This API is used to perform different operations according to error types. + * @attention + *
    + *
  • None
  • + *
* - *@param pcFileName [IN] Log file that stores error information. - *@param uwLineNo [IN] Line number of the erroneous line which should not be OS_ERR_MAGIC_WORD. - *@param uwErrorNo [IN] Error code. - *@param uwParaLen [IN] Length of the input parameter pPara. - *@param pPara [IN] User label of the error. + * @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 - *@since Huawei LiteOS V100R001C00 + * @retval LOS_OK The error is successfully processed. + * @par Dependency: + *
  • los_err.h: the header file that contains the API declaration.
+ * @see None + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_ErrHandle(CHAR *pcFileName, UINT32 uwLineNo, - UINT32 uwErrorNo, UINT32 uwParaLen, - VOID *pPara); +extern UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, + UINT32 errorNo, UINT32 paraLen, + VOID *para); /** * @ingroup los_err * Error handling function structure. */ -typedef struct tagUserErrFunc_S -{ - LOS_ERRORHANDLE_FUNC pfnHook; /**< Hook function for error handling.*/ +typedef struct tagUserErrFunc_S { + LOS_ERRORHANDLE_FUNC pfnHook; /**< Hook function for error handling. */ } USER_ERR_FUNC_S; /** * @ingroup los_err * Error handling function. */ -extern USER_ERR_FUNC_S g_stUserErrFunc; - -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, +extern USER_ERR_FUNC_S g_stUserErrFunc; + +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_DRIVER = 0x41, LOS_MOD_BUTT }; - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/include/los_errno.h b/kernel/include/los_errno.h index c9868d80e..9f5e02006 100644 --- a/kernel/include/los_errno.h +++ b/kernel/include/los_errno.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Errno * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_errno Error code +/** + * @defgroup los_errno Error code * @ingroup kernel */ @@ -40,7 +41,6 @@ #define _LOS_ERRNO_H #include "los_typedef.h" -#include "los_err.h" #ifdef __cplusplus #if __cplusplus @@ -48,65 +48,63 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** - * @ingroup los_errno - * OS error code flag. - */ -#define LOS_ERRNO_OS_ID ((UINT32)0x00 << 16) + * @ingroup los_errno + * OS error code flag. + */ +#define LOS_ERRNO_OS_ID (0x00U << 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 informative. + */ +#define LOS_ERRTYPE_NORMAL (0x00U << 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 warning. + */ +#define LOS_ERRTYPE_WARN (0x01U << 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 critical. + */ +#define LOS_ERRTYPE_ERROR (0x02U << 24) /** - * @ingroup los_errno - * Define the error level as fatal. - */ -#define LOS_ERRTYPE_FATAL ((UINT32)0x03 << 24) + * @ingroup los_errno + * Define the error level as fatal. + */ +#define LOS_ERRTYPE_FATAL (0x03U << 24) /** - * @ingroup los_errno - * Define fatal OS errors. - */ -#define LOS_ERRNO_OS_FATAL(MID, ERRNO) \ - (LOS_ERRTYPE_FATAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) + * @ingroup los_errno + * Define fatal OS errors. + */ +#define LOS_ERRNO_OS_FATAL(MID, ERRNO) \ + (LOS_ERRTYPE_FATAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) /** - * @ingroup los_errno - * Define critical OS errors. - */ -#define LOS_ERRNO_OS_ERROR(MID, ERRNO) \ - (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) + * @ingroup los_errno + * Define critical OS errors. + */ +#define LOS_ERRNO_OS_ERROR(MID, ERRNO) \ + (LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) /** - * @ingroup los_errno - * Define warning OS errors. - */ -#define LOS_ERRNO_OS_WARN(MID, ERRNO) \ - (LOS_ERRTYPE_WARN | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) + * @ingroup los_errno + * Define warning OS errors. + */ +#define LOS_ERRNO_OS_WARN(MID, ERRNO) \ + (LOS_ERRTYPE_WARN | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) /** - * @ingroup los_errno - * Define informative OS errors. - */ -#define LOS_ERRNO_OS_NORMAL(MID, ERRNO) \ - (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO)) - + * @ingroup los_errno + * Define informative OS errors. + */ +#define LOS_ERRNO_OS_NORMAL(MID, ERRNO) \ + (LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO))) #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_event.h b/kernel/include/los_event.h index ff6fd47cb..b4ffa0350 100644 --- a/kernel/include/los_event.h +++ b/kernel/include/los_event.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Event * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_event Event +/** + * @defgroup los_event Event * @ingroup kernel */ @@ -48,24 +49,23 @@ 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 */ +#define LOS_WAITMODE_AND 4U /** * @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 */ +#define LOS_WAITMODE_OR 2U /** * @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 */ +#define LOS_WAITMODE_CLR 1U /** * @ingroup los_event @@ -75,7 +75,8 @@ extern "C" { * * 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) +#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. @@ -84,7 +85,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_EVENT_READ_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x01) /** * @ingroup los_event @@ -94,7 +95,7 @@ extern "C" { * * Solution: Pass in a valid EVENTMASK value. */ -#define LOS_ERRNO_EVENT_EVENTMASK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x02) +#define LOS_ERRNO_EVENT_EVENTMASK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x02) /** * @ingroup los_event @@ -104,17 +105,20 @@ extern "C" { * * Solution: Read the event in a task. */ -#define LOS_ERRNO_EVENT_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x03) +#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. + * Event reading error code: The flag 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. + * Solution: Pass in a valid flag value. */ -#define LOS_ERRNO_EVENT_FLAGS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x04) +#define LOS_ERRNO_EVENT_FLAGS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x04) /** * @ingroup los_event @@ -124,7 +128,7 @@ extern "C" { * * Solution: Unlock the task and read the event. */ -#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) +#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05) /** * @ingroup los_event @@ -134,190 +138,209 @@ extern "C" { * * Solution: Check whether the input parameter is null. */ -#define LOS_ERRNO_EVENT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x06) +#define LOS_ERRNO_EVENT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x06) /** * @ingroup los_event - * Event reading error code: no initialized. - * + * Event reading error code: The event is being read in system-level task. + * old usage: The event is being read in software timer task. (LOS_ERRNO_EVENT_READ_IN_SWTMR_TSK) * Value: 0x02001c07 * - * Solution: Check whether the event is initialized. + * Solution: Read the event in a vailid task. */ -#define LOS_ERRNO_EVENT_NOT_INITIALIZED LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x07) +#define LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x07) /** * @ingroup los_event - * Event reading error code: should not be destory. + * 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) +#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*/ +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 pstEventCB. - *@attention - *
    - *
  • None.
  • - *
- * - *@param pstEventCB [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_EventInit(PEVENT_CB_S pstEventCB); +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 uwMode is LOS_WAITMODE_CLR, the puwEventID is passed-out.
  • - *
  • Otherwise the puwEventID is passed-in.
  • - *
- * - *@param uwEventID [IN/OUT] Pointer to the ID of the event to be checked. - *@param uwEventMask [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 uwEventID. - *@param uwMode [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 - *@since Huawei LiteOS V100R001C00 + * @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.
  • + *
  • 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 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 eventID. + * @param mode [IN] Event reading mode. The modes include LOS_WAITMODE_AND, LOS_WAITMODE_OR, LOS_WAITMODE_CLR. + * + * @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 mask is incorrect. + * @retval #LOS_ERRNO_EVENT_FLAGS_INVALID The passed-in event mode is invalid. + * @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_EventRead | LOS_EventWrite + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_EventPoll(UINT32 *uwEventID, UINT32 uwEventMask, UINT32 uwMode); +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 pstEventCB [IN/OUT] Pointer to the event control block to be checked. This parameter must point to valid memory. - *@param uwEventMask [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 uwEventID. - *@param uwMode [IN] Event reading mode. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_EventRead(PEVENT_CB_S pstEventCB, UINT32 uwEventMask, UINT32 uwMode, UINT32 uwTimeOut); +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 pstEventCB. - *@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 pstEventCB [IN/OUT] Pointer to the event control block into which an event is to be written. This parameter must point to valid memory. - *@param uwEvents [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_EventWrite(PEVENT_CB_S pstEventCB, UINT32 uwEvents); +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 pstEventCB to 0. pstEventCB must point to valid memory.
  • - *
- *@attention - *
    - *
  • The value of uwEvents needs to be reversed when it is passed-in.
  • - *
- * - *@param pstEventCB [IN/OUT] Pointer to the event control block to be cleared. - *@param uwEvents [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_EventClear(PEVENT_CB_S pstEventCB, UINT32 uwEvents); +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 pstEventCB [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_EventDestory(PEVENT_CB_S pstEventCB); - +extern UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_heap.h b/kernel/include/los_heap.h deleted file mode 100644 index 79616a870..000000000 --- a/kernel/include/los_heap.h +++ /dev/null @@ -1,208 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@defgroup los_heap Heap - * @ingroup kernel - */ - -#ifndef _LOS_HEAP_H -#define _LOS_HEAP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "los_base.h" -#if (LOSCFG_KERNEL_MEM_SLAB == YES) -#include "los_slab.ph" -#endif - -#define IS_ALIGNED(value) (0 == (((UINT32)(value)) & ((UINT32)(value - 1)))) -#define OS_MEM_ALIGN(value, uwAlign) (((UINT32)(value) + (UINT32)(uwAlign - 1)) & (~(UINT32)(uwAlign - 1))) -#define OS_MEM_ALIGN_FLAG (0x80000000) -#define OS_MEM_SET_ALIGN_FLAG(uwAlign) (uwAlign = ((uwAlign) | OS_MEM_ALIGN_FLAG)) -#define OS_MEM_GET_ALIGN_FLAG(uwAlign) ((uwAlign) & OS_MEM_ALIGN_FLAG) -#define OS_MEM_GET_ALIGN_GAPSIZE(uwAlign) ((uwAlign) & (~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() osHeapInit((VOID *)DDR_HEAP_START, DDR_HEAP_SIZE) -#define DDR_HEAP_ALLOC(sz) osHeapAllocAlign((VOID *)DDR_HEAP_START, OS_MEM_ALIGN(sz, DCACHE_LINE_SIZE), DCACHE_LINE_SIZE) -#define DDR_HEAP_FREE(p) osHeapFree((VOID *)DDR_HEAP_START, p) -#endif - -struct LOS_HEAP_NODE { - - struct LOS_HEAP_NODE* pstPrev; - UINT32 uwSize:30; - UINT32 uwUsed: 1; - UINT32 uwAlign:1; - UINT8 ucData[];/*lint !e43*/ -}; - -struct LOS_HEAP_MANAGER{ - struct LOS_HEAP_NODE *pstHead; - struct LOS_HEAP_NODE *pstTail; - UINT32 uwSize; -#if (LOSCFG_MEM_MUL_POOL == YES) - VOID *pNextPool; -#endif -#if (LOSCFG_KERNEL_MEM_SLAB == YES) - struct LOS_SLAB_CONTROL_HEADER stSlabCtrlHdr; -#endif -}; - -/** - *@ingroup los_heap - *@brief Initialization heap memory. - * - *@par Description: - *This API is used to initialization heap memory. - *@attention - *
    - *
  • None.
  • - *
- * - *@param pPool [IN/OUT] A pointer pointed to the memory pool. - *@param uwSz [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. - *@since Huawei LiteOS V100R001C00 - */ -extern BOOL osHeapInit(VOID *pPool, UINT32 uwSz); - -/** - *@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 pPool [IN/OUT] A pointer pointed to the memory pool. - *@param uwSz [IN] Size of heap memory. - * - *@retval VOID* - *@par Dependency: - *
  • los_heap.h: the header file that contains the API declaration.
- *@see osHeapFree - *@since Huawei LiteOS V100R001C00 - */ -extern VOID* osHeapAlloc(VOID *pPool, UINT32 uwSz); - -/** - *@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 pPool [IN/OUT] A pointer pointed to the memory pool. - *@param uwSz [IN] Size of heap memory. - *@param uwBoundary [IN] Boundary the heap needs align - * - *@retval VOID* - *@par Dependency: - *
  • los_heap.h: the header file that contains the API declaration.
- *@see osHeapFree - *@since Huawei LiteOS V100R001C00 - */ -extern VOID* osHeapAllocAlign(VOID *pPool, UINT32 uwSz, UINT32 uwBoundary); - -/** - *@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 pPool [IN/OUT] A pointer pointed to the memory pool. - *@param pPtr [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 osHeapAlloc - *@since Huawei LiteOS V100R001C00 - */ -extern BOOL osHeapFree(VOID *pPool, VOID* pPtr); - -/** - *@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. - *@since Huawei LiteOS - */ -#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES) -extern UINT32 osHeapGetHeapMemoryPeak(VOID); -#endif - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/kernel/include/los_ld_elflib.h b/kernel/include/los_ld_elflib.h new file mode 100644 index 000000000..5f51c2299 --- /dev/null +++ b/kernel/include/los_ld_elflib.h @@ -0,0 +1,255 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Dynload ElfLib HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup dynload Dynamic loading + * @ingroup kernel + */ + +#ifndef _LOS_LD_ELFLIB_H +#define _LOS_LD_ELFLIB_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup dynload + * @brief Set the memory pool address used by dynload + * + * @par Description: + * This API is used to set the memory pool address used by dynload. + * @attention + *
    + *
  • The parameter passed to this API should be a legal memory pool address by managed with LiteOS's memory + * algorithm, and whose value is outside of the LiteOS system memory
  • + *
+ * + * @param memPool [IN] the memory pool address. + * + * @retval TRUE Set successful. + * @retval FLASE Set failed. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_ModuleUnload + * @since Huawei LiteOS V200R002C00 + */ +extern BOOL LOS_DynMemPoolSet(VOID *memPool); + +/** + * @ingroup dynload + * @brief Load a shared object file. + * + * @par Description: + * This API is used to load a shared object file under a particular module file path. + * @attention + *
    + *
  • The parameter passed to this API should be a legal path of a shared object file.
  • + *
+ * + * @param elfFileName [IN] Shared object file path. + * + * @retval NULL The shared object file fails to be loaded. + * @retval VOID* The shared object file is successfully loaded. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_ModuleUnload + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_SoLoad(CHAR *elfFileName); + +/** + * @ingroup dynload + * @brief Load a object file. + * + * @par Description: + * This API is used to load a object file under a particular module file path. + * @attention + *
    + *
  • The parameter passed to this API should be a legal path of an object file.
  • + *
+ * + * @param elfFileName [IN] Object file path. + * + * @retval NULL The object file fails to be loaded. + * @retval VOID* The object file is successfully loaded. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_ModuleUnload + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_ObjLoad(CHAR *elfFileName); + +/** + * @ingroup dynload + * @brief Unload a module. + * + * @par Description: + * This API is used to unload a module with a particular module handle. + * @attention + *
    + *
  • None.
  • + *
+ * + * @param handle [IN] Module handle. + * + * @retval #LOS_NOK The module fails to be unloaded. + * @retval #LOS_OK The module is successfully unloaded. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_ObjLoad + * @since Huawei LiteOS V100R001C00 + */ +extern INT32 LOS_ModuleUnload(VOID *handle); + +/** + * @ingroup dynload + * @brief Destroy a dynamic loader. + * + * @par Description: + * This API is used to destroy a dynamic linker. + * @attention + *
    + *
  • When dynamic loading is no longer needed, call this API to destroy the dynamic linker.
  • + *
+ * + * @param None. + * + * @retval None. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_FindSymByName + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_LdDestroy(VOID); + +/** + * @ingroup dynload + * @brief Search for a symbol address. + * + * @par Description: + * This API is used to search for the address of a symbol according to a particular module handle and symbol name. + * @attention + *
    + *
  • If the value of handle is NULL, Huawei LiteOS searches for symbols (including system symbols) in the global + * symbol table. If handle is set to a valid module handle, Huawei LiteOS searches for symbols in the module that + * comes with the module handle.
  • + *
+ * + * @param handle [IN] Module handle. + * @param name [IN] Name of the symbol to be searched for. + * + * @retval NULL The symbol address is not found. + * @retval VOID* Symbol address. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_LdDestroy + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_FindSymByName(VOID *handle, CHAR *name); + +/** + * @ingroup dynload + * @brief Add a default path. + * + * @par Description: + * This API is used to add a path to default paths. + * @attention + *
    + *
  • + *
+ * + * @param path [IN] Path to be added to default paths. + * + * @retval #LOS_NOK The path is added unsuccessfully. + * @retval #LOS_OK The path is added successfully. + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_FindSymByName | LOS_LdDestroy + * @since Huawei LiteOS V100R001C00 + */ +extern INT32 LOS_PathAdd(CHAR *path); + +/** + * @ingroup dynload + * Define an enum type indicates load strategy. + * + * Type of load strategy of dynamic load, ZIP means using zipped shared object, NOZIP means using normal shared object. + */ +enum LOAD_STRATEGY { + ZIP, + NOZIP +}; + +/** + * @ingroup dynload + * Define the structure of the parameters used for dynamic. + * + * Information of specified parameters passed in during dynamic load. + */ +typedef struct tagDynloadParam { + enum LOAD_STRATEGY enLoadStrategy; +} DYNLOAD_PARAM_S; + +/** + * @ingroup dynload + * @brief Register the dynamic parameters. + * + * @par Description: + * This API is used to register the dynamic load parameters. + * @attention + *
    + *
  • + *
+ * + * @param dynloadParam [IN] dynamic load parameters to be registered. + * + * @par Dependency: + *
  • los_ld_elflib.h: the header file that contains the API declaration.
+ * @see LOS_FindSymByName | LOS_LdDestroy + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_DynParamReg(DYNLOAD_PARAM_S *dynloadParam); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_LD_ELFLIB_H */ diff --git a/kernel/include/los_list.h b/kernel/include/los_list.h index 96b9c7a0d..e314fb058 100644 --- a/kernel/include/los_list.h +++ b/kernel/include/los_list.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Doubly linked list * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ - /** @defgroup los_list Doubly linked list +/** + * @defgroup los_list Doubly linked list * @ingroup kernel */ @@ -47,404 +48,442 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** - *@ingroup los_list - *Structure of a node in a doubly linked list. + * @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*/ +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 pstList [IN] Node in a doubly linked list. - * - *@retval None. - *@par Dependency: - *
  • los_list.h: the header file that contains the API declaration.
- *@see - *@since Huawei LiteOS V100R001C00 + * @ingroup los_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 + * @since Huawei LiteOS V100R001C00 */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListInit(LOS_DL_LIST *pstList) +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list) { - pstList->pstNext = pstList; - pstList->pstPrev = pstList; + 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 pstObject [IN] Node in the doubly linked list. - * - *@retval None. - *@par Dependency: - *
  • los_list.h: the header file that contains the API declaration.
- *@see - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 + */ +#define LOS_DL_LIST_FIRST(object) ((object)->pstNext) + +/** + * @ingroup los_list + * @brief Point to the previous node pointed to by the current node. + * + * @par Description: + *
    + *
  • This API is used to point to the previous 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 + * @since Huawei LiteOS V100R001C00 */ -#define LOS_DL_LIST_FIRST(pstObject) ((pstObject)->pstNext) +#define LOS_DL_LIST_LAST(object) ((object)->pstPrev) + +/** + * @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 + * @since Huawei LiteOS V100R001C00 + */ +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 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 pstList [IN] Doubly linked list where the new node is inserted. - *@param pstNode [IN] New node to be inserted. - * - *@retval None - *@par Dependency: - *
  • los_list.h: the header file that contains the API declaration.
- *@see LOS_ListDelete - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListAdd(LOS_DL_LIST *pstList, LOS_DL_LIST *pstNode) +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node) { - pstNode->pstNext = pstList->pstNext; - pstNode->pstPrev = pstList; - pstList->pstNext->pstPrev = pstNode; - pstList->pstNext = pstNode; + LOS_ListAdd(list->pstPrev, 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 pstList [IN] Doubly linked list where the new node is inserted. - *@param pstNode [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 - *@since Huawei LiteOS V100R001C00 + * @ingroup los_list + * @brief Insert a node to the head of a doubly linked list. + * + * @par Description: + * This API is used to insert a new node to the head 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_ListTailInsert + * @since Huawei LiteOS V100R001C00 */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *pstList, LOS_DL_LIST *pstNode) +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListHeadInsert(LOS_DL_LIST *list, LOS_DL_LIST *node) { - LOS_ListAdd(pstList->pstPrev, pstNode); + LOS_ListAdd(list, 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 pstNode [IN] Node to be deleted. - * - *@retval None. - *@par Dependency: - *
  • los_list.h: the header file that contains the API declaration.
- *@see LOS_ListAdd - *@since Huawei LiteOS V100R001C00 + * @ingroup los_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 + * @since Huawei LiteOS V100R001C00 */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListDelete(LOS_DL_LIST *pstNode) +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node) { - pstNode->pstNext->pstPrev = pstNode->pstPrev; - pstNode->pstPrev->pstNext = pstNode->pstNext; - pstNode->pstNext = (LOS_DL_LIST *)NULL; - pstNode->pstPrev = (LOS_DL_LIST *)NULL; + node->pstNext->pstPrev = node->pstPrev; + node->pstPrev->pstNext = node->pstNext; + node->pstNext = NULL; + node->pstPrev = 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 pstList [IN] Doubly linked list. - * - *@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 - *@since Huawei LiteOS V100R001C00 + * @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 list. + * + * @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 + * @since Huawei LiteOS V100R001C00 */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *pstNode) +LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list) { - return (BOOL)(pstNode->pstNext == pstNode); + return (BOOL)(list->pstNext == list); } /** * @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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#define OFFSET_OF_FIELD(type, field) ((UINT32)&(((type *)0)->field)) +#define OFFSET_OF_FIELD(type, field) ((UINTPTR)&((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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#define LOS_OFF_SET_OF(type, member) ((long)&((type *)0)->member) /*lint -e(413) */ +#define LOS_OFF_SET_OF(type, member) ((UINTPTR)&((type *)0)->member) /** - *@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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ #define LOS_DL_LIST_ENTRY(item, type, member) \ - ((type *)((char *)item - LOS_OFF_SET_OF(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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#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)) +#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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#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)) - -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID osListDel(LOS_DL_LIST *pstPrevNode, LOS_DL_LIST *pstNextNode) -{ - pstNextNode->pstPrev = pstPrevNode; - pstPrevNode->pstNext = pstNextNode; -} +#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 pstList [IN] Doubly linked list. - * - *@retval None. - *@par Dependency: - *
  • los_list.h: the header file that contains the API declaration.
- *@see - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -LITE_OS_SEC_ALW_INLINE STATIC_INLINE VOID LOS_ListDelInit(LOS_DL_LIST *pstList) +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelInit(LOS_DL_LIST *list) { - osListDel(pstList->pstPrev, pstList->pstNext); - LOS_ListInit(pstList); + 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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#define LOS_DL_LIST_FOR_EACH(item, list) \ - for ((item) = (list)->pstNext; \ - (item) != (list); \ - (item) = (item)->pstNext) +#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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#define LOS_DL_LIST_FOR_EACH_SAFE(item, next, list) \ - for (item = (list)->pstNext, next = item->pstNext; item != (list); \ - item = next, next = item->pstNext) +#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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -#define LOS_DL_LIST_HEAD(list) \ - LOS_DL_LIST list = { &(list), &(list) } - +#define LOS_DL_LIST_HEAD(list) LOS_DL_LIST list = { &(list), &(list) } #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_membox.h b/kernel/include/los_membox.h index 34cfb50bd..0808fd20e 100644 --- a/kernel/include/los_membox.h +++ b/kernel/include/los_membox.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2017>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS memory Module HeadFile * 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 @@ -22,22 +22,25 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_membox Static memory + * @ingroup kernel + */ + #ifndef _LOS_MEMBOX_H #define _LOS_MEMBOX_H #include "los_config.h" -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_memcheck.h" -#endif #ifdef __cplusplus #if __cplusplus @@ -45,204 +48,213 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/** - * @ingroup los_membox - * Define whether to check the address validity - */ -#if (LOSCFG_PLATFORM_EXC == YES) -#define LOS_MEMBOX_CHECK -extern UINT8 g_aucMemMang[]; -#endif +#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) + (blkSize)) + +#define OS_MEMBOX_NODE_HEAD_SIZE sizeof(LOS_MEMBOX_NODE) /** * @ingroup los_membox * Structure of a free node in a memory pool */ -typedef struct tagMEMBOX_NODE -{ - struct tagMEMBOX_NODE *pstNext; /* Free node's pointer to the next node in a memory pool */ +typedef struct tagMEMBOX_NODE { + struct tagMEMBOX_NODE *pstNext; /**< Free node's pointer to the next node in a memory pool */ } LOS_MEMBOX_NODE; /** * @ingroup los_membox * Memory pool information structure */ -typedef struct -{ - UINT32 uwBlkSize; /* Block size */ - UINT32 uwBlkNum; /* Total number of blocks */ - UINT32 uwBlkCnt; /* The number of allocated blocks */ - LOS_MEMBOX_NODE stFreeList; /* Free list */ +typedef struct { + UINT32 uwBlkSize; /**< Block size */ + UINT32 uwBlkNum; /**< Block number */ + UINT32 uwBlkCnt; /**< The number of allocated blocks */ + LOS_MEMBOX_NODE stFreeList; /**< Free list */ } LOS_MEMBOX_INFO; +typedef LOS_MEMBOX_INFO OS_MEMBOX_S; + /** * @ingroup los_membox - * Default enabled membox's magic word detection function, this makes each block of membox - * need an extra 4 bytes of space. If it is not necessary, please do not change it. - * If the magic word of membox disabled, a bug will be generated, that is, when free a block - * that has been freed, the membox will be destroyed. + * Memory pool alignment */ -#define LOS_MEMBOX_MAGIC_CHECK -#ifdef LOS_MEMBOX_MAGIC_CHECK -#define LOS_MEMBOX_MAGIC_SIZE 4 -#else -#define LOS_MEMBOX_MAGIC_SIZE 0 -#endif +#define LOS_MEMBOX_ALLIGNED(memAddr) (((UINTPTR)(memAddr) + sizeof(UINTPTR) - 1) & (~(sizeof(UINTPTR) - 1))) /** * @ingroup los_membox - * The memory box is aligned to 4 (memory pool addr or memory box node size) + * Memory pool size */ -#define LOS_MEMBOX_ALIGNED(align) (((UINT32)(align) + 3) & 0xfffffffc) +#define LOS_MEMBOX_SIZE(blkSize, blkNum) \ + (sizeof(LOS_MEMBOX_INFO) + (LOS_MEMBOX_ALLIGNED((blkSize) + OS_MEMBOX_NODE_HEAD_SIZE) * (blkNum))) /** * @ingroup los_membox - * Memory pool size - * Users can use this macro to calculate the total size of membox based on block size and block number + * @brief Initialize a memory pool. + * + * @par Description: + *
    + *
  • This API is used to initialize a memory pool.
  • + *
+ * @attention + *
    + *
  • The poolSize 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.
  • + *
  • The pool parameter must be pointer size aligned.
  • + *
+ * + * @param pool [IN] Memory pool address. + * @param poolSize [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. + * @since Huawei LiteOS V100R001C00 */ -#define LOS_MEMBOX_SIZE(uwBlkSize, uwBlkNum) (sizeof(LOS_MEMBOX_INFO) + LOS_MEMBOX_ALIGNED(uwBlkSize + LOS_MEMBOX_MAGIC_SIZE) * (uwBlkNum)) +extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize); /** - *@ingroup los_membox - *@brief Initialize a memory pool. - * - *@par Description: - *
    - *
  • This API is used to initialize a memory pool.
  • - *
- *@attention - *
    - *
  • The uwBoxSize 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 pBoxMem [IN] Memory pool address. - *@param uwBoxSize [IN] Memory pool size. - *@param uwBlkSize [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. - *@since Huawei LiteOS V100R001C00 + * @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 pool [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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MemboxInit(VOID *pBoxMem, UINT32 uwBoxSize, UINT32 uwBlkSize); +extern VOID *LOS_MemboxAlloc(VOID *pool); /** - *@ingroup los_membox - *@brief Request a memory block. - * - *@par Description: - *
    - *
  • This API is used to request a memory block.
  • - *
- *@attention - *
    - *
  • The input pPool parameter must be initialized via func LOS_MemboxInit.
  • - *
- * - *@param pBoxMem [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 - *@since Huawei LiteOS V100R001C00 + * @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 box parameter must be allocated by LOS_MemboxAlloc.
  • + *
+ * + * @param pool [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 + * @since Huawei LiteOS V100R001C00 */ -extern VOID *LOS_MemboxAlloc(VOID *pBoxMem); +extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box); /** - *@ingroup los_membox - *@brief Free a memory block. - * - *@par Description: - *
    - *
  • This API is used to free a memory block.
  • - *
- *@attention - *
    - *
  • The input pPool parameter must be initialized via func LOS_MemboxInit.
  • - *
  • The input pBox parameter must be allocated by LOS_MemboxAlloc.
  • - *
- * - *@param pBoxMem [IN] Memory pool address. - *@param pBox [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 - *@since Huawei LiteOS V100R001C00 + * @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 box parameter must be allocated by LOS_MemboxAlloc.
  • + *
+ * + * @param pool [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. + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MemboxFree(VOID *pBoxMem, VOID *pBox); +extern VOID LOS_MemboxClr(VOID *pool, 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 pPool parameter must be initialized via func LOS_MemboxInit.
  • - *
  • The input pBox parameter must be allocated by LOS_MemboxAlloc.
  • - *
- * - *@param pBoxMem [IN] Memory pool address. - *@param pBox [IN] Memory block address. - * - *@retval VOID - *@par Dependency: - *
    - *
  • los_membox.h: the header file that contains the API declaration.
  • - *
- *@see None. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_membox + * @brief show membox info. + * + * @par Description: + *
    + *
  • This API is used to show the memory pool info.
  • + *
+ * @attention + *
    + *
  • The input pool parameter must be initialized via func LOS_MemboxInit.
  • + *
+ * + * @param pool [IN] Memory pool address. + * + * @retval VOID + * @par Dependency: + *
    + *
  • los_membox.h: the header file that contains the API declaration.
  • + *
+ * @see None. + * @since Huawei LiteOS V100R001C00 */ -extern VOID LOS_MemboxClr(VOID *pBoxMem, VOID *pBox); - +extern VOID LOS_ShowBox(VOID *pool); /** - *@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 pBoxMem [IN] Type #VOID* Pointer to the calculate membox. - *@param uwMaxBlk [OUT] Type #UINT32* Record membox max block. - *@param uwBlkCnt [OUT] Type #UINT32* Record membox block count alreay allocated. - *@param uwBlkSize [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MemboxStatisticsGet(VOID *pBoxMem, UINT32 *puwMaxBlk, UINT32 *puwBlkCnt, UINT32 *puwBlkSize); +extern UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize); #ifdef __cplusplus #if __cplusplus } -#endif +#endif /* __cplusplus */ #endif /* __cplusplus */ -#endif +#endif /* _LOS_MEMBOX_H */ diff --git a/kernel/include/los_memcheck.h b/kernel/include/los_memcheck.h index e51e75cae..09efa7261 100644 --- a/kernel/include/los_memcheck.h +++ b/kernel/include/los_memcheck.h @@ -1,113 +1,117 @@ -/*---------------------------------------------------------------------------- - * Huawei - LiteOS - *---------------------------------------------------------------------------- - * Name: LOS_MEMCHECK.H - * Purpose: Memory check header file - * Rev.: V1.0.0 - *---------------------------------------------------------------------------- - * - - * Copyright (c) 2014, Huawei Technologies Co., Ltd. - * All rights reserved. - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - - *THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - *WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - *MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - *ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - *WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - *ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - *OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - *----------------------------------------------------------------------------*/ -#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_aucMemMang[]; - -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; -}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 uwMemNum [IN] Type #UINT32 Memory pool number. - *@param pstMemExcInfo [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. - *@since Huawei LiteOS V100R001C00 - */ -UINT32 LOS_MemExcInfoGet(UINT32 uwMemNum, MEM_INFO_S *pstMemExcInfo); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#endif /* _LOS_MEMCHECK_H */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2015. All rights reserved. + * Description: LiteOS memory Module Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_MEMCHECK_H +#define _LOS_MEMCHECK_H + +#include "los_base.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +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. + * @since Huawei LiteOS V100R001C00 + */ +UINT32 LOS_MemExcInfoGet(UINT32 memNum, MEM_INFO_S *memExcInfo); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MEMCHECK_H */ diff --git a/kernel/include/los_memory.h b/kernel/include/los_memory.h index 25539da66..6edc61857 100644 --- a/kernel/include/los_memory.h +++ b/kernel/include/los_memory.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2017>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Mem Module HeadFile * 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 @@ -22,22 +22,28 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_memory Dynamic memory + * @ingroup kernel + */ + #ifndef _LOS_MEMORY_H #define _LOS_MEMORY_H + +#include "los_config.h" #include "los_base.h" -#if (LOSCFG_KERNEL_MEM_SLAB == YES) -#include -#endif -#include +#include "los_toolchain.h" +#include "los_membox.h" #ifdef __cplusplus #if __cplusplus @@ -45,182 +51,787 @@ 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; +#ifdef LOSCFG_MEM_LEAKCHECK -#if (LOSCFG_MEMORY_BESTFIT == YES) +/** + * @ingroup los_memory + * The omit layers of function call from call kernel memory interfaces + * such as LOS_MemAlloc/LOS_MemAllocAlign/LOS_MemRealloc/LOS_MemFree. + */ +#define LOS_OMIT_LR_CNT 2 -#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 +/** + * @ingroup los_memory + * The recored layes of function call. + */ +#define LOS_RECORD_LR_CNT 3 #endif +/** + * @ingroup los_memory + * Customized tuning function when allocating memory. + */ typedef VOID (*MALLOC_HOOK)(VOID); - extern MALLOC_HOOK g_MALLOC_HOOK; /** - *@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 pPool parameter must be initialized via func LOS_MemInit.
  • - *
- * - *@param pPool [IN] A pointer pointed to the memory pool. - * - *@retval #LOS_NOK The incoming parameter pPool 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. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * The start address of exc interaction dynamic memory pool address, when the exc + * interaction feature not support, m_aucSysMem0 equals to m_aucSysMem1. */ -extern UINT32 LOS_MemTotalUsedGet(VOID *pPool); +extern UINT8 *m_aucSysMem0; /** - *@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 pPool parameter must be initialized via func LOS_MemInit.
  • - *
- * - *@param pPool [IN] A pointer pointed to the memory pool. - * - *@retval #LOS_NOK The incoming parameter pPool 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. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * The start address of system dynamic memory pool address. */ -extern UINT32 LOS_MemFreeBlksGet(VOID *pPool); +extern UINT8 *m_aucSysMem1; /** - *@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 pPool parameter must be initialized via func LOS_MemInit.
  • - *
- * - *@param pPool [IN] A pointer pointed to the memory pool. - * - *@retval #LOS_NOK The incoming parameter pPool 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. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * The end address of system memory. */ -extern UINT32 LOS_MemUsedBlksGet(VOID *pPool); +extern UINTPTR g_sys_mem_addr_end; /** - *@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 pPtr 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 pPtr [IN] A used memory node. - * - *@retval #OS_INVALID The incoming parameter pPtr is illegal. - *@retval #UINT32 The task ID of used memory node pPtr. - *@par Dependency: - *
  • los_memory.h: the header file that contains the API declaration.
- *@see None. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * The size of exc interaction memory. */ -extern UINT32 LOS_MemTaskIdGet(VOID *pPool); +extern UINTPTR g_excInteractMemSize; /** - *@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 pPool parameter must be initialized via func LOS_MemInit.
  • - *
  • The last node of memory pool is not the end node.
  • - *
- * - *@param pPtr [IN] A pointer pointed to the memory pool. - * - *@retval #LOS_NOK The incoming parameter pPool 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. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * The memory Maximum memory usage statistics. + * @attention + *
  • If running as debug mode, it will affect the performance of memory malloc and free.
  • + *
  • OS_MEM_WATERLINE=YES: open the function for Maximum memory usage statistics
  • + *
  • OS_MEM_WATERLINE=NO: close the function for Maximum memory usage statistics, it set to NO as usual
  • + *
*/ -extern UINT32 LOS_MemLastUsedGet(VOID *pPool); +#ifdef LOSCFG_MEM_WATERLINE +#define OS_MEM_WATERLINE NO +#endif +#ifdef LOSCFG_MEM_MUL_MODULE /** - *@ingroup los_memory - *@brief Check the memory pool Integrity. - * - *@par Description: - *
    - *
  • This API is used to check the memory pool Integrity.
  • - *
- *@attention - *
    - *
  • The input pPool 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.
  • - *
+ * @ingroup los_memory + * The memory usage statistics depend on module, this is the max module no. + */ +#define MEM_MODULE_MAX 0x20 + +/** + * @ingroup los_memory + * @brief Allocate dynamic memory. + * + * @par Description: + *
    + *
  • This API is used to allocate a memory block of which the size is specified and update module mem used.
  • + *
+ * @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). + * @param moduleID [IN] module ID (0~MODULE_MAX). + * + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_MemMalloc(VOID *pool, UINT32 size, UINT32 moduleID); + +/** + * @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 and update module mem used.
  • + *
+ * @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. + * @param moduleID [IN] module ID (0~MODULE_MAX). + * + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_MemMallocAlign(VOID *pool, UINT32 size, UINT32 boundary, UINT32 moduleID); + +/** + * @ingroup los_memory + * @brief Free dynamic memory. + * + * @par Description: + *
  • This API is used to free specified dynamic memory that has been allocated and update module mem used.
  • + * @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 or LOS_MemRealloc.
    • + *
    + * + * @param pool [IN] Pointer to the memory pool that contains the dynamic memory block to be freed. + * @param ptr [IN] Starting address of the memory block to be freed. + * @param moduleID [IN] module ID (0~MODULE_MAX). + * + * @retval #LOS_NOK The memory block fails to be freed because the starting address of the memory block is + * invalid, or the memory overwriting occurs. + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemMfree(VOID *pool, VOID *ptr, UINT32 moduleID); + +/** + * @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. And update module mem used
    • + *
    + * @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 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 boundary 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. + * @param moduleID [IN] module ID (0~MODULE_MAX). + * + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_MemMrealloc(VOID *pool, VOID *ptr, UINT32 size, UINT32 moduleID); + +/** + * @ingroup los_memory + * @brief get special module's mem consume size. * - *@param pPool [IN] A pointer pointed to the memory pool. + * @par Description: + *
  • This API is used to get special module's mem consume size.
  • + * @param moduleID [IN] module ID (0~MODULE_MAX). * - *@retval #LOS_NOK The memory pool (pPool) is impaired. - *@retval #LOS_OK The memory pool (pPool) is integrated. - *@par Dependency: - *
    • los_memory.h: the header file that contains the API declaration.
    - *@see None. - *@since Huawei LiteOS V100R001C00 + * @retval #UINT32 The size of the special module's memory consumed. + * @retval #OS_NULL_INT The illegal module. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemMusedGet(UINT32 moduleID); +#endif + +#ifdef LOSCFG_MEM_MUL_POOL +/** + * @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 #OS_ERROR 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. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemDeInit(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. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemPoolList(VOID); +#endif + +/** + * @ingroup los_memory + * Memory pool extern information structure + */ +typedef struct { + UINT32 uwTotalUsedSize; + UINT32 uwTotalFreeSize; + UINT32 uwMaxFreeNodeSize; + UINT32 uwUsedNodeNum; + UINT32 uwFreeNodeNum; +#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) + UINT32 uwUsageWaterLine; +#endif +} LOS_MEM_POOL_STATUS; + +/** + * @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 #OS_ERROR 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. + * @since Huawei LiteOS V100R001C00 + */ +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 + * @since Huawei LiteOS V100R001C00 + */ +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 ptr 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 ptr [IN] Starting address of the memory block to be freed. + * + * @retval #LOS_NOK The memory block fails to be freed because the starting address of the memory block is + * invalid, or the memory overwriting occurs. + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MemIntegrityCheck(VOID *pPool); +extern UINT32 LOS_MemFree(VOID *pool, VOID *ptr); /** * @ingroup los_memory - * Define a mem size check intensity + * @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 or LOS_MemAllocAlign.
    • + *
    • 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 boundary 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 + * @since Huawei LiteOS V100R001C00 + */ +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 + * @since Huawei LiteOS V100R001C00 + */ +extern VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary); + +/** + * @ingroup los_memory + * @brief Get the size of memory pool's size. + * + * @par Description: + *
      + *
    • This API is used to get the size of memory pool' total size.
    • + *
    + * @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. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemPoolSizeGet(const VOID *pool); + +/** + * @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. + * @since Huawei LiteOS V100R001C00 + */ +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. + * @since Huawei LiteOS V100R001C00 + */ +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. + * @since Huawei LiteOS V100R001C00 + */ +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 ptr [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. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemTaskIdGet(VOID *ptr); + +/** + * @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 #UINTPTR The address of the last used node that casts to UINTPTR. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern UINTPTR LOS_MemLastUsedGet(VOID *pool); + +/** + * @ingroup los_memory + * @brief Get the infomation of memory pool. + * + * @par Description: + *
      + *
    • This API is used to get the infomation of memory pool.
    • + *
    + * @attention + *
      + *
    • The input pool parameter must be initialized via func LOS_MemInit.
    • + *
    + * + * @param pool [IN] A pointer pointed to the memory pool. + * @param poolStatus [IN] A pointer for storage the pool status + * + * @retval #LOS_NOK The incoming parameter pool is NULL or invalid. + * @retval #LOS_OK Success to get memory infomation. + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus); + +/** + * @ingroup los_memory + * @brief Get the number of free node in every size. + * + * @par Description: + *
      + *
    • This API is used to get the number of free node in every size.
    • + *
    + * @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 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. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemFreeNodeShow(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. + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemIntegrityCheck(VOID *pool); + +/** + * @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 #LOS_ERRNO_MEMCHECK_DISABLED Memcheck function does not open. + * @retval #LOS_ERRNO_MEMCHECK_PARA_NULL The pool or ptr is NULL. + * @retval #LOS_ERRNO_MEMCHECK_OUTSIDE The ptr address is not in the reasonable range. + * @retval #LOS_ERRNO_MEMCHECK_NO_HEAD Can't find the control head node from ptr. + * @retval #LOS_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 + * @since Huawei LiteOS V100R001C00 + */ +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 checkLevel [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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemCheckLevelSet(UINT8 checkLevel); + +/** + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT8 LOS_MemCheckLevelGet(VOID); + +#ifdef LOSCFG_KERNEL_MEM_BESTFIT_LITTLE +/** + * @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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_MemGetMaxFreeBlkSize(VOID *pool); +#if defined(LOSCFG_KERNEL_MEM_STATISTICS) && (LOSCFG_KERNEL_MEM_STATISTICS == YES) +/** + * @ingroup los_memory + * @brief Get the memory statistics from Heap. + * + * @par Description: + *
      + *
    • This API is used to dump the information of pool.
    • + *
    + * @attention + *
      + *
    • None.
    • + *
    + * + * @param pool [IN] Pointer to memory pool. + * + * @retval #None + * @par Dependency: + *
    • los_memory.h: the header file that contains the API declaration.
    + * @see None + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_HeapDumpMemoryStats(VOID *pool); +#endif +#endif + +/** + * @ingroup los_memory + * Define a mem size check intensity * - * Lowest mem check. + * Lowest mem check. */ -#define LOS_MEM_CHECK_LEVEL_LOW 0 +#define LOS_MEM_CHECK_LEVEL_LOW 0 /** * @ingroup los_memory @@ -228,7 +839,7 @@ extern UINT32 LOS_MemIntegrityCheck(VOID *pPool); * * Highest mem check. */ -#define LOS_MEM_CHECK_LEVEL_HIGH 1 +#define LOS_MEM_CHECK_LEVEL_HIGH 1 /** * @ingroup los_memory @@ -236,7 +847,7 @@ extern UINT32 LOS_MemIntegrityCheck(VOID *pPool); * * disable mem check. */ -#define LOS_MEM_CHECK_LEVEL_DISABLE 0xff +#define LOS_MEM_CHECK_LEVEL_DISABLE 0xff /** * @ingroup los_memory @@ -244,324 +855,47 @@ extern UINT32 LOS_MemIntegrityCheck(VOID *pPool); * * 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 pPool parameter must be initialized via func LOS_MemInit.
    • - *
    • The input pPtr 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 pPool [IN] A pointer pointed to the memory pool. - *@param pPtr [IN] A pointer pointed to the source node. - *@param puwTotalSize [OUT] A pointer to save total size, must point to valid memory. - *@param puwAvailSize [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 pPtr is NULL. - *@retval #OS_ERRNO_MEMCHECK_OUTSIDE The pPtr address is not in the reasonable range. - *@retval #OS_ERRNO_MEMCHECK_NO_HEAD Can't find the control head node from pPtr. - *@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 (pPtr). - *@par Dependency: - *
    • los_memory.h: the header file that contains the API declaration.
    - *@see LOS_MemCheckLevelSet | LOS_MemCheckLevelGet - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_MemNodeSizeCheck(VOID *pPool, VOID *pPtr, UINT32 *puwTotalSize, UINT32 *puwAvailSize); - -/** - *@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 ucLevel [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_MemCheckLevelSet(UINT8 ucLevel); - -/** - *@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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT8 LOS_MemCheckLevelGet(VOID); -#else +#define LOS_MEM_CHECK_LEVEL_DEFAULT LOS_MEM_CHECK_LEVEL_DISABLE /** - *@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 status [OUT] Type #LOS_MEM_STATUS* Pointer to the heap status structure to be obtained. - *@param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - * - *@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 - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * memcheck error code: the ptr or pool is NULL + * Value: 0x02000101 + * Solution: don't give a NULL parameter */ -extern UINT32 LOS_MemStatisticsGet(VOID *pPool, LOS_MEM_STATUS *pstStatus); +#define LOS_ERRNO_MEMCHECK_PARA_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x1) +/** + * @ingroup los_memory + * memcheck error code: the ptr addr not in the suit range + * Value: 0x02000102 + * Solution: check ptr and comfirm it included by stack + */ +#define LOS_ERRNO_MEMCHECK_OUTSIDE LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x2) /** - *@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 None. - * - *@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 - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * memcheck error code: can't find the ctrl node + * Value: 0x02000103 + * Solution: confirm the ptr if this node has been freed or has not been alloced */ -extern UINT32 LOS_MemGetMaxFreeBlkSize(VOID *pPool); -#endif +#define LOS_ERRNO_MEMCHECK_NO_HEAD LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x3) /** - *@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 uwSize 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 [pPool, pPool + uwSize] should not conflict with other pools.
    • - *
    - * - *@param pPool [IN] Starting address of memory. - *@param uwSize [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. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_MemInit(VOID *pPool, UINT32 uwSize); - -/** - *@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 pPool parameter must be initialized via func LOS_MemInit.
    • - *
    • The size of the input parameter uwSize 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 uwSize must be four byte-aligned.
    • - *
    - * - *@param pPool [IN] Pointer to the memory pool that contains the memory block to be allocated. - *@param uwSize [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 - *@since Huawei LiteOS V100R001C00 - */ -extern VOID *LOS_MemAlloc (VOID *pPool, 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 pPool parameter must be initialized via func LOS_MemInit.
    • - *
    • The input pMem parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign or LOS_MemRealloc.
    • - *
    - * - *@param pPool [IN] Pointer to the memory pool that contains the dynamic memory block to be freed. - *@param pMem [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_MemFree(VOID *pPool, VOID *pMem); - -/** - *@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 pPool parameter must be initialized via func LOS_MemInit.
    • - *
    • The input pPtr parameter must be allocated by LOS_MemAlloc.
    • - *
    • The size of the input parameter uwSize 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 uwSize must be aligned as follows: 1) if the pPtr is allocated by LOS_MemAlloc, it must be four byte-aligned; 2) if the pPtr is allocated by LOS_MemAllocAlign, it must be aligned with the size of the input parameter uwBoundary of LOS_MemAllocAlign.
    • - *
    - * - *@param pPool [IN] Pointer to the memory pool that contains the original and new memory blocks. - *@param pPtr [IN] Address of the original memory block. - *@param uwSize [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 - *@since Huawei LiteOS V100R001C00 - */ -extern VOID *LOS_MemRealloc(VOID *pPool, VOID *pPtr, UINT32 uwSize); - -/** - *@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 pPool parameter must be initialized via func LOS_MemInit.
    • - *
    • The size of the input parameter uwSize 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 pPool [IN] Pointer to the memory pool that contains the memory blocks to be allocated. - *@param uwSize [IN] Size of the memory to be allocated. - *@param uwBoundary [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 - *@since Huawei LiteOS V100R001C00 - */ -extern VOID *LOS_MemAllocAlign (VOID *pPool, UINT32 uwSize, UINT32 uwBoundary); - -#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 pPool [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. - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_MemDeInit(VOID *pPool); - -/** - *@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. - *@since Huawei LiteOS V100R001C00 + * @ingroup los_memory + * memcheck error code: the para level is wrong + * Value: 0x02000104 + * Solution: checkout the memcheck level by the func "OS_GetMemCheck_Level" */ -extern UINT32 LOS_MemPoolList(VOID); -#endif +#define LOS_ERRNO_MEMCHECK_WRONG_LEVEL LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x4) +/** + * @ingroup los_memory + * memcheck error code: memcheck func not open + * Value: 0x02000105 + * Solution: enable memcheck by the func "OS_SetMemCheck_Level" + */ +#define LOS_ERRNO_MEMCHECK_DISABLED LOS_ERRNO_OS_ERROR(LOS_MOD_MEM, 0x5) #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_mpu.h b/kernel/include/los_mpu.h new file mode 100644 index 000000000..25d1f3a29 --- /dev/null +++ b/kernel/include/los_mpu.h @@ -0,0 +1,288 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mpu + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_mpu Mpu + * @ingroup kernel + */ + +#ifndef _LOS_MPU_H +#define _LOS_MPU_H + +#include "los_base.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define MPU_DISABLE 0 +#define MPU_ENABLE 0x7 + +/** + * @ingroup los_mpu + * MPU support number : MPU maximum number of region support(According to the cotex-m4 authority Guide) + */ +#define MPU_MAX_SUPPORT 8 + +/** + * @ingroup los_mpu + * RAM address range : Need to be filled in before setting the protected area + * Can refer to the RAM address range in the icf file + */ +#define MPU_MIN_RAM_ADDRESS 0x20000400 +#define MPU_MAX_RAM_ADDRESS 0x2001FFFF + +/** + * @ingroup los_mpu + * Region size. + */ +#define MPU_REGION_SIZE_32B 0x04 +#define MPU_REGION_SIZE_64B 0x05 +#define MPU_REGION_SIZE_128B 0x06 +#define MPU_REGION_SIZE_256B 0x07 +#define MPU_REGION_SIZE_512B 0x08 +#define MPU_REGION_SIZE_1KB 0x09 +#define MPU_REGION_SIZE_2KB 0x0A +#define MPU_REGION_SIZE_4KB 0x0B +#define MPU_REGION_SIZE_8KB 0x0C +#define MPU_REGION_SIZE_16KB 0x0D +#define MPU_REGION_SIZE_32KB 0x0E +#define MPU_REGION_SIZE_64KB 0x0F +#define MPU_REGION_SIZE_128KB 0x10 +#define MPU_REGION_SIZE_256KB 0x11 +#define MPU_REGION_SIZE_512KB 0x12 +#define MPU_REGION_SIZE_1MB 0x13 +#define MPU_REGION_SIZE_2MB 0x14 +#define MPU_REGION_SIZE_4MB 0x15 +#define MPU_REGION_SIZE_8MB 0x16 +#define MPU_REGION_SIZE_16MB 0x17 +#define MPU_REGION_SIZE_32MB 0x18 +#define MPU_REGION_SIZE_64MB 0x19 +#define MPU_REGION_SIZE_128MB 0x1A +#define MPU_REGION_SIZE_256MB 0x1B +#define MPU_REGION_SIZE_512MB 0x1C +#define MPU_REGION_SIZE_1GB 0x1D +#define MPU_REGION_SIZE_2GB 0x1E +#define MPU_REGION_SIZE_4GB 0x1F + +/** + * @ingroup los_mpu + * Access permission. + */ +#define MPU_DEFS_RASR_AP_NO_ACCESS 0 /* privilege level and user level are prohibited */ +#define MPU_DEFS_RASR_AP_PRIV_RW 1 /* only privilege level can be read and write */ +#define MPU_DEFS_RASR_AP_PRIV_RW_USER_RO 2 /* privilege level read and write, user level read only */ +#define MPU_DEFS_RASR_AP_FULL_ACCESS 3 /* privilege level and user level can be read and write */ +#define MPU_DEFS_RASR_AP_PRIV_RO 5 /* privilege level read only, user level is prohibited */ +#define MPU_DEFS_RASR_AP_RO 6 /* privilege level and user level read only */ + +/** + * @ingroup los_mpu + * region info + * uwBaseAddress must be in the range of RAM + * uwAccessPermission and uwRegionSize are not arbitrary input, selected by the definition of the macro + */ +typedef struct tagRegionInfo { + UINT8 ucNumber; /* number of MPU register to be checked */ + UINT32 uwBaseAddress; /* set the base address of the protected region, + the base address must be in the range of RAM */ + UINT32 uwAccessPermission; /* privilege level and user level access permission */ + BOOL bSharable; /* whether to share */ + BOOL bCachable; /* whether cache */ + BOOL bBuffable; /* whether buffer */ + UINT32 uwRegionSize; /* region size */ + BOOL bHfnmiena; /* Whether in the NMI and hard fault service routine + is not mandatory in addition to MPU */ + BOOL bXN; /* To indicate whether instructions are fetchable in this region, + 0 fetchable; 1: otherwise */ +} MPU_REGION_INFO; + +/** + * @ingroup los_cpup + * MPU error code: The pointer to an input parameter is NULL. + * + * Value: 0x02001200 + * + * Solution: Check whether the pointer to the input parameter is usable. + */ +#define LOS_ERRNO_MPU_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x00) + +/** + * @ingroup los_mpu + * MPU error code: The base address is not aligned to the boundary of the region capacity. + * + * Value: 0x02001201 + * + * Solution: Check base address. + */ +#define LOS_ERRNO_MPU_INVALID_BASE_ADDRESS LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x01) + +/** + * @ingroup los_mpu + * MPU error code: Capacity less than 32 bytes. + * + * Value: 0x02001202 + * + * Solution: Guaranteed that the capacity is greater than or equal to 32 bytes. + */ +#define LOS_ERRNO_MPU_INVALID_CAPACITY LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x02) + +/** + * @ingroup los_mpu + * MPU error code: Chip is not configured MPU. + * + * Value: 0x02001203 + * + * Solution: Make sure the chip is configured with MPU. + */ +#define LOS_ERRNO_MPU_NOT_CONFIGURED LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x03) + +/** + * @ingroup los_mpu + * MPU error code: Invalid number. + * + * Value: 0x02001204 + * + * Solution: Enter a valid number. + */ +#define LOS_ERRNO_MPU_INVALID_NUMBER LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x04) + +/** + * @ingroup los_cpup + * MPU error code: Region has already been enabled. + * + * Value: 0x02001205 + * + * Solution: If you want to re enable the region, please first in addition to the region. + */ +#define LOS_ERRNO_MPU_REGION_IS_ENABLED LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x05) + +/** + * @ingroup los_cpup + * MPU error code: Region has already been disabled. + * + * Value: 0x02001206 + * + * Solution: If you want to re enable the region, please first in addition to the region. + */ +#define LOS_ERRNO_MPU_REGION_IS_DISABLED LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x06) + +/** + * @ingroup los_cpup + * MPU error code: Invalid access. + * + * Value: 0x02001207 + * + * Solution: Checking whether the access is correct. + */ +#define LOS_ERRNO_MPU_REGION_INVALID_ACCESS LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x07) + +/** + * @ingroup los_cpup + * MPU error code: Base address is not in RAM. + * + * Value: 0x02001208 + * + * Solution: Checking base address + */ +#define LOS_ERRNO_MPU_BASE_ADDRESS_NOT_IN_RAM LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x08) + +/** + * @ingroup los_cpup + * MPU error code: According to the current base address, the size of the application is too big. + * + * Value: 0x02001209 + * + * Solution: baseAddress + regionSize must not exceed RAM Max address + */ +#define LOS_ERRNO_MPU_REGION_SIZE_IS_TOO_BIG LOS_ERRNO_OS_ERROR(LOS_MOD_MPU, 0x09) + +/** + * @ingroup los_mpu + * @brief Obtain the set protection region. + * + * @par Description: + * This API is used to set protection region. + * @attention + *
      + *
    • the base address must be in the range of RAM.
    • + *
    + * + * @param mpuInfo [IN] MPU_REGION_INFO. Set the related configuration information for the protected area + * + * @retval #LOS_ERRNO_MPU_TASK_PTR_NULL 0x02001200: The pointer to an input parameter is NULL. + * @retval #LOS_ERRNO_MPU_INVALID_BASE_ADDRESS 0x02001201: The base address is not aligned to the boundary of the + * region capacity. + * @retval #LOS_ERRNO_MPU_INVALID_CAPACITY 0x02001202: Capacity less than 32 bytes. + * @retval #LOS_ERRNO_MPU_NOT_CONFIGURED 0x02001203: Chip is not configured MPU. + * @retval #LOS_ERRNO_MPU_INVALID_NUMBER 0x02001204: Invalid number. + * @retval #LOS_ERRNO_MPU_REGION_IS_ENABLED 0x02001205: Region has already been enabled. + * @retval #LOS_ERRNO_MPU_REGION_IS_DISABLED 0x02001206: Region has already been disabled. + * @par Dependency: + *
    • los_mpu.h: the header file that contains the API declaration.
    + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_SetProtectionRegion(MPU_REGION_INFO *mpuInfo); + +/** + * @ingroup los_mpu + * @brief Obtain the set protection region. + * + * @par Description: + * This API is used to set protection region. + * @attention + *
      + *
    • .
    • + *
    + * + * @param number [IN] UINT8.which region to be selected. + * + * @retval #LOS_ERRNO_MPU_INVALID_NUMBER 0x02001204: Invalid number. + * @retval #LOS_ERRNO_MPU_REGION_IS_DISABLED 0x02001206: Region has already been disabled. + * @par Dependency: + *
    • los_mpu.h: the header file that contains the API declaration.
    + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_RegionDisable(UINT8 number); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MPU_H */ diff --git a/kernel/include/los_mux.h b/kernel/include/los_mux.h index 37ae7664c..fd4de1abc 100644 --- a/kernel/include/los_mux.h +++ b/kernel/include/los_mux.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/** @defgroup los_mux Mutex +/** + * @defgroup los_mux Mutex * @ingroup kernel */ @@ -46,11 +47,10 @@ #ifdef __cplusplus #if __cplusplus -extern "C"{ +extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** * @ingroup los_mux * Mutex error code: The memory request fails. @@ -59,7 +59,7 @@ extern "C"{ * * 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) +#define LOS_ERRNO_MUX_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x00) /** * @ingroup los_mux @@ -69,66 +69,68 @@ extern "C"{ * * 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) +#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: 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: 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. -*/ + * @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. -*/ + * @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. -*/ + * @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 timeout 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). -*/ + * @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) /** @@ -140,13 +142,13 @@ extern "C"{ #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. -*/ + * @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) /** @@ -165,119 +167,130 @@ extern "C"{ */ #define LOS_ERRNO_MUX_REG_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0B) +/** +* @ingroup los_mux +* Mutex error code: The mutex is being locked in system-level task. +* old usage: The mutex is being locked in software timer task. (LOS_ERRNO_MUX_PEND_IN_SWTMR_TSK) +* Value: 0x02001d0C +* +* Solution: Pend the mutex in a vailid task. +*/ +#define LOS_ERRNO_MUX_PEND_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0C) + /** * @ingroup los_mux + * @brief Create a mutex. * - * Mutex error code: LOS_ERRNO_MUX_MAXNUM_ZERO is zero. - * Value: 0x02001d0C + * @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.
    • + *
    * - * 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 puwMuxHandle 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 puwMuxHandle [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 puwMuxHandle 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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MuxCreate(UINT32 *puwMuxHandle); +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 puwMuxHandle [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MuxDelete(UINT32 puwMuxHandle); +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 uwMuxHandle [IN] Handle of the mutex to be waited on. The value of handle should be in [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. - *@param uwTimeout [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 - *@since Huawei LiteOS V100R001C00 + * @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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MuxPend(UINT32 uwMuxHandle, UINT32 uwTimeout); +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 uwMuxHandle [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MuxPost(UINT32 uwMuxHandle); - +extern UINT32 LOS_MuxPost(UINT32 muxHandle); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_printf.h b/kernel/include/los_printf.h new file mode 100644 index 000000000..9771d928f --- /dev/null +++ b/kernel/include/los_printf.h @@ -0,0 +1,202 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Los_printf HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_printf Printf + * @ingroup kernel + */ + +#ifndef _LOS_PRINTF_H +#define _LOS_PRINTF_H + +#include "sys_config.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdarg.h" +#endif +#ifdef LOSCFG_LIB_LIBCMINI +#include "stdarg.h" +#endif +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#ifdef LOSCFG_SHELL_LK +extern void LOS_LkPrint(int level, const char *func, int line, const char *fmt, ...); +#endif + +#define LOS_EMG_LEVEL 0 + +#define LOS_COMMOM_LEVEL (LOS_EMG_LEVEL + 1) + +#define LOS_ERR_LEVEL (LOS_COMMOM_LEVEL + 1) + +#define LOS_WARN_LEVEL (LOS_ERR_LEVEL + 1) + +#define LOS_INFO_LEVEL (LOS_WARN_LEVEL + 1) + +#define LOS_DEBUG_LEVEL (LOS_INFO_LEVEL + 1) + +#ifdef LOSCFG_SHELL_LK +#define PRINT_LEVEL LOS_DEBUG_LEVEL +#else +#define PRINT_LEVEL LOS_ERR_LEVEL +#endif + +typedef VOID (*pf_OUTPUT)(const CHAR *fmt, ...); +/** + * @ingroup los_printf + * @brief Format and print data. + * + * @par Description: + * Print argument(s) according to fmt. + * + * @attention + *
      + *
    • None
    • + *
    + * + * @param fmt [IN] Type char* controls the ouput as in C printf. + * + * @retval None + * @par Dependency: + *
    • los_printf.h: the header file that contains the API declaration.
    + * @see printf + * @since Huawei LiteOS V100R001C00 + */ +extern VOID OsDprintf(const char *fmt, ...); + +#define dprintf OsDprintf + +#define diag_printf dprintf + +#ifndef PRINT_DEBUG +#if PRINT_LEVEL < LOS_DEBUG_LEVEL +#define PRINT_DEBUG(fmt, args...) +#else +#ifdef LOSCFG_SHELL_LK +#define PRINT_DEBUG(fmt, args...) LOS_LkPrint(LOS_DEBUG_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#else +#define PRINT_DEBUG(fmt, args...) do { \ + (dprintf("[DEBUG] "), dprintf(fmt, ##args)); \ +} while (0) +#endif +#endif +#endif + +#ifndef PRINT_INFO +#if PRINT_LEVEL < LOS_INFO_LEVEL +#define PRINT_INFO(fmt, args...) +#else +#ifdef LOSCFG_SHELL_LK +#define PRINT_INFO(fmt, args...) LOS_LkPrint(LOS_INFO_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#else +#define PRINT_INFO(fmt, args...) do { \ + (dprintf("[INFO] "), dprintf(fmt, ##args)); \ +} while (0) +#endif +#endif +#endif + +#ifndef PRINT_WARN +#if PRINT_LEVEL < LOS_WARN_LEVEL +#define PRINT_WARN(fmt, args...) +#else +#ifdef LOSCFG_SHELL_LK +#define PRINT_WARN(fmt, args...) LOS_LkPrint(LOS_WARN_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#else +#define PRINT_WARN(fmt, args...) do { \ + (dprintf("[WARN] "), dprintf(fmt, ##args)); \ +} while (0) +#endif +#endif +#endif + +#ifndef PRINT_ERR +#if PRINT_LEVEL < LOS_ERR_LEVEL +#define PRINT_ERR(fmt, args...) +#else +#ifdef LOSCFG_SHELL_LK +#define PRINT_ERR(fmt, args...) LOS_LkPrint(LOS_ERR_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#else +#define PRINT_ERR(fmt, args...) do { \ + (dprintf("[ERR] "), dprintf(fmt, ##args)); \ +} while (0) +#endif +#endif +#endif + +#ifndef PRINTK +#if PRINT_LEVEL < LOS_COMMOM_LEVEL +#define PRINTK(fmt, args...) +#else +#ifdef LOSCFG_SHELL_LK +#define PRINTK(fmt, args...) LOS_LkPrint(LOS_COMMOM_LEVEL, __FUNCTION__, __LINE__, fmt, ##args) +#else +#define PRINTK(fmt, args...) dprintf(fmt, ##args) +#endif +#endif +#endif + +#ifndef PRINT_EMG +#if PRINT_LEVEL < LOS_EMG_LEVEL +#define PRINT_EMG(fmt, args...) +#else +#define PRINT_EMG(fmt, args...) do { \ + (dprintf("[EMG] "), dprintf(fmt, ##args)); \ +} while (0) +#endif +#endif + +#ifndef PRINT_RELEASE +#define PRINT_RELEASE(fmt, args...) dprintf(fmt, ##args) +#endif + +#ifndef PRINT_TRACE +#ifdef DEBUG_TRACE +#define PRINT_TRACE(fmt, args...) do {dprintf("[TRACE] "fmt, ##args);} while (0) +#else +#define PRINT_TRACE(fmt, args...) +#endif +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_PRINTF_H */ diff --git a/kernel/include/los_queue.h b/kernel/include/los_queue.h index ae579c110..5e6c056fc 100644 --- a/kernel/include/los_queue.h +++ b/kernel/include/los_queue.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Queue * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_queue Queue +/** + * @defgroup los_queue Queue * @ingroup kernel */ @@ -48,637 +49,694 @@ 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 too small or too big. + * + * Value: 0x02000610 + * + * Solution: Pass in a correct buffer size between [sizeof(CHAR*), OS_NULL_SHORT - sizeof(UINT32)]. + */ +#define LOS_ERRNO_QUEUE_READSIZE_IS_INVALID 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 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 uwQueueID; /**< Queue ID */ - UINT16 usQueueLen; /**< Queue length */ - UINT16 usQueueSize; /**< Node size */ - UINT16 usQueueHead; /**< Node head */ - UINT16 usQueueTail; /**< Node tail */ - UINT16 usWritableCnt; /**< Count of writable resources */ - UINT16 usReadableCnt; /**< Count of readable resources */ - UINT32 uwWaitReadTask; /**< Resource reading task */ - UINT32 uwWaitWriteTask; /**< Resource writing task */ - UINT32 uwWaitMemTask; /**< Memory task */ + * @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 reading 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 uwQueueID; /**< Queue ID */ + UINT16 usQueueLen; /**< Queue length */ + UINT16 usQueueSize; /**< Node size */ + UINT16 usQueueHead; /**< Node head */ + UINT16 usQueueTail; /**< Node tail */ + UINT16 usWritableCnt; /**< Count of writable resources */ + UINT16 usReadableCnt; /**< Count of readable resources */ + UINT64 uwWaitReadTask; /**< Resource reading task */ + UINT64 uwWaitWriteTask; /**< Resource writing task */ + UINT64 uwWaitMemTask; /**< 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 pcQueueName [IN] Message queue name. Reserved parameter, not used for now. - *@param usLen [IN] Queue length. The value range is [1,0xffff]. - *@param puwQueueID [OUT] ID of the queue control structure that is successfully created. - *@param uwFlags [IN] Queue mode. Reserved parameter, not used for now. - *@param usMaxMsgSize [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, puwQueueID 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 usMaxMsgSize is larger than 0xffff - 4. - *@par Dependency: - *
    • los_queue.h: the header file that contains the API declaration.
    - *@see LOS_QueueDelete - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueCreate(CHAR *pcQueueName, - UINT16 usLen, - UINT32 *puwQueueID, - UINT32 uwFlags, - UINT16 usMaxMsgSize); - -/** - *@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 pBufferAddr. 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.
    • - *
    • pBufferAddr 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 uwTimeOut is a relative time.
    • - *
    - * - *@param uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pBufferAddr [OUT] Starting address that stores the obtained data. The starting address must not be null. - *@param puwBufferSize [IN/OUT] Where to maintain the buffer wantted-size before read, and the real-size after read. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueReadCopy(UINT32 uwQueueID, - VOID *pBufferAddr, - UINT32 *puwBufferSize, - UINT32 uwTimeOut); - -/** - *@ingroup los_queue - *@brief Write data into a queue. - * - *@par Description: - *This API is used to write the data of the size specified by uwBufferSize and stored at the address specified by pBufferAddr 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 uwBufferSize and is stored at the address specified by BufferAddr.
    • - *
    • The argument uwTimeOut is a relative time.
    • - *
    - * - *@param uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pBufferAddr [IN] Starting address that stores the data to be written.The starting address must not be null. - *@param uwBufferSize [IN] Passed-in buffer size. The value range is [1,USHRT_MAX - sizeof(UINT32)]. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueWriteCopy(UINT32 uwQueueID, - VOID *pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut); - -/** - *@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 pBufferAddr. - *@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.
    • - *
    • pBufferAddr 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 uwTimeOut is a relative time.
    • - *
    • The uwBufferSize is not really used in LOS_QueueRead, because the interface is only used to obtain the address of data.
    • - *
    • The buffer which the pBufferAddr pointing to must be greater than or equal to 4 bytes.
    • - *
    - * - *@param uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pBufferAddr [OUT] Starting address that stores the obtained data. The starting address must not be null. - *@param uwBufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueRead(UINT32 uwQueueID, - VOID *pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut); - -/** - *@ingroup los_queue - *@brief Write data into a queue. - * - *@par Description: - *This API is used to write the address of data specified by pBufferAddr 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 uwBufferSize and stored at the address specified by BufferAddr is to be written.
    • - *
    • The argument uwTimeOut is a relative time.
    • - *
    • The uwBufferSize is not really used in LOS_QueueWrite, because the interface is only used to write the address of data specified by pBufferAddr into a queue.
    • - *
    - * - *@param uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pBufferAddr [IN] Starting address that stores the data to be written. The starting address must not be null. - *@param uwBufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueWrite(UINT32 uwQueueID, - VOID *pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut); - -/** - *@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 uwBufferSize and stored at the address specified by pBufferAddr 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 uwBufferSize and stored at the address specified by BufferAddr is to be written.
    • - *
    • The argument uwTimeOut 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 uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pBufferAddr [OUT] Starting address that stores the data to be written. The starting address must not be null. - *@param uwBufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueWriteHead(UINT32 uwQueueID, - VOID *pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut); - -/** - *@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 uwBufferSize and stored at the address specified by pBufferAddr 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 uwBufferSize and stored at the address specified by BufferAddr is to be written.
    • - *
    • The argument uwTimeOut 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 uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pBufferAddr [OUT] Starting address that stores the data to be written. The starting address must not be null. - *@param uwBufferSize [IN] Passed-in buffer size, which must not be 0. The value range is [1,0xffffffff]. - *@param uwTimeOut [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueWriteHeadCopy(UINT32 uwQueueID, - VOID * pBufferAddr, - UINT32 uwBufferSize, - UINT32 uwTimeOut ); - - - /** - *@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 uwQueueID [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueDelete(UINT32 uwQueueID); - -/** - *@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 uwQueueID [IN] Queue ID created by LOS_QueueCreate. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT]. - *@param pstQueueInfo [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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_QueueInfoGet(UINT32 uwQueueID, QUEUE_INFO_S *pstQueueInfo); + * @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 usMaxMsgSize is larger than 0xffff - 4. + * @par Dependency: + *
    • los_queue.h: the header file that contains the API declaration.
    + * @see LOS_QueueDelete + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_QueueCreate(const 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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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 wanted-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_IS_INVALID The buffer size passed in during queue reading is invalid. + * @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 + * @since Huawei LiteOS V100R001C00 + */ +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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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 + * @since Huawei LiteOS V100R001C00 + */ +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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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,The value range is + * [sizeof(CHAR*),OS_NULL_SHORT - sizeof(UINT32)]. + * @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_IS_INVALID The buffer size passed in during queue reading is invalid. + * @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 + * @since Huawei LiteOS V100R001C00 + */ +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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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] This parameter is not in use temporarily. + * @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 + * @since Huawei LiteOS V100R001C00 + */ +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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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] This parameter is not in use temporarily. + * @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. 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 + * @since Huawei LiteOS V100R001C00 + */ +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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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 + * @since Huawei LiteOS V100R001C00 + */ +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 + * @since Huawei LiteOS V100R001C00 + */ +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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_runstop.h b/kernel/include/los_runstop.h new file mode 100644 index 000000000..da6f49174 --- /dev/null +++ b/kernel/include/los_runstop.h @@ -0,0 +1,179 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Runstop HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_runstop Wifi wake-up + * @ingroup kernel + */ + +#ifndef _LOS_RUNSTOP_H +#define _LOS_RUNSTOP_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_runstop + * @brief Define the type of a runstop callback function. + * + * @par Description: + * This API is used to define the type of a runstop callback function, + * so that it can be called in the phase of wifi wake-up. + * + * @attention + *
      + *
    • None.
    • + *
    + * + * @param None. + * + * @retval None. + * @par Dependency: + *
    • los_runstop.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +typedef VOID (*RUNSTOP_CALLBACK_FUNC)(VOID); + +/** + * @ingroup los_runstop + * @brief Define the type of a flash-reading function. + * + * @par Description: + * This API is used to define the type of a flash-reading function, + * so that it can be called to read data from a certain flash. + * + * @attention + *
      + *
    • None.
    • + *
    + * + * @param memAddr [IN] The memory starting address where to write the data reading from a certain flash. + * @param start [IN] The starting address to read data from a certain flash. + * @param size [IN] The size of data reading from a certain flash. + * + * @retval #INT32 The size of data read from flash. + * @par Dependency: + *
    • los_runstop.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +typedef INT32 (*FLASH_READ_FUNC)(VOID *memAddr, size_t start, size_t size); + +/** + * @ingroup los_runstop + * @brief Define the type of a flash-writing function. + * + * @par Description: + * This API is used to define the type of a flash-writing function, + * so that it can be called to write data from a certain flash. + * + * @attention + *
      + *
    • None.
    • + *
    + * + * @param memAddr [IN] The memory starting address where to read data and be wrote to a certain flash. + * @param start [IN] The starting address of a certain flash to write data. + * @param size [IN] The size of data writing to a certain flash. + * + * @retval #INT32 The size of data write to flash. + * @par Dependency: + *
    • los_runstop.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +typedef INT32 (*FLASH_WRITE_FUNC)(VOID *memAddr, size_t start, size_t size); + +/** + * @ingroup los_runstop + * Define the structure of the parameters used for runstop. + * + * Information of specified parameters passed in during runstop. + */ +typedef struct tagRunstopParam { + RUNSTOP_CALLBACK_FUNC pfIdleWakeupCallback; /**< Wake up callback function, called in idle task just after wake up + from runstop wifi memory mirroring */ + RUNSTOP_CALLBACK_FUNC pfWakeupCallback; /**< Wake up callback function, called just after wake up from runstop + wifi memory mirroring */ + RUNSTOP_CALLBACK_FUNC pfImageDoneCallback; /**< Image done callback function, called just after wifi memory + mirroring is stored */ + FLASH_READ_FUNC pfFlashReadFunc; /**< An abstract function for reading data from a certain flash */ + FLASH_WRITE_FUNC pfFlashWriteFunc; /**< An abstract function for writing data to a certain flash */ + size_t uwFlashReadAlignSize; /**< Block align size when reading data from a certain flash */ + size_t uwFlashEraseAlignSize; /**< Block align size when erasing data in a certain flash */ + size_t uwFlashWriteAlignSize; /**< Block align size when writing data to a certain flash */ + UINTPTR uwWowFlashAddr; /**< The flash starting address to which the wifi memory mirroring + is to be stored, the address should be flash write-alignment + length aligned */ + UINTPTR uwImageFlashAddr; /**< The flash starting address where the whole application image + is burned */ +} RUNSTOP_PARAM_S; + +/** + * @ingroup los_runstop + * @brief Store the wifi memory mirroring on a flash. + * + * @par Description: + * This API is used to store the wifi memory mirroring to the flash starting address passed in by a user. + * @attention + *
      + *
    • uwWowFlashAddr in runstopParam specifies the flash starting address to which the wifi memory mirroring + * is to be stored.It needs to be ensured that the flash starting address and the flash of the wifi memory + * mirroring size after the starting address are not occupied.
    • + *
    + * + * @param runstopParam [IN] Parameter which contains key information for runstop to use, including flash starting + * address to which the wifi memory mirroring is to be stored, etc. + * + * @retval None. + * @par Dependency: + *
    • los_runstop.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_MakeImage(RUNSTOP_PARAM_S *runstopParam); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_RUNSTOP_H */ diff --git a/kernel/include/los_scatter.h b/kernel/include/los_scatter.h new file mode 100644 index 000000000..82b70dbb1 --- /dev/null +++ b/kernel/include/los_scatter.h @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Scatter HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_scatter Scatter + * @ingroup kernel + */ + +#ifndef _LOS_SCATTER_H +#define _LOS_SCATTER_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_scatter + * Configuration item for scatter-loading time printing + * + * The scatter-loading time printing is disabled by default. + */ +#ifndef SCATTER_LOADTIME_PRINT +#define SCATTER_LOADTIME_PRINT 0 +#endif + +/** + * @ingroup los_scatter + * @brief Define the type of a flash-reading function. + * + * @par Description: + * This API is used to define the type of a flash-reading function, so that it can be called to read data from a + * certain flash. + * + * @attention + *
      + *
    • None.
    • + *
    + * + * @param memAddr [IN] The memory starting address where to write the data reading from a certain flash. + * @param start [IN] The starting address to read data from a certain flash. + * @param size [IN] The size of data reading from a certain flash. + * + * @retval #INT32 The size of data read from flash. + * @par Dependency: + *
    • los_scatter.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +typedef INT32 (*SCATTER_FLASH_READ_FUNC)(VOID *memAddr, size_t start, size_t size); + +/** + * @ingroup los_scatter + * @brief Define the type of a scatter-loading hook function. + * + * @par Description: + * This API is used to define the type of a scatter-loading hook function, so that it can be called in the loading phase + * of scatter-loading. + * + * @attention + *
      + *
    • None.
    • + *
    + * + * @param None. + * + * @retval None. + * @par Dependency: + *
    • los_scatter.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +typedef VOID (*SCATTER_ENTRY_FUNC)(VOID); + +/** + * @ingroup los_scatter + * Scatter-loading hook function + * + */ +extern SCATTER_ENTRY_FUNC g_SCATTER_AFTER_FUNC; + +/** + * @ingroup los_scatter + * @brief Scatter-loading function + * + * @par Description: + * This API is used to copy image data of specified size from a specified type of storage medium. + * @attention + *
      + *
    • None.
    • + *
    + * + * @param imageFlashAddr [IN] The flash starting address where the whole application image is burned. + * @param flashReadFunc [IN] An abstract function for reading data from a certain flash. + * @param readAlignSize [IN] Block align size when reading data from a certain flash. + * + * @retval None. + * @par Dependency: + *
    • los_scatter.h: the header file that contains the API declaration.
    + * @see None. + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_ScatterLoad(UINTPTR imageFlashAddr, SCATTER_FLASH_READ_FUNC flashReadFunc, size_t readAlignSize); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_SCATTER_H */ diff --git a/kernel/include/los_sem.h b/kernel/include/los_sem.h index 3e43fbe25..84d76ad7a 100644 --- a/kernel/include/los_sem.h +++ b/kernel/include/los_sem.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Semaphore * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_sem Semaphore +/** + * @defgroup los_sem Semaphore * @ingroup kernel */ @@ -50,7 +51,6 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** * @ingroup los_sem * Semaphore error code: The memory is insufficient. @@ -59,7 +59,7 @@ extern "C" { * * Solution: Allocate more memory. */ -#define LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00) +#define LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00) /** * @ingroup los_sem @@ -69,7 +69,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SEM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x01) /** * @ingroup los_sem @@ -79,7 +79,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SEM_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x02) /** * @ingroup los_sem @@ -89,38 +89,38 @@ extern "C" { * * 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) +#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: 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 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 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 @@ -130,7 +130,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SEM_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x07) /** * @ingroup los_sem @@ -140,7 +140,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SEM_OVERFLOW LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x08) /** * @ingroup los_sem @@ -150,141 +150,166 @@ extern "C" { * * 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) +#define LOS_ERRNO_SEM_PENDED LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x09) + +/** +* @ingroup los_sem +* Semaphore error code: The API is called in system-level callback, which is forbidden. +* old usage: The API is called in software timer callback, which is forbidden. (LOS_ERRNO_SEM_PEND_SWTERR) +* Value: 0x0200070A +* +* Solution: Do not call the API during an interrupt. +*/ +#define LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x0A) /** * @ingroup los_sem - * Semaphore error code: LOS_ERRNO_SEM_MAXNUM_ZERO is error. - * - * Value: 0x0200070A + * Maximum number of semaphores. * - * Solution: LOS_ERRNO_SEM_MAXNUM_ZERO should not be error. */ -#define LOS_ERRNO_SEM_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x0A) +#define OS_SEM_COUNT_MAX 0xFFFE /** - *@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 usCount and return the ID of this semaphore control structure. - *@attention - *
      - *
    • None.
    • - *
    - * - *@param usCount [IN] Initial number of available semaphores. The value range is [0, OS_SEM_COUNTING_MAX_COUNT). - *@param puwSemHandle [OUT] ID of the semaphore control structure that is initialized. - * - *@retval #LOS_ERRNO_SEM_PTR_NULL The passed-in puwSemHandle value is NULL. - *@retval #LOS_ERRNO_SEM_OVERFLOW The passed-in usCount 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 - *@since Huawei LiteOS V100R001C00 + * @ingroup los_sem + * Maximum number of binary semaphores. + * */ -extern UINT32 LOS_SemCreate(UINT16 usCount, UINT32 *puwSemHandle); +#define OS_SEM_BINARY_COUNT_MAX 1 /** - *@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 usCount and return the ID of this semaphore control structure. - *@attention - *
      - *
    • None.
    • - *
    - * - *@param usCount [IN] Initial number of available semaphores. The value range is [0, 1]. - *@param puwSemHandle [OUT] ID of the semaphore control structure that is initialized. - * - *@retval #LOS_ERRNO_SEM_PTR_NULL The passed-in puwSemHandle value is NULL. - *@retval #LOS_ERRNO_SEM_OVERFLOW The passed-in usCount 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 - *@since Huawei LiteOS V100R001C00 + * @ingroup los_sem + * @brief Create a 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_COUNT_MAX). + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_BinarySemCreate (UINT16 usCount, UINT32 *puwSemHandle); +extern UINT32 LOS_SemCreate(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 uwSemHandle. - *@attention - *
      - *
    • The specified sem id must be created first.
    • - *
    - * - *@param uwSemHandle [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 uwSemHandle 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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SemDelete(UINT32 uwSemHandle); +extern UINT32 LOS_BinarySemCreate(UINT16 count, 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 uwSemHandle and the parameter that specifies the timeout period. - *@attention - *
      - *
    • The specified sem id must be created first.
    • - *
    - * - *@param uwSemHandle [IN] ID of the semaphore control structure to be requested. The ID of the semaphore control structure is obtained from semaphore creation. - *@param uwTimeout [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 uwSemHandle 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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SemPend(UINT32 uwSemHandle, UINT32 uwTimeout); +extern UINT32 LOS_SemDelete(UINT32 semHandle); /** - *@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 uwSemHandle. - *@attention - *
      - *
    • The specified sem id must be created first.
    • - *
    - * - *@param uwSemHandle [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 uwSemHandle 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 - *@since Huawei LiteOS V100R001C00 + * @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.
    • + *
    • Do not call this API in software timer callback.
    • + *
    + * + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SemPost(UINT32 uwSemHandle); +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 + * @since Huawei LiteOS V100R001C00 + */ +extern UINT32 LOS_SemPost(UINT32 semHandle); #ifdef __cplusplus #if __cplusplus diff --git a/arch/arm/arm-m/cortex-m7/los_exc.ph b/kernel/include/los_spinlock.h similarity index 57% rename from arch/arm/arm-m/cortex-m7/los_exc.ph rename to kernel/include/los_spinlock.h index 7e39cdd87..eefbfdd83 100644 --- a/arch/arm/arm-m/cortex-m7/los_exc.ph +++ b/kernel/include/los_spinlock.h @@ -1,99 +1,116 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_EXC_PH -#define _LOS_EXC_PH - -#include "los_exc.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ -#if (LOSCFG_PLATFORM_EXC == YES) -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 -} EXC_INFO_TYPE; - -typedef struct tagExcInfoCallBackArray -{ - EXC_INFO_TYPE uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -}EXC_INFO_ARRAY_S; - - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(EXC_INFO_S) - 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(EXC_INFO_TYPE uwType, EXC_INFO_SAVE_CALLBACK pFunc, VOID* pArg); -#endif -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif +/*---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: Spinlock + * 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. + *---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + *---------------------------------------------------------------------------*/ + +#ifndef _LOS_SPINLOCK_H +#define _LOS_SPINLOCK_H +#include "los_typedef.h" +#include "los_config.h" +#include "los_hwi.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID ArchSpinLock(size_t *lock); +extern VOID ArchSpinUnlock(size_t *lock); +extern INT32 ArchSpinTrylock(size_t *lock); + +typedef struct Spinlock { + size_t rawLock; +} SPIN_LOCK_S; + +#define LOCKDEP_CHECK_IN(lock) +#define LOCKDEP_RECORD(lock) +#define LOCKDEP_CHECK_OUT(lock) +#define LOCKDEP_CLEAR_LOCKS() +#define SPIN_LOCK_INITIALIZER(lockName) \ +{ \ + .rawLock = 0U, \ +} + +#define SPIN_LOCK_INIT(lock) SPIN_LOCK_S lock = SPIN_LOCK_INITIALIZER(lock) + +/* + * For Non-SMP system, these apis does not handle with spinlocks, + * but for unifying the code of drivers, vendors and etc. + */ +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLock(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock) +{ + (VOID)lock; + return LOS_OK; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave) +{ + (VOID)lock; + *intSave = LOS_IntLock(); +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave) +{ + (VOID)lock; + LOS_IntRestore(intSave); +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock) +{ + (VOID)lock; + return TRUE; +} + +LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinInit(SPIN_LOCK_S *lock) +{ + (VOID)lock; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/kernel/include/los_swtmr.h b/kernel/include/los_swtmr.h index dda1a8eb5..48994d2e2 100644 --- a/kernel/include/los_swtmr.h +++ b/kernel/include/los_swtmr.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* --------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Software Timer Manager HeadFile * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/** @defgroup los_swtmr Software timer +/** + * @defgroup los_swtmr Software timer * @ingroup kernel */ @@ -41,6 +42,7 @@ #include "los_base.h" #include "los_task.h" +#include "los_sortlink_pri.h" #ifdef __cplusplus #if __cplusplus @@ -48,7 +50,6 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** * @ingroup los_swtmr * Software timer error code: The timeout handling function is NULL. @@ -57,7 +58,7 @@ extern "C" { * * Solution: Define the timeout handling function. */ -#define LOS_ERRNO_SWTMR_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00) +#define LOS_ERRNO_SWTMR_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00) /** * @ingroup los_swtmr @@ -67,7 +68,7 @@ extern "C" { * * Solution: Re-define the expiration time. */ -#define LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x01) +#define LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x01) /** * @ingroup los_swtmr @@ -77,7 +78,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SWTMR_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x02) /** * @ingroup los_swtmr @@ -87,7 +88,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SWTMR_RET_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x03) /** * @ingroup los_swtmr @@ -95,9 +96,10 @@ extern "C" { * * Value: 0x02000304 * - * Solution: Re-configure the permitted maximum number of software timers, or wait for a software timer to become available. + * 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) +#define LOS_ERRNO_SWTMR_MAXSIZE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x04) /** * @ingroup los_swtmr @@ -107,7 +109,7 @@ extern "C" { * * Solution: Pass in a valid software timer ID. */ -#define LOS_ERRNO_SWTMR_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x05) +#define LOS_ERRNO_SWTMR_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x05) /** * @ingroup los_swtmr @@ -117,7 +119,7 @@ extern "C" { * * Solution: Create a software timer. */ -#define LOS_ERRNO_SWTMR_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x06) +#define LOS_ERRNO_SWTMR_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x06) /** * @ingroup los_swtmr @@ -127,7 +129,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SWTMR_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x07) /** * @ingroup los_swtmr @@ -137,7 +139,7 @@ extern "C" { * * Solution: Re-configure the number of software timers. */ -#define LOS_ERRNO_SWTMR_MAXSIZE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x08) +#define LOS_ERRNO_SWTMR_MAXSIZE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x08) /** * @ingroup los_swtmr @@ -147,7 +149,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SWTMR_HWI_ACTIVE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x09) /** * @ingroup los_swtmr @@ -157,7 +159,7 @@ extern "C" { * * Solution: Expand the memory allocated by membox. */ -#define LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0a) +#define LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0a) /** * @ingroup los_swtmr @@ -167,7 +169,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0b) /** * @ingroup los_swtmr @@ -177,7 +179,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_SWTMR_TASK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0c) /** * @ingroup los_swtmr @@ -187,7 +189,7 @@ extern "C" { * * Solution: Start the software timer. */ -#define LOS_ERRNO_SWTMR_NOT_STARTED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0d) +#define LOS_ERRNO_SWTMR_NOT_STARTED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0d) /** * @ingroup los_swtmr @@ -197,13 +199,13 @@ extern "C" { * * Solution: Check the software timer state. */ -#define LOS_ERRNO_SWTMR_STATUS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0e) +#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) +#define LOS_ERRNO_SWTMR_SORTLIST_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0f) /** * @ingroup los_swtmr @@ -213,52 +215,29 @@ extern "C" { * * 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) - -#define OS_SWTMR_BIT_ALREADY_ALIGNED (1 << 31) -#define OS_SWTMR_BIT_CAN_ALIGNED (1 << 30) -#define OS_SWTMR_BIT_MULTIPLE (1 << 29) - -#define SET_ALIGN_SWTMR_ALREADY_ALIGNED(num) ((num) = 0x80000000 | ((num) & 0x7FFFFFFF)) -#define SET_ALIGN_SWTMR_ALREADY_NOT_ALIGNED(num) ((num) = ((num) & 0x7FFFFFFF)) -#define SET_ALIGN_SWTMR_CAN_ALIGNED(num) ((num) = 0x40000000| (num & 0xBFFFFFFF)) -#define SET_ALIGN_SWTMR_CAN_NOT_ALIGNED(num) ((num) = (num & 0xBFFFFFFF)) -#define SET_ALIGN_SWTMR_CAN_MULTIPLE(num) ((num)= 0x20000000|(num & 0xDFFFFFFF) ) -#define SET_ALIGN_SWTMR_CAN_NOT_MULTIPLE(num) ((num)= (num & 0xDFFFFFFF) ) -#define SET_ALIGN_SWTMR_DIVISOR_TIMERS(num, value) (num = (value & 0x00FFFFFF) | (num & 0xFF000000))//bit23:0 -#define GET_ALIGN_SWTMR_DIVISOR_TIMERS(num) (num & 0x00FFFFFF) - -#define CHECK_ALIGN_SWTMR_CAN_MULTI_ALIGN(num) ((num & 0xE0000000) == 0x60000000) -#define CHECK_ALIGN_SWTMR_CAN_PERIODIC_ALIGN(num) ((num & 0xE0000000) == 0x40000000) -#define CHECK_ALIGN_SWTMR_ALREADY_ALIGN(num) ((num & 0xC0000000) == 0xC0000000) - -enum enSwTmrRousesType -{ - OS_SWTMR_ROUSES_IGNORE, /* timer don't need to wake up system */ - OS_SWTMR_ROUSES_ALLOW, /* timer can wake up system */ -}; +#define LOS_ERRNO_SWTMR_TICK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x10) -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 error code: The software sortlink fails to be created. + * + * Value: 0x02000311 + * + * Solution: Check whether the memory is sufficient and re-create the sortlink. + */ +#define LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x11) /** * @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.*/ +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. */ }; /** @@ -266,14 +245,15 @@ enum enSwTmrType * @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. +* 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 uwPar [IN] the parameter of the callback function that handles software timer timeout. +* @param arg [IN] the parameter of the callback function that handles software timer timeout. * * @retval None. * @par Dependency: @@ -281,163 +261,165 @@ enum enSwTmrType * @see None. * @since Huawei LiteOS V100R001C00 */ -typedef VOID (*SWTMR_PROC_FUNC)(UINT32 uwPar); +typedef VOID (*SWTMR_PROC_FUNC)(UINTPTR arg); /** * @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 */ +typedef struct tagSwTmrCtrl { + SortLinkList stSortList; + UINT8 ucState; /**< Software timer state */ + UINT8 ucMode; /**< Software timer mode */ + UINT8 ucOverrun; /**< Times that a software timer repeats timing */ + UINT16 usTimerID; /**< Software timer ID */ + UINT32 uwCount; /**< Times that a software timer works */ + UINT32 uwInterval; /**< Timeout interval of a periodic software timer */ + UINT32 uwExpiry; /**< Timeout interval of an one-off software timer */ + UINTPTR 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 usSwTmrID [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SwtmrStart(UINT16 usSwTmrID); +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 usSwTmrID [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SwtmrStop(UINT16 usSwTmrID); +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 usSwTmrID [IN] Software timer ID created by LOS_SwtmrCreate. The value of ID should be in [0, LOSCFG_BASE_CORE_SWTMR_LIMIT - 1]. - *@param uwTick [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SwtmrTimeGet(UINT16 usSwTmrID, UINT32 *uwTick); +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 uwInterval [IN] Timing duration of the software timer to be created (unit: ms). - *@param ucMode [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 pfnHandler [IN] Callback function that handles software timer timeout. - *@param pusSwTmrID [OUT] Software timer ID created by LOS_SwtmrCreate. - *@param uwArg [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 - *@since Huawei LiteOS V100R001C00 + * @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: tick). + * @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 + * @since Huawei LiteOS V100R001C00 */ - extern UINT32 LOS_SwtmrCreate(UINT32 uwInterval, UINT8 ucMode, SWTMR_PROC_FUNC pfnHandler, UINT16 *pusSwTmrID, UINT32 uwArg - #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - , UINT8 ucRouses, UINT8 ucSensitive - #endif - ); +extern UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT16 *swtmrID, UINTPTR arg); /** - *@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 usSwTmrID [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_SwtmrDelete(UINT16 usSwTmrID); - +extern UINT32 LOS_SwtmrDelete(UINT16 swtmrID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_sys.h b/kernel/include/los_sys.h index 64e91f252..65abe2540 100644 --- a/kernel/include/los_sys.h +++ b/kernel/include/los_sys.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System time HeadFile * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_sys System time +/** + * @defgroup los_sys System time * @ingroup kernel */ @@ -41,6 +42,7 @@ #include "los_base.h" #include "los_hwi.h" +#include "los_hw.h" #ifdef __cplusplus #if __cplusplus @@ -48,155 +50,155 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - /** - *@ingroup los_sys - *System time basic function error code: Null pointer. + * @ingroup los_sys + * System time basic function error code: Null pointer. * - *Value: 0x02000010 + * Value: 0x02000010 * - *Solution: Check whether the input parameter is null. + * Solution: Check whether the input parameter is null. */ -#define LOS_ERRNO_SYS_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x10) +#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. + * @ingroup los_sys + * System time basic function error code: Invalid system clock configuration. * - *Value: 0x02000011 + * Value: 0x02000011 * - *Solution: Configure a valid system clock in los_config.h. + * Solution: Configure a valid system clock in los_config.h. */ -#define LOS_ERRNO_SYS_CLOCK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x11) +#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. + * @ingroup los_sys + * System time basic function error code: This error code is not in use temporarily. * - *Value: 0x02000012 + * Value: 0x02000012 * - *Solution: None. + * Solution: None. */ -#define LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x12) +#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. + * @ingroup los_sys + * System time error code: This error code is not in use temporarily. * - *Value: 0x02000013 + * Value: 0x02000013 * - *Solution: None. + * Solution: None. */ -#define LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x13) +#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. + * @ingroup los_sys + * System time error code: This error code is not in use temporarily. * - *Value: 0x02000014 + * Value: 0x02000014 * - *Solution: None. + * Solution: None. */ -#define LOS_ERRNO_SYS_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x14) +#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 */ +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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT64 LOS_TickCountGet (VOID); +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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ 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 uwTick [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 - *@since Huawei LiteOS V100R001C00 + * @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 tick [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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_Tick2MS(UINT32 uwTick); +extern UINT32 LOS_Tick2MS(UINT32 tick); /** - *@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 uwMillisec [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 - *@since Huawei LiteOS V100R001C00 + * @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 + * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_MS2Tick(UINT32 uwMillisec); +extern UINT32 LOS_MS2Tick(UINT32 millisec); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_tables.h b/kernel/include/los_tables.h new file mode 100644 index 000000000..8d9654088 --- /dev/null +++ b/kernel/include/los_tables.h @@ -0,0 +1,152 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tables + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_TABLES_H +#define _LOS_TABLES_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef LOS_HAL_TABLE_WOW_BEGIN +#define LOS_HAL_TABLE_WOW_BEGIN(label, name) \ + __asm__(".section \".liteos.table." X_STRING(name) ".wow.begin\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_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_STRING(name) ".wow.finish\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_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_STRING(name) ".scatter.begin\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_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_STRING(name) ".scatter.finish\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_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_STRING(name) ".begin\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_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_STRING(name) ".finish\",\"aw\"\n" \ + ".globl " X_STRING(LOS_LABEL_DEFN(label)) "\n" \ + ".type " X_STRING(LOS_LABEL_DEFN(label)) ",object\n" \ + ".p2align " X_STRING(LOSARC_P2ALIGNMENT) "\n" \ + X_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_STRING(name) ".extra") +#endif + +#ifndef LOS_HAL_TABLE_WOW_ENTRY +#define LOS_HAL_TABLE_WOW_ENTRY(name) \ + LOSBLD_ATTRIB_SECTION(".liteos.table." X_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_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_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_STRING(name) ".data." X_STRING(_qual)) \ + LOSBLD_ATTRIB_USED +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TABLES_H */ diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h index 7d5250510..427c5b802 100644 --- a/kernel/include/los_task.h +++ b/kernel/include/los_task.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Task Module Implementation HeadFile * 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 @@ -22,17 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_task Task +/** + * @defgroup los_task Task * @ingroup kernel */ @@ -42,9 +43,9 @@ #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_memory.h" #include "los_err.h" #ifdef __cplusplus @@ -53,6 +54,16 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +#define CPUID_TO_AFFI_MASK(cpuid) (0x1u << (cpuid)) + +/** + * @ingroup los_task + * Flag that indicates the task or task control block status. + * + * The task is automatically deleted. + */ +#define LOS_TASK_STATUS_DETACHED 0x0100U + /** * @ingroup los_task * Task error code: Insufficient memory for task creation. @@ -61,7 +72,7 @@ extern "C" { * * Solution: Allocate bigger memory partition to task creation. */ -#define LOS_ERRNO_TSK_NO_MEMORY LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x00) +#define LOS_ERRNO_TSK_NO_MEMORY LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x00) /** * @ingroup los_task @@ -71,7 +82,7 @@ extern "C" { * * Solution: Check the parameter. */ -#define LOS_ERRNO_TSK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x01) +#define LOS_ERRNO_TSK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x01) /** * @ingroup los_task @@ -81,7 +92,7 @@ extern "C" { * * Solution: Align the task stack. */ -#define LOS_ERRNO_TSK_STKSZ_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x02) +#define LOS_ERRNO_TSK_STKSZ_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x02) /** * @ingroup los_task @@ -91,7 +102,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_TSK_PRIOR_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x03) /** * @ingroup los_task @@ -101,7 +112,7 @@ extern "C" { * * Solution: Define the task entrance function. */ -#define LOS_ERRNO_TSK_ENTRY_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x04) +#define LOS_ERRNO_TSK_ENTRY_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x04) /** * @ingroup los_task @@ -111,7 +122,7 @@ extern "C" { * * Solution: Set the task name. */ -#define LOS_ERRNO_TSK_NAME_EMPTY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x05) +#define LOS_ERRNO_TSK_NAME_EMPTY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x05) /** * @ingroup los_task @@ -121,7 +132,7 @@ extern "C" { * * Solution: Expand the task stack. */ -#define LOS_ERRNO_TSK_STKSZ_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x06) +#define LOS_ERRNO_TSK_STKSZ_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x06) /** * @ingroup los_task @@ -131,7 +142,7 @@ extern "C" { * * Solution: Check the task ID. */ -#define LOS_ERRNO_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x07) +#define LOS_ERRNO_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x07) /** * @ingroup los_task @@ -141,7 +152,7 @@ extern "C" { * * Solution: Suspend the task after it is resumed. */ -#define LOS_ERRNO_TSK_ALREADY_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x08) +#define LOS_ERRNO_TSK_ALREADY_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x08) /** * @ingroup los_task @@ -151,7 +162,7 @@ extern "C" { * * Solution: Suspend the task. */ -#define LOS_ERRNO_TSK_NOT_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x09) +#define LOS_ERRNO_TSK_NOT_SUSPENDED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x09) /** * @ingroup los_task @@ -161,7 +172,17 @@ extern "C" { * * Solution: Create the task. */ -#define LOS_ERRNO_TSK_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0a) +#define LOS_ERRNO_TSK_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0a) + +/** + * @ingroup los_task + * Task error code: The task is locked when it is being deleted. + * + * Value: 0x0300020b + * + * Solution: Unlock the task. + */ +#define LOS_ERRNO_TSK_DELETE_LOCKED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x0b) /** * @ingroup los_task @@ -171,7 +192,7 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_MSG_NONZERO LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0c) +#define LOS_ERRNO_TSK_MSG_NONZERO LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0c) /** * @ingroup los_task @@ -181,7 +202,7 @@ extern "C" { * * Solution: Perform this operation after exiting from the interrupt. */ -#define LOS_ERRNO_TSK_DELAY_IN_INT LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x0d) +#define LOS_ERRNO_TSK_DELAY_IN_INT LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x0d) /** * @ingroup los_task @@ -191,17 +212,16 @@ extern "C" { * * Solution: Perform this operation after unlocking the task. */ -#define LOS_ERRNO_TSK_DELAY_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0e) +#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. - * + * Task error code: The task yeild occurs when the task is locked. * Value: 0x0200020f * * Solution: Check the task. */ -#define LOS_ERRNO_TSK_YIELD_INVALID_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0f) +#define LOS_ERRNO_TSK_YIELD_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x0f) /** * @ingroup los_task @@ -211,7 +231,7 @@ extern "C" { * * Solution: Increase the number of tasks. */ -#define LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x10) +#define LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x10) /** * @ingroup los_task @@ -221,7 +241,7 @@ extern "C" { * * Solution: Increase the number of task control blocks. */ -#define LOS_ERRNO_TSK_TCB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x11) +#define LOS_ERRNO_TSK_TCB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x11) /** * @ingroup los_task @@ -231,7 +251,7 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_HOOK_NOT_MATCH LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x12) +#define LOS_ERRNO_TSK_HOOK_NOT_MATCH LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x12) /** * @ingroup los_task @@ -241,17 +261,18 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x13) +#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. + * Task error code: The operation is performed on the system-level task. + * old usage: The operation is performed on the idle task (LOS_ERRNO_TSK_OPERATE_IDLE) * * Value: 0x02000214 * - * Solution: Check the task ID and do not operate on the idle task. + * Solution: Check the task ID and do not operate on the system-level task. */ -#define LOS_ERRNO_TSK_OPERATE_IDLE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x14) +#define LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x14) /** * @ingroup los_task @@ -261,7 +282,7 @@ extern "C" { * * Solution: Suspend the task after unlocking the task. */ -#define LOS_ERRNO_TSK_SUSPEND_LOCKED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x15) +#define LOS_ERRNO_TSK_SUSPEND_LOCKED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x15) /** * @ingroup los_task @@ -271,7 +292,7 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_FREE_STACK_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x17) +#define LOS_ERRNO_TSK_FREE_STACK_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x17) /** * @ingroup los_task @@ -281,7 +302,7 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_STKAREA_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x18) +#define LOS_ERRNO_TSK_STKAREA_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x18) /** * @ingroup los_task @@ -291,7 +312,7 @@ extern "C" { * * Solution: Perform task switching after creating an idle task. */ -#define LOS_ERRNO_TSK_ACTIVE_FAILED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x19) +#define LOS_ERRNO_TSK_ACTIVE_FAILED LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x19) /** * @ingroup los_task @@ -301,7 +322,7 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_CONFIG_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1a) +#define LOS_ERRNO_TSK_CONFIG_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1a) /** * @ingroup los_task @@ -311,7 +332,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_TSK_CP_SAVE_AREA_NOT_ALIGN LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1b) /** * @ingroup los_task @@ -321,7 +342,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_TSK_MSG_Q_TOO_MANY LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1d) /** * @ingroup los_task @@ -331,7 +352,7 @@ extern "C" { * * 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) +#define LOS_ERRNO_TSK_CP_SAVE_AREA_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1e) /** * @ingroup los_task @@ -341,7 +362,7 @@ extern "C" { * * Solution: This error code is not in use temporarily. */ -#define LOS_ERRNO_TSK_SELF_DELETE_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1f) +#define LOS_ERRNO_TSK_SELF_DELETE_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x1f) /** * @ingroup los_task @@ -351,7 +372,7 @@ extern "C" { * * Solution: shrink the task stack size parameter. */ -#define LOS_ERRNO_TSK_STKSZ_TOO_LARGE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x20) +#define LOS_ERRNO_TSK_STKSZ_TOO_LARGE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x20) /** * @ingroup los_task @@ -361,18 +382,59 @@ extern "C" { * * 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) +#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. + * Task error code: The task delay occurs in software timer task. * - * Value: 0x02000222 + * Value: 0x03000222 * - * Solution: Check the task ID and do not operate on the software timer task. + * Solution: Don't call Los_TaskDelay in software timer callback. */ -#define LOS_ERRNO_TSK_OPERATE_SWTMR LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x22) +#define LOS_ERRNO_TSK_DELAY_IN_SWTMR_TSK LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x22) + +/** + * @ingroup los_task + * Task error code: The cpu affinity mask is incorrect. + * + * Value: 0x03000223 + * + * Solution: Please set the correct cpu affinity mask. + */ +#define LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR LOS_ERRNO_OS_FATAL(LOS_MOD_TSK, 0x23) + +/** + * @ingroup los_task + * Task error code: Task yeild in int is not permited, which will result in unexpected result. + * + * Value: 0x02000224 + * + * Solution: Don't call LOS_TaskYield in Interrupt. + */ +#define LOS_ERRNO_TSK_YIELD_IN_INT LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x24) + +/** +* @ingroup los_task +* Task error code: Task sync resource (semaphore) allocated failed. +* +* Value: 0x02000225 +* +* Solution: Expand LOSCFG_BASE_IPC_SEM_LIMIT. +*/ +#define LOS_ERRNO_TSK_MP_SYNC_RESOURCE LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x25) + +/** +* @ingroup los_task +* Task error code: Task sync failed on operating running task across cores. +* +* Value: 0x02000226 +* +* Solution: Check task delete can be handled in user's scenario. +*/ +#define LOS_ERRNO_TSK_MP_SYNC_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_TSK, 0x26) +#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) /** * @ingroup los_task * Define the type of the task switching hook function. @@ -386,6 +448,7 @@ typedef VOID (*TSKSWITCHHOOK)(VOID); * */ extern TSKSWITCHHOOK g_pfnUsrTskSwitchHook; +#endif /** * @ingroup los_task @@ -395,10 +458,10 @@ extern TSKSWITCHHOOK g_pfnUsrTskSwitchHook; * This API is used to define the type of a task entrance function and call it after a task is created and triggered. * @attention None. * -* @param uwParam1 [IN] Type #UINT32 The first parameter passed to the task handling function. -* @param uwParam2 [IN] Type #UINT32 The second parameter passed to the task handling function. -* @param uwParam3 [IN] Type #UINT32 The third parameter passed to the task handling function. -* @param uwParam4 [IN] Type #UINT32 The fourth parameter passed to the task handling function. +* @param param1 [IN] Type #UINTPTR The first parameter passed to the task handling function. +* @param param2 [IN] Type #UINTPTR The second parameter passed to the task handling function. +* @param param3 [IN] Type #UINTPTR The third parameter passed to the task handling function. +* @param param4 [IN] Type #UINTPTR The fourth parameter passed to the task handling function. * * @retval None. * @par Dependency: @@ -406,7 +469,10 @@ extern TSKSWITCHHOOK g_pfnUsrTskSwitchHook; * @see * @since Huawei LiteOS V100R001C00 */ -typedef VOID *(*TSK_ENTRY_FUNC)(UINT32 uwArg); +typedef VOID *(*TSK_ENTRY_FUNC)(UINTPTR param1, + UINTPTR param2, + UINTPTR param3, + UINTPTR param4); /** * @ingroup los_task @@ -414,14 +480,14 @@ typedef VOID *(*TSK_ENTRY_FUNC)(UINT32 uwArg); * * 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 */ +typedef struct tagTskInitParam { + TSK_ENTRY_FUNC pfnTaskEntry; /**< Task entrance function */ + UINT16 usTaskPrio; /**< Task priority */ + UINTPTR auwArgs[4]; /**< Task parameters, of which the maximum number is four */ + UINT32 uwStackSize; /**< Task stack size */ + CHAR *pcName; /**< Task name */ + UINT32 uwResved; /**< It is automatically deleted if set to LOS_TASK_STATUS_DETACHED. + It is unable to be deleted if set to 0. */ } TSK_INIT_PARAM_S; /** @@ -429,73 +495,61 @@ typedef struct tagTskInitParam * Task name length * */ -#define LOS_TASK_NAMELEN 32 +#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 */ +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 */ + EVENT_CB_S uwEvent; /**< Event */ + UINT32 uwEventMask; /**< Event mask */ + UINT32 uwStackSize; /**< Task stack size */ + UINTPTR uwTopOfStack; /**< Task stack top */ + UINTPTR uwBottomOfStack; /**< Task stack bottom */ + UINTPTR 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 - * Task switch information structure. - * - */ -#define OS_TASK_SWITCH_INFO_COUNT (0xA) -typedef struct tagTaskSwitchInfo -{ - UINT8 ucIdx; - UINT8 ucIsFull; /* bit [7] store isfull status, bits [6:0] store count of task switch info */ - UINT16 auwPID[OS_TASK_SWITCH_INFO_COUNT]; - CHAR acName[OS_TASK_SWITCH_INFO_COUNT][LOS_TASK_NAMELEN]; -}OS_TASK_SWITCH_INFO; - - /** * @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. + * 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.
    • + *
    • 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.
    • + *
    • 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.
    • + *
    • The two parameters of this interface is pointer, it should be a correct value, otherwise, the system may be + * abnormal.
    • *
    * - * @param puwTaskID [OUT] Type #UINT32 * Task ID. - * @param pstInitParam [IN] Type #TSK_INIT_PARAM_S * Parameter for task creation. + * @param taskID [OUT] Type #UINT32 * Task ID. + * @param initParam [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_ID_INVALID Invalid Task ID, param taskID is NULL. + * @retval #LOS_ERRNO_TSK_PTR_NULL Param initParam 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. @@ -510,33 +564,38 @@ typedef struct tagTaskSwitchInfo * @see LOS_TaskDelete * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskCreateOnly(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam); +extern UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam); /** * @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. + * 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.
    • + *
    • 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.
    • + *
    • 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.
    • + *
    • The two parameters of this interface is pointer, it should be a correct value, otherwise, the system may be + * abnormal.
    • *
    * - * @param puwTaskID [OUT] Type #UINT32 * Task ID. - * @param pstInitParam [IN] Type #TSK_INIT_PARAM_S * Parameter for task creation. + * @param taskID [OUT] Type #UINT32 * Task ID. + * @param initParam [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_ID_INVALID Invalid Task ID, param taskID is NULL. + * @retval #LOS_ERRNO_TSK_PTR_NULL Param initParam 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. @@ -551,7 +610,7 @@ extern UINT32 LOS_TaskCreateOnly(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitPar * @see LOS_TaskDelete * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskCreate(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam); +extern UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam); /** * @ingroup los_task @@ -563,10 +622,11 @@ extern UINT32 LOS_TaskCreate(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam); * @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.
    • + *
    • 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 uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @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. @@ -577,7 +637,7 @@ extern UINT32 LOS_TaskCreate(UINT32 *puwTaskID, TSK_INIT_PARAM_S *pstInitParam); * @see LOS_TaskSuspend * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskResume(UINT32 uwTaskID); +extern UINT32 LOS_TaskResume(UINT32 taskID); /** * @ingroup los_task @@ -592,21 +652,22 @@ extern UINT32 LOS_TaskResume(UINT32 uwTaskID); *
  • The idle task and swtmr task cannot be suspended.
  • * * - * @param uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @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_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 * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskSuspend(UINT32 uwTaskID); +extern UINT32 LOS_TaskSuspend(UINT32 taskID); /** * @ingroup los_task @@ -619,39 +680,46 @@ extern UINT32 LOS_TaskSuspend(UINT32 uwTaskID); *
      *
    • 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.
    • + *
    • 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 uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @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_DELETE_LOCKED The task being deleted is current task and task scheduling + * is locked. * @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 * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskDelete(UINT32 uwTaskID); +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. + * 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.
    • + *
    • 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.
    • + *
    • DO NOT call this API in software timer callback.
    • *
    * - * @param uwTick [IN] Type #UINT32 Number of Ticks for which the task is delayed. + * @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. @@ -663,7 +731,7 @@ extern UINT32 LOS_TaskDelete(UINT32 uwTaskID); * @see * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskDelay(UINT32 uwTick); +extern UINT32 LOS_TaskDelay(UINT32 tick); /** * @ingroup los_task @@ -675,7 +743,8 @@ extern UINT32 LOS_TaskDelay(UINT32 uwTick); * @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.
    • + *
    • 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. @@ -693,11 +762,13 @@ extern VOID LOS_TaskLock(VOID); * @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. + * 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.
    • + *
    • 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. @@ -719,14 +790,15 @@ extern VOID LOS_TaskUnlock(VOID); * * @attention *
      - *
    • If the set priority is higher than the priority of the current running task, task scheduling probably occurs.
    • + *
    • 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 uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. - * @param usTaskPrio [IN] Type #UINT16 Task priority. + * @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. @@ -738,7 +810,7 @@ extern VOID LOS_TaskUnlock(VOID); * @see LOS_TaskPriSet * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskPriSet(UINT32 uwTaskID, UINT16 usTaskPrio); +extern UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio); /** * @ingroup los_task @@ -754,37 +826,41 @@ extern UINT32 LOS_TaskPriSet(UINT32 uwTaskID, UINT16 usTaskPrio); *
  • Using the interface in the interrupt is not allowed.
  • * * - * @param usTaskPrio [IN] Type #UINT16 Task priority. + * @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. + * @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 * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_CurTaskPriSet(UINT16 usTaskPrio); +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. + * 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.
    • + *
    • 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. + * @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 @@ -801,7 +877,7 @@ extern UINT32 LOS_TaskYield(VOID); * * @attention None. * - * @param uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @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. @@ -810,7 +886,7 @@ extern UINT32 LOS_TaskYield(VOID); * @see LOS_TaskPriSet * @since Huawei LiteOS V100R001C00 */ -extern UINT16 LOS_TaskPriGet(UINT32 uwTaskID); +extern UINT16 LOS_TaskPriGet(UINT32 taskID); /** * @ingroup los_task @@ -833,44 +909,6 @@ extern UINT16 LOS_TaskPriGet(UINT32 uwTaskID); */ 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 - * @since Huawei LiteOS V100R001C00 - */ -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 - * @since Huawei LiteOS V100R001C00 - */ -extern CHAR *LOS_CurTaskNameGet(VOID); - /** * @ingroup los_task * @brief Obtain a task information structure. @@ -880,11 +918,12 @@ extern CHAR *LOS_CurTaskNameGet(VOID); * * @attention *
      - *
    • One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may be abnormal.
    • + *
    • One parameter of this interface is a pointer, it should be a correct value, otherwise, the system may be + * abnormal.
    • *
    * - * @param uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. - * @param pstTaskInfo [OUT] Type #TSK_INFO_S* Pointer to the task information structure to be obtained. + * @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. @@ -895,130 +934,55 @@ extern CHAR *LOS_CurTaskNameGet(VOID); * @see * @since Huawei LiteOS V100R001C00 */ -extern UINT32 LOS_TaskInfoGet(UINT32 uwTaskID, TSK_INFO_S *pstTaskInfo); - -/** - * @ingroup los_task - * @brief Obtain the task status. - * - * @par Description: - * This API is used to obtain the task status. - * - * @attention None. - * - * @param uwTaskID [IN] Type #TSK_HANDLE_T Task ID. - * @param puwTaskStatus [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 - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_TaskStatusGet(UINT32 uwTaskID, UINT32* puwTaskStatus); +extern UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo); -/** - *@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 - *@since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_TaskInfoMonitor(VOID); /** * @ingroup los_task - * @brief Obtain tasks switch info. + * @brief Set the affinity mask of the task scheduling cpu. * * @par Description: - * This API is used to obtain tasks switch info. - * - * @attention None. + * This API is used to set the affinity mask of the task scheduling cpu. * - * @param uwIdx [IN] Type #UINT32 Switch info array index. - * @param pTaskSwitchInfo [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 - * @since Huawei LiteOS V100R001C00 - */ -extern UINT32 LOS_TaskSwitchInfoGet(UINT32 uwIdx, UINT32 *pTaskSwitchInfo); - -/** - * @ingroup los_task - * @brief Obtain tasks schduling info. - * - * @par Description: - * This API is used to obtain task is scheduled. - * - * @attention None. + * @attention + *
      + *
    • If any low LOSCFG_KERNEL_CORE_NUM bit of the mask is not setted, an error is reported.
    • + *
    * - * @param None. + * @param uwTaskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. + * @param usCpuAffiMask [IN] Type #UINT32 The scheduling cpu mask.The low to high bit of the mask corresponds to + * the cpu number, the high bit that exceeding the CPU number is ignored. * - * @retval 1: Tasks is scheduled. - * @retval 0: Tasks not scheduling yet. + * @retval #LOS_ERRNO_TSK_ID_INVALID Invalid task ID. + * @retval #LOS_ERRNO_TSK_NOT_CREATED The task is not created. + * @retval #LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR The task cpu affinity mask is incorrect. + * @retval #LOS_OK The task cpu affinity mask is successfully setted. * @par Dependency: *
    • los_task.h: the header file that contains the API declaration.
    - * @see - * @since Huawei LiteOS V100R001C00 + * @see LOS_TaskCpuAffiGet + * @since Huawei LiteOS V200R003C00 */ -extern BOOL LOS_TaskIsRunning(VOID); +extern UINT32 LOS_TaskCpuAffiSet(UINT32 uwTaskID, UINT16 usCpuAffiMask); /** * @ingroup los_task - * @brief Obtain current new task ID. + * @brief Get the affinity mask of the task scheduling cpu. * * @par Description: - * This API is used to obtain the ID of new task. + * This API is used to get the affinity mask of the task scheduling cpu. * * @attention None. * + * @param taskID [IN] Type #UINT32 Task ID. The task id value is obtained from task creation. * - * @retval #LOS_ERRNO_TSK_ID_INVALID 0x02000207: invalid Task ID. - * @retval # Task ID. + * @retval #0 The cpu affinity mask fails to be obtained. + * @retval #UINT16 The scheduling cpu mask. The low to high bit of the mask corresponds to the cpu number. * @par Dependency: *
    • los_task.h: the header file that contains the API declaration.
    - * @see - * @since Huawei LiteOS V100R001C00 + * @see LOS_TaskCpuAffiSet + * @since Huawei LiteOS V200R003C00 */ - 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. - * - * - * @retval #NULL: invalid Task name. - * @retval # Task name. - * @par Dependency: - *
    • los_task.h: the header file that contains the API declaration.
    - * @see - * @since Huawei LiteOS V100R001C00 - */ - extern CHAR* LOS_TaskNameGet(UINT32 uwTaskID); +extern UINT16 LOS_TaskCpuAffiGet(UINT32 taskID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_tick.h b/kernel/include/los_tick.h index 51f979b00..6a4746349 100644 --- a/kernel/include/los_tick.h +++ b/kernel/include/los_tick.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tick * 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 @@ -22,24 +22,27 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_tick Tick +/** + * @defgroup los_tick Tick * @ingroup kernel */ #ifndef _LOS_TICK_H #define _LOS_TICK_H +#include "los_err.h" #include "los_errno.h" +#include "hal_timer.h" #ifdef __cplusplus #if __cplusplus @@ -47,16 +50,16 @@ 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. + * 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) +#define LOS_ERRNO_TICK_CFG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x00) /** * @ingroup los_tick @@ -66,7 +69,7 @@ extern "C" { * * Solution: None. */ -#define LOS_ERRNO_TICK_NO_HWTIMER LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x01) +#define LOS_ERRNO_TICK_NO_HWTIMER LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x01) /** * @ingroup los_tick @@ -74,32 +77,106 @@ extern "C" { * * 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. + * 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_config + * system clock */ -#define LOS_ERRNO_TICK_PER_SEC_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x02) +extern UINT32 g_sysClock; /** - * @ingroup los_tick - * @brief: System clock get function. + * @ingroup los_config + * ticks per second + */ +extern UINT32 g_tickPerSecond; + +/** + * @ingroup los_tick + * @brief Obtain system cycle count. * - * @par Description: - * This API is used to get system clock. + * @par Description: + * This API is used to obtain system cycle count. * - * @attention: - *
    • None.
    + * @attention + *
      + *
    • This count is determined by the tick source.
    • + *
    * - * @param: None. + * @param puwCntHi [OUT] Type #UINT32 Pointer to the higher 32bit of cycles to be obtained. + * @param puwCntLo [OUT] Type #UINT32 Pointer to the lower 32bit of cycles to be obtained. * - * @retval: system clock. + * @retval None. * * @par Dependency: *
    • los_tick.h: the header file that contains the API declaration.
    - * @see None. + * @see * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); + +/** + * @ingroup los_tick + * @brief Obtain system time in nanoseconds. * - * */ -extern UINT32 LOS_SysClockGet(void); -extern BOOL g_bSysTickStart; + * @par Description: + * This API is used to obtain system time in nanoseconds. + * + * @attention None. + * + * @param None. + * + * @retval #UINT64 system time in nanoseconds. + * + * @par Dependency: + *
    • los_tick.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +extern UINT64 LOS_CurrNanosec(VOID); + +/** + * @ingroup los_tick + * @brief spinning-delay in microsecond (us). + * + * @par Description: + * This API is used to delay in microsecond. + * + * @attention None. + * + * @param #UINT32 microsecond needs to delay. + * + * @retval None. + * + * @par Dependency: + *
    • los_tick.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_Udelay(UINT32 usecs); + +/** + * @ingroup los_tick + * @brief spinning-delay in millisecond (ms). + * + * @par Description: + * This API is used to delay in millisecond. + * + * @attention None. + * + * @param #UINT32 millisecond needs to delay. + * + * @retval None. + * + * @par Dependency: + *
    • los_tick.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V100R001C00 + */ +extern VOID LOS_Mdelay(UINT32 usecs); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_tickless.h b/kernel/include/los_tickless.h index 7dd83624f..1a458b689 100644 --- a/kernel/include/los_tickless.h +++ b/kernel/include/los_tickless.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Tickless * 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 @@ -22,23 +22,26 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ - /**@defgroup los_tickless Tickless +/** + * @defgroup los_tickless Tickless * @ingroup kernel */ #ifndef _LOS_TICKLESS_H #define _LOS_TICKLESS_H +#include "los_typedef.h" + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -65,6 +68,7 @@ extern "C" { * @since Huawei LiteOS V200R001C00 */ extern VOID LOS_TicklessEnable(VOID); + /** * @ingroup los_tickless * @brief disable the tickless mode. diff --git a/kernel/include/los_toolchain.h b/kernel/include/los_toolchain.h new file mode 100644 index 000000000..eaff6e04e --- /dev/null +++ b/kernel/include/los_toolchain.h @@ -0,0 +1,151 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ToolChain + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_toolchain + * @ingroup kernel + */ + +#ifndef _LOS_TOOLCHAIN_H +#define _LOS_TOOLCHAIN_H + +#if defined ( __ICCARM__ ) +#include "iccarm_builtin.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* for ARM Compiler */ +#if 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(value) (__clz(value)) +#endif + +/* for IAR Compiler */ +#elif defined ( __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(value) (__iar_builtin_CLZ(value)) +#endif + +#ifndef CTZ +#define CTZ(value) (__UNDEFINED(value)) +#endif + +/* 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(value) (__builtin_clz(value)) +#endif + +#ifndef CTZ +#define CTZ(value) (__builtin_ctz(value)) +#endif + +#else +#error Unknown compiler. +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TOOLCHAIN_H */ diff --git a/kernel/include/los_trace.h b/kernel/include/los_trace.h new file mode 100644 index 000000000..cc693c983 --- /dev/null +++ b/kernel/include/los_trace.h @@ -0,0 +1,294 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: LiteOS Trace Module Implementation HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef RECORD_TRACE_H +#define RECORD_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 + * Interrupt direction: enter the new interrupt + */ +#define IRQ_DIRECT_IN 1 +/** + * @ingroup los_trace + * Interrupt direction: leave the old interrupt + */ +#define IRQ_DIRECT_OUT 0 + +/** + * @ingroup los_trace + * It's the length of tag, filled by los_trace system + */ +#define LOS_TRACE_TAG_LENGTH sizeof(UINTPTR) + +/** +* @ingroup los_trace +* @brief Define the type of a function used to record trace. +* +* @par Description: +* This API is used to define the type of a recording trace function and call it after task or interrupt switch. +* @attention None. +* +* @param inBuf [IN] Type #UINT8 * The buffer saved trace information. +* @param newID [IN] Type #UINT32 The destination. +* @param oldID [IN] Type #UINT32 The source ID for task or the direction for interrupt. +* +* @retval None. +* @par Dependency: +*
    • los_trace.h: the header file that contains the API declaration.
    +* @see +* @since Huawei LiteOS V200R003C00 +*/ +typedef UINT16 (*WriteHook)(UINT8 *inBuf, UINT32 newID, UINT32 oldID); + +/** + * @ingroup los_trace + * Stands for the trace type can be registered. + */ +typedef enum { + 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 = 5, /**< num for the register type, user can use 2~ LOS_TRACE_TYPE_NUM-1 */ +} TraceType; + +/** + * @ingroup los_trace + * struct to store the trace infomation + */ +typedef struct { + UINTPTR tracePos; /**< Data buffer current index position */ + UINTPTR traceWrapPos; /**< Data buffer last loop end position */ + UINT8 dataBuf[LOS_TRACE_BUFFER_SIZE]; /**< Data buffer */ +} TraceBuffer; + +/** + * @ingroup los_trace + * struct to store the task switch infomation + */ +typedef struct { + UINT32 srcTaskId; /**< source taskid */ + UINT32 destTaskId; /**< destination taskid */ + UINT64 currentTick; /**< Time at which the task switch happens */ +} TaskTraceFrame; + +/** + * @ingroup los_trace + * struct to store the interrupt infomation + */ +typedef struct { + UINT32 irqDirection; /**< IRQ_DIRECT_IN stands for entering the irq handler */ + /**< IRQ_DIRECT_OUT stands for leaving the previous irq handler */ + UINT32 irqNum; /**< IRQ number which trigger the interrupt */ + UINT64 currentTick; /**< Time at which the the trace is called */ +} IntTraceFrame; + +/** + * @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] TraceType. Type of trace information. + * @param newID [IN] UINT32. It stands for the new direction of trace + * @param oldID [IN] UINT32. It stands for the previous source of trace + * + * @retval NONE. + * + * @par Dependency: + *
    • los_trace.h: the header file that contains the API declaration.
    + * @see LOS_Trace + * @since Huawei LiteOS V200R003C00 + */ +VOID LOS_Trace(TraceType traceType, UINT32 newID, UINT32 oldID); + +/** + * @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 + * @since Huawei LiteOS V200R003C00 + */ +UINT32 LOS_TraceInit(VOID); + +/** + * @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 that trace type, input hookfnc and trace's data struct are established.
    • + * Otherwise, the trace will be failed. + *
    + * + * @param traceType [IN] TraceType. Type of trace information. + * @param inhook [IN] WriteHook. It's a callback function to store the useful trace + * information + * @param useSize [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 + * @since Huawei LiteOS V200R003C00 + */ +UINT32 LOS_TraceUserReg(TraceType traceType, WriteHook inHook, UINT16 useSize); + +/** + * @ingroup los_trace + * @brief the function to get certain type trace information frame size. + * + * @par Description: + * This API is used to get certain type trace information frame size. + * @attention + *
      + *
    • This API can be called to get frame size.
    • + * Otherwise, the trace will be failed. + *
    + * + * @param traceType [IN] TraceType. Type of trace information, it must belong to the defined enumeration type. + * + * @retval #UINT16 The certain type trace information frame size. + * + * @par Dependency: + *
    • los_trace.h: the header file that contains the API declaration.
    + * @see LOS_TraceFrameSizeGet + * @since Huawei LiteOS V200R003C00 + */ +INT32 LOS_TraceFrameSizeGet(TraceType traceType); + +/** + * @ingroup los_trace + * @brief copy trace buffer of certain cpu to user-defined buffer. + * + * @par Description: + * This API is used to copy system trace buffer of certain cpu to user-defined buffer. + * @attention + *
      + *
    • This API can be called only after that trace buffer has been established.
    • + * Otherwise, the trace will be failed. + *
    + * + * @param cpuID [IN] UINT32. Current cpu ID. + * @param outputBuf [IN] TraceBuffer. The type of user-defined buffer must be TraceBuffer structure type. + * + * @retval #TraceBuffer The point to trace buffer of certain cpuID. + * + * @par Dependency: + *
    • los_trace.h: the header file that contains the API declaration.
    + * @see LOS_TraceBufGet + * @since Huawei LiteOS V200R003C00 + */ +UINT32 LOS_TraceBufGet(TraceBuffer *outputBuf, UINT32 cpuID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/kernel/include/los_typedef.h b/kernel/include/los_typedef.h index 0d0393ef1..c306ec1fe 100644 --- a/kernel/include/los_typedef.h +++ b/kernel/include/los_typedef.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Type define * 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 @@ -22,24 +22,28 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_typedef Type define +/** + * @defgroup los_typedef Type define * @ingroup kernel -*/ + */ #ifndef _LOS_TYPEDEF_H #define _LOS_TYPEDEF_H - +#include "stddef.h" +#include "stdbool.h" +#include "stdint.h" #include "los_builddef.h" +#include "los_toolchain.h" #ifdef __cplusplus #if __cplusplus @@ -47,81 +51,124 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#ifndef LOS_TYPE_DEF -#define LOS_TYPE_DEF +#define OS_STRING(x) #x +#define X_STRING(x) OS_STRING(x) /* type definitions */ -typedef unsigned char UINT8; -typedef unsigned short UINT16; -#if defined (__ICC430__) || defined (__TI_COMPILER_VERSION__) -typedef unsigned long UINT32; +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; + +#ifdef __LP64__ +typedef long unsigned int UINT64; +typedef long signed int INT64; +typedef unsigned long UINTPTR; +typedef signed long INTPTR; #else -typedef unsigned int UINT32; +typedef unsigned long long UINT64; +typedef signed long long INT64; +typedef unsigned int UINTPTR; +typedef signed int INTPTR; #endif -typedef signed char INT8; -typedef signed short INT16; -#if defined (__ICC430__) || defined (__TI_COMPILER_VERSION__) -typedef signed long INT32; + +#ifdef __LP64__ +typedef __uint128_t UINT128; +typedef INT64 ssize_t; +typedef UINT64 size_t; +#define LOSCFG_AARCH64 #else -typedef signed int INT32; +typedef INT32 ssize_t; +typedef UINT32 size_t; #endif -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; +typedef UINTPTR AARCHPTR; +typedef size_t BOOL; -#define VOID void -#endif /*end of #ifndef LOS_TYPE_DEF*/ +#define VOID void +#define STATIC static #ifndef FALSE -#define FALSE ((BOOL)0) +#define FALSE 0U #endif #ifndef TRUE -#define TRUE ((BOOL)1) +#define TRUE 1U #endif #ifndef NULL -#define NULL ((VOID *)0) +#define NULL ((VOID *)0) #endif #ifdef YES #undef YES #endif -#define YES (1) +#define YES 1 -#ifdef NO -#undef NO +#ifdef NO +#undef NO #endif -#define NO (0) +#define NO 0 -#define OS_NULL_BYTE ((UINT8)0xFF) -#define OS_NULL_SHORT ((UINT16)0xFFFF) -#define OS_NULL_INT ((UINT32)0xFFFFFFFF) +#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) +#define LOS_OK 0 #endif #ifndef LOS_NOK -#define LOS_NOK (1U) +#define LOS_NOK 1 #endif -#define OS_FAIL (1) -#define OS_ERROR (UINT32)(-1) -#define OS_INVALID (UINT32)(-1) +#define OS_FAIL 1 +#define OS_ERROR (UINT32)(-1) +#define OS_INVALID (UINT32)(-1) -#define asm __asm +#define asm __asm #ifdef typeof #undef typeof #endif -#define typeof __typeof__ +#define typeof __typeof__ + +#ifndef LOS_LABEL_DEFN +#define LOS_LABEL_DEFN(label) label +#endif + +#ifndef LOSARC_ALIGNMENT +#define LOSARC_ALIGNMENT 8 +#endif +/* And corresponding power of two alignment */ +#ifndef LOSARC_P2ALIGNMENT +#ifdef LOSCFG_AARCH64 +#define LOSARC_P2ALIGNMENT 3 +#else +#define LOSARC_P2ALIGNMENT 2 +#endif +#endif + +/* Give a type or object explicit minimum alignment */ +#if !defined(LOSBLD_ATTRIB_ALIGN) +#define LOSBLD_ATTRIB_ALIGN(__align__) __attribute__((aligned(__align__))) +#endif + +/* Assign a defined variable to a specific section */ +#if !defined(LOSBLD_ATTRIB_SECTION) +#define LOSBLD_ATTRIB_SECTION(__sect__) __attribute__((section(__sect__))) +#endif +/* + * Tell the compiler not to throw away a variable or function. Only known + * available on 3.3.2 or above. Old version's didn't throw them away, + * but using the unused attribute should stop warnings. + */ +#define LOSBLD_ATTRIB_USED __attribute__((used)) #ifdef __cplusplus #if __cplusplus diff --git a/kernel/los_init.c b/kernel/los_init.c deleted file mode 100644 index f4a959765..000000000 --- a/kernel/los_init.c +++ /dev/null @@ -1,251 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "los_sys.h" -#include "los_tick.h" -#include "los_task.ph" -#include "los_config.h" - -#if (LOSCFG_PLATFORM_EXC == YES) -#include "los_exc.ph" -#endif - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -LITE_OS_SEC_BSS UINT8* m_aucSysMem0; - -#if ((LOSCFG_PLATFORM_EXC == YES) && (LOSCFG_SAVE_EXC_INFO == YES)) -LITE_OS_SEC_BSS UINT8 m_aucTaskArray[MAX_EXC_MEM_SIZE]; -#endif - -LITE_OS_SEC_TEXT_INIT void osEnableFPU(void) -{ - *(volatile UINT32 *)0xE000ED88 |= ((3UL << 20)|(3UL << 22)); -} - -/***************************************************************************** - 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_uwTskMaxNum = 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 uwRet; -#if (LOSCFG_BASE_CORE_TICK_HW_TIME == NO) - uwRet = osTickStart(); - - if (uwRet != LOS_OK) - { - PRINT_ERR("osTickStart error\n"); - return uwRet; - } -#else - extern int os_timer_init(void); - uwRet = os_timer_init(); - if (uwRet != LOS_OK) - { - PRINT_ERR("os_timer_init error\n"); - return uwRet; - } -#endif - -#if (LOSCFG_LIB_LIBC_NEWLIB_REENT == YES) - extern VOID osTaskSwitchImpurePtr(VOID); - osTaskSwitchImpurePtr(); -#endif - - LOS_StartToRun(); - - return uwRet; -} - -/***************************************************************************** - 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 uwRet; - - osRegister(); - - m_aucSysMem0 = OS_SYS_MEM_ADDR; - uwRet = osMemSystemInit(); - if (uwRet != LOS_OK) - { - PRINT_ERR("osMemSystemInit error %d\n", uwRet);/*lint !e515*/ - return uwRet; - } - -#if (LOSCFG_PLATFORM_HWI == YES) - { - osHwiInit(); - } -#endif - -#if (LOSCFG_PLATFORM_EXC == YES) - { - osExcInit(MAX_EXC_MEM_SIZE); - } -#endif - - uwRet =osTaskInit(); - if (uwRet != LOS_OK) - { - PRINT_ERR("osTaskInit error\n"); - return uwRet; - } - -#if (LOSCFG_BASE_CORE_TSK_MONITOR == YES) - { - osTaskMonInit(); - } -#endif - -#if (LOSCFG_BASE_CORE_CPUP == YES) - { - uwRet = osCpupInit(); - if (uwRet != LOS_OK) - { - PRINT_ERR("osCpupInit error\n"); - return uwRet; - } - } -#endif - -#if (LOSCFG_BASE_IPC_SEM == YES) - { - uwRet = osSemInit(); - if (uwRet != LOS_OK) - { - return uwRet; - } - } -#endif - -#if (LOSCFG_BASE_IPC_MUX == YES) - { - uwRet = osMuxInit(); - if (uwRet != LOS_OK) - { - return uwRet; - } - } -#endif - -#if (LOSCFG_BASE_IPC_QUEUE == YES) - { - uwRet = osQueueInit(); - if (uwRet != LOS_OK) - { - PRINT_ERR("osQueueInit error\n"); - return uwRet; - } - } -#endif - -#if (LOSCFG_BASE_CORE_SWTMR == YES) - { - uwRet = osSwTmrInit(); - if (uwRet != LOS_OK) - { - PRINT_ERR("osSwTmrInit error\n"); - return uwRet; - } - } -#endif - - #if(LOSCFG_BASE_CORE_TIMESLICE == YES) - osTimesliceInit(); - #endif - - uwRet = osIdleTaskCreate(); - if (uwRet != LOS_OK) - { - return uwRet; - } - -#if (LOSCFG_TEST == YES) - uwRet = los_TestInit(); - if (uwRet != LOS_OK) - { - PRINT_ERR("los_TestInit error\n"); - return uwRet; - } -#endif - - return LOS_OK; -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ diff --git a/osdepends/liteos/atiny_osdep.c b/osdepends/liteos/atiny_osdep.c index 21fdcc4a0..d60c60918 100644 --- a/osdepends/liteos/atiny_osdep.c +++ b/osdepends/liteos/atiny_osdep.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2016-2018>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Task Module Implementation * 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 @@ -22,50 +22,45 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ #include "osdepends/atiny_osdep.h" #include "los_memory.h" -#include "los_sys.ph" -#include "los_sem.ph" -#include "los_tick.ph" +#include "los_sys_pri.h" +#include "los_sem_pri.h" +#include "los_tick_pri.h" #include #include "los_mux.h" - #define ATINY_CNT_MAX_WAITTIME 0xFFFFFFFF -#define LOG_BUF_SIZE (256) +#define LOG_BUF_SIZE 256 #ifndef OK #define OK 0 #endif #ifndef ERR -#define ERR -1 +#define ERR (-1) #endif - static uint64_t osKernelGetTickCount (void) { uint64_t ticks; UINTPTR uvIntSave; - if(OS_INT_ACTIVE) - { + if (OS_INT_ACTIVE) { ticks = 0U; - } - else - { + } else { uvIntSave = LOS_IntLock(); - ticks = g_ullTickCount; + ticks = g_tickCount[0]; LOS_IntRestore(uvIntSave); } @@ -89,11 +84,11 @@ void atiny_free(void *ptr) int atiny_snprintf(char *buf, unsigned int size, const char *format, ...) { - int ret; + int ret; va_list args; va_start(args, format); - ret = vsnprintf(buf, size, format, args); + ret = vsprintf_s(buf, size, format, args); va_end(args); return ret; @@ -105,9 +100,9 @@ int atiny_printf(const char *format, ...) char str_buf[LOG_BUF_SIZE] = {0}; va_list list; - memset(str_buf, 0, LOG_BUF_SIZE); + (void)memset_s(str_buf, LOG_BUF_SIZE, 0, LOG_BUF_SIZE); va_start(list, format); - ret = vsnprintf(str_buf, LOG_BUF_SIZE, format, list); + ret = vsprintf_s(str_buf, LOG_BUF_SIZE, format, list); va_end(list); printf("%s", str_buf); @@ -117,17 +112,20 @@ int atiny_printf(const char *format, ...) char *atiny_strdup(const char *ch) { - char *copy; + char *copy = NULL; size_t length; - if(NULL == ch) + if (ch == NULL) { return NULL; + } length = strlen(ch); copy = (char *)atiny_malloc(length + 1); - if(NULL == copy) + if (copy == NULL) { return NULL; - strncpy(copy, ch, length); + } + + (void)strcpy_s(copy, length + 1, ch); copy[length] = '\0'; return copy; @@ -145,61 +143,51 @@ void *atiny_mutex_create(void) uint32_t uwRet; uint32_t uwSemId; - if (OS_INT_ACTIVE) - { + if (OS_INT_ACTIVE) { return NULL; } uwRet = LOS_BinarySemCreate(1, (UINT32 *)&uwSemId); - - if (uwRet == LOS_OK) - { + if (uwRet == LOS_OK) { return (void *)(GET_SEM(uwSemId)); - } - else - { + } else { return NULL; } } void atiny_mutex_destroy(void *mutex) { - if (OS_INT_ACTIVE) - { + if (OS_INT_ACTIVE) { return; } - if (mutex == NULL) - { + if (mutex == NULL) { return; } - (void)LOS_SemDelete(((SEM_CB_S *)mutex)->usSemID); + (void)LOS_SemDelete(((LosSemCB *)mutex)->semID); } void atiny_mutex_lock(void *mutex) { - if (mutex == NULL) - { + if (mutex == NULL) { return; } - if (OS_INT_ACTIVE) - { + if (OS_INT_ACTIVE) { return; } - (void)LOS_SemPend(((SEM_CB_S *)mutex)->usSemID, ATINY_CNT_MAX_WAITTIME); + (void)LOS_SemPend(((LosSemCB *)mutex)->semID, ATINY_CNT_MAX_WAITTIME); } void atiny_mutex_unlock(void *mutex) { - if (mutex == NULL) - { + if (mutex == NULL) { return; } - (void)LOS_SemPost(((SEM_CB_S *)mutex)->usSemID); + (void)LOS_SemPost(((LosSemCB *)mutex)->semID); } #else @@ -235,17 +223,15 @@ static bool atiny_task_mutex_is_valid(const atiny_task_mutex_s *mutex) int atiny_task_mutex_create(atiny_task_mutex_s *mutex) { - UINT32 ret; + int ret; - if (mutex == NULL) - { + if (mutex == NULL) { return ERR; } - memset(mutex, 0, sizeof(*mutex)); - ret = LOS_MuxCreate(&mutex->mutex); - if (ret != LOS_OK) - { + (void)memset_s(mutex, sizeof(atiny_task_mutex_s), 0, sizeof(atiny_task_mutex_s)); + ret = (int)LOS_MuxCreate(&mutex->mutex); + if (ret != LOS_OK) { return ret; } mutex->valid = true; @@ -257,43 +243,48 @@ int atiny_task_mutex_delete(atiny_task_mutex_s *mutex) { int ret; - if (!atiny_task_mutex_is_valid(mutex)) - { + if (mutex == NULL) { return ERR; } - do - { - ret = LOS_MuxDelete(mutex->mutex); - if (LOS_ERRNO_MUX_PENDED == ret) - { - LOS_TaskDelay(ATINY_DESTROY_MUTEX_WAIT_INTERVAL); - } - else - { + if (!atiny_task_mutex_is_valid(mutex)) { + return ERR; + } + + do { + ret = (int)LOS_MuxDelete(mutex->mutex); + if (ret == (int)LOS_ERRNO_MUX_PENDED) { + (void)LOS_TaskDelay(ATINY_DESTROY_MUTEX_WAIT_INTERVAL); + } else { break; } }while (true); - memset(mutex, 0, sizeof(*mutex)); + (void)memset_s(mutex, sizeof(atiny_task_mutex_s), 0, sizeof(atiny_task_mutex_s)); return ret; } int atiny_task_mutex_lock(atiny_task_mutex_s *mutex) { - if (!atiny_task_mutex_is_valid(mutex)) - { + if (mutex == NULL) { + return ERR; + } + + if (!atiny_task_mutex_is_valid(mutex)) { return ERR; } - return LOS_MuxPend(mutex->mutex, ATINY_CNT_MAX_WAITTIME); + return (int)LOS_MuxPend(mutex->mutex, ATINY_CNT_MAX_WAITTIME); } int atiny_task_mutex_unlock(atiny_task_mutex_s *mutex) { - if (!atiny_task_mutex_is_valid(mutex)) - { + if (mutex == NULL) { + return ERR; + } + + if (!atiny_task_mutex_is_valid(mutex)) { return ERR; } - return LOS_MuxPost(mutex->mutex); + return (int)LOS_MuxPost(mutex->mutex); } #endif /* LOSCFG_BASE_IPC_MUX == YES */ diff --git a/osdepends/liteos/cmsis/1.0/cmsis_liteos1.c b/osdepends/liteos/cmsis/1.0/cmsis_liteos1.c index 001bd3e64..43b87e55e 100644 --- a/osdepends/liteos/cmsis/1.0/cmsis_liteos1.c +++ b/osdepends/liteos/cmsis/1.0/cmsis_liteos1.c @@ -1,1462 +1,1556 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "cmsis_os.h" -#include "los_event.h" -#include "los_membox.h" -#include "los_hwi.h" - -#include "los_mux.ph" -#include "los_queue.ph" -#include "los_sem.ph" -#include "los_swtmr.ph" -#include "los_sys.ph" -#include "los_task.ph" -#include "los_tick.ph" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ -#if (CMSIS_OS_VER == 1) - -#define PRIORITY_WIN 4u - -INT32 osKernelRunning(void) -{ - extern BOOL g_bTaskScheduled; - return (g_bTaskScheduled); -} - -/// Start the RTOS Kernel with executing the specified thread -osStatus osKernelStart(void) -{ - (VOID)LOS_Start(); - return osOK; -} - -UINT32 osKernelSysTick (void) -{ - //todo: need to use external clock source - return (UINT32)g_ullTickCount; -} - -osStatus osKernelInitialize (void) -{ - INT32 ret; - - ret = LOS_KernelInit(); - if (ret != LOS_OK) - { - return osErrorOS; - } - - return osOK; -} - -// Thread Public API - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) -{ - osThreadId tskcb; - TSK_INIT_PARAM_S stTskInitParam; - UINT32 uwTskHandle; - UINT32 uwRet; - if ((thread_def == NULL) || - (thread_def->pthread == NULL) || - (thread_def->tpriority < osPriorityIdle) || - (thread_def->tpriority > osPriorityRealtime)) - { - return (osThreadId)NULL; - } - - (VOID)memset(&stTskInitParam, 0, sizeof(TSK_INIT_PARAM_S)); - stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)thread_def->pthread; - stTskInitParam.uwStackSize = thread_def->stacksize; - stTskInitParam.pcName = thread_def->name; - stTskInitParam.uwArg = (UINT32)argument; - stTskInitParam.usTaskPrio = (UINT16)(PRIORITY_WIN - thread_def->tpriority); /*1~7*/ - - uwRet = LOS_TaskCreate(&uwTskHandle, &stTskInitParam); - - if(LOS_OK != uwRet ) - { - return (osThreadId)NULL; - } - - tskcb = (osThreadId)&g_pstTaskCBArray[uwTskHandle]; - - return tskcb; -} - -/// Return the thread ID of the current running thread -osThreadId osThreadGetId(void) -{ - return (osThreadId)g_stLosTask.pstRunTask; -} - -UINT32 osThreadGetPId(osThreadId thread_id) -{ - return ((LOS_TASK_CB *)thread_id)->uwTaskID; -} -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus osThreadTerminate(osThreadId thread_id) -{ - UINT32 uwRet; - - if (thread_id == NULL) - return osErrorParameter; - - if (OS_INT_ACTIVE) - return osErrorISR; - - uwRet = LOS_TaskDelete(((LOS_TASK_CB *)thread_id)->uwTaskID); - - if (uwRet == LOS_OK) - return osOK; - else - return osErrorOS; -} - -/// Pass control to next thread that is in state READY -osStatus osThreadYield(void) -{ - UINT32 uwRet; - - if (OS_INT_ACTIVE) - return osErrorISR; - - uwRet = LOS_TaskYield(); - - if (uwRet == LOS_OK) - return osOK; - else - return osErrorOS; -} - -/// Change prority of an active thread -osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority) -{ - UINT32 uwRet; - UINT16 usPriorityTemp; - - if (thread_id == NULL) - return osErrorParameter; - - if (OS_INT_ACTIVE) - return osErrorISR; - - if (priority < osPriorityIdle || priority > osPriorityRealtime) - return osErrorPriority; - - usPriorityTemp = PRIORITY_WIN - priority; - - uwRet = LOS_TaskPriSet(((LOS_TASK_CB *)thread_id)->uwTaskID, usPriorityTemp); - - if (uwRet == LOS_OK) - return osOK; - else - return osErrorOS; -} - -/// Get current prority of an active thread -osPriority osThreadGetPriority(osThreadId thread_id) -{ - UINT16 usPriorityTemp; - INT16 osPriorityRet; - - if (thread_id == NULL) - return osPriorityError; - - usPriorityTemp = LOS_TaskPriGet(((LOS_TASK_CB *)thread_id)->uwTaskID); - - osPriorityRet = PRIORITY_WIN - usPriorityTemp; - - if (osPriorityRet < osPriorityIdle || osPriorityRet > osPriorityRealtime) - return osPriorityError; - - return (osPriority)osPriorityRet; -} - -osSemaphoreId osBinarySemaphoreCreate(const osSemaphoreDef_t *semaphore_def, INT32 count) -{ -#if (LOSCFG_BASE_IPC_SEM == YES) - UINT32 uwRet; - UINT32 *SemHandle; - SEM_CB_S *pstSemCreated; - - if (semaphore_def == NULL) - { - return (osSemaphoreId)NULL; - } - - SemHandle = (UINT32 *)(semaphore_def->puwSemHandle); - uwRet = LOS_BinarySemCreate (count, SemHandle); - - if (uwRet == LOS_OK) - { - pstSemCreated = GET_SEM(*SemHandle); - return (osSemaphoreId)pstSemCreated; - } - else - { - return (osSemaphoreId)NULL; - } -#endif -} - -osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, INT32 count) -{ -#if (LOSCFG_BASE_IPC_SEM == YES) - UINT32 uwRet; - UINT32 *SemHandle; - - if (semaphore_def == NULL) - { - return (osSemaphoreId)NULL; - } - - SemHandle = (UINT32 *)(semaphore_def->puwSemHandle); - uwRet = LOS_SemCreate (count, SemHandle); - - if (uwRet == LOS_OK) - { - return (osSemaphoreId)GET_SEM(*SemHandle); - } - else - { - return (osSemaphoreId)NULL; - } -#endif -} - -/// Wait until a Semaphore becomes available -/* -number of available tokens, or -1 in case of incorrect parameters. -*/ -INT32 osSemaphoreWait(osSemaphoreId semaphore_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_SEM == YES) - UINT32 uwRet; - UINT32 SemID; - - if (semaphore_id == NULL) - { - return -1; - } - - if (OS_INT_ACTIVE) - { - return -1; - } - - SemID = ((SEM_CB_S *)semaphore_id)->usSemID; - - uwRet = LOS_SemPend(SemID, LOS_MS2Tick(millisec)); - - if (uwRet == LOS_OK) - { - return ((SEM_CB_S *)semaphore_id)->usSemCount; - } - else - { - return -1; - } -#endif -} - -/// Release a Semaphore -/* -osOK: the semaphore has been released. -osErrorResource: all tokens have already been released. -osErrorParameter: the parameter semaphore_id is incorrect. -*/ -osStatus osSemaphoreRelease(osSemaphoreId semaphore_id) -{ -#if (LOSCFG_BASE_IPC_SEM == YES) - UINT32 uwRet; - UINT32 SemID; - - if (semaphore_id == NULL) - { - return osErrorParameter; - } - - SemID = ((SEM_CB_S *)semaphore_id)->usSemID; - uwRet = LOS_SemPost(SemID); - - if (uwRet == LOS_OK) - { - return osOK; - } - else if (uwRet == LOS_ERRNO_SEM_INVALID) - { - return osErrorParameter; - } - else - { - return osErrorResource; - } -#endif -} - -/* -osOK: the semaphore object has been deleted. -osErrorISR: osSemaphoreDelete cannot be called from interrupt service routines. -osErrorResource: the semaphore object could not be deleted. -osErrorParameter: the parameter semaphore_id is incorrect. -*/ -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) -{ -#if (LOSCFG_BASE_IPC_SEM == YES) - UINT32 uwRet; - UINT32 SemID; - - if (semaphore_id == NULL) - { - return osErrorParameter; - } - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - SemID = ((SEM_CB_S *)semaphore_id)->usSemID; - uwRet = LOS_SemDelete(SemID); - - if (uwRet == LOS_OK) - { - return osOK; - } - else if (uwRet == LOS_ERRNO_SEM_INVALID) - { - return osErrorParameter; - } - else - { - return osErrorResource; - } -#endif -} - -//Mutex Public API - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (const osMutexDef_t *mutex_def) -{ -#if (LOSCFG_BASE_IPC_MUX == YES) - UINT32 uwRet; - UINT32 *MuxHandle; - - if(mutex_def == NULL) - { - return (osMutexId)NULL; - } - - MuxHandle = (UINT32 *)(mutex_def->puwMuxHandle); - uwRet = LOS_MuxCreate (MuxHandle); - - if(uwRet == LOS_OK) - { - return (osMutexId)GET_MUX(*MuxHandle); - } - else - { - return (osMutexId)NULL; - } -#endif -} - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. -/* -osOK: the mutex has been obtain. -osErrorTimeoutResource: the mutex could not be obtained in the given time. -osErrorResource: the mutex could not be obtained when no timeout was specified. -osErrorParameter: the parameter mutex_id is incorrect. -osErrorISR: osMutexWait cannot be called from interrupt service routines. -*/ -osStatus osMutexWait (osMutexId mutex_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_MUX == YES) - UINT32 uwRet; - UINT32 MutID; - - if (mutex_id == NULL) - { - return osErrorParameter; - } - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - MutID = ((MUX_CB_S *)mutex_id)->ucMuxID; - - uwRet = LOS_MuxPend(MutID, LOS_MS2Tick(millisec)); - - if(uwRet == LOS_OK) - { - return osOK; - } - else if(uwRet == LOS_ERRNO_MUX_TIMEOUT) - { - return osErrorTimeoutResource; - } - else if(uwRet == LOS_ERRNO_MUX_UNAVAILABLE) - { - return osErrorResource; - } - else if(uwRet == LOS_ERRNO_MUX_PEND_INTERR) - { - return osErrorISR; - } - else - { - return osErrorParameter; - } -#endif -} - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. -/* -osOK: the mutex has been correctly released. -osErrorResource: the mutex was not obtained before. -osErrorParameter: the parameter mutex_id is incorrect. -osErrorISR: osMutexRelease cannot be called from interrupt service routines. // -*/ -osStatus osMutexRelease (osMutexId mutex_id) -{ -#if (LOSCFG_BASE_IPC_MUX == YES) - UINT32 uwRet; - UINT32 MutID; - - - if (mutex_id == NULL) - { - return osErrorParameter; - } - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - MutID = ((MUX_CB_S *)mutex_id)->ucMuxID; - uwRet = LOS_MuxPost(MutID); - - if(uwRet == LOS_OK) - { - return osOK; - } - else - { - return osErrorResource; - } -#endif -} - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. -/* -osOK: the mutex object has been deleted. -osErrorISR: osMutexDelete cannot be called from interrupt service routines. //osErrorISR -osErrorResource: all tokens have already been released. -osErrorParameter: the parameter mutex_id is incorrect. -*/ -osStatus osMutexDelete (osMutexId mutex_id) -{ -#if (LOSCFG_BASE_IPC_MUX == YES) - UINT32 uwRet; - UINT32 MutID; - - if (mutex_id == NULL) - { - return osErrorParameter; - } - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - MutID = ((MUX_CB_S *)mutex_id)->ucMuxID; - uwRet = LOS_MuxDelete(MutID); - - if(uwRet == LOS_OK) - { - return osOK; - } - else if(uwRet == LOS_ERRNO_MUX_INVALID) - { - return osErrorResource; - } - else - { - return osErrorParameter; - } -#endif -} - -osPoolId osPoolCreate (const osPoolDef_t *pool_def) -{ - UINT32 uwBlkSize, uwBoxSize; - UINT32 uwRet; - - if ((pool_def == NULL) || - (pool_def->pool_sz == 0) || - (pool_def->item_sz == 0) || - (pool_def->pool == NULL)) - { - return (osPoolId)NULL; - } - - uwBlkSize = (pool_def->item_sz + 3) & ~3; - uwBoxSize = /*sizeof(OS_MEMBOX_S) + */pool_def->pool_sz * uwBlkSize; /* delete sizeof(OS_MEMBOX_S) after membox management change */ - - uwRet = LOS_MemboxInit(pool_def->pool, uwBoxSize, uwBlkSize); - if(uwRet != LOS_OK) - { - return (osPoolId)NULL; - } - - return (osPoolId)(pool_def->pool); -} - -void *osPoolAlloc (osPoolId pool_id) -{ - void *ptr; - - if (pool_id == NULL) - return NULL; - - ptr = LOS_MemboxAlloc(pool_id); - - return ptr; -} - - -void *osPoolCAlloc (osPoolId pool_id) -{ - void *ptr; - - if (pool_id == NULL) - return NULL; - - ptr = LOS_MemboxAlloc(pool_id); - - if (ptr) - LOS_MemboxClr(pool_id, ptr); - - return ptr; -} - - -osStatus osPoolFree (osPoolId pool_id, void *block) -{ - INT32 res; - - if (pool_id == NULL) - return osErrorParameter; - - res = LOS_MemboxFree(pool_id, block); - - if (res != 0) - return osErrorValue; - - return osOK; -} - -// Message Queue Management Public API - -static inline UINT32 osMessageCheckRet(UINT32 uwRet) -{ - if (uwRet == LOS_OK) - { - uwRet = osOK; - } - else if (uwRet == LOS_ERRNO_QUEUE_INVALID || uwRet == LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT) - { - uwRet = osErrorParameter; - } - else if (uwRet == LOS_ERRNO_QUEUE_TIMEOUT || uwRet == LOS_ERRNO_QUEUE_ISFULL) - { - uwRet = osEventTimeout; - } - else - { - uwRet = osErrorOS; - } - return uwRet; -} - - -/// Create and Initialize Message Queue -osMessageQId osMessageCreate(osMessageQDef_t *queue_def, osThreadId thread_id) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwQueueID; - UINT32 uwRet; - - (void)(thread_id); - if (NULL == queue_def) - { - return (osMessageQId)NULL; - } - uwRet = LOS_QueueCreate((char *)NULL, (UINT16)(queue_def->queue_sz), &uwQueueID, 0, (UINT16)( queue_def->item_sz)); - if (uwRet == LOS_OK) - { - return (osMessageQId)GET_QUEUE_HANDLE(uwQueueID); - } - else - { - return (osMessageQId)NULL; - } -#endif -} - -/// Put a Message to a Queue header -osStatus osMessagePutHead(const osMessageQId queue_id, UINT32 info, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwRet; - uwRet = LOS_QueueWriteHead(MESSAGEQID_TO_QUEUEID(queue_id), (void *)info, sizeof(UINT32), LOS_MS2Tick(millisec)); - uwRet = osMessageCheckRet(uwRet); - return (osStatus)uwRet; -#endif -} - -/// Put a Message to a Queue -osStatus osMessagePut(const osMessageQId queue_id, UINT32 info, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwRet; - if(NULL == queue_id) - { - return osErrorParameter; - } - - uwRet = LOS_QueueWrite(MESSAGEQID_TO_QUEUEID(queue_id), (void *)info, sizeof(UINT32), LOS_MS2Tick(millisec)); - uwRet = osMessageCheckRet(uwRet); - return (osStatus)uwRet; -#endif -} - -/// Get a Message or Wait for a Message from a Queue -osEvent osMessageGet(osMessageQId queue_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - osEvent ret; - UINT32 uwRet; - if(NULL == queue_id) - { - ret.status = osErrorParameter; - return ret; - } - (VOID)memset((void *)(&ret), 0, sizeof(osEvent)); - uwRet = LOS_QueueRead(MESSAGEQID_TO_QUEUEID(queue_id), &(ret.value.v), sizeof(UINT32), LOS_MS2Tick(millisec)); - if (uwRet == LOS_OK) - { - ret.status = osEventMessage; - } - else if (uwRet == LOS_ERRNO_QUEUE_INVALID || uwRet == LOS_ERRNO_QUEUE_READ_IN_INTERRUPT) - { - ret.status = osErrorParameter; - } - else if (uwRet == LOS_ERRNO_QUEUE_ISEMPTY || uwRet == LOS_ERRNO_QUEUE_TIMEOUT) - { - ret.status = osEventTimeout; - } - else - { - ret.status = osErrorOS; - } - - return ret; -#endif -} - - -// Mail Queue Management Public API - -/// Create and Initialize mail queue -osMailQId osMailCreate(osMailQDef_t *queue_def, osThreadId thread_id) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwRet; - UINT32 uwQueueID; - UINT32 uwBlkSize, uwBoxSize; - - (void)(thread_id); - if (NULL == queue_def) - { - return (osMailQId)NULL; - } - uwRet = LOS_QueueCreate((char *)NULL, (UINT16)(queue_def->queue_sz), &uwQueueID, 0, sizeof(UINT32)); - if (uwRet == LOS_OK) - { - *(UINT32 *)(((void **)queue_def->pool) + 0) = (UINT32)(GET_QUEUE_HANDLE(uwQueueID)); - uwBlkSize = (queue_def->item_sz + 3) & (~3); - uwBoxSize = /* sizeof(OS_MEMBOX_S) + */queue_def->queue_sz * uwBlkSize; /* delete sizeof(OS_MEMBOX_S) after membox management change */ - - (void)LOS_MemboxInit(*(((void **)queue_def->pool) + 1), uwBoxSize, uwBlkSize); - return (osMailQId)queue_def->pool; - } - return (osMailQId)NULL; -#endif -} - -/// Allocate a memory block from a mail -void *osMailAlloc(osMailQId queue_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - void *pool = NULL; - UINT32 uwQueueID; - - if (queue_id == NULL) - { - return NULL; - } - - uwQueueID = *((UINT32 *)(((void **)queue_id) + 0)); - pool = *((((void **)queue_id) + 1)); - - return (void *)osQueueMailAlloc(MESSAGEQID_TO_QUEUEID(uwQueueID), pool, LOS_MS2Tick(millisec)); -#endif -} - -/// Allocate a memory block from a mail and set memory block to zero -void *osMailCAlloc(osMailQId queue_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - void *mem = NULL; - LOS_MEMBOX_INFO *pool = (LOS_MEMBOX_INFO *)NULL; - mem = osMailAlloc(queue_id, millisec); - - if (mem != NULL) - { - pool = (LOS_MEMBOX_INFO *)(*(((void **)queue_id) + 1)); - (VOID)memset(mem, 0, pool->uwBlkSize); - } - - return mem; -#endif -} - -/// Free a memory block from a mail -osStatus osMailFree(osMailQId queue_id, void *mail) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - void *pool = NULL; - UINT32 uwQueueID; - UINT32 uwRet; - - if (queue_id == NULL) - { - return osErrorParameter; - } - - uwQueueID = *((UINT32 *)(((void **)queue_id) + 0)); - pool = *((((void **)queue_id) + 1)); - - uwRet = osQueueMailFree(MESSAGEQID_TO_QUEUEID(uwQueueID), pool, mail); - if (uwRet == LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID || uwRet == LOS_ERRNO_QUEUE_MAIL_PTR_INVALID) - { - return osErrorParameter; - } - else if (uwRet == LOS_ERRNO_QUEUE_MAIL_FREE_ERROR) - { - return osErrorOS; - } - return osOK; -#endif -} - -/// Put a mail to a queue Header -osStatus osMailPutHead(osMailQId queue_id, void *mail) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwQueueID; - - if (queue_id == NULL) - { - return osErrorParameter; - } - - if (mail == NULL) - { - return osErrorValue; - } - - uwQueueID = *((UINT32 *)(((void **)queue_id) + 0)); - - return osMessagePutHead((osMessageQId)uwQueueID, (UINT32)mail, 0); -#endif -} - -/// Put a mail to a queue -osStatus osMailPut(osMailQId queue_id, void *mail) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwQueueID; - - if (queue_id == NULL) - { - return osErrorParameter; - } - - if (mail == NULL) - { - return osErrorValue; - } - - uwQueueID = *((UINT32 *)(((void **)queue_id) + 0)); - - return osMessagePut((osMessageQId)uwQueueID, (UINT32)mail, 0); -#endif -} - -/// Get a mail from a queue -osEvent osMailGet(osMailQId queue_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - UINT32 uwQueueID; - osEvent ret; - - if (queue_id == NULL) - { - ret.status = osErrorParameter; - return ret; - } - - uwQueueID = *((UINT32 *)(((void **)queue_id) + 0)); - ret = osMessageGet((osMessageQId)uwQueueID, millisec); - - if (ret.status == osEventMessage) - { - ret.status = osEventMail; - } - return ret; -#endif -} - -/*lint -e1055 -e534*/ -osStatus osMailClear(osMailQId queue_id) -{ -#if (LOSCFG_BASE_IPC_QUEUE == YES) - osEvent evt; - UINTPTR uvIntSave; - uvIntSave = LOS_IntLock(); - while(1) - { - evt = osMailGet(queue_id, 0); - if(evt.status == osEventMail) - { - (VOID)osMailFree(queue_id, evt.value.p); - } - else if(evt.status == osEventTimeout) - { - (VOID)LOS_IntRestore(uvIntSave); - return osOK; - } - else - { - (VOID)LOS_IntRestore(uvIntSave); - return evt.status; - } - } -#endif -} - -INT32 osSignalSet (osThreadId thread_id, INT32 signals) -{ - EVENT_CB_S sig; - UINT32 old_sig; - UINT32 uwRet; - - if (((LOS_TASK_CB *)thread_id) == NULL) - { - return 0x80000000;/*lint !e569*/ - } - - if (signals & (~((0x1 << osFeature_Signals) - 1))) - { - return osErrorValue; - } - - sig = ((LOS_TASK_CB *)thread_id)->uwEvent; - old_sig = sig.uwEventID; - if (sig.uwEventID == 0xFFFFFFFF) - { - uwRet = LOS_EventInit(&(((LOS_TASK_CB *)thread_id)->uwEvent)); - if (uwRet != LOS_OK) - { - return osErrorOS; - } - } - uwRet = LOS_EventWrite(&(((LOS_TASK_CB *)thread_id)->uwEvent), signals); - if (uwRet != LOS_OK) - { - return osErrorOS; - } - - return old_sig; -} - -INT32 osSignalClear (osThreadId thread_id, INT32 signals) -{ - EVENT_CB_S sig; - UINT32 old_sig; - UINT32 uwRet; - - if (((LOS_TASK_CB *)thread_id) == NULL) - { - return 0x80000000; /*lint !e569*/ - } - - if (signals & (~((0x1 << osFeature_Signals) - 1))) - { - return osErrorValue; - } - - sig = ((LOS_TASK_CB *)thread_id)->uwEvent; - old_sig = sig.uwEventID; - uwRet = LOS_EventClear(&(((LOS_TASK_CB *)thread_id)->uwEvent), ~(UINT32)signals); - if (uwRet != LOS_OK) - { - return osErrorValue; - } - - return old_sig; -} - -osEvent osSignalWait (INT32 signals, UINT32 millisec) -{ - UINT32 uwRet = 0; - osEvent ret; - UINT32 uwFlags = 0; - UINT32 uwTimeOut = osWaitForever; - EVENT_CB_S sig; - LOS_TASK_CB *pstRunTsk; - - if (OS_INT_ACTIVE) - { - /* Not allowed in ISR */ - ret.status = osErrorISR; - return ret; - } - - if (signals & (~((0x1 << osFeature_Signals) - 1))) - { - ret.status = osErrorValue; - return ret; - } - - if (signals != 0) - { - uwFlags |= LOS_WAITMODE_AND; - } - else - { - signals = 0xFFFFFFFF & ((0x1 << osFeature_Signals) - 1); - uwFlags |= LOS_WAITMODE_OR; - } - - uwTimeOut = LOS_MS2Tick(millisec); - - pstRunTsk = g_stLosTask.pstRunTask; - sig = ((LOS_TASK_CB *)pstRunTsk)->uwEvent; - if (sig.uwEventID == 0xFFFFFFFF) - { - uwRet = LOS_EventInit(&(((LOS_TASK_CB *)(g_stLosTask.pstRunTask))->uwEvent)); - if (uwRet != LOS_OK) - { - ret.status = osErrorOS; - return ret; - } - } - uwRet = LOS_EventRead(&(((LOS_TASK_CB *)(g_stLosTask.pstRunTask))->uwEvent), signals, uwFlags | LOS_WAITMODE_CLR, uwTimeOut); - if (uwRet == LOS_ERRNO_EVENT_READ_TIMEOUT) - { - ret.status = osEventTimeout; - ret.value.signals = 0; - } - else if (uwRet == 0) - { - ret.status = osOK; - ret.value.signals = 0; - } - else if(uwRet == LOS_ERRNO_EVENT_PTR_NULL || - uwRet == LOS_ERRNO_EVENT_EVENTMASK_INVALID || - uwRet == LOS_ERRNO_EVENT_READ_IN_LOCK || - uwRet == LOS_ERRNO_EVENT_READ_IN_INTERRUPT) - { - ret.status = osErrorOS; - ret.value.signals = 0; - } - else - { - ret.status = osEventSignal; - ret.value.signals = uwRet; - } - - return ret; -} - -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) -osTimerId osTimerExtCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument, os_timer_rouses_type ucRouses, os_timer_align_type ucSensitive) -{ - SWTMR_CTRL_S *pstSwtmr = NULL; -#if (LOSCFG_BASE_CORE_SWTMR == YES) - UINT32 uwRet; - UINT16 usSwTmrID; - - if ((timer_def == NULL) - || (timer_def->ptimer == NULL) - || (timer_def->default_interval == 0) - || ((type != osTimerOnce) && (type != osTimerPeriodic))) - { - return NULL; - } - - uwRet = LOS_SwtmrCreate(timer_def->default_interval, type, - (SWTMR_PROC_FUNC)(timer_def->ptimer), - &usSwTmrID, (UINT32)argument, ucRouses, ucSensitive); - - if (uwRet != LOS_OK) - { - return NULL; - } - - pstSwtmr = OS_SWT_FROM_SID(usSwTmrID); -#endif - return pstSwtmr; -} -#endif - -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) -{ - SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)NULL; -#if (LOSCFG_BASE_CORE_SWTMR == YES) - UINT32 uwRet; - UINT16 usSwTmrID; - - if ((timer_def == NULL) - || (timer_def->ptimer == NULL) - || (timer_def->default_interval == 0) - || ((type != osTimerOnce) && (type != osTimerPeriodic) && (type != osTimerDelay))) - { - return (osTimerId)NULL; - } - - uwRet = LOS_SwtmrCreate(timer_def->default_interval, type, - (SWTMR_PROC_FUNC)(timer_def->ptimer), - &usSwTmrID, (UINT32)argument -#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) - , osTimerRousesAllow, osTimerAlignIgnore -#endif - ); - - if (uwRet != LOS_OK) - { - return (osTimerId)NULL; - } - - pstSwtmr = OS_SWT_FROM_SID(usSwTmrID); -#endif - return pstSwtmr; -} - -osStatus osTimerStart (osTimerId timer_id, UINT32 millisec) -{ -#if (LOSCFG_BASE_CORE_SWTMR == YES) - SWTMR_CTRL_S *pstSwtmr; - UINT32 uwInterval; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - pstSwtmr = (SWTMR_CTRL_S *)timer_id; - if (pstSwtmr == NULL) - { - return osErrorParameter; - } - - uwInterval = LOS_MS2Tick(millisec); - if (uwInterval == 0) - { - return osErrorValue; - } - - pstSwtmr->uwInterval = uwInterval; - if (LOS_SwtmrStart(pstSwtmr->usTimerID)) - { - return osErrorResource; - } -#endif - return osOK; -} - -osStatus osTimerStop (osTimerId timer_id) -{ -#if (LOSCFG_BASE_CORE_SWTMR == YES) - SWTMR_CTRL_S *pstSwtmr; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - pstSwtmr = (SWTMR_CTRL_S *)timer_id; - if (pstSwtmr == NULL) - { - return osErrorParameter; - } - - if (LOS_SwtmrStop(pstSwtmr->usTimerID)) - { - return osErrorResource; - } -#endif - return osOK; -} - -osStatus osTimerRestart (osTimerId timer_id, UINT32 millisec, UINT8 strict) -{ -#if (LOSCFG_BASE_CORE_SWTMR == YES) - osStatus status = osOK; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - status = osTimerStop(timer_id); - if (strict && (status != osOK)) - { - return status; - } - - status = osTimerStart(timer_id, millisec); - if (status != osOK) - { - return status; - } -#endif - return osOK; -} - -osStatus osTimerDelete (osTimerId timer_id) -{ -#if (LOSCFG_BASE_CORE_SWTMR == YES) - SWTMR_CTRL_S *pstSwtmr; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - pstSwtmr = (SWTMR_CTRL_S *)timer_id; - if (pstSwtmr == NULL) - { - return osErrorParameter; - } - - if (LOS_SwtmrDelete(pstSwtmr->usTimerID)) - { - return osErrorResource; - } -#endif - return osOK; - -} - -osStatus osDelay (UINT32 millisec) -{ - UINT32 uwInterval; - UINT32 uwRet = 0; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - if (millisec == 0) - { - return osOK; - } - - //check if in idle we use udelay instead - if(g_uwIdleTaskID == LOS_CurTaskIDGet()) - { - PRINT_ERR("Idle Task Do Not Support Delay!\n"); - return osOK; - } - - uwInterval = LOS_MS2Tick(millisec); - - uwRet = LOS_TaskDelay(uwInterval); - - if (uwRet == LOS_OK) - { - return osEventTimeout; - } - else - { - return osErrorResource; - } -} - -#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) -osEvent osWait (UINT32 millisec) -{ - osEvent evt; - UINT32 uwInterval; - UINT32 uwRet = 0; - - if (OS_INT_ACTIVE) - { - evt.status = osErrorISR; - return evt; - } - - if (millisec == 0) - { - evt.status = osOK; - return evt; - } - - /* TODO: osEventSignal, osEventMessage, osEventMail */ - uwInterval = LOS_MS2Tick(millisec); - - uwRet = LOS_TaskDelay(uwInterval); - - if (uwRet == LOS_OK) - { - evt.status = osEventTimeout; - } - else - { - evt.status = osErrorResource; - } - - return evt; -} -#endif - -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - -fwMailQId g_fwMailQList = (fwMailQId)NULL; -UINT32 g_maxEventTime = 0x400; -#endif - -fwMailQId fwMailCreate (fwMailQDef_t *queue_def, osThreadId thread_id) -{ -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - // add mailQ to list - (void)osMailCreate(queue_def->queue_id, thread_id); - queue_def->next = (struct fw_MailQ_def *)g_fwMailQList; - g_fwMailQList = (fwMailQId)queue_def; - return (fwMailQId)queue_def; -#else - return osMailCreate(queue_def, thread_id); -#endif -} - -void *fwMailAlloc (fwMailQId queue_id, UINT32 millisec, UINT8 tag, UINT8 cmd) -{ - void *mem = NULL; - - if (queue_id == NULL) - return NULL; -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - mem = osMailAlloc((osMailQId)((((fwMailQDef_t *)queue_id)->queue_id)->pool), millisec); -#else - mem = osMailAlloc(queue_id, millisec); -#endif - - if (mem != NULL) - { - ((fw_event_t *)mem)->cmd = cmd; - ((fw_event_t *)mem)->tag = tag; - } - - return mem; -} - -void *fwMailCAlloc (fwMailQId queue_id, UINT32 millisec, UINT8 tag, UINT8 cmd) -{ - void *mem = NULL; - - if (queue_id == NULL) - return NULL; -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - mem = osMailCAlloc((osMailQId)((((fwMailQDef_t *)queue_id)->queue_id)->pool), millisec); -#else - mem = osMailCAlloc(queue_id, millisec); -#endif - - if (mem != NULL) - { - ((fw_event_t *)mem)->cmd = cmd; - ((fw_event_t *)mem)->tag = tag; - } - - return mem; -} - -osStatus fwMailFree (fwMailQId queue_id, void *mail) -{ - if (queue_id == NULL) - return osErrorParameter; - -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - return osMailFree((osMailQId)((((fwMailQDef_t *)queue_id)->queue_id)->pool), mail); -#else - return osMailFree(queue_id, mail); -#endif -} - -osStatus fwMailPut (fwMailQId queue_id, void *mail) -{ - if (queue_id == NULL) - return osErrorParameter; -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - return osMailPut((osMailQId)((((fwMailQDef_t *)queue_id)->queue_id)->pool), mail); -#else - return osMailPut(queue_id, mail); -#endif -} -/*lint -e438 -e550 -e529*/ -osEvent fwMailGet (fwMailQId queue_id, UINT32 millisec) -{ - osEvent evt; - UINT32 max_time; - void *pool; - UINT32 uwQueueID; - - if (queue_id == NULL) - { - evt.status = osErrorParameter; - return evt; - } -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - - pool = ((((fwMailQDef_t *)queue_id)->queue_id)->pool); - uwQueueID = *((UINT32 *)(((void **)(pool)) + 0)); - max_time = GET_EVENT_MAXTIME(queue_id) != 0 ? GET_EVENT_MAXTIME(queue_id) : g_maxEventTime; - - if (((fwMailQDef_t *)queue_id)->event_begin_time != 0 && - (osKernelSysTick() - ((fwMailQDef_t *)queue_id)->event_begin_time ) > max_time) - { - ((fwMailQDef_t *)queue_id)->timeout_cnt++; - PRINT_ERR("[ERR] Get QID %d TIMEOUTCNT %d\n", uwQueueID, ((fwMailQDef_t *)queue_id)->timeout_cnt); - } - - ((fwMailQDef_t *)queue_id)->event_begin_time = 0; - evt = osMailGet((osMailQId)((((fwMailQDef_t *)queue_id)->queue_id)->pool), millisec); - if (evt.status == osEventMail) - { - ((fwMailQDef_t *)queue_id)->last_event = *(fw_event_t *)(evt.value.p); - ((fwMailQDef_t *)queue_id)->event_begin_time = osKernelSysTick(); - } -#else - evt = osMailGet(queue_id, millisec); -#endif - return evt; -} - -/*lint -e438 -e550*/ -UINT32 fwMailQGetStatus(void) -{ -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - fwMailQDef_t *ptr = (fwMailQDef_t *)NULL; - void *pool = NULL; - UINT32 uwQueueID; - UINT32 curr_tick = osKernelSysTick(); - UINT32 max_time = 0; - UINT8 ret = 0; - - ptr = (fwMailQDef_t *)g_fwMailQList; - while (ptr != NULL) - { - max_time = GET_EVENT_MAXTIME(ptr) != 0 ? GET_EVENT_MAXTIME(ptr) : g_maxEventTime; - pool = ((ptr->queue_id)->pool); - uwQueueID = *((UINT32 *)(((void **)(pool)) + 0)); - if ( ptr->event_begin_time != 0 && (curr_tick - ptr->event_begin_time) > max_time) - { - ptr->timeout_cnt++; - PRINT_ERR("[ERR] QID %d OUTQUE %d Phase %d\n", uwQueueID, ptr->event_begin_time, GET_EVENT_PHASE(ptr)); - PRINT_ERR("TAG %d CMD %d\n", ptr->last_event.tag, ptr->last_event.cmd); - ret++; - } - if (ptr->timeout_cnt != 0) - { - PRINT_ERR("QID %d TIMEOUTCNT %d\n", uwQueueID, ptr->timeout_cnt); - ret += ptr->timeout_cnt; - ptr->timeout_cnt = 0; - } - ptr = ptr->next; - } - - if (ret) - return 1; - - return 0; -#else - return 0; -#endif -} -#endif // (CMSIS_OS_VER == 1) -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: CMSIS Interface V1.0 + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "cmsis_os.h" +#include "securec.h" +#include "los_event.h" +#include "los_membox.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 "los_sched_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#if (LOSCFG_CMSIS_VERSION == 1) + +#define PRIORITY_WIN 4 + +INT32 osKernelRunning(void) +{ + UINT32 cpuID = ArchCurrCpuid(); + return (INT32)(g_taskScheduled & (1U << cpuID)); +} + +/* Start the RTOS Kernel with executing the specified thread */ +osStatus osKernelStart(void) +{ + OsStart(); + return osOK; +} + +UINT32 osKernelSysTick(void) +{ + return (UINT32)g_tickCount[0]; +} + +osStatus osKernelInitialize(void) +{ + UINT32 ret; + + ret = LOS_KernelInit(); + if (ret != LOS_OK) { + return osErrorOS; + } + + return osOK; +} + +/* Create a thread and add it to Active Threads and set it to state READY */ +osThreadId osThreadCreate(const osThreadDef_t *threadDef, void *argument) +{ + osThreadId taskCb; + TSK_INIT_PARAM_S taskInitParam; + UINT32 taskHandle; + UINT32 ret; + if ((threadDef == NULL) || + (threadDef->pthread == NULL) || + (threadDef->tpriority < osPriorityIdle) || + (threadDef->tpriority > osPriorityRealtime)) { + return (osThreadId)NULL; + } + + (VOID)memset_s(&taskInitParam, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)threadDef->pthread; + taskInitParam.uwStackSize = threadDef->stacksize; + taskInitParam.pcName = threadDef->name; + taskInitParam.auwArgs[0] = (UINT32)(UINTPTR)argument; + taskInitParam.usTaskPrio = (UINT16)(PRIORITY_WIN - threadDef->tpriority); /* 1~7 */ + taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED; /* the cmsis task is detached, the task can deleteself */ + + ret = LOS_TaskCreate(&taskHandle, &taskInitParam); + if (ret != LOS_OK) { + return (osThreadId)NULL; + } + + taskCb = (osThreadId)&g_taskCBArray[taskHandle]; + + return taskCb; +} + +#if (LOSCFG_KERNEL_USERSPACE == YES) +osThreadId osUsrThreadCreate(const osThreadDef_t *thread_def, VOID *stack_pointer, UINT32 stack_size, VOID *argument) +{ + TSK_INIT_PARAM_S taskInitParam; + UINT32 taskHandle; + UINT32 ret; + if ((threadDef == NULL) || + (threadDef->pthread == NULL) || + (threadDef->tpriority < osPriorityIdle) || + (threadDef->tpriority > osPriorityRealtime)) { + return (osThreadId)NULL; + } + + (VOID)memset_s(&taskInitParam, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)thread_def->pthread; + taskInitParam.uwStackSize = thread_def->stacksize; + taskInitParam.pcName = thread_def->name; + taskInitParam.uwArg = (UINT32)argument; + taskInitParam.usTaskPrio = (UINT16)(PRIORITY_WIN - thread_def->tpriority); /* 1~7 */ + taskInitParam.uwResved = OS_TASK_STATUS_USERSPACE; + taskInitParam.pUserSP = stack_pointer; + taskInitParam.uwUserStackSize = stack_size; + + ret = LOS_TaskCreate(&taskHandle, &taskInitParam); + if (ret != LOS_OK) { + return (osThreadId)NULL; + } + + return (osThreadId)&g_taskCBArray[taskHandle]; +} +#endif + +/* Return the thread ID of the current running thread */ +osThreadId osThreadGetId(void) +{ + return (osThreadId)g_runTask; +} + +UINT32 osThreadGetPId(osThreadId threadId) +{ + return ((LosTaskCB *)threadId)->taskID; +} + +/* Terminate execution of a thread and remove it from ActiveThreads */ +osStatus osThreadTerminate(osThreadId threadId) +{ + UINT32 ret; + + if (threadId == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + ret = LOS_TaskDelete(((LosTaskCB *)threadId)->taskID); + if (ret == LOS_OK) { + return osOK; + } else { + return osErrorOS; + } +} + +/* Pass control to next thread that is in state READY */ +osStatus osThreadYield(void) +{ + UINT32 ret; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + ret = LOS_TaskYield(); + if (ret == LOS_OK) { + return osOK; + } else { + return osErrorOS; + } +} + +osStatus osThreadSetPriority(osThreadId threadId, osPriority priority) +{ + UINT32 ret; + UINT16 priorityTemp; + + if (threadId == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { + return osErrorPriority; + } + + priorityTemp = (UINT16)(PRIORITY_WIN - priority); + + ret = LOS_TaskPriSet(((LosTaskCB *)threadId)->taskID, priorityTemp); + if (ret == LOS_OK) { + return osOK; + } else { + return osErrorOS; + } +} + +osPriority osThreadGetPriority(osThreadId threadId) +{ + UINT16 priorityTemp; + INT16 priorityRet; + + if (threadId == NULL) { + return osPriorityError; + } + + priorityTemp = LOS_TaskPriGet(((LosTaskCB *)threadId)->taskID); + + priorityRet = (INT16)(PRIORITY_WIN - (INT32)priorityTemp); + if ((priorityRet < osPriorityIdle) || (priorityRet > osPriorityRealtime)) { + return osPriorityError; + } + + return (osPriority)priorityRet; +} + +#if (LOSCFG_KERNEL_USERSPACE == YES) +osStatus osThreadSelfSuspend(void) +{ + UINT32 taskHandle = ((LosTaskCB *)g_runTask)->taskID; + if (LOS_TaskSuspend(taskHandle) == LOS_OK) { + return osOK; + } else { + return osErrorOS; + } +} + +osStatus osThreadResume(osThreadId threadId) +{ + UINT32 ret; + UINT32 taskHandle = osThreadGetPId(threadId); + ret = LOS_TaskResume(taskHandle); + if (ret == LOS_OK) { + return osOK; + } else { + return osErrorOS; + } +} +#endif + +osSemaphoreId osBinarySemaphoreCreate(const osSemaphoreDef_t *semaphoreDef, INT32 count) +{ +#if (LOSCFG_BASE_IPC_SEM == YES) + UINT32 ret; + UINT32 *semHandle = NULL; + LosSemCB *semCreated = NULL; + + if ((semaphoreDef == NULL) || (count > OS_NULL_SHORT) || (count < 0)) { + return (osSemaphoreId)NULL; + } + + semHandle = (UINT32 *)(UINTPTR)(semaphoreDef->puwSemHandle); + if (semHandle == NULL) { + return (osSemaphoreId)NULL; + } + ret = LOS_BinarySemCreate((UINT16)count, semHandle); + if (ret == LOS_OK) { + semCreated = GET_SEM(*semHandle); + return semCreated; + } else { + return (osSemaphoreId)NULL; + } +#endif +} + +osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphoreDef, INT32 count) +{ +#if (LOSCFG_BASE_IPC_SEM == YES) + UINT32 ret; + UINT32 *semHandle = NULL; + + if ((semaphoreDef == NULL) || (count > OS_NULL_SHORT) || (count < 0)) { + return (osSemaphoreId)NULL; + } + + semHandle = (UINT32 *)(UINTPTR)(semaphoreDef->puwSemHandle); + ret = LOS_SemCreate((UINT16)count, semHandle); + if (ret == LOS_OK) { + return GET_SEM(*semHandle); + } else { + return NULL; + } +#endif +} + +/* + * Wait until a Semaphore becomes available + * return numbers of available tokens, or -1 in case of incorrect parameters. + */ +INT32 osSemaphoreWait(osSemaphoreId semaphoreId, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_SEM == YES) + UINT32 ret; + UINT32 semId; + + if (semaphoreId == NULL) { + return -1; + } + + if (OS_INT_ACTIVE) { + return -1; + } + + semId = ((LosSemCB *)semaphoreId)->semID; + + ret = LOS_SemPend(semId, LOS_MS2Tick(millisec)); + if (ret == LOS_OK) { + return ((LosSemCB *)semaphoreId)->semCount; + } else { + return -1; + } +#else + (VOID)semaphoreId; + (VOID)millisec; + return -1; +#endif +} + +/* + * Release a Semaphore + * osOK: the semaphore has been released. + * osErrorResource: all tokens have already been released. + * osErrorParameter: the parameter semaphore_id is incorrect. + */ +osStatus osSemaphoreRelease(osSemaphoreId semaphoreId) +{ +#if (LOSCFG_BASE_IPC_SEM == YES) + UINT32 ret; + UINT32 semId; + + if (semaphoreId == NULL) { + return osErrorParameter; + } + + semId = ((LosSemCB *)semaphoreId)->semID; + ret = LOS_SemPost(semId); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +#else + (VOID)semaphoreId; + return osErrorParameter; +#endif +} + +/* + * osOK: the semaphore object has been deleted. + * osErrorISR: osSemaphoreDelete cannot be called from interrupt service routines. + * osErrorResource: the semaphore object could not be deleted. + * osErrorParameter: the parameter semaphore_id is incorrect. + */ +osStatus osSemaphoreDelete(osSemaphoreId semaphoreId) +{ +#if (LOSCFG_BASE_IPC_SEM == YES) + UINT32 ret; + UINT32 semId; + + if (semaphoreId == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + semId = ((LosSemCB *)semaphoreId)->semID; + ret = LOS_SemDelete(semId); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +#else + (VOID)semaphoreId; + return osErrorParameter; +#endif +} + +/* + * Create and Initialize a Mutex object. + * param[in] mutex_def mutex definition referenced with \ref osMutex. + * return mutex ID for reference by other functions or NULL in case of error. + * note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. + */ +osMutexId osMutexCreate(const osMutexDef_t *mutexDef) +{ +#if (LOSCFG_BASE_IPC_MUX == YES) + UINT32 ret; + UINT32 *muxHandle = NULL; + + if (mutexDef == NULL) { + return NULL; + } + + muxHandle = (UINT32 *)(UINTPTR)(mutexDef->puwMuxHandle); + if (muxHandle == NULL) { + return NULL; + } + ret = LOS_MuxCreate(muxHandle); + if (ret == LOS_OK) { + return GET_MUX(*muxHandle); + } else { + return NULL; + } +#else + (VOID)mutexDef; + return NULL; +#endif +} + +/* + * Wait until a Mutex becomes available. + * param[in] mutex_id mutex ID obtained by \ref osMutexCreate. + * param[in] millisec timeout value or 0 in case of no time-out. + * return status code that indicates the execution status of the function. + * note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. + * osOK: the mutex has been obtain. + * osErrorTimeoutResource: the mutex could not be obtained in the given time. + * osErrorResource: the mutex could not be obtained when no timeout was specified. + * osErrorParameter: the parameter mutex_id is incorrect. + * osErrorISR: osMutexWait cannot be called from interrupt service routines. + */ +osStatus osMutexWait(osMutexId mutexId, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_MUX == YES) + UINT32 ret; + UINT32 mutId; + + if (mutexId == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + mutId = ((LosMuxCB*)mutexId)->muxID; + + ret = LOS_MuxPend(mutId, LOS_MS2Tick(millisec)); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_MUX_TIMEOUT) { + return osErrorTimeoutResource; + } else if (ret == LOS_ERRNO_MUX_UNAVAILABLE) { + return osErrorResource; + } else if (ret == LOS_ERRNO_MUX_PEND_INTERR) { + return osErrorISR; + } else { + return osErrorParameter; + } +#else + (VOID)mutexId; + (VOID)millisec; + return osErrorParameter; +#endif +} + +/* + * Release a Mutex that was obtained by \ref osMutexWait. + * param[in] mutex_id mutex ID obtained by \ref osMutexCreate. + * return status code that indicates the execution status of the function. + * note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. + * osOK: the mutex has been correctly released. + * osErrorResource: the mutex was not obtained before. + * osErrorParameter: the parameter mutex_id is incorrect. + * osErrorISR: osMutexRelease cannot be called from interrupt service routines. + */ +osStatus osMutexRelease(osMutexId mutexId) +{ +#if (LOSCFG_BASE_IPC_MUX == YES) + UINT32 ret; + UINT32 mutId; + + if (mutexId == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + mutId = ((LosMuxCB*)mutexId)->muxID; + ret = LOS_MuxPost(mutId); + if (ret == LOS_OK) { + return osOK; + } else { + return osErrorResource; + } +#else + (VOID)mutexId; + return osErrorParameter; +#endif +} + +/* + * Delete a Mutex that was created by \ref osMutexCreate. + * param[in] mutex_id mutex ID obtained by \ref osMutexCreate. + * return status code that indicates the execution status of the function. + * note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. + * osOK: the mutex object has been deleted. + * osErrorISR: osMutexDelete cannot be called from interrupt service routines. + * osErrorResource: all tokens have already been released. + * osErrorParameter: the parameter mutex_id is incorrect. + */ +osStatus osMutexDelete(osMutexId mutexId) +{ +#if (LOSCFG_BASE_IPC_MUX == YES) + UINT32 ret; + UINT32 mutId; + + if (mutexId == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + mutId = ((LosMuxCB*)mutexId)->muxID; + ret = LOS_MuxDelete(mutId); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_MUX_INVALID) { + return osErrorResource; + } else { + return osErrorParameter; + } +#else + (VOID)mutexId; + return osErrorParameter; +#endif +} + +osPoolId osPoolCreate(const osPoolDef_t *poolDef) +{ + UINT32 blkSize; + UINT32 boxSize; + UINT32 ret; + + if ((poolDef == NULL) || + (poolDef->pool_sz == 0) || + (poolDef->item_sz == 0) || + (poolDef->pool == NULL)) { + return (osPoolId)NULL; + } + + blkSize = (poolDef->item_sz + 3) & (~3); /* 3:the number 3 is for align 4 bytes */ + boxSize = LOS_MEMBOX_SIZE(blkSize, poolDef->pool_sz); + + ret = LOS_MemboxInit(poolDef->pool, boxSize, blkSize); + if (ret != LOS_OK) { + return (osPoolId)NULL; + } + + return (osPoolId)(poolDef->pool); +} + +void *osPoolAlloc(osPoolId poolId) +{ + void *ptr = NULL; + + if (poolId == NULL) { + return NULL; + } + + ptr = LOS_MemboxAlloc(poolId); + + return ptr; +} + +void *osPoolCAlloc(osPoolId poolId) +{ + void *ptr = NULL; + + if (poolId == NULL) { + return NULL; + } + + ptr = LOS_MemboxAlloc(poolId); + if (ptr) { + LOS_MemboxClr(poolId, ptr); + } + + return ptr; +} + +osStatus osPoolFree(osPoolId poolId, void *block) +{ + UINT32 res; + + if (poolId == NULL) { + return osErrorParameter; + } + + res = LOS_MemboxFree(poolId, block); + if (res != 0) { + return osErrorValue; + } + + return osOK; +} + +STATIC_INLINE UINT32 osMessageCheckRet(UINT32 ret) +{ + if (ret == LOS_OK) { + ret = osOK; + } else if (ret == LOS_ERRNO_QUEUE_INVALID || ret == LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT) { + ret = osErrorParameter; + } else if (ret == LOS_ERRNO_QUEUE_TIMEOUT || ret == LOS_ERRNO_QUEUE_ISFULL) { + ret = osEventTimeout; + } else { + ret = osErrorOS; + } + return ret; +} + +osMessageQId osMessageCreate(osMessageQDef_t *queueDef, osThreadId threadId) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 queueId; + UINT32 ret; + + (void)(threadId); + if (queueDef == NULL) { + return (osMessageQId)NULL; + } + ret = LOS_QueueCreate((char *)NULL, (UINT16)(queueDef->queue_sz), &queueId, 0, (UINT16)(queueDef->item_sz)); + if (ret == LOS_OK) { + return (osMessageQId)GET_QUEUE_HANDLE(queueId); + } else { + return (osMessageQId)NULL; + } +#else + (VOID)queueDef; + (VOID)threadId; + return (osMessageQId)NULL; +#endif +} + +osStatus osMessagePutHead(const osMessageQId queueId, UINT32 info, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 ret; + ret = LOS_QueueWriteHead(MESSAGEQID_TO_QUEUEID(queueId), + (void *)(UINTPTR)info, sizeof(UINT32), LOS_MS2Tick(millisec)); + ret = osMessageCheckRet(ret); + return (osStatus)ret; +#else + (VOID)queueId; + (VOID)info; + (VOID)millisec; + return (osStatus)osErrorParameter; +#endif +} + +static UINT32 osMessagePutCheckRet(UINT32 ret) +{ + UINT32 result; + if (ret == LOS_OK) { + result = osOK; + } else if ((ret == LOS_ERRNO_QUEUE_INVALID) || (ret == LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT)) { + result = osErrorParameter; + } else if ((ret == LOS_ERRNO_QUEUE_TIMEOUT) || (ret == LOS_ERRNO_QUEUE_ISFULL)) { + result = osEventTimeout; + } else { + result = osErrorOS; + } + + return result; +} + +osStatus osMessagePut(const osMessageQId queueId, UINT32 info, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 ret; + if (queueId == NULL) { + return osErrorParameter; + } + +#if (LOSCFG_BASE_CORE_SWTMR == YES) + if (MESSAGEQID_TO_QUEUEID(queueId) == 0) { + return osErrorParameter; + } +#endif + + ret = LOS_QueueWrite(MESSAGEQID_TO_QUEUEID(queueId), + (void*)(UINTPTR)info, sizeof(UINT32), LOS_MS2Tick(millisec)); + ret = osMessagePutCheckRet(ret); + return (osStatus)ret; +#else + (VOID)queue_id; + (VOID)info; + (VOID)millisec; + return (osStatus)osErrorParameter; +#endif +} + +static UINT32 osMessageGetCheckRet(UINT32 ret) +{ + UINT32 result; + if (ret == LOS_OK) { + result = osEventMessage; + } else if ((ret == LOS_ERRNO_QUEUE_INVALID) || (ret == LOS_ERRNO_QUEUE_READ_IN_INTERRUPT)) { + result = osErrorParameter; + } else if ((ret == LOS_ERRNO_QUEUE_TIMEOUT) || (ret == LOS_ERRNO_QUEUE_ISEMPTY)) { + result = osEventTimeout; + } else { + result = osErrorOS; + } + + return result; +} + +/* Get a Message or Wait for a Message from a Queue */ +osEvent osMessageGet(osMessageQId queueId, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 ret; + osEvent retEvent; + + if (queueId == NULL) { + retEvent.status = osErrorParameter; + return retEvent; + } + (VOID)memset_s((VOID *)(&retEvent), sizeof(osEvent), 0, sizeof(osEvent)); + ret = LOS_QueueRead(MESSAGEQID_TO_QUEUEID(queueId), &(retEvent.value.v), sizeof(UINT32), LOS_MS2Tick(millisec)); + retEvent.status = osMessageGetCheckRet(ret); + + return retEvent; +#else + (VOID)queue_id; + (VOID)millisec; + osEvent retEvent; + retEvent.status = osErrorParameter; + return retEvent; +#endif +} + +/* Create and Initialize mail queue */ +osMailQId osMailCreate(osMailQDef_t *queueDef, osThreadId threadId) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 ret; + UINT32 queueId; + UINT32 blkSize; + UINT32 boxSize; + + (void)(threadId); + if (queueDef == NULL) { + return (osMailQId)NULL; + } + + if (!queueDef->pool) { + return (osMailQId)NULL; + } + + ret = LOS_QueueCreate((char *)NULL, (UINT16)(queueDef->queue_sz), &queueId, 0, sizeof(UINT32)); + if (ret == LOS_OK) { + *(UINT32 *)(UINTPTR)((void **)(UINTPTR)queueDef->pool) = (UINT32)(UINTPTR)(GET_QUEUE_HANDLE(queueId)); + blkSize = (queueDef->item_sz + 3) & (~3); /* 3:the number 3 is for align 4 bytes */ + boxSize = LOS_MEMBOX_SIZE(blkSize, queueDef->queue_sz); + + (void)LOS_MemboxInit(*(((void **)queueDef->pool) + 1), boxSize, blkSize); + return (osMailQId)queueDef->pool; + } + return (osMailQId)NULL; +#else + (VOID)queue_def; + (VOID)thread_id; + return (osMailQId)NULL; +#endif +} + +/* Allocate a memory block from a mail */ +void *osMailAlloc(osMailQId queueId, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + void *pool = NULL; + UINT32 id; + + if (queueId == NULL) { + return NULL; + } + + id = *((UINT32 *)(UINTPTR)((void **)(UINTPTR)queueId)); + pool = *((((void **)(UINTPTR)queueId) + 1)); + + return (void *)OsQueueMailAlloc(MESSAGEQID_TO_QUEUEID((UINTPTR)id), pool, LOS_MS2Tick(millisec)); +#else + (VOID)queueId; + (VOID)millisec; + return NULL; +#endif +} + +/* Allocate a memory block from a mail and set memory block to zero */ +void *osMailCAlloc(osMailQId queueId, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + void *mem = NULL; + OS_MEMBOX_S *pool = NULL; + + mem = osMailAlloc(queueId, millisec); + if (mem != NULL) { + pool = (OS_MEMBOX_S *)(*(((void **)(UINTPTR)queueId) + 1)); + (VOID)memset_s(mem, pool->uwBlkSize, 0, pool->uwBlkSize); + } + + return mem; +#else + (VOID)queue_id; + (VOID)millisec; + return NULL; +#endif +} + +/* Free a memory block from a mail */ +osStatus osMailFree(osMailQId queueId, void *mail) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + void *pool = NULL; + UINT32 id; + UINT32 ret; + + if (queueId == NULL) { + return osErrorParameter; + } + + id = *((UINT32 *)(UINTPTR)((void **)(UINTPTR)queueId)); + pool = *((((void **)(UINTPTR)queueId) + 1)); + + ret = OsQueueMailFree(MESSAGEQID_TO_QUEUEID((UINTPTR)id), pool, mail); + if (ret == LOS_ERRNO_QUEUE_MAIL_HANDLE_INVALID || ret == LOS_ERRNO_QUEUE_MAIL_PTR_INVALID) { + return osErrorParameter; + } else if (ret == LOS_ERRNO_QUEUE_MAIL_FREE_ERROR) { + return osErrorOS; + } + return osOK; +#else + (VOID)queue_id; + (VOID)mail; + return osErrorParameter; +#endif +} + +/* Put a mail to a queue Header */ +osStatus osMailPutHead(osMailQId queueId, const void *mail) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 id; + + if (queueId == NULL) { + return osErrorParameter; + } + + if (mail == NULL) { + return osErrorValue; + } + + id = *((UINT32 *)(UINTPTR)((void **)(UINTPTR)queueId)); + + return osMessagePutHead ((osMessageQId)(UINTPTR)id, (UINT32)(UINTPTR)mail, 0); +#else + (VOID)queue_id; + (VOID)mail; + return osErrorParameter; +#endif +} + +/* Put a mail to a queue */ +osStatus osMailPut(osMailQId queueId, void *mail) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 id; + + if (queueId == NULL) { + return osErrorParameter; + } + + if (mail == NULL) { + return osErrorValue; + } + + id = *((UINT32 *)(UINTPTR)((void **)(UINTPTR)queueId)); + + return osMessagePut ((osMessageQId)(UINTPTR)id, (UINT32)(UINTPTR)mail, 0); +#else + (VOID)queue_id; + (VOID)mail; + return osErrorParameter; +#endif +} + +/* Get a mail from a queue */ +osEvent osMailGet(osMailQId queueId, UINT32 millisec) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + UINT32 id; + osEvent ret; + + if (queueId == NULL) { + ret.status = osErrorParameter; + return ret; + } + + id = *((UINT32 *)(UINTPTR)((void **)(UINTPTR)queueId)); + ret = osMessageGet((osMessageQId)(UINTPTR)id, millisec); + if (ret.status == osEventMessage) { + ret.status = osEventMail; + } + return ret; +#else + (VOID)queue_id; + (VOID)millisec; + osEvent ret; + ret.status = osErrorParameter; + return ret; +#endif +} + +osStatus osMailClear(osMailQId queueId) +{ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + osEvent evt; + UINTPTR intSave; + intSave = LOS_IntLock(); + for (; ;) { + evt = osMailGet(queueId, 0); + if (evt.status == osEventMail) { + (VOID)osMailFree(queueId, evt.value.p); + } else if (evt.status == osEventTimeout) { + LOS_IntRestore(intSave); + return osOK; + } else { + LOS_IntRestore(intSave); + return evt.status; + } + } +#else + (VOID)queueId; + return osErrorParameter; +#endif +} + +INT32 osSignalSet(osThreadId threadId, INT32 signals) +{ + EVENT_CB_S sig; + UINT32 oldSig; + UINT32 ret; + UINTPTR intSave; + + if (threadId == NULL) { + return (INT32)0x80000000; + } + + if (((UINT32)signals) & (~((0x1 << osFeature_Signals) - 1))) { + return osErrorValue; + } + + intSave = LOS_IntLock(); + sig = ((LosTaskCB *)threadId)->event; + oldSig = sig.uwEventID; + if (sig.uwEventID == 0xFFFFFFFF) { + ret = LOS_EventInit(&(((LosTaskCB *)threadId)->event)); + if (ret != LOS_OK) { + LOS_IntRestore(intSave); + return osErrorOS; + } + } + LOS_IntRestore(intSave); + + ret = LOS_EventWrite(&(((LosTaskCB *)threadId)->event), (UINT32)signals); + if (ret != LOS_OK) { + return osErrorOS; + } + + return (INT32)oldSig; +} + +INT32 osSignalClear(osThreadId threadId, INT32 signals) +{ + EVENT_CB_S sig; + UINT32 oldSig; + UINT32 ret; + + if (threadId == NULL) { + return (INT32)0x80000000; + } + + if (((UINT32)signals) & (~((0x1 << osFeature_Signals) - 1))) { + return osErrorValue; + } + + sig = ((LosTaskCB *)threadId)->event; + oldSig = sig.uwEventID; + ret = LOS_EventClear(&(((LosTaskCB *)threadId)->event), ~(UINT32)signals); + if (ret != LOS_OK) { + return osErrorValue; + } + + return (INT32)oldSig; +} + +STATIC_INLINE VOID osSignalWaitRetCheck(UINT32 ret, osEvent *evt) +{ + evt->value.signals = 0; + if (ret == LOS_ERRNO_EVENT_READ_TIMEOUT) { + evt->status = osEventTimeout; + } else if (ret == 0) { + evt->status = osOK; + } else if ((ret == LOS_ERRNO_EVENT_PTR_NULL) || (ret == LOS_ERRNO_EVENT_EVENTMASK_INVALID) || + (ret == LOS_ERRNO_EVENT_READ_IN_LOCK) || (ret == LOS_ERRNO_EVENT_READ_IN_INTERRUPT)) { + evt->status = osErrorOS; + } else { + evt->status = osEventSignal; + evt->value.signals = (INT32)ret; + } +} + +osEvent osSignalWait(INT32 signals, UINT32 millisec) +{ + UINT32 ret; + UINTPTR intSave; + osEvent evt; + UINT32 flags = 0; + UINT32 timeOut; + EVENT_CB_S sig; + LosTaskCB *runTsk = NULL; + + if (OS_INT_ACTIVE) { + /* Not allowed in ISR */ + evt.status = osErrorISR; + return evt; + } + + if (((UINT32)signals) & (~((0x1 << osFeature_Signals) - 1))) { + evt.status = osErrorValue; + return evt; + } + + if (signals != 0) { + flags |= LOS_WAITMODE_AND; + } else { + signals = (INT32)(0xFFFFFFFF & ((0x1 << osFeature_Signals) - 1)); + flags |= LOS_WAITMODE_OR; + } + + timeOut = LOS_MS2Tick(millisec); + + intSave = LOS_IntLock(); + runTsk = (LosTaskCB *)g_runTask; + sig = (runTsk)->event; + if (sig.uwEventID == 0xFFFFFFFF) { + ret = LOS_EventInit(&(((LosTaskCB *)g_runTask)->event)); + if (ret != LOS_OK) { + evt.status = osErrorOS; + LOS_IntRestore(intSave); + return evt; + } + } + LOS_IntRestore(intSave); + ret = LOS_EventRead(&(((LosTaskCB *)g_runTask)->event), + (UINT32)signals, flags | LOS_WAITMODE_CLR, timeOut); + + osSignalWaitRetCheck(ret, &evt); + + return evt; +} + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) +osTimerId osTimerExtCreate(const osTimerDef_t *timerDef, os_timer_type type, + void *argument, os_timer_rouses_type rouses, os_timer_align_type sensitive) +{ + SWTMR_CTRL_S *swTmr = NULL; +#if (LOSCFG_BASE_CORE_SWTMR == YES) + UINT32 ret; + UINT16 swTmrId; + + if ((timerDef == NULL) || + (timerDef->ptimer == NULL) || + (timerDef->default_interval == 0) || + ((type != osTimerOnce) && (type != osTimerPeriodic))) { + return NULL; + } + + ret = LOS_SwtmrCreate(timerDef->default_interval, type, + (SWTMR_PROC_FUNC)(timerDef->ptimer), + &swTmrId, (UINT32)(UINTPTR)argument, rouses, sensitive); + if (ret != LOS_OK) { + return NULL; + } + + swTmr = OS_SWT_FROM_SID(swTmrId); +#else + (VOID)timerDef; + (VOID)type; + (VOID)argument; + (VOID)rouses; + (VOID)sensitive; +#endif + return swTmr; +} +#endif + +osTimerId osTimerCreate(const osTimerDef_t *timerDef, os_timer_type type, void *argument) +{ + SWTMR_CTRL_S *swTmr = NULL; +#if (LOSCFG_BASE_CORE_SWTMR == YES) + UINT32 ret; + UINT16 swTmrId; + + if ((timerDef == NULL) || + (timerDef->ptimer == NULL) || + (timerDef->default_interval == 0) || + ((type != osTimerOnce) && (type != osTimerPeriodic) && (type != osTimerDelay))) { + return (osTimerId)NULL; + } + +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + ret = LOS_SwtmrCreate(timerDef->default_interval, type, + (SWTMR_PROC_FUNC)(timerDef->ptimer), + &swTmrId, (UINT32)(UINTPTR)argument, + osTimerRousesAllow, osTimerAlignIgnore); +#else + ret = LOS_SwtmrCreate(timerDef->default_interval, type, + (SWTMR_PROC_FUNC)(timerDef->ptimer), + &swTmrId, (UINT32)(UINTPTR)argument); +#endif + if (ret != LOS_OK) { + return (osTimerId)NULL; + } + + swTmr = OS_SWT_FROM_SID(swTmrId); +#else + (VOID)timerDef; + (VOID)type; + (VOID)argument; +#endif + return swTmr; +} + +osStatus osTimerStart(osTimerId timerId, UINT32 millisec) +{ +#if (LOSCFG_BASE_CORE_SWTMR == YES) + SWTMR_CTRL_S *swTmr = NULL; + UINT32 interval; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + swTmr = (SWTMR_CTRL_S *)timerId; + if (swTmr == NULL) { + return osErrorParameter; + } + + interval = LOS_MS2Tick(millisec); + if (interval == 0) { + return osErrorValue; + } + + swTmr->uwInterval = interval; + swTmr->uwExpiry = interval; + if (LOS_SwtmrStart(swTmr->usTimerID)) { + return osErrorResource; + } +#else + (VOID)timerId; + (VOID)millisec; +#endif + return osOK; +} + +osStatus osTimerStop(osTimerId timerId) +{ +#if (LOSCFG_BASE_CORE_SWTMR == YES) + SWTMR_CTRL_S *swTmr = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + swTmr = (SWTMR_CTRL_S *)timerId; + if (swTmr == NULL) { + return osErrorParameter; + } + + if (LOS_SwtmrStop(swTmr->usTimerID)) { + return osErrorResource; + } +#else + (VOID)timerId; +#endif + return osOK; +} + +osStatus osTimerRestart(osTimerId timerId, UINT32 millisec, UINT8 strict) +{ +#if (LOSCFG_BASE_CORE_SWTMR == YES) + osStatus status; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + status = osTimerStop(timerId); + if (strict && (status != osOK)) { + return status; + } + + status = osTimerStart(timerId, millisec); + if (status != osOK) { + return status; + } +#else + (VOID)timerId; + (VOID)millisec; + (VOID)strict; +#endif + return osOK; +} + +osStatus osTimerDelete(osTimerId timerId) +{ +#if (LOSCFG_BASE_CORE_SWTMR == YES) + SWTMR_CTRL_S *swTmr = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + swTmr = (SWTMR_CTRL_S *)timerId; + if (swTmr == NULL) { + return osErrorParameter; + } + + if (LOS_SwtmrDelete(swTmr->usTimerID)) { + return osErrorResource; + } +#else + (VOID)timerId; +#endif + return osOK; +} + +osStatus osDelay(UINT32 millisec) +{ + UINT32 interval; + UINT32 ret; + Percpu *perCpu = OsPercpuGet(); + UINT32 idleTaskID = perCpu->idleTaskID; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (millisec == 0) { + return osOK; + } + + /* check if in idle we use udelay instead */ + if (idleTaskID == LOS_CurTaskIDGet()) { + PRINT_ERR("Idle Task Do Not Support Delay!\n"); + return osOK; + } + + interval = LOS_MS2Tick(millisec); + ret = LOS_TaskDelay(interval); + if (ret == LOS_OK) { + return osEventTimeout; + } else { + return osErrorResource; + } +} + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) +osEvent osWait(UINT32 millisec) +{ + osEvent evt; + UINT32 interval; + UINT32 ret; + + if (OS_INT_ACTIVE) { + evt.status = osErrorISR; + return evt; + } + + if (millisec == 0) { + evt.status = osOK; + return evt; + } + + interval = LOS_MS2Tick(millisec); + ret = LOS_TaskDelay(interval); + if (ret == LOS_OK) { + evt.status = osEventTimeout; + } else { + evt.status = osErrorResource; + } + + return evt; +} +#endif + +#if (LOSCFG_COMPAT_CMSIS_FW == YES) +fwMailQId g_fwMailQList = (fwMailQId)NULL; +UINT32 g_maxEventTime = 0x400; +#endif + +fwMailQId fwMailCreate(fwMailQDef_t *queueDef, osThreadId threadId) +{ + if (queueDef == NULL) { + return (fwMailQId)NULL; + } +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + /* add mailQ to list */ + if (queueDef->queue_id == NULL) { + return (fwMailQId)NULL; + } + (VOID)osMailCreate(queueDef->queue_id, threadId); + queueDef->next = (struct fw_MailQ_def *)g_fwMailQList; + g_fwMailQList = (fwMailQId)queueDef; + return (fwMailQId)queueDef; +#else + return osMailCreate(queueDef, threadId); +#endif +} + +VOID *fwMailAlloc(fwMailQId queueId, UINT32 millisec, UINT8 tag, UINT8 cmd) +{ + VOID *mem = NULL; + + if (queueId == NULL) { + return NULL; + } + +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + osMailQDef_t *pQueueId = ((fwMailQDef_t *)queueId)->queue_id; + if (pQueueId == NULL) { + return NULL; + } + + if (pQueueId->pool == NULL) { + return NULL; + } + mem = osMailAlloc((osMailQId)(pQueueId)->pool, millisec); +#else + mem = osMailAlloc(queueId, millisec); +#endif + if (mem != NULL) { + ((fw_event_t*)mem)->cmd = cmd; + ((fw_event_t*)mem)->tag = tag; + } + + return mem; +} + +VOID *fwMailCAlloc(fwMailQId queueId, UINT32 millisec, UINT8 tag, UINT8 cmd) +{ + VOID *mem = NULL; + + if (queueId == NULL) { + return NULL; + } +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + osMailQDef_t *pQueueId = ((fwMailQDef_t *)queueId)->queue_id; + if (pQueueId == NULL) { + return NULL; + } + if (pQueueId->pool == NULL) { + return NULL; + } + mem = osMailCAlloc((osMailQId)(pQueueId)->pool, millisec); +#else + mem = osMailCAlloc(queue_id, millisec); +#endif + if (mem != NULL) { + ((fw_event_t*)mem)->cmd = cmd; + ((fw_event_t*)mem)->tag = tag; + } + + return mem; +} + +osStatus fwMailFree(fwMailQId queueId, VOID *mail) +{ + if (queueId == NULL) { + return osErrorParameter; + } + +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + osMailQDef_t *pQueueId = ((fwMailQDef_t *)queueId)->queue_id; + if (pQueueId == NULL) { + return osErrorParameter; + } + + if (pQueueId->pool == NULL) { + return osErrorParameter; + } + + return osMailFree((osMailQId)(pQueueId)->pool, mail); +#else + return osMailFree(queueId, mail); +#endif +} + +osStatus fwMailPut(fwMailQId queueId, VOID *mail) +{ + if (queueId == NULL) { + return osErrorParameter; + } + +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + osMailQDef_t *pQueueId = ((fwMailQDef_t *)queueId)->queue_id; + if (pQueueId == NULL) { + return osErrorParameter; + } + + if (pQueueId->pool == NULL) { + return osErrorParameter; + } + return osMailPut((osMailQId)(pQueueId)->pool, mail); +#else + return osMailPut(queueId, mail); +#endif +} + +osEvent fwMailGet(fwMailQId queueId, UINT32 millisec) +{ + osEvent evt; +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + UINT32 maxTime; + VOID *pool = NULL; + UINT32 id; +#endif + + evt.status = osErrorParameter; + if (queueId == NULL) { + return evt; + } +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + osMailQDef_t *pQueueId = ((fwMailQDef_t *)queueId)->queue_id; + if (pQueueId == NULL) { + return evt; + } + + if (pQueueId->pool == NULL) { + return evt; + } + + id = *((UINT32*)((VOID **)pool)); + maxTime = (GET_EVENT_MAXTIME(queueId) != 0) ? GET_EVENT_MAXTIME(queueId) : g_maxEventTime; + if ((((fwMailQDef_t *)queueId)->event_begin_time != 0) && + ((osKernelSysTick() - ((fwMailQDef_t *)queueId)->event_begin_time) > maxTime)) { + ((fwMailQDef_t *)queueId)->timeout_cnt++; + PRINT_ERR("[ERR] Get QID %d TIMEOUTCNT %d\n", id, ((fwMailQDef_t *)queueId)->timeout_cnt); + } + + ((fwMailQDef_t *)queueId)->event_begin_time = 0; + evt = osMailGet((osMailQId)((((fwMailQDef_t *)queueId)->queue_id)->pool), millisec); + if (evt.status == osEventMail) { + ((fwMailQDef_t *)queueId)->last_event = *(fw_event_t*)(evt.value.p); + ((fwMailQDef_t *)queueId)->event_begin_time = osKernelSysTick(); + } +#else + evt = osMailGet(queueId, millisec); +#endif + return evt; +} + +UINT32 fwMailQGetStatus(VOID) +{ +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + fwMailQDef_t *mailQueue = (fwMailQDef_t *)NULL; + VOID *pool = NULL; + UINT32 id; + UINT32 maxTime; + UINT32 currTick = osKernelSysTick(); + UINT32 ret = 0; + + mailQueue = (fwMailQDef_t *)g_fwMailQList; + while (mailQueue != NULL) { + maxTime = (GET_EVENT_MAXTIME(mailQueue) != 0) ? GET_EVENT_MAXTIME(mailQueue) : g_maxEventTime; + if (mailQueue->queue_id == NULL) { + return 0; + } + + pool = (mailQueue->queue_id)->pool; + if (pool == NULL) { + return 0; + } + + id = *((UINT32*)((VOID **)pool)); + if ((mailQueue->event_begin_time != 0) && ((currTick - mailQueue->event_begin_time) > maxTime)) { + mailQueue->timeout_cnt++; + PRINT_ERR("[ERR] QID %d OUTQUE %d Phase %d\n", id, mailQueue->event_begin_time, + GET_EVENT_PHASE(mailQueue)); + PRINT_ERR("TAG %d CMD %d\n", mailQueue->last_event.tag, mailQueue->last_event.cmd); + ret++; + } + if (mailQueue->timeout_cnt != 0) { + PRINT_ERR("QID %d TIMEOUTCNT %d\n", id, mailQueue->timeout_cnt); + ret += mailQueue->timeout_cnt; + mailQueue->timeout_cnt = 0; + } + mailQueue = mailQueue->next; + } + + return (ret > 0) ? 1 : 0; +#else + return 0; +#endif +} +#endif // (LOSCFG_CMSIS_VERSION == 1) +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/osdepends/liteos/cmsis/1.0/cmsis_os1.h b/osdepends/liteos/cmsis/1.0/cmsis_os1.h index ab7e71245..5d16a611e 100644 --- a/osdepends/liteos/cmsis/1.0/cmsis_os1.h +++ b/osdepends/liteos/cmsis/1.0/cmsis_os1.h @@ -1,885 +1,871 @@ -/* ---------------------------------------------------------------------- - * $Date: 5. February 2013 - * $Revision: V1.02 - * - * Project: CMSIS-RTOS API - * Title: cmsis_os.h template header file - * - * Version 0.02 - * Initial Proposal Phase - * Version 0.03 - * osKernelStart added, optional feature: main started as thread - * osSemaphores have standard behavior - * osTimerCreate does not start the timer, added osTimerStart - * osThreadPass is renamed to osThreadYield - * Version 1.01 - * Support for C++ interface - * - const attribute removed from the osXxxxDef_t typedef's - * - const attribute added to the osXxxxDef macros - * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete - * Added: osKernelInitialize - * Version 1.02 - * Control functions for short timeouts in microsecond resolution: - * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec - * Removed: osSignalGet - *---------------------------------------------------------------------------- - * - * Copyright (c) 2013 ARM LIMITED - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - 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. - * - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. - *---------------------------------------------------------------------------*/ - -/** -\page cmsis_os_h Header File Template: cmsis_os.h - -The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). -Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents -its implementation. - -The file cmsis_os.h contains: - - CMSIS-RTOS API function definitions - - struct definitions for parameters and return types - - status and priority values used by CMSIS-RTOS API functions - - macros for defining threads and other kernel objects - - -Name conventions and header file modifications - -All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. -Definitions that are prefixed \b os_ are not used in the application code but local to this header file. -All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. - -Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. -These definitions can be specific to the underlying RTOS kernel. - -Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer -compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. - - -Function calls from interrupt service routines - -The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): - - \ref osSignalSet - - \ref osSemaphoreRelease - - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree - - \ref osMessagePut, \ref osMessageGet - - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree - -Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called -from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. - -Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. -If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. - - -Define and reference object definitions - -With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file -that is used throughout a project as shown below: - -Header File -\code -#include // CMSIS RTOS header file - -// Thread definition -extern void thread_sample (void const *argument); // function prototype -osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); - -// Pool definition -osPoolDef(MyPool, 10, long); -\endcode - - -This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is -present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be -used throughout the whole project. - -Example -\code -#include "osObjects.h" // Definition of the CMSIS-RTOS objects -\endcode - -\code -#define osObjectExternal // Objects will be defined as external symbols -#include "osObjects.h" // Reference to the CMSIS-RTOS objects -\endcode - -*/ - -#ifndef _CMSIS_OS_H -#define _CMSIS_OS_H - -/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. -#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0]) - -/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. -#define osCMSIS_LOS 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0]) - -/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. -#define osKernelSystemId "LOS V1.0.0" ///< RTOS identification string - -/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. -#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available -#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available -#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available -#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available -#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread -#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available -#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available - -#include "los_typedef.h" -#include "los_config.h" -#include "string.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -// ==== Enumeration, structures, defines ==== - -/// Priority used for thread control. -/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. -typedef enum { - osPriorityIdle = -3, ///< priority: idle (lowest) - osPriorityLow = -2, ///< priority: low - osPriorityBelowNormal = -1, ///< priority: below normal - osPriorityNormal = 0, ///< priority: normal (default) - osPriorityAboveNormal = +1, ///< priority: above normal - osPriorityHigh = +2, ///< priority: high - osPriorityRealtime = +3, ///< priority: realtime (highest) - osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority -} osPriority; - -/// Timeout value. -/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. -#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value - -/// Status code values returned by CMSIS-RTOS functions. -/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. -typedef enum { - osOK = 0, ///< function completed; no error or event occurred. - osEventSignal = 0x08, ///< function completed; signal event occurred. - osEventMessage = 0x10, ///< function completed; message event occurred. - osEventMail = 0x20, ///< function completed; mail event occurred. - osEventTimeout = 0x40, ///< function completed; timeout occurred. - osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. - osErrorResource = 0x81, ///< resource not available: a specified resource was not available. - osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. - osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. - osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. - osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. - osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorValue = 0x86, ///< value of a parameter is out of range. - osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. - os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osStatus; - - -/// Timer type value for the timer definition. -/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. -typedef enum { - osTimerOnce = 0, ///< one-shot timer once - osTimerPeriodic = 1, ///< repeating timer - osTimerDelay = 2, ///< one-shot timer each time -} os_timer_type; - -typedef enum { - osTimerRousesIgnore = 0, ///< timer can't wakeup system - osTimerRousesAllow = 1 ///< timer can wakeup system -} os_timer_rouses_type; - -typedef enum { - osTimerAlignIgnore = 0, ///>> the following data type definitions may shall adapted towards a specific RTOS - -/// Thread ID identifies the thread (pointer to a thread control block). -/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. -typedef struct LOS_TASK_CB *osThreadId; - -/// Timer ID identifies the timer (pointer to a timer control block). -/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. -typedef struct tagSwTmrCtrl *osTimerId; - -/// Mutex ID identifies the mutex (pointer to a mutex control block). -/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. -typedef struct MUX_CB_S *osMutexId; - -/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. -typedef struct SEM_CB_S *osSemaphoreId; - -/// Pool ID identifies the memory pool (pointer to a memory pool control block). -/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_cb *osPoolId; - -/// Message ID identifies the message queue (pointer to a message queue control block). -/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_cb *osMessageQId; - -/// Mail ID identifies the mail queue (pointer to a mail queue control block). -/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_cb *osMailQId; - - -/// Thread Definition structure contains startup information of a thread. -/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_def { - char *name; - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - UINT32 instances; ///< maximum number of instances of that thread function - UINT32 stacksize; ///< stack size requirements in bytes; 0 is default stack size -} osThreadDef_t; - -/// Timer Definition structure contains timer parameters. -/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_def { - os_ptimer ptimer; ///< start address of a timer function - UINT32 default_interval; ///< time delay value of the timer. ms -} osTimerDef_t; - -/// Mutex Definition structure contains setup information for a mutex. -/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_def { - void *puwMuxHandle; // -} osMutexDef_t; - -/// Semaphore Definition structure contains setup information for a semaphore. -/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_def { - void* puwSemHandle; -} osSemaphoreDef_t; - -/// Definition structure for memory block allocation. -/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_def { - UINT32 pool_sz; ///< number of items (elements) in the pool - UINT32 item_sz; ///< size of an item - void *pool; ///< pointer to memory for pool -} osPoolDef_t; - -/// Definition structure for message queue. -/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_def { - UINT32 queue_sz; ///< number of elements in the queue - UINT32 item_sz; ///< size of an item - void *pool; ///< memory array for messages -} osMessageQDef_t; - -/// Definition structure for mail queue. -/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_def { - UINT32 queue_sz; ///< number of elements in the queue - UINT32 item_sz; ///< size of an item - void *pool; ///< memory array for mail -} osMailQDef_t; - -/// Event structure contains detailed information about an event. -/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. -/// However the struct may be extended at the end. -typedef struct { - osStatus status; ///< status code: event or error information - union { - UINT32 v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - INT32 signals; ///< signal flags - } value; ///< event value - union { - osMailQId mail_id; ///< mail id obtained by \ref osMailCreate - osMessageQId message_id; ///< message id obtained by \ref osMessageCreate - } def; ///< event definition -} osEvent; - - -// ==== Kernel Control Functions ==== - -/// Initialize the RTOS Kernel for creating objects. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. -osStatus osKernelInitialize (void); - -/// Start the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. -osStatus osKernelStart (void); - -/// Check if the RTOS kernel is already started. -/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. -/// \return 0 RTOS is not started, 1 RTOS is started. -INT32 osKernelRunning(void); - -#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available - -/// Get the RTOS kernel system timer counter -/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS. -/// \return RTOS kernel system timer as 32-bit value -UINT32 osKernelSysTick (void); - -/// The RTOS kernel system timer frequency in Hz -/// \note Reflects the system timer setting and is typically defined in a configuration file. -#define osKernelSysTickFrequency 100000000 - -/// Convert a microseconds value to a RTOS kernel system timer value. -/// \param microsec time value in microseconds. -/// \return time value normalized to the \ref osKernelSysTickFrequency -#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) - -#endif // System Timer available - -// ==== Thread Management ==== - -/// Create a Thread Definition with function, priority, and stack requirements. -/// \param name name of the thread function. -/// \param priority initial priority of the thread function. -/// \param instances number of possible thread instances. -/// \param stacksz stack size (in bytes) requirements for the thread function. -/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, instances, stacksz) \ -extern const osThreadDef_t os_thread_def_##name -#else // define the object -#define osThreadDef(name, priority, instances, stacksz) \ -const osThreadDef_t os_thread_def_##name = \ -{ #name,(name), (priority), (instances), (stacksz) } -#endif - -/// Access a Thread definition. -/// \param name name of the thread definition object. -/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osThread(name) \ -&os_thread_def_##name - -/// Create a thread and add it to Active Threads and set it to state READY. -/// \param[in] thread_def thread definition referenced with \ref osThread. -/// \param[in] argument pointer that is passed to the thread function as start argument. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. -osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); - -/// Return the thread ID of the current running thread. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. -osThreadId osThreadGetId (void); - -/// Terminate execution of a thread and remove it from Active Threads. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. -osStatus osThreadTerminate (osThreadId thread_id); - -/// Pass control to next thread that is in state \b READY. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. -osStatus osThreadYield (void); - -/// Change priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] priority new priority value for the thread function. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); - -/// Get current priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return current priority value of the thread function. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. -osPriority osThreadGetPriority (osThreadId thread_id); - - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] millisec time delay value -/// \return status code that indicates the execution status of the function. -osStatus osDelay (UINT32 millisec); - -#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available - -/// Wait for Signal, Message, Mail, or Timeout. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains signal, message, or mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. -osEvent osWait (UINT32 millisec); - -#endif // Generic Wait available - - -// ==== Timer Management Functions ==== -/// Define a Timer object. -/// \param name name of the timer object. -/// \param function name of the timer call back function. -/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osTimerDefaultInterval 1 -#if defined (osObjectsExternal) // object is external -#define osTimerDef(name, function) \ -extern const osTimerDef_t os_timer_def_##name -#else // define the object -#define osTimerDef(name, function) \ -const osTimerDef_t os_timer_def_##name = \ -{ (function), osTimerDefaultInterval } -#endif - -/// Access a Timer definition. -/// \param name name of the timer object. -/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osTimer(name) \ -&os_timer_def_##name - -/// Create a timer. -/// \param[in] timer_def timer object referenced with \ref osTimer. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. -/// \return timer ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \param[in] millisec time delay value of the timer. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. -osStatus osTimerStart (osTimerId timer_id, UINT32 millisec); - -/// Stop the timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. -osStatus osTimerStop (osTimerId timer_id); - -/// Restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \param[in] millisec time delay value of the timer. -/// \param[in] strict ignore close err when not strict mode. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerRestart shall be consistent in every CMSIS-RTOS. -osStatus osTimerRestart (osTimerId timer_id, UINT32 millisec, UINT8 strict); - -/// Delete a timer that was created by \ref osTimerCreate. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. -osStatus osTimerDelete (osTimerId timer_id); - -osTimerId osTimerExtCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument, os_timer_rouses_type ucRouses, os_timer_align_type ucSensitive); - - -// ==== Signal Management ==== - -/// Set the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that should be set. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. -INT32 osSignalSet (osThreadId thread_id, INT32 signals); - -/// Clear the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that shall be cleared. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. -INT32 osSignalClear (osThreadId thread_id, INT32 signals); - -/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. -/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event flag information or error code. -/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. -osEvent osSignalWait (INT32 signals, UINT32 millisec); - - -// ==== Mutex Management ==== - -/// Define a Mutex. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMutexDef(name) \ -extern const osMutexDef_t os_mutex_def_##name -#else // define the object -#define osMutexDef(name) \ -UINT32 puwMuxHandle_##name; \ -const osMutexDef_t os_mutex_def_##name = { &puwMuxHandle_##name } -#endif - -/// Access a Mutex definition. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMutex(name) \ -&os_mutex_def_##name - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (const osMutexDef_t *mutex_def); - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. -osStatus osMutexWait (osMutexId mutex_id, UINT32 millisec); - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. -osStatus osMutexRelease (osMutexId mutex_id); - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. -osStatus osMutexDelete (osMutexId mutex_id); - - -// ==== Semaphore Management Functions ==== - -#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available - -/// Define a Semaphore object. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osSemaphoreDef(name) \ -extern const osSemaphoreDef_t os_semaphore_def_##name -#else // define the object -#define osSemaphoreDef(name) \ -UINT32 puwSemHandle_##name; \ -const osSemaphoreDef_t os_semaphore_def_##name = { &puwSemHandle_##name } -#endif - -/// Access a Semaphore definition. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osSemaphore(name) \ -&os_semaphore_def_##name - -/// Create and Initialize a Semaphore object used for managing resources. -/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. -/// \param[in] count number of available resources. -/// \return semaphore ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. -osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, INT32 count); -osSemaphoreId osBinarySemaphoreCreate (const osSemaphoreDef_t *semaphore_def, INT32 count); - -/// Wait until a Semaphore token becomes available. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -INT32 osSemaphoreWait (osSemaphoreId semaphore_id, UINT32 millisec); - -/// Release a Semaphore token. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); - -/// Delete a Semaphore that was created by \ref osSemaphoreCreate. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); - -#endif // Semaphore available - - -// ==== Memory Pool Management Functions ==== - -#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available - -/// \brief Define a Memory Pool. -/// \param name name of the memory pool. -/// \param no maximum number of blocks (objects) in the memory pool. -/// \param type data type of a single block (object). -/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osPoolDef(name, no, type) \ -extern const osPoolDef_t os_pool_def_##name -#else // define the object -#define osPoolDef(name, no, type) \ -UINT32 os_pool_m_##name[3]; \ -const osPoolDef_t os_pool_def_##name = \ -{ (no), sizeof(type), (os_pool_m_##name) } -#endif - -/// \brief Access a Memory Pool definition. -/// \param name name of the memory pool -/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osPool(name) \ -&os_pool_def_##name - -/// Create and Initialize a memory pool. -/// \param[in] pool_def memory pool definition referenced with \ref osPool. -/// \return memory pool ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. -osPoolId osPoolCreate (const osPoolDef_t *pool_def); - -/// Allocate a memory block from a memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolAlloc (osPoolId pool_id); - -/// Allocate a memory block from a memory pool and set memory block to zero. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolCAlloc (osPoolId pool_id); - -/// Return an allocated memory block back to a specific memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \param[in] block address of the allocated memory block that is returned to the memory pool. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. -osStatus osPoolFree (osPoolId pool_id, void *block); - -#endif // Memory Pool Management available - - -// ==== Message Queue Management Functions ==== - -#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available - -/// \brief Create a Message Queue Definition. -/// \param name name of the queue. -/// \param queue_sz maximum number of messages in the queue. -/// \param type data type of a single message element (for debugger). -/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMessageQDef(name, queue_sz, type) \ -extern const osMessageQDef_t os_messageQ_def_##name -#else // define the object -#define osMessageQDef(name, queue_sz, type) \ -osMessageQDef_t os_messageQ_def_##name = \ -{ queue_sz, sizeof(UINT32), NULL } -#endif - -/// \brief Access a Message Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMessageQ(name) \ -&os_messageQ_def_##name - -/// Create and Initialize a Message Queue. -/// \param[in] queue_def queue definition referenced with \ref osMessageQ. -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return message queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. -osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); - -/// Put a Message to a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] info message information. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. -osStatus osMessagePut (osMessageQId queue_id, UINT32 info, UINT32 millisec); - -/// Get a Message or Wait for a Message from a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event information that includes status code. -/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. -osEvent osMessageGet (osMessageQId queue_id, UINT32 millisec); - -#endif // Message Queues available - - -// ==== Mail Queue Management Functions ==== - -#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available - -/// \brief Create a Mail Queue Definition. -/// \param name name of the queue -/// \param queue_sz maximum number of messages in queue -/// \param type data type of a single message element -/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMailQDef(name, queue_sz, type) \ -extern const osMailQDef_t os_mailQ_def_##name -#else // define the object -#define osMailQDef(name, queue_sz, type) \ -UINT32 os_mailQ_m_##name[3]; \ -UINT32 os_mailQ_p_##name[2] = {(0), (UINT32)(os_mailQ_m_##name)}; \ -osMailQDef_t os_mailQ_def_##name = \ -{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } -#endif - -/// \brief Access a Mail Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMailQ(name) \ -&os_mailQ_def_##name - -/// Create and Initialize mail queue. -/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return mail queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. -osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); - -/// Allocate a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. -void *osMailAlloc (osMailQId queue_id, UINT32 millisec); - -/// Allocate a memory block from a mail and set memory block to zero. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. -void *osMailCAlloc (osMailQId queue_id, UINT32 millisec); - -/// Put a mail to a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. -osStatus osMailPut (osMailQId queue_id, void *mail); - -/// Get a mail from a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. -osEvent osMailGet (osMailQId queue_id, UINT32 millisec); - -/// Free a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. -osStatus osMailFree (osMailQId queue_id, void *mail); - -#endif // Mail Queues available - -typedef struct fw_event_def -{ - UINT8 tag; - UINT8 cmd; - UINT16 option; /* Bits 0-5 indicate the message processing progress; bits 6-15 indicate the timeout period for processing this command. */ -}fw_event_t; - -#if (LOSCFG_COMPAT_CMSIS_FW == YES) - -typedef struct fw_MailQ_def{ - UINT32 event_begin_time; /* Last time when the queue was successfully read. */ - UINT32 timeout_cnt; /* Number of times the processing of messages in the queue times out. */ - fw_event_t last_event; /* null indicates that no event is being processed or the previous event has been processed. */ - struct fw_MailQ_def *next; - osMailQDef_t *queue_id; -}fwMailQDef_t; - -typedef struct fwMailQDef_t *fwMailQId; -extern fwMailQId g_fwMailQList; - -extern UINT32 g_maxEventTime; /* Default maximum time for processing a single event. */ - -#define fwMailQDef(name, queue_sz, type) \ - osMailQDef(name, queue_sz, type); \ - fwMailQDef_t fw_mailQ_def_##name = \ - {0, 0, {0, 0, 0}, NULL, osMailQ(name)} - -#define fwMailQ(name) \ - &fw_mailQ_def_##name - - -#define SET_EVENT_PHASE(mailQ, phase) \ - (((fwMailQDef_t *)(mailQ))->last_event.option = (0xFFFFFFC0 & (((fwMailQDef_t *)(mailQ))->last_event.option)) | (0x3F & (phase))) - -#define GET_EVENT_PHASE(mailQ) \ - ((((fwMailQDef_t *)(mailQ))->last_event.option) & 0x3F) - -#define SET_EVENT_MAXTIME(mailQ, time) \ - ((((fwMailQDef_t *)(mailQ))->last_event.option) |= ((time) << 0x6)) - -#define GET_EVENT_MAXTIME(mailQ) \ - ((((fwMailQDef_t *)(mailQ))->last_event.option) >> 0x6) - -#else - -#define fwMailQDef(name, queue_sz, type) \ - osMailQDef(name, queue_sz, type) - -#define fwMailQ(name) \ - osMailQ(name) - -#define fwMailQId osMailQId -#define fwMailQDef_t osMailQDef_t - -#define SET_EVENT_PHASE(event, phase) -#define GET_EVENT_PHASE(event) -#define SET_EVENT_MAXTIME(event, time) -#define GET_EVENT_MAXTIME(event) -#endif - -#define MESSAGEQID_TO_QUEUEID(_messageqid) (((QUEUE_CB_S *)(_messageqid))->usQueueID) - -fwMailQId fwMailCreate (fwMailQDef_t *queue_def, osThreadId thread_id); -void *fwMailAlloc (fwMailQId queue_id, UINT32 millisec, UINT8 tag, UINT8 cmd); -void *fwMailCAlloc (fwMailQId queue_id, UINT32 millisec, UINT8 tag, UINT8 cmd); -osStatus fwMailPut (fwMailQId queue_id, void *mail); -osEvent fwMailGet (fwMailQId queue_id, UINT32 millisec); -osStatus fwMailFree (fwMailQId queue_id, void *mail); -UINT32 fwMailQGetStatus(void); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif // _CMSIS_OS_H +/* ---------------------------------------------------------------------- + * $Date: 5. February 2013 + * $Revision: V1.02 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h template header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + *---------------------------------------------------------------------------- + * + * Copyright (c) 2013-2017 ARM LIMITED + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *---------------------------------------------------------------------------*/ +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +Name conventions and header file modifications + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +Function calls from interrupt service routines + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +Define and reference object definitions + +With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +Header File +\code +#include // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +Example +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS1_H +#define _CMSIS_OS1_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_LOS 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "LOS V1.0.0" ///< RTOS identification string + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available + +#include "los_typedef.h" +#include "los_config.h" +#include "string.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer once + osTimerPeriodic = 1, ///< repeating timer + osTimerDelay = 2 ///< one-shot timer each time +} os_timer_type; + +typedef enum { + osTimerRousesIgnore = 0, ///< timer can't wakeup system + osTimerRousesAllow = 1 ///< timer can wakeup system +} os_timer_rouses_type; + +typedef enum { + osTimerAlignIgnore = 0, ///>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct LosTaskCB *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct tagSwTmrCtrl *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct LosMuxCB *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct LosSemCB *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + char *name; + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + UINT32 instances; ///< maximum number of instances of that thread function + UINT32 stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + UINT32 default_interval; ///< time delay value of the timer. ms +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + void *puwMuxHandle; +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + void *puwSemHandle; +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + UINT32 pool_sz; ///< number of items (elements) in the pool + UINT32 item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + UINT32 queue_sz; ///< number of elements in the queue + UINT32 item_sz; ///< size of an item + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + UINT32 queue_sz; ///< number of elements in the queue + UINT32 item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + UINT32 v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + INT32 signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +INT32 osKernelRunning(void); + +#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter +/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS. +/// \return RTOS kernel system timer as 32-bit value +UINT32 osKernelSysTick (void); + +/// The RTOS kernel system timer frequency in Hz +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#define osKernelSysTickFrequency 100000000 + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#define osKernelSysTickMicroSec(microsec) (((uint64_t)(microsec) * (osKernelSysTickFrequency)) / 1000000) + +#endif // System Timer available + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ #name, (name), (priority), (instances), (stacksz) } +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (UINT32 millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +osEvent osWait (UINT32 millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimerDefaultInterval 1 +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), osTimerDefaultInterval } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, UINT32 millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \param[in] strict ignore close err when not strict mode. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerRestart shall be consistent in every CMSIS-RTOS. +osStatus osTimerRestart (osTimerId timer_id, UINT32 millisec, UINT8 strict); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); +osTimerId osTimerExtCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument, os_timer_rouses_type ucRouses, os_timer_align_type ucSensitive); + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +INT32 osSignalSet (osThreadId thread_id, INT32 signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +INT32 osSignalClear (osThreadId thread_id, INT32 signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +osEvent osSignalWait (INT32 signals, UINT32 millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +UINT32 puwMuxHandle_##name; \ +const osMutexDef_t os_mutex_def_##name = { &puwMuxHandle_##name } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, UINT32 millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +UINT32 puwSemHandle_##name; \ +const osSemaphoreDef_t os_semaphore_def_##name = { &puwSemHandle_##name } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, INT32 count); +osSemaphoreId osBinarySemaphoreCreate (const osSemaphoreDef_t *semaphore_def, INT32 count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +INT32 osSemaphoreWait (osSemaphoreId semaphore_id, UINT32 millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +UINT32 os_pool_m_##name[LOS_MEMBOX_SIZE(sizeof(type), (queue_sz)) / 4]; \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), (os_pool_m_##name) } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +osMessageQDef_t os_messageQ_def_##name = \ +{ queue_sz, sizeof(UINT32), NULL } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, UINT32 info, UINT32 millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +osEvent osMessageGet (osMessageQId queue_id, UINT32 millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +UINT32 os_mailQ_m_##name[LOS_MEMBOX_SIZE(sizeof(type), (queue_sz)) / 4]; \ +UINT32 os_mailQ_p_##name[2] = { (0), (UINT32)(os_mailQ_m_##name) }; \ +osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, UINT32 millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, UINT32 millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +osEvent osMailGet (osMailQId queue_id, UINT32 millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + +typedef struct fw_event_def { + UINT8 tag; + UINT8 cmd; + UINT16 option; /// Bits 0-5 indicate the message processing progress; bits 6-15 indicate the timeout period for processing this command. +} fw_event_t; + +#if (LOSCFG_COMPAT_CMSIS_FW == YES) + +typedef struct fw_MailQ_def { + UINT32 event_begin_time; /// Last time when the queue was successfully read. + UINT32 timeout_cnt; /// Number of times the processing of messages in the queue times out. + fw_event_t last_event; /// null indicates that no event is being processed or the previous event has been processed. + struct fw_MailQ_def *next; + osMailQDef_t *queue_id; +} fwMailQDef_t; + +typedef struct fwMailQDef_t *fwMailQId; +extern fwMailQId g_fwMailQList; + +extern UINT32 g_maxEventTime; /// Default maximum time for processing a single event. + +#define fwMailQDef(name, queue_sz, type) \ +osMailQDef(name, queue_sz, type); \ +fwMailQDef_t fw_mailQ_def_##name = \ +{ 0, 0, { 0, 0, 0 }, NULL, osMailQ(name) } + +#define fwMailQ(name) \ +&fw_mailQ_def_##name + +#define SET_EVENT_PHASE(mailQ, phase) \ +(((fwMailQDef_t *)(mailQ))->last_event.option = \ +(0xFFFFFFC0 & (((fwMailQDef_t *)(mailQ))->last_event.option)) | (0x3F & (phase))) + +#define GET_EVENT_PHASE(mailQ) \ +((((fwMailQDef_t *)(mailQ))->last_event.option) & 0x3FU) + +#define SET_EVENT_MAXTIME(mailQ, time) \ +((((fwMailQDef_t *)(mailQ))->last_event.option) |= ((time) << 0x6)) + +#define GET_EVENT_MAXTIME(mailQ) \ +((((fwMailQDef_t *)(mailQ))->last_event.option) >> 0x6) + +#else + +#define fwMailQDef(name, queue_sz, type) \ +osMailQDef(name, queue_sz, type) + +#define fwMailQ(name) \ +osMailQ(name) + +#define fwMailQId osMailQId +#define fwMailQDef_t osMailQDef_t + +#define SET_EVENT_PHASE(event, phase) +#define GET_EVENT_PHASE(event) +#define SET_EVENT_MAXTIME(event, time) +#define GET_EVENT_MAXTIME(event) +#endif + +#define MESSAGEQID_TO_QUEUEID(_messageqid) (((LosQueueCB *)(_messageqid))->queueID) + +fwMailQId fwMailCreate (fwMailQDef_t *queue_def, osThreadId thread_id); +void *fwMailAlloc (fwMailQId queue_id, UINT32 millisec, UINT8 tag, UINT8 cmd); +void *fwMailCAlloc (fwMailQId queue_id, UINT32 millisec, UINT8 tag, UINT8 cmd); +osStatus fwMailPut (fwMailQId queue_id, void *mail); +osEvent fwMailGet (fwMailQId queue_id, UINT32 millisec); +osStatus fwMailFree (fwMailQId queue_id, void *mail); +UINT32 fwMailQGetStatus (void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // _CMSIS_OS1_H diff --git a/osdepends/liteos/cmsis/2.0/cmsis_liteos2.c b/osdepends/liteos/cmsis/2.0/cmsis_liteos2.c index 43d0a0479..1189094ac 100644 --- a/osdepends/liteos/cmsis/2.0/cmsis_liteos2.c +++ b/osdepends/liteos/cmsis/2.0/cmsis_liteos2.c @@ -1,1645 +1,1377 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#include "cmsis_os.h" -#include "los_typedef.h" -#include "los_printf.h" - -#include "los_event.h" -#include "los_membox.h" -#include "los_hwi.h" - -#include "los_mux.ph" -#include "los_queue.ph" -#include "los_sem.ph" -#include "los_memory.ph" -#include "los_swtmr.ph" -#include "los_sys.ph" -#include "los_task.ph" -#include "los_tick.ph" -//#include "los_sleep.h" - -//#include "hal_clocks.h" -#include "string.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ -#if (CMSIS_OS_VER == 2) - -/* Kernel initialization state */ -static osKernelState_t KernelState; - -extern BOOL g_bTaskScheduled; - -#ifdef LOS_RUNSTOP -cb_uart_is_need_awake_fn uart_is_need_awake_callback = NULL; -#endif -#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" - -#ifndef UNUSED -#define UNUSED(var) do { (void)var; } while(0) -#endif -// ==== Kernel Management Functions ==== -uint32_t osTaskStackWaterMarkGet(UINT32 uwTaskID); - -extern VOID LOS_GetSystickCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); - -osStatus_t osKernelInitialize (void) -{ - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - if (KernelState != osKernelInactive) - { - return osError; - } - - if(LOS_OK == LOS_KernelInit()) - { - KernelState = osKernelReady; - return osOK; - } - else - { - return osError; - } -} - - -osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) -{ - 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); - } - memcpy(id_buf, KERNEL_ID, id_size); - } - - return osOK; -} - - -osKernelState_t osKernelGetState (void) -{ - if (OS_INT_ACTIVE) - { - return osKernelError; - } - - if(!g_bTaskScheduled) - { - if (KernelState == osKernelReady) - { - return osKernelReady; - } - else - { - return osKernelInactive; - } - } - else if(g_usLosTaskLock > 0) - { - return osKernelLocked; - } - else - { - return osKernelRunning; - } -} - - -osStatus_t osKernelStart (void) -{ - if(OS_INT_ACTIVE) - { - return osErrorISR; - } - - if(KernelState == osKernelReady) - { - if(LOS_OK == LOS_Start()) - { - 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_bTaskScheduled) - { - return (int32_t)osError; - } - - if(g_usLosTaskLock > 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_bTaskScheduled) - { - return (int32_t)osError; - } - - if(g_usLosTaskLock > 0) - { - LOS_TaskUnlock(); - if (g_usLosTaskLock != 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_bTaskScheduled) - { - return (int32_t)osError; - } - - switch (lock) - { - case 0: - LOS_TaskUnlock(); - if (g_usLosTaskLock != 0) - { - break; - } - return 0; - case 1: - LOS_TaskLock(); - return 1; - default: - break; - } - - return (int32_t)osError; - -} - - -uint64_t osKernelGetTickCount (void) -{ - uint64_t ticks; - UINTPTR uvIntSave; - - if(OS_INT_ACTIVE) - { - ticks = 0U; - } - else - { - uvIntSave = LOS_IntLock(); - ticks = g_ullTickCount; - LOS_IntRestore(uvIntSave); - } - - return ticks; -} - - -uint64_t osKernelGetTick2ms(void) -{ - return osKernelGetTickCount() * (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND); -} - - -uint64_t osMs2Tick(uint64_t ms) -{ - - return ms * (LOSCFG_BASE_CORE_TICK_PER_SECOND / OS_SYS_MS_PER_SECOND); -} - - -uint32_t osKernelGetTickFreq (void) -{ - uint32_t freq; - - if (OS_INT_ACTIVE) - { - freq = 0U; - } - else - { - freq = LOSCFG_BASE_CORE_TICK_PER_SECOND; - } - - return (freq); -} - - -uint32_t osKernelGetSysTimerCount (void) -{ - uint32_t count_high = 0; - uint32_t count_low = 0; - if (OS_INT_ACTIVE) - { - count_low = 0U; - } - else - { - LOS_GetSystickCycle((UINT32 *)&count_high, (UINT32 *)&count_low); - } - return count_low; -} - - -uint32_t osKernelGetSysTimerFreq (void) -{ - return OS_SYS_CLOCK; -} - - -// ==== Thread Management Functions ==== - -osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) -{ - UNUSED(argument); - - UINT32 uwTid; - UINT32 uwRet; - LOS_TASK_CB *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; - } - - memset(&stTskInitParam, 0, sizeof(TSK_INIT_PARAM_S)); - stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)func; - stTskInitParam.uwStackSize = attr->stack_size * 4; - 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) -{ - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE || thread_id == NULL) - { - return NULL; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - - return pstTaskCB->pcTaskName; -} - - -osThreadId_t osThreadGetId (void) -{ - if (OS_INT_ACTIVE) - { - return NULL; - } - - return (osThreadId_t)(g_stLosTask.pstRunTask); -} - - -osThreadState_t osThreadGetState (osThreadId_t thread_id) -{ - UINT16 usTaskStatus; - osThreadState_t stState; - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE || thread_id == NULL) - { - return osThreadError; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - usTaskStatus = pstTaskCB->usTaskStatus; - - if (usTaskStatus & OS_TASK_STATUS_RUNNING) - { - stState = osThreadRunning; - } - else if (usTaskStatus & OS_TASK_STATUS_READY) - { - stState = osThreadReady; - } - else if (usTaskStatus & - (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND | - OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND_QUEUE)) - { - stState = osThreadBlocked; - } - else if (usTaskStatus & OS_TASK_STATUS_UNUSED) - { - stState = osThreadInactive; - } - else - { - stState = osThreadError; - } - - return stState; -} - - -uint32_t osThreadGetStackSize (osThreadId_t thread_id) -{ - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE || thread_id == NULL) - { - return 0U; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - - return pstTaskCB->uwStackSize; -} - - -uint32_t osTaskStackWaterMarkGet(UINT32 uwTaskID) -{ - UINT32 uwCount = 0; - UINT32 *puwTopOfStack; - UINTPTR uvIntSave; - LOS_TASK_CB *pstTaskCB = NULL; - - if (uwTaskID > LOSCFG_BASE_CORE_TSK_LIMIT) - { - return 0; - } - - uvIntSave = LOS_IntLock(); - - pstTaskCB = OS_TCB_FROM_TID(uwTaskID); - if (OS_TASK_STATUS_UNUSED & (pstTaskCB->usTaskStatus)) - { - (VOID)LOS_IntRestore(uvIntSave); - return 0; - } - - // first 4 bytes is OS_TASK_MAGIC_WORD, skip - puwTopOfStack = (UINT32 *)pstTaskCB->uwTopOfStack + 1; - - while (*puwTopOfStack == (UINT32)OS_TASK_STACK_INIT) - { - ++puwTopOfStack; - ++uwCount; - } - - uwCount *= sizeof(UINT32); - - (VOID)LOS_IntRestore(uvIntSave); - return uwCount; -} - - -uint32_t osThreadGetStackSpace (osThreadId_t thread_id) -{ - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE || thread_id == NULL) - { - return 0U; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - - return osTaskStackWaterMarkGet(pstTaskCB->uwTaskID); -} - - -osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) -{ - UINT32 uwRet; - UINT16 usPriority; - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - if (thread_id == NULL) - { - return osErrorParameter; - } - - if (priority < osPriorityLow1 || priority > osPriorityAboveNormal6) - { - return osErrorParameter; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - usPriority = OS_TASK_PRIORITY_LOWEST - ((UINT16)priority - LOS_PRIORITY_WIN); - uwRet = LOS_TaskPriSet(pstTaskCB->uwTaskID, 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; - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE || thread_id == NULL) - { - return osPriorityError; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - usRet = LOS_TaskPriGet(pstTaskCB->uwTaskID); - - 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; - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - if (thread_id == NULL) - { - return osErrorParameter; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - uwRet = LOS_TaskSuspend(pstTaskCB->uwTaskID); - 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; - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - if (thread_id == NULL) - { - return osErrorParameter; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - uwRet = LOS_TaskResume(pstTaskCB->uwTaskID); - - 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; - LOS_TASK_CB *pstTaskCB = NULL; - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - if (thread_id == NULL) - { - return osErrorParameter; - } - - pstTaskCB = (LOS_TASK_CB *)thread_id; - uwRet = LOS_TaskDelete(pstTaskCB->uwTaskID); - - 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; - int index = 0; - - if (OS_INT_ACTIVE) - { - return 0U; - } - - for(; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) - { - if (!((g_pstTaskCBArray + index)->usTaskStatus & OS_TASK_STATUS_UNUSED)) - { - uwCount++; - } - } - - return uwCount; -} - - -// ==== Generic Wait Functions ==== - -osStatus_t osDelay (uint32_t ticks) -{ - UINT32 uwRet = 0; - - uwRet = LOS_TaskDelay(ticks); - if(uwRet == LOS_OK) - { - return osOK; - } - else - { - return osError; - } -} - - -osStatus_t osDelayUntil (uint64_t ticks) -{ - UINT32 uwRet; - UINT32 uwTicks; - UINT64 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) -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)argument, OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_SENSITIVE)) - { - return (osTimerId_t)NULL; - } -#else - if (LOS_OK != LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, &usSwTmrID, (UINT32)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 = LOS_Tick2MS(ticks); - //pstSwtmr->uwExpiry = LOS_Tick2MS(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 = NULL; - 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; - - 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 = 0; - - 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_EventDestory(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(((MUX_CB_S *)mutex_id)->ucMuxID, 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(((MUX_CB_S *)mutex_id)->ucMuxID); - - if (uwRet == LOS_OK) - { - return osOK; - } - else - { - return osErrorResource; - } -} - - -osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) -{ - UINT32 uwIntSave; - LOS_TASK_CB *pstTaskCB; - - if (OS_INT_ACTIVE) - { - return NULL; - } - - if (mutex_id == NULL) - { - return NULL; - } - - uwIntSave = LOS_IntLock(); - pstTaskCB = ((MUX_CB_S *)mutex_id)->pstOwner; - (VOID)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(((MUX_CB_S *)mutex_id)->ucMuxID); - - 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(((SEM_CB_S *)semaphore_id)->usSemID, 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(((SEM_CB_S *)semaphore_id)->usSemID); - - 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 = ((SEM_CB_S *)semaphore_id)->usSemCount; - (VOID)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(((SEM_CB_S *)semaphore_id)->usSemID); - - 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; - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - - if (pstQueue == NULL || msg_ptr == NULL || ((OS_INT_ACTIVE) && (0 != timeout))) - { - return osErrorParameter; - } - - uwBufferSize = (UINT32)(pstQueue->usQueueSize - sizeof(UINT32)); - uwRet = LOS_QueueWriteCopy((UINT32)pstQueue->usQueueID, (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; - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - - if (pstQueue == NULL || msg_ptr == NULL || ((OS_INT_ACTIVE) && (0 != timeout))) - { - return osErrorParameter; - } - - uwBufferSize = (UINT32)(pstQueue->usQueueSize - sizeof(UINT32)); - uwRet = LOS_QueueReadCopy((UINT32)pstQueue->usQueueID, 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; - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - - if (pstQueue == NULL) - { - capacity = 0U; - } - else - { - capacity = pstQueue->usQueueLen; - } - - return (capacity); -} - -uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id) -{ - uint32_t size; - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - - if (pstQueue == NULL) - { - size = 0U; - } - else - { - size = pstQueue->usQueueSize - sizeof(UINT32); - } - - return (size); -} - - -uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) -{ - uint32_t count; - UINTPTR uwIntSave; - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - - if (pstQueue == NULL) - { - count = 0U; - } - else - { - uwIntSave = LOS_IntLock(); - count = (uint32_t)(pstQueue->usReadWriteableCnt[OS_QUEUE_READ]); - LOS_IntRestore(uwIntSave); - } - return count; -} - - -uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) -{ - uint32_t space; - UINTPTR uwIntSave; - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - - if (pstQueue == NULL) - { - space = 0U; - } - else - { - uwIntSave = LOS_IntLock(); - space = (uint32_t)pstQueue->usReadWriteableCnt[OS_QUEUE_WRITE]; - LOS_IntRestore(uwIntSave); - } - return space; -} - - -osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) -{ - QUEUE_CB_S *pstQueue = (QUEUE_CB_S *)mq_id; - UINT32 uwRet; - - if (pstQueue == NULL) - { - return osErrorParameter; - } - - if (OS_INT_ACTIVE) - { - return osErrorISR; - } - - uwRet = LOS_QueueDelete((UINT32)pstQueue->usQueueID); - 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; - } -} -#endif - -#ifdef LOS_RUNSTOP -void osUartVetoCallbackRegister(cb_uart_is_need_awake_fn cb) -{ - if (cb != NULL) - { - uart_is_need_awake_callback = (cb_uart_is_need_awake_fn)cb; - } - return; -} - -void osAddStopClocksVeto(void) -{ - tickless_add_stop_clocks_veto(); -} - -void osRemoveStopClocksVeto(void) -{ - tickless_remove_stop_clocks_veto(); -} -#endif - -#endif // (CMSIS_OS_VER == 2) -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ +/*---------------------------------------------------------------------------- + * Copyright (c) <2013-2015>, + * 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. + *---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + *---------------------------------------------------------------------------*/ +#include "cmsis_os.h" +#include "los_config.h" +#include "string.h" +#include "securec.h" +#include "los_typedef.h" +#include "los_printf.h" +#include "los_event.h" +#include "los_membox.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 "los_sched_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#if (LOSCFG_CMSIS_VERSION == 2) + +/* Kernel initialization state */ +static osKernelState_t g_kernelState; + +#define LOS_PRIORITY_WIN 8 + +static const osVersion_t g_losVersion = {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) + +#define TASK_UNLOCK 0 +#define TASK_LOCK 1 + +/* Kernel Management Functions */ +uint32_t osTaskStackWaterMarkGet(uint32_t taskID); + + +osStatus_t osKernelInitialize (void) +{ + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (g_kernelState != osKernelInactive) { + return osError; + } + + if (LOS_OK == OsMain()) { + g_kernelState = osKernelReady; + return osOK; + } else { + return osError; + } +} + + +osStatus_t osKernelGetInfo(osVersion_t *version, char *idBuf, uint32_t idSize) +{ + uint32_t ret; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (version != NULL) { + version->api = g_losVersion.api; + version->kernel = g_losVersion.kernel; + } + + if ((idBuf != NULL) && (idSize != 0U)) { + if (idSize > (strlen(KERNEL_ID) + 1)) { + idSize = strlen(KERNEL_ID) + 1; + } + ret = memcpy_s(idBuf, idSize, KERNEL_ID, idSize); + if (ret != EOK) { + PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, ret); + return osError; + } + } + + return osOK; +} + + +osKernelState_t osKernelGetState (void) +{ + uint32_t losTaskLock = OsPercpuGet()->taskLockCnt;; + + if (OS_INT_ACTIVE) { + return osKernelError; + } + + if (!g_taskScheduled) { + if (g_kernelState == osKernelReady) { + return osKernelReady; + } else { + return osKernelInactive; + } + } else if (losTaskLock > 0) { + return osKernelLocked; + } else { + return osKernelRunning; + } +} + +osStatus_t osKernelStart (void) +{ + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (g_kernelState == osKernelReady) { + if (LOS_Start() == LOS_OK) { + g_kernelState = osKernelRunning; + return osOK; + } else { + return osError; + } + } else { + return osError; + } +} + + +int32_t osKernelLock(void) +{ + int32_t lock; + uint32_t losTaskLock = OsPercpuGet()->taskLockCnt;; + uint32_t cpuID = ArchCurrCpuid(); + + if (OS_INT_ACTIVE) { + return (int32_t)osErrorISR; + } + + if (!(g_taskScheduled & (1 << cpuID))) { + return (int32_t)osError; + } + + if (losTaskLock > 0) { + lock = 1; + } else { + LOS_TaskLock(); + lock = 0; + } + + return lock; +} + + +int32_t osKernelUnlock(void) +{ + int32_t lock; + uint32_t losTaskLock = OsPercpuGet()->taskLockCnt; + uint32_t cpuID = ArchCurrCpuid(); + + if (OS_INT_ACTIVE) { + return (int32_t)osErrorISR; + } + + if (!(g_taskScheduled & (1 << cpuID))) { + return (int32_t)osError; + } + + if (losTaskLock > 0) { + LOS_TaskUnlock(); + if (losTaskLock != 0) { + return (int32_t)osError; + } + lock = 1; + } else { + lock = 0; + } + + return lock; +} + + +int32_t osKernelRestoreLock(int32_t lock) +{ + uint32_t losTaskLock = OsPercpuGet()->taskLockCnt; + uint32_t cpuID = ArchCurrCpuid(); + + if (OS_INT_ACTIVE) { + return (int32_t)osErrorISR; + } + if (!(g_taskScheduled & (1 << cpuID))) { + return (int32_t)osError; + } + + switch (lock) { + case TASK_UNLOCK: + LOS_TaskUnlock(); + if (losTaskLock != 0) { + break; + } + return 0; + case TASK_LOCK: + LOS_TaskLock(); + return 1; + default: + break; + } + + return (int32_t)osError; +} + + +UINT64 osKernelGetTickCount(void) +{ + UINT64 ticks; + UINTPTR intSave; + + if (OS_INT_ACTIVE) { + ticks = 0U; + } else { + intSave = LOS_IntLock(); + ticks = g_tickCount[0]; + LOS_IntRestore(intSave); + } + + return ticks; +} + + +UINT64 osKernelGetTick2ms(void) +{ + return osKernelGetTickCount() * (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND); +} + + +UINT64 osMs2Tick(UINT64 ms) +{ + return ms * (LOSCFG_BASE_CORE_TICK_PER_SECOND / OS_SYS_MS_PER_SECOND); +} + + +uint32_t osKernelGetTickFreq(void) +{ + uint32_t freq; + + if (OS_INT_ACTIVE) { + freq = 0U; + } else { + freq = LOSCFG_BASE_CORE_TICK_PER_SECOND; + } + + return (freq); +} + +LITE_OS_SEC_TEXT_MINOR VOID LOS_GetSystickCycle(uint32_t *highCnt, uint32_t *lowCnt); +uint32_t osKernelGetSysTimerCount (void) +{ + uint32_t countHigh = 0; + uint32_t countLow = 0; + + if (OS_INT_ACTIVE) { + countLow = 0U; + } else { + LOS_GetSystickCycle((uint32_t *)&countHigh, (uint32_t *)&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) +{ + UNUSED(argument); + + uint32_t tid; + uint32_t ret; + LosTaskCB *taskCB = NULL; + TSK_INIT_PARAM_S tskInitParam; + + if (OS_INT_ACTIVE) { + return NULL; + } + + if ((attr == NULL) || (func == NULL)) { + return (osThreadId_t)NULL; + } + if ((attr->priority < osPriorityLow1) || (attr->priority > osPriorityAboveNormal6)) { + return (osThreadId_t)NULL; + } + + /* Ignore the return code when matching CSEC rule 6.6(4). */ + (void)memset_s(&tskInitParam, sizeof(tskInitParam), 0, sizeof(tskInitParam)); + tskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)func; + tskInitParam.uwStackSize = attr->stack_size * sizeof(uint32_t); + tskInitParam.pcName = (CHAR *)attr->name; + /* task priority: 0~31 */ + tskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - ((UINT16)(attr->priority) - LOS_PRIORITY_WIN); + + ret = LOS_TaskCreate(&tid, &tskInitParam); + if (ret != LOS_OK) { + return (osThreadId_t)NULL; + } + taskCB = OS_TCB_FROM_TID(tid); + + return (osThreadId_t)taskCB; +} + +const char *osThreadGetName(osThreadId_t threadID) +{ + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE || (threadID == NULL)) { + return NULL; + } + + taskCB = (LosTaskCB *)threadID; + + return taskCB->taskName; +} + + +osThreadId_t osThreadGetId (void) +{ + if (OS_INT_ACTIVE) { + return NULL; + } + + return (osThreadId_t)(g_runTask); +} + + +osThreadState_t osThreadGetState(osThreadId_t threadID) +{ + UINT16 taskStatus; + osThreadState_t state; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE || (threadID == NULL)) { + return osThreadError; + } + + taskCB = (LosTaskCB *)threadID; + taskStatus = taskCB->taskStatus; + if (taskStatus & OS_TASK_STATUS_RUNNING) { + state = osThreadRunning; + } else if (taskStatus & OS_TASK_STATUS_READY) { + state = osThreadReady; + } else if (taskStatus & + (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND | + OS_TASK_STATUS_SUSPEND)) { + state = osThreadBlocked; + } else if (taskStatus & OS_TASK_STATUS_UNUSED) { + state = osThreadInactive; + } else { + state = osThreadError; + } + + return state; +} + + +uint32_t osThreadGetStackSize(osThreadId_t threadID) +{ + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE || (threadID == NULL)) { + return 0U; + } + + taskCB = (LosTaskCB *)threadID; + + return taskCB->stackSize; +} + + +uint32_t osTaskStackWaterMarkGet(uint32_t taskID) +{ + uint32_t count = 0; + uint32_t *topOfStack = NULL; + UINTPTR intSave; + LosTaskCB *taskCB = NULL; + + if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { + return 0; + } + + intSave = LOS_IntLock(); + + taskCB = OS_TCB_FROM_TID(taskID); + if ((taskCB->taskStatus) & OS_TASK_STATUS_UNUSED) { + LOS_IntRestore(intSave); + return 0; + } + + /* first 4 bytes is OS_TASK_MAGIC_WORD, skip */ + topOfStack = (uint32_t *)(UINTPTR)taskCB->topOfStack + 1; + while (*topOfStack == (uint32_t)OS_STACK_INIT) { + ++topOfStack; + ++count; + } + + count *= sizeof(uint32_t); + LOS_IntRestore(intSave); + + return count; +} + + +uint32_t osThreadGetStackSpace(osThreadId_t threadID) +{ + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE || (threadID == NULL)) { + return 0U; + } + + taskCB = (LosTaskCB *)threadID; + + return osTaskStackWaterMarkGet(taskCB->taskID); +} + + +osStatus_t osThreadSetPriority(osThreadId_t threadID, osPriority_t priority) +{ + uint32_t ret; + UINT16 priorityTemp; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (threadID == NULL) { + return osErrorParameter; + } + + if ((priority < osPriorityLow1) || (priority > osPriorityAboveNormal6)) { + return osErrorParameter; + } + + taskCB = (LosTaskCB *)threadID; + priorityTemp = OS_TASK_PRIORITY_LOWEST - ((UINT16)priority - LOS_PRIORITY_WIN); + ret = LOS_TaskPriSet(taskCB->taskID, priorityTemp); + switch (ret) { + case LOS_ERRNO_TSK_PRIOR_ERROR: + /* fall-through */ + case LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK: + /* fall-through */ + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + case LOS_ERRNO_TSK_NOT_CREATED: + return osErrorResource; + default: + return osOK; + } +} + + +osPriority_t osThreadGetPriority(osThreadId_t threadID) +{ + UINT16 ret; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE || (threadID == NULL)) { + return osPriorityError; + } + + taskCB = (LosTaskCB *)threadID; + ret = LOS_TaskPriGet(taskCB->taskID); + if (ret == (UINT16)OS_INVALID) { + return osPriorityError; + } + + return (osPriority_t)(OS_TASK_PRIORITY_LOWEST - (ret - LOS_PRIORITY_WIN)); +} + + +osStatus_t osThreadYield (void) +{ + uint32_t ret; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + ret = LOS_TaskYield(); + if (ret == LOS_OK) { + return osOK; + } + + return osError; +} + + +osStatus_t osThreadSuspend(osThreadId_t threadID) +{ + uint32_t ret; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (threadID == NULL) { + return osErrorParameter; + } + + taskCB = (LosTaskCB *)threadID; + ret = LOS_TaskSuspend(taskCB->taskID); + switch (ret) { + case LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK: + /* fall-through */ + case LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED: + /* fall-through */ + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + + case LOS_ERRNO_TSK_NOT_CREATED: + /* fall-through */ + case LOS_ERRNO_TSK_ALREADY_SUSPENDED: + /* fall-through */ + case LOS_ERRNO_TSK_SUSPEND_LOCKED: + return osErrorResource; + default: + return osOK; + } +} + +osStatus_t osThreadResume(osThreadId_t threadID) +{ + uint32_t ret; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (threadID == NULL) { + return osErrorParameter; + } + + taskCB = (LosTaskCB *)threadID; + ret = LOS_TaskResume(taskCB->taskID); + switch (ret) { + case LOS_ERRNO_TSK_ID_INVALID: + return osErrorParameter; + case LOS_ERRNO_TSK_NOT_CREATED: + /* fall-through */ + case LOS_ERRNO_TSK_NOT_SUSPENDED: + return osErrorResource; + default: + return osOK; + } +} + +osStatus_t osThreadTerminate(osThreadId_t threadID) +{ + uint32_t ret; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (threadID == NULL) { + return osErrorParameter; + } + + taskCB = (LosTaskCB *)threadID; + ret = LOS_TaskDelete(taskCB->taskID); + switch (ret) { + case LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK: + /* fall-through */ + case LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED: + /* fall-through */ + 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 count = 0; + int index; + + if (OS_INT_ACTIVE) { + return 0U; + } + + for (index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) { + if (!((g_taskCBArray + index)->taskStatus & OS_TASK_STATUS_UNUSED)) { + count++; + } + } + + return count; +} + +/* Generic Wait Functions */ +osStatus_t osDelay(uint32_t ticks) +{ + uint32_t ret; + + ret = LOS_TaskDelay(ticks); + if (ret == LOS_OK) { + return osOK; + } else { + return osError; + } +} + +osStatus_t osDelayUntil(UINT64 ticks) +{ + uint32_t ret; + uint32_t ticksTemp; + UINT64 tickCount = osKernelGetTickCount(); + if (ticks < tickCount) { + return osError; + } + + ticksTemp = (uint32_t)(ticks - tickCount); + ret = LOS_TaskDelay(ticksTemp); + if (ret == 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 rouses, + os_timer_align_type sensitive) +{ + UNUSED(attr); + UINT16 swtmrID; + UINT8 mode; + + if (OS_INT_ACTIVE || (func == NULL) || + ((type != osTimerOnce) && (type != osTimerPeriodic))) { + return (osTimerId_t)NULL; + } + + if (type == osTimerOnce) { + mode = LOS_SWTMR_MODE_NO_SELFDELETE; + } else { + mode = LOS_SWTMR_MODE_PERIOD; + } + if (LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, + &swtmrID, (uint32_t)(UINTPTR)argument, + rouses, sensitive) != LOS_OK) { + return (osTimerId_t)NULL; + } + + return (osTimerId_t)OS_SWT_FROM_SID(swtmrID); +} +#endif +osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) +{ + UNUSED(attr); + UINT16 swtmrID; + UINT8 mode; + + if (OS_INT_ACTIVE || (func == NULL) || + ((type != osTimerOnce) && (type != osTimerPeriodic))) { + return (osTimerId_t)NULL; + } + + if (type == osTimerOnce) { + mode = LOS_SWTMR_MODE_NO_SELFDELETE; + } else { + mode = LOS_SWTMR_MODE_PERIOD; + } +#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == YES) + if (LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, + &swtmrID, (uint32_t)(UINTPTR)argument, + OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_SENSITIVE) != LOS_OK) { + return (osTimerId_t)NULL; + } +#else + if (LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, + &swtmrID, (uint32_t)(UINTPTR)argument) != LOS_OK) { + return (osTimerId_t)NULL; + } +#endif + + return (osTimerId_t)OS_SWT_FROM_SID(swtmrID); +} + + +osStatus_t osTimerStart(osTimerId_t timerID, uint32_t ticks) +{ + uint32_t ret; + SWTMR_CTRL_S *swtmr = NULL; + + if ((ticks == 0) || (timerID == NULL)) { + return osErrorParameter; + } + + swtmr = (SWTMR_CTRL_S *)timerID; + swtmr->uwInterval = LOS_Tick2MS(ticks); + ret = LOS_SwtmrStart(swtmr->usTimerID); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SWTMR_ID_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + + +const char *osTimerGetName(osTimerId_t timerID) +{ + UNUSED(timerID); + return (const char *)NULL; +} + + +osStatus_t osTimerStop(osTimerId_t timerID) +{ + uint32_t ret; + SWTMR_CTRL_S *swtmr = (SWTMR_CTRL_S *)timerID; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (swtmr == NULL) { + return osErrorParameter; + } + + ret = LOS_SwtmrStop(swtmr->usTimerID); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SWTMR_ID_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + + +uint32_t osTimerIsRunning(osTimerId_t timerID) +{ + if (OS_INT_ACTIVE || (timerID == NULL)) { + return 0; + } + + return (((SWTMR_CTRL_S *)timerID)->ucState == OS_SWTMR_STATUS_TICKING); +} + +osStatus_t osTimerDelete(osTimerId_t timerID) +{ + uint32_t ret; + SWTMR_CTRL_S *swtmr = (SWTMR_CTRL_S *)timerID; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (swtmr == NULL) { + return osErrorParameter; + } + + ret = LOS_SwtmrDelete(swtmr->usTimerID); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SWTMR_ID_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +#endif + +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) +{ + PEVENT_CB_S eventCB; + uint32_t ret; + + UNUSED(attr); + + if (OS_INT_ACTIVE) { + return (osEventFlagsId_t)NULL; + } + + eventCB = (PEVENT_CB_S)LOS_MemAlloc(m_aucSysMem0, sizeof(EVENT_CB_S)); + if (eventCB == NULL) { + return (osEventFlagsId_t)NULL; + } + + ret = LOS_EventInit(eventCB); + if (ret == LOS_ERRNO_EVENT_PTR_NULL) { + return (osEventFlagsId_t)NULL; + } else { + return (osEventFlagsId_t)eventCB; + } +} + + +const char *osEventFlagsGetName(osEventFlagsId_t efID) +{ + UNUSED(efID); + + if (OS_INT_ACTIVE) { + return (const char *)NULL; + } + + return (const char *)NULL; +} + + +uint32_t osEventFlagsSet(osEventFlagsId_t efID, uint32_t flags) +{ + PEVENT_CB_S eventCB = (PEVENT_CB_S)efID; + uint32_t ret; + uint32_t rflags; + + ret = LOS_EventWrite(eventCB, (uint32_t)flags); + if (ret != LOS_OK) { + return (uint32_t)osFlagsErrorParameter; + } else { + rflags = eventCB->uwEventID; + return rflags; + } +} + + +uint32_t osEventFlagsClear(osEventFlagsId_t efID, uint32_t flags) +{ + PEVENT_CB_S eventCB = (PEVENT_CB_S)efID; + UINTPTR intSave; + uint32_t rflags; + uint32_t ret; + + if (eventCB == NULL) { + return (uint32_t)osFlagsErrorParameter; + } + + intSave = LOS_IntLock(); + rflags = eventCB->uwEventID; + + ret = LOS_EventClear(eventCB, ~flags); + LOS_IntRestore(intSave); + if (ret != LOS_OK) { + return (uint32_t)osFlagsErrorParameter; + } else { + return rflags; + } +} + +uint32_t osEventFlagsGet(osEventFlagsId_t efID) +{ + PEVENT_CB_S eventCB = (PEVENT_CB_S)efID; + UINTPTR intSave; + uint32_t rflags; + + if (eventCB == NULL) { + return (uint32_t)osFlagsErrorParameter; + } + + intSave = LOS_IntLock(); + rflags = eventCB->uwEventID; + LOS_IntRestore(intSave); + + return rflags; +} + +uint32_t osEventFlagsWait(osEventFlagsId_t efID, uint32_t flags, uint32_t options, uint32_t timeout) +{ + PEVENT_CB_S eventCB = (PEVENT_CB_S)efID; + uint32_t mode = 0; + uint32_t ret; + uint32_t rflags; + + if (options > (osFlagsWaitAny | osFlagsWaitAll | osFlagsNoClear)) { + return (uint32_t)osFlagsErrorParameter; + } + + if ((options & osFlagsWaitAll) == osFlagsWaitAll) { + mode |= LOS_WAITMODE_AND; + } else { + mode |= LOS_WAITMODE_OR; + } + + if ((options & osFlagsNoClear) == osFlagsNoClear) { + mode &= ~LOS_WAITMODE_CLR; + } else { + mode |= LOS_WAITMODE_CLR; + } + + ret = LOS_EventRead(eventCB, (uint32_t)flags, mode, (uint32_t)timeout); + switch (ret) { + case LOS_ERRNO_EVENT_PTR_NULL: + /* fall-through */ + case LOS_ERRNO_EVENT_EVENTMASK_INVALID: + /* fall-through */ + case LOS_ERRNO_EVENT_SETBIT_INVALID: + return (uint32_t)osFlagsErrorParameter; + case LOS_ERRNO_EVENT_READ_IN_INTERRUPT: + /* fall-through */ + case LOS_ERRNO_EVENT_FLAGS_INVALID: + /* fall-through */ + 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)ret; + return rflags; + } +} + +osStatus_t osEventFlagsDelete(osEventFlagsId_t efID) +{ + PEVENT_CB_S eventCB = (PEVENT_CB_S)efID; + UINTPTR intSave; + osStatus_t ret; + + intSave = LOS_IntLock(); + if (LOS_EventDestroy(eventCB) == LOS_OK) { + ret = osOK; + } else { + ret = osErrorParameter; + } + LOS_IntRestore(intSave); + + if (LOS_MemFree(m_aucSysMem0, (void *)eventCB) == LOS_OK) { + ret = osOK; + } else { + ret = osErrorParameter; + } + + return ret; +} + +/* Mutex Management Functions */ +#if (LOSCFG_BASE_IPC_MUX == YES) +osMutexId_t osMutexNew (const osMutexAttr_t *attr) +{ + uint32_t ret; + uint32_t muxID; + + UNUSED(attr); + + if (OS_INT_ACTIVE) { + return NULL; + } + + ret = LOS_MuxCreate(&muxID); + if (ret == LOS_OK) { + return (osMutexId_t)(GET_MUX(muxID)); + } else { + return (osMutexId_t)NULL; + } +} + +osStatus_t osMutexAcquire(osMutexId_t mutexID, uint32_t timeout) +{ + uint32_t ret; + + if (mutexID == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) { + timeout = 0; + } + + ret = LOS_MuxPend(((LosMuxCB *)mutexID)->muxID, timeout); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_MUX_TIMEOUT) { + return osErrorTimeout; + } else if (ret == LOS_ERRNO_MUX_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + +osStatus_t osMutexRelease(osMutexId_t mutexID) +{ + uint32_t ret; + + if (mutexID == NULL) { + return osErrorParameter; + } + + ret = LOS_MuxPost(((LosMuxCB *)mutexID)->muxID); + if (ret == LOS_OK) { + return osOK; + } else { + return osErrorResource; + } +} + +osThreadId_t osMutexGetOwner(osMutexId_t mutexID) +{ + uint32_t intSave; + LosTaskCB *taskCB = NULL; + + if (OS_INT_ACTIVE) { + return NULL; + } + + if (mutexID == NULL) { + return NULL; + } + + intSave = LOS_IntLock(); + taskCB = ((LosMuxCB *)mutexID)->owner; + LOS_IntRestore(intSave); + + return (osThreadId_t)taskCB; +} + +osStatus_t osMutexDelete(osMutexId_t mutexID) +{ + uint32_t ret; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (mutexID == NULL) { + return osErrorParameter; + } + + ret = LOS_MuxDelete(((LosMuxCB *)mutexID)->muxID); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_MUX_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +#endif + +/* Semaphore Management Functions */ +#if (LOSCFG_BASE_IPC_SEM == YES) + +osSemaphoreId_t osSemaphoreNew(uint32_t maxCount, uint32_t initialCount, const osSemaphoreAttr_t *attr) +{ + uint32_t ret; + uint32_t semID; + + UNUSED(attr); + + if (OS_INT_ACTIVE) { + return (osSemaphoreId_t)NULL; + } + + if (maxCount == 1) { + ret = LOS_BinarySemCreate((UINT16)initialCount, &semID); + } else { + ret = LOS_SemCreate((UINT16)initialCount, &semID); + } + if (ret == LOS_OK) { + return (osSemaphoreId_t)(GET_SEM(semID)); + } else { + return (osSemaphoreId_t)NULL; + } +} + +osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphoreID, uint32_t timeout) +{ + uint32_t ret; + + if (semaphoreID == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) { + return osErrorISR; + } + + ret = LOS_SemPend(((LosSemCB *)semaphoreID)->semID, timeout); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SEM_TIMEOUT) { + return osErrorTimeout; + } else if (ret == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else if (ret == LOS_ERRNO_SEM_PEND_INTERR) { + return osErrorISR; + } else { + return osErrorResource; + } +} + +osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphoreID) +{ + uint32_t ret; + + if (semaphoreID == NULL) { + return osErrorParameter; + } + + ret = LOS_SemPost(((LosSemCB *)semaphoreID)->semID); + if (ret == LOS_OK) { + return osOK; + } else if (ret == LOS_ERRNO_SEM_INVALID) { + return osErrorParameter; + } else { + return osErrorResource; + } +} + +uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphoreID) +{ + uint32_t intSave; + uint32_t count; + + if (OS_INT_ACTIVE) { + return 0; + } + + if (semaphoreID == NULL) { + return 0; + } + + intSave = LOS_IntLock(); + count = ((LosSemCB *)semaphoreID)->semCount; + LOS_IntRestore(intSave); + + return count; +} + + +osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphoreID) +{ + uint32_t ret; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (semaphoreID == NULL) { + return osErrorParameter; + } + + ret = LOS_SemDelete(((LosSemCB *)semaphoreID)->semID); + if (ret == LOS_OK) { + return osOK; + } else if (ret == 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 msgCount, uint32_t msgSize, const osMessageQueueAttr_t *attr) +{ + uint32_t queueID; + uint32_t ret; + UNUSED(attr); + osMessageQueueId_t handle; + + if ((msgCount == 0) || (msgSize == 0) || OS_INT_ACTIVE) { + return (osMessageQueueId_t)NULL; + } + + ret = LOS_QueueCreate((char *)NULL, (UINT16)msgCount, &queueID, 0, (UINT16)msgSize); + if (ret == LOS_OK) { + handle = (osMessageQueueId_t)(GET_QUEUE_HANDLE(queueID)); + } else { + handle = (osMessageQueueId_t)NULL; + } + + return handle; +} + +osStatus_t osMessageQueuePut(osMessageQueueId_t mqID, const void *msgPtr, uint8_t msgPrio, uint32_t timeout) +{ + UNUSED(msgPrio); + uint32_t ret; + uint32_t bufferSize; + LosQueueCB *queueCB = (LosQueueCB *)mqID; + + if ((queueCB == NULL) || (msgPtr == NULL) || (OS_INT_ACTIVE && (timeout != 0))) { + return osErrorParameter; + } + + bufferSize = (uint32_t)(queueCB->queueSize - sizeof(uint32_t)); + ret = LOS_QueueWriteCopy((uint32_t)queueCB->queueID, (void *)msgPtr, bufferSize, timeout); + if (ret == LOS_OK) { + return osOK; + } else if ((ret == LOS_ERRNO_QUEUE_INVALID) || (ret == LOS_ERRNO_QUEUE_NOT_CREATE)) { + return osErrorParameter; + } else if (ret == LOS_ERRNO_QUEUE_TIMEOUT) { + return osErrorTimeout; + } else { + return osErrorResource; + } +} + +osStatus_t osMessageQueueGet(osMessageQueueId_t mqID, void *msgPtr, uint8_t *msgPrio, uint32_t timeout) +{ + UNUSED(msgPrio); + uint32_t ret; + uint32_t bufferSize; + LosQueueCB *queueCB = (LosQueueCB *)mqID; + + if ((queueCB == NULL) || (msgPtr == NULL) || (OS_INT_ACTIVE && (timeout != 0))) { + return osErrorParameter; + } + + bufferSize = (uint32_t)(queueCB->queueSize - sizeof(uint32_t)); + ret = LOS_QueueReadCopy((uint32_t)queueCB->queueID, msgPtr, &bufferSize, timeout); + if (ret == LOS_OK) { + return osOK; + } else if ((ret == LOS_ERRNO_QUEUE_INVALID) || (ret == LOS_ERRNO_QUEUE_NOT_CREATE)) { + return osErrorParameter; + } else if (ret == LOS_ERRNO_QUEUE_TIMEOUT) { + return osErrorTimeout; + } else { + return osErrorResource; + } +} + +uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mqID) +{ + uint32_t capacity; + LosQueueCB *queueCB = (LosQueueCB *)mqID; + + if (queueCB == NULL) { + capacity = 0U; + } else { + capacity = queueCB->queueLen; + } + + return (capacity); +} + +uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mqID) +{ + uint32_t size; + LosQueueCB *queueCB = (LosQueueCB *)mqID; + + if (queueCB == NULL) { + size = 0U; + } else { + size = queueCB->queueSize - sizeof(uint32_t); + } + + return size; +} + +uint32_t osMessageQueueGetCount(osMessageQueueId_t mqID) +{ + uint32_t count; + UINTPTR intSave; + LosQueueCB *queueCB = (LosQueueCB *)mqID; + + if (queueCB == NULL) { + count = 0U; + } else { + intSave = LOS_IntLock(); + count = (uint32_t)(queueCB->readWriteableCnt[OS_QUEUE_READ]); + LOS_IntRestore(intSave); + } + return count; +} + + +uint32_t osMessageQueueGetSpace(osMessageQueueId_t mqID) +{ + uint32_t space; + UINTPTR intSave; + LosQueueCB *queueCB = (LosQueueCB *)mqID; + + if (queueCB == NULL) { + space = 0U; + } else { + intSave = LOS_IntLock(); + space = (uint32_t)queueCB->readWriteableCnt[OS_QUEUE_WRITE]; + LOS_IntRestore(intSave); + } + return space; +} + +osStatus_t osMessageQueueDelete(osMessageQueueId_t mqID) +{ + LosQueueCB *queueCB = (LosQueueCB *)mqID; + uint32_t ret; + + if (queueCB == NULL) { + return osErrorParameter; + } + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + ret = LOS_QueueDelete((uint32_t)queueCB->queueID); + if (ret == LOS_OK) { + return osOK; + } else if ((ret == LOS_ERRNO_QUEUE_NOT_FOUND) || (ret == LOS_ERRNO_QUEUE_NOT_CREATE)) { + return osErrorParameter; + } else { + return osErrorResource; + } +} +#endif + +#endif // (LOSCFG_CMSIS_VERSION == 2) +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/osdepends/liteos/cmsis/2.0/cmsis_os2.h b/osdepends/liteos/cmsis/2.0/cmsis_os2.h index 06436ed2a..fa2a47b64 100644 --- a/osdepends/liteos/cmsis/2.0/cmsis_os2.h +++ b/osdepends/liteos/cmsis/2.0/cmsis_os2.h @@ -1,746 +1,771 @@ -/* - * Copyright (c) 2013-2017 ARM Limited. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ---------------------------------------------------------------------- - * - * $Date: 10. January 2017 - * $Revision: V2.1.0 - * - * Project: CMSIS-RTOS2 API - * Title: cmsis_os2.h header file - * - * Version 2.1.0 - * Support for critical and uncritical sections (nesting safe): - * - updated: osKernelLock, osKernelUnlock - * - added: osKernelRestoreLock - * Updated Thread and Event Flags: - * - changed flags parameter and return type from int32_t to uint32_t - * Version 2.0.0 - * Initial Release - *---------------------------------------------------------------------------*/ -#ifndef CMSIS_OS2_H_ -#define CMSIS_OS2_H_ - -#ifndef __NO_RETURN -#if defined(__CC_ARM) -#define __NO_RETURN __declspec(noreturn) -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -#define __NO_RETURN __attribute__((noreturn)) -#elif defined(__GNUC__) -#define __NO_RETURN __attribute__((noreturn)) -#elif defined(__ICCARM__) -#define __NO_RETURN __noreturn -#else -#define __NO_RETURN -#endif -#endif - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -// ==== Enumerations, structures, defines ==== - -/// Version information. -typedef struct { - uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). - uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). -} osVersion_t; - -/// Kernel state. -typedef enum { - osKernelInactive = 0, ///< Inactive. - osKernelReady = 1, ///< Ready. - osKernelRunning = 2, ///< Running. - osKernelLocked = 3, ///< Locked. - osKernelSuspended = 4, ///< Suspended. - osKernelError = -1, ///< Error. - osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. -} osKernelState_t; - -/// Thread state. -typedef enum { - osThreadInactive = 0, ///< Inactive. - osThreadReady = 1, ///< Ready. - osThreadRunning = 2, ///< Running. - osThreadBlocked = 3, ///< Blocked. - osThreadTerminated = 4, ///< Terminated. - osThreadError = -1, ///< Error. - osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. -} osThreadState_t; - -/// Priority values. -typedef enum { - osPriorityNone = 0, ///< No priority (not initialized). - osPriorityIdle = 1, ///< Reserved for Idle thread. - osPriorityLow = 8, ///< Priority: low - osPriorityLow1 = 8+1, ///< Priority: low + 1 - osPriorityLow2 = 8+2, ///< Priority: low + 2 - osPriorityLow3 = 8+3, ///< Priority: low + 3 - osPriorityLow4 = 8+4, ///< Priority: low + 4 - osPriorityLow5 = 8+5, ///< Priority: low + 5 - osPriorityLow6 = 8+6, ///< Priority: low + 6 - osPriorityLow7 = 8+7, ///< Priority: low + 7 - osPriorityBelowNormal = 16, ///< Priority: below normal - osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 - osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 - osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 - osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 - osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 - osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 - osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 - osPriorityNormal = 24, ///< Priority: normal - osPriorityNormal1 = 24+1, ///< Priority: normal + 1 - osPriorityNormal2 = 24+2, ///< Priority: normal + 2 - osPriorityNormal3 = 24+3, ///< Priority: normal + 3 - osPriorityNormal4 = 24+4, ///< Priority: normal + 4 - osPriorityNormal5 = 24+5, ///< Priority: normal + 5 - osPriorityNormal6 = 24+6, ///< Priority: normal + 6 - osPriorityNormal7 = 24+7, ///< Priority: normal + 7 - osPriorityAboveNormal = 32, ///< Priority: above normal - osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 - osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 - osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 - osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 - osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 - osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 - osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 - osPriorityHigh = 40, ///< Priority: high - osPriorityHigh1 = 40+1, ///< Priority: high + 1 - osPriorityHigh2 = 40+2, ///< Priority: high + 2 - osPriorityHigh3 = 40+3, ///< Priority: high + 3 - osPriorityHigh4 = 40+4, ///< Priority: high + 4 - osPriorityHigh5 = 40+5, ///< Priority: high + 5 - osPriorityHigh6 = 40+6, ///< Priority: high + 6 - osPriorityHigh7 = 40+7, ///< Priority: high + 7 - osPriorityRealtime = 48, ///< Priority: realtime - osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 - osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 - osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 - osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 - osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 - osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 - osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 - osPriorityISR = 56, ///< Reserved for ISR deferred thread. - osPriorityError = -1, ///< System cannot determine priority or illegal priority. - osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. -} osPriority_t; - -/// Entry point of a thread. -typedef void (*osThreadFunc_t) (void *argument); - -/// Entry point of a timer call back function. -typedef void (*osTimerFunc_t) (void *argument); - -/// Timer type. -typedef enum { - osTimerOnce = 0, ///< One-shot timer. - osTimerPeriodic = 1 ///< Repeating timer. -} osTimerType_t; - -/// Timeout value. -#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.0xffffffffUL -#define osNoWait 0x0U -/// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). -#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). -#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. -#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. - -/// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). -#define osFlagsError 0x80000000U ///< Error indicator. -#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). -#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). -#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). -#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). -#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). - -/// Thread attributes (attr_bits in \ref osThreadAttr_t). -#define osThreadDetached 0x00000000U ///< Thread created in detached state (default) -#define osThreadJoinable 0x00000001U ///< Thread created in joinable state - -/// Mutex attributes (attr_bits in \ref osMutexAttr_t). -#define osMutexRecursive 0x00000001U ///< Recursive mutex. -#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. -#define osMutexRobust 0x00000008U ///< Robust mutex. - -/// Status code values returned by CMSIS-RTOS functions. -typedef enum { - osOK = 0, ///< Operation completed successfully. - osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. - osErrorTimeout = -2, ///< Operation not completed within the timeout period. - osErrorResource = -3, ///< Resource not available. - osErrorParameter = -4, ///< Parameter error. - osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. - osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. -} osStatus_t; - - -/// \details Thread ID identifies the thread. -typedef void *osThreadId_t; - -/// \details Timer ID identifies the timer. -typedef void *osTimerId_t; - -/// \details Event Flags ID identifies the event flags. -typedef void *osEventFlagsId_t; - -/// \details Mutex ID identifies the mutex. -typedef void *osMutexId_t; - -/// \details Semaphore ID identifies the semaphore. -typedef void *osSemaphoreId_t; - -/// \details Memory Pool ID identifies the memory pool. -typedef void *osMemoryPoolId_t; - -/// \details Message Queue ID identifies the message queue. -typedef void *osMessageQueueId_t; - - -#ifndef TZ_MODULEID_T -#define TZ_MODULEID_T -/// \details Data type that identifies secure software modules called by a process. -typedef uint32_t TZ_ModuleId_t; -#endif - - -/// Attributes structure for thread. -typedef struct { - const char *name; ///< name of the thread - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block - void *stack_mem; ///< memory for stack - uint32_t stack_size; ///< size of stack - osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) - TZ_ModuleId_t tz_module; ///< TrustZone module identifier - uint32_t reserved; ///< reserved (must be 0) -} osThreadAttr_t; - -/// Attributes structure for timer. -typedef struct { - const char *name; ///< name of the timer - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osTimerAttr_t; - -/// Attributes structure for event flags. -typedef struct { - const char *name; ///< name of the event flags - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osEventFlagsAttr_t; - -/// Attributes structure for mutex. -typedef struct { - const char *name; ///< name of the mutex - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osMutexAttr_t; - -/// Attributes structure for semaphore. -typedef struct { - const char *name; ///< name of the semaphore - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block -} osSemaphoreAttr_t; - -/// Attributes structure for memory pool. -typedef struct { - const char *name; ///< name of the memory pool - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block - void *mp_mem; ///< memory for data storage - uint32_t mp_size; ///< size of provided memory for data storage -} osMemoryPoolAttr_t; - -/// Attributes structure for message queue. -typedef struct { - const char *name; ///< name of the message queue - uint32_t attr_bits; ///< attribute bits - void *cb_mem; ///< memory for control block - uint32_t cb_size; ///< size of provided memory for control block - void *mq_mem; ///< memory for data storage - uint32_t mq_size; ///< size of provided memory for data storage -} osMessageQueueAttr_t; - - -// ==== Kernel Management Functions ==== - -/// Initialize the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -osStatus_t osKernelInitialize (void); - -/// Get RTOS Kernel Information. -/// \param[out] version pointer to buffer for retrieving version information. -/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. -/// \param[in] id_size size of buffer for kernel identification string. -/// \return status code that indicates the execution status of the function. -osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); - -/// Get the current RTOS Kernel state. -/// \return current RTOS Kernel state. -osKernelState_t osKernelGetState (void); - -/// Start the RTOS Kernel scheduler. -/// \return status code that indicates the execution status of the function. -osStatus_t osKernelStart (void); - -/// Lock the RTOS Kernel scheduler. -/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). -int32_t osKernelLock (void); - -/// Unlock the RTOS Kernel scheduler. -/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). -int32_t osKernelUnlock (void); - -/// Restore the RTOS Kernel scheduler lock state. -/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. -/// \return new lock state (1 - locked, 0 - not locked, error code if negative). -int32_t osKernelRestoreLock (int32_t lock); - -/// Suspend the RTOS Kernel scheduler. -/// \return time in ticks, for how long the system can sleep or power-down. -uint32_t osKernelSuspend (void); - -/// Resume the RTOS Kernel scheduler. -/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. -void osKernelResume (uint32_t sleep_ticks); - -/// Get the RTOS kernel tick count. -/// \return RTOS kernel current tick count. -uint64_t osKernelGetTickCount (void); -/// Get the RTOS kernel current time. -/// \return RTOS kernel current time/ ms. -uint64_t osKernelGetTick2ms(void); -uint64_t osMs2Tick(uint64_t ticks); - -/// Get the RTOS kernel tick frequency. -/// \return frequency of the kernel tick. -uint32_t osKernelGetTickFreq (void); - -/// Get the RTOS kernel system timer count. -/// \return RTOS kernel current system timer count as 32-bit value. -uint32_t osKernelGetSysTimerCount (void); - -/// Get the RTOS kernel system timer frequency. -/// \return frequency of the system timer. -uint32_t osKernelGetSysTimerFreq (void); - - -// ==== Thread Management Functions ==== - -/// Create a thread and add it to Active Threads. -/// \param[in] func thread function. -/// \param[in] argument pointer that is passed to the thread function as start argument. -/// \param[in] attr thread attributes; NULL: default values. -/// \return thread ID for reference by other functions or NULL in case of error. -osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); - -/// Get name of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return name as NULL terminated string. -const char *osThreadGetName (osThreadId_t thread_id); - -/// Return the thread ID of the current running thread. -/// \return thread ID for reference by other functions or NULL in case of error. -osThreadId_t osThreadGetId (void); - -/// Get current thread state of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return current thread state of the specified thread. -osThreadState_t osThreadGetState (osThreadId_t thread_id); - -/// Get stack size of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return stack size in bytes. -uint32_t osThreadGetStackSize (osThreadId_t thread_id); - -/// Get available stack space of a thread based on stack watermark recording during execution. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return remaining stack space in bytes. -uint32_t osThreadGetStackSpace (osThreadId_t thread_id); - -/// Change priority of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \param[in] priority new priority value for the thread function. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); - -/// Get current priority of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return current priority value of the specified thread. -osPriority_t osThreadGetPriority (osThreadId_t thread_id); - -/// Pass control to next thread that is in state \b READY. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadYield (void); - -/// Suspend execution of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadSuspend (osThreadId_t thread_id); - -/// Resume execution of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadResume (osThreadId_t thread_id); - -/// Detach a thread (thread storage can be reclaimed when thread terminates). -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadDetach (osThreadId_t thread_id); - -/// Wait for specified thread to terminate. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadJoin (osThreadId_t thread_id); - -/// Terminate execution of current running thread. -__NO_RETURN void osThreadExit (void); - -/// Terminate execution of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -osStatus_t osThreadTerminate (osThreadId_t thread_id); - -/// Get number of active threads. -/// \return number of active threads. -uint32_t osThreadGetCount (void); - -/// Enumerate active threads. -/// \param[out] thread_array pointer to array for retrieving thread IDs. -/// \param[in] array_items maximum number of items in array for retrieving thread IDs. -/// \return number of enumerated threads. -uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); - - -// ==== Thread Flags Functions ==== - -/// Set the specified Thread Flags of a thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. -/// \param[in] flags specifies the flags of the thread that shall be set. -/// \return thread flags after setting or error code if highest bit set. -uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); - -/// Clear the specified Thread Flags of current running thread. -/// \param[in] flags specifies the flags of the thread that shall be cleared. -/// \return thread flags before clearing or error code if highest bit set. -uint32_t osThreadFlagsClear (uint32_t flags); - -/// Get the current Thread Flags of current running thread. -/// \return current thread flags. -uint32_t osThreadFlagsGet (void); - -/// Wait for one or more Thread Flags of the current running thread to become signaled. -/// \param[in] flags specifies the flags to wait for. -/// \param[in] options specifies flags options (osFlagsXxxx). -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return thread flags before clearing or error code if highest bit set. -uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); - - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value -/// \return status code that indicates the execution status of the function. -osStatus_t osDelay (uint32_t ticks); - -/// Wait until specified time. -/// \param[in] ticks absolute time in ticks -/// \return status code that indicates the execution status of the function. -osStatus_t osDelayUntil (uint64_t ticks); - - -// ==== Timer Management Functions ==== - -/// Create and Initialize a timer. -/// \param[in] func start address of a timer call back function. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. -/// \param[in] attr timer attributes; NULL: default values. -/// \return timer ID for reference by other functions or NULL in case of error. -osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); - -/// Get name of a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return name as NULL terminated string. -const char *osTimerGetName (osTimerId_t timer_id); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. -/// \return status code that indicates the execution status of the function. -osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); - -/// Stop a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osTimerStop (osTimerId_t timer_id); - -/// Check if a timer is running. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return 0 not running, 1 running. -uint32_t osTimerIsRunning (osTimerId_t timer_id); - -/// Delete a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osTimerDelete (osTimerId_t timer_id); - - -// ==== Event Flags Management Functions ==== - -/// Create and Initialize an Event Flags object. -/// \param[in] attr event flags attributes; NULL: default values. -/// \return event flags ID for reference by other functions or NULL in case of error. -osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); - -/// Get name of an Event Flags object. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \return name as NULL terminated string. -const char *osEventFlagsGetName (osEventFlagsId_t ef_id); - -/// Set the specified Event Flags. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \param[in] flags specifies the flags that shall be set. -/// \return event flags after setting or error code if highest bit set. -uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); - -/// Clear the specified Event Flags. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \param[in] flags specifies the flags that shall be cleared. -/// \return event flags before clearing or error code if highest bit set. -uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); - -/// Get the current Event Flags. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \return current event flags. -uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); - -/// Wait for one or more Event Flags to become signaled. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \param[in] flags specifies the flags to wait for. -/// \param[in] options specifies flags options (osFlagsXxxx). -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return event flags before clearing or error code if highest bit set. -uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); - -/// Delete an Event Flags object. -/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); - - -// ==== Mutex Management Functions ==== - -/// Create and Initialize a Mutex object. -/// \param[in] attr mutex attributes; NULL: default values. -/// \return mutex ID for reference by other functions or NULL in case of error. -osMutexId_t osMutexNew (const osMutexAttr_t *attr); - -/// Get name of a Mutex object. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return name as NULL terminated string. -const char *osMutexGetName (osMutexId_t mutex_id); - -/// Acquire a Mutex or timeout if it is locked. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); - -/// Release a Mutex that was acquired by \ref osMutexAcquire. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMutexRelease (osMutexId_t mutex_id); - -/// Get Thread which owns a Mutex object. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return thread ID of owner thread or NULL when mutex was not acquired. -osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); - -/// Delete a Mutex object. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMutexDelete (osMutexId_t mutex_id); - - -// ==== Semaphore Management Functions ==== - -/// Create and Initialize a Semaphore object. -/// \param[in] max_count maximum number of available tokens. -/// \param[in] initial_count initial number of available tokens. -/// \param[in] attr semaphore attributes; NULL: default values. -/// \return semaphore ID for reference by other functions or NULL in case of error. -osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); - -/// Get name of a Semaphore object. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return name as NULL terminated string. -const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); - -/// Acquire a Semaphore token or timeout if no tokens are available. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); - -/// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); - -/// Get current Semaphore token count. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return number of tokens available. -uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); - -/// Delete a Semaphore object. -/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); - - -// ==== Memory Pool Management Functions ==== - -/// Create and Initialize a Memory Pool object. -/// \param[in] block_count maximum number of memory blocks in memory pool. -/// \param[in] block_size memory block size in bytes. -/// \param[in] attr memory pool attributes; NULL: default values. -/// \return memory pool ID for reference by other functions or NULL in case of error. -osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); - -/// Get name of a Memory Pool object. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \return name as NULL terminated string. -const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); - -/// Allocate a memory block from a Memory Pool. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return address of the allocated memory block or NULL in case of no memory is available. -void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); - -/// Return an allocated memory block back to a Memory Pool. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \param[in] block address of the allocated memory block to be returned to the memory pool. -/// \return status code that indicates the execution status of the function. -osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); - -/// Get maximum number of memory blocks in a Memory Pool. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \return maximum number of memory blocks. -uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); - -/// Get memory block size in a Memory Pool. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \return memory block size in bytes. -uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); - -/// Get number of memory blocks used in a Memory Pool. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \return number of memory blocks used. -uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); - -/// Get number of memory blocks available in a Memory Pool. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \return number of memory blocks available. -uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); - -/// Delete a Memory Pool object. -/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); - - -// ==== Message Queue Management Functions ==== - -/// Create and Initialize a Message Queue object. -/// \param[in] msg_count maximum number of messages in queue. -/// \param[in] msg_size maximum message size in bytes. -/// \param[in] attr message queue attributes; NULL: default values. -/// \return message queue ID for reference by other functions or NULL in case of error. -osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); - -/// Get name of a Message Queue object. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return name as NULL terminated string. -const char *osMessageQueueGetName (osMessageQueueId_t mq_id); - -/// Put a Message into a Queue or timeout if Queue is full. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \param[in] msg_ptr pointer to buffer with message to put into a queue. -/// \param[in] msg_prio message priority. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); - -/// Get a Message from a Queue or timeout if Queue is empty. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \param[out] msg_ptr pointer to buffer for message to get from a queue. -/// \param[out] msg_prio pointer to buffer for message priority or NULL. -/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); - -/// Get maximum number of messages in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return maximum number of messages. -uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); - -/// Get maximum message size in a Memory Pool. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return maximum message size in bytes. -uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); - -/// Get number of queued messages in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return number of queued messages. -uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); - -/// Get number of available slots for messages in a Message Queue. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return number of available slots for messages. -uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); - -/// Reset a Message Queue to initial empty state. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); - -/// Delete a Message Queue object. -/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. -/// \return status code that indicates the execution status of the function. -osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); - -#ifdef __cplusplus -} -#endif - -#endif // CMSIS_OS2_H_ +/* + * Copyright (c) 2013-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 18. June 2018 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS2 API + * Title: cmsis_os2.h header file + * + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.0.0 + * Initial Release + *---------------------------------------------------------------------------*/ +#ifndef CMSIS_OS2_H_ +#define CMSIS_OS2_H_ + +#ifndef __NO_RETURN +#if defined(__CC_ARM) +#define __NO_RETURN __declspec(noreturn) +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __NO_RETURN __attribute__((noreturn)) +#elif defined(__GNUC__) +#define __NO_RETURN __attribute__((noreturn)) +#elif defined(__ICCARM__) +#define __NO_RETURN __noreturn +#else +#define __NO_RETURN +#endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +// ==== Enumerations, structures, defines ==== + +/// Version information. +typedef struct { + uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). + uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). +} osVersion_t; + +/// Kernel state. +typedef enum { + osKernelInactive = 0, ///< Inactive. + osKernelReady = 1, ///< Ready. + osKernelRunning = 2, ///< Running. + osKernelLocked = 3, ///< Locked. + osKernelSuspended = 4, ///< Suspended. + osKernelError = -1, ///< Error. + osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. +} osKernelState_t; + +/// Thread state. +typedef enum { + osThreadInactive = 0, ///< Inactive. + osThreadReady = 1, ///< Ready. + osThreadRunning = 2, ///< Running. + osThreadBlocked = 3, ///< Blocked. + osThreadTerminated = 4, ///< Terminated. + osThreadError = -1, ///< Error. + osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osThreadState_t; + +/// Priority values. +typedef enum { + osPriorityNone = 0, ///< No priority (not initialized). + osPriorityIdle = 1, ///< Reserved for Idle thread. + osPriorityLow = 8, ///< Priority: low + osPriorityLow1 = 8+1, ///< Priority: low + 1 + osPriorityLow2 = 8+2, ///< Priority: low + 2 + osPriorityLow3 = 8+3, ///< Priority: low + 3 + osPriorityLow4 = 8+4, ///< Priority: low + 4 + osPriorityLow5 = 8+5, ///< Priority: low + 5 + osPriorityLow6 = 8+6, ///< Priority: low + 6 + osPriorityLow7 = 8+7, ///< Priority: low + 7 + osPriorityBelowNormal = 16, ///< Priority: below normal + osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 + osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 + osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 + osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 + osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 + osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 + osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 + osPriorityNormal = 24, ///< Priority: normal + osPriorityNormal1 = 24+1, ///< Priority: normal + 1 + osPriorityNormal2 = 24+2, ///< Priority: normal + 2 + osPriorityNormal3 = 24+3, ///< Priority: normal + 3 + osPriorityNormal4 = 24+4, ///< Priority: normal + 4 + osPriorityNormal5 = 24+5, ///< Priority: normal + 5 + osPriorityNormal6 = 24+6, ///< Priority: normal + 6 + osPriorityNormal7 = 24+7, ///< Priority: normal + 7 + osPriorityAboveNormal = 32, ///< Priority: above normal + osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 + osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 + osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 + osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 + osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 + osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 + osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 + osPriorityHigh = 40, ///< Priority: high + osPriorityHigh1 = 40+1, ///< Priority: high + 1 + osPriorityHigh2 = 40+2, ///< Priority: high + 2 + osPriorityHigh3 = 40+3, ///< Priority: high + 3 + osPriorityHigh4 = 40+4, ///< Priority: high + 4 + osPriorityHigh5 = 40+5, ///< Priority: high + 5 + osPriorityHigh6 = 40+6, ///< Priority: high + 6 + osPriorityHigh7 = 40+7, ///< Priority: high + 7 + osPriorityRealtime = 48, ///< Priority: realtime + osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 + osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 + osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 + osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 + osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 + osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 + osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 + osPriorityISR = 56, ///< Reserved for ISR deferred thread. + osPriorityError = -1, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority_t; + +/// Entry point of a thread. +typedef void (*osThreadFunc_t) (void *argument); + +/// Entry point of a timer call back function. +typedef void (*osTimerFunc_t) (void *argument); + +/// Timer type. +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} osTimerType_t; + +typedef enum { + osTimerRousesIgnore = 0, ///< timer can't wakeup system + osTimerRousesAllow = 1 ///< timer can wakeup system +} os_timer_rouses_type; + +typedef enum { + osTimerAlignIgnore = 0, ///< timer no need to align + osTimerAlignAllow = 1 ///< timer need to align +} os_timer_align_type; + + +/// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.0xffffffffUL +#define osNoWait 0x0U +/// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). +#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. +#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. + +/// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +#define osFlagsError 0x80000000U ///< Error indicator. +#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). +#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). +#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). +#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). +#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). + +/// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached state (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable state + +/// Mutex attributes (attr_bits in \ref osMutexAttr_t). +#define osMutexRecursive 0x00000001U ///< Recursive mutex. +#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. +#define osMutexRobust 0x00000008U ///< Robust mutex. + +/// Status code values returned by CMSIS-RTOS functions. +typedef enum { + osOK = 0, ///< Operation completed successfully. + osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + osErrorTimeout = -2, ///< Operation not completed within the timeout period. + osErrorResource = -3, ///< Resource not available. + osErrorParameter = -4, ///< Parameter error. + osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus_t; + + +/// \details Thread ID identifies the thread. +typedef void *osThreadId_t; + +/// \details Timer ID identifies the timer. +typedef void *osTimerId_t; + +/// \details Event Flags ID identifies the event flags. +typedef void *osEventFlagsId_t; + +/// \details Mutex ID identifies the mutex. +typedef void *osMutexId_t; + +/// \details Semaphore ID identifies the semaphore. +typedef void *osSemaphoreId_t; + +/// \details Memory Pool ID identifies the memory pool. +typedef void *osMemoryPoolId_t; + +/// \details Message Queue ID identifies the message queue. +typedef void *osMessageQueueId_t; + + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + + +/// Attributes structure for thread. +typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) +} osThreadAttr_t; + +/// Attributes structure for timer. +typedef struct { + const char *name; ///< name of the timer + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osTimerAttr_t; + +/// Attributes structure for event flags. +typedef struct { + const char *name; ///< name of the event flags + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osEventFlagsAttr_t; + +/// Attributes structure for mutex. +typedef struct { + const char *name; ///< name of the mutex + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osMutexAttr_t; + +/// Attributes structure for semaphore. +typedef struct { + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osSemaphoreAttr_t; + +/// Attributes structure for memory pool. +typedef struct { + const char *name; ///< name of the memory pool + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mp_mem; ///< memory for data storage + uint32_t mp_size; ///< size of provided memory for data storage +} osMemoryPoolAttr_t; + +/// Attributes structure for message queue. +typedef struct { + const char *name; ///< name of the message queue + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mq_mem; ///< memory for data storage + uint32_t mq_size; ///< size of provided memory for data storage +} osMessageQueueAttr_t; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelInitialize (void); + +/// Get RTOS Kernel Information. +/// \param[out] version pointer to buffer for retrieving version information. +/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. +/// \param[in] id_size size of buffer for kernel identification string. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); + +/// Get the current RTOS Kernel state. +/// \return current RTOS Kernel state. +osKernelState_t osKernelGetState (void); + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelStart (void); + +/// Lock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelLock (void); + +/// Unlock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelUnlock (void); + +/// Restore the RTOS Kernel scheduler lock state. +/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +/// \return new lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelRestoreLock (int32_t lock); + +/// Suspend the RTOS Kernel scheduler. +/// \return time in ticks, for how long the system can sleep or power-down. +uint32_t osKernelSuspend (void); + +/// Resume the RTOS Kernel scheduler. +/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. +void osKernelResume (uint32_t sleep_ticks); + +/// Get the RTOS kernel tick count. +/// \return RTOS kernel current tick count. +uint64_t osKernelGetTickCount (void); +/// Get the RTOS kernel current time. +/// \return RTOS kernel current time/ ms. +uint64_t osKernelGetTick2ms(void); +uint64_t osMs2Tick(uint64_t ticks); + +/// Get the RTOS kernel tick frequency. +/// \return frequency of the kernel tick. +uint32_t osKernelGetTickFreq (void); + +/// Get the RTOS kernel system timer count. +/// \return RTOS kernel current system timer count as 32-bit value. +uint32_t osKernelGetSysTimerCount (void); + +/// Get the RTOS kernel system timer frequency. +/// \return frequency of the system timer. +uint32_t osKernelGetSysTimerFreq (void); + + +// ==== Thread Management Functions ==== + +/// Create a thread and add it to Active Threads. +/// \param[in] func thread function. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \param[in] attr thread attributes; NULL: default values. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + +/// Get name of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return name as NULL terminated string. +const char *osThreadGetName (osThreadId_t thread_id); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadGetId (void); + +/// Get current thread state of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current thread state of the specified thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id); + +/// Get stack size of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return stack size in bytes. +uint32_t osThreadGetStackSize (osThreadId_t thread_id); + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return remaining stack space in bytes. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id); + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current priority value of the specified thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadYield (void); + +/// Suspend execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSuspend (osThreadId_t thread_id); + +/// Resume execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadResume (osThreadId_t thread_id); + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadDetach (osThreadId_t thread_id); + +/// Wait for specified thread to terminate. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadJoin (osThreadId_t thread_id); + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void); + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadTerminate (osThreadId_t thread_id); + +/// Get number of active threads. +/// \return number of active threads. +uint32_t osThreadGetCount (void); + +/// Enumerate active threads. +/// \param[out] thread_array pointer to array for retrieving thread IDs. +/// \param[in] array_items maximum number of items in array for retrieving thread IDs. +/// \return number of enumerated threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); + + +// ==== Thread Flags Functions ==== + +/// Set the specified Thread Flags of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] flags specifies the flags of the thread that shall be set. +/// \return thread flags after setting or error code if highest bit set. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); + +/// Clear the specified Thread Flags of current running thread. +/// \param[in] flags specifies the flags of the thread that shall be cleared. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsClear (uint32_t flags); + +/// Get the current Thread Flags of current running thread. +/// \return current thread flags. +uint32_t osThreadFlagsGet (void); + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +/// \return status code that indicates the execution status of the function. +osStatus_t osDelay (uint32_t ticks); + +/// Wait until specified time. +/// \param[in] ticks absolute time in ticks +/// \return status code that indicates the execution status of the function. +osStatus_t osDelayUntil (uint64_t ticks); + + +// ==== Timer Management Functions ==== + +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); + +/// Create and Initialize a timer. +/// \param[in] func start address of a timer call back function. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \param[in] attr timer attributes; NULL: default values. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); + +/// Get name of a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return name as NULL terminated string. +const char *osTimerGetName (osTimerId_t timer_id); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStop (osTimerId_t timer_id); + +/// Check if a timer is running. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return 0 not running, 1 running. +uint32_t osTimerIsRunning (osTimerId_t timer_id); + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerDelete (osTimerId_t timer_id); + + +// ==== Event Flags Management Functions ==== + +/// Create and Initialize an Event Flags object. +/// \param[in] attr event flags attributes; NULL: default values. +/// \return event flags ID for reference by other functions or NULL in case of error. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); + +/// Get name of an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return name as NULL terminated string. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id); + +/// Set the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be set. +/// \return event flags after setting or error code if highest bit set. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); + +/// Clear the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be cleared. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); + +/// Get the current Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return current event flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); + +/// Wait for one or more Event Flags to become signaled. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); + +/// Delete an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); + + +// ==== Mutex Management Functions ==== + +/// Create and Initialize a Mutex object. +/// \param[in] attr mutex attributes; NULL: default values. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId_t osMutexNew (const osMutexAttr_t *attr); + +/// Get name of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return name as NULL terminated string. +const char *osMutexGetName (osMutexId_t mutex_id); + +/// Acquire a Mutex or timeout if it is locked. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexRelease (osMutexId_t mutex_id); + +/// Get Thread which owns a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return thread ID of owner thread or NULL when mutex was not acquired. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexDelete (osMutexId_t mutex_id); + + +// ==== Semaphore Management Functions ==== + +/// Create and Initialize a Semaphore object. +/// \param[in] max_count maximum number of available tokens. +/// \param[in] initial_count initial number of available tokens. +/// \param[in] attr semaphore attributes; NULL: default values. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); + +/// Get name of a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return name as NULL terminated string. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); + +/// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); + +/// Get current Semaphore token count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return number of tokens available. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); + + +// ==== Memory Pool Management Functions ==== + +/// Create and Initialize a Memory Pool object. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size memory block size in bytes. +/// \param[in] attr memory pool attributes; NULL: default values. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); + +/// Get name of a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return name as NULL terminated string. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); + +/// Get maximum number of memory blocks in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return maximum number of memory blocks. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); + +/// Get memory block size in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return memory block size in bytes. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks used in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks used. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks available in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks available. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); + +/// Delete a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); + + +// ==== Message Queue Management Functions ==== + +/// Create and Initialize a Message Queue object. +/// \param[in] msg_count maximum number of messages in queue. +/// \param[in] msg_size maximum message size in bytes. +/// \param[in] attr message queue attributes; NULL: default values. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); + +/// Get name of a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return name as NULL terminated string. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id); + +/// Put a Message into a Queue or timeout if Queue is full. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[in] msg_ptr pointer to buffer with message to put into a queue. +/// \param[in] msg_prio message priority. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[out] msg_ptr pointer to buffer for message to get from a queue. +/// \param[out] msg_prio pointer to buffer for message priority or NULL. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); + +/// Get maximum number of messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum number of messages. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); + +/// Get maximum message size in a Memory Pool. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum message size in bytes. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); + +/// Get number of queued messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of queued messages. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); + +/// Get number of available slots for messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of available slots for messages. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); + +/// Reset a Message Queue to initial empty state. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); + +/// Delete a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS2_H_ diff --git a/osdepends/liteos/cmsis/cmsis_liteos.c b/osdepends/liteos/cmsis/cmsis_liteos.c index 2555815f5..31118a6b6 100644 --- a/osdepends/liteos/cmsis/cmsis_liteos.c +++ b/osdepends/liteos/cmsis/cmsis_liteos.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: CMSIS Interface * 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 @@ -22,20 +22,20 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_config.h" +#include "menuconfig.h" -#if (CMSIS_OS_VER == 1) +#if (LOSCFG_CMSIS_VERSION == 1) #include "1.0/cmsis_liteos1.c" -#elif (CMSIS_OS_VER == 2) +#elif (LOSCFG_CMSIS_VERSION == 2) #include "2.0/cmsis_liteos2.c" #endif diff --git a/osdepends/liteos/cmsis/cmsis_os.h b/osdepends/liteos/cmsis/cmsis_os.h index 409484a32..c51b9b62a 100644 --- a/osdepends/liteos/cmsis/cmsis_os.h +++ b/osdepends/liteos/cmsis/cmsis_os.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: CMSIS Interface * 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 @@ -22,20 +22,25 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#include "los_config.h" +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H -#if (CMSIS_OS_VER == 1) +#include "menuconfig.h" + +#if (LOSCFG_CMSIS_VERSION == 1) #include "1.0/cmsis_os1.h" -#elif (CMSIS_OS_VER == 2) +#elif (LOSCFG_CMSIS_VERSION == 2) #include "2.0/cmsis_os2.h" #endif + +#endif // _CMSIS_OS_H diff --git a/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile b/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile index 03b7dd011..30265680b 100644 --- a/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile +++ b/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile @@ -19,7 +19,6 @@ DEBUG = 1 # optimization OPT = -Og - USE_OTA := no OTA_IS_NEED_DTLS := no ifeq ($(USE_FOTA), yes) @@ -50,7 +49,7 @@ HEX = $(OBJCOPY) -O ihex BIN = $(OBJCOPY) -O binary -S -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../.. @@ -93,14 +92,20 @@ HAL_DRIVER_SRC = \ HARDWARE_SRC = \ ${wildcard $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Hardware/Src/*.c} C_SOURCES += $(HARDWARE_SRC) - + ifeq ($(USE_BOOTLOADER), no) + HAL_DRIVER_SRC_NO_BOOTLOADER = \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c C_SOURCES += $(HAL_DRIVER_SRC_NO_BOOTLOADER) + +LIBSEC_SRC = \ + ${wildcard $(TOP_DIR)/components/lib/libsec/src/*.c} + C_SOURCES += $(LIBSEC_SRC) + KERNEL_SRC = \ ${wildcard $(TOP_DIR)/kernel/*.c} \ ${wildcard $(TOP_DIR)/kernel/base/core/*.c} \ @@ -109,7 +114,9 @@ KERNEL_SRC = \ ${wildcard $(TOP_DIR)/kernel/base/mem/membox/*.c} \ ${wildcard $(TOP_DIR)/kernel/base/mem/common/*.c} \ ${wildcard $(TOP_DIR)/kernel/base/misc/*.c} \ + ${wildcard $(TOP_DIR)/kernel/base/mp/*.c} \ ${wildcard $(TOP_DIR)/kernel/base/om/*.c} \ + ${wildcard $(TOP_DIR)/kernel/base/sched/sched_sq/*.c} \ ${wildcard $(TOP_DIR)/kernel/extended/tickless/*.c} C_SOURCES += $(KERNEL_SRC) @@ -117,11 +124,20 @@ CMSIS_SRC = \ ${wildcard $(TOP_DIR)/osdepends/liteos/cmsis/*.c} C_SOURCES += $(CMSIS_SRC) +BSP_SRC = \ + ${wildcard $(TOP_DIR)/targets/bsp/common/*.c} +BSP_SRC_EXCLUDE = \ + $(TOP_DIR)/targets/bsp/common/console.c \ + $(TOP_DIR)/targets/bsp/common/virtual_serial.c +BSP_SRC := $(filter-out $(BSP_SRC_EXCLUDE), $(BSP_SRC)) + C_SOURCES += $(BSP_SRC) + ARCH_SRC = \ - ${wildcard $(TOP_DIR)/arch/arm/arm-m/src/*.c} \ - ${wildcard $(TOP_DIR)/arch/arm/arm-m/cortex-m4/*.c} + ${wildcard $(TOP_DIR)/arch/common/*.c} \ + ${wildcard $(TOP_DIR)/arch/arm/cortex-m/src/*.c} \ + ${wildcard $(TOP_DIR)/arch/arm/cortex-m/cortex-m4/*.c} C_SOURCES += $(ARCH_SRC) - + ifeq ($(WITH_LWIP), yes) LWIP_SRC = \ ${wildcard $(TOP_DIR)/components/net/lwip/lwip-2.0.3/src/api/*.c} \ @@ -168,15 +184,13 @@ else $(TOP_DIR)/components/connectivity/agent_tiny/atiny_lwm2m/firmware_update.c, $(ATINY_TINY_SRC)) C_SOURCES += $(ATINY_TINY_SRC_NO_FOTA) endif - + AGENT_DEMO_SRC = \ ${wildcard $(TOP_DIR)/demos/agenttiny_lwm2m/*.c} C_SOURCES += $(AGENT_DEMO_SRC) endif - - OS_DEPENDS_SRC = \ ${wildcard $(TOP_DIR)/osdepends/liteos/*.c} C_SOURCES += $(OS_DEPENDS_SRC) @@ -190,7 +204,7 @@ NEWLIB_SRC = \ ${wildcard $(TOP_DIR)/components/lib/libc/newlib_stub.c} \ ${wildcard $(TOP_DIR)/components/lib/libc/errno.c} C_SOURCES += $(NEWLIB_SRC) - + ATINY_LOG = \ ${wildcard $(TOP_DIR)/components/log/*.c} @@ -274,6 +288,7 @@ endif endif USER_SRC = \ + $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/os_adapt/os_adapt.c \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/main.c \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/system_stm32f4xx.c \ $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/usart.c \ @@ -332,13 +347,13 @@ ifeq ($(USE_OTA), yes) OTA_SRC = \ ${wildcard $(TOP_DIR)/components/ota/flag_operate/*.c} \ ${wildcard $(TOP_DIR)/components/ota/package/*.c} \ - ${wildcard $(TOP_DIR)/components/ota/utility/*.c} + ${wildcard $(TOP_DIR)/components/ota/utility/*.c} C_SOURCES += $(OTA_SRC) -C_SOURCES += $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/board.c -C_SOURCES += $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/ota_port.c -#MQTT has add flash_adaptor.c + C_SOURCES += $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/board.c + C_SOURCES += $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/ota_port.c +#MQTT has add flash_adaptor.c ifneq ($(WITH_MQTT), yes) -C_SOURCES += $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/flash_adaptor.c + C_SOURCES += $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Src/flash_adaptor.c endif endif @@ -346,10 +361,10 @@ endif # ASM sources ASM_SOURCES_S = \ - ${wildcard $(TOP_DIR)/arch/arm/arm-m/cortex-m4/gcc/los_dispatch_gcc.S} + ${wildcard $(TOP_DIR)/arch/arm/cortex-m/cortex-m4/gcc/*.S} #blow use bootloader -else +else FLAG_SRC = \ ${wildcard $(TOP_DIR)/components/ota/flag_operate/*.c} @@ -419,7 +434,7 @@ endif ifeq ($(WITH_LWIP), yes) C_DEFS += \ -DWITH_LWIP \ - -D LWIP_TIMEVAL_PRIVATE=0 + -D LWIP_TIMEVAL_PRIVATE=0 ifeq ($(USE_LWIP_TCP), yes) C_DEFS += -DLWIP_TCP=1 @@ -498,14 +513,14 @@ HAL_DRIVER_INC = \ -I $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Drivers/STM32F4xx_HAL_Driver/Inc \ -I $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy C_INCLUDES += $(HAL_DRIVER_INC) - + INCLUDE_INC = \ -I $(TOP_DIR)/include C_INCLUDES += $(INCLUDE_INC) - + LWM2M_ATINY_INC = \ - -I $(TOP_DIR)/components/connectivity/agent_tiny/atiny_lwm2m - C_INCLUDES += $(LWM2M_ATINY_INC) + -I $(TOP_DIR)/components/connectivity/agent_tiny/atiny_lwm2m + C_INCLUDES += $(LWM2M_ATINY_INC) HARDWARE_INC = \ -I $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/Hardware/Inc @@ -523,30 +538,37 @@ OTA_INC = \ endif CMSIS_INC = \ - -I $(TOP_DIR)/arch/arm/arm-m/include \ -I $(TOP_DIR)/arch/arm/common/cmsis C_INCLUDES += $(CMSIS_INC) LITEOS_CMSIS = \ -I $(TOP_DIR)/osdepends/liteos/cmsis C_INCLUDES += $(LITEOS_CMSIS) - -ifeq ($(USE_BOOTLOADER), no) -OS_CONFIG_INC = \ - -I $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/OS_CONFIG - C_INCLUDES += $(OS_CONFIG_INC) + +ifeq ($(USE_BOOTLOADER), no) +BSP_INC = \ + -I $(TOP_DIR)/targets/bsp/common \ + -I $(TOP_DIR)/targets/bsp/include \ + -I $(TOP_DIR)/targets/bsp/hw/include \ + -I $(TOP_DIR)/targets/Cloud_STM32F429IGTx_FIRE/include + C_INCLUDES += $(BSP_INC) + KERNEL_INC = \ + -I $(TOP_DIR)/kernel/base/include \ + -I $(TOP_DIR)/kernel/extended/include \ -I $(TOP_DIR)/kernel/include \ - -I $(TOP_DIR)/kernel/base/include \ - -I $(TOP_DIR)/kernel/extended/include + -I $(TOP_DIR)/components/lib/libsec/include C_INCLUDES += $(KERNEL_INC) ARCH_INC = \ - -I $(TOP_DIR)/arch/arm/arm-m/include \ - -I $(TOP_DIR)/arch/arm/arm-m/cortex-m4 + -I $(TOP_DIR)/arch/common \ + -I $(TOP_DIR)/arch/arm/include \ + -I $(TOP_DIR)/arch/arm/cortex-m/include \ + -I $(TOP_DIR)/arch/arm/cortex-m/src/include \ + -I $(TOP_DIR)/arch/arm/cortex-m/cortex-m4/include C_INCLUDES += $(ARCH_INC) - + ifeq ($(WITH_LWIP), yes) LWIP_INC = \ -I $(TOP_DIR)/components/net/lwip/lwip-2.0.3/src/include @@ -580,7 +602,7 @@ endif -ifeq ($(WITH_MQTT), yes) +ifeq ($(WITH_MQTT), yes) MQTT_INC = \ -I $(TOP_DIR)/components/connectivity/mqtt/MQTTClient-C/src \ -I $(TOP_DIR)/components/connectivity/mqtt/MQTTClient-C/src/liteOS \ @@ -620,6 +642,13 @@ CMOCKERY_TEST_INC = \ C_INCLUDES += $(CMOCKERY_TEST_INC) endif +ifeq ($(WITH_LITEOS_TEST), yes) +include test_liteos.mk +else +C_DEFS += \ + -DLOSCFG_PLATFORM_OSAPPINIT +endif + #below use bootloader else FLAG_INC = \ @@ -628,12 +657,24 @@ FLAG_INC = \ C_INCLUDES += $(FLAG_INC) endif +############################# Security Option Begin ############################# +LITEOS_SSP = -fno-stack-protector +ifeq ($(LOSCFG_CC_STACKPROTECTOR), y) + LITEOS_SSP = -fstack-protector --param ssp-buffer-size=4 +endif +ifeq ($(LOSCFG_CC_STACKPROTECTOR_STRONG), y) + LITEOS_SSP = -fstack-protector-strong +endif +ifeq ($(LOSCFG_CC_STACKPROTECTOR_ALL), y) + LITEOS_SSP = -fstack-protector-all +endif +############################# Security Option End ############################## # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) $(LITEOS_SSP) -Wall -fdata-sections -ffunction-sections ifeq ($(DEBUG), 1) CFLAGS += -g -gdwarf-2 diff --git a/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile_Sota b/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile_Sota index 3c0e84e84..205f8b070 100755 --- a/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile_Sota +++ b/targets/Cloud_STM32F429IGTx_FIRE/GCC/Makefile_Sota @@ -44,7 +44,7 @@ HEX = $(OBJCOPY) -O ihex BIN = $(OBJCOPY) -O binary -S -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../.. diff --git a/targets/Cloud_STM32F429IGTx_FIRE/GCC/STM32F429IGTx_LiteOS_bootloader.ld b/targets/Cloud_STM32F429IGTx_FIRE/GCC/STM32F429IGTx_LiteOS_bootloader.ld index 3dee3765b..af3fb9521 100644 --- a/targets/Cloud_STM32F429IGTx_FIRE/GCC/STM32F429IGTx_LiteOS_bootloader.ld +++ b/targets/Cloud_STM32F429IGTx_FIRE/GCC/STM32F429IGTx_LiteOS_bootloader.ld @@ -173,6 +173,7 @@ SECTIONS . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; + __bss_end = _ebss; } >RAM /* User_heap_stack section, used to check that there is enough RAM left */ diff --git a/targets/Cloud_STM32F429IGTx_FIRE/GCC/config.mk b/targets/Cloud_STM32F429IGTx_FIRE/GCC/config.mk index 4067c83d8..8fe1dc73c 100644 --- a/targets/Cloud_STM32F429IGTx_FIRE/GCC/config.mk +++ b/targets/Cloud_STM32F429IGTx_FIRE/GCC/config.mk @@ -63,12 +63,12 @@ USE_FOTA := yes USE_SOTA := yes ####################################### -# Lwm2m bootstrap program +# Lwm2m bootstrap program ####################################### LWM2M_BOOTSTRAP := yes ####################################### -# Lwm2m bootstrap used +# Lwm2m bootstrap used ####################################### SUPPORT_DTLS_SRV := no @@ -97,3 +97,8 @@ endif # CMockery Test ####################################### WITH_CMOCKERY_TEST := no + +####################################### +# LiteOS test +####################################### +WITH_LITEOS_TEST := no diff --git a/targets/Cloud_STM32F429IGTx_FIRE/Inc/sys_init.h b/targets/Cloud_STM32F429IGTx_FIRE/Inc/sys_init.h index 07ea5e467..93070e445 100644 --- a/targets/Cloud_STM32F429IGTx_FIRE/Inc/sys_init.h +++ b/targets/Cloud_STM32F429IGTx_FIRE/Inc/sys_init.h @@ -44,7 +44,7 @@ #include "los_config.h" #include "los_sys.h" #include "los_typedef.h" -#include "los_task.ph" +#include "los_task_pri.h" #include "stdlib.h" #include "string.h" diff --git a/targets/Cloud_STM32F429IGTx_FIRE/OS_CONFIG/target_config.h b/targets/Cloud_STM32F429IGTx_FIRE/OS_CONFIG/target_config.h deleted file mode 100644 index 0d6d7a4cb..000000000 --- a/targets/Cloud_STM32F429IGTx_FIRE/OS_CONFIG/target_config.h +++ /dev/null @@ -1,418 +0,0 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2016-2018>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -/**@defgroup los_config System configuration items - * @ingroup kernel - */ - -#ifndef _TARGET_CONFIG_H -#define _TARGET_CONFIG_H - -#include "los_typedef.h" -#include "stm32f4xx.h" - - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#define LOSCFG_CORTEX_M4 - -/*============================================================================= - System clock module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * System clock (unit: HZ) - */ -#define OS_SYS_CLOCK (SystemCoreClock) - -/** - * @ingroup los_config - * Number of Ticks in one second - */ -#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL) - -/** - * @ingroup los_config - * External configuration item for timer tailoring - */ -#define LOSCFG_BASE_CORE_TICK_HW_TIME NO - -/** - * @ingroup los_config - * Configuration liteos kernel tickless - */ -#define LOSCFG_KERNEL_TICKLESS NO - -/*============================================================================= - Hardware interrupt module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for hardware interrupt tailoring - */ -#define LOSCFG_PLATFORM_HWI YES - -/** - * @ingroup los_config - * Maximum number of used hardware interrupts, including Tick timer interrupts. - */ -#define LOSCFG_PLATFORM_HWI_LIMIT 96 - - -/*============================================================================= - Task module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Default task priority - */ -#define LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO 10 - -/** - * @ingroup los_config - * Maximum supported number of tasks except the idle task rather than the number of usable tasks - */ -#define LOSCFG_BASE_CORE_TSK_LIMIT 15 // max num task - -/** - * @ingroup los_config - * Size of the idle task stack - */ -#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE (0x500U) // IDLE task stack - -/** - * @ingroup los_config - * Default task stack size - */ -#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x2D0U) // default stack - -/** - * @ingroup los_config - * Minimum stack size. - */ -#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE (0x130U) - -/** - * @ingroup los_config - * Configuration item for task Robin tailoring - */ -#define LOSCFG_BASE_CORE_TIMESLICE YES - -/** - * @ingroup los_config - * Longest execution time of tasks with the same priorities - */ -#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 10 - -/** - * @ingroup los_config - * Configuration item for task (stack) monitoring module tailoring - */ -#define LOSCFG_BASE_CORE_TSK_MONITOR YES - -/** - * @ingroup los_config - * Configuration item for task perf task filter hook - */ -#define LOSCFG_BASE_CORE_EXC_TSK_SWITCH YES - -/** - * @ingroup los_config - * Configuration item for performance moniter unit - */ -#define OS_INCLUDE_PERF YES - -/** - * @ingroup los_config - * Define a usable task priority.Highest task priority. - */ -#define LOS_TASK_PRIORITY_HIGHEST 0 - -/** - * @ingroup los_config - * Define a usable task priority.Lowest task priority. - */ -#define LOS_TASK_PRIORITY_LOWEST 31 - - -/*============================================================================= - Semaphore module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for semaphore module tailoring - */ -#define LOSCFG_BASE_IPC_SEM YES - -/** - * @ingroup los_config - * Maximum supported number of semaphores - */ -#define LOSCFG_BASE_IPC_SEM_LIMIT 20 // the max sem-numb - - -/*============================================================================= - Mutex module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for mutex module tailoring - */ -#define LOSCFG_BASE_IPC_MUX YES - -/** - * @ingroup los_config - * Maximum supported number of mutexes - */ -#define LOSCFG_BASE_IPC_MUX_LIMIT 20 // the max mutex-num - - -/*============================================================================= - Queue module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for queue module tailoring - */ -#define LOSCFG_BASE_IPC_QUEUE YES - -/** - * @ingroup los_config - * Maximum supported number of queues rather than the number of usable queues - */ -#define LOSCFG_BASE_IPC_QUEUE_LIMIT 10 //the max queue-numb - - -/*============================================================================= - Software timer module configuration -=============================================================================*/ - -#if (LOSCFG_BASE_IPC_QUEUE == YES) -/** - * @ingroup los_config - * Configuration item for software timer module tailoring - */ -#define LOSCFG_BASE_CORE_SWTMR YES - -#define LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE - -#define LOSCFG_BASE_CORE_SWTMR_TASK YES - -#define LOSCFG_BASE_CORE_SWTMR_ALIGN YES -#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 - * Maximum supported number of software timers rather than the number of usable software timers - */ -#define LOSCFG_BASE_CORE_SWTMR_LIMIT 16 // the max SWTMR numb - -/** - * @ingroup los_config - * Max number of software timers ID - */ -#define OS_SWTMR_MAX_TIMERID ((65535/LOSCFG_BASE_CORE_SWTMR_LIMIT) * LOSCFG_BASE_CORE_SWTMR_LIMIT) - -/** - * @ingroup los_config - * Maximum size of a software timer queue - */ -#define OS_SWTMR_HANDLE_QUEUE_SIZE (LOSCFG_BASE_CORE_SWTMR_LIMIT + 0) - -/** - * @ingroup los_config - * Minimum divisor of software timer multiple alignment - */ -#define LOS_COMMON_DIVISOR 10 -#endif - - -/*============================================================================= - Memory module configuration -=============================================================================*/ - -extern UINT8 *m_aucSysMem0; -extern UINT32 __LOS_HEAP_ADDR_START__; -extern UINT32 __LOS_HEAP_ADDR_END__; - -/** - * @ingroup los_config - * Starting address of the memory - */ -#define OS_SYS_MEM_ADDR (VOID *)__LOS_HEAP_ADDR_START__ - -/** - * @ingroup los_config - * Ending address of the memory - */ -extern UINT32 g_sys_mem_addr_end; - -/** - * @ingroup los_config - * Memory size - */ -#define OS_SYS_MEM_SIZE ((UINT32)(__LOS_HEAP_ADDR_END__ - __LOS_HEAP_ADDR_START__ + 1)) - -/** - * @ingroup los_config - * Configuration module tailoring of mem node integrity checking - */ -#define LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK YES - -/** - * @ingroup los_config - * Configuration module tailoring of mem node size checking - */ -#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK YES - -#define LOSCFG_MEMORY_BESTFIT YES - -/** - * @ingroup los_config - * Configuration module tailoring of more mempry pool checking - */ -#define LOSCFG_MEM_MUL_POOL YES - -/** - * @ingroup los_config - * Number of memory checking blocks - */ -#define OS_SYS_MEM_NUM 20 - -/** - * @ingroup los_config - * Configuration module tailoring of slab memory - */ -#define LOSCFG_KERNEL_MEM_SLAB YES - - -/*============================================================================= - fw Interface configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for the monitoring of task communication - */ -#define LOSCFG_COMPAT_CMSIS_FW YES - - -/*============================================================================= - others -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration system wake-up info to open - */ -#define OS_SR_WAKEUP_INFO YES - -/** - * @ingroup los_config - * Configuration CMSIS_OS_VER - */ -#define CMSIS_OS_VER 2 - - -/*============================================================================= - Exception module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for exception tailoring - */ -#define LOSCFG_PLATFORM_EXC NO - - -/*============================================================================= - Runstop module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for runstop module tailoring - */ -#define LOSCFG_KERNEL_RUNSTOP NO - - -/*============================================================================= - track configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for track - */ -#define LOSCFG_BASE_MISC_TRACK NO - -/** - * @ingroup los_config - * Max count of track items - */ -#define LOSCFG_BASE_MISC_TRACK_MAX_COUNT 1024 - -/*============================================================================= - VFS module configuration -=============================================================================*/ - -/** - * @ingroup los_config - * Configuration item for enabling LiteOS VFS - */ -#ifndef LOSCFG_ENABLE_VFS -#define LOSCFG_ENABLE_VFS YES -#endif - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - - -#endif /* _TARGET_CONFIG_H */ diff --git a/targets/Cloud_STM32F429IGTx_FIRE/Src/main.c b/targets/Cloud_STM32F429IGTx_FIRE/Src/main.c index 8a436965c..3103c9498 100644 --- a/targets/Cloud_STM32F429IGTx_FIRE/Src/main.c +++ b/targets/Cloud_STM32F429IGTx_FIRE/Src/main.c @@ -34,9 +34,8 @@ #include "main.h" #include "sys_init.h" - #include "los_base.h" -#include "los_task.ph" +#include "los_task_pri.h" #include "los_typedef.h" #include "los_sys.h" @@ -54,20 +53,13 @@ int main(void) UINT32 uwRet = LOS_OK; HardWare_Init(); - uwRet = LOS_KernelInit(); - if (uwRet != LOS_OK) - { - return LOS_NOK; - } - - extern UINT32 create_work_tasks(VOID); - uwRet = create_work_tasks(); + uwRet = OsMain(); if (uwRet != LOS_OK) { return LOS_NOK; } + OsStart(); - (void)LOS_Start(); return 0; } diff --git a/targets/Cloud_STM32F429IGTx_FIRE/Src/usart.c b/targets/Cloud_STM32F429IGTx_FIRE/Src/usart.c index bc024ec91..2ea6858cc 100644 --- a/targets/Cloud_STM32F429IGTx_FIRE/Src/usart.c +++ b/targets/Cloud_STM32F429IGTx_FIRE/Src/usart.c @@ -259,4 +259,8 @@ __attribute__((used)) int _write(int fd, char *ptr, int len) /* USER CODE BEGIN 1 */ - +int uart_write(const char *buf, int len, int timeout) +{ + (void)HAL_UART_Transmit(&huart1, (uint8_t *)buf, len, 0xFFFF); + return len; +} diff --git a/targets/Cloud_STM32F429IGTx_FIRE/Src/user_task.c b/targets/Cloud_STM32F429IGTx_FIRE/Src/user_task.c index 3983c6843..90ca5543e 100755 --- a/targets/Cloud_STM32F429IGTx_FIRE/Src/user_task.c +++ b/targets/Cloud_STM32F429IGTx_FIRE/Src/user_task.c @@ -57,13 +57,12 @@ static UINT32 g_fs_tskHandle; void atiny_task_entry(void) { - extern void agent_tiny_entry(); + extern void agent_tiny_entry(void); #if defined(WITH_LINUX) || defined(WITH_LWIP) hieth_hw_init(); net_init(); #elif defined(WITH_AT_FRAMEWORK) - #if defined(USE_ESP8266) extern at_adaptor_api esp8266_interface; printf("\r\n=============agent_tiny_entry USE_ESP8266============================\n"); @@ -186,7 +185,7 @@ uint32_t create_dtls_server_task() #endif -UINT32 create_work_tasks(VOID) +UINT32 app_init(VOID) { UINT32 uwRet = LOS_OK; diff --git a/targets/Cloud_STM32F429IGTx_FIRE/include/asm/hal_platform_ints.h b/targets/Cloud_STM32F429IGTx_FIRE/include/asm/hal_platform_ints.h new file mode 100644 index 000000000..1cd97b081 --- /dev/null +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/asm/hal_platform_ints.h @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: hal platform header + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef PLATFORM_HAL_PLATFORM_INTS_H +#define PLATFORM_HAL_PLATFORM_INTS_H + +#include "stm32f429xx.h" +#include"los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * Maximum number of supported hardware devices that generate hardware interrupts. + * The maximum number of hardware devices that generate hardware interrupts is 128. + */ +#define OS_HWI_MAX_NUM 240 + +/** + * Maximum interrupt number. + */ +#define OS_HWI_MAX ((OS_HWI_MAX_NUM) - 1) + +/** + * Minimum interrupt number. + */ +#define OS_HWI_MIN 0 + +/** + * Maximum usable interrupt number. + */ +#define OS_USER_HWI_MAX OS_HWI_MAX + +/** + * Minimum usable interrupt number. + */ +#define OS_USER_HWI_MIN OS_HWI_MIN + +#define OS_TICK_INT_NUM (SysTick_IRQn + OS_SYS_VECTOR_CNT) + +#define IO_ADDRESS(x) (x) + +#define HAL_READ_UINT8(addr, data) READ_UINT8(data, addr) + +#define HAL_WRITE_UINT8(addr, data) WRITE_UINT8(data, addr) + +#define HAL_READ_UINT32(addr, data) READ_UINT32(data, addr) + +#define HAL_WRITE_UINT32(addr, data) WRITE_UINT32(data, addr) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif // PLATFORM_HAL_PLATFORM_INTS_H diff --git a/kernel/base/core/los_priqueue.inc b/targets/Cloud_STM32F429IGTx_FIRE/include/asm/platform.h similarity index 77% rename from kernel/base/core/los_priqueue.inc rename to targets/Cloud_STM32F429IGTx_FIRE/include/asm/platform.h index fa940135b..51278e1bc 100644 --- a/kernel/base/core/los_priqueue.inc +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/asm/platform.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: asm platform header * 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 @@ -22,19 +22,20 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_PRIQUEUE_INC -#define _LOS_PRIQUEUE_INC +#ifndef _ASM_PLATFORM_H +#define _ASM_PLATFORM_H -#include "los_priqueue.ph" +#include "menuconfig.h" +#include "asm/hal_platform_ints.h" -#endif /* _LOS_PRIQUEUE_INC */ +#endif diff --git a/kernel/base/om/los_err.inc b/targets/Cloud_STM32F429IGTx_FIRE/include/board.h similarity index 79% rename from kernel/base/om/los_err.inc rename to targets/Cloud_STM32F429IGTx_FIRE/include/board.h index 555ad8a73..a20739b3c 100644 --- a/kernel/base/om/los_err.inc +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/board.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: board Config HeadFile * 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 @@ -22,19 +22,17 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -#ifndef _LOS_ERR_INC -#define _LOS_ERR_INC +#ifndef _BOARD_H +#define _BOARD_H -#include "los_err.ph" - -#endif /* _LOS_ERR_INC */ +#endif diff --git a/arch/arm/arm-m/cortex-m3/los_exc.inc b/targets/Cloud_STM32F429IGTx_FIRE/include/clock.h similarity index 75% rename from arch/arm/arm-m/cortex-m3/los_exc.inc rename to targets/Cloud_STM32F429IGTx_FIRE/include/clock.h index f3f482f81..4f71c5ae6 100644 --- a/arch/arm/arm-m/cortex-m3/los_exc.inc +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/clock.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: Hisoc Clock Implementation * 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 @@ -22,32 +22,34 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ -#ifndef _LOS_EXC_INC -#define _LOS_EXC_INC + * --------------------------------------------------------------------------- */ -#include "los_exc.ph" -#include "los_sys.ph" +#ifndef __HISOC_CLOCK_H__ +#define __HISOC_CLOCK_H__ + +#include "asm/platform.h" #ifdef __cplusplus #if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ +extern "C"{ +#endif +#endif /* __cplusplus */ +#define get_bus_clk() 216000000 #ifdef __cplusplus #if __cplusplus } -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ +#endif +#endif /* __cplusplus */ + +#endif -#endif /* _LOS_EXC_INC */ diff --git a/targets/Cloud_STM32F429IGTx_FIRE/include/menuconfig.h b/targets/Cloud_STM32F429IGTx_FIRE/include/menuconfig.h new file mode 100644 index 000000000..d4eab9584 --- /dev/null +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/menuconfig.h @@ -0,0 +1,96 @@ +/* + * Automatically generated C config: don't edit + */ +/* + * Version Number + */ +#ifndef LOSCFG_MODULE_SWITCH +#define LOSCFG_MODULE_SWITCH +/* + * Compiler + */ +#define LOSCFG_COMPILER_EABI_32 1 + +/* + * Platform + */ +#define __LOSCFG_PLATFORM__ "Cloud_STM32F429IGTx_FIRE" +#define LOSCFG_PLATFORM_STM32F429IGTX 1 +#define LOSCFG_PLATFORM_BSP_GIC_V2 1 +#undef LOSCFG_PLATFORM_BSP_GIC_V3 +#define LOSCFG_ARCH_ARM 1 +#define LOSCFG_ARCH_ARM_AARCH32 1 +#define LOSCFG_ARCH_ARM_V7M 1 +#define __LOSCFG_ARCH_ARM_VER__ "armv7-m" +#define LOSCFG_ARCH_FPU_VFP_V4 1 +#define LOSCFG_ARCH_FPU_VFP_D16 1 +#define __LOSCFG_ARCH_FPU__ "fpv4-sp-d16" +#define LOSCFG_ARCH_CORTEX_M4 1 +#define __LOSCFG_ARCH_CPU__ "cortex-m4" + +/* + * Extra Configurations + */ +#define LOSCFG_ARCH_FPU_DISABLE 1 + +/* + * Kernel + */ +#define LOSCFG_KERNEL_LITEKERNEL 1 +#undef LOSCFG_KERNEL_MEM_BESTFIT +#define LOSCFG_KERNEL_MEM_BESTFIT_LITTLE 1 +#undef LOSCFG_KERNEL_EXTKERNEL +#define LOSCFG_SCHED_SQ 1 + +/* + * Lib + */ +#define LOSCFG_LIB_LIBC 1 +#undef LOSCFG_LIB_LIBM + +/* + * Compat + */ +#define LOSCFG_COMPAT_CMSIS 1 +#define LOSCFG_CMSIS_VERSION 1 +#undef LOSCFG_COMPAT_POSIX +#undef LOSCFG_COMPAT_LINUX + +/* + * FileSystem + */ +#undef LOSCFG_FS_VFS + +/* + * Net + */ +#undef LOSCFG_NET_LWIP_SACK + +/* + * Debug + */ +#define LOSCFG_COMPILE_DEBUG 1 +#undef LOSCFG_PLATFORM_ADAPT +#undef LOSCFG_COREDUMP +#undef LOSCFG_GDB +#undef LOSCFG_ENABLE_MAGICKEY +#define LOSCFG_THUMB 1 +#undef LOSCFG_DEBUG_VERSION +#undef LOSCFG_DRIVERS_UART +#undef LOSCFG_PLATFORM_UART_WITHOUT_VFS +#define LOSCFG_PLATFORM_NO_UART 1 + +/* + * Driver + */ +#undef LOSCFG_DRIVERS + +/* + * Stack Smashing Protector (SSP) Compiler Feature + */ +#define LOSCFG_CC_NO_STACKPROTECTOR 1 +#undef LOSCFG_CC_STACKPROTECTOR +#undef LOSCFG_CC_STACKPROTECTOR_STRONG +#undef LOSCFG_CC_STACKPROTECTOR_ALL + +#endif diff --git a/targets/Cloud_STM32F429IGTx_FIRE/include/platform_config.h b/targets/Cloud_STM32F429IGTx_FIRE/include/platform_config.h new file mode 100644 index 000000000..7cb469313 --- /dev/null +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/platform_config.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: platform Config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef __PLATFORM_CONFIG_H__ +#define __PLATFORM_CONFIG_H__ + +#include "clock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define __CM4_REV 0x0001U /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1U /*!< STM32F4XX provides an MPU */ +#define __NVIC_PRIO_BITS 4U /*!< STM32F4XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /*!< FPU present */ + + +#define LOSCFG_BASE_CORE_EXC_TSK_SWITCH YES +#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 + +extern UINT32 __LOS_HEAP_ADDR_START__; +extern UINT32 __LOS_HEAP_ADDR_END__; +#define OS_SYS_MEM_SIZE ((UINT32)(__LOS_HEAP_ADDR_END__ - __LOS_HEAP_ADDR_START__ + 1)) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/targets/Cloud_STM32F429IGTx_FIRE/include/system_config.h b/targets/Cloud_STM32F429IGTx_FIRE/include/system_config.h new file mode 100644 index 000000000..ff212b0c2 --- /dev/null +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/system_config.h @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _SYSTEM_CONFIG_H +#define _SYSTEM_CONFIG_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** system source configuration**/ +#define LOSCFG_PLATFORM_HWI_LIMIT 96 +/** + * @ingroup los_config + * Maximum supported number of tasks inluding the idle task + */ +#define LOSCFG_BASE_CORE_TSK_CONFIG 15 +/** + * @ingroup los_config + * Maximum supported number of semaphores + */ +#define LOSCFG_BASE_IPC_SEM_CONFIG 20 +/** + * @ingroup los_config + * Maximum supported number of mutexes + */ +#define LOSCFG_BASE_IPC_MUX_CONFIG 20 +/** + * @ingroup los_config + * Maximum supported number of queues rather than the number of usable queues + */ +#define LOSCFG_BASE_IPC_QUEUE_CONFIG 10 +/** + * @ingroup los_config + * Maximum supported number of software timers rather than the number of usable software timers + */ +#define LOSCFG_BASE_CORE_SWTMR_CONFIG 16 + +#define LOS_TASK_MIN_STACK_SIZE (ALIGN(0x400, 4)) + +#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE 0x600 + +#define LOSCFG_COMPAT_CMSIS_FW YES + +#define LOSCFG_NO_SHARED_IRQ + +#define LOSCFG_PLATFORM_EXC YES + +#define LOSCFG_CC_STACKPROTECTOR_STRONG YES + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SYSTEM_CONFIG_H*/ diff --git a/targets/Cloud_STM32F429IGTx_FIRE/include/uart.h b/targets/Cloud_STM32F429IGTx_FIRE/include/uart.h new file mode 100644 index 000000000..036d59881 --- /dev/null +++ b/targets/Cloud_STM32F429IGTx_FIRE/include/uart.h @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: uart config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef __UART_H__ +#define __UART_H__ + +#include "stm32f4xx_hal.h" + +#define UART_WITH_LOCK 1 +#define UART_WITHOUT_LOCK 0 + +extern int uart_write(const char *buf, int len, int timeout); +#define UartPuts(str, len, isLock) uart_write(str, len, 0xFFFF) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/kernel/base/include/los_typedef.ph b/targets/Cloud_STM32F429IGTx_FIRE/os_adapt/os_adapt.c similarity index 80% rename from kernel/base/include/los_typedef.ph rename to targets/Cloud_STM32F429IGTx_FIRE/os_adapt/os_adapt.c index 483a53114..ea8b28243 100644 --- a/kernel/base/include/los_typedef.ph +++ b/targets/Cloud_STM32F429IGTx_FIRE/os_adapt/os_adapt.c @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: LiteOS adaptor file. * 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 @@ -22,19 +22,18 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_TYPEDEF_PH -#define _LOS_TYPEDEF_PH - + * --------------------------------------------------------------------------- */ #include "los_typedef.h" -#endif /* _LOS_TYPEDEF_PH */ +VOID OsBackTrace(VOID) +{ + +} diff --git a/targets/Mini_Project/cortex-m0plus_without_driver/GCC/Makefile b/targets/Mini_Project/cortex-m0plus_without_driver/GCC/Makefile index 5d42055d1..c7ba48c4a 100644 --- a/targets/Mini_Project/cortex-m0plus_without_driver/GCC/Makefile +++ b/targets/Mini_Project/cortex-m0plus_without_driver/GCC/Makefile @@ -48,7 +48,7 @@ HEX = $(OBJCOPY) -O ihex BIN = $(OBJCOPY) -O binary -S -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../../.. TARGET_DIR = $(PROJECTBASE)/.. diff --git a/targets/Mini_Project/cortex-m3_without_driver/GCC/Makefile b/targets/Mini_Project/cortex-m3_without_driver/GCC/Makefile index 1d43678fd..e68fe5515 100644 --- a/targets/Mini_Project/cortex-m3_without_driver/GCC/Makefile +++ b/targets/Mini_Project/cortex-m3_without_driver/GCC/Makefile @@ -48,7 +48,7 @@ HEX = $(OBJCOPY) -O ihex BIN = $(OBJCOPY) -O binary -S -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../../.. TARGET_DIR = $(PROJECTBASE)/.. diff --git a/targets/Mini_Project/cortex-m4_without_driver/GCC/Makefile b/targets/Mini_Project/cortex-m4_without_driver/GCC/Makefile index 7516a7d18..d514aa8c3 100644 --- a/targets/Mini_Project/cortex-m4_without_driver/GCC/Makefile +++ b/targets/Mini_Project/cortex-m4_without_driver/GCC/Makefile @@ -48,7 +48,7 @@ HEX = $(OBJCOPY) -O ihex BIN = $(OBJCOPY) -O binary -S -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../../.. TARGET_DIR = $(PROJECTBASE)/.. diff --git a/targets/NXP_LPC51U68/GCC/Makefile b/targets/NXP_LPC51U68/GCC/Makefile index 92eba0f1a..8b2232773 100644 --- a/targets/NXP_LPC51U68/GCC/Makefile +++ b/targets/NXP_LPC51U68/GCC/Makefile @@ -48,7 +48,7 @@ HEX = $(OBJCOPY) -O ihex BIN = $(OBJCOPY) -O binary -S -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../.. diff --git a/targets/STM32F103VET6_NB_GCC/GCC/Makefile b/targets/STM32F103VET6_NB_GCC/GCC/Makefile index 663c5dd94..a8f381e98 100644 --- a/targets/STM32F103VET6_NB_GCC/GCC/Makefile +++ b/targets/STM32F103VET6_NB_GCC/GCC/Makefile @@ -42,7 +42,7 @@ BIN = $(OBJCOPY) -O binary -S ####################################### -PROJECTBASE = $(PWD) +PROJECTBASE = $(CURDIR) override PROJECTBASE := $(abspath $(PROJECTBASE)) TOP_DIR = $(PROJECTBASE)/../../.. diff --git a/targets/bsp/Makefile b/targets/bsp/Makefile new file mode 100644 index 000000000..b663779b9 --- /dev/null +++ b/targets/bsp/Makefile @@ -0,0 +1,86 @@ +include $(LITEOSTOPDIR)/config.mk + +MODULE_NAME := bsp + +LOCAL_SRCS = $(wildcard board/$(LITEOS_PLATFORM)/*.c) \ + $(wildcard $(HWI_SRC)/*.c) \ + $(wildcard $(TIMER_SRC)/*.c) \ + $(wildcard $(HRTIMER_SRC)/*.c) \ + $(wildcard $(UART_SRC)/*.c) + +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/lib/libc/stdio \ + -I $(LITEOSTOPDIR)/compat/posix/src \ + -I $(LITEOSTOPDIR)/drivers/random/dev/random + +ifeq ($(LOSCFG_PLATFORM_DVFS), y) +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/dvfs/*.c) +endif + +ifeq ($(LOSCFG_SHELL_FULL_CAP), y) +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/extcmd/*.c) +endif + +ifeq ($(LOSCFG_DRIVERS_MMC), y) +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/mmc/*.c) +MMC_INCLUDE += -I $(LITEOSTOPDIR)/drivers/mmc/host/$(MMC_HOST_DIR) +LOCAL_INCLUDE += $(MMC_INCLUDE) +endif + +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/drivers/*.c) +ifeq ($(findstring y, $(LOSCFG_PLATFORM_HI3516DV300)$(LOSCFG_PLATFORM_HI3556V200)), y) +LOCAL_SRCS += $(wildcard common/*.c) +ifneq ($(LOSCFG_FS_VFS), y) +LOCAL_SRCS := $(filter-out common/console.c common/virtual_serial.c, $(LOCAL_SRCS)) +endif +else +LOCAL_SRCS += $(wildcard common/los_config.c) +LOCAL_SRCS += $(wildcard common/los_printf.c) +endif + +ifeq ($(LOSCFG_DRIVERS_NETDEV), y) +LOCAL_SRCS += $(wildcard $(NET_SRC)/*.c) +endif + +ifeq ($(LOSCFG_DRIVERS_RANDOM), y) +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/random/*.c) +endif + +ifeq ($(LOSCFG_DRIVERS_USB), y) +LOCAL_SRCS += $(wildcard $(USB_SRC)/*.c) +endif + +ifeq ($(LOSCFG_PLATFORM_ADAPT), y) +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/os_adapt/*.c) +endif + +LOCAL_INCLUDE += -I $(wildcard board)/$(LITEOS_PLATFORM)/include/pm +LOCAL_SRCS += $(wildcard board/$(LITEOS_PLATFORM)/pm/*.c) + +ifeq ($(LOSCFG_KERNEL_TICKLESS), y) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/include +endif + +ifeq ($(LOSCFG_KERNEL_TRACE), y) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/include +endif + +ifeq ($(LOSCFG_KERNEL_CPUP), y) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/include +endif + +ifeq ($(LOSCFG_KERNEL_RUNSTOP), y) +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/include +endif + +ifndef LOSCFG_PLATFORM_OSAPPINIT +LOCAL_INCLUDE += -I $(LITEOSTOPDIR)/test/include +endif + +ALL_ASSRCS := $(wildcard board/$(LITEOS_PLATFORM)/*.S) +ASSRCS := $(subst board/$(LITEOS_PLATFORM)/board.ld.S,,$(ALL_ASSRCS)) + +LOCAL_SRCS += $(ASSRCS) + +LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS) + +include $(MODULE) diff --git a/targets/bsp/bsp.mk b/targets/bsp/bsp.mk new file mode 100644 index 000000000..f2b991fac --- /dev/null +++ b/targets/bsp/bsp.mk @@ -0,0 +1,87 @@ +############################# SRCs ################################# +HWI_SRC := +MMU_SRC := +NET_SRC := +TIMER_SRC := +HRTIMER_SRC := +UART_SRC := +USB_SRC := + +############################# HI3556V200 Options################################# +ifeq ($(LOSCFG_PLATFORM_HI3556V200), y) + HWI_TYPE := arm/interrupt/gic + TIMER_TYPE := arm/timer/arm_generic + HRTIMER_TYPE := hisoc/hrtimer + NET_TYPE := hieth + UART_TYPE := amba-pl011 + USB_TYPE := usb3.0_hi3556v200 + LITEOS_CMACRO_TEST += -DTEST3556V200 + +########################## HI3516DV300 Options############################## +else ifeq ($(LOSCFG_PLATFORM_HI3516DV300), y) + HWI_TYPE := arm/interrupt/gic + TIMER_TYPE := arm/timer/arm_generic + HRTIMER_TYPE := hisoc/hrtimer + NET_TYPE := hieth + UART_TYPE := amba-pl011 + USB_TYPE := usb3.0_hi3516dv300 + LITEOS_CMACRO_TEST += -DTEST3516DV300 + +########################## hi1980_imu Options############################## +else ifeq ($(LOSCFG_PLATFORM_HI1980_IMU), y) + HWI_TYPE := arm/interrupt/gic + TIMER_TYPE := arm/timer/arm_generic + UART_TYPE := amba-pl011 + WARNING_AS_ERROR := + LITEOS_CMACRO_TEST += -DTESTHI1980IMU + +########################## qemu virt a53 Options############################## +else ifeq ($(LOSCFG_PLATFORM_QEMU_VIRT_A53), y) + HWI_TYPE := arm/interrupt/gic + TIMER_TYPE := arm/timer/arm_generic + UART_TYPE := amba-pl011 + LITEOS_CMACRO_TEST += -DTESTVIRTA53 + +######################### realview pbx a9 Options############################# +else ifeq ($(LOSCFG_PLATFORM_PBX_A9), y) + HWI_TYPE := arm/interrupt/gic + TIMER_TYPE := arm/timer/arm_private + UART_TYPE := amba-pl011 + LITEOS_CMACRO_TEST += -DTESTPBXA9 +######################### STM32F769IDISCOVERY Options############################# +else ifeq ($(LOSCFG_PLATFORM_STM32F769IDISCOVERY), y) + LITEOS_CMACRO_TEST += -DTESTSTM32F769IDISCOVERY + TIMER_TYPE := arm/timer/arm_cortex_m + +######################### STM32F429IGTX Options############################# +else ifeq ($(LOSCFG_PLATFORM_STM32F429IGTX), y) + LITEOS_CMACRO_TEST += -DTESTSTM32F429IGTX +endif + +HWI_SRC := hw/$(HWI_TYPE) +TIMER_SRC := hw/$(TIMER_TYPE) +HRTIMER_SRC := hw/$(HRTIMER_TYPE) +NET_SRC := net/$(NET_TYPE) +UART_SRC := uart/$(UART_TYPE) +USB_SRC := usb/$(USB_TYPE) + +LITEOS_BASELIB += -lbsp + +LITEOS_PLATFORM := $(subst $\",,$(LOSCFG_PLATFORM)) + +PLATFORM_INCLUDE := -I $(LITEOSTOPDIR)/platform/bsp/board/$(LITEOS_PLATFORM)/include \ + -I $(LITEOSTOPDIR)/platform/bsp/common \ + -I $(LITEOSTOPDIR)/platform/bsp/common/pm \ + -I $(LITEOSTOPDIR)/platform/bsp/hw/include \ + -I $(LITEOSTOPDIR)/platform/bsp/include \ + -I $(LITEOSTOPDIR)/platform/bsp/$(UART_SRC) + +ifeq ($(findstring y, $(LOSCFG_PLATFORM_HI3516DV300)$(LOSCFG_PLATFORM_HI3556V200)), y) + PLATFORM_INCLUDE += -I $(LITEOSTOPDIR)/platform/bsp/board/$(LITEOS_PLATFORM)/include/hisoc +endif + +-include $(LITEOSTOPDIR)/platform/bsp/board/$(LITEOS_PLATFORM)/board.mk + +LIB_SUBDIRS += platform/bsp +LITEOS_PLATFORM_INCLUDE += $(PLATFORM_INCLUDE) +LITEOS_CXXINCLUDE += $(PLATFORM_INCLUDE) diff --git a/targets/bsp/common/console.c b/targets/bsp/common/console.c new file mode 100644 index 000000000..53ee206c4 --- /dev/null +++ b/targets/bsp/common/console.c @@ -0,0 +1,1417 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Console Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "console.h" +#include "fcntl.h" +#ifdef CONFIG_FILE_MODE +#include "stdarg.h" +#endif +#include "unistd.h" +#include "securec.h" +#include "inode/inode.h" +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#endif +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#include "shell_pri.h" +#endif +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define EACH_CHAR 1 +/* Inter-module variable */ +extern UINT32 g_uart_fputc_en; +STATIC UINT32 ConsoleSendTask(UINTPTR param); +STATIC UINT8 g_taskConsoleIDArray[LOSCFG_BASE_CORE_TSK_CONFIG]; + + +STATIC SPIN_LOCK_INIT(g_consoleSpin); + +#define SHELL_TASK_PRIORITY 9 +#define CONSOLE_CIRBUF_EVENT 0x02U +#define CONSOLE_SEND_TASK_EXIT 0x04U +#define CONSOLE_SEND_TASK_RUNNING 0x10U + +CONSOLE_CB *g_console[CONSOLE_NUM]; +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +/* + * acquire uart driver function and filep of /dev/console, + * then store uart driver function in *filepOps + * and store filep of /dev/console in *privFilep. + */ +INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **filepOps) +{ + INT32 ret; + + if ((filep == NULL) || (filep->f_inode == NULL) || (filep->f_inode->i_private == NULL)) { + ret = EINVAL; + goto ERROUT; + } + + /* to find console device's filep(now it is *privFilep) throught i_private */ + *privFilep = (struct file *)filep->f_inode->i_private; + if (((*privFilep)->f_inode == NULL) || ((*privFilep)->f_inode->u.i_ops == NULL)) { + ret = EINVAL; + goto ERROUT; + } + + /* to find uart driver operation function throutht u.i_opss */ + *filepOps = (*privFilep)->f_inode->u.i_ops; + + return ENOERR; +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +INT32 ConsoleTcGetAttr(INT32 fd, struct termios *termios) +{ + struct file *filep = NULL; + CONSOLE_CB *consoleCB = NULL; + + if ((fd >= STDIN_FILENO) && (fd <= STDERR_FILENO)) { + fd = ConsoleUpdateFd(); + if (fd < STDIN_FILENO) { + return -EBADF; + } + } + + filep = fs_getfilep(fd); + if (filep == NULL) { + return -EPERM; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + return -EFAULT; + } + + termios->c_lflag = consoleCB->consoleTermios.c_lflag; + return LOS_OK; +} + +INT32 ConsoleTcSetAttr(INT32 fd, INT32 actions, const struct termios *termios) +{ + struct file *filep = NULL; + CONSOLE_CB *consoleCB = NULL; + + (VOID)actions; + if ((fd >= STDIN_FILENO) && (fd <= STDERR_FILENO)) { + fd = ConsoleUpdateFd(); + if (fd < STDIN_FILENO) { + return -EBADF; + } + } + + filep = fs_getfilep(fd); + if (filep == NULL) { + return -EPERM; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + return -EFAULT; + } + consoleCB->consoleTermios.c_lflag = termios->c_lflag; + return LOS_OK; +} + +STATIC UINT32 ConsoleRefcountGet(const CONSOLE_CB *consoleCB) +{ + return consoleCB->refCount; +} + +STATIC VOID ConsoleRefcountSet(CONSOLE_CB *consoleCB, BOOL flag) +{ + if (flag == TRUE) { + ++(consoleCB->refCount); + } else { + --(consoleCB->refCount); + } +} + +BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB) +{ + if (ConsoleRefcountGet(consoleCB) != FALSE) { + return TRUE; + } else { + return FALSE; + } +} + +STATIC INT32 ConsoleCtrlRightsCapture(CONSOLE_CB *consoleCB) +{ + (VOID)LOS_SemPend(consoleCB->consoleSem, LOS_WAIT_FOREVER); + if (ConsoleRefcountGet(consoleCB) == 0) { + (VOID)LOS_TaskSuspend(consoleCB->shellEntryId); + } + ConsoleRefcountSet(consoleCB, TRUE); + (VOID)LOS_SemPost(consoleCB->consoleSem); + return LOS_OK; +} + +STATIC INT32 ConsoleCtrlRightsRelease(CONSOLE_CB *consoleCB) +{ + (VOID)LOS_SemPend(consoleCB->consoleSem, LOS_WAIT_FOREVER); + + if (ConsoleRefcountGet(consoleCB) == 0) { + PRINT_ERR("console is free\n"); + (VOID)LOS_SemPost(consoleCB->consoleSem); + return LOS_NOK; + } else { + ConsoleRefcountSet(consoleCB, FALSE); + if (ConsoleRefcountGet(consoleCB) == 0) { + (VOID)LOS_TaskResume(consoleCB->shellEntryId); + } + } + (VOID)LOS_SemPost(consoleCB->consoleSem); + return LOS_OK; +} + +STATIC CONSOLE_CB *OsGetConsoleByDevice(const CHAR *deviceName) +{ + INT32 ret; + CHAR *fullpath = NULL; + struct inode *inode = NULL; + + ret = vfs_normalize_path(NULL, deviceName, &fullpath); + if (ret < 0) { + set_errno(EINVAL); + return NULL; + } + + inode = inode_find(fullpath, NULL); + free(fullpath); + if (inode == NULL) { + set_errno(ENOENT); + return NULL; + } + + if (g_console[CONSOLE_SERIAL - 1]->devInode == inode) { + inode_release(inode); + return g_console[CONSOLE_SERIAL - 1]; + } else if (g_console[CONSOLE_TELNET - 1]->devInode == inode) { + inode_release(inode); + return g_console[CONSOLE_TELNET - 1]; + } else { + inode_release(inode); + set_errno(ENOENT); + return NULL; + } +} + +STATIC INT32 OsGetConsoleID(const CHAR *deviceName) +{ + if ((deviceName != NULL) && + (strlen(deviceName) == strlen(SERIAL)) && + (!strncmp(deviceName, SERIAL, strlen(SERIAL)))) { + return CONSOLE_SERIAL; + } +#ifdef LOSCFG_NET_TELNET + else if ((deviceName != NULL) && + (strlen(deviceName) == strlen(TELNET)) && + (!strncmp(deviceName, TELNET, strlen(TELNET)))) { + return CONSOLE_TELNET; + } +#endif + return -1; +} + +STATIC INT32 OsConsoleFullpathToID(const CHAR *fullpath) +{ +#define CONSOLE_SERIAL_1 "/dev/console1" +#define CONSOLE_TELNET_2 "/dev/console2" + + size_t len; + + if (fullpath == NULL) { + return -1; + } + + len = strlen(fullpath); + if ((len == strlen(CONSOLE_SERIAL_1)) && + (!strncmp(fullpath, CONSOLE_SERIAL_1, strlen(CONSOLE_SERIAL_1)))) { + return CONSOLE_SERIAL; + } +#ifdef LOSCFG_NET_TELNET + else if ((len == strlen(CONSOLE_TELNET_2)) && + (!strncmp(fullpath, CONSOLE_TELNET_2, strlen(CONSOLE_TELNET_2)))) { + return CONSOLE_TELNET; + } +#endif + return -1; +} + +STATIC BOOL ConsoleFifoEmpty(const CONSOLE_CB *console) +{ + if (console->fifoOut == console->fifoIn) { + return TRUE; + } + return FALSE; +} + +STATIC VOID ConsoleFifoClearup(CONSOLE_CB *console) +{ + console->fifoOut = 0; + console->fifoIn = 0; + (VOID)memset_s(console->fifo, CONSOLE_FIFO_SIZE, 0, CONSOLE_FIFO_SIZE); +} + +STATIC VOID ConsoleFifoLenUpdate(CONSOLE_CB *console) +{ + console->currentLen = console->fifoIn - console->fifoOut; +} + +STATIC INT32 ConsoleReadFifo(CHAR *buffer, CONSOLE_CB *console, size_t bufLen) +{ + INT32 ret; + UINT32 readNum; + + readNum = MIN(bufLen, console->currentLen); + ret = memcpy_s(buffer, bufLen, console->fifo + console->fifoOut, readNum); + if (ret != EOK) { + PRINTK("%s,%d memcpy_s failed\n", __FUNCTION__, __LINE__); + return -1; + } + console->fifoOut += readNum; + if (ConsoleFifoEmpty(console)) { + ConsoleFifoClearup(console); + } + ConsoleFifoLenUpdate(console); + return (INT32)readNum; +} + +INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops) +{ + INT32 ret; + if (fops->open == NULL) { + return -EFAULT; + } + + /* + * adopt uart open function to open filep (filep is + * corresponding to filep of /dev/console) + */ + ret = fops->open(filep); + if (ret < 0) { + return -EPERM; + } + return ret; +} + +STATIC INLINE VOID UserEndOfRead(CONSOLE_CB *consoleCB, struct file *filep, + const struct file_operations_vfs *fops) +{ + CHAR ch; + if (consoleCB->consoleTermios.c_lflag & ECHO) { + ch = '\r'; + (VOID)fops->write(filep, &ch, 1); + } + consoleCB->fifo[consoleCB->fifoIn++] = '\n'; + consoleCB->fifo[consoleCB->fifoIn] = '\0'; + consoleCB->currentLen = consoleCB->fifoIn; +} + +STATIC INT32 UserFilepRead(CONSOLE_CB *consoleCB, struct file *filep, const struct file_operations_vfs *fops, + CHAR *buffer, size_t bufLen) +{ + INT32 ret; + CHAR ch; + + if (fops->read == NULL) { + return -EFAULT; + } + + /* + * adopt uart read function to read data from filep + * and write data to buffer (filep is + * corresponding to filep of /dev/console) + */ + if ((consoleCB->consoleTermios.c_lflag & ICANON) == 0) { + ret = fops->read(filep, buffer, bufLen); + if (ret < 0) { + return -EPERM; + } + return ret; + } + /* store data to console buffer, read data and stored data into console fifo */ + if (consoleCB->currentLen == 0) { + while (1) { + ret = fops->read(filep, &ch, EACH_CHAR); + if (ret <= 0) { + return ret; + } + + if (ch == '\r') { + ch = '\n'; + } + + if (consoleCB->consoleTermios.c_lflag & ECHO) { + (VOID)fops->write(filep, &ch, EACH_CHAR); + } + + /* + * store what you input + * 3 : fifoIn should less than (CONSOLE_FIFO_SIZE - EACH_CHAR) - 2(its space of '\n' and '\0') + */ + if ((ret == EACH_CHAR) && (ch != '\n') && (consoleCB->fifoIn <= (CONSOLE_FIFO_SIZE - 3))) { + consoleCB->fifo[consoleCB->fifoIn] = (UINT8)ch; + consoleCB->fifoIn++; + } + + /* return what you input */ + if (ch == '\n') { + UserEndOfRead(consoleCB, filep, fops); + ret = ConsoleReadFifo(buffer, consoleCB, bufLen); + break; + } + } + } else { + /* if data is already in console fifo, we returen them immediately */ + ret = ConsoleReadFifo(buffer, consoleCB, bufLen); + } + + return ret; +} + +INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen) +{ + INT32 ret; + if (fops->read == NULL) { + return -EFAULT; + } + /* + * adopt uart read function to read data from filep + * and write data to buffer (filep is + * corresponding to filep of /dev/console) + */ + ret = fops->read(filep, buffer, bufLen); + if (ret < 0) { + return -EPERM; + } + return ret; +} + +INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen) +{ + INT32 ret; + if (fops->write == NULL) { + return -EFAULT; + } + + ret = fops->write(filep, buffer, bufLen); + if (ret < 0) { + return -EPERM; + } + return ret; +} + +INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops) +{ + INT32 ret; + if ((fops == NULL) || (fops->close == NULL)) { + return -EFAULT; + } + + /* + * adopt uart close function to open filep (filep is + * corresponding to filep of /dev/console) + */ + ret = fops->close(filep); + if (ret < 0) { + return -EPERM; + } + return ret; +} + +INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg) +{ + INT32 ret; + if (fops->ioctl == NULL) { + return -EFAULT; + } + + ret = fops->ioctl(filep, cmd, arg); + if (ret < 0) { + return -EPERM; + } + return ret; +} + +INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds) +{ + INT32 ret; + if (fops->poll == NULL) { + return -EFAULT; + } + + /* + * adopt uart poll function to poll filep (filep is + * corresponding to filep of /dev/serial) + */ + ret = fops->poll(filep, fds); + if (ret < 0) { + return -EPERM; + } + return ret; +} + +STATIC INT32 ConsoleOpen(struct file *filep) +{ + INT32 ret; + UINT32 consoleID; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + consoleID = (UINT32)OsConsoleFullpathToID(filep->f_path); + if (consoleID == (UINT32)-1) { + ret = EPERM; + goto ERROUT; + } + filep->f_priv = g_console[consoleID - 1]; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + ret = FilepOpen(privFilep, fileOps); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + return ENOERR; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 ConsoleClose(struct file *filep) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + ret = FilepClose(privFilep, fileOps); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + + return ENOERR; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC ssize_t ConsoleRead(struct file *filep, CHAR *buffer, size_t bufLen) +{ + INT32 ret; + struct file *privFilep = NULL; + CONSOLE_CB *consoleCB = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + consoleCB = OsGetConsoleByTaskID(OsCurrTaskGet()->taskID); + if (consoleCB == NULL) { + return -EFAULT; + } + } + + /* + * shell task use FilepRead function to get data, + * user task use UserFilepRead to get data + */ +#ifdef LOSCFG_SHELL + if (OsCurrTaskGet()->taskEntry == (TSK_ENTRY_FUNC)ShellEntry) { + ret = FilepRead(privFilep, fileOps, buffer, bufLen); + if (ret < 0) { + goto ERROUT; + } + } else { +#endif + (VOID)ConsoleCtrlRightsCapture(consoleCB); + ret = UserFilepRead(consoleCB, privFilep, fileOps, buffer, bufLen); + (VOID)ConsoleCtrlRightsRelease(consoleCB); + if (ret < 0) { + goto ERROUT; + } +#ifdef LOSCFG_SHELL + } +#endif + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC ssize_t ConsoleWrite(struct file *filep, const CHAR *buffer, size_t bufLen) +{ + INT32 ret; + INT32 cnt = 0; + UINT32 intSave; + CONSOLE_CB *consoleCB = NULL; + CirBufSendCB *cirBufSendCB = NULL; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + if (fileOps->write == NULL) { + ret = EFAULT; + goto ERROUT; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + ret = EFAULT; + goto ERROUT; + } + cirBufSendCB = consoleCB->cirBufSendCB; + + /* + * adopt uart open function to read data from buffer + * and write data to filep (filep is + * corresponding to filep of /dev/console) + */ +#ifdef LOSCFG_SHELL_DMESG + (VOID)OsLogMemcpyRecord(buffer, bufLen); + if (!OsCheckConsoleLock()) { +#endif + LOS_CirBufLock(&cirBufSendCB->cirBufCB, &intSave); + while (cnt < (INT32)bufLen) { + if ((buffer[cnt] == '\n') || (buffer[cnt] == '\r')) { + (VOID)LOS_CirBufWrite(&cirBufSendCB->cirBufCB, "\r", 1); + (VOID)LOS_CirBufWrite(&cirBufSendCB->cirBufCB, &buffer[cnt], 1); + cnt++; + continue; + } + (VOID)LOS_CirBufWrite(&cirBufSendCB->cirBufCB, &buffer[cnt], 1); + cnt++; + } + LOS_CirBufUnlock(&cirBufSendCB->cirBufCB, intSave); + (VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT); +#ifdef LOSCFG_SHELL_DMESG + } +#endif + return cnt; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 ConsoleIoctl(struct file *filep, INT32 cmd, unsigned long arg) +{ + INT32 ret; + struct file *privFilep = NULL; + CONSOLE_CB *consoleCB = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + + if (fileOps->ioctl == NULL) { + ret = EFAULT; + goto ERROUT; + } + + consoleCB = (CONSOLE_CB *)filep->f_priv; + if (consoleCB == NULL) { + ret = EINVAL; + goto ERROUT; + } + + switch (cmd) { + case CONSOLE_CONTROL_RIGHTS_CAPTURE: + ret = ConsoleCtrlRightsCapture(consoleCB); + break; + case CONSOLE_CONTROL_RIGHTS_RELEASE: + ret = ConsoleCtrlRightsRelease(consoleCB); + break; + default: + ret = fileOps->ioctl(privFilep, cmd, arg); + break; + } + + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + + return ret; +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 ConsolePoll(struct file *filep, poll_table *fds) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + + ret = FilepPoll(privFilep, fileOps, fds); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +/* console device driver function structure */ +STATIC const struct file_operations_vfs g_consoleDevOps = { + .open = ConsoleOpen, /* open */ + .close = ConsoleClose, /* close */ + .read = ConsoleRead, /* read */ + .write = ConsoleWrite, /* write */ + .seek = NULL, + .ioctl = ConsoleIoctl, +#ifndef CONFIG_DISABLE_POLL + .poll = ConsolePoll, +#endif + .unlink = NULL +}; + +STATIC VOID OsConsoleTermiosInit(CONSOLE_CB *consoleCB, const CHAR *deviceName) +{ + struct termios consoleTermios; + + if ((deviceName != NULL) && + (strlen(deviceName) == strlen(SERIAL)) && + (!strncmp(deviceName, SERIAL, strlen(SERIAL)))) { + consoleCB->isNonBlock = SetSerialBlock(consoleCB); + + /* set console to have a buffer for user */ + (VOID)ConsoleTcGetAttr(consoleCB->fd, &consoleTermios); + consoleTermios.c_lflag |= ICANON | ECHO; + (VOID)ConsoleTcSetAttr(consoleCB->fd, 0, &consoleTermios); + } +#ifdef LOSCFG_NET_TELNET + else if ((deviceName != NULL) && + (strlen(deviceName) == strlen(TELNET)) && + (!strncmp(deviceName, TELNET, strlen(TELNET)))) { + consoleCB->isNonBlock = SetTelnetBlock(consoleCB); + } +#endif +} + +STATIC INT32 OsConsoleFileInit(CONSOLE_CB *consoleCB) +{ + INT32 ret; + struct inode *inode = NULL; + struct file *filep = NULL; + CHAR *fullpath = NULL; + + ret = vfs_normalize_path(NULL, consoleCB->name, &fullpath); + if (ret < 0) { + return EINVAL; + } + + inode = inode_find(fullpath, NULL); + if (inode == NULL) { + ret = ENOENT; + goto ERROUT_WITH_FULLPATH; + } + + consoleCB->fd = files_allocate(inode, O_RDWR, (off_t)0, consoleCB, STDERR_FILENO + 1); + if (consoleCB->fd < 0) { + ret = EMFILE; + goto ERROUT_WITH_INODE; + } + + filep = fs_getfilep(consoleCB->fd); + if (filep == NULL) { + ret = EPERM; + goto ERROUT_WITH_INODE; + } + filep->f_path = fullpath; + return LOS_OK; + +ERROUT_WITH_INODE: + inode_release(inode); +ERROUT_WITH_FULLPATH: + free(fullpath); + return ret; +} + +/* + * Initialized console control platform so that when we operate /dev/console + * as if we are operating /dev/ttyS0 (uart0). + */ +STATIC INT32 OsConsoleDevInit(CONSOLE_CB *consoleCB, const CHAR *deviceName) +{ + INT32 ret; + CHAR *fullpath = NULL; + struct file *filep = NULL; + struct inode *inode = NULL; + + /* allocate memory for filep,in order to unchange the value of filep */ + filep = (struct file *)LOS_MemAlloc(m_aucSysMem0, sizeof(struct file)); + if (filep == NULL) { + ret = ENOMEM; + goto ERROUT; + } + + /* Adopt procedure of open function to allocate 'filep' to /dev/console */ + ret = vfs_normalize_path(NULL, deviceName, &fullpath); + if (ret < 0) { + ret = EINVAL; + goto ERROUT_WITH_FILEP; + } + + inode = inode_find(fullpath, NULL); + if (inode == NULL) { + ret = ENOENT; + goto ERROUT_WITH_FULLPATH; + } + + consoleCB->devInode = inode; + + /* + * initialize the console filep which is associated with /dev/console, + * assign the uart0 inode of /dev/ttyS0 to console inod of /dev/console, + * then we can operate console's filep as if we operate uart0 filep of + * /dev/ttyS0. + */ + (VOID)memset_s(filep, sizeof(struct file), 0, sizeof(struct file)); + filep->f_oflags = O_RDWR; + filep->f_pos = 0; + filep->f_inode = inode; + filep->f_path = NULL; + filep->f_priv = NULL; + + if (inode->u.i_ops->open != NULL) { + (VOID)inode->u.i_ops->open(filep); + } else { + ret = EFAULT; + goto ERROUT_WITH_INODE; + } + + /* + * Use filep to connect console and uart, we can find uart driver function throught filep. + * now we can operate /dev/console to operate /dev/ttyS0 through filep. + */ + (VOID)register_driver(consoleCB->name, &g_consoleDevOps, DEFFILEMODE, filep); + inode_release(inode); + free(fullpath); + return LOS_OK; + +ERROUT_WITH_INODE: + inode_release(inode); +ERROUT_WITH_FULLPATH: + free(fullpath); +ERROUT_WITH_FILEP: + (VOID)LOS_MemFree(m_aucSysMem0, filep); +ERROUT: + set_errno(ret); + return LOS_NOK; +} + +STATIC UINT32 OsConsoleDevDeinit(const CONSOLE_CB *consoleCB) +{ + INT32 ret; + struct file *filep = NULL; + struct inode *inode = NULL; + CHAR *fullpath = NULL; + + ret = vfs_normalize_path(NULL, consoleCB->name, &fullpath); + if (ret < 0) { + ret = EINVAL; + goto ERROUT; + } + + inode = inode_find(fullpath, NULL); + if (inode == NULL) { + ret = ENOENT; + goto ERROUT_WITH_FULLPATH; + } + + filep = inode->i_private; + if (filep != NULL) { + (VOID)LOS_MemFree(m_aucSysMem0, filep); /* free filep what you malloc from console_init */ + inode->i_private = NULL; + } else { + ret = EBADF; + goto ERROUT_WITH_INODE; + } + inode_release(inode); + free(fullpath); + (VOID)unregister_driver(consoleCB->name); + return LOS_OK; + +ERROUT_WITH_INODE: + inode_release(inode); +ERROUT_WITH_FULLPATH: + free(fullpath); +ERROUT: + set_errno(ret); + return LOS_NOK; +} + +STATIC CirBufSendCB *ConsoleCirBufCreate(VOID) +{ + UINT32 ret; + CHAR *fifo = NULL; + CirBufSendCB *cirBufSendCB = NULL; + CirBuf *cirBufCB = NULL; + + cirBufSendCB = (CirBufSendCB *)LOS_MemAlloc(m_aucSysMem0, sizeof(CirBufSendCB)); + if (cirBufSendCB == NULL) { + return NULL; + } + (VOID)memset_s(cirBufSendCB, sizeof(CirBufSendCB), 0, sizeof(CirBufSendCB)); + + fifo = (CHAR *)LOS_MemAlloc(m_aucSysMem0, TELNET_CIRBUF_SIZE); + if (fifo == NULL) { + goto ERROR_WITH_SENDCB; + } + (VOID)memset_s(fifo, TELNET_CIRBUF_SIZE, 0, TELNET_CIRBUF_SIZE); + + cirBufCB = &cirBufSendCB->cirBufCB; + ret = LOS_CirBufInit(cirBufCB, fifo, TELNET_CIRBUF_SIZE); + if (ret != LOS_OK) { + goto ERROR_WITH_FIFO; + } + + (VOID)LOS_EventInit(&cirBufSendCB->sendEvent); + return cirBufSendCB; + +ERROR_WITH_FIFO: + (VOID)LOS_MemFree(m_aucSysMem0, cirBufCB->fifo); +ERROR_WITH_SENDCB: + (VOID)LOS_MemFree(m_aucSysMem0, cirBufSendCB); + return NULL; +} + +STATIC VOID ConsoleCirBufDelete(CirBufSendCB *cirBufSendCB) +{ + CirBuf *cirBufCB = &cirBufSendCB->cirBufCB; + + (VOID)LOS_MemFree(m_aucSysMem0, cirBufCB->fifo); + LOS_CirBufDeinit(cirBufCB); + (VOID)LOS_EventDestroy(&cirBufSendCB->sendEvent); + (VOID)LOS_MemFree(m_aucSysMem0, cirBufSendCB); +} + +STATIC UINT32 OsConsoleBufInit(CONSOLE_CB *consoleCB) +{ + UINT32 ret; + TSK_INIT_PARAM_S initParam = {0}; + + consoleCB->cirBufSendCB = ConsoleCirBufCreate(); + if (consoleCB->cirBufSendCB == NULL) { + return LOS_NOK; + } + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ConsoleSendTask; + initParam.usTaskPrio = SHELL_TASK_PRIORITY; + initParam.auwArgs[0] = (UINTPTR)consoleCB; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + if (consoleCB->consoleID == CONSOLE_SERIAL) { + initParam.pcName = "SendToSer"; + } else { + initParam.pcName = "SendToTelnet"; + } + initParam.uwResved = LOS_TASK_STATUS_DETACHED; + + ret = LOS_TaskCreate(&consoleCB->sendTaskID, &initParam); + if (ret != LOS_OK) { + ConsoleCirBufDelete(consoleCB->cirBufSendCB); + consoleCB->cirBufSendCB = NULL; + return LOS_NOK; + } + (VOID)LOS_EventRead(&consoleCB->cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_RUNNING, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + + return LOS_OK; +} + +STATIC VOID OsConsoleBufDeinit(CONSOLE_CB *consoleCB) +{ + CirBufSendCB *cirBufSendCB = consoleCB->cirBufSendCB; + + consoleCB->cirBufSendCB = NULL; + (VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_EXIT); +} + +STATIC CONSOLE_CB *OsConsoleCBInit(UINT32 consoleID) +{ + CONSOLE_CB *consoleCB = (CONSOLE_CB *)LOS_MemAlloc((VOID *)m_aucSysMem0, sizeof(CONSOLE_CB)); + if (consoleCB == NULL) { + return NULL; + } + (VOID)memset_s(consoleCB, sizeof(CONSOLE_CB), 0, sizeof(CONSOLE_CB)); + + consoleCB->consoleID = consoleID; + consoleCB->shellEntryId = 0xffffffff; /* initialize shellEntryId to an invalid value */ + consoleCB->name = LOS_MemAlloc((VOID *)m_aucSysMem0, CONSOLE_NAMELEN); + if (consoleCB->name == NULL) { + PRINT_ERR("consoleCB->name malloc failed\n"); + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB); + return NULL; + } + return consoleCB; +} + +STATIC VOID OsConsoleCBDeinit(CONSOLE_CB *consoleCB) +{ + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB->name); + consoleCB->name = NULL; + (VOID)LOS_MemFree((VOID *)m_aucSysMem0, consoleCB); +} + +STATIC CONSOLE_CB *OsConsoleCreate(UINT32 consoleID, const CHAR *deviceName) +{ + INT32 ret; + CONSOLE_CB *consoleCB = OsConsoleCBInit(consoleID); + if (consoleCB == NULL) { + PRINT_ERR("console malloc error.\n"); + return NULL; + } + + ret = snprintf_s(consoleCB->name, CONSOLE_NAMELEN, CONSOLE_NAMELEN - 1, + "%s%u", CONSOLE, consoleCB->consoleID); + if (ret == -1) { + PRINT_ERR("consoleCB->name snprintf_s failed\n"); + goto ERR_WITH_NAME; + } + + ret = (INT32)OsConsoleBufInit(consoleCB); + if (ret != LOS_OK) { + goto ERR_WITH_NAME; + } + + ret = (INT32)LOS_SemCreate(1, &consoleCB->consoleSem); + if (ret != LOS_OK) { + PRINT_ERR("creat sem for uart failed\n"); + goto ERR_WITH_BUF; + } + + ret = OsConsoleDevInit(consoleCB, deviceName); + if (ret != LOS_OK) { + goto ERR_WITH_SEM; + } + + ret = OsConsoleFileInit(consoleCB); + if (ret != LOS_OK) { + goto ERR_WITH_DEV; + } + + OsConsoleTermiosInit(consoleCB, deviceName); + return consoleCB; + +ERR_WITH_DEV: + ret = (INT32)OsConsoleDevDeinit(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("OsConsoleDevDeinit failed!\n"); + } +ERR_WITH_SEM: + (VOID)LOS_SemDelete(consoleCB->consoleSem); +ERR_WITH_BUF: + OsConsoleBufDeinit(consoleCB); +ERR_WITH_NAME: + OsConsoleCBDeinit(consoleCB); + return NULL; +} + +STATIC UINT32 OsConsoleDelete(CONSOLE_CB *consoleCB) +{ + UINT32 ret; + + (VOID)files_close(consoleCB->fd); + ret = OsConsoleDevDeinit(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("OsConsoleDevDeinit failed!\n"); + } + OsConsoleBufDeinit((CONSOLE_CB *)consoleCB); + (VOID)LOS_SemDelete(consoleCB->consoleSem); + (VOID)LOS_MemFree(m_aucSysMem0, consoleCB->name); + consoleCB->name = NULL; + (VOID)LOS_MemFree(m_aucSysMem0, consoleCB); + + return ret; +} + +/* Initialized system console and return stdinfd stdoutfd stderrfd */ +INT32 system_console_init(const CHAR *deviceName) +{ +#ifdef LOSCFG_SHELL + UINT32 ret; +#endif + INT32 consoleID; + UINT32 intSave; + CONSOLE_CB *consoleCB = NULL; + + consoleID = OsGetConsoleID(deviceName); + if (consoleID == -1) { + PRINT_ERR("device is full.\n"); + return VFS_ERROR; + } + + consoleCB = OsConsoleCreate((UINT32)consoleID, deviceName); + if (consoleCB == NULL) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + return VFS_ERROR; + } + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + g_console[consoleID - 1] = consoleCB; + if (OsCurrTaskGet() != NULL) { + g_taskConsoleIDArray[OsCurrTaskGet()->taskID] = (UINT8)consoleID; + } + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + +#ifdef LOSCFG_SHELL + ret = OsShellInit(consoleID); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); + LOS_SpinLockSave(&g_consoleSpin, &intSave); + (VOID)OsConsoleDelete(consoleCB); + g_console[consoleID - 1] = NULL; + g_taskConsoleIDArray[OsCurrTaskGet()->taskID] = 0; + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + return VFS_ERROR; + } +#endif + + return ENOERR; +} + +INT32 system_console_deinit(const CHAR *deviceName) +{ + UINT32 ret; + CONSOLE_CB *consoleCB = NULL; + UINT32 taskIdx; + LosTaskCB *taskCB = NULL; + UINT32 intSave; + + consoleCB = OsGetConsoleByDevice(deviceName); + if (consoleCB == NULL) { + return VFS_ERROR; + } + +#ifdef LOSCFG_SHELL + (VOID)OsShellDeinit((INT32)consoleCB->consoleID); +#endif + + LOS_SpinLockSave(&g_consoleSpin, &intSave); + /* Redirect all tasks to serial as telnet was unavailable after deinitializing */ + for (taskIdx = 0; taskIdx < g_taskMaxNum; taskIdx++) { + taskCB = ((LosTaskCB *)g_taskCBArray) + taskIdx; + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } else { + g_taskConsoleIDArray[taskCB->taskID] = CONSOLE_SERIAL; + } + } + g_console[consoleCB->consoleID - 1] = NULL; + LOS_SpinUnlockRestore(&g_consoleSpin, intSave); + + ret = OsConsoleDelete(consoleCB); + if (ret != LOS_OK) { + PRINT_ERR("%s, Failed to system_console_deinit\n", __FUNCTION__); + return VFS_ERROR; + } + + return ENOERR; +} + +BOOL ConsoleEnable(VOID) +{ + INT32 consoleID; + + if (OsCurrTaskGet() != NULL) { + consoleID = g_taskConsoleIDArray[OsCurrTaskGet()->taskID]; + if (g_uart_fputc_en == 0) { + if ((g_console[CONSOLE_TELNET - 1] != NULL) && OsPreemptable()) { + return TRUE; + } else { + return FALSE; + } + } + + if (consoleID == 0) { + return FALSE; + } else if ((consoleID == CONSOLE_TELNET) && OsPreemptable()) { + return TRUE; + } +#if defined (LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined (LOSCFG_DRIVERS_USB_ETH_SER_GADGET) + else if ((SerialTypeGet() == SERIAL_TYPE_USBTTY_DEV) && (userial_mask_get() == 1)) { + return TRUE; + } +#endif + } + + return FALSE; +} + +VOID ConsoleTaskReg(INT32 consoleID, UINT32 taskID) +{ + g_console[consoleID - 1]->shellEntryId = taskID; +} + +BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB) +{ + INT32 ret; + + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return FALSE; + } + ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_NONBLOCK); + if (ret != 0) { + return FALSE; + } + + return TRUE; +} + +BOOL SetSerialBlock(const CONSOLE_CB *consoleCB) +{ + INT32 ret; + + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return TRUE; + } + ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_SERIAL, CONSOLE_RD_BLOCK); + if (ret != 0) { + return TRUE; + } + + return FALSE; +} + +BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB) +{ + INT32 ret; + + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return FALSE; + } + ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_NONBLOCK); + if (ret != 0) { + return FALSE; + } + return TRUE; +} + +BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB) +{ + INT32 ret; + + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return TRUE; + } + ret = ioctl(consoleCB->fd, CONSOLE_CMD_RD_BLOCK_TELNET, CONSOLE_RD_BLOCK); + if (ret != 0) { + return TRUE; + } + return FALSE; +} + +BOOL is_nonblock(const CONSOLE_CB *consoleCB) +{ + if (consoleCB == NULL) { + PRINT_ERR("%s: Input parameter is illegal\n", __FUNCTION__); + return FALSE; + } + return consoleCB->isNonBlock; +} + +INT32 ConsoleUpdateFd(VOID) +{ + INT32 consoleID = 0; + + if (OsCurrTaskGet() != NULL) { + consoleID = g_taskConsoleIDArray[(OsCurrTaskGet())->taskID]; + } else { + return -1; + } + + if (g_uart_fputc_en == 0) { + if (g_console[CONSOLE_TELNET - 1] != NULL) { + consoleID = CONSOLE_TELNET; + } else { + return -1; + } + } else if (consoleID == 0) { + if (g_console[CONSOLE_SERIAL - 1] != NULL) { + consoleID = CONSOLE_SERIAL; + } else if (g_console[CONSOLE_TELNET - 1] != NULL) { + consoleID = CONSOLE_TELNET; + } else { + PRINT_ERR("No console dev used.\n"); + return -1; + } + } + + if (g_console[consoleID - 1] == NULL) { + return -1; + } + + return g_console[consoleID - 1]->fd; +} + +CONSOLE_CB *OsGetConsoleByID(INT32 consoleID) +{ + if (consoleID != CONSOLE_TELNET) { + consoleID = CONSOLE_SERIAL; + } + return g_console[consoleID - 1]; +} + +CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskID) +{ + INT32 consoleID = g_taskConsoleIDArray[taskID]; + + return OsGetConsoleByID(consoleID); +} + +VOID OsSetConsoleID(UINT32 newTaskID, UINT32 curTaskID) +{ + if ((newTaskID >= LOSCFG_BASE_CORE_TSK_LIMIT) || (curTaskID >= LOSCFG_BASE_CORE_TSK_LIMIT)) { + return; + } + + g_taskConsoleIDArray[newTaskID] = g_taskConsoleIDArray[curTaskID]; +} + +STATIC ssize_t WriteToTerminal(const CONSOLE_CB *consoleCB, const CHAR *buffer, size_t bufLen) +{ + INT32 ret, fd; + struct file *privFilep = NULL; + struct file *filep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + fd = consoleCB->fd; + filep = fs_getfilep(fd); + ret = GetFilepOps(filep, &privFilep, &fileOps); + + if (fileOps->write == NULL) { + ret = EFAULT; + goto ERROUT; + } + (VOID)fileOps->write(privFilep, buffer, bufLen); + + return 0; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC UINT32 ConsoleSendTask(UINTPTR param) +{ + CONSOLE_CB *consoleCB = (CONSOLE_CB *)param; + CirBufSendCB *cirBufSendCB = consoleCB->cirBufSendCB; + CirBuf *cirBufCB = &cirBufSendCB->cirBufCB; + UINT32 ret, size; + UINT32 intSave; + CHAR *buf = NULL; + + (VOID)LOS_EventWrite(&cirBufSendCB->sendEvent, CONSOLE_SEND_TASK_RUNNING); + + while (1) { + ret = LOS_EventRead(&cirBufSendCB->sendEvent, CONSOLE_CIRBUF_EVENT | CONSOLE_SEND_TASK_EXIT, + LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); + if (ret == CONSOLE_CIRBUF_EVENT) { + size = LOS_CirBufUsedSize(cirBufCB); + if (size == 0) { + continue; + } + buf = (CHAR *)LOS_MemAlloc(m_aucSysMem1, size + 1); + if (buf == NULL) { + continue; + } + (VOID)memset_s(buf, size + 1, 0, size + 1); + + LOS_CirBufLock(cirBufCB, &intSave); + (VOID)LOS_CirBufRead(cirBufCB, buf, size); + LOS_CirBufUnlock(cirBufCB, intSave); + + (VOID)WriteToTerminal(consoleCB, buf, size); + (VOID)LOS_MemFree(m_aucSysMem1, buf); + } else if (ret == CONSOLE_SEND_TASK_EXIT) { + break; + } + } + + ConsoleCirBufDelete(cirBufSendCB); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/targets/bsp/common/console.h b/targets/bsp/common/console.h new file mode 100644 index 000000000..c3f89245d --- /dev/null +++ b/targets/bsp/common/console.h @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Console HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _CONSOLE_H +#define _CONSOLE_H + +#include "los_config.h" +#ifdef LOSCFG_FS_VFS +#include "asm/termbits.h" +#ifdef LOSCFG_NET_TELNET +#include "telnet_dev.h" +#endif +#include "virtual_serial.h" +#include "los_cir_buf_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_FS_VFS + +/* Define two fixed console id for Console ID. */ +#define CONSOLE_SERIAL 1 +#define CONSOLE_TELNET 2 + +#define LOSCFG_PLATFORM_CONSOLE +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +#define CONSOLE "/dev/console" +#define CONSOLE_NAMELEN 16 + +#define CONSOLE_CMD_RD_BLOCK_SERIAL 0x104 +#define CONSOLE_CMD_RD_BLOCK_TELNET 101 +#define CONSOLE_RD_BLOCK 1 +#define CONSOLE_RD_NONBLOCK 0 +#define CONSOLE_SHELL_KEY_EVENT 0x112 +#define CONSOLE_SHELL_EXITED 0x400 +#define CONSOLE_CONTROL_RIGHTS_CAPTURE 201 +#define CONSOLE_CONTROL_RIGHTS_RELEASE 202 +#define CONSOLE_FIFO_SIZE 1024 +#define CONSOLE_NUM 2 + + +#define TELNET_CIRBUF_SIZE 0x1000 + +typedef struct { + CirBuf cirBufCB; /* Circular buffer CB */ + EVENT_CB_S sendEvent; /* Inform telnet send task */ +} CirBufSendCB; + +typedef struct { + UINT32 consoleID; + UINT32 consoleType; + UINT32 consoleSem; + UINT32 shellEntryId; + UINT32 consoleMask; + struct inode *devInode; + CHAR *name; + INT32 fd; + UINT32 refCount; + BOOL isNonBlock; +#ifdef LOSCFG_SHELL + VOID *shellHandle; +#endif + UINT32 sendTaskID; + CirBufSendCB *cirBufSendCB; + UINT8 fifo[CONSOLE_FIFO_SIZE]; + UINT32 fifoOut; + UINT32 fifoIn; + UINT32 currentLen; + struct termios consoleTermios; +} CONSOLE_CB; + +extern INT32 system_console_init(const CHAR *deviceName); +extern INT32 system_console_deinit(const CHAR *deviceName); +extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB); +extern BOOL SetSerialBlock(const CONSOLE_CB *consoleCB); +extern BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB); +extern BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB); +extern CONSOLE_CB *OsGetConsoleByID(INT32 consoleID); +extern CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskID); +extern VOID ConsoleTaskReg(INT32 consoleID, UINT32 taskID); +extern INT32 ConsoleUpdateFd(VOID); +extern BOOL ConsoleEnable(VOID); +extern BOOL is_nonblock(const CONSOLE_CB *consoleCB); +extern BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB); +extern INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops); +extern INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops); +extern INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen); +extern INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen); +extern INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds); +extern INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg); +extern INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops); + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _CONSOLE_H */ diff --git a/targets/bsp/common/hwi_shell.c b/targets/bsp/common/hwi_shell.c new file mode 100644 index 000000000..b2ded2b1f --- /dev/null +++ b/targets/bsp/common/hwi_shell.c @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Hwi Shell Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_config.h" +#ifdef LOSCFG_SHELL +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +#include "los_cpup_pri.h" +#endif +#include "los_hwi_pri.h" +#include "shcmd.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +STATIC CPUP_INFO_S g_hwiCpupAll[OS_HWI_MAX_NUM]; +STATIC CPUP_INFO_S g_hwiCpup10s[OS_HWI_MAX_NUM]; +STATIC CPUP_INFO_S g_hwiCpup1s[OS_HWI_MAX_NUM]; +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv) +{ + UINT32 i; + UINT32 intSave; + UINT64 cycles; + size_t size = sizeof(CPUP_INFO_S) * OS_HWI_MAX_NUM; + + (VOID)argv; + if (argc > 0) { + PRINTK("\nUsage: hwi\n"); + return OS_ERROR; + } + + (VOID)memset_s(g_hwiCpupAll, size, 0, size); + (VOID)memset_s(g_hwiCpup10s, size, 0, size); + (VOID)memset_s(g_hwiCpup1s, size, 0, size); + + intSave = LOS_IntLock(); + (VOID)LOS_AllCpuUsage(OS_HWI_MAX_NUM, g_hwiCpupAll, CPUP_ALL_TIME, 0); + (VOID)LOS_AllCpuUsage(OS_HWI_MAX_NUM, g_hwiCpup10s, CPUP_LAST_TEN_SECONDS, 0); + (VOID)LOS_AllCpuUsage(OS_HWI_MAX_NUM, g_hwiCpup1s, CPUP_LAST_ONE_SECONDS, 0); + LOS_IntRestore(intSave); + + PRINTK(" InterruptNo Count Name CYCLECOST CPUUSE CPUUSE10s CPUUSE1s mode\n"); + for (i = OS_HWI_FORM_EXC_NUM; i < OS_HWI_MAX_NUM + OS_HWI_FORM_EXC_NUM; i++) { + if (OsGetHwiFormCnt(i)) { + cycles = g_cpup[g_taskMaxNum + i].allTime / OsGetHwiFormCnt(i); + } else { + cycles = 0; + } + /* Different cores has different hwi form implementation */ + if (HWI_IS_REGISTED(i) && (OsGetHwiFormName(i) != NULL)) { + PRINTK(" %8d: %-10d%-12s %-10llu", i, OsGetHwiFormCnt(i), OsGetHwiFormName(i), cycles); + } else if (HWI_IS_REGISTED(i)) { + PRINTK(" %8d: %-10d%-12s %-10llu", i, OsGetHwiFormCnt(i), "", cycles); + } else { + continue; + } + PRINTK("%2d.%-7d" + "%2d.%-9d" + "%2d.%-6d" + "%s\n", + g_hwiCpupAll[i].uwUsage / LOS_CPUP_PRECISION_MULT, + g_hwiCpupAll[i].uwUsage % LOS_CPUP_PRECISION_MULT, + g_hwiCpup10s[i].uwUsage / LOS_CPUP_PRECISION_MULT, + g_hwiCpup10s[i].uwUsage % LOS_CPUP_PRECISION_MULT, + g_hwiCpup1s[i].uwUsage / LOS_CPUP_PRECISION_MULT, + g_hwiCpup1s[i].uwUsage % LOS_CPUP_PRECISION_MULT, + g_hwiForm[i].uwParam == IRQF_SHARED ? "shared" : "normal"); + } + return 0; +} +#else +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv) +{ + UINT32 i; + + (VOID)argv; + if (argc > 0) { + PRINTK("\nUsage: hwi\n"); + return OS_ERROR; + } + + PRINTK(" InterruptNo Count Name\n"); + for (i = OS_HWI_FORM_EXC_NUM; i < OS_HWI_MAX_NUM + OS_HWI_FORM_EXC_NUM; i++) { + /* Different cores has different hwi form implementation */ + if (HWI_IS_REGISTED(i) && (OsGetHwiFormName(i) != NULL)) { + PRINTK(" %8d:%10d: %-s\n", i, OsGetHwiFormCnt(i), OsGetHwiFormName(i)); + } else if (HWI_IS_REGISTED(i)) { + PRINTK(" %8d:%10d:\n", i, OsGetHwiFormCnt(i)); + } + } + return 0; +} +#endif + +SHELLCMD_ENTRY(hwi_shellcmd, CMD_TYPE_EX, "hwi", 0, (CmdCallBackFunc)OsShellCmdHwi); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* LOSCFG_SHELL */ diff --git a/targets/bsp/common/los_builddef.h b/targets/bsp/common/los_builddef.h new file mode 100644 index 000000000..dc7ac212b --- /dev/null +++ b/targets/bsp/common/los_builddef.h @@ -0,0 +1,115 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Build Define HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * HuaweiLite OS may be subject to applicable export control laws and regulations, which might + * include those applicable to HuaweiLite OS of U.S. and the country in which you are located. + * Import, export and usage of HuaweiLite OS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_BUILDEF_H +#define _LOS_BUILDEF_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_LITTLE_ENDIAN 0x1234 /* Little endian */ +#define OS_BIG_ENDIAN 0x4321 /* Big endian */ + +#ifndef OS_BYTE_ORDER +#define OS_BYTE_ORDER OS_LITTLE_ENDIAN +#endif + +extern char __text_start, __text_end; +extern char __ram_data_start, __ram_data_end; + +/* Define OS code data sections */ +/* The indicator function is inline */ +#ifndef LITE_OS_SEC_ALW_INLINE +#define LITE_OS_SEC_ALW_INLINE /* __attribute__((always_inline)) */ +#endif + +#ifndef LITE_OS_SEC_TEXT +#define LITE_OS_SEC_TEXT /* __attribute__((section(".text.sram"))) */ +#endif + +#ifndef LITE_OS_SEC_TEXT_MINOR +#define LITE_OS_SEC_TEXT_MINOR /* __attribute__((section(".text.ddr"))) */ +#endif + +#ifndef LITE_OS_SEC_TEXT_INIT +#define LITE_OS_SEC_TEXT_INIT /* __attribute__((section(".text.init"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA +#define LITE_OS_SEC_DATA /* __attribute__((section(".data.sram"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA_MINOR +#define LITE_OS_SEC_DATA_MINOR /* __attribute__((section(".data.ddr"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA_INIT +#define LITE_OS_SEC_DATA_INIT /* __attribute__((section(".data.init"))) */ +#endif + +#ifndef LITE_OS_SEC_DATA_VEC +#define LITE_OS_SEC_DATA_VEC __attribute__((section(".data.vector"))) +#endif + +#ifndef LITE_OS_SEC_BSS +#define LITE_OS_SEC_BSS /* __attribute__((section(".bss.sram"))) */ +#endif + +#ifndef LITE_OS_SEC_BSS_MINOR +#define LITE_OS_SEC_BSS_MINOR /* __attribute__((section(".bss.ddr"))) */ +#endif + +#ifndef LITE_OS_SEC_BSS_INIT +#define LITE_OS_SEC_BSS_INIT /* __attribute__((section(".bss.init"))) */ +#endif + +#ifndef LITE_OS_SEC_ITCM +#define LITE_OS_SEC_ITCM /* __attribute__((section(".itcm "))) */ +#endif +#ifndef LITE_OS_SEC_DTCM +#define LITE_OS_SEC_DTCM /* __attribute__((section(".dtcm"))) */ +#endif + +#define PACK1 + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_BUILDEF_H */ diff --git a/targets/bsp/common/los_cir_buf.c b/targets/bsp/common/los_cir_buf.c new file mode 100644 index 000000000..e05a38c29 --- /dev/null +++ b/targets/bsp/common/los_cir_buf.c @@ -0,0 +1,232 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: Circular Buffer Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_cir_buf_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 LOS_CirBufUsedSize(CirBuf *cirbufCB) +{ + UINT32 size; + UINT32 intSave; + + if (cirbufCB == NULL) { + return 0; + } + + LOS_SpinLockSave(&cirbufCB->lock, &intSave); + size = cirbufCB->size - cirbufCB->remain; + LOS_SpinUnlockRestore(&cirbufCB->lock, intSave); + + return size; +} + +/* + * startIdx + * | + * 0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0 + * | + * endIdx + */ +STATIC UINT32 OsCirBufWriteLinear(CirBuf *cirbufCB, const CHAR *buf, UINT32 size) +{ + UINT32 cpSize; + errno_t err; + + cpSize = (cirbufCB->remain < size) ? cirbufCB->remain : size; + + if (cpSize == 0) { + return 0; + } + + err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, cirbufCB->remain, buf, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain -= cpSize; + cirbufCB->endIdx += cpSize; + + return cpSize; +} + +STATIC UINT32 OsCirBufWriteLoop(CirBuf *cirbufCB, const CHAR *buf, UINT32 size) +{ + UINT32 right, cpSize; + errno_t err; + + right = cirbufCB->size - cirbufCB->endIdx; + cpSize = (right < size) ? right : size; + + err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, right, buf, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain -= cpSize; + cirbufCB->endIdx += cpSize; + if (cirbufCB->endIdx == cirbufCB->size) { + cirbufCB->endIdx = 0; + } + + if (cpSize == size) { + return size; + } else { + cpSize += OsCirBufWriteLinear(cirbufCB, buf + cpSize, size - cpSize); + } + + return cpSize; +} + +UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size) +{ + UINT32 cpSize = 0; + + if ((cirbufCB == NULL) || (buf == NULL) || (size == 0)) { + return 0; + } + + if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == 0)) { + return 0; + } + + if (cirbufCB->startIdx <= cirbufCB->endIdx) { + cpSize = OsCirBufWriteLoop(cirbufCB, buf, size); + } else { + cpSize = OsCirBufWriteLinear(cirbufCB, buf, size); + } + + return cpSize; +} + +STATIC UINT32 OsCirBufReadLinear(CirBuf *cirbufCB, CHAR *buf, UINT32 size) +{ + UINT32 cpSize, remain; + errno_t err; + + remain = cirbufCB->endIdx - cirbufCB->startIdx; + cpSize = (remain < size) ? remain : size; + + if (cpSize == 0) { + return 0; + } + + err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain += cpSize; + cirbufCB->startIdx += cpSize; + + return cpSize; +} + +STATIC UINT32 OsCirBufReadLoop(CirBuf *cirbufCB, CHAR *buf, UINT32 size) +{ + UINT32 right, cpSize; + errno_t err; + + right = cirbufCB->size - cirbufCB->startIdx; + cpSize = (right < size) ? right : size; + + err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize); + if (err != EOK) { + return 0; + } + + cirbufCB->remain += cpSize; + cirbufCB->startIdx += cpSize; + if (cirbufCB->startIdx == cirbufCB->size) { + cirbufCB->startIdx = 0; + } + + if (cpSize < size) { + cpSize += OsCirBufReadLinear(cirbufCB, buf + cpSize, size - cpSize); + } + + return cpSize; +} + +UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size) +{ + UINT32 cpSize; + + if ((cirbufCB == NULL) || (buf == NULL) || (size == 0)) { + return 0; + } + + if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == cirbufCB->size)) { + return 0; + } + + if (cirbufCB->startIdx >= cirbufCB->endIdx) { + cpSize = OsCirBufReadLoop(cirbufCB, buf, size); + } else { + cpSize = OsCirBufReadLinear(cirbufCB, buf, size); + } + + return cpSize; +} + +UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size) +{ + if ((cirbufCB == NULL) || (fifo == NULL)) { + return LOS_NOK; + } + + (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf)); + LOS_SpinInit(&cirbufCB->lock); + cirbufCB->size = size; + cirbufCB->remain = size; + cirbufCB->status = CBUF_USED; + cirbufCB->fifo = fifo; + + return LOS_OK; +} + +VOID LOS_CirBufDeinit(CirBuf *cirbufCB) +{ + (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf)); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/targets/bsp/common/los_cir_buf_pri.h b/targets/bsp/common/los_cir_buf_pri.h new file mode 100644 index 000000000..4f6ba97b8 --- /dev/null +++ b/targets/bsp/common/los_cir_buf_pri.h @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: Circular Buffer Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_CIRBUF_PRI_H +#define _LOS_CIRBUF_PRI_H + +#include "los_typedef.h" +#include "los_spinlock.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + CBUF_UNUSED, + CBUF_USED +} CirBufStatus; + +typedef struct { + UINT32 startIdx; + UINT32 endIdx; + UINT32 size; + UINT32 remain; + SPIN_LOCK_S lock; + CirBufStatus status; + CHAR *fifo; +} CirBuf; + +STATIC INLINE VOID LOS_CirBufLock(CirBuf *cirbufCB, UINT32 *intSave) +{ + if (cirbufCB == NULL) { + return; + } + LOS_SpinLockSave(&cirbufCB->lock, intSave); +} + +STATIC INLINE VOID LOS_CirBufUnlock(CirBuf *cirbufCB, UINT32 intSave) +{ + if (cirbufCB == NULL) { + return; + } + LOS_SpinUnlockRestore(&cirbufCB->lock, intSave); +} + +extern UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size); +extern VOID LOS_CirBufDeinit(CirBuf *cirbufCB); +extern UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size); +extern UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size); +extern UINT32 LOS_CirBufUsedSize(CirBuf *cirbufCB); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CIRBUF_PRI_H */ diff --git a/targets/bsp/common/los_config.c b/targets/bsp/common/los_config.c new file mode 100644 index 000000000..6df5b6102 --- /dev/null +++ b/targets/bsp/common/los_config.c @@ -0,0 +1,411 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Config Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_config.h" +#include "string.h" +#include "stdio.h" +#ifdef LOSCFG_COMPAT_LINUX +#include "linux/workqueue.h" +#include "linux/module.h" +#endif +#include "los_sys.h" +#include "los_tick.h" +#include "los_task_pri.h" +#include "los_printf.h" +#include "los_swtmr_pri.h" +#include "los_timeslice_pri.h" +#include "los_memory_pri.h" +#include "los_sem_pri.h" +#include "los_mux_pri.h" +#include "los_queue_pri.h" +#include "los_memstat_pri.h" +#include "los_hwi_pri.h" +#include "los_spinlock.h" +#include "los_atomic.h" +#include "los_exc_pri.h" +#include "gic_common.h" + +#ifdef LOSCFG_FS_VFS +#include "fs/fs.h" +#endif + +#if (LOSCFG_KERNEL_TRACE == YES) +#include "los_trace.h" +#endif + +#ifdef LOSCFG_KERNEL_CPUP +#include "los_cpup_pri.h" +#endif + +#ifdef LOSCFG_COMPAT_POSIX +#include "pprivate.h" +#endif + +#ifdef LOSCFG_DRIVERS_UART +#include "console.h" +#endif +#ifdef LOSCFG_KERNEL_TICKLESS +#include "los_tickless.h" +#endif +#ifdef LOSCFG_ARCH_CORTEX_M7 +#include "los_exc_pri.h" +#endif +#ifdef LOSCFG_MEM_RECORDINFO +#include "los_memrecord_pri.h" +#endif +#include "los_hw_tick_pri.h" +#include "los_hwi_pri.h" +#ifdef LOSCFG_KERNEL_DYNLOAD +#include "los_ld_initlib_pri.h" +#endif + +#ifdef LOSCFG_KERNEL_RUNSTOP +#include "los_runstop_pri.h" +#endif + +#if defined(LOSCFG_HW_RANDOM_ENABLE) || defined (LOSCFG_DRIVERS_RANDOM) +#include "randomdev.h" +#include "yarrow.h" +#endif +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#endif +#ifdef LOSCFG_SHELL_LK +#include "shell_pri.h" +#endif + +#ifndef LOSCFG_PLATFORM_OSAPPINIT +#include "los_test_pri.h" +#endif +#ifdef LOSCFG_DRIVERS_BASE +#include "driver_base_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_PLATFORM_OSAPPINIT +extern UINT32 OsAppInit(VOID); +extern VOID app_init(VOID); +#endif + +#if (LOSCFG_LIB_CONFIGURABLE == YES) +LITE_OS_SEC_BSS UINT32 g_taskLimit; +LITE_OS_SEC_BSS UINT32 g_semLimit; +LITE_OS_SEC_BSS UINT32 g_swtmrLimit; +LITE_OS_SEC_BSS UINT32 g_muxLimit; +LITE_OS_SEC_BSS UINT32 g_queLimit; + +#endif + + +LITE_OS_SEC_TEXT_INIT VOID OsRegister(VOID) +{ +#if (LOSCFG_LIB_CONFIGURABLE == YES) + g_taskLimit = LOSCFG_BASE_CORE_TSK_CONFIG; + g_semLimit = LOSCFG_BASE_IPC_SEM_CONFIG; + g_swtmrLimit = LOSCFG_BASE_CORE_SWTMR_CONFIG; + g_muxLimit = LOSCFG_BASE_IPC_MUX_CONFIG; + g_queLimit = LOSCFG_BASE_IPC_QUEUE_CONFIG; +#endif + + /* LOSCFG_BASE_CORE_TSK_LIMIT include IDLE task */ + g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT; + g_sysClock = OS_SYS_CLOCK; + g_tickPerSecond = LOSCFG_BASE_CORE_TICK_PER_SECOND; + + return; +} + +LITE_OS_SEC_TEXT_INIT VOID OsStart(VOID) +{ + LosTaskCB *taskCB = NULL; + UINT32 cpuid = ArchCurrCpuid(); + + OsTickStart(); + + LOS_SpinLock(&g_taskSpin); + taskCB = OsGetTopTask(); + + OS_SCHEDULER_SET(cpuid); + OsCurrTaskSet(taskCB); + PRINTK("cpu %d entering scheduler\n", cpuid); + OsStartToRun(taskCB); +} + +LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsIpcInit(VOID) +{ + UINT32 ret; +#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) { + return ret; + } +#endif + return LOS_OK; +} + +#if (LOSCFG_DRIVERS_BASE == YES) +LITE_OS_SEC_TEXT_INIT STATIC VOID OsDriverBaseInit(VOID) +{ + (VOID)BusInit(); + (VOID)PlatformBusInit(); + (VOID)do_initCalls(LEVEL_ARCH); +} +#endif + +LITE_OS_SEC_TEXT_INIT UINT32 OsMain(void) +{ + UINT32 ret; + + ret = OsMemSystemInit((UINTPTR)&OS_SYS_MEM_START + OS_EXC_INTERACTMEM_SIZE); + if (ret != LOS_OK) { + return ret; + } + + OsRegister(); + +#ifdef LOSCFG_SHELL_LK + OsLkLoggerInit(NULL); +#endif + +#ifdef LOSCFG_EXC_INTERACTION +#ifdef LOSCFG_ARCH_CORTEX_M7 + /* 4096: 4K space for Stack */ + ret = OsMemExcInteractionInit((UINT32)&__bss_end + 4096); +#else + ret = OsMemExcInteractionInit((UINTPTR)&__bss_end); +#endif + if (ret != LOS_OK) { + return ret; + } +#endif + +#ifdef LOSCFG_SHELL_DMESG + ret = OsDmesgInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + +#if (LOSCFG_PLATFORM_HWI == YES) + OsHwiInit(); +#endif + + OsExcInit(); + + ret = OsTickInit(g_sysClock, LOSCFG_BASE_CORE_TICK_PER_SECOND); + if (ret != LOS_OK) { + return ret; + } + +#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS + uart_init(); +#ifdef LOSCFG_SHELL + uart_hwiCreate(); +#endif //LOSCFG_SHELL +#endif //LOSCFG_PLATFORM_UART_WITHOUT_VFS + 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_IPC_QUEUE == YES) || (LOSCFG_BASE_IPC_MUX == YES) || (LOSCFG_BASE_IPC_SEM == YES)) + ret = OsIpcInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + + /* + * CPUP should be inited before first task creation. Don't change this init sequence + * if not neccessary. The sequence should be like this: + * 1. OsIpcInit + * 2. OsCpupInit -> has first task creation + * 3. other inits have task creation + */ +#ifdef LOSCFG_KERNEL_CPUP + ret = OsCpupInit(); + if (ret != LOS_OK) { + PRINT_ERR("OsCpupInit error\n"); + return ret; + } +#endif + +#if (LOSCFG_BASE_CORE_SWTMR == YES) + ret = OsSwtmrInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + +#ifdef LOSCFG_KERNEL_DYNLOAD + ret = OsDynloadInit(); + if (ret != LOS_OK) { + return ret; + } +#endif + +#if defined(LOSCFG_HW_RANDOM_ENABLE) || defined (LOSCFG_DRIVERS_RANDOM) + random_alg_context.ra_init_alg(NULL); + run_harvester_iterate(NULL); +#endif + + ret = OsIdleTaskCreate(); + if (ret != LOS_OK) { + return ret; + } + +#ifdef LOSCFG_KERNEL_RUNSTOP + ret = OsWowWriteFlashTaskCreate(); + if (ret != LOS_OK) { + return ret; + } +#endif + +#if (LOSCFG_DRIVERS_BASE == YES) + OsDriverBaseInit(); +#endif + +#ifdef LOSCFG_PLATFORM_OSAPPINIT + ret = OsAppInit(); +#else /* LOSCFG_TEST */ + ret = OsTestInit(); +#endif + if (ret != LOS_OK) { + return ret; + } +#if (LOSCFG_KERNEL_TRACE == YES) + LOS_TraceInit(); +#endif + + return LOS_OK; +} + +#ifdef LOSCFG_PLATFORM_OSAPPINIT +STATIC UINT32 OsAppTaskCreate(VOID) +{ + UINT32 taskID; + TSK_INIT_PARAM_S appTask; + + (VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)app_init; + appTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + appTask.pcName = "app_Task"; + appTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO; + appTask.uwResved = LOS_TASK_STATUS_DETACHED; + return LOS_TaskCreate(&taskID, &appTask); +} + +#ifdef LOSCFG_MEM_RECORDINFO +STATIC UINT32 OsMemShowTaskCreate(VOID) +{ + UINT32 taskID; + TSK_INIT_PARAM_S appTask; + + (VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsMemRecordShowTask; + appTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + appTask.pcName = "memshow_Task"; + appTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO; + appTask.uwResved = LOS_TASK_STATUS_DETACHED; + return LOS_TaskCreate(&taskID, &appTask); +} +#endif +#endif + +UINT32 OsAppInit(VOID) +{ +#ifdef LOSCFG_PLATFORM_OSAPPINIT + UINT32 ret; +#ifdef LOSCFG_FS_VFS + los_vfs_init(); +#endif +#ifdef LOSCFG_COMPAT_LINUX + ret = HrtimersInit(); + if (ret != LOS_OK) { + PRINT_ERR("HrtimersInit error\n"); + return ret; + } + g_pstSystemWq = create_workqueue("system_wq"); +#endif + ret = OsAppTaskCreate(); + PRINTK("OsAppInit\n"); + if (ret != LOS_OK) { + return ret; + } +#ifdef LOSCFG_MEM_RECORDINFO + ret = OsMemShowTaskCreate(); + if (ret != LOS_OK) { + PRINTK("create memshow_Task error %u\n", ret); + return ret; + } + PRINTK("create memshow_Task ok\n"); +#endif +#ifdef LOSCFG_KERNEL_TICKLESS + LOS_TicklessEnable(); +#endif + +#endif /* LOSCFG_PLATFORM_OSAPPINIT */ + + return 0; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/targets/bsp/common/los_config.h b/targets/bsp/common/los_config.h new file mode 100644 index 000000000..0dbafab2d --- /dev/null +++ b/targets/bsp/common/los_config.h @@ -0,0 +1,567 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +/** + * @defgroup los_config System configuration items + */ + +#ifndef _LOS_CONFIG_H +#define _LOS_CONFIG_H + +#include "platform_config.h" +#include "system_config.h" +#include "los_tick.h" +#include "board.h" +#include "sys_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_config + * int stack start addr + */ +extern CHAR __int_stack_start; +extern CHAR __rodata_start; +extern CHAR __rodata_end; +extern CHAR __bss_start; +extern CHAR __bss_end; +extern UINT32 __heap_start; +extern UINT32 __heap_end; + +/** + * @ingroup los_config + * Number of sort link + */ +#define OS_TSK_SORTLINK_LEN_CONFIG 8U + +/** + * @ingroup los_config + * Number of priority queue + */ +#define OS_PRIORITY_QUEUE_NUM_CONFIG 32 + +/** + * @ingroup los_config + * Configuration lib configurable feature to open + */ +#ifndef LOSCFG_LIB_CONFIGURABLE +#define LOSCFG_LIB_CONFIGURABLE NO +#endif + +/** + * @ingroup los_config + * Eexception handle + */ +#ifndef LOSCFG_PLATFORM_EXC +#define LOSCFG_PLATFORM_EXC NO +#endif + +/****************************** System clock module configuration ****************************/ +/** + * @ingroup los_config + * System clock (unit: HZ) + */ +#ifndef OS_SYS_CLOCK +#define OS_SYS_CLOCK (get_bus_clk()) +#endif +/** + * @ingroup los_config + * time timer clock (unit: HZ) + */ +#ifndef OS_TIME_TIMER_CLOCK +#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK +#endif + +/** + * @ingroup los_config + * limit addr range when search for 'func local(frame pointer)' or 'func name' + */ +#ifndef OS_SYS_FUNC_ADDR_START +#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start) +#endif +#ifndef OS_SYS_FUNC_ADDR_END +#define OS_SYS_FUNC_ADDR_END g_sys_mem_addr_end +#endif + +/** + * @ingroup los_config + * Number of Ticks in one second + */ +#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND +#define LOSCFG_BASE_CORE_TICK_PER_SECOND 100 +#endif + +/** + * @ingroup los_config + * Microseconds of adjtime in one second + */ +#ifndef LOSCFG_BASE_CORE_ADJ_PER_SECOND +#define LOSCFG_BASE_CORE_ADJ_PER_SECOND 500 +#endif + +/** + * @ingroup los_config + * Sched clck interval + */ +#define SCHED_CLOCK_INTETRVAL_TICKS 100 + +/** + * @ingroup los_config + * External configuration item for timer tailoring + */ +#ifndef LOSCFG_BASE_CORE_TICK_HW_TIME +#define LOSCFG_BASE_CORE_TICK_HW_TIME NO +#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 96 +#endif + +/** + * @ingroup los_config + * The binary point value decide the maximum preemption level. + * If preemption supported, the config value is [0, 1, 2, 3, 4, 5, 6], + * to the corresponding preemption level value is [128, 64, 32, 16, 8, 4, 2]. + */ +#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION +#ifndef MAX_BINARY_POINT_VALUE +#define MAX_BINARY_POINT_VALUE 4 +#endif +#endif + +/****************************** Task module configuration ********************************/ +/** + * @ingroup los_config + * Minimum stack size. + * + * 0x600 bytes, aligned on a boundary of 8. + * 0x600 bytes, aligned on a boundary of 4. + */ +#ifndef LOS_TASK_MIN_STACK_SIZE +#ifdef __LP64__ +#define LOS_TASK_MIN_STACK_SIZE (ALIGN(0x800, 8)) +#else +#define LOS_TASK_MIN_STACK_SIZE (ALIGN(0x800, 4)) +#endif +#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 + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +extern UINT32 g_taskLimits; +#define LOSCFG_BASE_CORE_TSK_LIMIT g_taskLimits +#else +#define LOSCFG_BASE_CORE_TSK_LIMIT LOSCFG_BASE_CORE_TSK_CONFIG +#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 SIZE(0x800) +#endif + +/** + * @ingroup los_config + * Default task stack size + */ +#ifndef LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE +#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0x6000) +#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 2 +#endif + +/** + * @ingroup los_config + * Configuration item for task (stack) monitoring module tailoring + */ +#ifndef LOSCFG_BASE_CORE_TSK_MONITOR +#define LOSCFG_BASE_CORE_TSK_MONITOR YES +#endif + +/** + * @ingroup los_config + * Configuration item for task perf task filter hook + */ +#ifndef OS_PERF_TSK_FILTER +#define OS_PERF_TSK_FILTER NO +#endif + +/** + * @ingroup los_config + * Check configuration specifications valid + */ +#if (LOSCFG_BASE_CORE_TSK_CONFIG <= 0) +#error "task maxnum cannot be zero" +#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 + +#if (LOSCFG_BASE_IPC_SEM == YES) +#if (LOSCFG_BASE_IPC_SEM_CONFIG <= 0) +#error "sem maxnum cannot be zero" +#endif +#endif + +/** + * @ingroup los_config + * Maximum supported number of semaphores + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +extern UINT32 g_semLimits; +#define LOSCFG_BASE_IPC_SEM_LIMIT g_semLimits +#else +#define LOSCFG_BASE_IPC_SEM_LIMIT LOSCFG_BASE_IPC_SEM_CONFIG +#endif + +/** + * @ingroup los_config + * Maximum supported number of sortlink + */ +#define OS_TSK_SORTLINK_LEN OS_TSK_SORTLINK_LEN_CONFIG + +/** + * @ingroup los_config + * Maximum supported number of priority queue + */ +#define OS_PRIORITY_QUEUE_NUM OS_PRIORITY_QUEUE_NUM_CONFIG + +/****************************** mutex module configuration ******************************/ +/** + * @ingroup los_config + * Configuration item for mutex module tailoring + */ +#ifndef LOSCFG_BASE_IPC_MUX +#define LOSCFG_BASE_IPC_MUX YES +#endif + +#if (LOSCFG_BASE_IPC_MUX == YES) +#if (LOSCFG_BASE_IPC_MUX_CONFIG <= 0) +#error "mux maxnum cannot be zero" +#endif +#endif + +/** + * @ingroup los_config + * Maximum supported number of mutexes + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +extern UINT32 g_muxLimits; +#define LOSCFG_BASE_IPC_MUX_LIMIT g_muxLimits +#else +#define LOSCFG_BASE_IPC_MUX_LIMIT LOSCFG_BASE_IPC_MUX_CONFIG +#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 + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +extern UINT32 g_queLimit; +#define LOSCFG_BASE_IPC_QUEUE_LIMIT g_queLimit +#else +#define LOSCFG_BASE_IPC_QUEUE_LIMIT LOSCFG_BASE_IPC_QUEUE_CONFIG +#endif +/****************************** Software timer module configuration **************************/ +#if (LOSCFG_BASE_IPC_QUEUE == YES) + +#if (LOSCFG_BASE_IPC_QUEUE_CONFIG <= 0) +#error "queue maxnum cannot be zero" +#endif +/** + * @ingroup los_config + * Configuration item for software timer module tailoring + */ +#ifndef LOSCFG_BASE_CORE_SWTMR +#define LOSCFG_BASE_CORE_SWTMR YES +#endif + +#if (LOSCFG_BASE_CORE_SWTMR == YES) +#if (LOSCFG_BASE_CORE_SWTMR_CONFIG <= 0) +#error "software timer maxnum cannot be zero" +#endif +#endif + +/** + * @ingroup los_config + * Maximum supported number of software timers rather than the number of usable software timers + */ +#if (LOSCFG_LIB_CONFIGURABLE == YES) +extern UINT32 g_swtmrLimits; +#define LOSCFG_BASE_CORE_SWTMR_LIMIT g_swtmrLimits +#else +#define LOSCFG_BASE_CORE_SWTMR_LIMIT LOSCFG_BASE_CORE_SWTMR_CONFIG +#endif + +/** + * @ingroup los_config + * Max number of software timers ID + * + * 0xFFFF: max number of all software timers + */ +#ifndef OS_SWTMR_MAX_TIMERID +#define OS_SWTMR_MAX_TIMERID ((0xFFFF / 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 +#endif + +#endif + +/****************************** Memory module configuration **************************/ +#ifndef LOSCFG_KERNEL_MEM_STATISTICS +#define LOSCFG_KERNEL_MEM_STATISTICS YES +#endif + +#ifndef OS_EXC_INTERACTMEM_SIZE +#define OS_EXC_INTERACTMEM_SIZE (g_excInteractMemSize) +#endif + +/** + * @ingroup los_config + * Starting address of the system memory + */ +#ifndef OS_SYS_MEM_START +#define OS_SYS_MEM_START __bss_end +#endif + +/** + * @ingroup los_config + * Starting address of the system memory + */ +#ifndef OS_SYS_MEM_ADDR +#define OS_SYS_MEM_ADDR &m_aucSysMem1[0] +#endif + +/** + * @ingroup los_config + * Memory size + */ +#ifndef OS_SYS_MEM_SIZE +#define OS_SYS_MEM_SIZE ((g_sys_mem_addr_end) - \ + ((OS_EXC_INTERACTMEM_SIZE + ((UINTPTR)&__bss_end) + (64 - 1)) & ~(64 - 1))) +#endif + +#ifndef OS_SYS_MEM_NUM +#define OS_SYS_MEM_NUM 20 +#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 + +#ifndef LOSCFG_COMPAT_CMSIS +#define LOSCFG_COMPAT_CMSIS NO +#endif + +/****************************** CPU module configuration **************************/ +#define LOSCFG_KERNEL_CORE_NUM 1 + +#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1) + +/****************************** trace module configuration **************************/ +#ifndef LOSCFG_KERNEL_TRACE +#define LOSCFG_KERNEL_TRACE NO +#endif + +/** + * @ingroup los_trace + * It's the total size of trace buffer. It's in the unit of char + */ +#if (LOSCFG_KERNEL_TRACE == YES) +#define LOS_TRACE_BUFFER_SIZE 2048 +#endif + +/****************************** Dynamic loading module configuration **************************/ +#ifndef OS_AUTOINIT_DYNLOADER +#define OS_AUTOINIT_DYNLOADER YES +#endif + +/****************************** exception information configuration ******************************/ +#ifdef LOSCFG_SHELL_EXCINFO +/** + * @ingroup los_config + * the size of space for recording exception information + */ +#define EXCINFO_RECORD_BUF_SIZE (16 * 1024) + +/** + * @ingroup los_config + * the address of space for recording exception information + * @attention + *
      + *
    • if uses, the address must be valid in flash, and it should not overlap with other addresses + * used to store valid information.
    • + *
    + * + */ +#define EXCINFO_RECORD_ADDR (0xffffffff) + +/** + * @ingroup los_config + * @brief define the type of functions for reading or writing exception information . + * + * @par Description: + *
      + *
    • This defination is used to declare the type of functions for reading or writing exception information
    • + *
    + * @attention + *
      + *
    • "startAddr" must be left to save the exception address space, the size of "buf" is "space"
    • + *
    + * + * @param startAddr [IN] Address of storage ,its must be left to save the exception address space + * @param space [IN] size of storage.its is also the size of "buf" + * @param rwFlag [IN] writer-read flag, 0 for writing,1 for reading, other number is to do nothing. + * @param buf [IN] the buffer of storing data. + * + * @retval none. + * @par Dependency: + *
    • los_config.h: the header file that contains the type defination.
    + * @see + * @since Huawei LiteOS V200R002C00 + */ +typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf); + +/** + * @ingroup los_config + * @brief Register recording exception information function. + * + * @par Description: + *
      + *
    • This API is used to Register recording exception information function, + * and specify location and space and size
    • + *
    + * @attention + *
      + *
    • "startAddr" must be left to save the exception address space, the size of "buf" is "space", + * the space of "buf" is malloc or free in user's code
    • + *
    + * + * @param startAddr [IN] Address of storage, it must be left to save the exception address space + * @param space [IN] size of storage space, it is also the size of "buf" + * @param buf [IN] the buffer of storing exception information, the space of "buf" is malloc or free + in user's code + * @param hook [IN] the function for reading or writing exception information. + * + * @retval none. + * @par Dependency: + *
    • los_config.h: the header file that contains the API declaration.
    + * @see + * @since Huawei LiteOS V200R002C00 + */ +VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook); +#endif + +UINT32 OsMain(VOID); +VOID OsStart(VOID); +extern UINT32 LOS_KernelInit(VOID); +extern LITE_OS_SEC_TEXT_INIT VOID OsRegister(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_CONFIG_H */ diff --git a/targets/bsp/common/los_exc_interaction.c b/targets/bsp/common/los_exc_interaction.c new file mode 100644 index 000000000..ef03b2ea6 --- /dev/null +++ b/targets/bsp/common/los_exc_interaction.c @@ -0,0 +1,139 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Exception Interaction Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_exc_interaction_pri.h" +#ifdef LOSCFG_EXC_INTERACTION +#include "los_task_pri.h" +#ifdef LOSCFG_SHELL +#include "shell.h" +#include "shell_pri.h" +#endif +#include "console.h" +#include "hisoc/uart.h" +#include "hal_hwi.h" + +/* Inter-module variable and function */ +extern CONSOLE_CB *g_console[]; + +#define IS_UARTSHELL_ID(taskID) (((taskID) == shellCB->shellTaskHandle) || \ + ((taskID) == shellCB->shellEntryHandle)) + +STATIC BOOL IsIdleTask(UINT32 taskID) +{ + UINT32 i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + if (taskID == g_percpu[i].idleTaskID) { + return TRUE; + } + } + + return FALSE; +} + +STATIC BOOL IsSwtTask(UINT32 taskID) +{ + UINT32 i; + + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + if (taskID == g_percpu[i].swtmrTaskID) { + return TRUE; + } + } + + return FALSE; +} + +UINT32 OsExcInteractionTaskCheck(const TSK_INIT_PARAM_S *initParam) +{ + if (initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)OsIdleTask) { + return LOS_OK; + } + if ((initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellTask) || + (initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellEntry)) { + return LOS_OK; + } + return LOS_NOK; +} + +VOID OsExcInteractionTaskKeep(VOID) +{ + LosTaskCB *taskCB = NULL; + UINT16 tempStatus; + UINT32 taskID; + UINT32 curIrqNum; + ShellCB *shellCB = NULL; + CONSOLE_CB *consoleCB = NULL; + + consoleCB = g_console[CONSOLE_SERIAL - 1]; + if (consoleCB == NULL) { + PRINTK("Serial Shell Uninitialized\n"); + return; + } + shellCB = (ShellCB *)(consoleCB->shellHandle); + + g_intCount[ArchCurrCpuid()] = 0; + for (taskID = 0; taskID < g_taskMaxNum; taskID++) { + if (taskID == OsCurrTaskGet()->taskID) { + continue; + } else if ((IsIdleTask(taskID) == TRUE) || IS_UARTSHELL_ID(taskID)) { + continue; + } + + taskCB = OS_TCB_FROM_TID(taskID); + + tempStatus = taskCB->taskStatus; + if (tempStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + if (IsSwtTask(taskID) == TRUE) { + taskCB->taskFlags &= (~OS_TASK_FLAG_SYSTEM); + } + + (VOID)LOS_TaskDelete(taskID); + } + HalIrqInit(); + HalIrqUnmask(NUM_HAL_INTERRUPT_UART); + curIrqNum = HalCurIrqGet(); + HalIrqClear(curIrqNum); + (VOID)LOS_TaskDelete(OsCurrTaskGet()->taskID); + /* unreachable */ +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif diff --git a/targets/bsp/common/los_exc_interaction_pri.h b/targets/bsp/common/los_exc_interaction_pri.h new file mode 100644 index 000000000..a74cf0778 --- /dev/null +++ b/targets/bsp/common/los_exc_interaction_pri.h @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Exception Interaction Implementation Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_EXC_INTER_PRI_H +#define _LOS_EXC_INTER_PRI_H + +#include "los_config.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 OsExcInteractionTaskCheck(const TSK_INIT_PARAM_S *initParam); +extern VOID OsExcInteractionTaskKeep(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXC_INTER_PRI_H */ diff --git a/targets/bsp/common/los_excinfo.c b/targets/bsp/common/los_excinfo.c new file mode 100644 index 000000000..be83f042c --- /dev/null +++ b/targets/bsp/common/los_excinfo.c @@ -0,0 +1,260 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Exception Information Module Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_base.h" +#if defined(LOSCFG_SHELL_EXCINFO) && defined(LOSCFG_DRIVERS_MTD_SPI_NOR) +#include "linux/mtd/mtd.h" +#include "linux/module.h" +#include "linux/mtd/mtd_list.h" +#include "spinor.h" +#endif +#include "los_hwi.h" +#ifdef LOSCFG_FS_VFS +#include "fs/fs.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_SHELL_EXCINFO +STATIC log_read_write_fn g_excInfoRW = NULL; /* the hook of read-writing exception information */ +STATIC CHAR *g_excInfoBuf = NULL; /* pointer to the buffer for storing the exception information */ +STATIC UINT32 g_excInfoIndex = 0xFFFF; /* the index of the buffer for storing the exception information */ +STATIC UINT32 g_recordAddr = 0; /* the address of storing the exception information */ +STATIC UINT32 g_recordSpace = 0; /* the size of storing the exception information */ + +VOID SetExcInfoRW(log_read_write_fn func) +{ + g_excInfoRW = func; +} + +log_read_write_fn GetExcInfoRW(VOID) +{ + return g_excInfoRW; +} + +VOID SetExcInfoBuf(CHAR *buf) +{ + g_excInfoBuf = buf; +} + +CHAR *GetExcInfoBuf(VOID) +{ + return g_excInfoBuf; +} + +VOID SetExcInfoIndex(UINT32 index) +{ + g_excInfoIndex = index; +} + +UINT32 GetExcInfoIndex(VOID) +{ + return g_excInfoIndex; +} + +VOID SetRecordAddr(UINT32 addr) +{ + g_recordAddr = addr; +} + +UINT32 GetRecordAddr(VOID) +{ + return g_recordAddr; +} + +VOID SetRecordSpace(UINT32 space) +{ + g_recordSpace = space; +} + +UINT32 GetRecordSpace(VOID) +{ + return g_recordSpace; +} + +VOID WriteExcBufVa(const CHAR *format, va_list arglist) +{ + errno_t ret; + + if (g_recordSpace > g_excInfoIndex) { + ret = vsnprintf_s((g_excInfoBuf + g_excInfoIndex), (g_recordSpace - g_excInfoIndex), + (g_recordSpace - g_excInfoIndex - 1), format, arglist); + if (ret == -1) { + PRINT_ERR("exc info buffer is not enough or vsnprintf_s is error.\n"); + return; + } + g_excInfoIndex += ret; + } +} + +VOID WriteExcInfoToBuf(const CHAR *format, ...) +{ + va_list arglist; + + va_start(arglist, format); + WriteExcBufVa(format, arglist); + va_end(arglist); +} + +#ifdef LOSCFG_DRIVERS_MTD_SPI_NOR + +STATIC struct mtd_info *g_mtdSpinor = NULL; + +STATIC VOID OsSpiflashErase(UINT32 start, size_t size) +{ + struct erase_info eraseInfo; + + (VOID)memset_s(&eraseInfo, sizeof(struct erase_info), 0, sizeof(struct erase_info)); + eraseInfo.mtd = g_mtdSpinor; + eraseInfo.callback = NULL; + eraseInfo.fail_addr = (UINT64)MTD_FAIL_ADDR_UNKNOWN; + eraseInfo.addr = start; + eraseInfo.len = size; + eraseInfo.time = 1; + eraseInfo.retries = 1; + eraseInfo.dev = 0; + eraseInfo.cell = 0; + eraseInfo.priv = 0; + eraseInfo.state = 0; + eraseInfo.next = NULL; + eraseInfo.scrub = 0; + (VOID)g_mtdSpinor->erase(g_mtdSpinor, &eraseInfo); +} + +STATIC INT32 OsWriteExcInfoToSpiFlash(UINT32 startAddr, UINT32 space, const CHAR *buf) +{ + UINT32 outLen; + UINT32 len = (space < g_recordSpace) ? space : g_recordSpace; + + (VOID)startAddr; + OsSpiflashErase(g_recordAddr, LOS_Align(g_recordSpace, g_mtdSpinor->erasesize)); + return g_mtdSpinor->write(g_mtdSpinor, (loff_t)g_recordAddr, len, &outLen, buf); +} + +STATIC INT32 OsReadExcInfoForSpiFlash(UINT32 startAddr, UINT32 space, CHAR *buf) +{ + UINT32 outLen; + UINT32 len = (space < g_recordSpace) ? space : g_recordSpace; + + (VOID)startAddr; + return g_mtdSpinor->read(g_mtdSpinor, (loff_t)g_recordAddr, len, &outLen, buf); +} +#endif + +VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook) +{ + if ((hook == NULL) || (buf == NULL)) { + PRINT_ERR("Buf or hook is null.\n"); + return; + } + + g_recordAddr = startAddr; + g_recordSpace = space; + g_excInfoBuf = buf; + g_excInfoRW = hook; + +#ifdef LOSCFG_FS_VFS + los_vfs_init(); +#endif +} + +/* Be called in the exception. */ +VOID OsReadWriteExceptionInfo(UINT32 startAddr, UINT32 space, UINT32 flag, CHAR *buf) +{ + if ((buf == NULL) || (space == 0)) { + PRINT_ERR("buffer is null or space is zero\n"); + return; + } + +#ifdef LOSCFG_DRIVERS_MTD_SPI_NOR + g_mtdSpinor = get_mtd("spinor"); + if (g_mtdSpinor == NULL) { + (VOID)spinor_init(); + g_mtdSpinor = get_mtd("spinor"); + if (g_mtdSpinor == NULL) { + PRINT_ERR("Init spinor is failed\n"); + return; + } + } +#endif + + if (flag == 0) { +#ifdef LOSCFG_DRIVERS_MTD_SPI_NOR + if (OsWriteExcInfoToSpiFlash(startAddr, space, buf) != LOS_OK) { + PRINT_ERR("Exception information written to flash failed\n"); + } + free(buf); /* Consider whether or not the "buf" is released according to actual use */ +#endif + } else if (flag == 1) { +#ifdef LOSCFG_DRIVERS_MTD_SPI_NOR + if (OsReadExcInfoForSpiFlash(startAddr, space, buf) != LOS_OK) { + PRINT_ERR("Exception information read from flash failed\n"); + } +#endif + } else { + PRINT_ERR("flag is error\n"); + } +} + +VOID OsRecordExcInfoTime(VOID) +{ +#ifdef LOSCFG_FS_VFS +#define NOW_TIME_LENGTH 24 + time_t t; + struct tm *tmTime = NULL; + CHAR nowTime[NOW_TIME_LENGTH]; + + (VOID)time(&t); + tmTime = localtime(&t); + if (tmTime == NULL) { + return; + } + (VOID)memset_s(nowTime, sizeof(nowTime), 0, sizeof(nowTime)); + (VOID)strftime(nowTime, NOW_TIME_LENGTH, "%Y-%m-%d %H:%M:%S", tmTime); +#undef NOW_TIME_LENGTH + WriteExcInfoToBuf("%s \n", nowTime); +#endif +} + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/targets/bsp/common/los_excinfo_pri.h b/targets/bsp/common/los_excinfo_pri.h new file mode 100644 index 000000000..ec7285051 --- /dev/null +++ b/targets/bsp/common/los_excinfo_pri.h @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: ExcInfo Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_EXCINFO_PRI_H +#define _LOS_EXCINFO_PRI_H + +#include "los_config.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_SHELL_EXCINFO +extern VOID SetExcInfoRW(log_read_write_fn func); +extern log_read_write_fn GetExcInfoRW(VOID); +extern VOID SetExcInfoBuf(CHAR *buf); +extern CHAR *GetExcInfoBuf(VOID); +extern VOID SetExcInfoIndex(UINT32 index); +extern UINT32 GetExcInfoIndex(VOID); +extern VOID SetRecordAddr(UINT32 addr); +extern UINT32 GetRecordAddr(VOID); +extern VOID SetRecordSpace(UINT32 space); +extern UINT32 GetRecordSpace(VOID); +extern VOID WriteExcBufVa(const CHAR *format, va_list arg); +extern VOID WriteExcInfoToBuf(const CHAR *format, ...); +extern VOID OsRecordExcInfoTime(VOID); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXCINFO_PRI_H */ diff --git a/targets/bsp/common/los_magickey.c b/targets/bsp/common/los_magickey.c new file mode 100644 index 000000000..b58cd0862 --- /dev/null +++ b/targets/bsp/common/los_magickey.c @@ -0,0 +1,158 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: MagicKey Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_magickey.h" +#include "los_task_pri.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#ifdef LOSCFG_ENABLE_MAGICKEY + +#define MAGIC_KEY_NUM 5 + +STATIC VOID OsMagicHelp(VOID); +STATIC VOID OsMagicTaskShow(VOID); +STATIC VOID OsMagicPanic(VOID); +STATIC VOID OsMagicMemCheck(VOID); + +STATIC MagicKeyOp g_magicMemCheckOp = { + .opHandler = OsMagicMemCheck, + .helpMsg = "Check system memory(ctrl+e) ", + .magicKey = 0x05 /* ctrl + e */ +}; + +STATIC MagicKeyOp g_magicPanicOp = { + .opHandler = OsMagicPanic, + .helpMsg = "System panic(ctrl+p) ", + .magicKey = 0x10 /* ctrl + p */ +}; + +STATIC MagicKeyOp g_magicTaskShowOp = { + .opHandler = OsMagicTaskShow, + .helpMsg = "Show task information(ctrl+t) ", + .magicKey = 0x14 /* ctrl + t */ +}; + +STATIC MagicKeyOp g_magicHelpOp = { + .opHandler = OsMagicHelp, + .helpMsg = "Show all magic op key(ctrl+z) ", + .magicKey = 0x1a /* ctrl + z */ +}; + +/* + * NOTICE:Suggest don't use + * ctrl+h/backspace=0x8, + * ctrl+i/tab=0x9, + * ctrl+m/enter=0xd, + * ctrl+n/shift out=0xe, + * ctrl+o/shift in=0xf, + * ctrl+[/esc=0x1b, + * ctrl+] used for telnet commond mode; + */ +STATIC MagicKeyOp *g_magicOpTable[MAGIC_KEY_NUM] = { + &g_magicMemCheckOp, /* ctrl + e */ + &g_magicPanicOp, /* ctrl + p */ + &g_magicTaskShowOp, /* ctrl + t */ + &g_magicHelpOp, /* ctrl + z */ + NULL /* rserved */ +}; + +STATIC VOID OsMagicHelp(VOID) +{ + INT32 i; + PRINTK("HELP: "); + for (i = 0; g_magicOpTable[i] != NULL; ++i) { + PRINTK("%s ", g_magicOpTable[i]->helpMsg); + } + PRINTK("\n"); + return; +} + +STATIC VOID OsMagicTaskShow(VOID) +{ + (VOID)OsShellCmdDumpTask(0, NULL); + return; +} + +STATIC VOID OsMagicPanic(VOID) +{ + LOS_Panic("Magic key :\n"); + return; +} + +STATIC VOID OsMagicMemCheck(VOID) +{ + if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) { + PRINTK("system memcheck over, all passed!\n"); + } + return; +} +#endif + +INT32 CheckMagicKey(CHAR key) +{ +#ifdef LOSCFG_ENABLE_MAGICKEY + INT32 i; + STATIC UINT32 magicKeySwitch = 0; + if (key == 0x12) { /* ctrl + r */ + magicKeySwitch = ~magicKeySwitch; + if (magicKeySwitch != 0) { + PRINTK("Magic key on\n"); + } else { + PRINTK("Magic key off\n"); + } + return 1; + } + if (magicKeySwitch != 0) { + for (i = 0; g_magicOpTable[i] != NULL; ++i) { + if (key == g_magicOpTable[i]->magicKey) { + (g_magicOpTable[i])->opHandler(); + return 1; + } + } + } +#else + (VOID)key; +#endif + return 0; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/kernel/base/include/los_event.ph b/targets/bsp/common/los_magickey.h similarity index 75% rename from kernel/base/include/los_event.ph rename to targets/bsp/common/los_magickey.h index 1ba5f5420..465272c17 100644 --- a/kernel/base/include/los_event.ph +++ b/targets/bsp/common/los_magickey.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. + * Description: MagicKey Headfile * 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 @@ -22,36 +22,39 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_EVENT_PH -#define _LOS_EVENT_PH - -#include "los_event.h" + * --------------------------------------------------------------------------- */ +#ifndef _LOS_MAGICKEY_H +#define _LOS_MAGICKEY_H + +#include "los_exc.h" + #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cplusplus */ -#endif /* __cplusplus */ - - -extern UINT32 osEventReadOnce(PEVENT_CB_S pstEventCB, UINT32 uwEventMask, UINT32 uwMode, UINT32 uwTimeOut); -extern UINT32 osEventWriteOnce(PEVENT_CB_S pstEventCB, UINT32 uwEvents); - - +#endif /* __cplusplus */ + +typedef struct { + VOID (*opHandler)(VOID); + CHAR *helpMsg; + CHAR magicKey; +} MagicKeyOp; + +extern INT32 CheckMagicKey(CHAR key); + #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_EVENT_PH */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/targets/bsp/common/los_printf.c b/targets/bsp/common/los_printf.c new file mode 100644 index 000000000..ad296bfb7 --- /dev/null +++ b/targets/bsp/common/los_printf.c @@ -0,0 +1,263 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Printf Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_base.h" +#ifdef LOSCFG_LIB_LIBC +#include "stdlib.h" +#include "unistd.h" +#endif +#ifdef LOSCFG_LIB_LIBCMINI +#include "stdarg.h" +#endif +#include "los_hwi.h" +#include "los_memory_pri.h" +#include "uart.h" +#ifdef LOSCFG_FS_VFS +#include "console.h" +#endif +#ifdef LOSCFG_SHELL_DMESG +#include "dmesg_pri.h" +#endif +#ifdef LOSCFG_SHELL_EXCINFO +#include "los_excinfo_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define USE_STACK_BUFFER +#define SIZEBUF 256 + +typedef enum { + NO_OUTPUT = 0, + UART_OUTPUT = 1, + CONSOLE_OUTPUT = 2, + EXC_OUTPUT = 3 +} OutputType; + +STATIC VOID ErrorMsg(VOID) +{ + const CHAR *p = "Output illegal string! vsnprintf_s failed!\n"; + (VOID)UartPuts(p, (INT32)strlen(p), UART_WITH_LOCK); +} + +STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock) +{ +#ifdef LOSCFG_SHELL_DMESG + if (!OsCheckUartLock()) { + UartPuts(str, len, isLock); + } + if (isLock != UART_WITHOUT_LOCK) { + (VOID)OsLogMemcpyRecord(str, len); + } +#else + (VOID)UartPuts(str, (INT32)len, isLock); +#endif +} + +STATIC VOID OutputControl(const CHAR *str, UINT32 len, OutputType type) +{ + switch (type) { + case CONSOLE_OUTPUT: +#ifdef LOSCFG_PLATFORM_CONSOLE + if (ConsoleEnable() == TRUE) { + (VOID)write(STDOUT_FILENO, str, (size_t)len); + break; + } +#endif + /* fall-through */ + case UART_OUTPUT: + UartOutput(str, len, UART_WITH_LOCK); + break; + case EXC_OUTPUT: + UartOutput(str, len, UART_WITHOUT_LOCK); + break; + default: + break; + } + return; +} + +STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen) +{ +#ifdef USE_STACK_BUFFER + if (bufLen != SIZEBUF) { + (VOID)LOS_MemFree(m_aucSysMem0, buf); + } +#else + (VOID)LOS_MemFree(m_aucSysMem0, buf); +#endif +} + +STATIC VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type) +{ + INT32 len; + UINT32 bufLen = SIZEBUF; + CHAR *bBuf = NULL; +#ifdef USE_STACK_BUFFER + CHAR aBuf[SIZEBUF]; + bBuf = aBuf; +#else + bBuf = (CHAR *)LOS_MemAlloc(m_aucSysMem0, SIZEBUF); + if (bBuf == NULL) { + PRINT_ERR("%s, %d, malloc failed!\n", __FUNCTION__, __LINE__); + return; + } +#endif + len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap); + if ((len == -1) && (*bBuf == '\0')) { + /* parameter is illegal or some features in fmt dont support */ + ErrorMsg(); + goto EXIT; + } + + while (len == -1) { + /* bBuf is not enough */ + OsVprintfFree(bBuf, bufLen); + + bufLen = bufLen << 1; + if ((INT32)bufLen <= 0) { + PRINT_ERR("%s, %d, length overflow!\n", __FUNCTION__, __LINE__); + return; + } + bBuf = (CHAR *)LOS_MemAlloc(m_aucSysMem0, bufLen); + if (bBuf == NULL) { + PRINT_ERR("%s, %d, malloc failed!\n", __FUNCTION__, __LINE__); + return; + } + len = vsnprintf_s(bBuf, bufLen, bufLen - 1, fmt, ap); + if (*bBuf == '\0') { + /* parameter is illegal or some features in fmt dont support */ + ErrorMsg(); + goto EXIT; + } + } + *(bBuf + len) = '\0'; + OutputControl(bBuf, len, type); +EXIT: + OsVprintfFree(bBuf, bufLen); +} + +VOID UartVprintf(const CHAR *fmt, va_list ap) +{ + OsVprintf(fmt, ap, UART_OUTPUT); +} + +__attribute__((noinline)) VOID UartPrintf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, UART_OUTPUT); + va_end(ap); +} + +__attribute__ ((noinline)) VOID OsDprintf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, CONSOLE_OUTPUT); + va_end(ap); +} + +VOID LkDprintf(const CHAR *fmt, va_list ap) +{ + OsVprintf(fmt, ap, CONSOLE_OUTPUT); +} + +#ifdef LOSCFG_SHELL_DMESG +VOID DmesgPrintf(const CHAR *fmt, va_list ap) +{ + OsVprintf(fmt, ap, CONSOLE_OUTPUT); +} +#endif + +#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS +__attribute__ ((noinline)) INT32 printf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, UART_OUTPUT); + va_end(ap); +} +#else +#ifdef LOSCFG_PLATFORM_NO_UART +__attribute__ ((noinline)) int printf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, CONSOLE_OUTPUT); + va_end(ap); + return LOS_OK; +} +#endif +#endif + +__attribute__((noinline)) VOID syslog(INT32 level, const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + OsVprintf(fmt, ap, CONSOLE_OUTPUT); + va_end(ap); + (VOID)level; +} + +__attribute__((noinline)) VOID ExcPrintf(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + /* uart output without print-spinlock */ + OsVprintf(fmt, ap, EXC_OUTPUT); + va_end(ap); +} + +VOID PrintExcInfo(const CHAR *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + /* uart output without print-spinlock */ + OsVprintf(fmt, ap, EXC_OUTPUT); +#ifdef LOSCFG_SHELL_EXCINFO + WriteExcBufVa(fmt, ap); +#endif + va_end(ap); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/targets/bsp/common/los_timer_pri.h b/targets/bsp/common/los_timer_pri.h new file mode 100644 index 000000000..0e14ae916 --- /dev/null +++ b/targets/bsp/common/los_timer_pri.h @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Timer Inner HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ +#ifndef _LOS_TIMER_PRI_H +#define _LOS_TIMER_PRI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern VOID OsAdjTime(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif /* _LOS_TIMER_PRI_H */ diff --git a/kernel/base/core/los_timeslice.inc b/targets/bsp/common/pm/hal_cpu_freq.h similarity index 76% rename from kernel/base/core/los_timeslice.inc rename to targets/bsp/common/pm/hal_cpu_freq.h index d4b62b0c1..df38464c1 100644 --- a/kernel/base/core/los_timeslice.inc +++ b/targets/bsp/common/pm/hal_cpu_freq.h @@ -1,6 +1,6 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * All rights reserved. +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Cpu Freq HeadFile * 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 @@ -22,23 +22,21 @@ * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- * Notice of Export Control Law * =============================================== * Huawei LiteOS may be subject to applicable export control laws and regulations, which might * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ + * --------------------------------------------------------------------------- */ -/**@defgroup los_timeslice Timeslice - * @ingroup kernel - */ +#ifndef __HAL_CPU_FREQ_H__ +#define __HAL_CPU_FREQ_H__ -#ifndef _LOS_TIMESLICE_INC -#define _LOS_TIMESLICE_INC +void hal_cpu_set_freq_clk(unsigned int freq); +int hal_cpu_get_freq_clk(void); -#include "los_timeslice.ph" +#endif -#endif /* _LOS_TIMESLICE_INC */ diff --git a/targets/bsp/common/pm/hal_cpu_regulator.h b/targets/bsp/common/pm/hal_cpu_regulator.h new file mode 100644 index 000000000..3f167c7ae --- /dev/null +++ b/targets/bsp/common/pm/hal_cpu_regulator.h @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Cpu Regulator HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef __HAL_CPU_REGULATOR_H__ +#define __HAL_CPU_REGULATOR_H__ + +void hal_cpu_domain_set_voltage(int step, int regulator_max, int set_volt); +int hal_cpu_domain_get_voltage(int step, int regulator_max); +int hal_cpu_domain_get_regulator_step(int min_uV, int max_uV); + +#endif + diff --git a/targets/bsp/common/pm/hal_media_freq.h b/targets/bsp/common/pm/hal_media_freq.h new file mode 100644 index 000000000..e3c508efb --- /dev/null +++ b/targets/bsp/common/pm/hal_media_freq.h @@ -0,0 +1,58 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Media Freq HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef __HAL_MEDIA_FREQ_H__ +#define __HAL_MEDIA_FREQ_H__ + +#define MEDIA_AVS_VOLT_STEP 10000 /* mv */ +#define MEDIA_AVS_HPM_DELTA_MIN 1 +#define MEDIA_AVS_HPM_DELTA_MAX 6 + +#define MEDIA_PROF_NUM 2 +#define MEDIA_TEMP_NUM 2 + +#define MEDIA_SVB_NUM 4 + +#define OTP_MDA_HPM_IDDQ 0x12032004 + +unsigned int hal_get_hpm_value(void); +void hal_media_set_hpm_div(unsigned int div); +unsigned hal_media_update_vmax(unsigned int hpm_mda_value); +void hal_media_hpm_init(void); +void hal_media_tsensor_init(void); +int hal_media_get_average_hpm(void); +int hal_media_get_average_temperature(void); + +#endif /* End of #ifndef __HAL_MEDIA_FREQ_H__ */ + diff --git a/targets/bsp/common/pm/hal_media_regulator.h b/targets/bsp/common/pm/hal_media_regulator.h new file mode 100644 index 000000000..746afe232 --- /dev/null +++ b/targets/bsp/common/pm/hal_media_regulator.h @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Media Freq HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef __HAL_MEDIA_REGULATOR_H__ +#define __HAL_MEDIA_REGULATOR_H__ + +void hal_media_domain_set_voltage(int step, int max_uV, int set_volt); +int hal_media_domain_get_regulator_step(int min_uV, int max_uV); +int hal_media_domain_get_voltage(int step, int max_uV); + +#endif + diff --git a/kernel/base/include/los_base.ph b/targets/bsp/common/sys_config.h similarity index 69% rename from kernel/base/include/los_base.ph rename to targets/bsp/common/sys_config.h index 0326a1c51..c94ca4d89 100644 --- a/kernel/base/include/los_base.ph +++ b/targets/bsp/common/sys_config.h @@ -1,70 +1,73 @@ -/*---------------------------------------------------------------------------- - * Copyright (c) <2013-2015>, - * 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. - *---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- - * Notice of Export Control Law - * =============================================== - * Huawei LiteOS may be subject to applicable export control laws and regulations, which might - * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. - * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such - * applicable export control laws and regulations. - *---------------------------------------------------------------------------*/ - -#ifndef _LOS_BASE_PH -#define _LOS_BASE_PH - -#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 uwCntHi; /**< Upper 32 bits of the tick value*/ - UINT32 uwCntLo; /**< Lower 32 bits of the tick value*/ -} CPU_TICK; - -#define OS_GOTO_ERREND() \ - do \ - { \ - goto LOS_ERREND; \ - } while (0) - - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* _LOS_BASE_PH */ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: System Config HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _SYS_CONFIG_H +#define _SYS_CONFIG_H + +#include "menuconfig.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifndef LOSCFG_MACRO_CONFIG +#define LOSCFG_MACRO_CONFIG + +#ifdef LOSCFG_LIB_LIBC +#define CONFIG_STRERROR +#endif + +#ifdef LOSCFG_NET_LWIP_SACK +#define LWIP_BSD_API 1 +#endif + +#ifdef LOSCFG_DEBUG_VERSION +#define LOSCFG_MEM_WATERLINE +#endif + +#ifdef LOSCFG_DRIVERS_USB +#define SUPPORT_LOS_USB_NEW_DRIVER +#define USB_DEBUG_VAR 5 +#endif +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _SYS_CONFIG_H */ \ No newline at end of file diff --git a/targets/bsp/common/virtual_serial.c b/targets/bsp/common/virtual_serial.c new file mode 100644 index 000000000..b924e0af9 --- /dev/null +++ b/targets/bsp/common/virtual_serial.c @@ -0,0 +1,315 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Virtual Serial Implementation + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "virtual_serial.h" +#include "fcntl.h" +#ifdef CONFIG_FILE_MODE +#include "stdarg.h" +#endif +#ifdef LOSCFG_FS_VFS +#include "inode/inode.h" +#include "console.h" +#endif +#include "uart.h" +#include "local.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +STATIC volatile UINT32 g_serialType = 0; +STATIC struct file g_serialFilep; + +UINT32 SerialTypeGet(VOID) +{ + return g_serialType; +} + +STATIC VOID SerialTypeSet(const CHAR *deviceName) +{ + if (!strncmp(deviceName, SERIAL_UARTDEV, strlen(SERIAL_UARTDEV))) { + g_serialType = SERIAL_TYPE_UART_DEV; + } else if (!strncmp(deviceName, SERIAL_TTYGS0, strlen(SERIAL_TTYGS0))) { + g_serialType = SERIAL_TYPE_USBTTY_DEV; + } +} + +STATIC INT32 SerialOpen(struct file *filep) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = EINVAL; + goto ERROUT; + } + + ret = FilepOpen(privFilep, fileOps); + if (ret < 0) { + ret = EPERM; + goto ERROUT; + } + + if (g_serialType == SERIAL_TYPE_UART_DEV) { + HalIrqUnmask(NUM_HAL_INTERRUPT_UART); + } + return ENOERR; + +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +STATIC INT32 SerialClose(struct file *filep) +{ + (VOID)filep; + + if (g_serialType == SERIAL_TYPE_UART_DEV) { + HalIrqMask(NUM_HAL_INTERRUPT_UART); + } +#if defined(LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined(LOSCFG_DRIVERS_USB_ETH_SER_GADGET) + else if (g_serialType == SERIAL_TYPE_USBTTY_DEV) { + userial_mask_set(0); + } +#endif + + return ENOERR; +} + +STATIC ssize_t SerialRead(struct file *filep, CHAR *buffer, size_t bufLen) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + ret = FilepRead(privFilep, fileOps, buffer, bufLen); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +/* Note: do not add print function in this module! */ +STATIC ssize_t SerialWrite(FAR struct file *filep, FAR const CHAR *buffer, size_t bufLen) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + ret = FilepWrite(privFilep, fileOps, buffer, bufLen); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC INT32 SerialIoctl(struct file *filep, INT32 cmd, unsigned long arg) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + + ret = FilepIoctl(privFilep, fileOps, cmd, arg); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC INT32 SerialPoll(struct file *filep, poll_table *fds) +{ + INT32 ret; + struct file *privFilep = NULL; + const struct file_operations_vfs *fileOps = NULL; + + ret = GetFilepOps(filep, &privFilep, &fileOps); + if (ret != ENOERR) { + ret = -EINVAL; + goto ERROUT; + } + ret = FilepPoll(privFilep, fileOps, fds); + if (ret < 0) { + goto ERROUT; + } + return ret; + +ERROUT: + set_errno(-ret); + return VFS_ERROR; +} + +STATIC const struct file_operations_vfs g_serialDevOps = { + SerialOpen, /* open */ + SerialClose, /* close */ + SerialRead, /* read */ + SerialWrite, + NULL, + SerialIoctl, +#ifndef CONFIG_DISABLE_POLL + SerialPoll, +#endif + NULL +}; + +INT32 virtual_serial_init(const CHAR *deviceName) +{ + INT32 ret; + CHAR *fullpath = NULL; + struct inode *inode = NULL; + + if (deviceName == NULL) { + ret = EINVAL; + goto ERROUT; + } + + SerialTypeSet(deviceName); + + ret = vfs_normalize_path(NULL, deviceName, &fullpath); + if (ret < 0) { + ret = EINVAL; + goto ERROUT; + } + + inode = inode_find(fullpath, NULL); + if (inode == NULL) { + ret = ENOENT; + goto ERROUT_WITH_FULLPATH; + } + + (VOID)memset_s(&g_serialFilep, sizeof(struct file), 0, sizeof(struct file)); + g_serialFilep.f_oflags = O_RDWR; + g_serialFilep.f_inode = inode; + + if (inode->u.i_ops->open != NULL) { + (VOID)inode->u.i_ops->open(&g_serialFilep); + } else { + ret = EFAULT; + inode_release(inode); + goto ERROUT_WITH_FULLPATH; + } + + (VOID)register_driver(SERIAL, &g_serialDevOps, DEFFILEMODE, &g_serialFilep); + inode_release(inode); + free(fullpath); + return ENOERR; + +ERROUT_WITH_FULLPATH: + free(fullpath); +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +INT32 virtual_serial_deinit(VOID) +{ + INT32 ret; + struct file *filep = NULL; + struct inode *inode = NULL; + CHAR *fullpath = NULL; + + /* It's a process opposite virtual_serial_init */ + ret = vfs_normalize_path(NULL, SERIAL, &fullpath); + if (ret < 0) { + ret = EINVAL; + goto ERROUT; + } + + inode = inode_find(fullpath, NULL); + if (inode == NULL) { + ret = ENOENT; + goto ERROUT_WITH_FULLPATH; + } + + filep = inode->i_private; + if ((filep != NULL) && (inode->u.i_ops != NULL)) { + (VOID)inode->u.i_ops->close(filep); /* close filep */ + inode->i_private = NULL; + } else { + ret = EBADF; + goto ERROUT_WITH_INODE; + } + inode_release(inode); + free(fullpath); + (VOID)unregister_driver(SERIAL); + + return ENOERR; + +ERROUT_WITH_INODE: + inode_release(inode); +ERROUT_WITH_FULLPATH: + free(fullpath); +ERROUT: + set_errno(ret); + return VFS_ERROR; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/targets/bsp/common/virtual_serial.h b/targets/bsp/common/virtual_serial.h new file mode 100644 index 000000000..d2805e2ea --- /dev/null +++ b/targets/bsp/common/virtual_serial.h @@ -0,0 +1,78 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Virtual Serial HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _VIRTUAL_SERIAL_H +#define _VIRTUAL_SERIAL_H + +#include "los_config.h" +#ifdef LOSCFG_FS_VFS +#include "fs/fs.h" +#endif +#if defined(LOSCFG_DRIVERS_USB_SERIAL_GADGET) || defined(LOSCFG_DRIVERS_USB_ETH_SER_GADGET) +#include "implementation/usb_api_pri.h" +#endif + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_FS_VFS +#define SERIAL "/dev/serial" +#define SERIAL_TTYGS0 "/dev/ttyGS0" +#define SERIAL_UARTDEV "/dev/uartdev" + +#define SERIAL_TYPE_UART_DEV 1 +#define SERIAL_TYPE_USBTTY_DEV 2 + +extern INT32 virtual_serial_init(const CHAR *deviceName); +extern INT32 virtual_serial_deinit(VOID); + +extern UINT32 SerialTypeGet(VOID); + +typedef struct { + struct file *filep; + UINT32 mask; +} LOS_VIRSERIAL_CB; + +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _VIRTUAL_SERIAL_H */ diff --git a/targets/bsp/hw/arm/interrupt/gic/gic_v2.c b/targets/bsp/hw/arm/interrupt/gic/gic_v2.c new file mode 100644 index 000000000..1bc8bd6cd --- /dev/null +++ b/targets/bsp/hw/arm/interrupt/gic/gic_v2.c @@ -0,0 +1,174 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: General interrupt controller version 2.0 (GICv2). + * Notes: Reference from arm documents: + * https://static.docs.arm.com/ihi0048/bb/IHI0048B_b_gic_architecture_specification.pdf + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "gic_common.h" +#include "los_hwi_pri.h" +#include "los_mp.h" + +STATIC_ASSERT(OS_USER_HWI_MAX <= 1020, "hwi max is too large!"); + +#ifdef LOSCFG_PLATFORM_BSP_GIC_V2 + +STATIC UINT32 g_curIrqNum = 0; + +UINT32 HalCurIrqGet(VOID) +{ + return g_curIrqNum; +} + +VOID HalIrqMask(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ICENABLER(vector / 32)) = 1U << (vector % 32); +} + +VOID HalIrqUnmask(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32); +} + +VOID HalIrqPending(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32); +} + +VOID HalIrqClear(UINT32 vector) +{ + GIC_REG_32(GICC_EOIR) = vector; +} + +VOID HalIrqInitPercpu(VOID) +{ + /* unmask interrupts */ + GIC_REG_32(GICC_PMR) = 0xFF; + + /* enable gic cpu interface */ + GIC_REG_32(GICC_CTLR) = 1; +} + +VOID HalIrqInit(VOID) +{ + UINT32 i; + + /* set externel interrupts to be level triggered, active low. */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 16) { + GIC_REG_32(GICD_ICFGR(i / 16)) = 0; + } + + /* set externel interrupts to CPU 0 */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 4) { + GIC_REG_32(GICD_ITARGETSR(i / 4)) = 0x01010101; + } + + /* set priority on all interrupts */ + for (i = 0; i < OS_HWI_MAX_NUM; i += 4) { + GIC_REG_32(GICD_IPRIORITYR(i / 4)) = GICD_INT_DEF_PRI_X4; + } + + /* disable all interrupts. */ + for (i = 0; i < OS_HWI_MAX_NUM; i += 32) { + GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0; + } + + HalIrqInitPercpu(); + + /* enable gic distributor control */ + GIC_REG_32(GICD_CTLR) = 1; +} + +VOID HalIrqHandler(VOID) +{ + UINT32 iar = GIC_REG_32(GICC_IAR); + UINT32 vector = iar & 0x3FFU; + + /* + * invalid irq number, mainly the spurious interrupts 0x3ff, + * gicv2 valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM + * to do the checking. + */ + if (vector >= OS_HWI_MAX_NUM) { + return; + } + g_curIrqNum = vector; + + OsInterrupt(vector); + + /* use orignal iar to do the EOI */ + GIC_REG_32(GICC_EOIR) = iar; +} + +CHAR *HalIrqVersion(VOID) +{ + UINT32 pidr = GIC_REG_32(GICD_PIDR2V2); + CHAR *irqVerString = NULL; + + switch (pidr >> GIC_REV_OFFSET) { + case GICV1: + irqVerString = "GICv1"; + break; + case GICV2: + irqVerString = "GICv2"; + break; + default: + irqVerString = "unknown"; + } + return irqVerString; +} + +UINT32 HalIrqCreate(UINT32 irq, UINT8 priority) +{ + (VOID)irq; + (VOID)priority; + return LOS_OK; +} +UINT32 HalIrqDelete(UINT32 irq) +{ + (VOID)irq; + return LOS_OK; +} + +#endif diff --git a/targets/bsp/hw/arm/interrupt/gic/gic_v3.c b/targets/bsp/hw/arm/interrupt/gic/gic_v3.c new file mode 100644 index 000000000..5e5dc2106 --- /dev/null +++ b/targets/bsp/hw/arm/interrupt/gic/gic_v3.c @@ -0,0 +1,364 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: General interrupt controller version 3.0 (GICv3). + * Notes: Reference from arm documents: + * https://static.docs.arm.com/ihi0069/d/IHI0069D_gic_architecture_specification.pdf + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "gic_common.h" +#include "gic_v3.h" +#include "los_typedef.h" +#include "los_hwi_pri.h" +#include "los_mp.h" + +#ifdef LOSCFG_PLATFORM_BSP_GIC_V3 + +STATIC UINT32 g_curIrqNum = 0; + +STATIC INLINE UINT64 MpidrToAffinity(UINT64 mpidr) +{ + return ((MPIDR_AFF_LEVEL(mpidr, 3) << 32) | + (MPIDR_AFF_LEVEL(mpidr, 2) << 16) | + (MPIDR_AFF_LEVEL(mpidr, 1) << 8) | + (MPIDR_AFF_LEVEL(mpidr, 0))); +} + +STATIC VOID GicWaitForRwp(UINT64 reg) +{ + INT32 count = 1000000; + + while (GIC_REG_32(reg) & (1U << 31)) { + count -= 1; + if (!count) { + PRINTK("gic_v3: rwp timeout 0x%x\n", GIC_REG_32(reg)); + return; + } + } +} + +STATIC INLINE VOID GicdSetGroup(UINT32 irq) +{ + /* configure spi as group 0 on secure mode and group 1 on unsecure mode */ +#if LOSCFG_ARCH_SECURE_MONITOR_MODE + GIC_REG_32(GICD_IGROUPR(irq / 32)) = 0; +#else + GIC_REG_32(GICD_IGROUPR(irq / 32)) = 0xffffffff; +#endif +} + +STATIC INLINE VOID GicrSetWaker(UINT32 cpu) +{ + GIC_REG_32(GICR_WAKER(cpu)) &= ~GICR_WAKER_PROCESSORSLEEP; + DSB; + ISB; + while ((GIC_REG_32(GICR_WAKER(cpu)) & 0x4) == GICR_WAKER_CHILDRENASLEEP); +} + +STATIC INLINE VOID GicrSetGroup(UINT32 cpu) +{ + /* configure sgi/ppi as group 0 on secure mode and group 1 on unsecure mode */ +#if LOSCFG_ARCH_SECURE_MONITOR_MODE + GIC_REG_32(GICR_IGROUPR0(cpu)) = 0; + GIC_REG_32(GICR_IGRPMOD0(cpu)) = 0; +#else + GIC_REG_32(GICR_IGROUPR0(cpu)) = 0xffffffff; +#endif +} + +STATIC VOID GicdSetPmr(UINT32 irq, UINT8 priority) +{ + UINT32 pos = irq >> 2; /* one irq have the 8-bit interrupt priority field */ + UINT32 newPri = GIC_REG_32(GICD_IPRIORITYR(pos)); + + /* Shift and mask the correct bits for the priority */ + newPri &= ~(GIC_PRIORITY_MASK << ((irq % 4) * GIC_PRIORITY_OFFSET)); + newPri |= priority << ((irq % 4) * GIC_PRIORITY_OFFSET); + + GIC_REG_32(GICD_IPRIORITYR(pos)) = newPri; +} + +STATIC VOID GicrSetPmr(UINT32 irq, UINT8 priority) +{ + UINT32 cpu = ArchCurrCpuid(); + UINT32 pos = irq >> 2; /* one irq have the 8-bit interrupt priority field */ + UINT32 newPri = GIC_REG_32(GICR_IPRIORITYR0(cpu) + pos * 4); + + /* Clear priority offset bits and set new priority */ + newPri &= ~(GIC_PRIORITY_MASK << ((irq % 4) * GIC_PRIORITY_OFFSET)); + newPri |= priority << ((irq % 4) * GIC_PRIORITY_OFFSET); + + GIC_REG_32(GICR_IPRIORITYR0(cpu) + pos * 4) = newPri; +} + +STATIC VOID GiccInitPercpu(VOID) +{ + /* enable system register interface */ + UINT32 sre = GiccGetSre(); + if (!(sre & 0x1)) { + GiccSetSre(sre | 0x1); + + /* + * Need to check that the SRE bit has actually been set. If + * not, it means that SRE is disabled at up EL level. We're going to + * die painfully, and there is nothing we can do about it. + */ + sre = GiccGetSre(); + LOS_ASSERT(sre & 0x1); + } + +#if LOSCFG_ARCH_SECURE_MONITOR_MODE + /* Enable group 0 and disable grp1ns grp1s interrupts */ + GiccSetIgrpen0(1); + GiccSetIgrpen1(0); + + /* + * For priority grouping. + * The value of this field control show the 8-bit interrupt priority field + * is split into a group priority field, that determines interrupt preemption, + * and a subpriority field. + */ + GiccSetBpr0(MAX_BINARY_POINT_VALUE); +#else + /* enable group 1 interrupts */ + GiccSetIgrpen1(1); +#endif + + /* set priority threshold to max */ + GiccSetPmr(0xff); + + /* EOI deactivates interrupt too (mode 0) */ + GiccSetCtlr(0); +} + +UINT32 HalCurIrqGet(VOID) +{ + return g_curIrqNum; +} + +VOID HalIrqMask(UINT32 vector) +{ + INT32 i; + const UINT32 mask = 1U << (vector % 32); + + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + if (vector < 32) { + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + GIC_REG_32(GICR_ICENABLER0(i)) = mask; + GicWaitForRwp(GICR_CTLR(i)); + } + } else { + GIC_REG_32(GICD_ICENABLER(vector >> 5)) = mask; + GicWaitForRwp(GICD_CTLR); + } +} + +VOID HalIrqUnmask(UINT32 vector) +{ + INT32 i; + const UINT32 mask = 1U << (vector % 32); + + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { + return; + } + + if (vector < 32) { + for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) { + GIC_REG_32(GICR_ISENABLER0(i)) = mask; + GicWaitForRwp(GICR_CTLR(i)); + } + } else { + GIC_REG_32(GICD_ISENABLER(vector >> 5)) = mask; + GicWaitForRwp(GICD_CTLR); + } +} + +VOID HalIrqPending(UINT32 vector) +{ + if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { /*lint !e685 !e568*/ + return; + } + + GIC_REG_32(GICD_ISPENDR(vector >> 5)) = 1U << (vector % 32); +} + +VOID HalIrqClear(UINT32 vector) +{ + GiccSetEoir(vector); + ISB; +} + +UINT32 HalIrqSetPrio(UINT32 vector, UINT8 priority) +{ + UINT8 prio = priority; + + if (vector > OS_HWI_MAX_NUM) { + PRINT_ERR("Invalid irq value %u, max irq is %u\n", vector, OS_HWI_MAX_NUM); + return LOS_NOK; + } + + prio = prio & (UINT8)GIC_INTR_PRIO_MASK; + + if (vector >= GIC_MIN_SPI_NUM) { + GicdSetPmr(vector, prio); + } else { + GicrSetPmr(vector, prio); + } + + return LOS_OK; +} + +VOID HalIrqInitPercpu(VOID) +{ + INT32 idx; + UINT32 cpu = ArchCurrCpuid(); + + /* GICR init */ + GicrSetWaker(cpu); + GicrSetGroup(cpu); + GicWaitForRwp(GICR_CTLR(cpu)); + + /* GICR: clear and mask sgi/ppi */ + GIC_REG_32(GICR_ICENABLER0(cpu)) = 0xffffffff; + GIC_REG_32(GICR_ICPENDR0(cpu)) = 0xffffffff; + + GIC_REG_32(GICR_ISENABLER0(cpu)) = 0xffffffff; + + for (idx = 0; idx < GIC_MIN_SPI_NUM; idx += 1) { + GicrSetPmr(idx, MIN_INTERRUPT_PRIORITY); + } + + GicWaitForRwp(GICR_CTLR(cpu)); + + /* GICC init */ + GiccInitPercpu(); +} + +VOID HalIrqInit(VOID) +{ + UINT32 i; + UINT64 affinity; + + /* disable distributor */ + GIC_REG_32(GICD_CTLR) = 0; + GicWaitForRwp(GICD_CTLR); + ISB; + + /* set externel interrupts to be level triggered, active low. */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 16) { + GIC_REG_32(GICD_ICFGR(i / 16)) = 0; + } + + /* config distributer, mask and clear all spis, set group x */ + for (i = 32; i < OS_HWI_MAX_NUM; i += 32) { + GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff; + GIC_REG_32(GICD_ICPENDR(i / 32)) = 0xffffffff; + GIC_REG_32(GICD_IGRPMODR(i / 32)) = 0; + + GicdSetGroup(i); + } + + /* set spi priority as default */ + for (i = 32; i < OS_HWI_MAX_NUM; i++) { + GicdSetPmr(i, MIN_INTERRUPT_PRIORITY); + } + + GicWaitForRwp(GICD_CTLR); + + /* disable all interrupts. */ + for (i = 0; i < OS_HWI_MAX_NUM; i += 32) { + GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff; + } + + /* enable distributor with ARE, group 1 enabled */ + GIC_REG_32(GICD_CTLR) = CTLR_ENALBE_G0 | CTLR_ENABLE_G1NS | CTLR_ARE_S; + + /* set spi to boot cpu only. ARE must be enabled */ + affinity = MpidrToAffinity(AARCH64_SYSREG_READ(mpidr_el1)); + for (i = 32; i < OS_HWI_MAX_NUM; i++) { + GIC_REG_64(GICD_IROUTER(i)) = affinity; + } + + HalIrqInitPercpu(); +} + +VOID HalIrqHandler(VOID) +{ + UINT32 iar = GiccGetIar(); + UINT32 vector = iar & 0x3FFU; + + /* + * invalid irq number, mainly the spurious interrupts 0x3ff, + * valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM to do + * the checking. + */ + if (vector >= OS_HWI_MAX_NUM) { + return; + } + g_curIrqNum = vector; + + OsInterrupt(vector); + GiccSetEoir(vector); +} + +CHAR *HalIrqVersion(VOID) +{ + UINT32 pidr = GIC_REG_32(GICD_PIDR2V3); + CHAR *irqVerString = NULL; + + switch (pidr >> GIC_REV_OFFSET) { + case GICV3: + irqVerString = "GICv3"; + break; + case GICV4: + irqVerString = "GICv4"; + break; + default: + irqVerString = "unknown"; + } + return irqVerString; +} + +UINT32 HalIrqCreate(UINT32 irq, UINT8 priority) +{ + (VOID)irq; + (VOID)priority; + return LOS_OK; +} +UINT32 HalIrqDelete(UINT32 irq) +{ + (VOID)irq; + return LOS_OK; +} +#endif diff --git a/targets/bsp/hw/arm/timer/arm_generic/arm_generic_timer.c b/targets/bsp/hw/arm/timer/arm_generic/arm_generic_timer.c new file mode 100644 index 000000000..722a27613 --- /dev/null +++ b/targets/bsp/hw/arm/timer/arm_generic/arm_generic_timer.c @@ -0,0 +1,207 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: ARM generic timer. + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "los_hw_pri.h" +#include "los_tick_pri.h" +#include "los_sys_pri.h" +#include "gic_common.h" + +#define STRING_COMB(x, y, z) x ## y ## z + +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE +#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTPS, reg) +#else +#define TIMER_REG(reg) STRING_COMB(TIMER_REG_, CNTP, reg) +#endif +#define TIMER_REG_CTL TIMER_REG(_CTL) /* 32 bits */ +#define TIMER_REG_TVAL TIMER_REG(_TVAL) /* 32 bits */ +#define TIMER_REG_CVAL TIMER_REG(_CVAL) /* 64 bits */ +#define TIMER_REG_CT TIMER_REG(CT) /* 64 bits */ + +#ifdef __LP64__ + +#define TIMER_REG_CNTFRQ cntfrq_el0 + +/* CNTP AArch64 registers */ +#define TIMER_REG_CNTP_CTL cntp_ctl_el0 +#define TIMER_REG_CNTP_TVAL cntp_tval_el0 +#define TIMER_REG_CNTP_CVAL cntp_cval_el0 +#define TIMER_REG_CNTPCT cntpct_el0 + +/* CNTPS AArch64 registers */ +#define TIMER_REG_CNTPS_CTL cntps_ctl_el1 +#define TIMER_REG_CNTPS_TVAL cntps_tval_el1 +#define TIMER_REG_CNTPS_CVAL cntps_cval_el1 +#define TIMER_REG_CNTPSCT cntpct_el0 + +#define READ_TIMER_REG32(reg) AARCH64_SYSREG_READ(reg) +#define READ_TIMER_REG64(reg) AARCH64_SYSREG_READ(reg) +#define WRITE_TIMER_REG32(reg, val) AARCH64_SYSREG_WRITE(reg, (UINT64)(val)) +#define WRITE_TIMER_REG64(reg, val) AARCH64_SYSREG_WRITE(reg, val) + +#else /* Aarch32 */ + +#define TIMER_REG_CNTFRQ CP15_REG(c14, 0, c0, 0) + +/* CNTP AArch32 registers */ +#define TIMER_REG_CNTP_CTL CP15_REG(c14, 0, c2, 1) +#define TIMER_REG_CNTP_TVAL CP15_REG(c14, 0, c2, 0) +#define TIMER_REG_CNTP_CVAL CP15_REG64(c14, 2) +#define TIMER_REG_CNTPCT CP15_REG64(c14, 0) + +/* CNTPS AArch32 registers are banked and accessed though CNTP */ +#define CNTPS CNTP + +#define READ_TIMER_REG32(reg) ARM_SYSREG_READ(reg) +#define READ_TIMER_REG64(reg) ARM_SYSREG64_READ(reg) +#define WRITE_TIMER_REG32(reg, val) ARM_SYSREG_WRITE(reg, val) +#define WRITE_TIMER_REG64(reg, val) ARM_SYSREG64_WRITE(reg, val) + +#endif + +#define OS_CYCLE_PER_TICK (g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +UINT32 HalClockFreqRead(VOID) +{ + return READ_TIMER_REG32(TIMER_REG_CNTFRQ); +} + +VOID HalClockFreqWrite(UINT32 freq) +{ + WRITE_TIMER_REG32(TIMER_REG_CNTFRQ, freq); +} + +STATIC_INLINE UINT32 TimerCtlRead(VOID) +{ + return READ_TIMER_REG32(TIMER_REG_CTL); +} + +STATIC_INLINE VOID TimerCtlWrite(UINT32 cntpCtl) +{ + WRITE_TIMER_REG32(TIMER_REG_CTL, cntpCtl); +} + +STATIC_INLINE UINT64 TimerCvalRead(VOID) +{ + return READ_TIMER_REG64(TIMER_REG_CVAL); +} + +STATIC_INLINE VOID TimerCvalWrite(UINT64 cval) +{ + WRITE_TIMER_REG64(TIMER_REG_CVAL, cval); +} + +STATIC_INLINE VOID TimerTvalWrite(UINT32 tval) +{ + WRITE_TIMER_REG32(TIMER_REG_TVAL, tval); +} + +UINT64 HalClockGetCycles(VOID) +{ + UINT64 cntpct; + + cntpct = READ_TIMER_REG64(TIMER_REG_CT); + return cntpct; +} + +LITE_OS_SEC_TEXT VOID OsTickEntry(VOID) +{ + TimerCtlWrite(0); + + OsTickHandler(); + + /* + * use last cval to generate the next tick's timing is + * absolute and accurate. DO NOT use tval to drive the + * generic time in which case tick will be slower. + */ + TimerCvalWrite(TimerCvalRead() + OS_CYCLE_PER_TICK); + SchedClockTimerCtlWrite(1); +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockInit(VOID) +{ + UINT32 ret; + + g_sysClock = HalClockFreqRead(); + ret = LOS_HwiCreate(OS_TICK_INT_NUM, MIN_INTERRUPT_PRIORITY, 0, OsTickEntry, 0); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret); + } +} + +LITE_OS_SEC_TEXT_INIT VOID HalClockStart(VOID) +{ + HalIrqUnmask(OS_TICK_INT_NUM); + + /* triggle the first tick */ + TimerCtlWrite(0); + TimerTvalWrite(OS_CYCLE_PER_TICK); + TimerCtlWrite(1); +} + +VOID HalDelayUs(UINT32 usecs) +{ + UINT64 cycles = (UINT64)usecs * HalClockFreqRead() / OS_SYS_US_PER_SECOND; + UINT64 deadline = HalClockGetCycles() + cycles; + + while (HalClockGetCycles() < deadline) { + __asm__ volatile ("nop"); + } +} + +UINT64 HalSchedClock(VOID) +{ + return LOS_CurrNanosec(); +} + +UINT32 HalClockGetTickTimerCycles(VOID) +{ + UINT64 cval = TimerCvalRead(); + UINT64 cycles = HalClockGetCycles(); + + return (UINT32)((cval > cycles) ? (cval - cycles) : 0); +} + +VOID HalClockTickTimerReload(UINT32 cycles) +{ + HalIrqMask(OS_TICK_INT_NUM); + HalIrqClear(OS_TICK_INT_NUM); + + TimerCtlWrite(0); + TimerCvalWrite(HalClockGetCycles() + cycles); + TimerCtlWrite(1); + + HalIrqUnmask(OS_TICK_INT_NUM); +} diff --git a/targets/bsp/hw/arm/timer/arm_private/arm_private_timer.c b/targets/bsp/hw/arm/timer/arm_private/arm_private_timer.c new file mode 100644 index 000000000..abf1ba0d9 --- /dev/null +++ b/targets/bsp/hw/arm/timer/arm_private/arm_private_timer.c @@ -0,0 +1,138 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: ARM private timer. + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#include "asm/platform.h" +#include "los_hwi.h" +#include "los_tick_pri.h" + +#define OS_CYCLE_PER_TICK (TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND) + +typedef struct { + UINT32 load; /* Private Timer Load Register */ + UINT32 count; /* Private Timer Counter Register */ + UINT32 control; /* Private Timer Control Register */ + UINT32 intStatus; /* Private Timer Interrupt Status Register */ +} PrivateTimer; + +typedef struct { + UINT32 low; /* Global Timer Counter Registers, low bits */ + UINT32 high; /* Global Timer Counter Registers, high bits */ + UINT32 control; /* Global Timer Control Register */ + UINT32 intStatus; /* Global Timer Interrupt Status Register */ + UINT32 compareLow; /* Comparator Value Registers, low bits */ + UINT32 compareHigh; /* Comparator Value Registers, high bits */ + UINT32 increment; /* Auto-increment Register */ +} GlobalTimer; + +PrivateTimer *g_privateTimer = (PrivateTimer *)PRVTIMER_BASE_ADDR; +GlobalTimer *g_globalTimer = (GlobalTimer *)GTIMER_BASE_ADDR; + +UINT32 HalClockFreqRead(VOID) +{ + return TIMER_FREQ; +} + +VOID HalClockFreqWrite(UINT32 freq) +{ + PRINT_WARN("private timer does not support setting frequency\n"); +} + +VOID HalClockStart(VOID) +{ + HalIrqUnmask(PRVTIMER_INT_NUM); + + g_privateTimer->load = OS_CYCLE_PER_TICK; + g_privateTimer->control = 0x06; /* IAE bits = 110, not eanbled yet */ + g_privateTimer->control |= 0x01; /* enable private timer */ +} + +VOID OsTickEntry(VOID) +{ + OsTickHandler(); + + /* clear private timer */ + g_privateTimer->intStatus = 0x01; +} + +VOID HalClockInit(VOID) +{ + UINT32 ret; + + ret = LOS_HwiCreate(PRVTIMER_INT_NUM, 0xa0, 0, OsTickEntry, NULL); + if (ret != LOS_OK) { + PRINT_ERR("%s, %d create tick irq failed, ret:0x%x\n", __FUNCTION__, __LINE__, ret); + } +} + +UINT64 HalClockGetCycles(VOID) +{ + UINT32 low, high; + + do { + high = g_globalTimer->high; + low = g_globalTimer->low; + } while (g_globalTimer->high != high); + + /* combine high and low into 8 bytes cycles */ + return (((UINT64)high << 32) | low); +} + +VOID HalDelayUs(UINT32 usecs) +{ + UINT64 tmo = LOS_CurrNanosec() + usecs * 1000; + + while (LOS_CurrNanosec() < tmo) { + __asm__ volatile ("nop"); + } +} + +UINT64 HalSchedClock(VOID) +{ + return LOS_CurrNanosec(); +} + +UINT32 HalClockGetTickTimerCycles(VOID) +{ + return g_privateTimer->count; +} + +VOID HalClockTickTimerReload(UINT32 period) +{ + HalIrqUnmask(PRVTIMER_INT_NUM); + + /* set control counter regs to defaults */ + g_privateTimer->load = period; + g_privateTimer->control = 0x06; /* IAE bits = 110, not eanbled yet */ + g_privateTimer->control |= 0x01; /* reenable private timer */ +} diff --git a/targets/bsp/hw/include/gic_common.h b/targets/bsp/hw/include/gic_common.h new file mode 100644 index 000000000..0341199a5 --- /dev/null +++ b/targets/bsp/hw/include/gic_common.h @@ -0,0 +1,126 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: General interrupt controller version 3.0 (GICv3). + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _GIC_COMMON_H +#define _GIC_COMMON_H + +#include "stdint.h" +#include "asm/platform.h" +#include "los_config.h" + +/* gic arch revision */ +enum { + GICV1 = 1, + GICV2, + GICV3, + GICV4 +}; + +#define GIC_REV_MASK 0xF0 +#define GIC_REV_OFFSET 0x4 + +#ifdef LOSCFG_PLATFORM_BSP_GIC_V2 +#define GICC_CTLR (GICC_OFFSET + 0x00) /* CPU Interface Control Register */ +#define GICC_PMR (GICC_OFFSET + 0x04) /* Interrupt Priority Mask Register */ +#define GICC_BPR (GICC_OFFSET + 0x08) /* Binary Point Register */ +#define GICC_IAR (GICC_OFFSET + 0x0c) /* Interrupt Acknowledge Register */ +#define GICC_EOIR (GICC_OFFSET + 0x10) /* End of Interrupt Register */ +#define GICC_RPR (GICC_OFFSET + 0x14) /* Running Priority Register */ +#define GICC_HPPIR (GICC_OFFSET + 0x18) /* Highest Priority Pending Interrupt Register */ +#endif + +#define GICD_CTLR (GICD_OFFSET + 0x000) /* Distributor Control Register*/ +#define GICD_TYPER (GICD_OFFSET + 0x004) /* Interrupt Controller Type Register */ +#define GICD_IIDR (GICD_OFFSET + 0x008) /* Distributor Implementer Identification Register */ +#define GICD_IGROUPR(n) (GICD_OFFSET + 0x080 + (n) * 4) /* Interrupt Group Registers */ +#define GICD_ISENABLER(n) (GICD_OFFSET + 0x100 + (n) * 4) /* Interrupt Set-Enable Registers */ +#define GICD_ICENABLER(n) (GICD_OFFSET + 0x180 + (n) * 4) /* Interrupt Clear-Enable Registers */ +#define GICD_ISPENDR(n) (GICD_OFFSET + 0x200 + (n) * 4) /* Interrupt Set-Pending Registers */ +#define GICD_ICPENDR(n) (GICD_OFFSET + 0x280 + (n) * 4) /* Interrupt Clear-Pending Registers */ +#define GICD_ISACTIVER(n) (GICD_OFFSET + 0x300 + (n) * 4) /* GICv2 Interrupt Set-Active Registers */ +#define GICD_ICACTIVER(n) (GICD_OFFSET + 0x380 + (n) * 4) /* Interrupt Clear-Active Registers */ +#define GICD_IPRIORITYR(n) (GICD_OFFSET + 0x400 + (n) * 4) /* Interrupt Priority Registers */ +#define GICD_ITARGETSR(n) (GICD_OFFSET + 0x800 + (n) * 4) /* Interrupt Processor Targets Registers */ +#define GICD_ICFGR(n) (GICD_OFFSET + 0xc00 + (n) * 4) /* Interrupt Configuration Registers */ +#define GICD_SGIR (GICD_OFFSET + 0xf00) /* Software Generated Interrupt Register */ +#define GICD_CPENDSGIR(n) (GICD_OFFSET + 0xf10 + (n) * 4) /* SGI Clear-Pending Registers; NOT available on cortex-a9*/ +#define GICD_SPENDSGIR(n) (GICD_OFFSET + 0xf20 + (n) * 4) /* SGI Set-Pending Registers; NOT available on cortex-a9*/ +#define GICD_PIDR2V2 (GICD_OFFSET + 0xfe8) +#define GICD_PIDR2V3 (GICD_OFFSET + 0xffe8) + +#ifdef LOSCFG_PLATFORM_BSP_GIC_V3 +#define GICD_IGRPMODR(n) (GICD_OFFSET + 0x0d00 + (n) * 4)/* Interrupt Group Mode Reisters */ +#define GICD_IROUTER(n) (GICD_OFFSET + 0x6000 + (n) * 8)/* Interrupt Rounter Reisters */ +#endif + +#define GIC_REG_8(reg) (*(volatile UINT8 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) +#define GIC_REG_32(reg) (*(volatile UINT32 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) +#define GIC_REG_64(reg) (*(volatile UINT64 *)((UINTPTR)(GIC_BASE_ADDR + (reg)))) + +#define GICD_INT_DEF_PRI 0xa0U +#define GICD_INT_DEF_PRI_X4 (((UINT32)GICD_INT_DEF_PRI << 24) | \ + ((UINT32)GICD_INT_DEF_PRI << 16) | \ + ((UINT32)GICD_INT_DEF_PRI << 8) | \ + (UINT32)GICD_INT_DEF_PRI) + +#define GIC_MIN_SPI_NUM 32 + +/* Interrupt preemption config */ +#define GIC_PRIORITY_MASK 0xFFU +#define GIC_PRIORITY_OFFSET 8 + +/* + * The number of bits to shift for an interrupt priority is dependent + * on the number of bits implemented by the interrupt controller. + * If the MAX_BINARY_POINT_VALUE is 7, + * it means that interrupt preemption is not supported. + */ +#ifndef LOSCFG_ARCH_INTERRUPT_PREEMPTION +#define MAX_BINARY_POINT_VALUE 7 +#define PRIORITY_SHIFT 0 +#define GIC_MAX_INTERRUPT_PREEMPTION_LEVEL 0U +#else +#define PRIORITY_SHIFT ((MAX_BINARY_POINT_VALUE + 1) % GIC_PRIORITY_OFFSET) +#define GIC_MAX_INTERRUPT_PREEMPTION_LEVEL ((UINT8)((GIC_PRIORITY_MASK + 1) >> PRIORITY_SHIFT)) +#endif + +#define GIC_INTR_PRIO_MASK ((UINT8)(0xFFFFFFFFU << PRIORITY_SHIFT)) + +/* + * The preemption level is up to 128, and the maximum value corresponding to the interrupt priority is 254 [7:1]. + * If the GIC_MAX_INTERRUPT_PREEMPTION_LEVEL is 0, the minimum priority is 0xff. + */ +#define MIN_INTERRUPT_PRIORITY ((UINT8)((GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 1) << PRIORITY_SHIFT)) + +#endif diff --git a/targets/bsp/hw/include/gic_v3.h b/targets/bsp/hw/include/gic_v3.h new file mode 100644 index 000000000..e8adab37d --- /dev/null +++ b/targets/bsp/hw/include/gic_v3.h @@ -0,0 +1,206 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: General interrupt controller version 3.0 (GICv3). + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _GIC_V3_H_ +#define _GIC_V3_H_ + +#include "stdint.h" +#include "asm/platform.h" +#include "los_hw_cpu.h" + +#define BIT_32(bit) (1u << bit) +#define BIT_64(bit) (1ul << bit) + +#define ICC_CTLR_EL1 "S3_0_C12_C12_4" +#define ICC_PMR_EL1 "S3_0_C4_C6_0" +#define ICC_IAR1_EL1 "S3_0_C12_C12_0" +#define ICC_SRE_EL1 "S3_0_C12_C12_5" +#define ICC_BPR0_EL1 "S3_0_C12_C8_3" +#define ICC_BPR1_EL1 "S3_0_C12_C12_3" +#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" +#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" +#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" +#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" +#define ICC_EOIR0_EL1 "S3_0_c12_c8_1" +#define ICC_IAR0_EL1 "S3_0_C12_C8_0" + +#define ICC_CTLR_EL3 "S3_6_C12_C12_4" +#define ICC_SRE_EL3 "S3_6_C12_C12_5" +#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" + +/* GICD_CTLR bit definitions */ +#define CTLR_ENALBE_G0 BIT_32(0) +#define CTLR_ENABLE_G1NS BIT_32(1) +#define CTLR_ENABLE_G1S BIT_32(2) +#define CTLR_RES0 BIT_32(3) +#define CTLR_ARE_S BIT_32(4) +#define CTLR_ARE_NS BIT_32(5) +#define CTLR_DS BIT_32(6) +#define CTLR_E1NWF BIT_32(7) +#define GICD_CTLR_RWP BIT_32(31) + +/* peripheral identification registers */ +#define GICD_CIDR0 (GICD_OFFSET + 0xfff0) +#define GICD_CIDR1 (GICD_OFFSET + 0xfff4) +#define GICD_CIDR2 (GICD_OFFSET + 0xfff8) +#define GICD_CIDR3 (GICD_OFFSET + 0xfffc) +#define GICD_PIDR0 (GICD_OFFSET + 0xffe0) +#define GICD_PIDR1 (GICD_OFFSET + 0xffe4) +#define GICD_PIDR2 (GICD_OFFSET + 0xffe8) +#define GICD_PIDR3 (GICD_OFFSET + 0xffec) + +/* GICD_PIDR bit definitions and masks */ +#define GICD_PIDR2_ARCHREV_SHIFT 4 +#define GICD_PIDR2_ARCHREV_MASK 0xf + +/* redistributor registers */ +#define GICR_SGI_OFFSET (GICR_OFFSET + 0x10000) + +#define GICR_CTLR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0000) +#define GICR_IIDR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0004) +#define GICR_TYPER(i, n) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0008 + (n)*4) +#define GICR_STATUSR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0010) +#define GICR_WAKER(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0014) +#define GICR_IGROUPR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0080) +#define GICR_IGRPMOD0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0d00) +#define GICR_ISENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0100) +#define GICR_ICENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0180) +#define GICR_ISPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0200) +#define GICR_ICPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0280) +#define GICR_ISACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0300) +#define GICR_ICACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0380) +#define GICR_IPRIORITYR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0400) +#define GICR_ICFGR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c00) +#define GICR_ICFGR1(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c04) +#define GICR_NSACR(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0e00) + +#define GICR_WAKER_PROCESSORSLEEP_LEN 1U +#define GICR_WAKER_PROCESSORSLEEP_OFFSET 1 +#define GICR_WAKER_CHILDRENASLEEP_LEN 1U +#define GICR_WAKER_CHILDRENASLEEP_OFFSET 2 +#define GICR_WAKER_PROCESSORSLEEP (GICR_WAKER_PROCESSORSLEEP_LEN << GICR_WAKER_PROCESSORSLEEP_OFFSET) +#define GICR_WAKER_CHILDRENASLEEP (GICR_WAKER_CHILDRENASLEEP_LEN << GICR_WAKER_CHILDRENASLEEP_OFFSET) + +STATIC INLINE VOID GiccSetCtlr(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_CTLR_EL3 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_CTLR_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE VOID GiccSetPmr(UINT32 val) +{ + __asm__ volatile("msr " ICC_PMR_EL1 ", %0" ::"r"(val)); + ISB; + DSB; +} + +STATIC INLINE VOID GiccSetIgrpen0(UINT32 val) +{ + __asm__ volatile("msr " ICC_IGRPEN0_EL1 ", %0" ::"r"(val)); + ISB; +} + +STATIC INLINE VOID GiccSetIgrpen1(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_IGRPEN1_EL3 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_IGRPEN1_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE UINT32 GiccGetSre(VOID) +{ + UINT32 temp; +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("mrs %0, " ICC_SRE_EL3 : "=r"(temp)); +#else + __asm__ volatile("mrs %0, " ICC_SRE_EL1 : "=r"(temp)); +#endif + return temp; +} + +STATIC INLINE VOID GiccSetSre(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_SRE_EL3 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_SRE_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE VOID GiccSetEoir(UINT32 val) +{ +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("msr " ICC_EOIR0_EL1 ", %0" ::"r"(val)); +#else + __asm__ volatile("msr " ICC_EOIR1_EL1 ", %0" ::"r"(val)); +#endif + ISB; +} + +STATIC INLINE UINT32 GiccGetIar(VOID) +{ + UINT32 temp; + +#ifdef LOSCFG_ARCH_SECURE_MONITOR_MODE + __asm__ volatile("mrs %0, " ICC_IAR0_EL1 : "=r"(temp)); +#else + __asm__ volatile("mrs %0, " ICC_IAR1_EL1 : "=r"(temp)); +#endif + DSB; + + return temp; +} + +STATIC INLINE VOID GiccSetSgi1r(UINT64 val) +{ + __asm__ volatile("msr " ICC_SGI1R_EL1 ", %0" ::"r"(val)); + ISB; + DSB; +} + +STATIC INLINE VOID GiccSetBpr0(UINT32 val) +{ + __asm__ volatile("msr " ICC_BPR0_EL1 ", %0" ::"r"(val)); + ISB; + DSB; +} +#endif diff --git a/targets/bsp/include/hal_hwi.h b/targets/bsp/include/hal_hwi.h new file mode 100644 index 000000000..e9f0221cc --- /dev/null +++ b/targets/bsp/include/hal_hwi.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Hwi Implementation HeadFile + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _HWI_H +#define _HWI_H + +#include "los_typedef.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_PLATFORM_HWI == YES) +extern VOID HalIrqInit(VOID); +extern VOID HalIrqInitPercpu(VOID); +extern VOID HalIrqMask(UINT32 vector); +extern VOID HalIrqUnmask(UINT32 vector); +extern VOID HalIrqPending(UINT32 vector); +extern VOID HalIrqClear(UINT32 vector); +extern CHAR *HalIrqVersion(VOID); +extern UINT32 HalCurIrqGet(VOID); +extern UINT32 HalIrqSetPrio(UINT32 vector, UINT8 priority); +extern UINT32 HalIrqCreate(UINT32 irq, UINT8 priority); +extern UINT32 HalIrqDelete(UINT32 irq); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _HWI_H */ diff --git a/targets/bsp/include/hal_timer.h b/targets/bsp/include/hal_timer.h new file mode 100644 index 000000000..f1f604325 --- /dev/null +++ b/targets/bsp/include/hal_timer.h @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: LiteOS Timer Header File + * 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. + * --------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Notice of Export Control Law + * =============================================== + * Huawei LiteOS may be subject to applicable export control laws and regulations, which might + * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. + * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such + * applicable export control laws and regulations. + * --------------------------------------------------------------------------- */ + +#ifndef _LOS_TIMER_H +#define _LOS_TIMER_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +extern UINT32 HalClockFreqRead(VOID); +extern VOID HalClockFreqWrite(UINT32 freq); +extern VOID HalClockStart(VOID); +extern VOID HalClockIrqClear(VOID); +extern VOID HalClockInit(VOID); +extern UINT64 HalClockGetCycles(VOID); +extern VOID HalDelayUs(UINT32 usecs); +extern UINT64 HalSchedClock(VOID); +extern UINT32 HalClockGetTickTimerCycles(VOID); +extern VOID HalClockTickTimerReload(UINT32 cycles); + +extern UINT32 HrtimersInit(VOID); +extern VOID HrtimerClockIrqClear(VOID); +extern VOID HrtimerClockStart(UINT32 period); +extern VOID HrtimerClockStop(VOID); +extern UINT32 HrtimerClockValueGet(VOID); +extern VOID HrtimerClockInit(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_TIMER_H */