From 25b432927cde295555243e23e1a8e755dd47075e Mon Sep 17 00:00:00 2001 From: huangjieliang Date: Fri, 29 Jan 2021 11:02:40 +0800 Subject: [PATCH] Description: Sync liteos_m to OpenHarmony. Reviewed-by: likailong --- components/cpup/los_cpup.c | 4 +- components/exchook/los_exc_info.c | 308 ++++ components/exchook/los_exc_info.h | 116 ++ components/exchook/los_exchook.c | 135 ++ components/exchook/los_exchook.h | 105 ++ components/fs/fatfs/fatfs.c | 1351 +++++++++++++++++ components/fs/fatfs/fatfs.h | 80 + kal/cmsis/cmsis_liteos2.c | 306 +++- kal/kal.c | 3 +- kal/kal.h | 3 +- kal/posix/include/libc.h | 92 +- kal/posix/src/time.c | 312 +++- .../arm/cortex-m3/keil/los_arch_interrupt.h | 42 +- kernel/arch/arm/cortex-m3/keil/los_context.c | 8 +- .../arch/arm/cortex-m3/keil/los_interrupt.c | 60 +- kernel/arch/arm/cortex-m3/keil/los_timer.c | 52 +- .../arm/cortex-m4/iar/los_arch_interrupt.h | 42 +- kernel/arch/arm/cortex-m4/iar/los_context.c | 69 +- kernel/arch/arm/cortex-m4/iar/los_dispatch.S | 4 +- kernel/arch/arm/cortex-m4/iar/los_interrupt.c | 63 +- kernel/arch/arm/cortex-m4/iar/los_mpu.c | 207 +++ kernel/arch/arm/cortex-m4/iar/los_timer.c | 52 +- .../arm/cortex-m7/gcc/los_arch_interrupt.h | 42 +- kernel/arch/arm/cortex-m7/gcc/los_interrupt.c | 54 +- kernel/arch/arm/cortex-m7/gcc/los_timer.c | 52 +- .../arch/arm/cortex-m7/iar/los_arch_atomic.h | 161 ++ .../arch/arm/cortex-m7/iar/los_arch_context.h | 131 ++ .../arm/cortex-m7/iar/los_arch_interrupt.h | 746 +++++++++ .../arch/arm/cortex-m7/iar/los_arch_timer.h | 54 + kernel/arch/arm/cortex-m7/iar/los_context.c | 243 +++ kernel/arch/arm/cortex-m7/iar/los_dispatch.S | 179 +++ kernel/arch/arm/cortex-m7/iar/los_exc.S | 285 ++++ kernel/arch/arm/cortex-m7/iar/los_interrupt.c | 384 +++++ kernel/arch/arm/cortex-m7/iar/los_mpu.c | 207 +++ kernel/arch/arm/cortex-m7/iar/los_timer.c | 258 ++++ kernel/arch/include/los_arch.h | 5 + kernel/arch/include/los_interrupt.h | 13 - kernel/arch/include/los_mpu.h | 93 ++ kernel/arch/include/los_timer.h | 40 +- kernel/arch/risc-v/los_arch_interrupt.h | 11 - kernel/arch/risc-v/los_exc.S | 24 +- kernel/arch/risc-v/los_interrupt.c | 29 +- kernel/arch/risc-v/los_timer.c | 33 +- kernel/include/los_config.h | 86 +- kernel/include/los_membox.h | 154 +- kernel/include/los_memory.h | 94 +- kernel/include/los_swtmr.h | 26 +- kernel/include/los_task.h | 43 +- kernel/src/los_init.c | 22 +- kernel/src/los_queue.c | 11 - kernel/src/los_sem.c | 2 - kernel/src/los_swtmr.c | 18 +- kernel/src/los_task.c | 109 +- kernel/src/los_tick.c | 2 +- kernel/src/mm/los_membox.c | 391 +++-- kernel/src/mm/los_memory.c | 882 +++++++++-- .../cortex-m3_stm32f103_simulator_keil/main.c | 2 +- .../target_config.h | 16 +- .../dprintf.c | 2 +- .../main.c | 7 +- .../project/los_demo.ewp | 6 + .../target_config.h | 14 +- .../target_config.h | 2 +- utils/los_compiler.h | 10 + utils/los_debug.c | 98 ++ utils/los_debug.h | 149 +- 66 files changed, 7645 insertions(+), 959 deletions(-) mode change 100644 => 100755 components/cpup/los_cpup.c create mode 100644 components/exchook/los_exc_info.c create mode 100644 components/exchook/los_exc_info.h create mode 100644 components/exchook/los_exchook.c create mode 100644 components/exchook/los_exchook.h create mode 100644 components/fs/fatfs/fatfs.c create mode 100644 components/fs/fatfs/fatfs.h mode change 100644 => 100755 kal/cmsis/cmsis_liteos2.c mode change 100644 => 100755 kal/kal.c mode change 100644 => 100755 kal/kal.h mode change 100644 => 100755 kal/posix/include/libc.h mode change 100644 => 100755 kal/posix/src/time.c mode change 100644 => 100755 kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h mode change 100644 => 100755 kernel/arch/arm/cortex-m3/keil/los_context.c mode change 100644 => 100755 kernel/arch/arm/cortex-m3/keil/los_interrupt.c mode change 100644 => 100755 kernel/arch/arm/cortex-m3/keil/los_timer.c mode change 100644 => 100755 kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h mode change 100644 => 100755 kernel/arch/arm/cortex-m4/iar/los_context.c mode change 100644 => 100755 kernel/arch/arm/cortex-m4/iar/los_dispatch.S mode change 100644 => 100755 kernel/arch/arm/cortex-m4/iar/los_interrupt.c create mode 100644 kernel/arch/arm/cortex-m4/iar/los_mpu.c mode change 100644 => 100755 kernel/arch/arm/cortex-m4/iar/los_timer.c mode change 100644 => 100755 kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h mode change 100644 => 100755 kernel/arch/arm/cortex-m7/gcc/los_interrupt.c mode change 100644 => 100755 kernel/arch/arm/cortex-m7/gcc/los_timer.c create mode 100644 kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h create mode 100644 kernel/arch/arm/cortex-m7/iar/los_arch_context.h create mode 100644 kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h create mode 100644 kernel/arch/arm/cortex-m7/iar/los_arch_timer.h create mode 100644 kernel/arch/arm/cortex-m7/iar/los_context.c create mode 100644 kernel/arch/arm/cortex-m7/iar/los_dispatch.S create mode 100644 kernel/arch/arm/cortex-m7/iar/los_exc.S create mode 100644 kernel/arch/arm/cortex-m7/iar/los_interrupt.c create mode 100644 kernel/arch/arm/cortex-m7/iar/los_mpu.c create mode 100644 kernel/arch/arm/cortex-m7/iar/los_timer.c mode change 100644 => 100755 kernel/arch/include/los_arch.h mode change 100644 => 100755 kernel/arch/include/los_interrupt.h create mode 100644 kernel/arch/include/los_mpu.h mode change 100644 => 100755 kernel/arch/include/los_timer.h mode change 100644 => 100755 kernel/arch/risc-v/los_arch_interrupt.h mode change 100644 => 100755 kernel/arch/risc-v/los_interrupt.c mode change 100644 => 100755 kernel/arch/risc-v/los_timer.c mode change 100644 => 100755 kernel/include/los_config.h mode change 100644 => 100755 kernel/include/los_membox.h mode change 100644 => 100755 kernel/include/los_memory.h mode change 100644 => 100755 kernel/include/los_swtmr.h mode change 100644 => 100755 kernel/include/los_task.h mode change 100644 => 100755 kernel/src/los_init.c mode change 100644 => 100755 kernel/src/los_queue.c mode change 100644 => 100755 kernel/src/los_sem.c mode change 100644 => 100755 kernel/src/los_swtmr.c mode change 100644 => 100755 kernel/src/los_task.c mode change 100644 => 100755 kernel/src/los_tick.c mode change 100644 => 100755 kernel/src/mm/los_membox.c mode change 100644 => 100755 kernel/src/mm/los_memory.c mode change 100644 => 100755 targets/cortex-m3_stm32f103_simulator_keil/main.c mode change 100644 => 100755 targets/cortex-m3_stm32f103_simulator_keil/target_config.h mode change 100644 => 100755 targets/cortex-m4_stm32f429ig_fire-challenger_iar/dprintf.c mode change 100644 => 100755 targets/cortex-m4_stm32f429ig_fire-challenger_iar/main.c mode change 100644 => 100755 targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp mode change 100644 => 100755 targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h mode change 100644 => 100755 targets/cortex-m7_nucleo_f767zi_gcc/target_config.h mode change 100644 => 100755 utils/los_compiler.h create mode 100644 utils/los_debug.c mode change 100644 => 100755 utils/los_debug.h diff --git a/components/cpup/los_cpup.c b/components/cpup/los_cpup.c old mode 100644 new mode 100755 index 94fa4d7e..e077ebae --- a/components/cpup/los_cpup.c +++ b/components/cpup/los_cpup.c @@ -32,9 +32,8 @@ #include "los_cpup.h" #include "securec.h" #include "los_memory.h" -#include "los_timer.h" #include "los_debug.h" - +#include "los_timer.h" #ifdef __cplusplus #if __cplusplus extern "C" { @@ -62,6 +61,7 @@ LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL; LITE_OS_SEC_BSS UINT64 g_lastRecordTime; LITE_OS_SEC_BSS UINT16 g_hisPos; /* cntInfo.maxCnt; + len = sizeof(UINT32) + (sizeof(CHAR) * LOS_TASK_NAMELEN); + if (taskSwitchInfo->cntInfo.isFull) { + i = taskSwitchInfo->idx; + loop = i + taskSwitchCount; + } else { + i = 0; + loop = taskSwitchInfo->idx; + } + + return OsExcHookFunc(type, i, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_TaskSwitchInfoGet); +} +#endif + +VOID OsExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) +{ + ExcInfoArray *excInfo = NULL; + if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { + PRINT_ERR("HalExcRegister ERROR!\n"); + return; + } + excInfo = &(g_excArray[type]); + if (excInfo->valid == TRUE) { + return; + } + + excInfo->type = type; + excInfo->fnExcInfoCb = func; + excInfo->arg = arg; + excInfo->valid = TRUE; +} + +STATIC VOID OsExcMsgDump(VOID) +{ + UINT32 index; + + /* Ignore the return code when matching CSEC rule 6.6(4). */ + (VOID)memset_s(g_excMsgArray, g_excArraySize, EXC_MSG_ARRAY_INIT_VALUE, g_excArraySize); + + *((UINT32 *)g_excContent) = MAX_EXC_MEM_SIZE; /* The total length of exception information. */ + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + + for (index = 0; index < OS_EXC_TYPE_MAX; index++) { + if (!g_excArray[index].valid) { + continue; + } + g_excArray[index].fnExcInfoCb(g_excArray[index].type, g_excArray[index].arg); + } + + *((UINT32 *)g_excContent) = OS_EXC_TYPE_MAX; + g_excContent = (UINT8 *)g_excContent + sizeof(UINT32); + return; +} + +VOID OsExcMsgDumpInit(VOID) +{ + g_excQueueMaxNum = LOSCFG_BASE_IPC_QUEUE_LIMIT; + g_excMemMaxNum = OS_SYS_MEM_NUM; + g_excContent = (VOID *)g_excMsgArray; + + OsExcRegister(OS_EXC_TYPE_CONTEXT, OsExcContentGet, NULL); + OsExcRegister(OS_EXC_TYPE_TSK, OsExcTaskMsgGet, &g_taskMaxNum); +#if (LOSCFG_BASE_IPC_QUEUE == 1) + OsExcRegister(OS_EXC_TYPE_QUE, OsExcQueueMsgGet, &g_excQueueMaxNum); +#endif + OsExcRegister(OS_EXC_TYPE_NVIC, OsExcSaveIntStatus, NULL); +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) + OsExcRegister(OS_EXC_TYPE_TSK_SWITCH, OsExcTskSwitchMsgGet, &g_taskSwitchInfo); +#endif + OsExcRegister(OS_EXC_TYPE_MEM, OsExcMemMsgGet, &g_excMemMaxNum); + + (VOID)LOS_RegExcHook(EXC_INTERRUPT, (ExcHookFn)OsExcMsgDump); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + diff --git a/components/exchook/los_exc_info.h b/components/exchook/los_exc_info.h new file mode 100644 index 00000000..dc2f98da --- /dev/null +++ b/components/exchook/los_exc_info.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_config.h" +#include "los_task.h" +#include "los_queue.h" +#include "los_memory.h" +#include "los_arch_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define INFO_TYPE_AND_SIZE 8 + +#define MAX_SCENE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(ExcInfo) + sizeof(EXC_CONTEXT_S)) +#define MAX_TSK_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) + +#if (LOSCFG_BASE_IPC_QUEUE == 1) +#define MAX_QUEUE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT) +#else +#define MAX_QUEUE_INFO_SIZE (0) +#endif + +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) +#define MAX_SWITCH_INFO_SIZE (INFO_TYPE_AND_SIZE + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT) +#else +#define MAX_SWITCH_INFO_SIZE (0) +#endif + +#define MAX_MEM_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(MemInfoCB) * OS_SYS_MEM_NUM) +#define MAX_EXC_MEM_SIZE (INFO_TYPE_AND_SIZE + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE) + +typedef enum { + OS_EXC_TYPE_CONTEXT = 0, + OS_EXC_TYPE_TSK = 1, + OS_EXC_TYPE_QUE = 2, + OS_EXC_TYPE_NVIC = 3, + OS_EXC_TYPE_TSK_SWITCH = 4, + OS_EXC_TYPE_MEM = 5, + OS_EXC_TYPE_MAX = 6 +} ExcInfoType; + +typedef struct { + ExcInfoType flag; + UINT32 length; + ExcInfo info; + EXC_CONTEXT_S context; +} ExcContextInfoArray; + +typedef struct { + ExcInfoType flag; + UINT32 length; + TSK_INFO_S taskInfo[LOSCFG_BASE_CORE_TSK_LIMIT + 1]; +} ExcTaskInfoArray; + +typedef struct { + ExcInfoType flag; + UINT32 length; + QUEUE_INFO_S queueInfo[LOSCFG_BASE_CORE_TSK_LIMIT]; +} ExcQueueInfoArray; + +typedef struct { + UINT32 totalLen; + ExcContextInfoArray excInfo; + ExcTaskInfoArray taskInfo; + ExcQueueInfoArray queueInfo; +} ExcMsgArray; + +typedef UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID *); + +typedef struct { + ExcInfoType type; + UINT32 valid; + EXC_INFO_SAVE_CALLBACK fnExcInfoCb; + VOID *arg; +} ExcInfoArray; + +VOID OsExcMsgDumpInit(VOID); +extern UINT8 g_excMsgArray[MAX_EXC_MEM_SIZE]; + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/components/exchook/los_exchook.c b/components/exchook/los_exchook.c new file mode 100644 index 00000000..7583f53c --- /dev/null +++ b/components/exchook/los_exchook.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_exchook.h" +#include "los_context.h" + +#ifndef LOSCFG_BASE_EXC_HOOK_LIMIT +#define LOSCFG_BASE_EXC_HOOK_LIMIT 16 +#endif + +struct Node { + ExcHookFn excHookFn; + struct Node *next; +}; + +STATIC struct Node g_excNodes[LOSCFG_BASE_EXC_HOOK_LIMIT]; +STATIC struct Node *g_excHeads[EXC_TYPE_END + 1]; /* EXC_TYPE_END is used for the free list. */ + +STATIC VOID DoExcHookInRegOrder(EXC_TYPE excType, struct Node *node) +{ + if (node != NULL) { + DoExcHookInRegOrder(excType, node->next); + node->excHookFn(excType); + } +} + +STATIC VOID DoExcHook(EXC_TYPE excType) +{ + UINTPTR intSave; + if (excType >= EXC_TYPE_END) { + return; + } + intSave = LOS_IntLock(); + DoExcHookInRegOrder(excType, g_excHeads[excType]); + LOS_IntRestore(intSave); +} + +STATIC struct Node *GetFreeNode(VOID) +{ + struct Node *node = NULL; + if (g_excHeads[EXC_TYPE_END] == NULL) { + if (g_excNodes[0].excHookFn != NULL) { + /* no free node now */ + return NULL; + } else { + /* Initialize the free list */ + for (int i = 0; i < LOSCFG_BASE_EXC_HOOK_LIMIT; ++i) { + g_excNodes[i].next = g_excHeads[EXC_TYPE_END]; + g_excHeads[EXC_TYPE_END] = &g_excNodes[i]; + } + OsExcHookRegister(DoExcHook); + } + } + + node = g_excHeads[EXC_TYPE_END]; + g_excHeads[EXC_TYPE_END] = node->next; + return node; +} + +UINT32 LOS_RegExcHook(EXC_TYPE excType, ExcHookFn excHookFn) +{ + UINTPTR intSave; + struct Node *node = NULL; + if (excType >= EXC_TYPE_END || excHookFn == NULL) { + return LOS_ERRNO_SYS_PTR_NULL; + } + + intSave = LOS_IntLock(); + node = GetFreeNode(); + if (node == NULL) { + LOS_IntRestore(intSave); + return LOS_ERRNO_SYS_HOOK_IS_FULL; + } + + node->excHookFn = excHookFn; + node->next = g_excHeads[excType]; + g_excHeads[excType] = node; + LOS_IntRestore(intSave); + return LOS_OK; +} + +UINT32 LOS_UnRegExcHook(EXC_TYPE excType, ExcHookFn excHookFn) +{ + UINTPTR intSave; + struct Node *node = NULL; + struct Node *preNode = NULL; + if (excType >= EXC_TYPE_END || excHookFn == NULL) { + return LOS_ERRNO_SYS_PTR_NULL; + } + + intSave = LOS_IntLock(); + for (node = g_excHeads[excType]; node != NULL; node = node->next) { + if (node->excHookFn == excHookFn) { + if (preNode) { + preNode->next = node->next; + } else { + g_excHeads[excType] = node->next; + } + node->excHookFn = NULL; + node->next = g_excHeads[EXC_TYPE_END]; + g_excHeads[EXC_TYPE_END] = node; + } + preNode = node; + } + LOS_IntRestore(intSave); + return LOS_OK; +} diff --git a/components/exchook/los_exchook.h b/components/exchook/los_exchook.h new file mode 100644 index 00000000..8bc5760a --- /dev/null +++ b/components/exchook/los_exchook.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup los_exchook Exception hooks + * @ingroup kernel + */ + +#ifndef _LOS_EXCHOOK_H +#define _LOS_EXCHOOK_H + +#include "los_tick.h" +#include "los_debug.h" +#include "los_arch_interrupt.h" +#include "los_interrupt.h" +#include "los_task.h" +#include "los_queue.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @ingroup los_exchook + * @brief: System exception hooks register function. + * + * @par Description: + * This API is used to register exception hooks. + * Hooks will be invoked in reverse order. + * + * @attention: + * + * + * @param: None. + * + * @retval: LOS_OK success. + * LOS_ERRNO_SYS_HOOK_IS_FULL too many hooks registered. @see LOSCFG_BASE_EXC_HOOK_LIMIT + * LOS_ERRNO_SYS_PTR_NULL excHookFn is null or invalid excType. + * + * @par Dependency: + * + * @see None. + * + * */ +extern UINT32 LOS_RegExcHook(EXC_TYPE excType, ExcHookFn excHookFn); + +/** + * @ingroup los_exchook + * @brief: System exception hooks unregister function. + * + * @par Description: + * This API is used to unregister exception hooks. + * + * @attention: + * + * + * @param: None. + * + * @retval: LOS_OK success. + * LOS_ERRNO_SYS_PTR_NULL excHookFn is null or invalid excType. + * + * @par Dependency: + * + * @see None. + * + * */ +extern UINT32 LOS_UnRegExcHook(EXC_TYPE excType, ExcHookFn excHookFn); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_EXCHOOK_H */ diff --git a/components/fs/fatfs/fatfs.c b/components/fs/fatfs/fatfs.c new file mode 100644 index 00000000..4b7d4346 --- /dev/null +++ b/components/fs/fatfs/fatfs.c @@ -0,0 +1,1351 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_compiler.h" +#include "fcntl.h" +#include "unistd.h" +#include "sys/mount.h" +#include "sys/stat.h" +#include "sys/statfs.h" +#include "dirent.h" +#include "stdio.h" +#include "errno.h" +#include "pthread.h" +#include "time.h" +#include "securec.h" +#include "ff.h" +#include "los_debug.h" +#include "fatfs.h" +#include "cmsis_os.h" + +#define FS_SUCCESS 0 +#define FS_FAILURE (-1) +/* the max name length of different parts should not bigger than 32 */ +#define FS_DRIVE_NAME_MAX_LEN 32 + +#ifndef FAT_MAX_OPEN_DIRS +#define FAT_MAX_OPEN_DIRS 8 +#endif /* FAT_MAX_OPEN_DIRS */ + +#ifndef FAT_MAX_OPEN_FILES +#define FAT_MAX_OPEN_FILES 50 +#endif /* FAT_MAX_OPEN_FILES */ + +#ifndef FS_LOCK_TIMEMOUT_SEC +#define FS_LOCK_TIMEMOUT_SEC 15 +#endif /* FS_LOCK_TIMEMOUT_SEC */ + +#define PART_NAME 0x0 +#define VOLUME_NAME 0x1 +#define PATH_NAME 0x2 +#define NAME_MASK 0x3 + +typedef struct { + UINT8 useFlag; + FIL fil; +} FatHandleStruct; + +static FatHandleStruct g_handle[FAT_MAX_OPEN_FILES] = {0}; +static DIR g_dir[FAT_MAX_OPEN_DIRS] = {0}; +static FATFS g_fatfs[FF_VOLUMES] = {0}; +static UINT8 g_workBuffer[FF_MAX_SS]; +static UINT32 g_fileNum = 0; +static UINT32 g_dirNum = 0; +static struct dirent g_retValue; +static pthread_mutex_t g_fsMutex = PTHREAD_MUTEX_INITIALIZER; + +static const char * const g_volPath[FF_VOLUMES] = {FF_VOLUME_STRS}; +static BOOL g_volWriteEnable[FF_VOLUMES] = {FALSE}; + +static int FsLock(void) +{ + INT32 ret = 0; + struct timespec absTimeout = {0}; + if (osKernelGetState() != osKernelRunning) { + return ret; + } + ret = clock_gettime(CLOCK_REALTIME, &absTimeout); + if (ret != 0) { + PRINTK("clock gettime err 0x%x!\r\n", errno); + return errno; + } + absTimeout.tv_sec += FS_LOCK_TIMEMOUT_SEC; + ret = pthread_mutex_timedlock(&g_fsMutex, &absTimeout); + return ret; +} + +static void FsUnlock(void) +{ + if (osKernelGetState() != osKernelRunning) { + return; + } + (void)pthread_mutex_unlock(&g_fsMutex); +} + +static bool IsValidFd(int fd) +{ + if ((fd < 0) || (fd >= FAT_MAX_OPEN_FILES) || (g_handle[fd].useFlag == 0)) { + return false; + } + return true; +} + +static int FsChangeDrive(const char *path) +{ + INT32 res; + CHAR tmpPath[FS_DRIVE_NAME_MAX_LEN] = { "/" }; /* the max name length of different parts is 16 */ + errno_t retErr; + UINT16 pathLen; + pathLen = strlen((char const *)path); + /* make sure the path begin with "/", the path like /xxx/yyy/... */ + if (pathLen >= (FS_DRIVE_NAME_MAX_LEN - 1)) { + /* 2: except first flag "/" and last end flag */ + pathLen = FS_DRIVE_NAME_MAX_LEN - 2; + } + + retErr = strncpy_s(tmpPath + 1, (FS_DRIVE_NAME_MAX_LEN - 1), (char const *)path, pathLen); + if (retErr != EOK) { + return FS_FAILURE; + } + + res = f_chdrive(tmpPath); + if (res != FR_OK) { + return FS_FAILURE; + } + + return FS_SUCCESS; +} + +static int FsPartitionMatch(const char *path, int flag) +{ + INT32 ret; + UINT32 index; + CHAR tmpName[FF_MAX_LFN] = {0}; + + if (path == NULL) { + return FS_FAILURE; + } + + switch ((UINT32)flag & NAME_MASK) { + case VOLUME_NAME: + ret = sscanf_s(path, "/%[^/]", tmpName, FF_MAX_LFN); + if (ret <= 0) { + return FS_FAILURE; + } + break; + case PATH_NAME: + ret = sscanf_s(path, "%[^/]", tmpName, FF_MAX_LFN); + if (ret <= 0) { + return FS_FAILURE; + } + break; + case PART_NAME: + default: + ret = strcpy_s(tmpName, FF_MAX_LFN, path); + if (ret != EOK) { + return FS_FAILURE; + } + } + + for (index = 0; index < FF_VOLUMES; index++) { + if (strcmp(tmpName, g_volPath[index]) == 0) { + return index; + } + } + return FS_FAILURE; +} + +static int Remount(const char *path, unsigned long mountflags) +{ + INT32 index; + + index = FsPartitionMatch(path, PART_NAME); + if (index == FS_FAILURE) { + PRINTK("Wrong volume path!\r\n"); + errno = ENOENT; + return FS_FAILURE; + } + + /* remount is not allowed when the device is not mounted. */ + if (g_fatfs[index].fs_type == 0) { + errno = EINVAL; + return FS_FAILURE; + } + g_volWriteEnable[index] = (mountflags & MS_RDONLY) ? FALSE : TRUE; + + return FS_SUCCESS; +} + +static bool FsCheckByPath(const char *path) +{ + INT32 index; + + index = FsPartitionMatch(path, PATH_NAME); + if (index == FS_FAILURE) { + return FS_FAILURE; + } + + return g_volWriteEnable[index]; +} + +static bool FsCheckByID(int id) +{ + INT32 index; + + for (index = 0; index < FF_VOLUMES; index++) { + if (g_fatfs[index].id == id) { + return g_volWriteEnable[index]; + } + } + return false; +} + +static unsigned int FatFsGetMode(int oflags) +{ + UINT32 fmode = FA_READ; + + if ((UINT32)oflags & O_WRONLY) { + fmode |= FA_WRITE; + } + + if (((UINT32)oflags & O_ACCMODE) & O_RDWR) { + fmode |= FA_WRITE; + } + /* Creates a new file if the file is not existing, otherwise, just open it. */ + if ((UINT32)oflags & O_CREAT) { + fmode |= FA_OPEN_ALWAYS; + /* Creates a new file. If the file already exists, the function shall fail. */ + if ((UINT32)oflags & O_EXCL) { + fmode |= FA_CREATE_NEW; + } + } + /* Creates a new file. If the file already exists, its length shall be truncated to 0. */ + if ((UINT32)oflags & O_TRUNC) { + fmode |= FA_CREATE_ALWAYS; + } + + return fmode; +} + +static int FatfsErrno(int result) +{ + INT32 status = 0; + + if (result < 0) { + return result; + } + + /* FatFs errno to Libc errno */ + switch (result) { + case FR_OK: + break; + + case FR_NO_FILE: + case FR_NO_PATH: + case FR_NO_FILESYSTEM: + status = ENOENT; + break; + + case FR_INVALID_NAME: + status = EINVAL; + break; + + case FR_EXIST: + case FR_INVALID_OBJECT: + status = EEXIST; + break; + + case FR_DISK_ERR: + case FR_NOT_READY: + case FR_INT_ERR: + status = EIO; + break; + + case FR_WRITE_PROTECTED: + status = EROFS; + break; + case FR_MKFS_ABORTED: + case FR_INVALID_PARAMETER: + status = EINVAL; + break; + + case FR_NO_SPACE_LEFT: + status = ENOSPC; + break; + case FR_NO_DIRENTRY: + status = ENFILE; + break; + case FR_NO_EMPTY_DIR: + status = ENOTEMPTY; + break; + case FR_IS_DIR: + status = EISDIR; + break; + case FR_NO_DIR: + status = ENOTDIR; + break; + case FR_NO_EPERM: + case FR_DENIED: + status = EPERM; + break; + case FR_LOCKED: + status = EBUSY; + break; + default: + status = result; + break; + } + + return status; +} + +int mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data) +{ + INT32 index; + FRESULT res; + INT32 ret; + + if ((target == NULL) || (filesystemtype == NULL)) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (mountflags & MS_REMOUNT) { + ret = Remount(target, mountflags); + goto OUT; + } + + if (strcmp(filesystemtype, "fat") != 0) { + errno = ENODEV; + ret = FS_FAILURE; + goto OUT; + } + + index = FsPartitionMatch(target, VOLUME_NAME); + if (index == FS_FAILURE) { + errno = ENODEV; + ret = FS_FAILURE; + goto OUT; + } + + /* If the volume has been mounted */ + if (g_fatfs[index].fs_type != 0) { + errno = EBUSY; + ret = FS_FAILURE; + goto OUT; + } + + res = f_mount(&g_fatfs[index], target, 1); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + g_volWriteEnable[index] = (mountflags & MS_RDONLY) ? FALSE : TRUE; + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int umount(const char *target) +{ + FRESULT res; + INT32 ret; + INT32 index; + + if (target == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + index = FsPartitionMatch(target, VOLUME_NAME); + if (index == FS_FAILURE) { + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + /* The volume is not mounted */ + if (g_fatfs[index].fs_type == 0) { + errno = EINVAL; + ret = FS_FAILURE; + goto OUT; + } + + /* umount is not allowed when a file or diretory is opened. */ + if (f_checkopenlock(index) != FR_OK) { + errno = EBUSY; + ret = FS_FAILURE; + goto OUT; + } + + res = f_mount((FATFS *)NULL, target, 0); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + if (g_fatfs[index].win != NULL) { + ff_memfree(g_fatfs[index].win); + } + + (void)memset_s(&g_fatfs[index], sizeof(FATFS), 0x0, sizeof(FATFS)); + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +static int CloseAll(int index) +{ + INT32 i; + FRESULT res; + + for (i = 0; i < FAT_MAX_OPEN_FILES; i++) { + if (g_fileNum <= 0) { + break; + } + if ((g_handle[i].useFlag == 1) && (g_handle[i].fil.obj.fs == &g_fatfs[index])) { + res = f_close(&g_handle[i].fil); + if (res != FR_OK) { + errno = FatfsErrno(res); + return FS_FAILURE; + } + (void)memset_s(&g_handle[i], sizeof(FatHandleStruct), 0x0, sizeof(FatHandleStruct)); + g_fileNum--; + } + } + + for (i = 0; i < FAT_MAX_OPEN_DIRS; i++) { + if (g_dirNum <= 0) { + break; + } + if (g_dir[i].obj.fs == &g_fatfs[index]) { + res = f_closedir(&g_dir[i]); + if (res != FR_OK) { + errno = FatfsErrno(res); + return FS_FAILURE; + } + (void)memset_s(&g_dir[i], sizeof(DIR), 0x0, sizeof(DIR)); + g_dirNum--; + } + } + + return FS_SUCCESS; +} + +int umount2(const char *target, int flag) +{ + INT32 index; + INT32 ret; + UINT32 flags; + FRESULT res; + + if (target == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + flags = MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW; + if ((UINT32)flag & ~flags) { + errno = EINVAL; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + index = FsPartitionMatch(target, VOLUME_NAME); + if (index == FS_FAILURE) { + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + /* The volume is not mounted */ + if (g_fatfs[index].fs_type == 0) { + errno = EINVAL; + ret = FS_FAILURE; + goto OUT; + } + + if ((UINT32)flag & MNT_FORCE) { + ret = CloseAll(index); + if (ret != FS_SUCCESS) { + goto OUT; + } + } + + res = f_mount((FATFS *)NULL, target, 0); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + if (g_fatfs[index].win != NULL) { + ff_memfree(g_fatfs[index].win); + } + + (void)memset_s(&g_fatfs[index], sizeof(FATFS), 0x0, sizeof(FATFS)); + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int open(const char *path, int oflag, ...) +{ + FRESULT res; + UINT32 i; + UINT32 openNum = 0; + UINT32 fmode; + INT32 ret; + FILINFO fileInfo = {0}; + + if (path == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + fmode = FatFsGetMode(oflag); + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (g_fileNum >= FAT_MAX_OPEN_FILES) { + PRINTK("FAT g_fileNum is out of range 0x%x!\r\n", g_fileNum); + errno = ENFILE; + ret = FS_FAILURE; + goto OUT; + } + + for (i = 0; i < FAT_MAX_OPEN_FILES; i++) { + if (g_handle[i].useFlag == 0) { + openNum = i; + break; + } + } + + if (i >= FAT_MAX_OPEN_FILES) { + PRINTK("FAT opennum is out of range 0x%x!\r\n", openNum); + errno = ENFILE; + ret = FS_FAILURE; + goto OUT; + } + + ret = FsChangeDrive(path); + if (ret != FS_SUCCESS) { + PRINTK("FAT open ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + /* cannot creat a new file in the write protected part */ + if ((((UINT32)oflag & O_CREAT) != 0) && (!FsCheckByPath(path))) { + res = f_stat(path, &fileInfo); + if ((res == FR_NO_FILE) || (res == FR_NO_PATH)) { + PRINTK("FAT creat err 0x%x!\r\n", res); + errno = EACCES; + ret = FS_FAILURE; + goto OUT; + } + } + + res = f_open(&g_handle[openNum].fil, path, fmode); + if (res != FR_OK) { + PRINTK("FAT open err 0x%x!\r\n", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + g_handle[openNum].useFlag = 1; + g_fileNum++; + + ret = openNum; + +OUT: + FsUnlock(); + return ret; +} + +int close(int fd) +{ + FRESULT res; + INT32 ret; + + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + res = f_close(&g_handle[fd].fil); + if (res != FR_OK) { + PRINTK("FAT close err 0x%x!\r\n", res); + FsUnlock(); + errno = FatfsErrno(res); + return FS_FAILURE; + } + +#if !FF_FS_TINY + if (g_handle[fd].fil.buf != NULL) { + (void)ff_memfree(g_handle[fd].fil.buf); + } +#endif + + (void)memset_s(&g_handle[fd], sizeof(FatHandleStruct), 0x0, sizeof(FatHandleStruct)); + + if (g_fileNum > 0) { + g_fileNum--; + } + + FsUnlock(); + + return FS_SUCCESS; +} + +ssize_t read(int fd, void *buf, size_t nbyte) +{ + FRESULT res; + INT32 ret; + UINT32 lenRead; + + if (buf == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + res = f_read(&g_handle[fd].fil, buf, nbyte, &lenRead); + if (res != FR_OK) { + FsUnlock(); + errno = FatfsErrno(res); + return FS_FAILURE; + } + FsUnlock(); + + return (ssize_t)lenRead; +} + +ssize_t write(int fd, const void *buf, size_t nbyte) +{ + FRESULT res; + INT32 ret; + UINT32 lenWrite; + static BOOL overFlow = FALSE; + + if (buf == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!FsCheckByID(g_handle[fd].fil.obj.fs->id)) { + errno = EACCES; + goto ERROUT; + } + res = f_write(&g_handle[fd].fil, buf, nbyte, &lenWrite); + if ((res == FR_OK) && (lenWrite == 0) && (nbyte != 0) && (overFlow == FALSE)) { + overFlow = TRUE; + PRINTK("FAT write err 0x%x!\r\n", fd); + } + if ((res != FR_OK) || (nbyte != lenWrite)) { + errno = FatfsErrno(res); + goto ERROUT; + } + + FsUnlock(); + return (ssize_t)lenWrite; + +ERROUT: + FsUnlock(); + return FS_FAILURE; +} + +off_t lseek(int fd, off_t offset, int whence) +{ + FRESULT res; + INT32 ret; + off_t pos; + + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (whence == SEEK_SET) { + pos = 0; + } else if (whence == SEEK_CUR) { + pos = f_tell(&g_handle[fd].fil); + } else if (whence == SEEK_END) { + pos = f_size(&g_handle[fd].fil); + } else { + errno = EINVAL; + goto ERROUT; + } + + res = f_lseek(&g_handle[fd].fil, offset + pos); + if (res != FR_OK) { + errno = FatfsErrno(res); + goto ERROUT; + } + + pos = f_tell(&g_handle[fd].fil); + FsUnlock(); + return pos; + +ERROUT: + FsUnlock(); + return FS_FAILURE; +} + +/* Remove the specified FILE */ +int unlink(const char *path) +{ + FRESULT res; + INT32 ret; + + if (path == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!FsCheckByPath(path)) { + errno = EACCES; + ret = FS_FAILURE; + goto OUT; + } + + ret = FsChangeDrive(path); + if (ret != FS_SUCCESS) { + PRINTK("FAT ulink ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + res = f_unlink(path); + if (res != FR_OK) { + PRINTK("FAT ulink err 0x%x!\r\n", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +/* Return information about a file */ +int fstat(int fd, struct stat *buf) +{ + INT32 ret; + + if (buf == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + buf->st_size = f_size(&g_handle[fd].fil); + buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | + S_IWUSR | S_IWGRP | S_IWOTH | + S_IXUSR | S_IXGRP | S_IXOTH; + if (g_handle[fd].fil.obj.attr & AM_RDO) { + buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + } + + FsUnlock(); + return FS_SUCCESS; +} + +int stat(const char *__restrict path, struct stat *__restrict buf) +{ + FRESULT res; + FILINFO fileInfo = {0}; + INT32 ret; + + if ((path == NULL) || (buf == NULL)) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + ret = FsChangeDrive(path); + if (ret != FS_SUCCESS) { + PRINTK("FAT stat ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + res = f_stat(path, &fileInfo); + if (res != FR_OK) { + PRINTK("FAT stat err 0x%x!\r\n", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + buf->st_size = fileInfo.fsize; + buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | + S_IWUSR | S_IWGRP | S_IWOTH | + S_IXUSR | S_IXGRP | S_IXOTH; + + if (fileInfo.fattrib & AM_RDO) { + buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + } + + if (fileInfo.fattrib & AM_DIR) { + buf->st_mode &= ~S_IFREG; + buf->st_mode |= S_IFDIR; + } + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +/* Synchronize all changes to Flash */ +int fsync(int fd) +{ + FRESULT res; + INT32 ret; + + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!FsCheckByID(g_handle[fd].fil.obj.fs->id)) { + errno = EACCES; + ret = FS_FAILURE; + goto OUT; + } + res = f_sync(&g_handle[fd].fil); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int mkdir(const char *path, mode_t mode) +{ + FRESULT res; + INT32 ret; + + if (path == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!FsCheckByPath(path)) { + errno = EACCES; + ret = FS_FAILURE; + goto OUT; + } + + ret = FsChangeDrive(path); + if (ret != FS_SUCCESS) { + PRINTK("FAT mkdir ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + res = f_mkdir(path); + if (res != FR_OK) { + PRINTK("FAT mkdir err 0x%x!\r\n", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +DIR *opendir(const char *dirName) +{ + FRESULT res; + UINT32 openNum = 0; + UINT32 i; + INT32 ret; + + if (dirName == NULL) { + errno = EFAULT; + return NULL; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return NULL; + } + + if (g_dirNum >= FAT_MAX_OPEN_DIRS) { + PRINTK("FAT opendir g_dirNum err 0x%x!\r\n", g_dirNum); + errno = ENFILE; + goto ERROUT; + } + + for (i = 0; i < FAT_MAX_OPEN_DIRS; i++) { + if (g_dir[i].dir == NULL) { + openNum = i; + break; + } + } + + if (i >= FAT_MAX_OPEN_DIRS) { + PRINTK("FAT dir opennum is out of range 0x%x!\r\n", openNum); + errno = ENFILE; + goto ERROUT; + } + + ret = FsChangeDrive(dirName); + if (ret != FS_SUCCESS) { + PRINTK("FAT opendir ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + goto ERROUT; + } + + res = f_opendir(&g_dir[openNum], dirName); + if (res != FR_OK) { + g_dir[openNum].dir = NULL; + PRINTK("FAT opendir err 0x%x!\r\n", res); + errno = FatfsErrno(res); + goto ERROUT; + } + + g_dirNum++; + + FsUnlock(); + return &g_dir[openNum]; + +ERROUT: + FsUnlock(); + return NULL; +} + +struct dirent *readdir(DIR *dir) +{ + FRESULT res; + INT32 ret; + FILINFO fileInfo = {0}; + + if (dir == NULL) { + errno = EBADF; + return NULL; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return NULL; + } + + res = f_readdir(dir, &fileInfo); + /* if res not ok or fname is NULL , return NULL */ + if ((res != FR_OK) || (fileInfo.fname[0] == 0x0)) { + PRINTK("FAT readdir err 0x%x!\r\n", res); + errno = FatfsErrno(res); + FsUnlock(); + return NULL; + } + + (void)memcpy_s(g_retValue.d_name, sizeof(g_retValue.d_name), fileInfo.fname, sizeof(g_retValue.d_name)); + if (fileInfo.fattrib & AM_DIR) { + g_retValue.d_type = DT_DIR; + } else { + g_retValue.d_type = DT_REG; + } + FsUnlock(); + + return &g_retValue; +} + +int closedir(DIR *dir) +{ + FRESULT res; + INT32 ret; + + if (dir == NULL) { + errno = EBADF; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + g_dirNum--; + + res = f_closedir(dir); + if (res != FR_OK) { + PRINTK("FAT closedir err 0x%x!\r\n", res); + FsUnlock(); + errno = FatfsErrno(res); + return FS_FAILURE; + } + dir->dir = NULL; + FsUnlock(); + + return FS_SUCCESS; +} + +int rmdir(const char *path) +{ + FRESULT res; + INT32 ret; + + if (path == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!FsCheckByPath(path)) { + errno = EACCES; + ret = FS_FAILURE; + goto OUT; + } + + ret = FsChangeDrive(path); + if (ret != FS_SUCCESS) { + PRINTK("FAT rmdir ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + res = f_rmdir(path); + if (res != FR_OK) { + PRINTK("FAT rmdir err 0x%x!\r\n", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int rename(const char *oldName, const char *newName) +{ + FRESULT res; + INT32 ret; + + if ((oldName == NULL) || (newName == NULL)) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + if (!FsCheckByPath(oldName) || !FsCheckByPath(newName)) { + errno = EACCES; + ret = FS_FAILURE; + goto OUT; + } + + ret = FsChangeDrive(oldName); + if (ret != FS_SUCCESS) { + PRINTK("FAT f_getfree ChangeDrive err 0x%x!\r\n", ret); + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + res = f_rename(oldName, newName); + if (res != FR_OK) { + PRINTK("FAT frename err 0x%x!\r\n", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int statfs(const char *path, struct statfs *buf) +{ + FATFS *fs = NULL; + UINT32 freeClust; + FRESULT res; + INT32 ret; + + if ((path == NULL) || (buf == NULL)) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + ret = FsChangeDrive(path); + if (ret != FR_OK) { + PRINTK("FAT f_getfree ChangeDrive err %d.", ret); + errno = FatfsErrno(FR_INVALID_PARAMETER); + ret = FS_FAILURE; + goto OUT; + } + + res = f_getfree(path, &freeClust, &fs); + if (res != FR_OK) { + PRINTK("FAT f_getfree err 0x%x.", res); + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + buf->f_bfree = freeClust; + buf->f_bavail = freeClust; + /* Cluster #0 and #1 is for VBR, reserve sectors and fat */ + buf->f_blocks = fs->n_fatent - 2; +#if FF_MAX_SS != FF_MIN_SS + buf->f_bsize = fs->ssize * fs->csize; +#else + buf->f_bsize = FF_MIN_SS * fs->csize; +#endif + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int fatfs_fdisk(int pdrv, const unsigned int *partTbl) +{ + INT32 index; + FRESULT res; + INT32 ret; + + if (partTbl == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + ret = FS_FAILURE; + goto OUT; + } + + /* fdisk is not allowed when the device has been mounted. */ + for (index = 0; index < FF_VOLUMES; index++) { + if ((g_fatfs[index].pdrv == pdrv) && (g_fatfs[index].fs_type != 0)) { + errno = EBUSY; + ret = FS_FAILURE; + goto OUT; + } + } + + res = f_fdisk(pdrv, (DWORD const *)partTbl, g_workBuffer); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + +int fatfs_format(const char *dev, int sectors, int option) +{ + INT32 index; + FRESULT res; + INT32 ret; + + if (dev == NULL) { + errno = EFAULT; + return FS_FAILURE; + } + + ret = FsLock(); + if (ret != 0) { + errno = ret; + return FS_FAILURE; + } + + index = FsPartitionMatch(dev, VOLUME_NAME); + if (index == FS_FAILURE) { + errno = ENOENT; + ret = FS_FAILURE; + goto OUT; + } + + /* format is not allowed when the device has been mounted. */ + if (g_fatfs[index].fs_type != 0) { + errno = EBUSY; + ret = FS_FAILURE; + goto OUT; + } + + res = f_mkfs(dev, option, sectors, g_workBuffer, FF_MAX_SS); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} \ No newline at end of file diff --git a/components/fs/fatfs/fatfs.h b/components/fs/fatfs/fatfs.h new file mode 100644 index 00000000..c5c494a9 --- /dev/null +++ b/components/fs/fatfs/fatfs.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FATFS_H +#define _FATFS_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* Format options */ +#define FMT_FAT 0x01 +#define FMT_FAT32 0x02 +#define FMT_ANY 0x07 + +/** + * @brief divide a physical drive (SD card, U disk, and MMC card), this function is OHOS-specific + * @param pdrv physical drive number. + * @param partTbl list of partition size to create on the drive. + * -- item is <= 100: specifies the partition size in percentage of the entire drive space. + * -- item is > 100: specifies number of sectors. + * @return fdisk result + * @retval -1 fdisk error + * @retval 0 fdisk successful + */ +int fatfs_fdisk(int pdrv, const unsigned int *partTbl); + +/** + * @brief format FAT device (SD card, U disk, and MMC card), this function is OHOS-specific + * @param dev device name. + * @param sectors sectors per cluster, can be 0 OR power of 2. The sector size for standard FAT volumes is 512 bytes. + * -- sector number is 0 OR >128: automatically choose the appropriate cluster size. + * -- sector number is 1 ~ 128: cluster size = sectors per cluster * 512B. + * @param option file system type. + * -- FMT_FAT + * -- FMT_FAT32 + * -- FMT_ANY + * @return format result + * @retval -1 format error + * @retval 0 format successful + */ +int fatfs_format(const char *dev, int sectors, int option); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _FATFS_H */ \ No newline at end of file diff --git a/kal/cmsis/cmsis_liteos2.c b/kal/cmsis/cmsis_liteos2.c old mode 100644 new mode 100755 index 80bb11b3..88e4eef0 --- a/kal/cmsis/cmsis_liteos2.c +++ b/kal/cmsis/cmsis_liteos2.c @@ -39,6 +39,7 @@ #include "los_sem.h" #include "los_swtmr.h" #include "los_task.h" +#include "los_timer.h" #include "kal.h" #include "los_debug.h" @@ -71,7 +72,6 @@ const osVersion_t g_stLosVersion = { 001, 001 }; ((UINT32)LITEOS_VERSION_BUILD * 1UL)) #define KERNEL_ID "HUAWEI-LiteOS" -#define UNUSED(var) do { (void)var; } while (0) // ==== Kernel Management Functions ==== uint32_t osTaskStackWaterMarkGet(UINT32 taskID); @@ -277,7 +277,6 @@ uint32_t osKernelGetTickFreq(void) return (freq); } -extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo); uint32_t osKernelGetSysTimerCount(void) { uint32_t countHigh = 0; @@ -285,7 +284,7 @@ uint32_t osKernelGetSysTimerCount(void) if (OS_INT_ACTIVE) { countLow = 0U; } else { - LOS_GetCpuCycle((UINT32 *)&countHigh, (UINT32 *)&countLow); + HalGetCpuCycle((UINT32 *)&countHigh, (UINT32 *)&countLow); } return countLow; } @@ -655,22 +654,14 @@ uint32_t osThreadGetCount(void) } -// ==== Generic Wait Functions ==== -WEAK UINT32 HalDelay(UINT32 ticks) -{ - UNUSED(ticks); - return LOS_ERRNO_TSK_DELAY_IN_INT; -} - - osStatus_t osDelay(uint32_t ticks) { - UINT32 uwRet; + UINT32 uwRet = LOS_OK; if (ticks == 0) { return osOK; } if (osKernelGetState() != osKernelRunning) { - uwRet = HalDelay(ticks); + HalDelay(ticks); } else { uwRet = LOS_TaskDelay(ticks); } @@ -707,7 +698,7 @@ osStatus_t osDelayUntil(uint32_t ticks) osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { UNUSED(attr); - UINT16 usSwTmrID; + UINT32 usSwTmrID; UINT8 mode; if ((NULL == func) || ((osTimerOnce != type) && (osTimerPeriodic != type))) { @@ -1369,6 +1360,293 @@ void osThreadExit(void) } #endif +#define MP_ALLOC 1U +#define MD_ALLOC 2U +#define MEM_POOL_VALID 0xFFEEFF00 + +typedef struct { + LOS_MEMBOX_INFO poolInfo; + void *poolBase; + uint32_t poolSize; + uint32_t status; + const char *name; +} MemPoolCB; + +osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) +{ + MemPoolCB *mp = NULL; + const char *name = NULL; + LOS_MEMBOX_NODE *node = NULL; + uint32_t memCB = 0; + uint32_t memMP = 0; + uint32_t size; + uint32_t index; + + if (OS_INT_ACTIVE) { + return NULL; + } + + if ((block_count == 0) || (block_size == 0)) { + return NULL; + } + + size = block_count * block_size; + + if (attr != NULL) { + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(MemPoolCB))) { + memCB = 1; + } + + if ((attr->mp_mem != NULL) && + (((UINTPTR)attr->mp_mem & 0x3) == 0) && /* 0x3: Check if array is 4-byte aligned. */ + (attr->mp_size >= size)) { + memMP = 1; + } + name = attr->name; + } + + if (memCB == 0) { + mp = LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(MemPoolCB)); + if (mp == NULL) { + return NULL; + } + mp->status = MP_ALLOC; + } else { + mp = attr->cb_mem; + mp->status = 0; + } + + if (memMP == 0) { + mp->poolBase = LOS_MemAlloc(OS_SYS_MEM_ADDR, size); + if (mp->poolBase == NULL) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, mp); + return NULL; + } + mp->status |= MD_ALLOC; + } else { + mp->poolBase = attr->mp_mem; + } + mp->poolSize = size; + mp->name = name; + mp->poolInfo.uwBlkCnt = 0; + mp->poolInfo.uwBlkNum = block_count; + mp->poolInfo.uwBlkSize = block_size; + + node = (LOS_MEMBOX_NODE *)mp->poolBase; + mp->poolInfo.stFreeList.pstNext = node; + for (index = 0; index < block_count - 1; ++index) { + node->pstNext = OS_MEMBOX_NEXT(node, block_size); + node = node->pstNext; + } + node->pstNext = NULL; + + mp->status |= MEM_POOL_VALID; + + return mp; +} + +void *osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + LOS_MEMBOX_NODE *node = NULL; + UINTPTR intSave; + + UNUSED(timeout); + + if (mp_id == NULL) { + return NULL; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) == MEM_POOL_VALID) { + node = mp->poolInfo.stFreeList.pstNext; + if (node != NULL) { + mp->poolInfo.stFreeList.pstNext = node->pstNext; + mp->poolInfo.uwBlkCnt++; + } + } + LOS_IntRestore(intSave); + + return node; +} + +osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block) +{ + + MemPoolCB *mp = (MemPoolCB *)mp_id; + LOS_MEMBOX_NODE *node = NULL; + LOS_MEMBOX_NODE *nodeTmp = NULL; + UINTPTR intSave; + + if ((mp_id == NULL) || (block == NULL)) { + return osErrorParameter; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) != MEM_POOL_VALID) { + LOS_IntRestore(intSave); + return osErrorResource; + } + + if (((UINTPTR)block < (UINTPTR)mp->poolBase) || + ((UINTPTR)block >= ((UINTPTR)mp->poolBase + (UINTPTR)mp->poolSize))) { + LOS_IntRestore(intSave); + return osErrorParameter; + } + + node = (LOS_MEMBOX_NODE *)block; + nodeTmp = mp->poolInfo.stFreeList.pstNext; + mp->poolInfo.stFreeList.pstNext = node; + node->pstNext = nodeTmp; + mp->poolInfo.uwBlkCnt--; + LOS_IntRestore(intSave); + + return osOK; +} + +osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + UINTPTR intSave; + + if (OS_INT_ACTIVE) { + return osErrorISR; + } + + if (mp_id == NULL) { + return osErrorParameter; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) != MEM_POOL_VALID) { + LOS_IntRestore(intSave); + return osErrorResource; + } + + if (mp->status & MD_ALLOC) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, mp->poolBase); + mp->poolBase = NULL; + } + + mp->name = NULL; + mp->status &= ~MEM_POOL_VALID; + + if (mp->status & MP_ALLOC) { + (void)LOS_MemFree(OS_SYS_MEM_ADDR, mp); + } + LOS_IntRestore(intSave); + + return osOK; +} + +uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + UINTPTR intSave; + uint32_t num; + + if (mp_id == NULL) { + return 0; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) != MEM_POOL_VALID) { + num = 0; + } else { + num = mp->poolInfo.uwBlkNum; + } + LOS_IntRestore(intSave); + + return num; +} + +uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + UINTPTR intSave; + uint32_t size; + + if (mp_id == NULL) { + return 0; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) != MEM_POOL_VALID) { + size = 0; + } else { + size = mp->poolInfo.uwBlkSize; + } + LOS_IntRestore(intSave); + + return size; +} + +uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + UINTPTR intSave; + uint32_t count; + + if (mp_id == NULL) { + return 0; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) != MEM_POOL_VALID) { + count = 0; + } else { + count = mp->poolInfo.uwBlkCnt; + } + LOS_IntRestore(intSave); + + return count; +} + +uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + UINTPTR intSave; + uint32_t space; + + if (mp_id == NULL) { + return 0; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) != MEM_POOL_VALID) { + space = 0; + } else { + space = mp->poolInfo.uwBlkCnt - mp->poolInfo.uwBlkCnt; + } + LOS_IntRestore(intSave); + + return space; + +} + +const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id) +{ + MemPoolCB *mp = (MemPoolCB *)mp_id; + const char *p = NULL; + UINTPTR intSave; + + if (mp_id == NULL) { + return NULL; + } + + if (OS_INT_ACTIVE) { + return NULL; + } + + intSave = LOS_IntLock(); + if ((mp->status & MEM_POOL_VALID) == MEM_POOL_VALID) { + p = mp->name; + } + LOS_IntRestore(intSave); + + return p; +} + #endif // (CMSIS_OS_VER == 2) #ifdef __cplusplus #if __cplusplus diff --git a/kal/kal.c b/kal/kal.c old mode 100644 new mode 100755 index 0c41efee..4cbc6b2f --- a/kal/kal.c +++ b/kal/kal.c @@ -30,6 +30,7 @@ */ #include "kal.h" +#include "los_interrupt.h" #include "los_swtmr.h" #ifdef __cplusplus @@ -43,7 +44,7 @@ osTimerId_t osTimerExtNew(osTimerFunc_t func, osTimerType_t type, void *argument osTimerRouses_t ucRouses, osTimerAlign_t ucSensitive) { UNUSED(attr); - UINT16 usSwTmrID; + UINT32 usSwTmrID; UINT8 mode; if ((OS_INT_ACTIVE) || (NULL == func) || ((osTimerOnce != type) && (osTimerPeriodic != type))) { diff --git a/kal/kal.h b/kal/kal.h old mode 100644 new mode 100755 index 9a5605e9..daa19c8f --- a/kal/kal.h +++ b/kal/kal.h @@ -32,8 +32,9 @@ #ifndef _KAL_H #define _KAL_H -#include "cmsis_os2.h" +#include "los_config.h" #include "los_compiler.h" +#include "cmsis_os2.h" #ifdef __cplusplus #if __cplusplus diff --git a/kal/posix/include/libc.h b/kal/posix/include/libc.h old mode 100644 new mode 100755 index 92c9e265..cfec7955 --- a/kal/posix/include/libc.h +++ b/kal/posix/include/libc.h @@ -1,46 +1,46 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LIBC_H_ -#define LIBC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -const char *libc_get_version_string(void); -int libc_get_version(void); - -#ifdef __cplusplus -} -#endif - -#endif // LIBC_H_ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBC_H_ +#define LIBC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +const char *libc_get_version_string(void); +int libc_get_version(void); + +#ifdef __cplusplus +} +#endif + +#endif // LIBC_H_ diff --git a/kal/posix/src/time.c b/kal/posix/src/time.c old mode 100644 new mode 100755 index 4a8a5b54..8c61d8c6 --- a/kal/posix/src/time.c +++ b/kal/posix/src/time.c @@ -30,6 +30,7 @@ */ #include +#include #include #include #include @@ -49,9 +50,64 @@ #define OS_SYS_US_PER_SECOND 1000000 #define OS_SYS_MS_PER_SECOND 1000 +#define TM_YEAR_BASE 1900 +#define EPOCH_YEAR 1970 +#define SECS_PER_MIN 60 +#define MINS_PER_HOUR 60 +#define SECS_PER_HOUR 3600 /* 60 * 60 */ +#define SECS_PER_DAY 86400 /* 60 * 60 * 24 */ +#define SECS_PER_NORMAL_YEAR 31536000 /* 60 * 60 * 24 * 365 */ +#define DAYS_PER_WEEK 7 +#define DAYS_PER_NORMAL_YEAR 365 +#define DAYS_PER_LEAP_YEAR 366 +#define BEGIN_WEEKDAY 4 +#define TIME_ZONE_MAX 720 /* 12 * 60 */ +#define TIME_ZONE_MIN (-840) /* -14 * 60 */ + /* accumulative time delta from discontinuous modify */ STATIC struct timespec g_accDeltaFromSet; +STATIC const UINT16 g_daysInMonth[2][13] = { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +STATIC const UINT8 g_montbl[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +/* + * Nonzero if YEAR is a leap year (every 4 years, + * except every 100th isn't, and every 400th is). + */ +#ifndef IS_LEAP_YEAR +#define IS_LEAP_YEAR(year) \ + (((year) % 4 == 0) && (((year) % 100 != 0) || ((year) % 400 == 0))) +#endif +/* The lowest two bytes indicate minutes of the time zone */ +#ifndef OFFSET_TO_MINUTE +#define OFFSET_TO_MINUTE(time) (((time) < 0) ? (-(time)) : (time)) +#endif +/* The highest 31 bytes, 1 indicates eastern time zone£¬0 indicates western time zone */ +#ifndef TIME_ZONE_SIGN +#define TIME_ZONE_SIGN(time) ((time) >> 31) +#endif + +#define DIV(a, b) (((a) / (b)) - ((a) % (b) < 0)) +#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) + +/* 946656000000ms is the UTC 2000-01-01 00:00:00 */ +static UINT64 g_rtcTimeBase = 946656000000; +static UINT64 g_systickBase = 0; + +/* + * Time zone information, stored in minutes, + * negative values indicate the east of UTC, + * positive values indicate the west of UTC. + */ +static INT32 g_rtcTimeZone = -480; +static struct tm g_tm = {0}; + /* internal functions */ STATIC INLINE BOOL ValidTimeSpec(const struct timespec *tp) { @@ -126,7 +182,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *restrict timerID) { UINT32 ret; - UINT16 swtmrID; + UINT32 swtmrID; if (!timerID || (clockID != CLOCK_REALTIME)) { errno = EINVAL; @@ -155,7 +211,7 @@ int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *rest int timer_delete(timer_t timerID) { - UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + UINT32 swtmrID = (UINT32)(UINTPTR)timerID; if (LOS_SwtmrDelete(swtmrID) != LOS_OK) { errno = EINVAL; return -1; @@ -169,7 +225,7 @@ int timer_settime(timer_t timerID, int flags, struct itimerspec *restrict oldValue) { UINTPTR intSave; - UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + UINT32 swtmrID = (UINT32)(UINTPTR)timerID; SWTMR_CTRL_S *swtmr = NULL; UINT32 interval, expiry, ret; @@ -235,7 +291,7 @@ int timer_gettime(timer_t timerID, struct itimerspec *value) { UINT32 tick = 0; SWTMR_CTRL_S *swtmr = NULL; - UINT16 swtmrID = (UINT16)(UINTPTR)timerID; + UINT32 swtmrID = (UINT16)(UINTPTR)timerID; UINT32 ret; if (value == NULL) { @@ -424,3 +480,251 @@ int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct return EINVAL; } } + +clock_t clock(void) +{ + return HalGetExpandTick(); +} + +time_t time(time_t *timer) +{ + UINT64 usec = 0; + time_t sec; + INT32 rtcRet; + UINT32 offsetSec; + HalGetRtcTimeZone(&g_rtcTimeZone); + + rtcRet = HalGetRtcTime(&usec); + if (rtcRet != 0) { + UINT64 currentTime; + UINT64 tickDelta; + UINT64 currentTick = HalGetExpandTick(); + if ((g_systickBase != 0) && (currentTick > g_systickBase)) { + tickDelta = currentTick - g_systickBase; + } + currentTime = g_rtcTimeBase + tickDelta; + sec = currentTime / OS_SYS_MS_PER_SECOND; + } else { + sec = usec / OS_SYS_US_PER_SECOND; + } + offsetSec = (OFFSET_TO_MINUTE(g_rtcTimeZone)) * SECS_PER_MIN; + if (TIME_ZONE_SIGN(g_rtcTimeZone)) { + sec += (time_t)offsetSec; + } else { + sec -= (time_t)offsetSec; + } + if (timer != NULL) { + *timer = sec; + } + return sec; +} + +/* + * Compute the `struct tm' representation of T, + * offset OFFSET seconds east of UTC, + * and store year, yday, mon, mday, wday, hour, min, sec into *TP. + * Return nonzero if successful. + */ +static INT32 ConvertSecs2Utc(time_t t, INT32 offset, struct tm *tp) +{ + time_t days; + time_t rem; + time_t year; + time_t month; + time_t yearGuess; + + days = t / SECS_PER_DAY; + rem = t % SECS_PER_DAY; + rem += offset; + while (rem < 0) { + rem += SECS_PER_DAY; + --days; + } + while (rem >= SECS_PER_DAY) { + rem -= SECS_PER_DAY; + ++days; + } + tp->tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + tp->tm_min = rem / SECS_PER_MIN; + tp->tm_sec = rem % SECS_PER_MIN; + /* January 1, 1970 was a Thursday. */ + tp->tm_wday = (BEGIN_WEEKDAY + days) % DAYS_PER_WEEK; + if (tp->tm_wday < 0) { + tp->tm_wday += DAYS_PER_WEEK; + } + year = EPOCH_YEAR; + + while ((days < 0) || + (days >= (IS_LEAP_YEAR (year) ? DAYS_PER_LEAP_YEAR : DAYS_PER_NORMAL_YEAR))) { + /* Guess a corrected year, assuming 365 days per year. */ + yearGuess = year + days / DAYS_PER_NORMAL_YEAR - (days % DAYS_PER_NORMAL_YEAR < 0); + + /* Adjust days and year to match the guessed year. */ + days -= ((yearGuess - year) * DAYS_PER_NORMAL_YEAR + + LEAPS_THRU_END_OF (yearGuess - 1) - + LEAPS_THRU_END_OF (year - 1)); + year = yearGuess; + } + tp->tm_year = year - TM_YEAR_BASE; + if (tp->tm_year != year - TM_YEAR_BASE) { + return 0; + } + tp->tm_yday = days; + const UINT16 *daysInMonth = g_daysInMonth[IS_LEAP_YEAR(year)]; + /* valid month value is 0-11 */ + for (month = 11; days < (long int) daysInMonth[month]; --month) { + continue; + } + days -= daysInMonth[month]; + tp->tm_mon = month; + tp->tm_mday = days + 1; + return 1; +} + +struct tm *gmtime_r(const time_t *timer, struct tm *tp) +{ + time_t t64; + UINT32 intSave; + if ((timer == NULL) || (tp == NULL)) { + return NULL; + } + intSave = LOS_IntLock(); + t64 = *timer; + if (!ConvertSecs2Utc(t64, 0, tp)) { + tp = NULL; + } + (void)LOS_IntRestore(intSave); + return tp; +} + +struct tm *gmtime(const time_t *timer) +{ + return gmtime_r(timer, &g_tm); +} + +struct tm *localtime_r(const time_t *timer, struct tm *tp) +{ + UINT32 intSave; + time_t t64; + INT32 offset; + if ((timer == NULL) || (tp == NULL)) { + return NULL; + } + intSave = LOS_IntLock(); + t64 = *timer; + offset = -(g_rtcTimeZone * SECS_PER_MIN); + if (!ConvertSecs2Utc(t64, offset, tp)) { + tp = NULL; + } + (void)LOS_IntRestore(intSave); + return tp; +} + +struct tm *localtime(const time_t *timer) +{ + return localtime_r(timer, &g_tm); +} + +static time_t ConvertUtc2Secs(struct tm *tm) +{ + time_t seconds = 0; + INT32 month = 0; + UINT8 leap = 0; + + INT32 year = (EPOCH_YEAR - TM_YEAR_BASE); + while (year < tm->tm_year) { + seconds += SECS_PER_NORMAL_YEAR; + if (IS_LEAP_YEAR(year + TM_YEAR_BASE)) { + seconds += SECS_PER_DAY; + } + year++; + } + + if (IS_LEAP_YEAR(tm->tm_year + TM_YEAR_BASE)) { + leap = 1; + } + while (month < tm->tm_mon) { + if ((month == 1) && leap) { + seconds += (g_montbl[month] + 1) * SECS_PER_DAY; + } else { + seconds += g_montbl[month] * SECS_PER_DAY; + } + month++; + } + + seconds += (tm->tm_mday - 1) * SECS_PER_DAY; + + seconds += tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MIN + tm->tm_sec; + + return seconds; +} + +time_t mktime(struct tm *tmptr) +{ + struct tm tempTime; + time_t timeInSeconds; + if (tmptr == NULL) { + return 0; + } + if (tmptr->tm_year < (EPOCH_YEAR - TM_YEAR_BASE)) { + return 0; + } + tempTime = *tmptr; + timeInSeconds = ConvertUtc2Secs(&tempTime); + timeInSeconds += g_rtcTimeZone * SECS_PER_MIN; + return timeInSeconds; +} + +int gettimeofday(struct timeval *tv, void *ptz) +{ + INT32 rtcRet; + INT32 timeZone = 0; + UINT64 usec = 0; + UINT64 currentTime; + UINT64 tickDelta = 0; + UINT64 currentTick; + + struct timezone *tz = (struct timezone *)ptz; + if ((tv == NULL) && (tz == NULL)) { + return -1; + } + if (tv != NULL) { + rtcRet = HalGetRtcTime(&usec); + if (rtcRet != 0) { + currentTick = HalGetExpandTick(); + if ((g_systickBase != 0) && (currentTick > g_systickBase)) { + tickDelta = currentTick - g_systickBase; + } + currentTime = g_rtcTimeBase + tickDelta; + tv->tv_sec = currentTime / OS_SYS_MS_PER_SECOND; + tv->tv_usec = (currentTime % OS_SYS_MS_PER_SECOND) * OS_SYS_MS_PER_SECOND; + } else { + tv->tv_sec = usec / OS_SYS_US_PER_SECOND; + tv->tv_usec = usec % OS_SYS_US_PER_SECOND; + } + } + HalGetRtcTimeZone(&timeZone); + if (tz != NULL) { + tz->tz_minuteswest = timeZone; + } + return 0; +} + +int settimeofday(const struct timeval *tv, const struct timezone *tz) +{ + UINT64 usec; + if ((tv == NULL) || (tz == NULL)) { + return -1; + } + g_rtcTimeBase = tv->tv_sec * OS_SYS_MS_PER_SECOND + tv->tv_usec / OS_SYS_MS_PER_SECOND; + g_systickBase = HalGetExpandTick(); + if ((tz->tz_minuteswest > TIME_ZONE_MIN) && + (tz->tz_minuteswest < TIME_ZONE_MAX)) { + g_rtcTimeZone = tz->tz_minuteswest; + } + usec = tv->tv_sec * OS_SYS_US_PER_SECOND + tv->tv_usec; + HalSetRtcTime(g_rtcTimeBase, &usec); + HalSetRtcTimeZone(g_rtcTimeZone); + return 0; +} \ No newline at end of file diff --git a/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h b/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h old mode 100644 new mode 100755 index 6a271023..3ffd4bff --- a/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h @@ -461,6 +461,8 @@ extern VOID HalPendSV(VOID); #define OS_NVIC_INT_ENABLE_SIZE 0x20 #define OS_NVIC_INT_PRI_SIZE 0xF0 #define OS_NVIC_EXCPRI_SIZE 0xC +#define OS_NVIC_INT_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 #define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE #define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE @@ -729,49 +731,11 @@ typedef struct tagExcInfo { extern UINT32 g_curNestCount; extern UINT32 g_intCount; - -static VOID OsExcSave2DDR(VOID); -VOID OsExcInfoDisplay(ExcInfo *exc); - extern UINT8 g_uwExcTbl[32]; +extern ExcInfo g_excInfo; - - -typedef struct tagExcInfoCallBackArray { - ExcInfoType uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -} ExcInfoArray; - - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) -#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) #define MAX_INT_INFO_SIZE (8 + 0x164) -#if (LOSCFG_BASE_IPC_QUEUE == 1) -#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 == 1) -#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 == 1) -#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) - - - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/arch/arm/cortex-m3/keil/los_context.c b/kernel/arch/arm/cortex-m3/keil/los_context.c old mode 100644 new mode 100755 index 53ca335f..0534d705 --- a/kernel/arch/arm/cortex-m3/keil/los_context.c +++ b/kernel/arch/arm/cortex-m3/keil/los_context.c @@ -151,9 +151,15 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI void HalBackTrace() { - } +#if (LOSCFG_MEM_LEAKCHECK == 1) +VOID HalRecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, + UINTPTR stackStart, UINTPTR stackEnd) +{ +} +#endif + LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) { UINT32 ret; diff --git a/kernel/arch/arm/cortex-m3/keil/los_interrupt.c b/kernel/arch/arm/cortex-m3/keil/los_interrupt.c old mode 100644 new mode 100755 index 5fd2634a..824c20e5 --- a/kernel/arch/arm/cortex-m3/keil/los_interrupt.c +++ b/kernel/arch/arm/cortex-m3/keil/los_interrupt.c @@ -42,8 +42,8 @@ extern "C" { #endif /* __cplusplus */ /*lint -save -e40 -e522 -e533*/ - UINT32 g_intCount = 0; + /*lint -restore*/ #ifdef __ICCARM__ #pragma location = ".data.vector" @@ -59,6 +59,11 @@ HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; #endif +__weak VOID SysTick_Handler(VOID) +{ + return; +} + /* **************************************************************************** Function : HalIntNumGet Description : Get a interrupt number @@ -90,6 +95,16 @@ LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) while (1) {} } +WEAK VOID HalPreInterruptHandler(UINT32 arg) +{ + return; +} + +WEAK VOID HalAftInterruptHandler(UINT32 arg) +{ + return; +} + /* **************************************************************************** Function : HalInterrupt Description : Hardware interrupt entry function @@ -114,6 +129,8 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) hwiIndex = HalIntNumGet(); + HalPreInterruptHandler(hwiIndex); + #if (OS_HWI_WITH_ARG == 1) if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); @@ -123,6 +140,9 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) g_hwiSlaveForm[hwiIndex](); } #endif + + HalAftInterruptHandler(hwiIndex); + intSave = LOS_IntLock(); g_intCount--; LOS_IntRestore(intSave); @@ -203,8 +223,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) return LOS_OK; } -#define OS_NVIC_INT_CTRL_SIZE 4 -#define OS_NVIC_SHCSR_SIZE 4 #define FAULT_STATUS_REG_BIT 32 #define USGFAULT (1 << 18) #define BUSFAULT (1 << 17) @@ -212,9 +230,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) #define DIV0FAULT (1 << 4) #define HARDFAULT_IRQN (-13) -static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; - -static ExcInfo g_excInfo = {0}; +ExcInfo g_excInfo = {0}; UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, @@ -287,17 +303,6 @@ UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) return 0; } -VOID HalDumpMsg(VOID) -{ - UINT32 index = 0; - for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { - if (g_excArray[index].uwValid == FALSE) { - continue; - } - g_excArray[index].pFnExcInfoCb(index, g_excArray[index].pArg); - } -} - LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) { UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; @@ -328,22 +333,9 @@ LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, U } else { g_excInfo.context = excBufAddr; } - HalDumpMsg(); - HalSysExit(); -} -VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) -{ - ExcInfoArray *excInfo = NULL; - if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { - PRINT_ERR("HalExcRegister ERROR!\n"); - return; - } - excInfo = &(g_excArray[type]); - excInfo->uwType = type; - excInfo->pFnExcInfoCb = func; - excInfo->pArg = arg; - excInfo->uwValid = TRUE; + OsDoExcHook(EXC_INTERRUPT); + HalSysExit(); } /* **************************************************************************** @@ -370,6 +362,7 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcUsageFault; g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = HalExcSvcCall; g_hwiForm[PendSV_IRQn + OS_SYS_VECTOR_CNT] = HalPendSV; + g_hwiForm[SysTick_IRQn + OS_SYS_VECTOR_CNT] = SysTick_Handler; /* Interrupt vector table location */ SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; @@ -383,9 +376,6 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() /* Enable DIV 0 and unaligned exception */ *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; - HalExcRegister(OS_EXC_TYPE_CONTEXT, (EXC_INFO_SAVE_CALLBACK)HalExcContextDump, NULL); - HalExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)HalExcNvicDump, NULL); - return; } diff --git a/kernel/arch/arm/cortex-m3/keil/los_timer.c b/kernel/arch/arm/cortex-m3/keil/los_timer.c old mode 100644 new mode 100755 index df914357..572ffe18 --- a/kernel/arch/arm/cortex-m3/keil/los_timer.c +++ b/kernel/arch/arm/cortex-m3/keil/los_timer.c @@ -49,7 +49,7 @@ Input : none output : none return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) +WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) { UINT32 ret; @@ -78,6 +78,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) return LOS_OK; } +VOID HalSysTickReload(UINT32 cyclesPerTick) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + NVIC_ClearPendingIRQ(SysTick_IRQn); + SysTick->LOAD = (UINT32)(cyclesPerTick - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + /* **************************************************************************** Function : HalSysTickCurrCycleGet Description : Get System cycle count @@ -213,21 +222,34 @@ VOID HalEnterSleep(LOS_SysSleepEnum sleep) __ISB(); } -//extern unsigned int SystemCoreClock; -void HalDelay(UINT32 ticks) +WEAK VOID HalDelay(UINT32 ticks) { -#if 0 - UINT32 delayTimes; - /* there are 4 machine cycle in loop */ - if ((ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES)) >= 0xffffffff) { - delayTimes = 0xffffffff; - } else { - delayTimes = ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES); - } - while (delayTimes) { - delayTimes = delayTimes - 1; - } -#endif + +} + +WEAK UINT64 HalGetExpandTick(VOID) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTime(UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTimeZone(INT32 *timeZone) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTimeZone(INT32 timeZone) +{ + return LOS_OK; } #ifdef __cplusplus diff --git a/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h b/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h old mode 100644 new mode 100755 index 6a271023..3ffd4bff --- a/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h @@ -461,6 +461,8 @@ extern VOID HalPendSV(VOID); #define OS_NVIC_INT_ENABLE_SIZE 0x20 #define OS_NVIC_INT_PRI_SIZE 0xF0 #define OS_NVIC_EXCPRI_SIZE 0xC +#define OS_NVIC_INT_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 #define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE #define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE @@ -729,49 +731,11 @@ typedef struct tagExcInfo { extern UINT32 g_curNestCount; extern UINT32 g_intCount; - -static VOID OsExcSave2DDR(VOID); -VOID OsExcInfoDisplay(ExcInfo *exc); - extern UINT8 g_uwExcTbl[32]; +extern ExcInfo g_excInfo; - - -typedef struct tagExcInfoCallBackArray { - ExcInfoType uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -} ExcInfoArray; - - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) -#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) #define MAX_INT_INFO_SIZE (8 + 0x164) -#if (LOSCFG_BASE_IPC_QUEUE == 1) -#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 == 1) -#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 == 1) -#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) - - - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/arch/arm/cortex-m4/iar/los_context.c b/kernel/arch/arm/cortex-m4/iar/los_context.c old mode 100644 new mode 100755 index f15654fa..1c6b2935 --- a/kernel/arch/arm/cortex-m4/iar/los_context.c +++ b/kernel/arch/arm/cortex-m4/iar/los_context.c @@ -151,9 +151,76 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI void HalBackTrace() { - + } +#if (LOSCFG_MEM_LEAKCHECK == 1) +#define CODE_SECTION_NAME ".text" +#pragma section=CODE_SECTION_NAME +#define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME)) +#define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME)) + +/* check the disassembly instruction is 'BL' or 'BLX' */ +STATIC INLINE BOOL HalInsIsBlOrBlx(UINTPTR addr) +{ +#define BL_INS_MASK 0xF800 +#define BL_INS_HIGH 0xF800 +#define BL_INS_LOW 0xF000 +#define BLX_INX_MASK 0xFF00 +#define BLX_INX 0x4700 + UINT16 ins1 = *((UINT16 *)addr); + UINT16 ins2 = *((UINT16 *)(addr + 2)); /* 2: Thumb instruction is two bytes. */ + + if (((ins2 & BL_INS_MASK) == BL_INS_HIGH) && ((ins1 & BL_INS_MASK) == BL_INS_LOW)) { + return TRUE; + } else if ((ins2 & BLX_INX_MASK) == BLX_INX) { + return TRUE; + } else { + return FALSE; + } +} + +VOID HalRecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, + UINTPTR stackStart, UINTPTR stackEnd) +{ + if (LR == NULL) { + return; + } + + UINT32 count = 0; + UINT32 index = 0; + UINTPTR sp = stackStart; + UINTPTR pc; + + /* copy called function address */ + for (; sp < stackEnd; sp += sizeof(UINTPTR)) { + /* the *sp value may be LR, so need decrease a word to PC */ + pc = *((UINTPTR *)sp) - sizeof(UINTPTR); + /* the Cortex-M using thumb instruction, so the pc must be an odd number */ + if ((pc & 0x1) == 0) { + continue; + } + /* fix the PC address in thumb mode */ + pc = *((UINTPTR *)sp) - 1; + if ((pc >= CODE_START_ADDR) && (pc <= CODE_END_ADDR) &&(count < LRSize) && + HalInsIsBlOrBlx(pc - sizeof(UINTPTR))) { + if (index++ < jumpCount) { + continue; + } + LR[count++] = pc; + if (count == LRSize) { + break; + } + } + } + + /* if linkReg is not enough,clean up the last of the effective LR as the end. */ + if (count < LRSize) { + LR[count] = 0; + } +} +#endif + LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) { UINT32 ret; diff --git a/kernel/arch/arm/cortex-m4/iar/los_dispatch.S b/kernel/arch/arm/cortex-m4/iar/los_dispatch.S old mode 100644 new mode 100755 index cbb3fd44..09b88b9c --- a/kernel/arch/arm/cortex-m4/iar/los_dispatch.S +++ b/kernel/arch/arm/cortex-m4/iar/los_dispatch.S @@ -83,6 +83,7 @@ HalStartToRun LDR.W R1, =OS_FPU_CPACR LDR R1, [R1] AND R1, R1, #OS_FPU_CPACR_ENABLE + CMP R1, #OS_FPU_CPACR_ENABLE BNE __DisabledFPU ADD R12, R12, #100 @@ -136,6 +137,7 @@ HalTaskSwitch LDR.W R3, =OS_FPU_CPACR LDR R3, [R3] AND R3, R3, #OS_FPU_CPACR_ENABLE + CMP R3, #OS_FPU_CPACR_ENABLE BNE __DisabledFPU1 VSTMDB R0!, {D8-D15} @@ -163,6 +165,7 @@ __DisabledFPU1 LDR R1, [R0] AND R3, R3, #OS_FPU_CPACR_ENABLE + CMP R3, #OS_FPU_CPACR_ENABLE BNE __DisabledFPU2 VLDMIA R1!, {D8-D15} @@ -174,4 +177,3 @@ __DisabledFPU2 BX LR END - diff --git a/kernel/arch/arm/cortex-m4/iar/los_interrupt.c b/kernel/arch/arm/cortex-m4/iar/los_interrupt.c old mode 100644 new mode 100755 index 132c00c8..f8a3898b --- a/kernel/arch/arm/cortex-m4/iar/los_interrupt.c +++ b/kernel/arch/arm/cortex-m4/iar/los_interrupt.c @@ -34,7 +34,6 @@ #include #include "los_debug.h" #include "los_task.h" -#include "los_tick.h" #ifdef __cplusplus #if __cplusplus @@ -43,8 +42,8 @@ extern "C" { #endif /* __cplusplus */ /*lint -save -e40 -e522 -e533*/ - UINT32 g_intCount = 0; + /*lint -restore*/ #ifdef __ICCARM__ #pragma location = ".data.vector" @@ -60,6 +59,11 @@ HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; #endif +__weak VOID SysTick_Handler(VOID) +{ + return; +} + /* **************************************************************************** Function : HalIntNumGet Description : Get a interrupt number @@ -91,6 +95,16 @@ LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) while (1) {} } +WEAK VOID HalPreInterruptHandler(UINT32 arg) +{ + return; +} + +WEAK VOID HalAftInterruptHandler(UINT32 arg) +{ + return; +} + /* **************************************************************************** Function : HalInterrupt Description : Hardware interrupt entry function @@ -115,6 +129,8 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) hwiIndex = HalIntNumGet(); + HalPreInterruptHandler(hwiIndex); + #if (OS_HWI_WITH_ARG == 1) if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); @@ -124,6 +140,9 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) g_hwiSlaveForm[hwiIndex](); } #endif + + HalAftInterruptHandler(hwiIndex); + intSave = LOS_IntLock(); g_intCount--; LOS_IntRestore(intSave); @@ -204,8 +223,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) return LOS_OK; } -#define OS_NVIC_INT_CTRL_SIZE 4 -#define OS_NVIC_SHCSR_SIZE 4 #define FAULT_STATUS_REG_BIT 32 #define USGFAULT (1 << 18) #define BUSFAULT (1 << 17) @@ -213,9 +230,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) #define DIV0FAULT (1 << 4) #define HARDFAULT_IRQN (-13) -static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; - -static ExcInfo g_excInfo = {0}; +ExcInfo g_excInfo = {0}; UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, @@ -224,6 +239,7 @@ UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { 0, 0, 0, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL }; +#if (LOSCFG_KERNEL_PRINTF != 0) UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) { UINT32 *base = NULL; @@ -257,6 +273,7 @@ UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) } return 0; } +#endif UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) { @@ -288,17 +305,6 @@ UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) return 0; } -VOID HalDumpMsg(VOID) -{ - UINT32 index = 0; - for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { - if (g_excArray[index].uwValid == FALSE) { - continue; - } - g_excArray[index].pFnExcInfoCb(index, g_excArray[index].pArg); - } -} - LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) { UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; @@ -329,22 +335,9 @@ LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, U } else { g_excInfo.context = excBufAddr; } - HalDumpMsg(); - HalSysExit(); -} -VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) -{ - ExcInfoArray *excInfo = NULL; - if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { - PRINT_ERR("HalExcRegister ERROR!\n"); - return; - } - excInfo = &(g_excArray[type]); - excInfo->uwType = type; - excInfo->pFnExcInfoCb = func; - excInfo->pArg = arg; - excInfo->uwValid = TRUE; + OsDoExcHook(EXC_INTERRUPT); + HalSysExit(); } /* **************************************************************************** @@ -371,6 +364,7 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcUsageFault; g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = HalExcSvcCall; g_hwiForm[PendSV_IRQn + OS_SYS_VECTOR_CNT] = HalPendSV; + g_hwiForm[SysTick_IRQn + OS_SYS_VECTOR_CNT] = SysTick_Handler; /* Interrupt vector table location */ SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; @@ -384,9 +378,6 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() /* Enable DIV 0 and unaligned exception */ *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; - HalExcRegister(OS_EXC_TYPE_CONTEXT, (EXC_INFO_SAVE_CALLBACK)HalExcContextDump, NULL); - HalExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)HalExcNvicDump, NULL); - return; } diff --git a/kernel/arch/arm/cortex-m4/iar/los_mpu.c b/kernel/arch/arm/cortex-m4/iar/los_mpu.c new file mode 100644 index 00000000..5e4194d7 --- /dev/null +++ b/kernel/arch/arm/cortex-m4/iar/los_mpu.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_mpu.h" +#include "los_config.h" +#include "los_context.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define SIZE_4G_BYTE 0x100000000 +#define MPU_MAX_REGION_NUM 16 +typedef enum { + MPU_AP_FORBID_USER_FORBID = 0x0, /* Privileged:No access Unprivileged:No access */ + MPU_AP_RW_USER_FORBID = 0x1, /* Privileged:Read/Write Unprivileged:No access */ + MPU_AP_RW_USER_RO = 0x2, /* Privileged:Read/Write Unprivileged:Read-only */ + MPU_AP_RW_USER_RW = 0x3, /* Privileged:Read/Write Unprivileged:Read/Write */ + MPU_AP_NA_USER_NA = 0x4, /* Privileged:UNPREDICTABLE Unprivileged:UNPREDICTABLE */ + MPU_AP_RO_USER_FORBID = 0x5, /* Privileged:Read-only Unprivileged:No access */ + MPU_AP_RO_USER_RO = 0x6, /* Privileged:Read-only Unprivileged:Read-only */ +} MpuApConfig; + +VOID HalMpuEnable(UINT32 defaultRegionEnable) +{ + UINTPTR intSave = HalIntLock(); + MPU->CTRL = (MPU_CTRL_ENABLE_Msk | ((defaultRegionEnable << MPU_CTRL_PRIVDEFENA_Pos) & MPU_CTRL_PRIVDEFENA_Msk)); + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + __DSB(); + __ISB(); + HalIntRestore(intSave); +} +VOID HalMpuDisable(VOID) +{ + UINTPTR intSave = HalIntLock(); + MPU->CTRL = 0; + __DSB(); + __ISB(); + HalIntRestore(intSave); +} + +STATIC VOID HalMpuRASRAddMemAttr(MPU_CFG_PARA *para, UINT32 *RASR) +{ + BOOL cachable = 0; + BOOL buffable = 0; + switch (para->memType) { + case MPU_MEM_ON_CHIP_ROM: + case MPU_MEM_ON_CHIP_RAM: + cachable = 1; + buffable = 0; + break; + case MPU_MEM_XIP_PSRAM: + cachable = 1; + buffable = 1; + break; + case MPU_MEM_XIP_NOR_FLASH: + cachable = 0; + buffable = 1; + break; + default: + break; + } + (*RASR) |= ((cachable << MPU_RASR_C_Pos) | (buffable << MPU_RASR_B_Pos)); +} + +STATIC UINT32 HalMpuEncodeSize(UINT64 size) +{ + UINT32 encodeSize = 0; + if (size > SIZE_4G_BYTE) { + return 0; + } + if ((size & 0x1F) != 0) { /* size sould aligned to 32 byte at least. */ + return 0; + } + size = (size >> 2); + while (size != 0) { + if (((size & 1) != 0) && ((size & 0xFFFFFFFE) != 0)) { /* size != 2^x (5 <= x <= 32) 128B - 4GB */ + return 0; + } + size = (size >> 1); + encodeSize++; + } + return encodeSize; +} + +STATIC UINT32 HalMpuEncodeAP(MpuAccessPermission permission) +{ + UINT32 ap; + switch (permission) { + case MPU_RW_BY_PRIVILEGED_ONLY: + ap = MPU_AP_RW_USER_FORBID; + break; + case MPU_RW_ANY: + ap = MPU_AP_RW_USER_RW; + break; + case MPU_RO_BY_PRIVILEGED_ONLY: + ap = MPU_AP_RO_USER_FORBID; + break; + case MPU_RO_ANY: + ap = MPU_AP_RO_USER_RO; + break; + default: + ap = MPU_AP_RW_USER_RW; + break; + } + return ap; +} + +STATIC UINT32 HalMpuGetRASR(UINT32 encodeSize, MPU_CFG_PARA *para) +{ + UINT32 RASR; + UINT32 ap; + ap = HalMpuEncodeAP(para->permission); + RASR = MPU_RASR_ENABLE_Msk; + RASR |= ((encodeSize << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk); + RASR |= ((ap << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | ((para->executable << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | + ((para->shareability << MPU_RASR_S_Pos) & MPU_RASR_S_Msk); + HalMpuRASRAddMemAttr(para, &RASR); + return RASR; +} + +UINT32 HalMpuSetRegion(UINT32 regionId, MPU_CFG_PARA *para) +{ + UINT32 RASR; + UINT32 RBAR; + UINT32 RNR; + UINT32 encodeSize; + UINTPTR intSave; + UINT64 size; + + if ((regionId >= MPU_MAX_REGION_NUM)||(para == NULL)) { + return LOS_NOK; + } + RNR = regionId; + encodeSize = HalMpuEncodeSize(para->size); + if (encodeSize == 0) { + return LOS_NOK; + } + size = para->size - 1; /* size aligned after encode check */ + if ((para->baseAddr & size) != 0) { /* base addr should aligned to region size */ + return LOS_NOK; + } + RBAR = para->baseAddr & MPU_RBAR_ADDR_Msk; + RASR = HalMpuGetRASR(encodeSize, para); + intSave = HalIntLock(); + MPU->RNR = RNR; + MPU->RBAR = RBAR; + MPU->RASR = RASR; + __DSB(); + __ISB(); + HalIntRestore(intSave); + return LOS_OK; +} + +UINT32 HalMpuDisableRegion(UINT32 regionId) +{ + volatile UINT32 type; + UINTPTR intSave; + if (regionId >= MPU_MAX_REGION_NUM) { + return LOS_NOK; + } + intSave = HalIntLock(); + type = MPU->TYPE; + if ((MPU_TYPE_DREGION_Msk & type) != 0) { + MPU->RNR = regionId; + MPU->RASR = 0; + __DSB(); + __ISB(); + } + HalIntRestore(intSave); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/kernel/arch/arm/cortex-m4/iar/los_timer.c b/kernel/arch/arm/cortex-m4/iar/los_timer.c old mode 100644 new mode 100755 index 2486a29e..77a418b6 --- a/kernel/arch/arm/cortex-m4/iar/los_timer.c +++ b/kernel/arch/arm/cortex-m4/iar/los_timer.c @@ -48,7 +48,7 @@ Input : none output : none return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) +WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) { UINT32 ret; @@ -76,6 +76,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) return LOS_OK; } +VOID HalSysTickReload(UINT32 cyclesPerTick) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + NVIC_ClearPendingIRQ(SysTick_IRQn); + SysTick->LOAD = (UINT32)(cyclesPerTick - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + /* **************************************************************************** Function : HalSysTickCurrCycleGet Description : Get System cycle count @@ -211,21 +220,34 @@ VOID HalEnterSleep(LOS_SysSleepEnum sleep) __ISB(); } -//extern unsigned int SystemCoreClock; -void HalDelay(UINT32 ticks) +WEAK VOID HalDelay(UINT32 ticks) { -#if 0 - UINT32 delayTimes; - /* there are 4 machine cycle in loop */ - if ((ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES)) >= 0xffffffff) { - delayTimes = 0xffffffff; - } else { - delayTimes = ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES); - } - while (delayTimes) { - delayTimes = delayTimes - 1; - } -#endif + +} + +WEAK UINT64 HalGetExpandTick(VOID) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTime(UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTimeZone(INT32 *timeZone) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTimeZone(INT32 timeZone) +{ + return LOS_OK; } #ifdef __cplusplus diff --git a/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h b/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h old mode 100644 new mode 100755 index 6a271023..3ffd4bff --- a/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h @@ -461,6 +461,8 @@ extern VOID HalPendSV(VOID); #define OS_NVIC_INT_ENABLE_SIZE 0x20 #define OS_NVIC_INT_PRI_SIZE 0xF0 #define OS_NVIC_EXCPRI_SIZE 0xC +#define OS_NVIC_INT_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 #define OS_NVIC_INT_PEND_SIZE OS_NVIC_INT_ACT_SIZE #define OS_NVIC_INT_ACT_SIZE OS_NVIC_INT_ENABLE_SIZE @@ -729,49 +731,11 @@ typedef struct tagExcInfo { extern UINT32 g_curNestCount; extern UINT32 g_intCount; - -static VOID OsExcSave2DDR(VOID); -VOID OsExcInfoDisplay(ExcInfo *exc); - extern UINT8 g_uwExcTbl[32]; +extern ExcInfo g_excInfo; - - -typedef struct tagExcInfoCallBackArray { - ExcInfoType uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -} ExcInfoArray; - - - -#define MAX_SCENE_INFO_SIZE (8 + sizeof(ExcInfo) - 4 + sizeof(EXC_CONTEXT_S)) -#define MAX_TSK_INFO_SIZE (8 + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) #define MAX_INT_INFO_SIZE (8 + 0x164) -#if (LOSCFG_BASE_IPC_QUEUE == 1) -#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 == 1) -#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 == 1) -#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) - - - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c old mode 100644 new mode 100755 index f95b50f1..40ac32bf --- a/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c +++ b/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c @@ -42,8 +42,8 @@ extern "C" { #endif /* __cplusplus */ /*lint -save -e40 -e522 -e533*/ - UINT32 g_intCount = 0; + /*lint -restore*/ HWI_PROC_FUNC __attribute__((aligned(0x100))) g_hwiForm[OS_VECTOR_CNT] = {0}; @@ -85,6 +85,16 @@ LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) while (1) {} } +WEAK VOID HalPreInterruptHandler(UINT32 arg) +{ + return; +} + +WEAK VOID HalAftInterruptHandler(UINT32 arg) +{ + return; +} + /* **************************************************************************** Function : HalInterrupt Description : Hardware interrupt entry function @@ -109,6 +119,8 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) hwiIndex = HalIntNumGet(); + HalPreInterruptHandler(hwiIndex); + #if (OS_HWI_WITH_ARG == 1) if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); @@ -118,6 +130,9 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) g_hwiSlaveForm[hwiIndex](); } #endif + + HalAftInterruptHandler(hwiIndex); + intSave = LOS_IntLock(); g_intCount--; LOS_IntRestore(intSave); @@ -198,8 +213,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) return LOS_OK; } -#define OS_NVIC_INT_CTRL_SIZE 4 -#define OS_NVIC_SHCSR_SIZE 4 #define FAULT_STATUS_REG_BIT 32 #define USGFAULT (1 << 18) #define BUSFAULT (1 << 17) @@ -207,9 +220,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) #define DIV0FAULT (1 << 4) #define HARDFAULT_IRQN (-13) -static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; - -static ExcInfo g_excInfo = {0}; +ExcInfo g_excInfo = {0}; UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, @@ -282,17 +293,6 @@ UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) return 0; } -VOID HalDumpMsg(VOID) -{ - UINT32 index = 0; - for (index = 0; index < (OS_EXC_TYPE_MAX - 1); index++) { - if (g_excArray[index].uwValid == FALSE) { - continue; - } - g_excArray[index].pFnExcInfoCb(index, g_excArray[index].pArg); - } -} - LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) { UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; @@ -323,22 +323,9 @@ LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, U } else { g_excInfo.context = excBufAddr; } - HalDumpMsg(); - HalSysExit(); -} -VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) -{ - ExcInfoArray *excInfo = NULL; - if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { - PRINT_ERR("HalExcRegister ERROR!\n"); - return; - } - excInfo = &(g_excArray[type]); - excInfo->uwType = type; - excInfo->pFnExcInfoCb = func; - excInfo->pArg = arg; - excInfo->uwValid = TRUE; + OsDoExcHook(EXC_INTERRUPT); + HalSysExit(); } /* **************************************************************************** @@ -379,9 +366,6 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() /* Enable DIV 0 and unaligned exception */ *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; - HalExcRegister(OS_EXC_TYPE_CONTEXT, (EXC_INFO_SAVE_CALLBACK)HalExcContextDump, NULL); - HalExcRegister(OS_EXC_TYPE_NVIC, (EXC_INFO_SAVE_CALLBACK)HalExcNvicDump, NULL); - return; } diff --git a/kernel/arch/arm/cortex-m7/gcc/los_timer.c b/kernel/arch/arm/cortex-m7/gcc/los_timer.c old mode 100644 new mode 100755 index 0adf9f57..9cfbdfa8 --- a/kernel/arch/arm/cortex-m7/gcc/los_timer.c +++ b/kernel/arch/arm/cortex-m7/gcc/los_timer.c @@ -48,7 +48,7 @@ Input : none output : none return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed **************************************************************************** */ -LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) +WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) { UINT32 ret; @@ -77,6 +77,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) return LOS_OK; } +VOID HalSysTickReload(UINT32 cyclesPerTick) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + NVIC_ClearPendingIRQ(SysTick_IRQn); + SysTick->LOAD = (UINT32)(cyclesPerTick - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + /* **************************************************************************** Function : HalSysTickCurrCycleGet Description : Get System cycle count @@ -212,21 +221,34 @@ VOID HalEnterSleep(LOS_SysSleepEnum sleep) __ISB(); } -//extern unsigned int SystemCoreClock; -void HalDelay(UINT32 ticks) +WEAK VOID HalDelay(UINT32 ticks) { -#if 0 - UINT32 delayTimes; - /* there are 4 machine cycle in loop */ - if ((ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES)) >= 0xffffffff) { - delayTimes = 0xffffffff; - } else { - delayTimes = ticks * (SystemCoreClock / MACHINE_CYCLE_DEALAY_TIMES); - } - while (delayTimes) { - delayTimes = delayTimes - 1; - } -#endif + +} + +WEAK UINT64 HalGetExpandTick(VOID) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTime(UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTimeZone(INT32 *timeZone) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTimeZone(INT32 timeZone) +{ + return LOS_OK; } #ifdef __cplusplus diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h b/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h new file mode 100644 index 00000000..2e6121c3 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LOS_ATOMIC_H +#define LOS_ATOMIC_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/** + * @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 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) +{ + INT32 prevVal = 0; + UINT32 status = 0; + + 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 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 addSelf 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 HalAtomicDecRet(volatile INT32 *v) +{ + INT32 val = 0; + UINT32 status = 0; + + 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 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 HalAtomicCmpXchg32bits(volatile INT32 *v, INT32 val, INT32 oldVal) +{ + INT32 prevVal = 0; + UINT32 status = 0; + + 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; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* LOS_ATOMIC_H */ + diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_context.h b/kernel/arch/arm/cortex-m7/iar/los_arch_context.h new file mode 100644 index 00000000..4759cb69 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_context.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_ARCH_CONTEXT_H +#define _LOS_ARCH_CONTEXT_H + +#include "los_config.h" +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +typedef struct tagTskContext { +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + UINT32 S16; + UINT32 S17; + UINT32 S18; + UINT32 S19; + UINT32 S20; + UINT32 S21; + UINT32 S22; + UINT32 S23; + UINT32 S24; + UINT32 S25; + UINT32 S26; + UINT32 S27; + UINT32 S28; + UINT32 S29; + UINT32 S30; + UINT32 S31; +#endif + UINT32 uwR4; + UINT32 uwR5; + UINT32 uwR6; + UINT32 uwR7; + UINT32 uwR8; + UINT32 uwR9; + UINT32 uwR10; + UINT32 uwR11; + UINT32 uwPriMask; + UINT32 uwR0; + UINT32 uwR1; + UINT32 uwR2; + UINT32 uwR3; + UINT32 uwR12; + UINT32 uwLR; + UINT32 uwPC; + UINT32 uwxPSR; +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + UINT32 S0; + UINT32 S1; + UINT32 S2; + UINT32 S3; + UINT32 S4; + UINT32 S5; + UINT32 S6; + UINT32 S7; + UINT32 S8; + UINT32 S9; + UINT32 S10; + UINT32 S11; + UINT32 S12; + UINT32 S13; + UINT32 S14; + UINT32 S15; + UINT32 FPSCR; + UINT32 NO_NAME; +#endif +} TaskContext; + +/** + * @ingroup los_config + * @brief: Task start running function. + * + * @par Description: + * This API is used to start a task. + * + * @attention: + *
  • None.
+ * + * @param: None. + * + * @retval None. + * + * @par Dependency: + *
  • los_config.h: the header file that contains the API declaration.
+ * @see None. + */ +extern VOID HalStartToRun(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_ARCH_CONTEXT_H */ + diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h b/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h new file mode 100644 index 00000000..3ffd4bff --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h @@ -0,0 +1,746 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_EXC_H +#define _LOS_EXC_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +/* * + * @ingroup los_hwi + * Maximum number of used hardware interrupts. + */ +#ifndef OS_HWI_MAX_NUM +#define OS_HWI_MAX_NUM LOSCFG_PLATFORM_HWI_LIMIT +#endif + +/* * + * @ingroup los_hwi + * Highest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_HIGHEST +#define OS_HWI_PRIO_HIGHEST 0 +#endif + +/* * + * @ingroup los_hwi + * Lowest priority of a hardware interrupt. + */ +#ifndef OS_HWI_PRIO_LOWEST +#define OS_HWI_PRIO_LOWEST 7 +#endif + + +/* * + * @ingroup los_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_intCount; + +/* * + * @ingroup los_hwi + * Count of M-Core system interrupt vector. + */ +#define OS_SYS_VECTOR_CNT 16 + +/* * + * @ingroup los_hwi + * Count of M-Core interrupt vector. + */ +#define OS_VECTOR_CNT (OS_SYS_VECTOR_CNT + OS_HWI_MAX_NUM) + +/* * + * @ingroup los_hwi + * AIRCR register priority group parameter . + */ +#define OS_NVIC_AIRCR_PRIGROUP 7 + +/* * + * @ingroup los_hwi + * Boot interrupt vector table. + */ +extern UINT32 _BootVectors[]; + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt number. + * + * Value: 0x02000900 + * + * Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable for a Cortex-A7 platform is [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. + */ +#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Null hardware interrupt handling function. + * + * Value: 0x02000901 + * + * Solution: Pass in a valid non-null hardware interrupt handling function. + */ +#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation. + * + * Value: 0x02000902 + * + * Solution: Increase the configured maximum number of supported hardware interrupts. + */ +#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Insufficient memory for hardware interrupt initialization. + * + * Value: 0x02000903 + * + * Solution: Expand the configured memory. + */ +#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created. + * + * Value: 0x02000904 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Invalid interrupt priority. + * + * Value: 0x02000905 + * + * Solution: Ensure that the interrupt priority is valid. The value range of the interrupt priority applicable for a Cortex-A7 platform is [0,15]. + */ +#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: Incorrect interrupt creation mode. + * + * Value: 0x02000906 + * + * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of which the value can be 0 or 1. + */ +#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) + +/* * + * @ingroup los_hwi + * Hardware interrupt error code: The interrupt has already been created as a fast interrupt. + * + * Value: 0x02000907 + * + * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. + */ +#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) + +/* * + * @ingroup los_hwi + * SysTick control and status register. + */ +#define OS_SYSTICK_CONTROL_REG 0xE000E010 + +/* * + * @ingroup los_hw + * SysTick current value register. + */ +#define OS_SYSTICK_CURRENT_REG 0xE000E018 + +/* * + * @ingroup los_hwi + * Interrupt Priority-Level Registers. + */ +#define OS_NVIC_PRI_BASE 0xE000E400 + +/* * + * @ingroup los_hwi + * Interrupt enable register for 0-31. + */ +#define OS_NVIC_SETENA_BASE 0xE000E100 + +/* * + * @ingroup los_hwi + * interrupt pending register. + */ +#define OS_NVIC_SETPEND_BASE 0xE000E200 + +/* * + * @ingroup los_hwi + * Interrupt active register. + */ +#define OS_NVIC_INT_ACT_BASE 0xE000E300 + +/* * + * @ingroup los_hwi + * Interrupt disable register for 0-31. + */ +#define OS_NVIC_CLRENA_BASE 0xE000E180 + +/* * + * @ingroup los_hwi + * Interrupt control and status register. + */ +#define OS_NVIC_INT_CTRL 0xE000ED04 + +/* * + * @ingroup los_hwi + * Vector table offset register. + */ +#define OS_NVIC_VTOR 0xE000ED08 + +/* * + * @ingroup los_hwi + * Application interrupt and reset control register + */ +#define OS_NVIC_AIRCR 0xE000ED0C + +/* * + * @ingroup los_hwi + * System exception priority register. + */ +#define OS_NVIC_EXCPRI_BASE 0xE000ED18 + +/* * + * @ingroup los_hwi + * Interrupt No. 1 :reset. + */ +#define OS_EXC_RESET 1 + +/* * + * @ingroup los_hwi + * Interrupt No. 2 :Non-Maskable Interrupt. + */ +#define OS_EXC_NMI 2 + +/* * + * @ingroup los_hwi + * Interrupt No. 3 :(hard)fault. + */ +#define OS_EXC_HARD_FAULT 3 + +/* * + * @ingroup los_hwi + * Interrupt No. 4 :MemManage fault. + */ +#define OS_EXC_MPU_FAULT 4 + +/* * + * @ingroup los_hwi + * Interrupt No. 5 :Bus fault. + */ +#define OS_EXC_BUS_FAULT 5 + +/* * + * @ingroup los_hwi + * Interrupt No. 6 :Usage fault. + */ +#define OS_EXC_USAGE_FAULT 6 + +/* * + * @ingroup los_hwi + * Interrupt No. 11 :SVCall. + */ +#define OS_EXC_SVC_CALL 11 + +/* * + * @ingroup los_hwi + * Interrupt No. 12 :Debug monitor. + */ +#define OS_EXC_DBG_MONITOR 12 + +/* * + * @ingroup los_hwi + * Interrupt No. 14 :PendSV. + */ +#define OS_EXC_PEND_SV 14 + +/* * + * @ingroup los_hwi + * Interrupt No. 15 :SysTick. + */ +#define OS_EXC_SYS_TICK 15 + +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT]; + +#if (OS_HWI_WITH_ARG == 1) +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVectonr(num, vector, arg) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT].pParm = (VOID *)arg; \ + } while(0) +#else +/* * + * @ingroup los_hwi + * hardware interrupt Slave form mapping handling function array. + */ +extern HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT]; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +#define OsSetVector(num, vector) \ + do { \ + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; \ + g_hwiSlaveForm[num + OS_SYS_VECTOR_CNT] = vector; \ + } while(0) +#endif + +/* * + * @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. + */ +extern VOID HalInterrupt(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. + */ +extern UINT32 HalIntNumGet(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. + */ +extern VOID HalHwiDefaultHandler(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. + */ +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. + */ +extern VOID HalPendSV(VOID); + + +#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_CTRL_SIZE 4 +#define OS_NVIC_SHCSR_SIZE 4 + +#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 OS_EXC_EVENT 0x00000001 + +/** + *@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 HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr); + +/** + * @ingroup los_hwi + * @brief: Exception initialization. + * + * @par Description: + * This API is used to configure the exception function vector table. + * + * @attention: + *
  • 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. + */ +VOID OsExcInit(VOID); + +VOID HalExcNMI(VOID); +VOID HalExcHardFault(VOID); +VOID HalExcMemFault(VOID); +VOID HalExcBusFault(VOID); +VOID HalExcUsageFault(VOID); +VOID HalExcSvcCall(VOID); +VOID HalHwiInit(); + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状æ€å¯„存器入栈时å‘生错误 + */ +#define OS_EXC_BF_STKERR 1 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状æ€å¯„存器出栈时å‘生错误 + */ +#define OS_EXC_BF_UNSTKERR 2 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状æ€å¯„存器ä¸ç²¾ç¡®çš„æ•°æ®è®¿é—®è¿ä¾‹ + */ +#define OS_EXC_BF_IMPRECISERR 3 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状æ€å¯„存器精确的数æ®è®¿é—®è¿ä¾‹ + */ +#define OS_EXC_BF_PRECISERR 4 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:总线状æ€å¯„å­˜å™¨å–æŒ‡æ—¶çš„访问è¿ä¾‹ + */ +#define OS_EXC_BF_IBUSERR 5 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管ç†çжæ€å¯„存器入栈时å‘生错误 + */ +#define OS_EXC_MF_MSTKERR 6 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管ç†çжæ€å¯„存器出栈时å‘生错误 + */ +#define OS_EXC_MF_MUNSTKERR 7 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管ç†çжæ€å¯„存器数æ®è®¿é—®è¿ä¾‹ + */ +#define OS_EXC_MF_DACCVIOL 8 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:存储器管ç†çжæ€å¯„å­˜å™¨å–æŒ‡è®¿é—®è¿ä¾‹ + */ +#define OS_EXC_MF_IACCVIOL 9 + + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,表示除法è¿ç®—时除数为零 + */ +#define OS_EXC_UF_DIVBYZERO 10 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,未对é½è®¿é—®å¯¼è‡´çš„错误 + */ +#define OS_EXC_UF_UNALIGNED 11 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图执行å处ç†å™¨ç›¸å…³æŒ‡ä»¤ + */ +#define OS_EXC_UF_NOCP 12 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:ç”¨æ³•é”™è¯¯ï¼Œåœ¨å¼‚å¸¸è¿”å›žæ—¶è¯•å›¾éžæ³•地加载EXC_RETURN到PC + */ +#define OS_EXC_UF_INVPC 13 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:用法错误,试图切入ARMçŠ¶æ€ + */ +#define OS_EXC_UF_INVSTATE 14 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:ç”¨æ³•é”™è¯¯ï¼Œæ‰§è¡Œçš„æŒ‡ä»¤å…¶ç¼–ç æ˜¯æœªå®šä¹‰çš„——解ç ä¸èƒ½ + */ +#define OS_EXC_UF_UNDEFINSTR 15 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:NMI中断 + */ + +#define OS_EXC_CAUSE_NMI 16 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:硬fault + */ +#define OS_EXC_CAUSE_HARDFAULT 17 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:任务处ç†å‡½æ•°é€€å‡º + */ +#define OS_EXC_CAUSE_TASK_EXIT 18 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:致命错误 + */ +#define OS_EXC_CAUSE_FATAL_ERR 19 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:调试事件导致的硬fault + */ +#define OS_EXC_CAUSE_DEBUGEVT 20 + +/** + *@ingroup los_exc + *Cortex-M3异常具体类型:å–å‘釿—¶å‘生的硬fault + */ +#define OS_EXC_CAUSE_VECTBL 21 + +/** + *@ingroup los_exc + * 异常信æ¯ç»“构体 + * + * æè¿°:M4å¹³å°ä¸‹çš„å¼‚å¸¸è§¦å‘æ—¶ä¿å­˜çš„å¼‚å¸¸ä¿¡æ¯ + * + */ +typedef struct tagExcInfo { + /**< 异常å‘生阶段: 0表示异常å‘生在åˆå§‹åŒ–中,1表示异常å‘生在任务中,2表示异常å‘生在中断中 */ + UINT16 phase; + /**< 异常类型,出异常时对照上é¢åˆ—出的1-19å· */ + UINT16 type; + /**< 若为精确地å€è®¿é—®é”™è¯¯è¡¨ç¤ºå¼‚常å‘ç”Ÿæ—¶çš„é”™è¯¯è®¿é—®åœ°å€ */ + UINT32 faultAddr; + /**< 在中断中å‘生异常,表示中断å·ã€‚在任务中å‘生异常,表示任务id,如果å‘生在åˆå§‹åŒ–中,则为0xffffffff */ + UINT32 thrdPid; + /**< 异常嵌套个数,目å‰ä»…支æŒç¬¬ä¸€æ¬¡è¿›å…¥å¼‚常时执行注册的钩å­å‡½æ•° */ + UINT16 nestCnt; + /**< ä¿ç•™ */ + UINT16 reserved; + /**< 自动压栈浮点寄存器的异常å‘生时刻的硬件上下文 */ + EXC_CONTEXT_S * context; +} ExcInfo; + +extern UINT32 g_curNestCount; +extern UINT32 g_intCount; +extern UINT8 g_uwExcTbl[32]; +extern ExcInfo g_excInfo; + +#define MAX_INT_INFO_SIZE (8 + 0x164) + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_EXC_H */ + diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h b/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h new file mode 100644 index 00000000..2f38c220 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LOS_ARCH_TIMER_H +#define _LOS_ARCH_TIMER_H + +#include "los_config.h" +#include "los_compiler.h" +#include "los_context.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +UINT32 HalTickStart(OS_TICK_HANDLER handler); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#endif /* _LOS_ARCH_TIMER_H */ + diff --git a/kernel/arch/arm/cortex-m7/iar/los_context.c b/kernel/arch/arm/cortex-m7/iar/los_context.c new file mode 100644 index 00000000..2c12e0ab --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_context.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_config.h" +#include "los_task.h" +#include "securec.h" +#include "los_interrupt.h" +#include "los_arch_context.h" +#include "los_arch_interrupt.h" +#include "los_arch_timer.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/* **************************************************************************** + Function : HalArchInit + Description : arch init function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalArchInit() +{ + HalHwiInit(); +} + +/* **************************************************************************** + Function : HalSysExit + Description : Task exit function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) +{ + LOS_IntLock(); + for(;;); +} + +/* **************************************************************************** + Function : HalTskStackInit + Description : Task stack initialization function + Input : taskID --- TaskID + stackSize --- Total size of the stack + topStack --- Top of task's stack + Output : None + Return : Context pointer + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack) +{ + TaskContext *context = NULL; + errno_t result; + + /* initialize the task stack, write magic num to stack top */ + result = memset_s(topStack, stackSize, (INT32)(OS_TASK_STACK_INIT & 0xFF), stackSize); + if (result != EOK) { + printf("memset_s is failed:%s[%d]\r\n", __FUNCTION__, __LINE__); + } + *((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD; + + context = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext)); + +#if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined(__FPU_USED) && (__FPU_USED == 1U))) + context->S16 = 0xAA000010; + context->S17 = 0xAA000011; + context->S18 = 0xAA000012; + context->S19 = 0xAA000013; + context->S20 = 0xAA000014; + context->S21 = 0xAA000015; + context->S22 = 0xAA000016; + context->S23 = 0xAA000017; + context->S24 = 0xAA000018; + context->S25 = 0xAA000019; + context->S26 = 0xAA00001A; + context->S27 = 0xAA00001B; + context->S28 = 0xAA00001C; + context->S29 = 0xAA00001D; + context->S30 = 0xAA00001E; + context->S31 = 0xAA00001F; + context->S0 = 0xAA000000; + context->S1 = 0xAA000001; + context->S2 = 0xAA000002; + context->S3 = 0xAA000003; + context->S4 = 0xAA000004; + context->S5 = 0xAA000005; + context->S6 = 0xAA000006; + context->S7 = 0xAA000007; + context->S8 = 0xAA000008; + context->S9 = 0xAA000009; + context->S10 = 0xAA00000A; + context->S11 = 0xAA00000B; + context->S12 = 0xAA00000C; + context->S13 = 0xAA00000D; + context->S14 = 0xAA00000E; + context->S15 = 0xAA00000F; + context->FPSCR = 0x00000000; + context->NO_NAME = 0xAA000011; +#endif + + context->uwR4 = 0x04040404L; + context->uwR5 = 0x05050505L; + context->uwR6 = 0x06060606L; + context->uwR7 = 0x07070707L; + context->uwR8 = 0x08080808L; + context->uwR9 = 0x09090909L; + context->uwR10 = 0x10101010L; + context->uwR11 = 0x11111111L; + context->uwPriMask = 0; + context->uwR0 = taskID; + context->uwR1 = 0x01010101L; + context->uwR2 = 0x02020202L; + context->uwR3 = 0x03030303L; + context->uwR12 = 0x12121212L; + context->uwLR = (UINT32)(UINTPTR)HalSysExit; + context->uwPC = (UINT32)(UINTPTR)OsTaskEntry; + context->uwxPSR = 0x01000000L; + + return (VOID *)context; +} + +void HalBackTrace() +{ + +} + +#ifdef __ICCARM__ +#if (LOSCFG_MEM_LEAKCHECK == 1) +#define CODE_SECTION_NAME ".text" +#pragma section=CODE_SECTION_NAME +#define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME)) +#define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME)) + +/* check the disassembly instruction is 'BL' or 'BLX' */ +STATIC INLINE BOOL HalInsIsBlOrBlx(UINTPTR addr) +{ +#define BL_INS_MASK 0xF800 +#define BL_INS_HIGH 0xF800 +#define BL_INS_LOW 0xF000 +#define BLX_INX_MASK 0xFF00 +#define BLX_INX 0x4700 + UINT16 ins1 = *((UINT16 *)addr); + UINT16 ins2 = *((UINT16 *)(addr + 2)); /* 2: Thumb instruction is two bytes. */ + + if (((ins2 & BL_INS_MASK) == BL_INS_HIGH) && ((ins1 & BL_INS_MASK) == BL_INS_LOW)) { + return TRUE; + } else if ((ins2 & BLX_INX_MASK) == BLX_INX) { + return TRUE; + } else { + return FALSE; + } +} + +VOID HalRecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, + UINTPTR stackStart, UINTPTR stackEnd) +{ + if (LR == NULL) { + return; + } + + UINT32 count = 0; + UINT32 index = 0; + UINTPTR sp = stackStart; + UINTPTR pc; + + /* copy called function address */ + for (; sp < stackEnd; sp += sizeof(UINTPTR)) { + /* the *sp value may be LR, so need decrease a word to PC */ + pc = *((UINTPTR *)sp) - sizeof(UINTPTR); + /* the Cortex-M using thumb instruction, so the pc must be an odd number */ + if ((pc & 0x1) == 0) { + continue; + } + /* fix the PC address in thumb mode */ + pc = *((UINTPTR *)sp) - 1; + if ((pc >= CODE_START_ADDR) && (pc <= CODE_END_ADDR) &&(count < LRSize) && + HalInsIsBlOrBlx(pc - sizeof(UINTPTR))) { + if (index++ < jumpCount) { + continue; + } + LR[count++] = pc; + if (count == LRSize) { + break; + } + } + } + + /* if linkReg is not enough,clean up the last of the effective LR as the end. */ + if (count < LRSize) { + LR[count] = 0; + } +} +#endif +#endif + +LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) +{ + UINT32 ret; + ret = HalTickStart(handler); + if (ret != LOS_OK) { + return ret; + } + HalStartToRun(); + return LOS_OK; /* never return */ +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + + diff --git a/kernel/arch/arm/cortex-m7/iar/los_dispatch.S b/kernel/arch/arm/cortex-m7/iar/los_dispatch.S new file mode 100644 index 00000000..09b88b9c --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_dispatch.S @@ -0,0 +1,179 @@ +; +; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +; +; Redistribution and use in source and binary forms, with or without modification, +; are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, this list of +; conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright notice, this list +; of conditions and the following disclaimer in the documentation and/or other materials +; provided with the distribution. +; +; 3. Neither the name of the copyright holder nor the names of its contributors may be used +; to endorse or promote products derived from this software without specific prior written +; permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; + + PRESERVE8 + + EXPORT HalIntLock + EXPORT HalIntUnLock + EXPORT HalIntRestore + EXPORT HalStartToRun + EXPORT HalTaskSchedule + EXPORT HalPendSV + + IMPORT g_losTask + IMPORT g_taskScheduled + +OS_FPU_CPACR EQU 0xE000ED88 +OS_FPU_CPACR_ENABLE EQU 0x00F00000 +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 + +HalStartToRun + 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] + + LDR.W R1, =OS_FPU_CPACR + LDR R1, [R1] + AND R1, R1, #OS_FPU_CPACR_ENABLE + CMP R1, #OS_FPU_CPACR_ENABLE + BNE __DisabledFPU + ADD R12, R12, #100 + + LDMFD R12!, {R0-R7} + ADD R12, R12, #72 + MSR PSP, R12 + VPUSH S0; + VPOP S0; + MOV LR, R5 + CPSIE I + BX R6 + +__DisabledFPU + ADD R12, R12, #36 + + LDMFD R12!, {R0-R7} + MSR PSP, R12 + MOV LR, R5 + CPSIE I + BX R6 + + +HalIntLock + MRS R0, PRIMASK + CPSID I + BX LR + +HalIntUnLock + MRS R0, PRIMASK + CPSIE I + BX LR + +HalIntRestore + MSR PRIMASK, R0 + BX LR + +HalTaskSchedule + LDR R0, =OS_NVIC_INT_CTRL + LDR R1, =OS_NVIC_PENDSVSET + STR R1, [R0] + BX LR + +HalPendSV + MRS R12, PRIMASK + CPSID I + +HalTaskSwitch + MRS R0, PSP + + STMFD R0!, {R4-R12} + LDR.W R3, =OS_FPU_CPACR + LDR R3, [R3] + AND R3, R3, #OS_FPU_CPACR_ENABLE + CMP R3, #OS_FPU_CPACR_ENABLE + BNE __DisabledFPU1 + VSTMDB R0!, {D8-D15} + +__DisabledFPU1 + 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] + AND R3, R3, #OS_FPU_CPACR_ENABLE + CMP R3, #OS_FPU_CPACR_ENABLE + BNE __DisabledFPU2 + VLDMIA R1!, {D8-D15} + +__DisabledFPU2 + LDMFD R1!, {R4-R12} + MSR PSP, R1 + + MSR PRIMASK, R12 + BX LR + + END diff --git a/kernel/arch/arm/cortex-m7/iar/los_exc.S b/kernel/arch/arm/cortex-m7/iar/los_exc.S new file mode 100644 index 00000000..45e11851 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_exc.S @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + PRESERVE8 + SECTION .text:CODE(2) + THUMB + + EXPORT HalExcNMI + EXPORT HalExcHardFault + EXPORT HalExcMemFault + EXPORT HalExcBusFault + EXPORT HalExcUsageFault + EXPORT HalExcSvcCall + + IMPORT HalExcHandleEntry + IMPORT g_uwExcTbl + IMPORT g_taskScheduled + +OS_FLG_BGD_ACTIVE EQU 0x0002 + +OS_EXC_CAUSE_NMI EQU 16 +OS_EXC_CAUSE_HARDFAULT EQU 17 + +HF_DEBUGEVT EQU 20 +HF_VECTBL EQU 21 + +FLAG_ADDR_VALID EQU 0x10000 +FLAG_HWI_ACTIVE EQU 0x20000 +FLAG_NO_FLOAT EQU 0x10000000 + +OS_NVIC_FSR EQU 0xE000ED28 ;include BusFault/MemFault/UsageFault State Regeister +OS_NVIC_HFSR EQU 0xE000ED2C ;HardFault State Regeister +OS_NVIC_BFAR EQU 0xE000ED38 +OS_NVIC_MMAR EQU 0xE000ED34 +OS_NVIC_ACT_BASE EQU 0xE000E300 +OS_NVIC_SHCSRS EQU 0xE000ED24 +OS_NVIC_SHCSR_MASK EQU 0xC00 + +HalExcNMI + MOV R0, #OS_EXC_CAUSE_NMI + MOV R1, #0 + B osExcDispatch + +HalExcHardFault + MOV R0, #OS_EXC_CAUSE_HARDFAULT + LDR R2, =OS_NVIC_HFSR + LDR R2, [R2] + + MOV R1, #HF_DEBUGEVT + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x80000000 + BNE osExcDispatch ; DEBUGEVT + + AND R0, R0 , #0x000000FF + MOV R1, #HF_VECTBL + ORR R0, R0, R1, LSL #0x8 + TST R2, #0x00000002 + BNE osExcDispatch ; VECTBL + + ;if not DEBUGEVT and VECTBL then is FORCED + AND R0, R0, #0x000000FF + + LDR R2, =OS_NVIC_FSR + LDR R2, [R2] + + TST R2, #0x8000 ; BFARVALID + BNE _HFBusFault ; BusFault + + TST R2, #0x80 ; MMARVALID + BNE _HFMemFault ; MemFault + + MOV R12,#0 + B osHFExcCommonBMU + +_HFBusFault + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + B osHFExcCommonBMU + +_HFMemFault + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + +osHFExcCommonBMU + CLZ R2, R2 + LDR R3, =g_uwExcTbl + ADD R3, R3, R2 + LDRB R2, [R3] + ORR R0, R0, R2, LSL #0x8 + ORR R0, R0 ,R12 + B osExcDispatch + +HalExcSvcCall + TST LR, #0x4 + ITE EQ + MRSEQ R0, MSP + MRSNE R0, PSP + LDR R1, [R0,#24] + LDRB R0, [R1,#-2] + MOV R1, #0 + B osExcDispatch + +HalExcBusFault + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x8000 ; BFARVALID + BEQ _ExcBusNoADDR + LDR R1, =OS_NVIC_BFAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1F00 + + B osExcCommonBMU + +_ExcBusNoADDR + MOV R12,#0 + B osExcCommonBMU + +HalExcMemFault + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + TST R0, #0x80 ; MMARVALID + BEQ _ExcMemNoADDR + LDR R1, =OS_NVIC_MMAR + LDR R1, [R1] + MOV R12, #FLAG_ADDR_VALID + AND R0, R0, #0x1B + + B osExcCommonBMU + +_ExcMemNoADDR + MOV R12,#0 + B osExcCommonBMU + +HalExcUsageFault + LDR R0, =OS_NVIC_FSR + LDR R0, [R0] + + MOV R1, #0x030F + LSL R1, R1, #16 + AND R0, R0, R1 + MOV R12, #0 + +osExcCommonBMU + CLZ R0, R0 + LDR R3, =g_uwExcTbl + ADD R3, R3, R0 + LDRB R0, [R3] + ORR R0, R0, R12 + +; R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR +osExcDispatch + LDR R2, =OS_NVIC_ACT_BASE + MOV R12, #8 ; R12 is hwi check loop counter + +_hwiActiveCheck + LDR R3, [R2] ; R3 store active hwi register when exc + CMP R3, #0 + BEQ _hwiActiveCheckNext + + ; exc occured in IRQ + ORR R0, R0, #FLAG_HWI_ACTIVE + RBIT R2, R3 + CLZ R2, R2 + AND R12, R12, #1 + ADD R2, R2, R12, LSL #5 ; calculate R2 (hwi number) as uwPid + +_ExcInMSP + CMP LR, #0XFFFFFFED + BNE _NoFloatInMsp + ADD R3, R13, #104 + PUSH {R3} + MRS R12, PRIMASK ; store message-->exc: disable int? + PUSH {R4-R12} ; store message-->exc: {R4-R12} + VPUSH {D8-D15} + B _handleEntry + +_NoFloatInMsp + ADD R3, R13, #32 + PUSH {R3} ; save IRQ SP ; store message-->exc: MSP(R13) + + MRS R12, PRIMASK ; store message-->exc: disable int? + PUSH {R4-R12} ; store message-->exc: {R4-R12} + ORR R0, R0, #FLAG_NO_FLOAT + B _handleEntry + +_hwiActiveCheckNext + ADD R2, R2, #4 ; next NVIC ACT ADDR + SUBS R12, R12, #1 + BNE _hwiActiveCheck + + ;/*NMI interrupt excption*/ + LDR R2, =OS_NVIC_SHCSRS + LDRH R2,[R2] + LDR R3,=OS_NVIC_SHCSR_MASK + AND R2, R2,R3 + CMP R2,#0 + BNE _ExcInMSP + ; exc occured in Task or Init or exc + ; reserved for register info from task stack + + LDR R2, =g_taskScheduled + LDR R2, [R2] + TST R2, #1 ; OS_FLG_BGD_ACTIVE + BEQ _ExcInMSP ; if exc occured in Init then branch + + + CMP LR, #0xFFFFFFED ;auto push floating registers + BNE _NoFloatInPsp + + ; exc occured in Task + MOV R2, R13 + SUB R13, #96 ; add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #104 + PUSH {R12} ; save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + VPUSH {D8-D15} + + ; copy auto saved task register + + LDMFD R3!, {R4-R11} ; R4-R11 store PSP reg(auto push when exc in task) + VLDMIA R3!, {D8-D15} + VSTMDB R2!, {D8-D15} + STMFD R2!, {R4-R11} + B _handleEntry + +_NoFloatInPsp + MOV R2, R13 ;no auto push floating registers + SUB R13, #32 ; add 8 Bytes reg(for STMFD) + + MRS R3, PSP + ADD R12, R3, #32 + PUSH {R12} ; save task SP + + MRS R12, PRIMASK + PUSH {R4-R12} + + LDMFD R3, {R4-R11} ; R4-R11 store PSP reg(auto push when exc in task) + STMFD R2!, {R4-R11} + ORR R0, R0, #FLAG_NO_FLOAT + +_handleEntry + MOV R3, R13 ; R13:the 4th param + CPSID I + CPSID F + B HalExcHandleEntry + + NOP + END diff --git a/kernel/arch/arm/cortex-m7/iar/los_interrupt.c b/kernel/arch/arm/cortex-m7/iar/los_interrupt.c new file mode 100644 index 00000000..3efcfdc0 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_interrupt.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_interrupt.h" +#include "los_context.h" +#include "los_arch_interrupt.h" +#include +#include "los_debug.h" +#include "los_task.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +/*lint -save -e40 -e522 -e533*/ +UINT32 g_intCount = 0; + +/*lint -restore*/ +#pragma location = ".data.vector" +#pragma data_alignment=0x100 +HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; + +#if (OS_HWI_WITH_ARG == 1) +HWI_SLAVE_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; +#else +HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +#endif + +WEAK VOID SysTick_Handler(VOID) +{ + return; +} + +/* **************************************************************************** + Function : HalIntNumGet + Description : Get a interrupt number + Input : None + Output : None + Return : Interrupt Indexes number + **************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalIntNumGet(VOID) +{ + return __get_IPSR(); +} + +inline UINT32 HalIsIntAcvive(VOID) +{ + return (g_intCount > 0); +} +/* **************************************************************************** + Function : HalHwiDefaultHandler + Description : default handler of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +/*lint -e529*/ +LITE_OS_SEC_TEXT_MINOR VOID HalHwiDefaultHandler(VOID) +{ + UINT32 irqNum = HalIntNumGet(); + PRINT_ERR("%s irqnum:%d\n", __FUNCTION__, irqNum); + while (1) {} +} + +WEAK VOID HalPreInterruptHandler(UINT32 arg) +{ + return; +} + +WEAK VOID HalAftInterruptHandler(UINT32 arg) +{ + return; +} + +/* **************************************************************************** + Function : HalInterrupt + Description : Hardware interrupt entry function + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) +{ + UINT32 hwiIndex; + UINT32 intSave; + +#if (LOSCFG_KERNEL_RUNSTOP == 1) + SCB->SCR &= (UINT32) ~((UINT32)SCB_SCR_SLEEPDEEP_Msk); +#endif + + intSave = LOS_IntLock(); + + g_intCount++; + + LOS_IntRestore(intSave); + + hwiIndex = HalIntNumGet(); + + HalPreInterruptHandler(hwiIndex); + +#if (OS_HWI_WITH_ARG == 1) + if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { + g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + } +#else + if (g_hwiSlaveForm[hwiIndex] != 0) { + g_hwiSlaveForm[hwiIndex](); + } +#endif + + HalAftInterruptHandler(hwiIndex); + + intSave = LOS_IntLock(); + g_intCount--; + LOS_IntRestore(intSave); +} + +/* **************************************************************************** + Function : HalHwiCreate + Description : create hardware interrupt + Input : hwiNum --- hwi num to create + hwiPrio --- priority of the hwi + mode --- unused + handler --- hwi handler + arg --- param of the hwi handler + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum, + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) +{ + UINTPTR intSave; + + if (handler == NULL) { + return OS_ERRNO_HWI_PROC_FUNC_NULL; + } + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + if (g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)HalHwiDefaultHandler) { + return OS_ERRNO_HWI_ALREADY_CREATED; + } + + if (hwiPrio > OS_HWI_PRIO_LOWEST) { + return OS_ERRNO_HWI_PRIO_INVALID; + } + + intSave = LOS_IntLock(); +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(hwiNum, handler, arg); +#else + OsSetVector(hwiNum, handler); +#endif + NVIC_EnableIRQ((IRQn_Type)hwiNum); + NVIC_SetPriority((IRQn_Type)hwiNum, hwiPrio); + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +/* **************************************************************************** + Function : HalHwiDelete + Description : Delete hardware interrupt + Input : hwiNum --- hwi num to delete + Output : None + Return : LOS_OK on success or error code on failure + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) +{ + UINT32 intSave; + + if (hwiNum >= OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + NVIC_DisableIRQ((IRQn_Type)hwiNum); + + intSave = LOS_IntLock(); + + g_hwiForm[hwiNum + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +#define FAULT_STATUS_REG_BIT 32 +#define USGFAULT (1 << 18) +#define BUSFAULT (1 << 17) +#define MEMFAULT (1 << 16) +#define DIV0FAULT (1 << 4) +#define HARDFAULT_IRQN (-13) + +ExcInfo g_excInfo = {0}; + +UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { + 0, 0, 0, 0, 0, 0, OS_EXC_UF_DIVBYZERO, OS_EXC_UF_UNALIGNED, + 0, 0, 0, 0, OS_EXC_UF_NOCP, OS_EXC_UF_INVPC, OS_EXC_UF_INVSTATE, OS_EXC_UF_UNDEFINSTR, + 0, 0, 0, OS_EXC_BF_STKERR, OS_EXC_BF_UNSTKERR, OS_EXC_BF_IMPRECISERR, OS_EXC_BF_PRECISERR, OS_EXC_BF_IBUSERR, + 0, 0, 0, OS_EXC_MF_MSTKERR, OS_EXC_MF_MUNSTKERR, 0, OS_EXC_MF_DACCVIOL, OS_EXC_MF_IACCVIOL +}; + +#if (LOSCFG_KERNEL_PRINTF != 0) +UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) +{ + UINT32 *base = NULL; + UINT32 len = 0, i, j; +#define OS_NR_NVIC_EXC_DUMP_Types 7 + UINT32 rgNvicBases[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_SETENA_BASE, OS_NVIC_SETPEND_BASE, + OS_NVIC_INT_ACT_BASE, OS_NVIC_PRI_BASE, OS_NVIC_EXCPRI_BASE, OS_NVIC_SHCSR, OS_NVIC_INT_CTRL}; + UINT32 rgNvicLens[OS_NR_NVIC_EXC_DUMP_Types] = {OS_NVIC_INT_ENABLE_SIZE, OS_NVIC_INT_PEND_SIZE, + OS_NVIC_INT_ACT_SIZE, OS_NVIC_INT_PRI_SIZE, OS_NVIC_EXCPRI_SIZE, OS_NVIC_SHCSR_SIZE, OS_NVIC_INT_CTRL_SIZE}; + char strRgEnable[] = "enable"; + char strRgPending[] = "pending"; + char strRgActive[] = "active"; + char strRgPriority[] = "priority"; + char strRgException[] = "exception"; + char strRgShcsr[] = "shcsr"; + char strRgIntCtrl[] = "control"; + char *strRgs[] = {strRgEnable, strRgPending, strRgActive, strRgPriority, strRgException, strRgShcsr, strRgIntCtrl}; + (VOID)index; + (VOID)excContent; + + PRINTK("OS exception NVIC dump: \n"); + for (i = 0; i < OS_NR_NVIC_EXC_DUMP_Types; i++) { + base = (UINT32 *)rgNvicBases[i]; + len = rgNvicLens[i]; + PRINTK("interrupt %s register, base address: 0x%x, size: 0x%x\n", strRgs[i], base, len); + len = (len >> 2); + for (j = 0; j < len; j++) { + PRINTK("0x%x ", *(base + j)); + } + PRINTK("\n"); + } + return 0; +} +#endif + +UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) +{ + (VOID)index; + (VOID)excContent; + PRINTK("OS exception context dump:\n"); + PRINTK("Phase = 0x%x\n", g_excInfo.phase); + PRINTK("Type = 0x%x\n", g_excInfo.type); + PRINTK("FaultAddr = 0x%x\n", g_excInfo.faultAddr); + PRINTK("ThrdPid = 0x%x\n", g_excInfo.thrdPid); + PRINTK("R0 = 0x%x\n", g_excInfo.context->uwR0); + PRINTK("R1 = 0x%x\n", g_excInfo.context->uwR1); + PRINTK("R2 = 0x%x\n", g_excInfo.context->uwR2); + PRINTK("R3 = 0x%x\n", g_excInfo.context->uwR3); + PRINTK("R4 = 0x%x\n", g_excInfo.context->uwR4); + PRINTK("R5 = 0x%x\n", g_excInfo.context->uwR5); + PRINTK("R6 = 0x%x\n", g_excInfo.context->uwR6); + PRINTK("R7 = 0x%x\n", g_excInfo.context->uwR7); + PRINTK("R8 = 0x%x\n", g_excInfo.context->uwR8); + PRINTK("R9 = 0x%x\n", g_excInfo.context->uwR9); + PRINTK("R10 = 0x%x\n", g_excInfo.context->uwR10); + PRINTK("R11 = 0x%x\n", g_excInfo.context->uwR11); + PRINTK("R12 = 0x%x\n", g_excInfo.context->uwR12); + PRINTK("PriMask = 0x%x\n", g_excInfo.context->uwPriMask); + PRINTK("SP = 0x%x\n", g_excInfo.context->uwSP); + PRINTK("LR = 0x%x\n", g_excInfo.context->uwLR); + PRINTK("PC = 0x%x\n", g_excInfo.context->uwPC); + PRINTK("xPSR = 0x%x\n", g_excInfo.context->uwxPSR); + return 0; +} + +LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) +{ + UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; + g_intCount++; + g_excInfo.nestCnt++; + + 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 (g_losTask.runTask != NULL) { + if (tmpFlag & OS_EXC_FLAG_IN_HWI) { + g_excInfo.phase = OS_EXC_IN_HWI; + g_excInfo.thrdPid = pid; + } else { + g_excInfo.phase = OS_EXC_IN_TASK; + g_excInfo.thrdPid = g_losTask.runTask->taskID; + } + } else { + g_excInfo.phase = OS_EXC_IN_INIT; + g_excInfo.thrdPid = OS_NULL_INT; + } + if (excType & OS_EXC_FLAG_NO_FLOAT) { + g_excInfo.context = (EXC_CONTEXT_S *)((CHAR *)excBufAddr - LOS_OFF_SET_OF(EXC_CONTEXT_S, uwR4)); + } else { + g_excInfo.context = excBufAddr; + } + + OsDoExcHook(EXC_INTERRUPT); + HalSysExit(); +} + +/* **************************************************************************** + Function : HalHwiInit + Description : initialization of the hardware interrupt + Input : None + Output : None + Return : None + **************************************************************************** */ +LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() +{ +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) + UINT32 index; + g_hwiForm[0] = 0; /* [0] Top of Stack */ + g_hwiForm[1] = Reset_Handler; /* [1] reset */ + for (index = 2; index < OS_VECTOR_CNT; index++) { + g_hwiForm[index] = (HWI_PROC_FUNC)HalHwiDefaultHandler; + } + /* Exception handler register */ + g_hwiForm[NonMaskableInt_IRQn + OS_SYS_VECTOR_CNT] = HalExcNMI; + g_hwiForm[HARDFAULT_IRQN + OS_SYS_VECTOR_CNT] = HalExcHardFault; + g_hwiForm[MemoryManagement_IRQn + OS_SYS_VECTOR_CNT] = HalExcMemFault; + g_hwiForm[BusFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcBusFault; + g_hwiForm[UsageFault_IRQn + OS_SYS_VECTOR_CNT] = HalExcUsageFault; + g_hwiForm[SVCall_IRQn + OS_SYS_VECTOR_CNT] = HalExcSvcCall; + g_hwiForm[PendSV_IRQn + OS_SYS_VECTOR_CNT] = HalPendSV; + g_hwiForm[SysTick_IRQn + OS_SYS_VECTOR_CNT] = SysTick_Handler; + + /* Interrupt vector table location */ + SCB->VTOR = (UINT32)(UINTPTR)g_hwiForm; +#endif +#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ + NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP); +#endif + + /* Enable USGFAULT, BUSFAULT, MEMFAULT */ + *(volatile UINT32 *)OS_NVIC_SHCSR |= (USGFAULT | BUSFAULT | MEMFAULT); + /* Enable DIV 0 and unaligned exception */ + *(volatile UINT32 *)OS_NVIC_CCR |= DIV0FAULT; + + return; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/arch/arm/cortex-m7/iar/los_mpu.c b/kernel/arch/arm/cortex-m7/iar/los_mpu.c new file mode 100644 index 00000000..5e4194d7 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_mpu.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_mpu.h" +#include "los_config.h" +#include "los_context.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +#define SIZE_4G_BYTE 0x100000000 +#define MPU_MAX_REGION_NUM 16 +typedef enum { + MPU_AP_FORBID_USER_FORBID = 0x0, /* Privileged:No access Unprivileged:No access */ + MPU_AP_RW_USER_FORBID = 0x1, /* Privileged:Read/Write Unprivileged:No access */ + MPU_AP_RW_USER_RO = 0x2, /* Privileged:Read/Write Unprivileged:Read-only */ + MPU_AP_RW_USER_RW = 0x3, /* Privileged:Read/Write Unprivileged:Read/Write */ + MPU_AP_NA_USER_NA = 0x4, /* Privileged:UNPREDICTABLE Unprivileged:UNPREDICTABLE */ + MPU_AP_RO_USER_FORBID = 0x5, /* Privileged:Read-only Unprivileged:No access */ + MPU_AP_RO_USER_RO = 0x6, /* Privileged:Read-only Unprivileged:Read-only */ +} MpuApConfig; + +VOID HalMpuEnable(UINT32 defaultRegionEnable) +{ + UINTPTR intSave = HalIntLock(); + MPU->CTRL = (MPU_CTRL_ENABLE_Msk | ((defaultRegionEnable << MPU_CTRL_PRIVDEFENA_Pos) & MPU_CTRL_PRIVDEFENA_Msk)); + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + __DSB(); + __ISB(); + HalIntRestore(intSave); +} +VOID HalMpuDisable(VOID) +{ + UINTPTR intSave = HalIntLock(); + MPU->CTRL = 0; + __DSB(); + __ISB(); + HalIntRestore(intSave); +} + +STATIC VOID HalMpuRASRAddMemAttr(MPU_CFG_PARA *para, UINT32 *RASR) +{ + BOOL cachable = 0; + BOOL buffable = 0; + switch (para->memType) { + case MPU_MEM_ON_CHIP_ROM: + case MPU_MEM_ON_CHIP_RAM: + cachable = 1; + buffable = 0; + break; + case MPU_MEM_XIP_PSRAM: + cachable = 1; + buffable = 1; + break; + case MPU_MEM_XIP_NOR_FLASH: + cachable = 0; + buffable = 1; + break; + default: + break; + } + (*RASR) |= ((cachable << MPU_RASR_C_Pos) | (buffable << MPU_RASR_B_Pos)); +} + +STATIC UINT32 HalMpuEncodeSize(UINT64 size) +{ + UINT32 encodeSize = 0; + if (size > SIZE_4G_BYTE) { + return 0; + } + if ((size & 0x1F) != 0) { /* size sould aligned to 32 byte at least. */ + return 0; + } + size = (size >> 2); + while (size != 0) { + if (((size & 1) != 0) && ((size & 0xFFFFFFFE) != 0)) { /* size != 2^x (5 <= x <= 32) 128B - 4GB */ + return 0; + } + size = (size >> 1); + encodeSize++; + } + return encodeSize; +} + +STATIC UINT32 HalMpuEncodeAP(MpuAccessPermission permission) +{ + UINT32 ap; + switch (permission) { + case MPU_RW_BY_PRIVILEGED_ONLY: + ap = MPU_AP_RW_USER_FORBID; + break; + case MPU_RW_ANY: + ap = MPU_AP_RW_USER_RW; + break; + case MPU_RO_BY_PRIVILEGED_ONLY: + ap = MPU_AP_RO_USER_FORBID; + break; + case MPU_RO_ANY: + ap = MPU_AP_RO_USER_RO; + break; + default: + ap = MPU_AP_RW_USER_RW; + break; + } + return ap; +} + +STATIC UINT32 HalMpuGetRASR(UINT32 encodeSize, MPU_CFG_PARA *para) +{ + UINT32 RASR; + UINT32 ap; + ap = HalMpuEncodeAP(para->permission); + RASR = MPU_RASR_ENABLE_Msk; + RASR |= ((encodeSize << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk); + RASR |= ((ap << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | ((para->executable << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | + ((para->shareability << MPU_RASR_S_Pos) & MPU_RASR_S_Msk); + HalMpuRASRAddMemAttr(para, &RASR); + return RASR; +} + +UINT32 HalMpuSetRegion(UINT32 regionId, MPU_CFG_PARA *para) +{ + UINT32 RASR; + UINT32 RBAR; + UINT32 RNR; + UINT32 encodeSize; + UINTPTR intSave; + UINT64 size; + + if ((regionId >= MPU_MAX_REGION_NUM)||(para == NULL)) { + return LOS_NOK; + } + RNR = regionId; + encodeSize = HalMpuEncodeSize(para->size); + if (encodeSize == 0) { + return LOS_NOK; + } + size = para->size - 1; /* size aligned after encode check */ + if ((para->baseAddr & size) != 0) { /* base addr should aligned to region size */ + return LOS_NOK; + } + RBAR = para->baseAddr & MPU_RBAR_ADDR_Msk; + RASR = HalMpuGetRASR(encodeSize, para); + intSave = HalIntLock(); + MPU->RNR = RNR; + MPU->RBAR = RBAR; + MPU->RASR = RASR; + __DSB(); + __ISB(); + HalIntRestore(intSave); + return LOS_OK; +} + +UINT32 HalMpuDisableRegion(UINT32 regionId) +{ + volatile UINT32 type; + UINTPTR intSave; + if (regionId >= MPU_MAX_REGION_NUM) { + return LOS_NOK; + } + intSave = HalIntLock(); + type = MPU->TYPE; + if ((MPU_TYPE_DREGION_Msk & type) != 0) { + MPU->RNR = regionId; + MPU->RASR = 0; + __DSB(); + __ISB(); + } + HalIntRestore(intSave); + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/kernel/arch/arm/cortex-m7/iar/los_timer.c b/kernel/arch/arm/cortex-m7/iar/los_timer.c new file mode 100644 index 00000000..9cfbdfa8 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/iar/los_timer.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "los_config.h" +#include "los_tick.h" +#include "los_arch_interrupt.h" +#include "los_timer.h" +#include "los_context.h" +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + + + +/* **************************************************************************** +Function : HalTickStart +Description : Configure Tick Interrupt Start +Input : none +output : none +return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed +**************************************************************************** */ +WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) +{ + UINT32 ret; + + if ((OS_SYS_CLOCK == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) || + (LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) { + return LOS_ERRNO_TICK_CFG_INVALID; + } + +#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1) +#if (OS_HWI_WITH_ARG == 1) + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler, NULL); +#else + OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler); +#endif +#endif + + g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; + g_ullTickCount = 0; + + ret = SysTick_Config(g_cyclesPerTick); + if (ret == 1) { + return LOS_ERRNO_TICK_PER_SEC_TOO_SMALL; + } + + return LOS_OK; +} + +VOID HalSysTickReload(UINT32 cyclesPerTick) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + NVIC_ClearPendingIRQ(SysTick_IRQn); + SysTick->LOAD = (UINT32)(cyclesPerTick - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +/* **************************************************************************** +Function : HalSysTickCurrCycleGet +Description : Get System cycle count +Input : none +output : none +return : hwCycle --- the system cycle count +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR UINT32 HalSysTickCurrCycleGet(VOID) +{ + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + hwCycle += g_cyclesPerTick; + } + + LOS_IntRestore(intSave); + + return hwCycle; +} + +/* **************************************************************************** +Function : HalGetCpuCycle +Description : Get System cycle count +Input : none +output : cntHi --- CpuTick High 4 byte + cntLo --- CpuTick Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + hwCycle = SysTick->VAL; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = SysTick->VAL; + swTick++; + } + + cycle = (((swTick) * g_cyclesPerTick) + (g_cyclesPerTick - hwCycle)); + + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +/* **************************************************************************** +Function : HalGetSystickCycle +Description : Get Sys tick cycle count +Input : none +output : cntHi --- SysTick count High 4 byte + cntLo --- SysTick count Low 4 byte +return : none +**************************************************************************** */ +LITE_OS_SEC_TEXT_MINOR VOID HalGetSystickCycle(UINT32 *cntHi, UINT32 *cntLo) +{ + UINT64 swTick; + UINT64 cycle; + UINT32 hwCycle; + UINTPTR intSave; + UINT32 systickLoad; + UINT32 systickCur; + + intSave = LOS_IntLock(); + + swTick = g_ullTickCount; + + systickLoad = SysTick->LOAD; + systickCur = SysTick->VAL; + if (systickLoad < systickCur) { + LOS_IntRestore(intSave); + return; + } + hwCycle = systickLoad - systickCur; + + /* tick has come, but may interrupt environment, not counting the Tick interrupt response, to do +1 */ + if ((SCB->ICSR & TICK_CHECK) != 0) { + hwCycle = systickLoad - systickCur; + swTick++; + } + + cycle = hwCycle + swTick * systickLoad; + *cntHi = cycle >> SHIFT_32_BIT; + *cntLo = cycle & CYCLE_CHECK; + + LOS_IntRestore(intSave); + + return; +} + +static BOOL g_sysSleepFlag = FALSE; + +VOID HalTickLock(VOID) +{ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; +} + +VOID HalTickUnlock(VOID) +{ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +BOOL HalGetSysSleepFlag(VOID) +{ + return g_sysSleepFlag; +} + +VOID HalClearSysSleepFlag(VOID) +{ + g_sysSleepFlag = FALSE; +} + +VOID HalEnterSleep(LOS_SysSleepEnum sleep) +{ + __DSB(); + __WFI(); + __ISB(); +} + +WEAK VOID HalDelay(UINT32 ticks) +{ + +} + +WEAK UINT64 HalGetExpandTick(VOID) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTime(UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTimeZone(INT32 *timeZone) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTimeZone(INT32 timeZone) +{ + return LOS_OK; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/kernel/arch/include/los_arch.h b/kernel/arch/include/los_arch.h old mode 100644 new mode 100755 index 5794e3bd..37775978 --- a/kernel/arch/include/los_arch.h +++ b/kernel/arch/include/los_arch.h @@ -46,6 +46,11 @@ VOID HalArchInit(); void HalBackTrace(); #define LOS_BackTrace HalBackTrace +#if (LOSCFG_MEM_LEAKCHECK == 1) +VOID HalRecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, + UINTPTR stackStart, UINTPTR stackEnd); +#endif + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/arch/include/los_interrupt.h b/kernel/arch/include/los_interrupt.h old mode 100644 new mode 100755 index ee4ef2e0..0125f1dd --- a/kernel/arch/include/los_interrupt.h +++ b/kernel/arch/include/los_interrupt.h @@ -56,18 +56,6 @@ typedef UINT16 HWI_MODE_T; typedef UINT32 HWI_ARG_T; -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*); - #if (OS_HWI_WITH_ARG == 1) typedef VOID (*HWI_PROC_FUNC)(VOID *parm); typedef struct { @@ -84,7 +72,6 @@ UINT32 HalIsIntAcvive(VOID); #define OS_INT_ACTIVE (HalIsIntAcvive()) #define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) -VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg); /* * * @ingroup los_hwi * @brief Delete hardware interrupt. diff --git a/kernel/arch/include/los_mpu.h b/kernel/arch/include/los_mpu.h new file mode 100644 index 00000000..7e4f1da4 --- /dev/null +++ b/kernel/arch/include/los_mpu.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup memory protection + * @ingroup kernel + */ + +#ifndef _LOS_MPU_H +#define _LOS_MPU_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +typedef enum { + MPU_RW_BY_PRIVILEGED_ONLY = 0, + MPU_RW_ANY = 1, + MPU_RO_BY_PRIVILEGED_ONLY = 2, + MPU_RO_ANY = 3, +} MpuAccessPermission; + +typedef enum { + MPU_EXECUTABLE = 0, + MPU_NON_EXECUTABLE = 1, +} MpuExecutable; + +typedef enum { + MPU_NO_SHARE = 0, + MPU_SHARE = 1, +} MpuShareability; + +typedef enum { + MPU_MEM_ON_CHIP_ROM = 0, + MPU_MEM_ON_CHIP_RAM = 1, + MPU_MEM_XIP_PSRAM = 2, + MPU_MEM_XIP_NOR_FLASH = 3, + MPU_MEM_SHARE_MEM = 4, +} MpuMemType; + +typedef struct { + UINT32 baseAddr; + UINT64 size; /* armv7 size == 2^x (5 <= x <= 32) 128B - 4GB */ + MpuAccessPermission permission; + MpuExecutable executable; + MpuShareability shareability; + MpuMemType memType; +} MPU_CFG_PARA; + +VOID HalMpuEnable(UINT32 defaultRegionEnable); +VOID HalMpuDisable(); +UINT32 HalMpuSetRegion(UINT32 regionId, MPU_CFG_PARA *para); +UINT32 HalMpuDisableRegion(UINT32 regionId); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif /* _LOS_MPU_H */ diff --git a/kernel/arch/include/los_timer.h b/kernel/arch/include/los_timer.h old mode 100644 new mode 100755 index 9b6b6c3c..e27cb40f --- a/kernel/arch/include/los_timer.h +++ b/kernel/arch/include/los_timer.h @@ -28,6 +28,18 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#ifndef LOS_TIMER_H +#define LOS_TIMER_H + +#include "los_compiler.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + #define TICK_CHECK 0x4000000 #define CYCLE_CHECK 0xFFFFFFFFU #define SHIFT_32_BIT 32 @@ -38,7 +50,7 @@ #define RTC_WAKEUPCLOCK_RTCCLK 32768 #define RTC_WAKEUPCLOCK_RTCCLK_DIV 16 #define RTC_CALIBRATE_SLEEP_TIME 8 -#define MACHINE_CYCLE_DEALAY_TIMES 4000 +#define MACHINE_CYCLE_DEALAY_TIMES (LOSCFG_BASE_CORE_TICK_PER_SECOND << 2) typedef enum { OS_SYS_NORMAL_SLEEP = 0, @@ -51,11 +63,21 @@ VOID HalTickUnlock(VOID); BOOL HalGetSysSleepFlag(VOID); -VOID HalClearSysSleepFlag(VOID); - +VOID HalClearSysSleepFlag(VOID); VOID HalEnterSleep(LOS_SysSleepEnum sleep); +VOID HalDelay(UINT32 ticks); + +UINT64 HalGetExpandTick(VOID); + +INT32 HalGetRtcTime(UINT64 *usec); + +INT32 HalGetRtcTimeZone(INT32 *timeZone); + +INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec); + +INT32 HalSetRtcTimeZone(INT32 timeZone); /** * @ingroup los_timer @@ -79,7 +101,6 @@ VOID HalEnterSleep(LOS_SysSleepEnum sleep); * @see */ -#if (LOSCFG_KERNEL_TICKLESS == YES) /** * @ingroup los_hwi * @brief reconfig systick, and clear SysTick_IRQn. @@ -98,10 +119,9 @@ VOID HalEnterSleep(LOS_SysSleepEnum sleep); * @retval None. * @par Dependency: *
  • los_hwi.h: the header file that contains the API declaration.
- * @see LOS_IntRestore + * @see None */ extern VOID HalSysTickReload(UINT32 cyclesPerTick); -#endif /** * @ingroup los_hwi @@ -191,3 +211,11 @@ extern VOID HalTicklessEnable(VOID); * @see LOS_TicklessEnable */ extern VOID HalTicklessDisable(VOID); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/kernel/arch/risc-v/los_arch_interrupt.h b/kernel/arch/risc-v/los_arch_interrupt.h old mode 100644 new mode 100755 index 63ee4463..f318311d --- a/kernel/arch/risc-v/los_arch_interrupt.h +++ b/kernel/arch/risc-v/los_arch_interrupt.h @@ -67,17 +67,6 @@ typedef struct { LosExcContext *context; } LosExcInfo; -typedef UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID*); - -typedef struct { - ExcInfoType uwType; - UINT32 uwValid; - EXC_INFO_SAVE_CALLBACK pFnExcInfoCb; - VOID* pArg; -} ExcInfoArray; - -#define MAX_EXC_MEM_SIZE 0 - /** * @ingroup los_hwi * Highest priority of a hardware interrupt. diff --git a/kernel/arch/risc-v/los_exc.S b/kernel/arch/risc-v/los_exc.S index b0511bb8..b90375ff 100755 --- a/kernel/arch/risc-v/los_exc.S +++ b/kernel/arch/risc-v/los_exc.S @@ -74,18 +74,18 @@ .endm .macro PUSH_CALLEE_REG - SREG s11, 9 * REGBYTES(sp) - SREG s10, 10 * REGBYTES(sp) - SREG s9, 11 * REGBYTES(sp) - SREG s8, 12 * REGBYTES(sp) - SREG s7, 13 * REGBYTES(sp) - SREG s6, 14 * REGBYTES(sp) - SREG s5, 15 * REGBYTES(sp) - SREG s4, 26 * REGBYTES(sp) - SREG s3, 27 * REGBYTES(sp) - SREG s2, 28 * REGBYTES(sp) - SREG s1, 29 * REGBYTES(sp) - SREG s0, 30 * REGBYTES(sp) + SREG s11, 9 * REGBYTES(sp) + SREG s10, 10 * REGBYTES(sp) + SREG s9, 11 * REGBYTES(sp) + SREG s8, 12 * REGBYTES(sp) + SREG s7, 13 * REGBYTES(sp) + SREG s6, 14 * REGBYTES(sp) + SREG s5, 15 * REGBYTES(sp) + SREG s4, 26 * REGBYTES(sp) + SREG s3, 27 * REGBYTES(sp) + SREG s2, 28 * REGBYTES(sp) + SREG s1, 29 * REGBYTES(sp) + SREG s0, 30 * REGBYTES(sp) .endm .macro POP_ALL_REG diff --git a/kernel/arch/risc-v/los_interrupt.c b/kernel/arch/risc-v/los_interrupt.c old mode 100644 new mode 100755 index b5c5bfbd..8983ec37 --- a/kernel/arch/risc-v/los_interrupt.c +++ b/kernel/arch/risc-v/los_interrupt.c @@ -44,8 +44,6 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -static ExcInfoArray g_excArray[OS_EXC_TYPE_MAX]; - LosExcInfo g_excInfo; #define RISCV_EXC_TYPE_NUM 16 #define RISCV_EXC_LOAD_MISALIGNED 4 @@ -344,7 +342,7 @@ STATIC VOID ExcInfoDisplay(const LosExcContext *excBufAddr) PRINTK("taskName = %s\n\r", g_losTask.runTask->taskName); PRINTK("taskID = %u\n\r", g_losTask.runTask->taskID); - PRINTK("system mem addr:0x%x\n\r", (UINTPTR)OS_SYS_MEM_ADDR); + PRINTK("system mem addr:0x%x\n\r", (UINTPTR)LOSCFG_SYS_HEAP_ADDR); ExcInfoDisplayContext(&g_excInfo); } @@ -361,7 +359,7 @@ VOID HalExcEntry(const LosExcContext *excBufAddr) g_excInfo.type = excBufAddr->mcause & 0x1FF; g_excInfo.context = (LosExcContext *)excBufAddr; - if (g_excInfo.nestCnt > 2) { + if (g_excInfo.nestCnt > 2) { /* 2: Number of layers of exception nesting */ PRINTK("hard faule!\n\r"); goto SYSTEM_DEATH; } @@ -381,24 +379,11 @@ VOID HalExcEntry(const LosExcContext *excBufAddr) DisplayTaskInfo(); SYSTEM_DEATH: + OsDoExcHook(EXC_INTERRUPT); while (1) { } } -VOID HalExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg) -{ - ExcInfoArray *excInfo = NULL; - if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) { - PRINT_ERR("HalExcRegister ERROR!\n"); - return; - } - excInfo = &(g_excArray[type]); - excInfo->uwType = type; - excInfo->pFnExcInfoCb = func; - excInfo->pArg = arg; - excInfo->uwValid = TRUE; -} - LITE_OS_SEC_TEXT VOID HalTaskBackTrace(UINT32 taskID) { LosTaskCB *taskCB = NULL; @@ -435,11 +420,19 @@ LITE_OS_SEC_TEXT VOID HalBackTrace(VOID) BackTrace(fp); } +#if (LOSCFG_MEM_LEAKCHECK == 1) +VOID HalRecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, + UINTPTR stackStart, UINTPTR stackEnd) +{ +} +#endif + /* stack protector */ UINT32 __stack_chk_guard = 0xd00a0dff; VOID __stack_chk_fail(VOID) { + OsDoExcHook(EXC_STACKOVERFLOW); /* __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)); diff --git a/kernel/arch/risc-v/los_timer.c b/kernel/arch/risc-v/los_timer.c old mode 100644 new mode 100755 index 6b2378fc..495372bf --- a/kernel/arch/risc-v/los_timer.c +++ b/kernel/arch/risc-v/los_timer.c @@ -33,6 +33,7 @@ #include "los_config.h" #include "los_arch_interrupt.h" #include "riscv_hal.h" +#include "los_timer.h" #ifdef __cplusplus #if __cplusplus @@ -42,7 +43,7 @@ extern "C" { #define NS_PER_SECOND 1000000000.0 -LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER handler) +WEAK UINT32 HalTickStart(OS_TICK_HANDLER handler) { g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND; @@ -66,6 +67,36 @@ LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo) return; } +WEAK VOID HalDelay(UINT32 ticks) +{ + +} + +WEAK UINT64 HalGetExpandTick(VOID) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTime(UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalGetRtcTimeZone(INT32 *timeZone) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec) +{ + return LOS_OK; +} + +WEAK INT32 HalSetRtcTimeZone(INT32 timeZone) +{ + return LOS_OK; +} + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h old mode 100644 new mode 100755 index 35123c90..9767d117 --- a/kernel/include/los_config.h +++ b/kernel/include/los_config.h @@ -120,7 +120,7 @@ extern "C" { * If LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT is set to 0, vector base address will not be * modified by system. In arm, it should be noted that PendSV_Handler and SysTick_Handler should * be redefined to HalPendSV and OsTickHandler respectly in this case, because system depends on - * these interrupt handlers to run normally. What's more, LOS_HwiCreate will not register handlers. + * these interrupt handlers to run normally. What's more, LOS_HwiCreate will not register handler. */ #ifndef LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT #define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 1 @@ -348,14 +348,6 @@ extern "C" { #endif #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 @@ -382,12 +374,20 @@ extern "C" { ============================================================================= */ extern UINT8 *m_aucSysMem0; +/** + * @ingroup los_config + * Configure whether the kernel uses external heap memory + */ +#ifndef LOSCFG_SYS_EXTERNAL_HEAP +#define LOSCFG_SYS_EXTERNAL_HEAP 0 +#endif + /** * @ingroup los_config * Starting address of the memory */ -#ifndef OS_SYS_MEM_ADDR -#define OS_SYS_MEM_ADDR (&m_aucSysMem0[0]) +#ifndef LOSCFG_SYS_HEAP_ADDR +#define LOSCFG_SYS_HEAP_ADDR (&m_aucSysMem0[0]) #endif /** @@ -395,25 +395,15 @@ extern UINT8 *m_aucSysMem0; * Starting address of the task stack */ #ifndef OS_TASK_STACK_ADDR -#define OS_TASK_STACK_ADDR OS_SYS_MEM_ADDR +#define OS_TASK_STACK_ADDR LOSCFG_SYS_HEAP_ADDR #endif -/** - * @ingroup los_config - * Ending address of the memory - */ -extern UINT32 g_sysMemAddrEnd; - /** * @ingroup los_config * Memory size */ -#ifndef OS_SYS_MEM_SIZE -#define OS_SYS_MEM_SIZE 0x10000UL -#endif - -#ifndef LOSCFG_MEMORY_BESTFIT -#define LOSCFG_MEMORY_BESTFIT 1 +#ifndef LOSCFG_SYS_HEAP_SIZE +#define LOSCFG_SYS_HEAP_SIZE 0x10000UL #endif /** @@ -424,6 +414,14 @@ extern UINT32 g_sysMemAddrEnd; #define LOSCFG_MEM_MUL_POOL 1 #endif +/** + * @ingroup los_config + * Configuration module tailoring of memory released by task id + */ +#ifndef LOSCFG_MEM_FREE_BY_TASKID +#define LOSCFG_MEM_FREE_BY_TASKID 0 +#endif + /** * @ingroup los_config * Configuration module tailoring of mem node integrity checking @@ -434,18 +432,26 @@ extern UINT32 g_sysMemAddrEnd; /** * @ingroup los_config - * Configuration module tailoring of mem node size checking + * Configuration memory leak detection */ -#ifndef LOSCFG_BASE_MEM_NODE_SIZE_CHECK -#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK 0 +#ifndef LOSCFG_MEM_LEAKCHECK +#define LOSCFG_MEM_LEAKCHECK 0 #endif /** * @ingroup los_config - * Configuration of memory statistics + * Configuration memory leak recorded num */ -#ifndef LOSCFG_KERNEL_MEM_STATISTICS -#define LOSCFG_KERNEL_MEM_STATISTICS 0 +#ifndef LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM +#define LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM 1024 +#endif + +/** + * @ingroup los_config + * Configuration of memory pool record memory consumption waterline + */ +#ifndef LOSCFG_MEM_WATERLINE +#define LOSCFG_MEM_WATERLINE 1 #endif /** @@ -456,14 +462,6 @@ extern UINT32 g_sysMemAddrEnd; #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 1 -#endif - /** * @ingroup los_config * Size of unaligned memory @@ -523,7 +521,7 @@ extern UINT32 g_sysMemAddrEnd; * Configuration CMSIS_OS_VER */ #ifndef CMSIS_OS_VER -#define CMSIS_OS_VER 1 +#define CMSIS_OS_VER 2 #endif /* ============================================================================= @@ -537,6 +535,16 @@ extern UINT32 g_sysMemAddrEnd; #define LOSCFG_KERNEL_TRACE 0 #endif +/* ============================================================================= + printf configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration liteos printf + */ +#ifndef LOSCFG_KERNEL_PRINTF +#define LOSCFG_KERNEL_PRINTF 1 +#endif #ifdef __cplusplus #if __cplusplus diff --git a/kernel/include/los_membox.h b/kernel/include/los_membox.h old mode 100644 new mode 100755 index 1d0f537d..ba6e990b --- a/kernel/include/los_membox.h +++ b/kernel/include/los_membox.h @@ -29,39 +29,67 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * @defgroup los_membox Static memory + * @ingroup kernel + */ + #ifndef _LOS_MEMBOX_H #define _LOS_MEMBOX_H -#if (LOSCFG_PLATFORM_EXC == 1) -#include "los_memory.h" -#endif +#include "los_config.h" +#include "los_debug.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) + (blkSize)) + +#define OS_MEMBOX_NODE_HEAD_SIZE sizeof(LOS_MEMBOX_NODE) -#define BOX_ALIGN_8 0x80000000 -/* ---------------------------------------------------------------------------- - * Global Functions - * --------------------------------------------------------------------------- */ /** * @ingroup los_membox - * Define whether to check the address validity + * Structure of a free node in a memory pool */ -#if (LOSCFG_PLATFORM_EXC == 0) -#define LOS_MEMBOX_CHECK -extern UINT8 g_memMang[]; +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 LOS_MEMBOX_INFO { + UINT32 uwBlkSize; /**< Block size */ + UINT32 uwBlkNum; /**< Block number */ + UINT32 uwBlkCnt; /**< The number of allocated blocks */ +#if (LOSCFG_PLATFORM_EXC == 1) + struct LOS_MEMBOX_INFO *nextMemBox; /**< Point to the next membox */ +#endif + LOS_MEMBOX_NODE stFreeList; /**< Free list */ +} LOS_MEMBOX_INFO; + +typedef LOS_MEMBOX_INFO OS_MEMBOX_S; + +#if (LOSCFG_PLATFORM_EXC == 1) +UINT32 OsMemboxExcInfoGet(UINT32 memNumMax, MemInfoCB *memExcInfo); #endif -typedef struct tagMemBoxCB { - UINT32 uwMaxBlk; - UINT32 uwBlkCnt; - UINT32 uwBlkSize; /* Memory block size */ -}OS_MEMBOX_S; +/** + * @ingroup los_membox + * Memory pool alignment + */ +#define LOS_MEMBOX_ALLIGNED(memAddr) (((UINTPTR)(memAddr) + sizeof(UINTPTR) - 1) & (~(sizeof(UINTPTR) - 1))) -typedef OS_MEMBOX_S *OS_MEMBOX_S_P; - -#ifdef LOS_MEMBOX_CHECK -#define LOS_MEMBOX_MAGIC_SIZE 4 -#else -#define LOS_MEMBOX_MAGIC_SIZE 0 -#endif +/** + * @ingroup los_membox + * Memory pool size + */ +#define LOS_MEMBOX_SIZE(blkSize, blkNum) \ + (sizeof(LOS_MEMBOX_INFO) + (LOS_MEMBOX_ALLIGNED((blkSize) + OS_MEMBOX_NODE_HEAD_SIZE) * (blkNum))) /** * @ingroup los_membox @@ -73,13 +101,14 @@ typedef OS_MEMBOX_S *OS_MEMBOX_S_P; * * @attention *
    - *
  • The boxSize parameter value should match the following two conditions :
  • - *
  • 1) Be less than or equal to the Memory pool size; 2) Be greater than the size of LOS_MEMBOX_INFO.
  • + *
  • 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.
  • *
* - * @param boxMem [IN] Memory pool address. - * @param boxSize [IN] Memory pool size. - * @param blkSize [IN] Memory block size. + * @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. @@ -89,7 +118,7 @@ typedef OS_MEMBOX_S *OS_MEMBOX_S_P; * * @see None. */ -extern UINT32 LOS_MemboxInit(VOID *boxMem, UINT32 boxSize, UINT32 blkSize); +extern UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize); /** * @ingroup los_membox @@ -104,7 +133,7 @@ extern UINT32 LOS_MemboxInit(VOID *boxMem, UINT32 boxSize, UINT32 blkSize); *
  • The input pool parameter must be initialized via func LOS_MemboxInit.
  • * * - * @param boxMem [IN] Memory pool address. + * @param pool [IN] Memory pool address. * * @retval #VOID* The request is accepted, and return a memory block address. * @retval #NULL The request fails. @@ -114,7 +143,7 @@ extern UINT32 LOS_MemboxInit(VOID *boxMem, UINT32 boxSize, UINT32 blkSize); * * @see LOS_MemboxFree */ -extern VOID *LOS_MemboxAlloc(VOID *boxMem); +extern VOID *LOS_MemboxAlloc(VOID *pool); /** * @ingroup los_membox @@ -127,11 +156,11 @@ extern VOID *LOS_MemboxAlloc(VOID *boxMem); * @attention *
      *
    • The input pool parameter must be initialized via func LOS_MemboxInit.
    • - *
    • The input pBox parameter must be allocated by LOS_MemboxAlloc.
    • + *
    • The input box parameter must be allocated by LOS_MemboxAlloc.
    • *
    * - * @param boxMem [IN] Memory pool address. - * @param box [IN] Memory block address. + * @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. @@ -141,7 +170,7 @@ extern VOID *LOS_MemboxAlloc(VOID *boxMem); * * @see LOS_MemboxAlloc */ -extern UINT32 LOS_MemboxFree(const VOID *boxMem, VOID *box); +extern UINT32 LOS_MemboxFree(VOID *pool, VOID *box); /** * @ingroup los_membox @@ -154,11 +183,11 @@ extern UINT32 LOS_MemboxFree(const VOID *boxMem, VOID *box); * @attention *
      *
    • The input pool parameter must be initialized via func LOS_MemboxInit.
    • - *
    • The input pBox parameter must be allocated by LOS_MemboxAlloc.
    • + *
    • The input box parameter must be allocated by LOS_MemboxAlloc.
    • *
    * - * @param boxMem [IN] Memory pool address. - * @param box [IN] Memory block address. + * @param pool [IN] Memory pool address. + * @param box [IN] Memory block address. * * @retval VOID * @par Dependency: @@ -167,8 +196,31 @@ extern UINT32 LOS_MemboxFree(const VOID *boxMem, VOID *box); * * @see None. */ -extern VOID LOS_MemboxClr(const VOID *boxMem, VOID *box); +extern VOID LOS_MemboxClr(VOID *pool, VOID *box); +/** + * @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. + */ +extern VOID LOS_ShowBox(VOID *pool); /** * @ingroup los_membox @@ -180,8 +232,8 @@ extern VOID LOS_MemboxClr(const VOID *boxMem, VOID *box); * * @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 boxMem [IN] Type #VOID* Pointer to the calculate membox. @@ -197,18 +249,10 @@ extern VOID LOS_MemboxClr(const VOID *boxMem, VOID *box); */ extern UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize); -#define OS_MEMBOX_NEXT(addr, blkSize) (LOS_MEMBOX_NODE *)((UINT8 *)(addr) + (blkSize)) +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ -#ifdef LOS_MEMBOX_CHECK -#define OS_MEMBOX_MAGIC 0xa55a5aa5 -#define OS_MEMBOX_SET_MAGIC(addr) (*((UINT32 *)(addr)) = OS_MEMBOX_MAGIC) -#define OS_MEMBOX_CHECK_MAGIC(addr) ((*((UINT32 *)(addr)) == OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK) -#else -#define OS_MEMBOX_SET_MAGIC(addr) -#define OS_MEMBOX_CHECK_MAGIC(addr) LOS_OK -#endif - -#define OS_MEMBOX_USER_ADDR(addr) ((VOID *)((UINT8 *)(addr) + LOS_MEMBOX_MAGIC_SIZE)) -#define OS_MEMBOX_NODE_ADDR(addr) ((LOS_MEMBOX_NODE *)((UINT8 *)(addr) - LOS_MEMBOX_MAGIC_SIZE)) - -#endif +#endif /* _LOS_MEMBOX_H */ diff --git a/kernel/include/los_memory.h b/kernel/include/los_memory.h old mode 100644 new mode 100755 index e6656f1b..667b6956 --- a/kernel/include/los_memory.h +++ b/kernel/include/los_memory.h @@ -39,6 +39,7 @@ #include "los_config.h" #include "los_list.h" +#include "los_debug.h" #ifdef __cplusplus #if __cplusplus @@ -46,33 +47,53 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -#ifdef LOSCFG_MEM_LEAKCHECK - -/** - * @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 - -/** - * @ingroup los_memory - * The recored layes of function call. - */ -#define LOS_RECORD_LR_CNT 3 +#if (LOSCFG_PLATFORM_EXC == 1) +UINT32 OsMemExcInfoGet(UINT32 memNumMax, MemInfoCB *memExcInfo); #endif /** * @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
    • - *
    + * Starting address of the memory. */ -#ifdef LOSCFG_MEM_WATERLINE -#define OS_MEM_WATERLINE NO +#define OS_SYS_MEM_ADDR LOSCFG_SYS_HEAP_ADDR + +#if (LOSCFG_MEM_LEAKCHECK == 1) + +/** + * @ingroup los_memory + * The default is 5, which means that the function call stack is recorded from the kernel interface, + * such as LOS_MemAlloc/LOS_MemAllocAlign/LOS_MemRealloc/LOS_MemFree. If you want to further ignore + * the number of function call layers, you can increase this value appropriately. + * + */ +#define LOS_OMIT_LR_CNT 5 + +/** + * @ingroup los_memory + * The record number of layers of the function call relationship starting from the number of + * ignored layers(LOS_OMIT_LR_CNT). + */ +#define LOS_RECORD_LR_CNT 3 + +/** + * @ingroup los_memory + * @brief Print function call stack information of all used nodes. + * + * @par Description: + *
      + *
    • This API is used to print function call stack information of all used nodes.
    • + *
    + * + * @param pool [IN] Starting address of memory. + * + * @retval none. + * @par Dependency: + *
      + *
    • los_memory.h: the header file that contains the API declaration.
    • + *
    + * @see None. + */ +extern VOID LOS_MemUsedNodeShow(VOID *pool); #endif #if (LOSCFG_MEM_MUL_POOL == 1) @@ -126,7 +147,7 @@ typedef struct { UINT32 maxFreeNodeSize; UINT32 usedNodeNum; UINT32 freeNodeNum; -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) +#if (LOSCFG_MEM_WATERLINE == 1) UINT32 usageWaterLine; #endif } LOS_MEM_POOL_STATUS; @@ -396,6 +417,33 @@ extern UINT32 LOS_MemFreeNodeShow(VOID *pool); */ extern UINT32 LOS_MemIntegrityCheck(const VOID *pool); +/** + * @ingroup los_memory + * @brief Enable memory pool to support no internal lock during using interfaces. + * + * @par Description: + *
      + *
    • This API is used to enable memory pool to support no internal lock during using interfaces,
    • + *
    • such as LOS_MemAlloc/LOS_MemAllocAlign/LOS_MemRealloc/LOS_MemFree and so on. + *
    + * @attention + *
      + *
    • The memory pool does not support multi-threaded concurrent application scenarios. + *
    • If you want to use this function, you need to call this interface before the memory + * pool is used, it cannot be called during the trial period.
    • + *
    + * + * @param pool [IN] Starting address of memory. + * + * @retval node. + * @par Dependency: + *
      + *
    • los_memory.h: the header file that contains the API declaration.
    • + *
    + * @see None. + */ +extern VOID LOS_MemUnlockEnable(VOID *pool); + extern UINT32 OsMemSystemInit(VOID); #ifdef __cplusplus diff --git a/kernel/include/los_swtmr.h b/kernel/include/los_swtmr.h old mode 100644 new mode 100755 index e38f81f6..bce51ff9 --- a/kernel/include/los_swtmr.h +++ b/kernel/include/los_swtmr.h @@ -273,7 +273,7 @@ typedef struct tagSwTmrCtrl { UINT8 ucRouses; /* wake up enable */ UINT8 ucSensitive; /* align enable */ #endif - UINT16 usTimerID; /* Software timer ID */ + UINT32 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 @@ -293,8 +293,7 @@ typedef struct tagSwTmrCtrl { *
  • 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]. + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. * * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. @@ -304,7 +303,7 @@ typedef struct tagSwTmrCtrl { *
    • los_swtmr.h: the header file that contains the API declaration.
    * @see LOS_SwtmrStop | LOS_SwtmrCreate */ -extern UINT32 LOS_SwtmrStart(UINT16 swtmrID); +extern UINT32 LOS_SwtmrStart(UINT32 swtmrID); /** * @ingroup los_swtmr @@ -317,8 +316,7 @@ extern UINT32 LOS_SwtmrStart(UINT16 swtmrID); *
  • 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]. + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. * * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. @@ -329,7 +327,7 @@ extern UINT32 LOS_SwtmrStart(UINT16 swtmrID); *
    • los_swtmr.h: the header file that contains the API declaration.
    * @see LOS_SwtmrStart | LOS_SwtmrCreate */ -extern UINT32 LOS_SwtmrStop(UINT16 swtmrID); +extern UINT32 LOS_SwtmrStop(UINT32 swtmrID); /** * @ingroup los_swtmr @@ -343,8 +341,7 @@ extern UINT32 LOS_SwtmrStop(UINT16 swtmrID); *
  • 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 swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. * @param tick [OUT] Number of remaining Ticks configured on the software timer. * * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. @@ -356,7 +353,7 @@ extern UINT32 LOS_SwtmrStop(UINT16 swtmrID); *
    • los_swtmr.h: the header file that contains the API declaration.
    * @see LOS_SwtmrCreate */ -extern UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick); +extern UINT32 LOS_SwtmrTimeGet(UINT32 swtmrID, UINT32 *tick); /** * @ingroup los_swtmr @@ -395,7 +392,7 @@ extern UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick); extern UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, - UINT16 *swtmrID, + UINT32 *swtmrID, UINT32 arg, UINT8 rouses, UINT8 sensitive); @@ -403,7 +400,7 @@ extern UINT32 LOS_SwtmrCreate(UINT32 interval, extern UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, - UINT16 *swtmrID, + UINT32 *swtmrID, UINT32 arg); #endif @@ -418,8 +415,7 @@ extern UINT32 LOS_SwtmrCreate(UINT32 interval, *
  • 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]. + * @param swtmrID [IN] Software timer ID created by LOS_SwtmrCreate. * * @retval #LOS_ERRNO_SWTMR_ID_INVALID Invalid software timer ID. * @retval #LOS_ERRNO_SWTMR_NOT_CREATED The software timer is not created. @@ -429,7 +425,7 @@ extern UINT32 LOS_SwtmrCreate(UINT32 interval, *
    • los_swtmr.h: the header file that contains the API declaration.
    * @see LOS_SwtmrCreate */ -extern UINT32 LOS_SwtmrDelete(UINT16 swtmrID); +extern UINT32 LOS_SwtmrDelete(UINT32 swtmrID); /** * @ingroup los_swtmr diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h old mode 100644 new mode 100755 index 3e13c610..d3d135aa --- a/kernel/include/los_task.h +++ b/kernel/include/los_task.h @@ -1517,6 +1517,24 @@ extern UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 ta */ #define OS_TSK_SORTLINK_LEN 32 +/** + * @ingroup los_task + * @brief the num of high-order bit + */ +#define OS_TSK_HIGH_BITS 5U + +/** + * @ingroup los_task + * @brief the num of low-order bit + */ +#define OS_TSK_LOW_BITS (32U - OS_TSK_HIGH_BITS) + +/** + * @ingroup los_task + * @brief the max num of roll + */ +#define OS_TSK_MAX_ROLLNUM (0xFFFFFFFFU - OS_TSK_SORTLINK_LEN) + /** * @ingroup los_task * @brief the bit width occupied by the delayed ticks of task @@ -1527,7 +1545,19 @@ extern UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 ta * @ingroup los_task * @brief the mask of delayed tasks bucket id. */ -#define OS_TSK_SORTLINK_MASK (OS_TSK_SORTLINK_LEN - 1) +#define OS_TSK_SORTLINK_MASK (OS_TSK_SORTLINK_LEN - 1U) + +/** + * @ingroup los_task + * @brief the high-order mask of roll num. + */ +#define OS_TSK_HIGH_BITS_MASK (OS_TSK_SORTLINK_MASK << OS_TSK_LOW_BITS) + +/** + * @ingroup los_task + * @brief the low-order mask of roll num. + */ +#define OS_TSK_LOW_BITS_MASK (~OS_TSK_HIGH_BITS_MASK) /** * @ingroup los_task @@ -1620,9 +1650,9 @@ typedef struct { } LosTask; typedef struct { - LOS_DL_LIST *sortLink; - UINT16 cursor; - UINT16 unused; + LOS_DL_LIST *sortLink; + UINT16 cursor; + UINT16 reserved; } TaskSortLinkAttr; /** @@ -1650,8 +1680,11 @@ typedef struct { TaskCountInfo cntInfo; UINT16 pid[OS_TASK_SWITCH_INFO_COUNT]; CHAR name[OS_TASK_SWITCH_INFO_COUNT][LOS_TASK_NAMELEN]; -}TaskSwitchInfo; +} TaskSwitchInfo; +#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) +extern TaskSwitchInfo g_taskSwitchInfo; +#endif extern LosTask g_losTask; diff --git a/kernel/src/los_init.c b/kernel/src/los_init.c old mode 100644 new mode 100755 index 204b8f25..bf932d40 --- a/kernel/src/los_init.c +++ b/kernel/src/los_init.c @@ -54,14 +54,16 @@ #include "los_cpup.h" #endif +#if (LOSCFG_PLATFORM_EXC == 1) +#include "los_exc_info.h" +#endif + #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cpluscplus */ #endif /* __cpluscplus */ -UINT8 *m_aucSysMem0; - /***************************************************************************** Function : LOS_Reboot Description : system exception, die in here, wait for watchdog. @@ -71,6 +73,7 @@ UINT8 *m_aucSysMem0; *****************************************************************************/ LITE_OS_SEC_TEXT_INIT VOID LOS_Reboot(VOID) { + OsDoExcHook(EXC_REBOOT); HalSysExit(); } @@ -103,8 +106,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_Start(VOID) return HalStartSchedule(OsTickHandler); } -extern UINT8 g_memStart[OS_SYS_MEM_SIZE]; - /***************************************************************************** Function : LOS_KernelInit Description : System kernel initialization function, configure all system modules @@ -115,11 +116,9 @@ extern UINT8 g_memStart[OS_SYS_MEM_SIZE]; LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID) { UINT32 ret; - printf("entering kernel init...\n"); + PRINTK("entering kernel init...\n"); OsRegister(); - m_aucSysMem0 = g_memStart; - g_sysMemAddrEnd = ((UINT32)OS_SYS_MEM_ADDR + OS_SYS_MEM_SIZE); ret = OsMemSystemInit(); if (ret != LOS_OK) { PRINT_ERR("OsMemSystemInit error %d\n", ret); @@ -193,13 +192,10 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID) } #endif -#ifdef LOSCFG_TEST - //ret = los_TestInit(); - //if (ret != LOS_OK) { - // PRINT_ERR("los_TestInit error\n"); - // return ret; - //} +#if (LOSCFG_PLATFORM_EXC == 1) + OsExcMsgDumpInit(); #endif + return LOS_OK; } diff --git a/kernel/src/los_queue.c b/kernel/src/los_queue.c old mode 100644 new mode 100755 index 97bffaf0..66320371 --- a/kernel/src/los_queue.c +++ b/kernel/src/los_queue.c @@ -34,12 +34,9 @@ #include "los_membox.h" #include "los_task.h" #include "los_memory.h" -#if (LOSCFG_PLATFORM_EXC == 1) #include "los_interrupt.h" -#endif #include "los_debug.h" - #ifdef __cplusplus #if __cplusplus extern "C" { @@ -50,9 +47,6 @@ extern "C" { LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL ; LITE_OS_SEC_BSS LOS_DL_LIST g_freeQueueList; -#if (LOSCFG_PLATFORM_EXC == 1) -LITE_OS_SEC_BSS UINT32 g_excQueueMaxNum; -#endif /************************************************************************** Function : OsQueueInit @@ -85,11 +79,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID) LOS_ListTailInsert(&g_freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]); } -#if (LOSCFG_PLATFORM_EXC == 1) - g_excQueueMaxNum = LOSCFG_BASE_IPC_QUEUE_LIMIT; - HalExcRegister(OS_EXC_TYPE_QUE, (EXC_INFO_SAVE_CALLBACK)LOS_QueueInfoGet, &g_excQueueMaxNum); -#endif - return LOS_OK; } diff --git a/kernel/src/los_sem.c b/kernel/src/los_sem.c old mode 100644 new mode 100755 index b1eacbc3..e9b89420 --- a/kernel/src/los_sem.c +++ b/kernel/src/los_sem.c @@ -32,9 +32,7 @@ #include "los_arch.h" #include "los_sem.h" #include "los_memory.h" -#if (LOSCFG_PLATFORM_EXC == 1) #include "los_interrupt.h" -#endif #include "los_debug.h" #ifdef __cplusplus diff --git a/kernel/src/los_swtmr.c b/kernel/src/los_swtmr.c old mode 100644 new mode 100755 index f0f867fa..82fcccf0 --- a/kernel/src/los_swtmr.c +++ b/kernel/src/los_swtmr.c @@ -64,8 +64,8 @@ static SWTMR_CTRL_S *g_swtmrRouses = NULL; /* first swtmr tha static SWTMR_CTRL_S *g_swtmrRousesPrev = NULL; #endif -#define SWTMR_MAX_RUNNING_TICKS 2 - +#define SWTMR_MAX_RUNNING_TICKS 2 +#define OS_SWTMR_MAX_TIMERID ((0xFFFFFFFF / LOSCFG_BASE_CORE_SWTMR_LIMIT) * LOSCFG_BASE_CORE_SWTMR_LIMIT) /***************************************************************************** Function : OsSwtmrTask @@ -182,7 +182,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) } #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) -STATIC_INLINE UINT32 OsSwtmrCalcAlignCount(UINT32 interval, UINT16 timerId) +STATIC_INLINE UINT32 OsSwtmrCalcAlignCount(UINT32 interval, UINT32 timerId) { SWTMR_CTRL_S *cur = g_swtmrSortList; UINT32 count = 0; @@ -600,7 +600,7 @@ Return : LOS_OK on success or error code on failure LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, - UINT16 *swtmrId, + UINT32 *swtmrId, UINT32 arg, UINT8 rouses, UINT8 sensitive) @@ -608,7 +608,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, - UINT16 *swtmrId, + UINT32 *swtmrId, UINT32 arg) #endif { @@ -675,7 +675,7 @@ Input : swtmrId ------- Software timer ID Output : None Return : LOS_OK on success or error code on failure *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrId) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT32 swtmrId) { SWTMR_CTRL_S *swtmr = NULL; UINTPTR intSave; @@ -735,7 +735,7 @@ Input : swtmrId ------- Software timer ID Output : None Return : LOS_OK on success or error code on failure *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT32 swtmrId) { SWTMR_CTRL_S *swtmr = NULL; UINTPTR intSave; @@ -772,7 +772,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId) return ret; } -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrId, UINT32 *tick) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT32 swtmrId, UINT32 *tick) { SWTMR_CTRL_S *swtmr = NULL; UINTPTR intSave; @@ -820,7 +820,7 @@ Input : swtmrId ------- Software timer ID Output : None Return : LOS_OK on success or error code on failure *****************************************************************************/ -LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrId) +LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT32 swtmrId) { SWTMR_CTRL_S *swtmr = NULL; UINTPTR intSave; diff --git a/kernel/src/los_task.c b/kernel/src/los_task.c old mode 100644 new mode 100755 index 1a370bf0..dc017313 --- a/kernel/src/los_task.c +++ b/kernel/src/los_task.c @@ -30,16 +30,15 @@ */ #include "los_config.h" #include "securec.h" -#include "los_sem.h" -#include "los_mux.h" #include "los_memory.h" +#include "los_mux.h" +#include "los_sem.h" #include "los_timer.h" #include "los_interrupt.h" #if (LOSCFG_BASE_CORE_CPUP == 1) #include "los_cpup.h" #endif #include "los_debug.h" - #ifdef __cplusplus #if __cplusplus extern "C" { @@ -51,20 +50,20 @@ extern "C" { * @brief Convinence macro for bitwise operation of task module */ #define EVALUATE_L(NUMBER, VALUE) \ - ((NUMBER) = (((NUMBER) & 0xf8000000) | (VALUE))) + ((NUMBER) = (((NUMBER) & OS_TSK_HIGH_BITS_MASK) | (VALUE))) #define EVALUATE_H(NUMBER, VALUE) \ - ((NUMBER) = (((NUMBER) & 0x07ffffff) | ((VALUE) << 27))) + ((NUMBER) = (((NUMBER) & OS_TSK_LOW_BITS_MASK) | ((VALUE) << OS_TSK_LOW_BITS))) #define UWROLLNUMSUB(NUMBER1, NUMBER2) \ - ((NUMBER1) = (((NUMBER1) & 0xf8000000) | (UWROLLNUM(NUMBER1) - UWROLLNUM(NUMBER2)))) + ((NUMBER1) = (((NUMBER1) & OS_TSK_HIGH_BITS_MASK) | (UWROLLNUM(NUMBER1) - UWROLLNUM(NUMBER2)))) #define UWROLLNUMADD(NUMBER1, NUMBER2) \ - ((NUMBER1) = (((NUMBER1) & 0xf8000000) | (UWROLLNUM(NUMBER1) + UWROLLNUM(NUMBER2)))) + ((NUMBER1) = (((NUMBER1) & OS_TSK_HIGH_BITS_MASK) | (UWROLLNUM(NUMBER1) + UWROLLNUM(NUMBER2)))) -#define UWROLLNUM(NUMBER) ((NUMBER) & 0x07ffffff) +#define UWROLLNUM(NUMBER) ((NUMBER) & OS_TSK_LOW_BITS_MASK) -#define UWSORTINDEX(NUMBER) ((NUMBER) >> 27) +#define UWSORTINDEX(NUMBER) ((NUMBER) >> OS_TSK_LOW_BITS) #define UWROLLNUMDEC(NUMBER) \ ((NUMBER) = ((NUMBER) - 1)) @@ -116,7 +115,6 @@ TSKSWITCHHOOK g_pfnUsrTskSwitchHook = NULL; #endif /* LOSCFG_BASE_CORE_TSK_MONITOR == 1 */ #if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1) - TaskSwitchInfo g_taskSwitchInfo; #endif @@ -209,6 +207,28 @@ STATIC VOID OsRecyleFinishedTask(VOID) LOS_IntRestore(intSave); } +UINT32 OsTaskNextSwitchTimeGet(VOID) +{ + LosTaskCB *taskCB = NULL; + UINT32 taskSortLinkTick = LOS_WAIT_FOREVER; + LOS_DL_LIST *listObject = NULL; + UINT32 tempTicks; + UINT32 index; + + for (index = 0; index < OS_TSK_SORTLINK_LEN; index++) { + listObject = g_taskSortLink.sortLink + ((g_taskSortLink.cursor + index) % OS_TSK_SORTLINK_LEN); + if (!LOS_ListEmpty(listObject)) { + taskCB = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList); + tempTicks = (index == 0) ? OS_TSK_SORTLINK_LEN : index; + tempTicks += (UINT32)(UWROLLNUM((UINT32)taskCB->idxRollNum) * OS_TSK_SORTLINK_LEN); + if (taskSortLinkTick > tempTicks) { + taskSortLinkTick = tempTicks; + } + } + } + return taskSortLinkTick; +} + /***************************************************************************** Function : OsIdleTask Description : Idle task. @@ -495,6 +515,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsPrintAllTskInfoHeader() *****************************************************************************/ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID) { +#if (LOSCFG_KERNEL_PRINTF != 0) LosTaskCB *taskCB = (LosTaskCB *)NULL; UINT32 loopNum; UINT32 semID; @@ -551,7 +572,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID) (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuTenSec); (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuOneSec); #endif - +#endif return LOS_OK; } @@ -612,9 +633,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID) LOS_ListInit(listObject); } -#if (LOSCFG_PLATFORM_EXC == 1) - HalExcRegister((ExcInfoType)OS_EXC_TYPE_TSK, (EXC_INFO_SAVE_CALLBACK)LOS_TaskInfoGet, &g_taskMaxNum); -#endif return LOS_OK; } @@ -693,6 +711,50 @@ LITE_OS_SEC_TEXT CHAR *LOS_CurTaskNameGet(VOID) return taskName; } +#if (LOSCFG_BASE_CORE_TSK_MONITOR == 1) +#if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == 0) +/***************************************************************************** + Function : OsHandleRunTaskStackOverflow + Description : handle stack overflow exception of the run task. + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT STATIC VOID OsHandleRunTaskStackOverflow(VOID) +{ + PRINT_ERR("CURRENT task ID: %s:%d stack overflow!\n", + g_losTask.runTask->taskName, g_losTask.runTask->taskID); + OsDoExcHook(EXC_STACKOVERFLOW); +} + +/***************************************************************************** + Function : OsHandleNewTaskStackOverflow + Description : handle stack overflow exception of the new task. + Input : None + Output : None + Return : None + *****************************************************************************/ +LITE_OS_SEC_TEXT STATIC VOID OsHandleNewTaskStackOverflow(VOID) +{ + LosTaskCB *tmp = NULL; + + PRINT_ERR("HIGHEST task ID: %s:%d SP error!\n", + g_losTask.newTask->taskName, g_losTask.newTask->taskID); + PRINT_ERR("HIGHEST task StackPointer: 0x%x TopOfStack: 0x%x\n", + (UINT32)(UINTPTR)(g_losTask.newTask->stackPointer), g_losTask.newTask->topOfStack); + + /* + * make sure LOS_CurTaskIDGet and LOS_CurTaskNameGet returns the ID and name of which task + * that occurred stack overflow exception in OsDoExcHook temporary. + */ + tmp = g_losTask.runTask; + g_losTask.runTask = g_losTask.newTask; + OsDoExcHook(EXC_STACKOVERFLOW); + g_losTask.runTask = tmp; +} +#endif +#endif + /***************************************************************************** Function : OsTaskSwitchCheck Description : Check task switch @@ -703,19 +765,16 @@ LITE_OS_SEC_TEXT CHAR *LOS_CurTaskNameGet(VOID) #if (LOSCFG_BASE_CORE_TSK_MONITOR == 1) LITE_OS_SEC_TEXT VOID OsTaskSwitchCheck(VOID) { + UINTPTR intSave = LOS_IntLock(); #if (LOSCFG_EXC_HRADWARE_STACK_PROTECTION == 0) UINT32 endOfStack = g_losTask.newTask->topOfStack + g_losTask.newTask->stackSize; if ((*(UINT32 *)(UINTPTR)(g_losTask.runTask->topOfStack)) != OS_TASK_MAGIC_WORD) { - PRINT_ERR("CURRENT task ID: %s:%d stack overflow!\n", - g_losTask.runTask->taskName, g_losTask.runTask->taskID); + OsHandleRunTaskStackOverflow(); } if (((UINT32)(UINTPTR)(g_losTask.newTask->stackPointer) <= (g_losTask.newTask->topOfStack)) || ((UINT32)(UINTPTR)(g_losTask.newTask->stackPointer) > endOfStack)) { - PRINT_ERR("HIGHEST task ID: %s:%d SP error!\n", - g_losTask.newTask->taskName, g_losTask.newTask->taskID); - PRINT_ERR("HIGHEST task StackPointer: 0x%x TopOfStack: 0x%x\n", - (UINT32)(UINTPTR)(g_losTask.newTask->stackPointer), g_losTask.newTask->topOfStack); + OsHandleNewTaskStackOverflow(); } #endif @@ -747,6 +806,7 @@ LITE_OS_SEC_TEXT VOID OsTaskSwitchCheck(VOID) #if (LOSCFG_BASE_CORE_CPUP == 1) OsTskCycleEndStart(); #endif /* LOSCFG_BASE_CORE_CPUP */ + LOS_IntRestore(intSave); } LITE_OS_SEC_TEXT_MINOR VOID OsTaskMonInit(VOID) @@ -755,11 +815,6 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMonInit(VOID) // Ignore the return code when matching CSEC rule 6.6(4). (VOID)memset_s(&g_taskSwitchInfo, sizeof(TaskSwitchInfo), 0, sizeof(TaskSwitchInfo)); g_taskSwitchInfo.cntInfo.maxCnt = OS_TASK_SWITCH_INFO_COUNT; -#if (LOSCFG_PLATFORM_EXC == 1) - HalExcRegister((ExcInfoType)OS_EXC_TYPE_TSK_SWITCH, - (EXC_INFO_SAVE_CALLBACK)LOS_TaskSwitchInfoGet, - &g_taskSwitchInfo); -#endif #endif g_pfnUsrTskSwitchHook = NULL; return; @@ -813,7 +868,7 @@ LITE_OS_SEC_TEXT_INIT STATIC_INLINE UINT32 OsTaskInitParamCheck(TSK_INIT_PARAM_S return LOS_ERRNO_TSK_PRIOR_ERROR; } - if (taskInitParam->uwStackSize > OS_SYS_MEM_SIZE) { + if (taskInitParam->uwStackSize > LOSCFG_SYS_HEAP_SIZE) { return LOS_ERRNO_TSK_STKSZ_TOO_LARGE; } @@ -1601,6 +1656,8 @@ VOID LOS_Schedule(VOID) LOS_IntRestore(intSave); } + + #if (LOSCFG_BASE_CORE_TIMESLICE == 1) LITE_OS_SEC_BSS OsTaskRobin g_taskTimeSlice; diff --git a/kernel/src/los_tick.c b/kernel/src/los_tick.c old mode 100644 new mode 100755 index df5761f1..ab01331d --- a/kernel/src/los_tick.c +++ b/kernel/src/los_tick.c @@ -30,9 +30,9 @@ */ #include "los_tick.h" +#include "los_config.h" #include "los_task.h" #include "los_swtmr.h" -#include "los_config.h" #ifdef __cplusplus #if __cplusplus diff --git a/kernel/src/mm/los_membox.c b/kernel/src/mm/los_membox.c old mode 100644 new mode 100755 index 0447a3fb..f007aa8d --- a/kernel/src/mm/los_membox.c +++ b/kernel/src/mm/los_membox.c @@ -29,182 +29,303 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "los_membox.h" #include "securec.h" #include "los_interrupt.h" #include "los_context.h" -#include "los_membox.h" -#include "los_memory.h" #include "los_debug.h" +#include "los_task.h" -#if (LOSCFG_PLATFORM_EXC == 0) || (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) -UINT8 g_memMang[MEM_INFO_SIZE]; -#endif +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ -UINT32 LOS_MemboxInit(VOID *boxMem, UINT32 boxSize, UINT32 blkSize) +/* The magic length is 32 bits, the lower 8 bits are used to save the owner task ID, + and the other 24 bits are used to set the magic number for verification. */ +#define OS_MEMBOX_MAGIC 0xa55a5a00 +#define OS_MEMBOX_TASKID_BITS 8 +#define OS_MEMBOX_MAX_TASKID ((1 << OS_MEMBOX_TASKID_BITS) - 1) +#define OS_MEMBOX_TASKID_GET(addr) (((UINTPTR)(addr)) & OS_MEMBOX_MAX_TASKID) + +STATIC INLINE VOID OsMemBoxSetMagic(LOS_MEMBOX_NODE *node) { - UINTPTR intSave; -#ifdef LOS_MEMBOX_CHECK - UINT32 *memCount = (UINT32 *)g_memMang; - MEM_INFO *memInfo = (MEM_INFO *)(g_memMang + sizeof(UINT32)); - UINT8 loop; -#endif + UINT8 taskID = (UINT8)LOS_CurTaskIDGet(); + node->pstNext = (LOS_MEMBOX_NODE *)(OS_MEMBOX_MAGIC | taskID); +} - if (boxMem == NULL) { - return OS_ERROR; +STATIC INLINE UINT32 OsMemBoxCheckMagic(LOS_MEMBOX_NODE *node) +{ + UINT32 taskID = OS_MEMBOX_TASKID_GET(node->pstNext); + if (taskID > (LOSCFG_BASE_CORE_TSK_LIMIT + 1)) { + return LOS_NOK; + } else { + return (node->pstNext == (LOS_MEMBOX_NODE *)(OS_MEMBOX_MAGIC | taskID)) ? 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)) +#define MEMBOX_LOCK(state) ((state) = HalIntLock()) +#define MEMBOX_UNLOCK(state) HalIntRestore(state) + +STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node) +{ + UINT32 offset; + + if (boxInfo->uwBlkSize == 0) { + return LOS_NOK; + } + + offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1)); + if ((offset % boxInfo->uwBlkSize) != 0) { + return LOS_NOK; + } + + if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) { + return LOS_NOK; + } + + return OsMemBoxCheckMagic((LOS_MEMBOX_NODE *)node); +} + +#if (LOSCFG_PLATFORM_EXC == 1) +STATIC LOS_MEMBOX_INFO *g_memBoxHead = NULL; +STATIC VOID OsMemBoxAdd(VOID *pool) +{ + LOS_MEMBOX_INFO *nextPool = g_memBoxHead; + LOS_MEMBOX_INFO *curPool = NULL; + + while (nextPool != NULL) { + curPool = nextPool; + nextPool = nextPool->nextMemBox; + } + + if (curPool == NULL) { + g_memBoxHead = pool; + } else { + curPool->nextMemBox = pool; + } + + ((LOS_MEMBOX_INFO *)pool)->nextMemBox = NULL; +} +#endif + +UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + UINT32 index; + UINT32 intSave; + + if (pool == NULL) { + return LOS_NOK; } - /* Initialize memory block system, returns 0 if OK, 1 if fails. */ if (blkSize == 0) { - return OS_ERROR; - } - if (boxSize == 0) { - return OS_ERROR; + return LOS_NOK; } -#ifdef LOS_MEMBOX_CHECK - intSave = LOS_IntLock(); - for (loop = 0; loop < *memCount; loop++) { - if (memInfo->uwStartAddr == (UINTPTR)boxMem) { - (*memCount)--; - break; - } - memInfo++; + if (poolSize < sizeof(LOS_MEMBOX_INFO)) { + return LOS_NOK; } - if (*memCount < OS_SYS_MEM_NUM) { - memInfo->uwType = MEM_MANG_MEMBOX; - memInfo->uwStartAddr = (UINTPTR)boxMem; - memInfo->uwSize = boxSize; - UINT32 allocSize = boxSize / blkSize * sizeof(VOID *); - VOID *ptr = LOS_MemAlloc(m_aucSysMem0, allocSize); - if (ptr == NULL) { - PRINT_ERR("LOS_MemAlloc return fail!\n"); - return LOS_NOK; - } else { - UINT32 ret = memset_s(ptr, allocSize, 0, allocSize); - if (ret != LOS_OK) { - (VOID)LOS_MemFree(m_aucSysMem0, ptr); - PRINT_ERR("memset return fail!\n"); - return LOS_NOK; - } - } - memInfo->blkAddrArray = ptr; - (*memCount)++; + + MEMBOX_LOCK(intSave); + boxInfo->uwBlkSize = LOS_MEMBOX_ALLIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); + if (boxInfo->uwBlkSize == 0) { + MEMBOX_UNLOCK(intSave); + return LOS_NOK; } - LOS_IntRestore(intSave); + boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize; + boxInfo->uwBlkCnt = 0; + if (boxInfo->uwBlkNum == 0) { + MEMBOX_UNLOCK(intSave); + return LOS_NOK; + } + + node = (LOS_MEMBOX_NODE *)(boxInfo + 1); + + boxInfo->stFreeList.pstNext = node; + + for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) { + node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize); + node = node->pstNext; + } + + node->pstNext = NULL; + +#if (LOSCFG_PLATFORM_EXC == 1) + OsMemBoxAdd(pool); #endif - /* Create a Memory structure. */ - intSave = LOS_IntLock(); - ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk = boxSize / blkSize; - ((OS_MEMBOX_S_P)boxMem)->uwBlkSize = blkSize; - ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt = 0; - LOS_IntRestore(intSave); + MEMBOX_UNLOCK(intSave); return LOS_OK; } -/* --------------------------- LOS_MemboxAlloc ---------------------------------- */ -VOID *LOS_MemboxAlloc(VOID *boxMem) +VOID *LOS_MemboxAlloc(VOID *pool) { - VOID *ret = NULL; - UINTPTR intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + LOS_MEMBOX_NODE *nodeTmp = NULL; + UINT32 intSave; - if (boxMem == NULL) { + if (pool == NULL) { return NULL; } - intSave = LOS_IntLock(); - if (((OS_MEMBOX_S_P)boxMem)->uwBlkCnt < ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk) { - ret = LOS_MemAlloc(m_aucSysMem0, ((OS_MEMBOX_S_P)boxMem)->uwBlkSize); - if (ret != NULL) { - ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt++; -#ifdef LOS_MEMBOX_CHECK - UINT32 *memCount = (UINT32 *)g_memMang; - MEM_INFO *memInfo = (MEM_INFO *)(VOID *)(g_memMang + sizeof(UINT32)); - UINT8 loop; - UINT8 idx; - for (loop = 0; loop < *memCount; loop++) { - if (memInfo->uwStartAddr == (UINTPTR)boxMem) { - if (memInfo->blkAddrArray != NULL) { - for (idx = 0; idx < ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk; idx++) { - if (((VOID **)(memInfo->blkAddrArray))[idx] == NULL) { - ((VOID **)(memInfo->blkAddrArray))[idx] = ret; - break; - } - } - } - break; - } - memInfo++; - } -#endif - } else { - PRINT_ERR("LOS_AllocMem return fail!\n"); - } + + MEMBOX_LOCK(intSave); + node = &(boxInfo->stFreeList); + if (node->pstNext != NULL) { + nodeTmp = node->pstNext; + node->pstNext = nodeTmp->pstNext; + OsMemBoxSetMagic(nodeTmp); + boxInfo->uwBlkCnt++; } - LOS_IntRestore(intSave); + MEMBOX_UNLOCK(intSave); + + return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp); +} + +UINT32 LOS_MemboxFree(VOID *pool, VOID *box) +{ + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + UINT32 ret = LOS_NOK; + UINT32 intSave; + + if ((pool == NULL) || (box == NULL)) { + return LOS_NOK; + } + + MEMBOX_LOCK(intSave); + do { + LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box); + if (OsCheckBoxMem(boxInfo, node) != LOS_OK) { + break; + } + + node->pstNext = boxInfo->stFreeList.pstNext; + boxInfo->stFreeList.pstNext = node; + boxInfo->uwBlkCnt--; + ret = LOS_OK; + } while (0); + MEMBOX_UNLOCK(intSave); + return ret; } -/* --------------------------- LOS_MemboxFree ---------------------------------- */ -UINT32 LOS_MemboxFree(const VOID *boxMem, VOID *box) +VOID LOS_MemboxClr(VOID *pool, VOID *box) { - UINT32 freeRes; - UINTPTR intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; - if (boxMem == NULL) { - return LOS_NOK; - } - freeRes = LOS_MemFree(m_aucSysMem0, box); - if (freeRes == LOS_OK) { - intSave = LOS_IntLock(); - if (((OS_MEMBOX_S_P)boxMem)->uwBlkCnt) { - ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt--; -#ifdef LOS_MEMBOX_CHECK - UINT32 *memCount = (UINT32 *)g_memMang; - MEM_INFO *memInfo = (MEM_INFO *)(VOID *)(g_memMang + sizeof(UINT32)); - UINT8 loop; - UINT8 idx; - for (loop = 0; loop < *memCount; loop++) { - if (memInfo->uwStartAddr == (UINTPTR)boxMem) { - if (memInfo->blkAddrArray != NULL) { - for (idx = 0; idx < ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk; idx++) { - if (((VOID **)(memInfo->blkAddrArray))[idx] == box) { - ((VOID **)(memInfo->blkAddrArray))[idx] = NULL; - break; - } - } - } - break; - } - memInfo++; - } -#endif - } - LOS_IntRestore(intSave); - } - return freeRes; -} - -/* --------------------------- LOS_MemboxClr ---------------------------------- */ -VOID LOS_MemboxClr(const VOID *boxMem, VOID *box) -{ - if (boxMem == NULL || box == NULL) { + if ((pool == NULL) || (box == NULL)) { return; } - // Ignore the return code when matching CSEC rule 6.6(2). - (VOID)memset_s(box, ((OS_MEMBOX_S_P)boxMem)->uwBlkSize, 0, ((OS_MEMBOX_S_P)boxMem)->uwBlkSize); + + (VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0, + (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE)); } -UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, UINT32 *blkCnt, UINT32 *blkSize) +VOID LOS_ShowBox(VOID *pool) +{ + UINT32 index; + UINT32 intSave; + LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool; + LOS_MEMBOX_NODE *node = NULL; + + if (pool == NULL) { + return; + } + MEMBOX_LOCK(intSave); + PRINT_INFO("membox(0x%x,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum); + PRINT_INFO("free node list:\r\n"); + + for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL; + node = node->pstNext, ++index) { + PRINT_INFO("(%u,0x%x)\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,0x%x,0x%x)\r\n", index, node, node->pstNext); + } + MEMBOX_UNLOCK(intSave); +} + +UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk, + UINT32 *blkCnt, UINT32 *blkSize) { if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) { return LOS_NOK; } - *maxBlk = ((OS_MEMBOX_S_P)boxMem)->uwMaxBlk; - *blkCnt = ((OS_MEMBOX_S_P)boxMem)->uwBlkCnt; - *blkSize = ((OS_MEMBOX_S_P)boxMem)->uwBlkSize; + *maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum; + *blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt; + *blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize; return LOS_OK; } +#if (LOSCFG_PLATFORM_EXC == 1) +STATIC VOID OsMemboxExcInfoGetSub(const LOS_MEMBOX_INFO *pool, MemInfoCB *memExcInfo) +{ + LOS_MEMBOX_NODE *node = NULL; + UINTPTR poolStart, poolEnd; + UINT32 index; + UINT32 intSave; + + (VOID)memset_s(memExcInfo, sizeof(MemInfoCB), 0, sizeof(MemInfoCB)); + + MEMBOX_LOCK(intSave); + memExcInfo->type = MEM_MANG_MEMBOX; + memExcInfo->startAddr = (UINTPTR)pool; + memExcInfo->size = pool->uwBlkNum * pool->uwBlkSize; + memExcInfo->blockSize = pool->uwBlkSize; + memExcInfo->size = pool->uwBlkNum; /* Block num */ + memExcInfo->free = pool->uwBlkNum - pool->uwBlkCnt; + + poolStart = (UINTPTR)pool; + poolEnd = poolStart + pool->uwBlkSize * pool->uwBlkNum + sizeof(LOS_MEMBOX_INFO); + node = (LOS_MEMBOX_NODE *)(pool + 1); + for (index = 0; index < pool->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, pool->uwBlkSize)) { + if (((UINTPTR)node < poolStart) || ((UINTPTR)node >= poolEnd)) { + if (OsMemBoxCheckMagic(node)) { + memExcInfo->errorAddr = (UINT32)(UINTPTR)((CHAR *)node + OS_MEMBOX_NODE_HEAD_SIZE); + memExcInfo->errorLen = pool->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE; + memExcInfo->errorOwner = OS_MEMBOX_TASKID_GET(node->pstNext); + break; + } + } + } + MEMBOX_UNLOCK(intSave); +} + +UINT32 OsMemboxExcInfoGet(UINT32 memNumMax, MemInfoCB *memExcInfo) +{ + LOS_MEMBOX_INFO *memBox = g_memBoxHead; + UINT32 count = 0; + UINT8 *buffer = (UINT8 *)memExcInfo; + + while (memBox != NULL) { + OsMemboxExcInfoGetSub(memBox, (MemInfoCB *)buffer); + count++; + buffer += sizeof(MemInfoCB); + if (count >= memNumMax) { + break; + } + memBox = memBox->nextMemBox; + } + + return count; +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/kernel/src/mm/los_memory.c b/kernel/src/mm/los_memory.c old mode 100644 new mode 100755 index cf7fad9d..73499c4f --- a/kernel/src/mm/los_memory.c +++ b/kernel/src/mm/los_memory.c @@ -36,6 +36,7 @@ #include "los_memory.h" #include "los_task.h" #include "los_debug.h" +#include "los_timer.h" #ifdef LOSCFG_LIB_LIBC #endif @@ -46,11 +47,28 @@ extern "C" { #endif /* __cplusplus */ /* Used to cut non-essential functions. */ -#define OS_MEM_FREE_BY_TASKID 1 #define OS_MEM_EXPAND_ENABLE 0 -#define OS_MEM_TRACE 0 +#define OS_MEM_PRINT_DEBUG 0 -__attribute__((section(".data.init"))) UINT32 g_sysMemAddrEnd; +#if OS_MEM_PRINT_DEBUG +#define MEM_TRACE_MALLOC 0 +#define MEM_TRACE_FREE 1 +#define MEM_TRACE_MEMALIGN 2 +#define MEM_TRACE_REALLOC 3 + +STATIC INLINE UINT64 OsMemClockGetCycles(VOID) +{ + UINT32 cntHi, cntLo; + HalGetCpuCycle(&cntHi, &cntLo); + return (((UINT64)cntHi << 32) + cntLo); /* 32: 32 bits left to form 64 bits. */ +} +#endif + +UINT8 *m_aucSysMem0 = NULL; + +#if (LOSCFG_SYS_EXTERNAL_HEAP == 0) +STATIC UINT8 g_memStart[LOSCFG_SYS_HEAP_SIZE]; +#endif #if (LOSCFG_MEM_MUL_POOL == 1) VOID *g_poolHead = NULL; @@ -63,8 +81,9 @@ VOID *g_poolHead = NULL; /* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */ #define OS_MEM_SMALL_BUCKET_COUNT 31 #define OS_MEM_SMALL_BUCKET_MAX_SIZE 128 -/* Giving 2^OS_MEM_SLI free lists for each large bucket. */ +/* Giving OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ #define OS_MEM_LARGE_BUCKET_COUNT 24 +#define OS_MEM_FREE_LIST_NUM (1 << OS_MEM_SLI) /* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */ #define OS_MEM_LARGE_START_BUCKET 7 @@ -90,7 +109,7 @@ STATIC INLINE UINT16 OsMemFLS(UINT32 bitmap) STATIC INLINE UINT32 OsMemLog2(UINT32 size) { - return (size > 0) ? OsMemFLS(size) : 0; + return OsMemFLS(size); } /* Get the first level: f = log2(size). */ @@ -99,37 +118,38 @@ STATIC INLINE UINT32 OsMemFlGet(UINT32 size) if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { return ((size >> 2) - 1); /* 2: The small bucket setup is 4. */ } - return (OsMemLog2(size) - OS_MEM_LARGE_START_BUCKET + OS_MEM_SMALL_BUCKET_COUNT); + return OsMemLog2(size); } /* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) { - if ((fl < OS_MEM_SMALL_BUCKET_COUNT) || (size < OS_MEM_SMALL_BUCKET_MAX_SIZE)) { - PRINT_ERR("fl or size is too small, fl = %u, size = %u\n", fl, size); - return 0; - } - - UINT32 sl = (size << OS_MEM_SLI) >> (fl - OS_MEM_SMALL_BUCKET_COUNT + OS_MEM_LARGE_START_BUCKET); - return (sl - (1 << OS_MEM_SLI)); + return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); } /* The following is the memory algorithm related macro definition and interface implementation. */ struct OsMemNodeHead { +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) UINT32 magic; +#endif +#if (LOSCFG_MEM_LEAKCHECK == 1) + UINTPTR linkReg[LOS_RECORD_LR_CNT]; +#endif union { struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ - struct OsMemNodeHead *next; /* The next is used for last node points to the expand node */ + struct OsMemNodeHead *next; /* The next is used for sentinel node points to the expand node */ } ptr; +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) + UINT32 taskID : 6; + UINT32 sizeAndFlag : 26; +#else UINT32 sizeAndFlag; +#endif }; struct OsMemUsedNodeHead { struct OsMemNodeHead header; -#if OS_MEM_FREE_BY_TASKID - UINT32 taskID; -#endif }; struct OsMemFreeNodeHead { @@ -142,6 +162,10 @@ struct OsMemPoolInfo { VOID *pool; UINT32 totalSize; UINT32 attr; +#if (LOSCFG_MEM_WATERLINE == 1) + UINT32 waterLine; /* Maximum usage size in a memory pool */ + UINT32 curUsedSize; /* Current usage size in a memory pool */ +#endif }; struct OsMemPoolHead { @@ -153,22 +177,46 @@ struct OsMemPoolHead { #endif }; -/* Spinlock for mem module, only available on SMP mode */ -#define MEM_LOCK(pool, state) ((void)(pool), (state) = LOS_IntLock()) -#define MEM_UNLOCK(pool, state) ((void)(pool), LOS_IntRestore(state)) - /* The memory pool support expand. */ -#define OS_MEM_POOL_EXPAND_ENABLE 0x01 -/* The memory pool ssupport no lock. */ -#define OS_MEM_POOL_LOCK_ENABLE 0x02 +#define OS_MEM_POOL_EXPAND_ENABLE 0x01 +/* The memory pool support no lock. */ +#define OS_MEM_POOL_UNLOCK_ENABLE 0x02 -#define OS_MEM_NODE_MAGIC 0xABCDDCBA -#define OS_MEM_MIN_ALLOC_SIZE (sizeof(struct OsMemFreeNodeHead) - sizeof(struct OsMemUsedNodeHead)) +#define MEM_LOCK(pool, state) do { \ + if (!((pool)->info.attr & OS_MEM_POOL_UNLOCK_ENABLE)) { \ + (state) = LOS_IntLock(); \ + } \ +} while (0); +#define MEM_UNLOCK(pool, state) do { \ + if (!((pool)->info.attr & OS_MEM_POOL_UNLOCK_ENABLE)) { \ + LOS_IntRestore(state); \ + } \ +} while (0); -#define OS_MEM_NODE_USED_FLAG 0x80000000U -#define OS_MEM_NODE_ALIGNED_FLAG 0x40000000U -#define OS_MEM_NODE_LAST_FLAG 0x20000000U /* Sentinel Node */ -#define OS_MEM_NODE_ALIGNED_AND_USED_FLAG (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) +#define OS_MEM_NODE_MAGIC 0xABCDDCBA +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) +#define OS_MEM_NODE_USED_FLAG (1U << 25) +#define OS_MEM_NODE_ALIGNED_FLAG (1U << 24) +#define OS_MEM_NODE_LAST_FLAG (1U << 23) /* Sentinel Node */ +#if (LOSCFG_MEM_LEAKCHECK == 1) +#define OS_MEM_NODE_LEAK_FLAG (1U << 22) +#endif +#else +#define OS_MEM_NODE_USED_FLAG (1U << 31) +#define OS_MEM_NODE_ALIGNED_FLAG (1U << 30) +#define OS_MEM_NODE_LAST_FLAG (1U << 29) /* Sentinel Node */ +#if (LOSCFG_MEM_LEAKCHECK == 1) +#define OS_MEM_NODE_LEAK_FLAG (1U << 28) +#endif +#endif + +#if (LOSCFG_MEM_LEAKCHECK == 1) +#define OS_MEM_NODE_ALIGNED_AND_USED_FLAG \ + (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG | OS_MEM_NODE_LEAK_FLAG) +#else +#define OS_MEM_NODE_ALIGNED_AND_USED_FLAG \ + (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LAST_FLAG) +#endif #define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ ((sizeAndFlag) & OS_MEM_NODE_ALIGNED_FLAG) @@ -183,9 +231,15 @@ struct OsMemPoolHead { #define OS_MEM_NODE_GET_SIZE(sizeAndFlag) \ ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_AND_USED_FLAG) #define OS_MEM_NODE_SET_LAST_FLAG(sizeAndFlag) \ - ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_LAST_FLAG)) + ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_LAST_FLAG)) #define OS_MEM_NODE_GET_LAST_FLAG(sizeAndFlag) \ ((sizeAndFlag) & OS_MEM_NODE_LAST_FLAG) +#if (LOSCFG_MEM_LEAKCHECK == 1) +#define OS_MEM_NODE_GET_LEAK_FLAG(sizeAndFlag) \ + ((sizeAndFlag) & OS_MEM_NODE_LEAK_FLAG) +#define OS_MEM_NODE_SET_LEAK_FLAG(sizeAndFlag) \ + ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_LEAK_FLAG)) +#endif #define OS_MEM_ALIGN_SIZE sizeof(UINTPTR) #define OS_MEM_IS_POW_TWO(value) ((((UINTPTR)(value)) & ((UINTPTR)(value) - 1)) == 0) @@ -193,6 +247,8 @@ struct OsMemPoolHead { #define OS_MEM_IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1))) #define OS_MEM_NODE_HEAD_SIZE sizeof(struct OsMemUsedNodeHead) #define OS_MEM_MIN_POOL_SIZE (OS_MEM_NODE_HEAD_SIZE + sizeof(struct OsMemPoolHead)) +#define OS_MEM_MIN_LEFT_SIZE sizeof(struct OsMemFreeNodeHead) +#define OS_MEM_MIN_ALLOC_SIZE 8 #define OS_MEM_NEXT_NODE(node) \ ((struct OsMemNodeHead *)(VOID *)((UINT8 *)(node) + OS_MEM_NODE_GET_SIZE((node)->sizeAndFlag))) #define OS_MEM_FIRST_NODE(pool) \ @@ -203,17 +259,39 @@ struct OsMemPoolHead { (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) < (UINT8 *)(endAddr))) #define OS_MEM_MIDDLE_ADDR(startAddr, middleAddr, endAddr) \ (((UINT8 *)(startAddr) <= (UINT8 *)(middleAddr)) && ((UINT8 *)(middleAddr) <= (UINT8 *)(endAddr))) +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) +STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave); #define OS_MEM_SET_MAGIC(node) ((node)->magic = OS_MEM_NODE_MAGIC) #define OS_MEM_MAGIC_VALID(node) ((node)->magic == OS_MEM_NODE_MAGIC) +#else +#define OS_MEM_SET_MAGIC(node) +#define OS_MEM_MAGIC_VALID(node) TRUE +#endif STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node); STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead *node); STATIC VOID OsMemInfoPrint(VOID *pool); -#if OS_MEM_FREE_BY_TASKID +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) STATIC INLINE VOID OsMemNodeSetTaskID(struct OsMemUsedNodeHead *node) { - node->taskID = LOS_CurTaskIDGet(); + node->header.taskID = LOS_CurTaskIDGet(); +} +#endif + +#if (LOSCFG_MEM_WATERLINE == 1) +STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) +{ + pool->info.curUsedSize += size; + if (pool->info.curUsedSize > pool->info.waterLine) { + pool->info.waterLine = pool->info.curUsedSize; + } +} +#else +STATIC INLINE VOID OsMemWaterUsedRecord(struct OsMemPoolHead *pool, UINT32 size) +{ + (VOID)pool; + (VOID)size; } #endif @@ -291,7 +369,7 @@ STATIC INLINE struct OsMemNodeHead *PreSentinelNodeGet(const VOID *pool, const s sentinelNode = OS_MEM_END_NODE(pool, ((struct OsMemPoolHead *)pool)->info.totalSize); while (sentinelNode != NULL) { if (OsMemIsLastSentinelNode(sentinelNode)) { - PRINT_ERR("PreSentinelNodeGet can not find node %#x\n", node); + PRINT_ERR("PreSentinelNodeGet can not find node 0x%x\n", node); return NULL; } nextNode = OsMemSentinelNodeGet(sentinelNode); @@ -331,7 +409,7 @@ STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *n } if (OsMemLargeNodeFree(node) != LOS_OK) { - PRINT_ERR("TryShrinkPool free %#x failed!\n", node); + PRINT_ERR("TryShrinkPool free 0x%x failed!\n", node); return FALSE; } @@ -370,13 +448,10 @@ RETRY: endNode = OS_MEM_END_NODE(newNode, size); (VOID)memset_s(endNode, sizeof(*endNode), 0, sizeof(*endNode)); endNode->ptr.next = NULL; - endNode->magic = OS_MEM_NODE_MAGIC; + OS_MEM_SET_MAGIC(endNode); OsMemSentinelNodeSet(endNode, NULL, 0); -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) - poolInfo->poolCurUsedSize = sizeof(LosMemPoolInfo) + OS_MULTI_DLNK_HEAD_SIZE + - OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); - poolInfo->poolWaterLine = poolInfo->poolCurUsedSize; -#endif + OsMemWaterUsedRecord(poolInfo, OS_MEM_NODE_HEAD_SIZE); + return 0; } @@ -390,15 +465,144 @@ VOID LOS_MemExpandEnable(VOID *pool) } #endif +#if (LOSCFG_MEM_LEAKCHECK == 1) +struct OsMemLeakCheckInfo { + struct OsMemNodeHead *node; + UINTPTR linkReg[LOS_RECORD_LR_CNT]; +}; + +struct OsMemLeakCheckInfo g_leakCheckRecord[LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM] = {0}; +STATIC UINT32 g_leakCheckRecordCnt = 0; + +STATIC INLINE VOID OsMemLeakCheckInfoRecord(struct OsMemNodeHead *node) +{ + struct OsMemLeakCheckInfo *info = &g_leakCheckRecord[g_leakCheckRecordCnt]; + + if (!OS_MEM_NODE_GET_LEAK_FLAG(node->sizeAndFlag)) { + info->node = node; + (VOID)memcpy_s(info->linkReg, sizeof(info->linkReg), node->linkReg, sizeof(node->linkReg)); + OS_MEM_NODE_SET_LEAK_FLAG(node->sizeAndFlag); + g_leakCheckRecordCnt++; + if (g_leakCheckRecordCnt >= LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM) { + g_leakCheckRecordCnt = 0; + } + } +} + +STATIC INLINE VOID OsMemLeakCheckInit(VOID) +{ + (VOID)memset_s(g_leakCheckRecord, sizeof(struct OsMemLeakCheckInfo) * LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM, + 0, sizeof(struct OsMemLeakCheckInfo) * LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM); + g_leakCheckRecordCnt = 0; +} + +STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node) +{ + UINT32 taskID = LOS_CurTaskIDGet(); + if (taskID == LOS_ERRNO_TSK_ID_INVALID) { + return; + } + + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + UINTPTR stackStart = (UINTPTR)taskCB->stackPointer; + UINTPTR stackEnd = stackStart + taskCB->stackSize; + + HalRecordLR(node->linkReg, LOS_RECORD_LR_CNT, LOS_OMIT_LR_CNT, stackStart, stackEnd); +} + +STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) +{ + UINT32 count; + + if (OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { + PRINTK("0x%x: ", node); + for (count = 0; count < LOS_RECORD_LR_CNT; count++) { + PRINTK(" 0x%x ", node->linkReg[count]); + } + PRINTK("\n"); + + OsMemLeakCheckInfoRecord(node); + } +} + +VOID LOS_MemUsedNodeShow(VOID *pool) +{ + if (pool == NULL) { + PRINTK("input param is NULL\n"); + return; + } + if (LOS_MemIntegrityCheck(pool)) { + PRINTK("LOS_MemIntegrityCheck error\n"); + return; + } + struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *endNode = NULL; + UINT32 intSave; + UINT32 count; + + PRINTK("\n\rnode "); + for (count = 0; count < LOS_RECORD_LR_CNT; count++) { + PRINTK(" LR[%u] ", count); + } + PRINTK("\n"); + + MEM_LOCK(poolInfo, intSave); + OsMemLeakCheckInit(); + endNode = OS_MEM_END_NODE(pool, poolInfo->info.totalSize); +#if OS_MEM_EXPAND_ENABLE + UINT32 size; + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode; + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + if (tmpNode == endNode) { + if (OsMemIsLastSentinelNode(endNode) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); + tmpNode = OsMemSentinelNodeGet(endNode); + endNode = OS_MEM_END_NODE(tmpNode, size); + continue; + } else { + break; + } + } else { + OsMemUsedNodePrint(tmpNode); + } + } +#else + for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode; + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + OsMemUsedNodePrint(tmpNode); + } +#endif + MEM_UNLOCK(poolInfo, intSave); +} + +#if (LOSCFG_KERNEL_PRINTF != 0) +STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, + const struct OsMemNodeHead *preNode) +{ + int i; + PRINTK("\n broken node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + PRINTK(" LR[%d]:0x%x\n", i, tmpNode->linkReg[i]); + } + + PRINTK("\n pre node head LR info: \n"); + for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + PRINTK(" LR[%d]:0x%x\n", i, preNode->linkReg[i]); + } +} +#endif +#endif + STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) { UINT32 fl = OsMemFlGet(size); - if (fl < OS_MEM_SMALL_BUCKET_COUNT) { + if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { return fl; } UINT32 sl = OsMemSlGet(size, fl); - return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_SMALL_BUCKET_COUNT) << OS_MEM_SLI) + sl); + return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); } STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, @@ -437,11 +641,11 @@ STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, U UINT32 mask; do { - if (fl < OS_MEM_SMALL_BUCKET_COUNT) { + if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { index = fl; } else { sl = OsMemSlGet(size, fl); - curIndex = ((fl - OS_MEM_SMALL_BUCKET_COUNT) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT; + curIndex = ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT; index = curIndex + 1; } @@ -487,10 +691,11 @@ STATIC INLINE VOID OsMemListAdd(struct OsMemPoolHead *pool, UINT32 listIndex, st if (firstNode != NULL) { firstNode->prev = node; } + node->prev = NULL; node->next = firstNode; pool->freeList[listIndex] = node; OsMemSetFreeListBit(pool, listIndex); - node->header.magic = OS_MEM_NODE_MAGIC; + OS_MEM_SET_MAGIC(&node->header); } STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, struct OsMemFreeNodeHead *node) @@ -499,6 +704,8 @@ STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, pool->freeList[listIndex] = node->next; if (node->next == NULL) { OsMemClearFreeListBit(pool, listIndex); + } else { + node->next->prev = NULL; } } else { node->prev->next = node->next; @@ -506,7 +713,7 @@ STATIC INLINE VOID OsMemListDelete(struct OsMemPoolHead *pool, UINT32 listIndex, node->next->prev = node->prev; } } - node->header.magic = OS_MEM_NODE_MAGIC; + OS_MEM_SET_MAGIC(&node->header); } STATIC INLINE VOID OsMemFreeNodeAdd(VOID *pool, struct OsMemFreeNodeHead *node) @@ -574,7 +781,7 @@ STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr) { struct OsMemUsedNodeHead *node = (struct OsMemUsedNodeHead *)addr; -#if OS_MEM_FREE_BY_TASKID +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) OsMemNodeSetTaskID(node); #endif @@ -591,17 +798,17 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) poolHead->info.pool = pool; poolHead->info.totalSize = size; - poolHead->info.attr = OS_MEM_POOL_LOCK_ENABLE; /* default attr: lock, not expand. */ + poolHead->info.attr &= ~(OS_MEM_POOL_UNLOCK_ENABLE | OS_MEM_POOL_EXPAND_ENABLE); /* default attr: lock, not expand. */ newNode = OS_MEM_FIRST_NODE(pool); newNode->sizeAndFlag = (size - sizeof(struct OsMemPoolHead) - OS_MEM_NODE_HEAD_SIZE); - newNode->ptr.prev = NULL; - newNode->magic = OS_MEM_NODE_MAGIC; + newNode->ptr.prev = OS_MEM_END_NODE(pool, size); + OS_MEM_SET_MAGIC(newNode); OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode); /* The last mem node */ endNode = OS_MEM_END_NODE(pool, size); - endNode->magic = OS_MEM_NODE_MAGIC; + OS_MEM_SET_MAGIC(endNode); #if OS_MEM_EXPAND_ENABLE endNode->ptr.next = NULL; OsMemSentinelNodeSet(endNode, NULL, 0); @@ -610,6 +817,10 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size) endNode->ptr.prev = newNode; OS_MEM_NODE_SET_USED_FLAG(endNode->sizeAndFlag); #endif +#if (LOSCFG_MEM_WATERLINE == 1) + poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE; + poolHead->info.waterLine = poolHead->info.curUsedSize; +#endif return LOS_OK; } @@ -629,7 +840,7 @@ STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size) poolEnd = (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool); if (((pool <= nextPool) && (((UINTPTR)pool + size) > (UINTPTR)nextPool)) || (((UINTPTR)pool < poolEnd) && (((UINTPTR)pool + size) >= poolEnd))) { - PRINT_ERR("pool [%#x, %#x) conflict with pool [%#x, %#x)\n", (UINTPTR)pool, + PRINT_ERR("pool [0x%x, 0x%x) conflict with pool [0x%x, 0x%x)\n", (UINTPTR)pool, (UINTPTR)pool + size, (UINTPTR)nextPool, (UINTPTR)nextPool + LOS_MemPoolSizeGet(nextPool)); return LOS_NOK; } @@ -695,11 +906,6 @@ UINT32 LOS_MemInit(VOID *pool, UINT32 size) } #endif -#if OS_MEM_TRACE - LOS_TraceReg(LOS_TRACE_MEM_TIME, OsMemTimeTrace, LOS_TRACE_MEM_TIME_NAME, LOS_TRACE_ENABLE); - LOS_TraceReg(LOS_TRACE_MEM_INFO, OsMemInfoTrace, LOS_TRACE_MEM_INFO_NAME, LOS_TRACE_ENABLE); -#endif - return LOS_OK; } @@ -716,11 +922,6 @@ UINT32 LOS_MemDeInit(VOID *pool) OsMemPoolDeinit(pool); -#if OS_MEM_TRACE - LOS_TraceUnreg(LOS_TRACE_MEM_TIME); - LOS_TraceUnreg(LOS_TRACE_MEM_INFO); -#endif - return LOS_OK; } @@ -741,6 +942,13 @@ UINT32 LOS_MemPoolList(VOID) STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave) { struct OsMemNodeHead *allocNode = NULL; + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + if (OsMemAllocCheck(pool, intSave) == LOS_NOK) { + return NULL; + } +#endif + UINT32 allocSize = OS_MEM_ALIGN(size + OS_MEM_NODE_HEAD_SIZE, OS_MEM_ALIGN_SIZE); if (allocSize == 0) { return NULL; @@ -770,18 +978,23 @@ retry: return NULL; } - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= allocNode->sizeAndFlag) { + if ((allocSize + OS_MEM_MIN_LEFT_SIZE) <= allocNode->sizeAndFlag) { OsMemSplitNode(pool, allocNode, allocSize); } OS_MEM_NODE_SET_USED_FLAG(allocNode->sizeAndFlag); + OsMemWaterUsedRecord(pool, OS_MEM_NODE_GET_SIZE(allocNode->sizeAndFlag)); + +#if (LOSCFG_MEM_LEAKCHECK == 1) + OsMemLinkRegisterRecord(allocNode); +#endif return OsMemCreateUsedNode((VOID *)allocNode); } VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { -#if OS_MEM_TRACE - UINT64 start = HalClockGetCycles(); +#if OS_MEM_PRINT_DEBUG + UINT64 start = OsMemClockGetCycles(); #endif if ((pool == NULL) || (size == 0)) { @@ -805,17 +1018,17 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_MALLOC, timeUsed); +#if OS_MEM_PRINT_DEBUG + UINT64 end = OsMemClockGetCycles(); + UINT32 timeUsed = end - start; + PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_MALLOC, timeUsed); LOS_MEM_POOL_STATUS poolStatus = {0}; (VOID)LOS_MemInfoGet(pool, &poolStatus); - UINT8 fragment = 100 - poolStatus.uwMaxFreeNodeSize * 100 / poolStatus.uwTotalFreeSize; /* 100: percent denominator. */ + UINT8 fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; /* 100: percent denominator. */ UINT8 usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); /* 100: percent denominator. */ - LOS_Trace(LOS_TRACE_MEM_INFO, (UINTPTR)pool & MEM_POOL_ADDR_MASK, fragment, usage, poolStatus.uwTotalFreeSize, - poolStatus.uwMaxFreeNodeSize, poolStatus.uwUsedNodeNum, poolStatus.uwFreeNodeNum); + PRINTK("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d\n", usage, fragment, + poolStatus.maxFreeNodeSize, poolStatus.totalFreeSize); #endif return ptr; @@ -823,8 +1036,8 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { -#if OS_MEM_TRACE - UINT64 start = HalClockGetCycles(); +#if OS_MEM_PRINT_DEBUG + UINT64 start = OsMemClockGetCycles(); #endif UINT32 gapSize; @@ -875,10 +1088,10 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_MEMALIGN, timeUsed); +#if OS_MEM_PRINT_DEBUG + UINT64 end = OsMemClockGetCycles(); + UINT32 timeUsed = end - start; + PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_MEMALIGN, timeUsed); #endif return ptr; @@ -888,11 +1101,6 @@ STATIC INLINE BOOL OsMemAddrValidCheck(const struct OsMemPoolHead *pool, const V { UINT32 size; - /* First node prev is NULL */ - if (addr == NULL) { - return TRUE; - } - size = pool->info.totalSize; if (OS_MEM_MIDDLE_ADDR_OPEN_END(pool + 1, addr, (UINTPTR)pool + size)) { return TRUE; @@ -993,7 +1201,14 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead return ret; } +#if (LOSCFG_MEM_WATERLINE == 1) + pool->info.curUsedSize -= OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); +#endif + node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); +#if (LOSCFG_MEM_LEAKCHECK == 1) + OsMemLinkRegisterRecord(node); +#endif struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */ if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)preNode); @@ -1009,14 +1224,16 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead #if OS_MEM_EXPAND_ENABLE if (pool->info.attr & OS_MEM_POOL_EXPAND_ENABLE) { + struct OsMemNodeHead *firstNode = OS_MEM_FIRST_NODE(pool); /* if this is a expand head node, and all unused, free it to pmm */ - if ((node->ptr.prev != NULL) && (node->ptr.prev > node)) { + if ((node->prev > node) && (node != firstNode)) { if (TryShrinkPool(pool, node)) { - return LOS_NOK; + return LOS_OK; } } } #endif + OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)node); return ret; @@ -1024,8 +1241,8 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { -#if OS_MEM_TRACE - UINT64 start = HalClockGetCycles(); +#if OS_MEM_PRINT_DEBUG + UINT64 start = OsMemClockGetCycles(); #endif if ((pool == NULL) || (ptr == NULL) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *)) || @@ -1060,10 +1277,10 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_FREE, timeUsed); +#if OS_MEM_PRINT_DEBUG + UINT64 end = OsMemClockGetCycles(); + UINT32 timeUsed = end - start; + PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_FREE, timeUsed); #endif return ret; @@ -1071,36 +1288,33 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize) { -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) +#if (LOSCFG_MEM_WATERLINE == 1) struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; #endif - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= nodeSize) { + if ((allocSize + OS_MEM_MIN_LEFT_SIZE) <= nodeSize) { OsMemSplitNode(pool, node, allocSize); OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) - poolInfo->poolCurUsedSize -= nodeSize - allocSize; +#if (LOSCFG_MEM_WATERLINE == 1) + poolInfo->info.curUsedSize -= nodeSize - allocSize; #endif } +#if (LOSCFG_MEM_LEAKCHECK == 1) + OsMemLinkRegisterRecord(node); +#endif } STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, struct OsMemNodeHead *node, UINT32 nodeSize, struct OsMemNodeHead *nextNode) { -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) - struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; -#endif - node->sizeAndFlag = nodeSize; OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode); OsMemMergeNode(nextNode); - if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= node->sizeAndFlag) { + if ((allocSize + OS_MEM_MIN_LEFT_SIZE) <= node->sizeAndFlag) { OsMemSplitNode(pool, node, allocSize); } -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) - poolInfo->poolCurUsedSize += (node->sizeAndFlag - nodeSize); - if (poolInfo->poolCurUsedSize > poolInfo->poolWaterLine) { - poolInfo->poolWaterLine = poolInfo->poolCurUsedSize; - } + OsMemWaterUsedRecord((struct OsMemPoolHead *)pool, node->sizeAndFlag - nodeSize); +#if (LOSCFG_MEM_LEAKCHECK == 1) + OsMemLinkRegisterRecord(node); #endif } @@ -1160,18 +1374,14 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { -#if OS_MEM_TRACE - UINT64 start = HalClockGetCycles(); +#if OS_MEM_PRINT_DEBUG + UINT64 start = OsMemClockGetCycles(); #endif if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { return NULL; } - if (size < OS_MEM_MIN_ALLOC_SIZE) { - size = OS_MEM_MIN_ALLOC_SIZE; - } - if (ptr == NULL) { return LOS_MemAlloc(pool, size); } @@ -1181,6 +1391,10 @@ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) return NULL; } + if (size < OS_MEM_MIN_ALLOC_SIZE) { + size = OS_MEM_MIN_ALLOC_SIZE; + } + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; struct OsMemNodeHead *node = NULL; VOID *newPtr = NULL; @@ -1202,16 +1416,16 @@ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_TRACE - UINT64 end = HalClockGetCycles(); - UINT32 timeUsed = MEM_TRACE_CYCLE_TO_US(end - start); - LOS_Trace(LOS_TRACE_MEM_TIME, (UINTPTR)pool & MEM_POOL_ADDR_MASK, MEM_TRACE_REALLOC, timeUsed); +#if OS_MEM_PRINT_DEBUG + UINT64 end = OsMemClockGetCycles(); + UINT32 timeUsed = end - start; + PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_REALLOC, timeUsed); #endif return newPtr; } -#if OS_MEM_FREE_BY_TASKID +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) { if (pool == NULL) { @@ -1237,7 +1451,7 @@ UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID) } node = (struct OsMemUsedNodeHead *)tmpNode; - if (node->taskID == taskID) { + if (node->header.taskID == taskID) { OsMemFree(poolHead, &node->header); } } @@ -1319,12 +1533,307 @@ UINT32 LOS_MemTotalUsedGet(VOID *pool) return memUsed; } -UINT32 LOS_MemIntegrityCheck(const VOID *pool) +STATIC INLINE VOID OsMemMagicCheckPrint(struct OsMemNodeHead **tmpNode) { +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + PRINT_ERR("[%s], %d, memory check error!\n" + "memory used but magic num wrong, magic num = 0x%x\n", + __FUNCTION__, __LINE__, (*tmpNode)->magic); +#endif +} + +STATIC UINT32 OsMemAddrValidCheckPrint(const VOID *pool, struct OsMemFreeNodeHead **tmpNode) +{ + if (((*tmpNode)->prev != NULL) && !OsMemAddrValidCheck(pool, (*tmpNode)->prev)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " freeNode.prev: 0x%x is out of legal mem range\n", + __FUNCTION__, __LINE__, (*tmpNode)->prev); + return LOS_NOK; + } + if (((*tmpNode)->next != NULL) && !OsMemAddrValidCheck(pool, (*tmpNode)->next)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " freeNode.next: 0x%x is out of legal mem range\n", + __FUNCTION__, __LINE__, (*tmpNode)->next); + return LOS_NOK; + } return LOS_OK; } -STATIC INLINE VOID OsMemInfoGet(struct OsMemNodeHead *node, LOS_MEM_POOL_STATUS *poolStatus) +STATIC UINT32 OsMemIntegrityCheckSub(struct OsMemNodeHead **tmpNode, const VOID *pool, + const struct OsMemNodeHead *endNode) +{ + if (!OS_MEM_MAGIC_VALID(*tmpNode)) { + OsMemMagicCheckPrint(tmpNode); + return LOS_NOK; + } + + if (!OsMemAddrValidCheck(pool, (*tmpNode)->ptr.prev)) { + PRINT_ERR("[%s], %d, memory check error!\n" + " node prev: 0x%x is out of legal mem range\n", + __FUNCTION__, __LINE__, (*tmpNode)->ptr.next); + } + + if (!OS_MEM_NODE_GET_USED_FLAG((*tmpNode)->sizeAndFlag)) { /* is free node, check free node range */ + if (OsMemAddrValidCheckPrint(pool, (struct OsMemFreeNodeHead **)tmpNode)) { + return LOS_NOK; + } + } + + return LOS_OK; +} + +STATIC UINT32 OsMemFreeListNodeCheck(const struct OsMemPoolHead *pool, + const struct OsMemFreeNodeHead *node) +{ + if (!OsMemAddrValidCheck(pool, node) || + ((node->prev != NULL) && !OsMemAddrValidCheck(pool, node->prev)) || + ((node->next != NULL) && !OsMemAddrValidCheck(pool, node->next)) || + !OsMemAddrValidCheck(pool, node->header.ptr.prev)) { + return LOS_NOK; + } + + if (!OS_MEM_IS_ALIGNED(node, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(node->prev, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(node->next, sizeof(VOID *)) || + !OS_MEM_IS_ALIGNED(node->header.ptr.prev, sizeof(VOID *))) { + return LOS_NOK; + } + + return LOS_OK; +} + +STATIC VOID OsMemPoolHeadCheck(const struct OsMemPoolHead *pool) +{ + struct OsMemFreeNodeHead *tmpNode = NULL; + UINT32 index; + UINT32 flag = 0; + + if ((pool->info.pool != pool) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *))) { + PRINT_ERR("wrong mem pool addr: 0x%x, func: %s, line: %d\n", pool, __FUNCTION__, __LINE__); + return; + } + + for (index = 0; index < OS_MEM_FREE_LIST_COUNT; index++) { + for (tmpNode = pool->freeList[index]; tmpNode != NULL; tmpNode = tmpNode->next) { + if (OsMemFreeListNodeCheck(pool, tmpNode)) { + flag = 1; + PRINT_ERR("FreeListIndex: %u, node: 0x%x, bNode: 0x%x, prev: 0x%x, next: 0x%x\n", + index, tmpNode, tmpNode->header.ptr.prev, tmpNode->prev, tmpNode->next); + } + } + } + + if (flag) { + PRINTK("mem pool info: poolAddr: 0x%x, poolSize: 0x%x\n", pool, pool->info.totalSize); +#if (LOSCFG_MEM_WATERLINE == 1) + PRINTK("mem pool info: poolWaterLine: 0x%x, poolCurUsedSize: 0x%x\n", pool->info.waterLine, + pool->info.curUsedSize); +#endif +#if OS_MEM_EXPAND_ENABLE + UINT32 size; + struct OsMemNodeHead *node = NULL; + struct OsMemNodeHead *sentinel = OS_MEM_END_NODE(pool, pool->info.totalSize); + while (OsMemIsLastSentinelNode(sentinel) == FALSE) { + size = OS_MEM_NODE_GET_SIZE(sentinel->sizeAndFlag); + node = OsMemSentinelNodeGet(sentinel); + sentinel = OS_MEM_END_NODE(node, size); + PRINTK("expand node info: nodeAddr: 0x%x, nodeSize: 0x%x\n", node, size); + } +#endif + } +} + +STATIC UINT32 OsMemIntegrityCheck(const struct OsMemPoolHead *pool, struct OsMemNodeHead **tmpNode, + struct OsMemNodeHead **preNode) +{ + struct OsMemNodeHead *endNode = OS_MEM_END_NODE(pool, pool->info.totalSize); + + OsMemPoolHeadCheck(pool); + + *preNode = OS_MEM_FIRST_NODE(pool); + do { + for (*tmpNode = *preNode; *tmpNode < endNode; *tmpNode = OS_MEM_NEXT_NODE(*tmpNode)) { + if (OsMemIntegrityCheckSub(tmpNode, pool, endNode) == LOS_NOK) { + return LOS_NOK; + } + *preNode = *tmpNode; + } +#if OS_MEM_EXPAND_ENABLE + if (OsMemIsLastSentinelNode(*tmpNode) == FALSE) { + *preNode = OsMemSentinelNodeGet(*tmpNode); + endNode = OS_MEM_END_NODE(*preNode, OS_MEM_NODE_GET_SIZE((*tmpNode)->sizeAndFlag)); + } else +#endif + { + break; + } + } while (1); + return LOS_OK; +} + +#if (LOSCFG_KERNEL_PRINTF != 0) +STATIC VOID OsMemNodeInfo(const struct OsMemNodeHead *tmpNode, + const struct OsMemNodeHead *preNode) +{ + struct OsMemUsedNodeHead *usedNode = NULL; + struct OsMemFreeNodeHead *freeNode = NULL; + + if (tmpNode == preNode) { + PRINTK("\n the broken node is the first node\n"); + } + + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + usedNode = (struct OsMemUsedNodeHead *)tmpNode; + PRINTK("\n broken node head: 0x%x " +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + "0x%x " +#endif + "0x%x, ", + usedNode->header.ptr.prev, +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + usedNode->header.magic, +#endif + usedNode->header.sizeAndFlag); + } else { + freeNode = (struct OsMemFreeNodeHead *)tmpNode; + PRINTK("\n broken node head: 0x%x 0x%x " +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + "0x%x " +#endif + "0x%x, ", + freeNode->header.ptr.prev, freeNode->next, freeNode->prev, +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + freeNode->header.magic, +#endif + freeNode->header.sizeAndFlag); + } + + if (OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { + usedNode = (struct OsMemUsedNodeHead *)preNode; + PRINTK("prev node head: 0x%x " +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + "0x%x " +#endif + "0x%x\n", + usedNode->header.ptr.prev, +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + usedNode->header.magic, +#endif + usedNode->header.sizeAndFlag); + } else { + freeNode = (struct OsMemFreeNodeHead *)preNode; + PRINTK("prev node head: 0x%x 0x%x " +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + "0x%x " +#endif + "0x%x, ", + freeNode->header.ptr.prev, freeNode->next, freeNode->prev, +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) + freeNode->header.magic, +#endif + freeNode->header.sizeAndFlag); + } + +#if (LOSCFG_MEM_LEAKCHECK == 1) + OsMemNodeBacktraceInfo(tmpNode, preNode); +#endif +} +#endif + +struct OsMemIntegrityCheckInfo { + struct OsMemNodeHead preNode; + struct OsMemNodeHead errNode; +}; + +struct OsMemIntegrityCheckInfo g_integrityCheckRecord = {0}; + +STATIC INLINE VOID OsMemCheckInfoRecord(const struct OsMemNodeHead *errNode, + const struct OsMemNodeHead *preNode) +{ + (VOID)memcpy_s(&g_integrityCheckRecord.preNode, sizeof(struct OsMemNodeHead), + preNode, sizeof(struct OsMemNodeHead)); + (VOID)memcpy_s(&g_integrityCheckRecord.errNode, sizeof(struct OsMemNodeHead), + errNode, sizeof(struct OsMemNodeHead)); +} + +STATIC VOID OsMemIntegrityCheckError(struct OsMemPoolHead *pool, + const struct OsMemNodeHead *tmpNode, + const struct OsMemNodeHead *preNode, + UINT32 intSave) +{ +#if (LOSCFG_KERNEL_PRINTF != 0) + OsMemNodeInfo(tmpNode, preNode); +#endif + OsMemCheckInfoRecord(tmpNode, preNode); +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) + LosTaskCB *taskCB = NULL; + if (OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) { + struct OsMemUsedNodeHead *usedNode = (struct OsMemUsedNodeHead *)preNode; + UINT32 taskID = usedNode->header.taskID; + if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) { + MEM_UNLOCK(pool, 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)) { + MEM_UNLOCK(pool, intSave); + LOS_Panic("\r\nTask ID %u in pre node is not created!\n", taskID); + return; + } + } else { + PRINTK("The prev node is free\n"); + } + MEM_UNLOCK(pool, intSave); + PRINT_ERR("cur node: 0x%x, pre node: 0x%x, pre node was allocated by task: %d, %s\n", + tmpNode, preNode, taskCB->taskID, taskCB->taskName); + LOS_Panic("Memory interity check error!\n"); +#else + MEM_UNLOCK(pool, intSave); + LOS_Panic("Memory interity check error, cur node: 0x%x, pre node: 0x%x\n", tmpNode, preNode); +#endif +} + +#if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1) +STATIC INLINE UINT32 OsMemAllocCheck(struct OsMemPoolHead *pool, UINT32 intSave) +{ + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *preNode = NULL; + + if (OsMemIntegrityCheck(pool, &tmpNode, &preNode)) { + OsMemIntegrityCheckError(pool, tmpNode, preNode, intSave); + return LOS_NOK; + } + return LOS_OK; +} +#endif + +UINT32 LOS_MemIntegrityCheck(const VOID *pool) +{ + if (pool == NULL) { + return LOS_NOK; + } + + struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool; + struct OsMemNodeHead *tmpNode = NULL; + struct OsMemNodeHead *preNode = NULL; + UINT32 intSave = 0; + + MEM_LOCK(poolHead, intSave); + if (OsMemIntegrityCheck(poolHead, &tmpNode, &preNode)) { + goto ERROR_OUT; + } + MEM_UNLOCK(poolHead, intSave); + return LOS_OK; + +ERROR_OUT: + OsMemIntegrityCheckError(poolHead, tmpNode, preNode, intSave); + return LOS_NOK; +} + +STATIC INLINE VOID OsMemInfoGet(struct OsMemPoolHead *poolInfo, struct OsMemNodeHead *node, + LOS_MEM_POOL_STATUS *poolStatus) { UINT32 totalUsedSize = 0; UINT32 totalFreeSize = 0; @@ -1334,14 +1843,14 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemNodeHead *node, LOS_MEM_POOL_STATUS UINT32 size; if (!OS_MEM_NODE_GET_USED_FLAG(node->sizeAndFlag)) { - size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag) - sizeof(struct OsMemFreeNodeHead); + size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); ++freeNodeNum; totalFreeSize += size; if (maxFreeSize < size) { maxFreeSize = size; } } else { - size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag) - sizeof(struct OsMemUsedNodeHead); + size = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag); ++usedNodeNum; totalUsedSize += size; } @@ -1352,9 +1861,6 @@ STATIC INLINE VOID OsMemInfoGet(struct OsMemNodeHead *node, LOS_MEM_POOL_STATUS poolStatus->maxFreeNodeSize : maxFreeSize; poolStatus->usedNodeNum += usedNodeNum; poolStatus->freeNodeNum += freeNodeNum; -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) - poolStatus->usageWaterLine = poolInfo->poolWaterLine; -#endif } UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) @@ -1367,7 +1873,7 @@ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) } if ((pool == NULL) || (poolInfo->info.pool != pool)) { - PRINT_ERR("wrong mem pool addr: %#x, line:%d\n", (UINTPTR)poolInfo, __LINE__); + PRINT_ERR("wrong mem pool addr: 0x%x, line:%d\n", (UINTPTR)poolInfo, __LINE__); return LOS_NOK; } @@ -1381,6 +1887,8 @@ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) UINT32 size; for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode <= endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { if (tmpNode == endNode) { + poolStatus->totalUsedSize += OS_MEM_NODE_HEAD_SIZE; + poolStatus->usedNodeNum++; if (OsMemIsLastSentinelNode(endNode) == FALSE) { size = OS_MEM_NODE_GET_SIZE(endNode->sizeAndFlag); tmpNode = OsMemSentinelNodeGet(endNode); @@ -1390,13 +1898,16 @@ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) break; } } else { - OsMemInfoGet(tmpNode, poolStatus); + OsMemInfoGet(poolInfo, tmpNode, poolStatus); } } #else for (tmpNode = OS_MEM_FIRST_NODE(pool); tmpNode < endNode; tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { - OsMemInfoGet(tmpNode, poolStatus); + OsMemInfoGet(poolInfo, tmpNode, poolStatus); } +#endif +#if (LOSCFG_MEM_WATERLINE == 1) + poolStatus->usageWaterLine = poolInfo->info.waterLine; #endif MEM_UNLOCK(poolInfo, intSave); @@ -1405,6 +1916,7 @@ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) STATIC VOID OsMemInfoPrint(VOID *pool) { +#if (LOSCFG_KERNEL_PRINTF != 0) struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; LOS_MEM_POOL_STATUS status = {0}; @@ -1412,7 +1924,7 @@ STATIC VOID OsMemInfoPrint(VOID *pool) return; } -#if defined(OS_MEM_WATERLINE) && (OS_MEM_WATERLINE == YES) +#if (LOSCFG_MEM_WATERLINE == 1) PRINTK("pool addr pool size used size free size " "max free node size used node num free node num UsageWaterLine\n"); PRINTK("--------------- -------- ------- -------- " @@ -1421,7 +1933,6 @@ STATIC VOID OsMemInfoPrint(VOID *pool) poolInfo->info.pool, LOS_MemPoolSizeGet(pool), status.totalUsedSize, status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum, status.freeNodeNum, status.usageWaterLine); - #else PRINTK("pool addr pool size used size free size " "max free node size used node num free node num\n"); @@ -1432,14 +1943,16 @@ STATIC VOID OsMemInfoPrint(VOID *pool) status.totalFreeSize, status.maxFreeNodeSize, status.usedNodeNum, status.freeNodeNum); #endif +#endif } UINT32 LOS_MemFreeNodeShow(VOID *pool) { +#if (LOSCFG_KERNEL_PRINTF != 0) struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; if ((poolInfo == NULL) || ((UINTPTR)pool != (UINTPTR)poolInfo->info.pool)) { - PRINT_ERR("wrong mem pool addr: %#x, line: %d\n", (UINTPTR)poolInfo, __LINE__); + PRINT_ERR("wrong mem pool addr: 0x%x, line: %d\n", (UINTPTR)poolInfo, __LINE__); return LOS_NOK; } @@ -1466,31 +1979,120 @@ UINT32 LOS_MemFreeNodeShow(VOID *pool) PRINTK("free index: %03u, ", index); if (index < OS_MEM_SMALL_BUCKET_COUNT) { - PRINTK("size: [%#x], num: %u\n", (index + 1) << 2, countNum[index]); /* 2: setup is 4. */ + PRINTK("size: [0x%x], num: %u\n", (index + 1) << 2, countNum[index]); /* 2: setup is 4. */ } else { UINT32 val = 1 << (((index - OS_MEM_SMALL_BUCKET_COUNT) >> OS_MEM_SLI) + OS_MEM_LARGE_START_BUCKET); UINT32 offset = val >> OS_MEM_SLI; - PRINTK("size: [%#x, %#x], num: %u\n", (offset * ((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI))) + val, + PRINTK("size: [0x%x, 0x%x], num: %u\n", (offset * ((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI))) + val, ((offset * (((index - OS_MEM_SMALL_BUCKET_COUNT) % (1 << OS_MEM_SLI)) + 1)) + val - 1), countNum[index]); } } PRINTK("\n ********************************************************************\n\n"); - +#endif return LOS_OK; } +VOID LOS_MemUnlockEnable(VOID *pool) +{ + if (pool == NULL) { + return; + } + + ((struct OsMemPoolHead *)pool)->info.attr |= OS_MEM_POOL_UNLOCK_ENABLE; +} + UINT32 OsMemSystemInit(VOID) { UINT32 ret; - UINT32 memSize; - m_aucSysMem0 = (UINT8 *)(UINTPTR)(((UINT32)(UINTPTR)m_aucSysMem0 + (OS_MEM_ALIGN_SIZE - 1)) & - ~(OS_MEM_ALIGN_SIZE - 1)); - memSize = ((UINT32)g_sysMemAddrEnd) - OS_SYS_NOCACHEMEM_SIZE - (UINT32)(UINTPTR)m_aucSysMem0; - ret = LOS_MemInit(m_aucSysMem0, memSize); - PRINT_INFO("LiteOS heap memory address:0x%x,size:0x%x\n", m_aucSysMem0, memSize); + +#if (LOSCFG_SYS_EXTERNAL_HEAP == 0) + m_aucSysMem0 = g_memStart; +#else + m_aucSysMem0 = LOSCFG_SYS_HEAP_ADDR; +#endif + + if ((UINTPTR)m_aucSysMem0 & (OS_MEM_ALIGN_SIZE - 1)) { + m_aucSysMem0 = (UINT8 *)(((UINTPTR)m_aucSysMem0 + (OS_MEM_ALIGN_SIZE - 1)) & + ~(OS_MEM_ALIGN_SIZE - 1)); + } + + ret = LOS_MemInit(m_aucSysMem0, LOSCFG_SYS_HEAP_SIZE); + PRINT_INFO("LiteOS heap memory address:0x%x,size:0x%x\n", m_aucSysMem0, LOSCFG_SYS_HEAP_SIZE); return ret; } +#if (LOSCFG_PLATFORM_EXC == 1) +STATIC VOID OsMemExcInfoGetSub(struct OsMemPoolHead *pool, MemInfoCB *memExcInfo) +{ + struct OsMemNodeHead *tmpNode = NULL; + UINT32 taskID = OS_TASK_ERRORID; + UINT32 intSave; + + (VOID)memset_s(memExcInfo, sizeof(MemInfoCB), 0, sizeof(MemInfoCB)); + + MEM_LOCK(pool, intSave); + memExcInfo->type = MEM_MANG_MEMORY; + memExcInfo->startAddr = (UINTPTR)pool->info.pool; + memExcInfo->size = pool->info.totalSize; + memExcInfo->free = pool->info.totalSize - LOS_MemTotalUsedGet(pool); + + for (tmpNode = OS_MEM_FIRST_NODE(pool); + tmpNode < OS_MEM_END_NODE(pool, pool->info.totalSize); + tmpNode = OS_MEM_NEXT_NODE(tmpNode)) { + memExcInfo->blockSize++; + if (OS_MEM_NODE_GET_USED_FLAG(tmpNode->sizeAndFlag)) { + if (!OS_MEM_MAGIC_VALID(tmpNode)) { +#if (LOSCFG_MEM_FREE_BY_TASKID == 1) + taskID = ((struct OsMemUsedNodeHead *)tmpNode)->header.taskID; +#endif + goto ERROUT; + } + } else { /* is free node, check free node range */ + struct OsMemFreeNodeHead *freeNode = (struct OsMemFreeNodeHead *)tmpNode; + if ((freeNode->prev != NULL) && !OsMemAddrValidCheck(pool, freeNode->prev)) { + goto ERROUT; + } + if ((freeNode->next != NULL) && !OsMemAddrValidCheck(pool, freeNode->next)) { + goto ERROUT; + } + } + } + MEM_UNLOCK(pool, intSave); + return; + +ERROUT: + memExcInfo->errorAddr = (UINTPTR)((CHAR *)tmpNode + OS_MEM_NODE_HEAD_SIZE); + memExcInfo->errorLen = OS_MEM_NODE_GET_SIZE(tmpNode->sizeAndFlag) - OS_MEM_NODE_HEAD_SIZE; + memExcInfo->errorOwner = taskID; + MEM_UNLOCK(pool, intSave); + return; +} + +UINT32 OsMemExcInfoGet(UINT32 memNumMax, MemInfoCB *memExcInfo) +{ + UINT8 *buffer = (UINT8 *)memExcInfo; + UINT32 count = 0; + +#if (LOSCFG_MEM_MUL_POOL == 1) + struct OsMemPoolHead *memPool = g_poolHead; + while (memPool != NULL) { + OsMemExcInfoGetSub(memPool, (MemInfoCB *)buffer); + count++; + buffer += sizeof(MemInfoCB); + if (count >= memNumMax) { + break; + } + memPool = memPool->nextPool; + } +#else + OsMemExcInfoGetSub(m_aucSysMem0, buffer); + count++; +#endif + + return count; +} +#endif + #ifdef __cplusplus #if __cplusplus } diff --git a/targets/cortex-m3_stm32f103_simulator_keil/main.c b/targets/cortex-m3_stm32f103_simulator_keil/main.c old mode 100644 new mode 100755 index 44d7e08d..b5d61ca1 --- a/targets/cortex-m3_stm32f103_simulator_keil/main.c +++ b/targets/cortex-m3_stm32f103_simulator_keil/main.c @@ -43,7 +43,7 @@ extern "C" { #endif /* __cpluscplus */ #pragma data_alignment=8 -UINT8 g_memStart[OS_SYS_MEM_SIZE]; +UINT8 g_memStart[LOSCFG_SYS_HEAP_SIZE]; VOID taskSampleEntry2(VOID) { diff --git a/targets/cortex-m3_stm32f103_simulator_keil/target_config.h b/targets/cortex-m3_stm32f103_simulator_keil/target_config.h old mode 100644 new mode 100755 index 68942abb..34ede252 --- a/targets/cortex-m3_stm32f103_simulator_keil/target_config.h +++ b/targets/cortex-m3_stm32f103_simulator_keil/target_config.h @@ -86,16 +86,16 @@ extern "C" { /*============================================================================= Memory module configuration =============================================================================*/ -#define OS_SYS_MEM_SIZE 0x00013000 -#define LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK 0 -#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK 1 +extern unsigned char g_memStart[]; +#define LOSCFG_SYS_EXTERNAL_HEAP 1 +#define LOSCFG_SYS_HEAP_ADDR (&g_memStart[0]) +#define LOSCFG_SYS_HEAP_SIZE 0x00013000 #define LOSCFG_MEM_MUL_POOL 1 #define OS_SYS_MEM_NUM 20 -#define LOSCFG_KERNEL_MEM_SLAB 0 -/*============================================================================= - Exception module configuration -=============================================================================*/ -#define LOSCFG_PLATFORM_EXC 1 +/* ============================================================================= + printf module configuration +============================================================================= */ +#define LOSCFG_KERNEL_PRINTF 1 #ifdef __cplusplus #if __cplusplus diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/dprintf.c b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/dprintf.c old mode 100644 new mode 100755 index 90e20b18..4516ef00 --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/dprintf.c +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/dprintf.c @@ -174,5 +174,5 @@ int printf(char const *fmt, ...) va_start(ap, fmt); /*lint !e1055 !e534 !e530*/ __dprintf(fmt, ap, fputc, 0); /*lint !e611 !e64*/ va_end(ap); - return 0; + return 0; } diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/main.c b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/main.c old mode 100644 new mode 100755 index 97a4c60d..e54d3ae2 --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/main.c +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/main.c @@ -43,9 +43,6 @@ extern "C" { #endif /* __cpluscplus */ #endif /* __cpluscplus */ -#pragma data_alignment=8 -UINT8 g_memStart[OS_SYS_MEM_SIZE]; - VOID taskSampleEntry2(VOID) { while(1) { @@ -109,8 +106,8 @@ LITE_OS_SEC_TEXT_INIT int main(void) if (ret == LOS_OK) { LOS_Start(); } - - while (1) { + + while (1) { __asm volatile("wfi"); } } diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp old mode 100644 new mode 100755 index 4f8f4f95..0439b2fb --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp @@ -2078,9 +2078,15 @@ $PROJ_DIR$\..\..\..\components\cpup\los_cpup.c + + $PROJ_DIR$\..\..\..\components\exchook\los_exchook.c + utils + + $PROJ_DIR$\..\..\..\utils\los_debug.c + $PROJ_DIR$\..\..\..\utils\los_error.c diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h old mode 100644 new mode 100755 index f3c86cb4..50b8fcd0 --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h @@ -48,7 +48,7 @@ extern "C" { /*============================================================================= System clock module configuration =============================================================================*/ -#define OS_SYS_CLOCK 64000000 +#define OS_SYS_CLOCK 180000000 #define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL) #define LOSCFG_BASE_CORE_TICK_HW_TIME 0 /*============================================================================= @@ -90,16 +90,12 @@ extern "C" { /*============================================================================= Memory module configuration =============================================================================*/ -#define OS_SYS_MEM_SIZE 0x00013000 -#define LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK 0 -#define LOSCFG_BASE_MEM_NODE_SIZE_CHECK 1 #define LOSCFG_MEM_MUL_POOL 1 #define OS_SYS_MEM_NUM 20 -#define LOSCFG_KERNEL_MEM_SLAB 0 -/*============================================================================= - Exception module configuration -=============================================================================*/ -#define LOSCFG_PLATFORM_EXC 1 +/* ============================================================================= + printf module configuration +============================================================================= */ +#define LOSCFG_KERNEL_PRINTF 1 #ifdef __cplusplus #if __cplusplus diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/target_config.h b/targets/cortex-m7_nucleo_f767zi_gcc/target_config.h old mode 100644 new mode 100755 index 9bdadebe..5e61737b --- a/targets/cortex-m7_nucleo_f767zi_gcc/target_config.h +++ b/targets/cortex-m7_nucleo_f767zi_gcc/target_config.h @@ -98,7 +98,7 @@ extern "C" { /*============================================================================= Exception module configuration =============================================================================*/ -#define LOSCFG_PLATFORM_EXC 1 +#define LOSCFG_PLATFORM_EXC 0 #ifdef __cplusplus #if __cplusplus diff --git a/utils/los_compiler.h b/utils/los_compiler.h old mode 100644 new mode 100755 index 648a95c5..73683993 --- a/utils/los_compiler.h +++ b/utils/los_compiler.h @@ -308,8 +308,12 @@ typedef signed int INTPTR; #endif #ifndef NULL +#ifdef __cplusplus +#define NULL 0L +#else #define NULL ((VOID *)0) #endif +#endif #define OS_NULL_BYTE ((UINT8)0xFF) #define OS_NULL_SHORT ((UINT16)0xFFFF) @@ -382,6 +386,12 @@ static inline UINT32 LOS_Align(UINT32 addr, UINT32 boundary) goto LOS_ERREND; \ } while (0) +#ifndef UNUSED +#define UNUSED(var) \ + do { \ + (void)var; \ + } while (0) +#endif #ifdef __cplusplus #if __cplusplus diff --git a/utils/los_debug.c b/utils/los_debug.c new file mode 100644 index 00000000..83566565 --- /dev/null +++ b/utils/los_debug.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "los_debug.h" +#include "stdarg.h" +#include "los_context.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_KERNEL_PRINTF == 1) +STATIC const CHAR *g_logString[] = { + "EMG", + "COMMON", + "ERR", + "WARN", + "INFO", + "DEBUG", +}; +#endif + +STATIC ExcHookFn g_excHook; + +VOID OsExcHookRegister(ExcHookFn excHookFn) +{ + UINTPTR intSave = LOS_IntLock(); + if (!g_excHook) { + g_excHook = excHookFn; + } + LOS_IntRestore(intSave); +} + +VOID OsDoExcHook(EXC_TYPE excType) +{ + UINTPTR intSave = LOS_IntLock(); + if (g_excHook) { + g_excHook(excType); + } + LOS_IntRestore(intSave); +} + +#if (LOSCFG_KERNEL_PRINTF == 1) +INT32 OsLogLevelCheck(INT32 level) +{ + if (level > PRINT_LEVEL) { + return LOS_NOK; + } + + if ((level != LOG_COMMON_LEVEL) && ((level > LOG_EMG_LEVEL) && (level <= LOG_DEBUG_LEVEL))) { + PRINTK("[%s]", g_logString[level]); + } + + return LOS_OK; +} +#endif + +#if (LOSCFG_KERNEL_PRINTF > 1) +WEAK VOID HalConsoleOutput(LogModuleType type, INT32 level, const CHAR *fmt, ...) +{ +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/utils/los_debug.h b/utils/los_debug.h old mode 100644 new mode 100755 index 3ff3d1d6..fef97e0e --- a/utils/los_debug.h +++ b/utils/los_debug.h @@ -36,6 +36,7 @@ #ifndef _LOS_DEBUG_H #define _LOS_DEBUG_H +#include "los_config.h" #include "los_compiler.h" #ifdef __cplusplus @@ -44,26 +45,71 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +#if (LOSCFG_PLATFORM_EXC == 1) +enum MemMangType { + MEM_MANG_MEMBOX, + MEM_MANG_MEMORY, + MEM_MANG_EMPTY +}; -#define LOS_EMG_LEVEL 0 +typedef struct { + UINT32 type; + UINT32 startAddr; + UINT32 size; + VOID *blkAddrArray; +} MemInfo; -#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) - -#ifndef PRINT_LEVEL -#define PRINT_LEVEL LOS_ERR_LEVEL +typedef struct { + enum MemMangType type; + UINT32 startAddr; + UINT32 size; + UINT32 free; + UINT32 blockSize; + UINT32 errorAddr; + UINT32 errorLen; + UINT32 errorOwner; +} MemInfoCB; #endif +typedef enum { + EXC_REBOOT, + EXC_ASSERT, + EXC_STACKOVERFLOW, + EXC_INTERRUPT, + EXC_TYPE_END +} EXC_TYPE; + +typedef VOID (*ExcHookFn)(EXC_TYPE excType); + +VOID OsExcHookRegister(ExcHookFn excHookFn); + +VOID OsDoExcHook(EXC_TYPE excType); + +#define LOG_EMG_LEVEL 0 + +#define LOG_COMMON_LEVEL (LOG_EMG_LEVEL + 1) + +#define LOG_ERR_LEVEL (LOG_COMMON_LEVEL + 1) + +#define LOG_WARN_LEVEL (LOG_ERR_LEVEL + 1) + +#define LOG_INFO_LEVEL (LOG_WARN_LEVEL + 1) + +#define LOG_DEBUG_LEVEL (LOG_INFO_LEVEL + 1) + +#ifndef PRINT_LEVEL +#define PRINT_LEVEL LOG_ERR_LEVEL +#endif + +typedef enum { + LOG_MODULE_KERNEL, + LOG_MODULE_FS, + LOS_MODULE_OTHERS +} LogModuleType; + /** - *@ingroup los_printf - *@brief Format and print data. + * @ingroup los_printf + * @brief Format and print data. * * @par Description: * Print argument(s) according to fmt. @@ -73,62 +119,45 @@ extern "C" { *
  • None
  • * * - *@param fmt [IN] Type char* controls the ouput as in C printf. + * @param type [IN] Type LogModuleType indicates the log type. + * @param level [IN] Type LogLevel indicates the log level. + * @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 + * @retval None + * @par Dependency: + *
    • los_printf.h: the header file that contains the API declaration.
    + * @see LOS_Printf + * @since none */ -extern int printf(char const *str, ...); -#define PRINT printf - - -#if PRINT_LEVEL < LOS_DEBUG_LEVEL -#define PRINT_DEBUG(fmt, args...) +#if (LOSCFG_KERNEL_PRINTF == 1) +extern INT32 printf(const CHAR *fmt, ...); +extern INT32 OsLogLevelCheck(INT32 level); +#define LOS_Printf(type, level, fmt, args...) do { \ + if (!OsLogLevelCheck(level)) { \ + printf(fmt, ##args); \ + } \ +} while (0) +#elif (LOSCFG_KERNEL_PRINTF == 0) +#define LOS_Printf(type, level, fmt, args...) #else -#define PRINT_DEBUG(fmt, args...) do{(PRINT("[DEBUG] "), PRINT(fmt, ##args));}while(0) +extern VOID HalConsoleOutput(LogModuleType type, INT32 level, const CHAR *fmt, ...); +#define LOS_Printf HalConsoleOutput #endif -#if PRINT_LEVEL < LOS_INFO_LEVEL -#define PRINT_INFO(fmt, args...) -#else -#define PRINT_INFO(fmt, args...) do{(PRINT("[INFO] "), PRINT(fmt, ##args));}while(0) -#endif +#define PRINT_DEBUG(fmt, args...) LOS_Printf(LOG_MODULE_KERNEL, LOG_DEBUG_LEVEL, fmt, ##args) +#define PRINT_INFO(fmt, args...) LOS_Printf(LOG_MODULE_KERNEL, LOG_INFO_LEVEL, fmt, ##args) +#define PRINT_WARN(fmt, args...) LOS_Printf(LOG_MODULE_KERNEL, LOG_WARN_LEVEL, fmt, ##args) +#define PRINT_ERR(fmt, args...) LOS_Printf(LOG_MODULE_KERNEL, LOG_ERR_LEVEL, fmt, ##args) +#define PRINTK(fmt, args...) LOS_Printf(LOG_MODULE_KERNEL, LOG_COMMON_LEVEL, fmt, ##args) +#define PRINT_EMG(fmt, args...) LOS_Printf(LOG_MODULE_KERNEL, LOG_EMG_LEVEL, fmt, ##args) -#if PRINT_LEVEL < LOS_WARN_LEVEL -#define PRINT_WARN(fmt, args...) -#else -#define PRINT_WARN(fmt, args...) do{(PRINT("[WARN] "), PRINT(fmt, ##args));}while(0) -#endif - -#if PRINT_LEVEL < LOS_ERR_LEVEL -#define PRINT_ERR(fmt, args...) -#else -#define PRINT_ERR(fmt, args...) do{(PRINT("[ERR] "), PRINT(fmt, ##args));}while(0) -#endif - -#if PRINT_LEVEL < LOS_COMMOM_LEVEL -#define PRINTK(fmt, args...) -#else -#define PRINTK(fmt, args...) PRINT(fmt, ##args) -#endif - -#if PRINT_LEVEL < LOS_EMG_LEVEL -#define PRINT_EMG(fmt, args...) -#else -#define PRINT_EMG(fmt, args...) do{(PRINT("[EMG] "), PRINT(fmt, ##args));}while(0) -#endif - -#define PRINT_RELEASE(fmt, args...) PRINT(fmt, ##args) - -#if PRINT_LEVEL < LOS_ERR_LEVEL +#if PRINT_LEVEL < LOG_ERR_LEVEL #define LOS_ASSERT(judge) #else #define LOS_ASSERT(judge) \ do { \ if ((judge) == 0) { \ + OsDoExcHook(EXC_ASSERT); \ (VOID)LOS_IntLock(); \ PRINT_ERR("ASSERT ERROR! %s, %d, %s\n", __FILE__, __LINE__, __func__); \ while (1) { } \