From 778c8b9930b52eba5691b3155806665a14c2dbc9 Mon Sep 17 00:00:00 2001 From: mamingshuai Date: Thu, 11 Mar 2021 20:30:40 +0800 Subject: [PATCH] update openharmony 1.0.1 --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 13 - .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 15 - .gitignore | 7 + BUILD.gn | 63 + LICENSE | 6 +- NOTICE | 8 + README.md | 77 + README_zh.md | 77 + components/backtrace/BUILD.gn | 40 + components/backtrace/los_backtrace.c | 277 +++ components/backtrace/los_backtrace.h | 162 ++ components/bounds_checking_function/BUILD.gn | 74 + components/cppsupport/BUILD.gn | 37 + components/cppsupport/los_cppsupport.c | 4 +- components/cppsupport/los_cppsupport.h | 4 +- components/cpup/BUILD.gn | 40 + components/cpup/los_cpup.c | 4 +- components/cpup/los_cpup.h | 4 +- components/exchook/BUILD.gn | 42 + components/exchook/los_exc_info.c | 4 +- components/exchook/los_exc_info.h | 6 +- components/exchook/los_exchook.c | 4 +- components/exchook/los_exchook.h | 4 +- components/fs/BUILD.gn | 39 + components/fs/fatfs/BUILD.gn | 47 + components/fs/fatfs/fatfs.c | 148 +- components/fs/fatfs/fatfs.h | 40 +- .../src/file.c => components/fs/fatfs/fs.c | 184 +- .../net/lwip-2.1/enhancement/src/fixme.c | 178 ++ .../net/lwip-2.1/porting/include/arch/cc.h | 104 + .../net/lwip-2.1/porting/include/arch/perf.h | 42 + .../lwip-2.1/porting/include/arch/sys_arch.h | 141 +- .../lwip-2.1/porting/include/lwip/lwipopts.h | 299 +++ .../net/lwip-2.1/porting/include/lwip/netif.h | 77 + .../lwip-2.1/porting/include/lwip/netifapi.h | 54 + .../net/lwip-2.1/porting/include/lwipopts.h | 38 + .../net/lwip-2.1/porting/include/netdb.h | 39 + .../net/lwip-2.1/porting/include/sys/socket.h | 79 + .../net/lwip-2.1/porting/src/driverif.c | 357 +++ .../net/lwip-2.1/porting/src/lwip_init.c | 40 + .../net/lwip-2.1/porting/src/netdb_porting.c | 40 + .../lwip-2.1/porting/src/sockets_porting.c | 181 ++ .../net/lwip-2.1/porting/src/sys_arch.c | 342 +++ components/net/test/lwip_test.h | 78 + components/net/test/net_socket_test_001.c | 43 + components/net/test/net_socket_test_002.c | 116 + components/net/test/net_socket_test_003.c | 252 ++ components/net/test/net_socket_test_004.c | 87 + components/net/test/net_socket_test_005.c | 67 + components/net/test/net_socket_test_006.c | 62 + components/net/test/net_socket_test_007.c | 109 + components/net/test/net_socket_test_008.c | 187 ++ components/net/test/net_socket_test_009.c | 167 ++ components/net/test/net_socket_test_010.c | 162 ++ components/net/test/net_socket_test_011.c | 440 ++++ components/net/test/net_socket_test_012.c | 152 ++ components/net/test/net_socket_test_013.c | 139 ++ components/net/test/test_main.c | 145 ++ figures/OpenHarmony-LiteOS-M核内核架构图.png | Bin 0 -> 17197 bytes ...openharmony-the-liteos-cortex-m-kernel.png | Bin 0 -> 17197 bytes kal/BUILD.gn | 55 + kal/cmsis/BUILD.gn | 41 + kal/cmsis/LICENSE.txt | 201 ++ kal/cmsis/README.OpenSource | 11 + kal/cmsis/cmsis_liteos.c | 4 +- kal/cmsis/cmsis_liteos2.c | 4 +- kal/cmsis/cmsis_os.h | 4 +- kal/cmsis/hos_cmsis_adp.h | 4 +- kal/kal.c | 4 +- kal/kal.h | 4 +- kal/posix/BUILD.gn | 49 + kal/posix/include/COPYRIGHT | 190 ++ kal/posix/include/README | 29 +- kal/posix/include/README.OpenSource | 11 + kal/posix/include/bits/alltypes.h | 28 +- kal/posix/include/libc.h | 4 +- kal/posix/include/limits.h | 3 +- kal/posix/include/pthread.h | 3 +- kal/posix/include/sched.h | 15 +- kal/posix/include/signal.h | 0 kal/posix/include/sys/capability.h | 4 +- kal/posix/src/errno.c | 4 +- kal/posix/src/libc.c | 4 +- kal/posix/src/libc_config.h | 102 +- kal/posix/src/malloc.c | 184 +- kal/posix/src/pthread.c | 10 +- kal/posix/src/pthread_attr.c | 6 +- kal/posix/src/pthread_mutex.c | 4 +- kal/posix/src/semaphore.c | 4 +- kal/posix/src/time.c | 23 +- kernel/BUILD.gn | 66 + .../CMSIS END USER LICENCE AGREEMENT.pdf | Bin 0 -> 24914 bytes kernel/arch/arm/cortex-m3/keil/cmsis/LICENSE | 25 + .../cortex-m3/keil/cmsis/README.OpenSource | 11 + .../arch/arm/cortex-m3/keil/cmsis/README.txt | 37 + .../arch/arm/cortex-m3/keil/los_arch_atomic.h | 7 +- .../arm/cortex-m3/keil/los_arch_context.h | 4 +- .../arm/cortex-m3/keil/los_arch_interrupt.h | 35 +- .../arch/arm/cortex-m3/keil/los_arch_timer.h | 4 +- kernel/arch/arm/cortex-m3/keil/los_context.c | 15 +- kernel/arch/arm/cortex-m3/keil/los_dispatch.S | 4 +- kernel/arch/arm/cortex-m3/keil/los_exc.S | 4 +- .../arch/arm/cortex-m3/keil/los_interrupt.c | 62 +- kernel/arch/arm/cortex-m3/keil/los_startup.s | 48 +- kernel/arch/arm/cortex-m3/keil/los_timer.c | 5 +- kernel/arch/arm/cortex-m33/gcc/BUILD.gn | 46 + .../arch/arm/cortex-m33/gcc/los_arch_atomic.h | 7 +- .../arm/cortex-m33/gcc/los_arch_context.h | 4 +- .../arm/cortex-m33/gcc/los_arch_interrupt.h | 35 +- .../arch/arm/cortex-m33/gcc/los_arch_timer.h | 4 +- kernel/arch/arm/cortex-m33/gcc/los_context.c | 4 +- kernel/arch/arm/cortex-m33/gcc/los_dispatch.S | 4 +- kernel/arch/arm/cortex-m33/gcc/los_exc.S | 4 +- .../arch/arm/cortex-m33/gcc/los_interrupt.c | 62 +- kernel/arch/arm/cortex-m33/gcc/los_timer.c | 5 +- kernel/arch/arm/cortex-m4/gcc/BUILD.gn | 47 + .../arch/arm/cortex-m4/gcc/los_arch_atomic.h | 7 +- .../arch/arm/cortex-m4/gcc/los_arch_context.h | 7 +- .../arm/cortex-m4/gcc/los_arch_interrupt.h | 195 +- .../arch/arm/cortex-m4/gcc/los_arch_timer.h | 4 +- kernel/arch/arm/cortex-m4/gcc/los_context.c | 21 +- kernel/arch/arm/cortex-m4/gcc/los_dispatch.S | 70 +- kernel/arch/arm/cortex-m4/gcc/los_exc.S | 24 +- kernel/arch/arm/cortex-m4/gcc/los_interrupt.c | 160 +- kernel/arch/arm/cortex-m4/gcc/los_mpu.c | 207 ++ kernel/arch/arm/cortex-m4/gcc/los_timer.c | 78 +- .../arch/arm/cortex-m4/iar/los_arch_atomic.h | 7 +- .../arch/arm/cortex-m4/iar/los_arch_context.h | 6 +- .../arm/cortex-m4/iar/los_arch_interrupt.h | 152 +- .../arch/arm/cortex-m4/iar/los_arch_timer.h | 4 +- kernel/arch/arm/cortex-m4/iar/los_context.c | 88 +- kernel/arch/arm/cortex-m4/iar/los_dispatch.S | 4 +- kernel/arch/arm/cortex-m4/iar/los_exc.S | 4 +- kernel/arch/arm/cortex-m4/iar/los_interrupt.c | 99 +- kernel/arch/arm/cortex-m4/iar/los_mpu.c | 4 +- kernel/arch/arm/cortex-m4/iar/los_timer.c | 28 +- kernel/arch/arm/cortex-m7/gcc/BUILD.gn | 46 + .../arch/arm/cortex-m7/gcc/los_arch_atomic.h | 7 +- .../arch/arm/cortex-m7/gcc/los_arch_context.h | 4 +- .../arm/cortex-m7/gcc/los_arch_interrupt.h | 35 +- .../arch/arm/cortex-m7/gcc/los_arch_timer.h | 4 +- kernel/arch/arm/cortex-m7/gcc/los_context.c | 9 +- kernel/arch/arm/cortex-m7/gcc/los_dispatch.S | 4 +- kernel/arch/arm/cortex-m7/gcc/los_exc.S | 4 +- kernel/arch/arm/cortex-m7/gcc/los_interrupt.c | 62 +- kernel/arch/arm/cortex-m7/gcc/los_timer.c | 5 +- .../arch/arm/cortex-m7/iar/los_arch_atomic.h | 7 +- .../arch/arm/cortex-m7/iar/los_arch_context.h | 4 +- .../arm/cortex-m7/iar/los_arch_interrupt.h | 35 +- .../arch/arm/cortex-m7/iar/los_arch_timer.h | 4 +- kernel/arch/arm/cortex-m7/iar/los_context.c | 78 +- kernel/arch/arm/cortex-m7/iar/los_dispatch.S | 4 +- kernel/arch/arm/cortex-m7/iar/los_exc.S | 4 +- kernel/arch/arm/cortex-m7/iar/los_interrupt.c | 62 +- kernel/arch/arm/cortex-m7/iar/los_mpu.c | 5 +- kernel/arch/arm/cortex-m7/iar/los_timer.c | 5 +- kernel/arch/include/los_arch.h | 14 +- kernel/arch/include/los_atomic.h | 4 +- kernel/arch/include/los_context.h | 4 +- kernel/arch/include/los_interrupt.h | 20 +- kernel/arch/include/los_mpu.h | 4 +- kernel/arch/include/los_timer.h | 8 +- kernel/arch/risc-v/riscv32/gcc/BUILD.gn | 47 + .../risc-v/{ => riscv32/gcc}/asm/soc_common.h | 2 +- .../{ => riscv32/gcc}/los_arch_context.h | 5 +- .../{ => riscv32/gcc}/los_arch_interrupt.h | 2 +- .../risc-v/{ => riscv32/gcc}/los_arch_timer.h | 4 +- .../risc-v/{ => riscv32/gcc}/los_context.c | 2 +- .../risc-v/{ => riscv32/gcc}/los_dispatch.S | 2 +- .../arch/risc-v/{ => riscv32/gcc}/los_exc.S | 2 +- .../risc-v/{ => riscv32/gcc}/los_interrupt.c | 126 +- .../arch/risc-v/{ => riscv32/gcc}/los_timer.c | 2 +- kernel/include/los_config.h | 51 +- kernel/include/los_event.h | 4 +- kernel/include/los_membox.h | 6 +- kernel/include/los_memory.h | 21 +- kernel/include/los_mux.h | 4 +- kernel/include/los_queue.h | 4 +- kernel/include/los_sem.h | 4 +- kernel/include/los_swtmr.h | 4 +- kernel/include/los_task.h | 8 +- kernel/include/los_tick.h | 4 +- kernel/src/los_event.c | 4 +- kernel/src/los_init.c | 12 +- kernel/src/los_mux.c | 8 +- kernel/src/los_queue.c | 4 +- kernel/src/los_sem.c | 11 +- kernel/src/los_swtmr.c | 4 +- kernel/src/los_task.c | 9 +- kernel/src/los_tick.c | 6 +- kernel/src/mm/los_membox.c | 4 +- kernel/src/mm/los_memory.c | 252 +- readme.md | 3 - .../Driver/STM32F103/uart.c | 31 + .../cortex-m3_stm32f103_simulator_keil/main.c | 4 +- .../target_config.h | 8 +- .../LICENSE.pdf | Bin 0 -> 89685 bytes .../CMSIS_END_USER_LICENCE_AGREEMENT.pdf | Bin 0 -> 172641 bytes .../Device/ST/STM32F4xx/Include/stm32f4xx.h | 6 +- .../Source/Templates/system_stm32f4xx.c | 8 - .../Libraries/CMSIS/README.txt | 42 + ...MCD-ST Liberty SW License Agreement V2.pdf | Bin 0 -> 17797 bytes .../board/iar_stm32f429ig_fire-challenger.c | 35 +- .../board/iar_stm32f429ig_fire-challenger.h | 31 + .../dprintf.c | 10 +- .../main.c | 8 +- .../project/los_demo.dep | 2063 +++++++++-------- .../project/los_demo.ewp | 10 +- .../project/los_demo.ewt | 9 + .../project/settings/los_demo.crun | 13 - .../project/settings/los_demo.dbgdt | 4 - .../project/settings/los_demo.dnx | 100 - .../project/settings/los_demo.wsdt | 464 ---- .../stm32f4xx_conf.h | 60 +- .../stm32f4xx_it.c | 64 +- .../stm32f4xx_it.h | 28 +- .../target_config.h | 10 +- .../Core/Inc/task_sample.h | 4 +- .../Core/Src/syscalls.c | 191 -- .../Core/Src/task_sample.c | 4 +- .../Drivers/CMSIS/LICENSE.txt | 201 ++ .../Drivers/CMSIS/README.md | 104 + .../cortex-m7_nucleo_f767zi_gcc/LICENSE.pdf | Bin 0 -> 89685 bytes targets/cortex-m7_nucleo_f767zi_gcc/Makefile | 1 - .../target_config.h | 4 +- .../riscv_sifive_fe310_gcc/target_config.h | 90 + utils/BUILD.gn | 42 + utils/los_compiler.h | 4 +- utils/los_debug.c | 22 +- utils/los_debug.h | 7 +- utils/los_error.c | 4 +- utils/los_error.h | 4 +- utils/los_list.h | 4 +- utils/los_reg.h | 4 +- 234 files changed, 9721 insertions(+), 3414 deletions(-) delete mode 100644 .gitee/ISSUE_TEMPLATE.zh-CN.md delete mode 100644 .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md create mode 100644 BUILD.gn create mode 100644 NOTICE create mode 100644 README.md create mode 100644 README_zh.md create mode 100644 components/backtrace/BUILD.gn create mode 100644 components/backtrace/los_backtrace.c create mode 100644 components/backtrace/los_backtrace.h create mode 100755 components/bounds_checking_function/BUILD.gn create mode 100644 components/cppsupport/BUILD.gn create mode 100644 components/cpup/BUILD.gn create mode 100644 components/exchook/BUILD.gn mode change 100644 => 100755 components/exchook/los_exchook.c mode change 100644 => 100755 components/exchook/los_exchook.h create mode 100644 components/fs/BUILD.gn create mode 100644 components/fs/fatfs/BUILD.gn mode change 100644 => 100755 components/fs/fatfs/fatfs.c mode change 100644 => 100755 components/fs/fatfs/fatfs.h rename kal/posix/src/file.c => components/fs/fatfs/fs.c (64%) mode change 100644 => 100755 create mode 100644 components/net/lwip-2.1/enhancement/src/fixme.c create mode 100644 components/net/lwip-2.1/porting/include/arch/cc.h create mode 100644 components/net/lwip-2.1/porting/include/arch/perf.h rename kal/posix/src/pthread_impl.h => components/net/lwip-2.1/porting/include/arch/sys_arch.h (69%) create mode 100644 components/net/lwip-2.1/porting/include/lwip/lwipopts.h create mode 100644 components/net/lwip-2.1/porting/include/lwip/netif.h create mode 100644 components/net/lwip-2.1/porting/include/lwip/netifapi.h create mode 100644 components/net/lwip-2.1/porting/include/lwipopts.h create mode 100644 components/net/lwip-2.1/porting/include/netdb.h create mode 100644 components/net/lwip-2.1/porting/include/sys/socket.h create mode 100644 components/net/lwip-2.1/porting/src/driverif.c create mode 100644 components/net/lwip-2.1/porting/src/lwip_init.c create mode 100644 components/net/lwip-2.1/porting/src/netdb_porting.c create mode 100644 components/net/lwip-2.1/porting/src/sockets_porting.c create mode 100755 components/net/lwip-2.1/porting/src/sys_arch.c create mode 100644 components/net/test/lwip_test.h create mode 100644 components/net/test/net_socket_test_001.c create mode 100644 components/net/test/net_socket_test_002.c create mode 100644 components/net/test/net_socket_test_003.c create mode 100644 components/net/test/net_socket_test_004.c create mode 100644 components/net/test/net_socket_test_005.c create mode 100644 components/net/test/net_socket_test_006.c create mode 100644 components/net/test/net_socket_test_007.c create mode 100644 components/net/test/net_socket_test_008.c create mode 100644 components/net/test/net_socket_test_009.c create mode 100644 components/net/test/net_socket_test_010.c create mode 100644 components/net/test/net_socket_test_011.c create mode 100755 components/net/test/net_socket_test_012.c create mode 100755 components/net/test/net_socket_test_013.c create mode 100644 components/net/test/test_main.c create mode 100644 figures/OpenHarmony-LiteOS-M核内核架构图.png create mode 100644 figures/architecture-of-openharmony-the-liteos-cortex-m-kernel.png create mode 100644 kal/BUILD.gn create mode 100644 kal/cmsis/BUILD.gn create mode 100644 kal/cmsis/LICENSE.txt create mode 100644 kal/cmsis/README.OpenSource create mode 100644 kal/posix/BUILD.gn create mode 100644 kal/posix/include/COPYRIGHT create mode 100644 kal/posix/include/README.OpenSource mode change 100644 => 100755 kal/posix/include/bits/alltypes.h mode change 100755 => 100644 kal/posix/include/libc.h mode change 100644 => 100755 kal/posix/include/signal.h mode change 100644 => 100755 kal/posix/src/pthread_mutex.c create mode 100644 kernel/BUILD.gn create mode 100644 kernel/arch/arm/cortex-m3/keil/cmsis/CMSIS END USER LICENCE AGREEMENT.pdf create mode 100644 kernel/arch/arm/cortex-m3/keil/cmsis/LICENSE create mode 100755 kernel/arch/arm/cortex-m3/keil/cmsis/README.OpenSource create mode 100644 kernel/arch/arm/cortex-m3/keil/cmsis/README.txt create mode 100644 kernel/arch/arm/cortex-m33/gcc/BUILD.gn create mode 100644 kernel/arch/arm/cortex-m4/gcc/BUILD.gn create mode 100644 kernel/arch/arm/cortex-m4/gcc/los_mpu.c mode change 100644 => 100755 kernel/arch/arm/cortex-m4/iar/los_mpu.c create mode 100644 kernel/arch/arm/cortex-m7/gcc/BUILD.gn mode change 100644 => 100755 kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h mode change 100644 => 100755 kernel/arch/arm/cortex-m7/iar/los_dispatch.S mode change 100644 => 100755 kernel/arch/arm/cortex-m7/iar/los_interrupt.c mode change 100644 => 100755 kernel/arch/arm/cortex-m7/iar/los_mpu.c mode change 100644 => 100755 kernel/arch/arm/cortex-m7/iar/los_timer.c mode change 100644 => 100755 kernel/arch/include/los_mpu.h create mode 100644 kernel/arch/risc-v/riscv32/gcc/BUILD.gn rename kernel/arch/risc-v/{ => riscv32/gcc}/asm/soc_common.h (98%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_arch_context.h (96%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_arch_interrupt.h (95%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_arch_timer.h (92%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_context.c (98%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_dispatch.S (99%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_exc.S (98%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_interrupt.c (80%) rename kernel/arch/risc-v/{ => riscv32/gcc}/los_timer.c (94%) mode change 100755 => 100644 kernel/include/los_swtmr.h mode change 100755 => 100644 kernel/include/los_task.h mode change 100755 => 100644 kernel/src/los_swtmr.c mode change 100755 => 100644 kernel/src/los_tick.c delete mode 100644 readme.md create mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/LICENSE.pdf create mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/Libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf create mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/Libraries/CMSIS/README.txt create mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/MCD-ST Liberty SW License Agreement V2.pdf mode change 100755 => 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/main.c mode change 100644 => 100755 targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.dep delete mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/settings/los_demo.crun delete mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/settings/los_demo.dbgdt delete mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/settings/los_demo.dnx delete mode 100644 targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/settings/los_demo.wsdt delete mode 100644 targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/syscalls.c create mode 100644 targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/LICENSE.txt create mode 100644 targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/README.md create mode 100644 targets/cortex-m7_nucleo_f767zi_gcc/LICENSE.pdf mode change 100755 => 100644 targets/cortex-m7_nucleo_f767zi_gcc/target_config.h create mode 100755 targets/riscv_sifive_fe310_gcc/target_config.h create mode 100644 utils/BUILD.gn mode change 100644 => 100755 utils/los_debug.c diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md deleted file mode 100644 index f09d98dd..00000000 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,13 +0,0 @@ -### 该问题是怎么引起的? - - - -### 重现步骤 - - - -### 报错信息 - - - - diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md deleted file mode 100644 index 33948fdc..00000000 --- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,15 +0,0 @@ -### 相关的Issue - - -### 原因(目的、解决的问题等) - - -### 描述(做了什么,变更了什么) - - -### 测试用例(新增、改动、可能影响的功能) - - - - - diff --git a/.gitignore b/.gitignore index df3c495f..f31ded30 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,13 @@ test tags cscope.* *.swp +/**/*_iar/project/ +!los_demo.eww +!los_demo.ewp +!los_demo.ewd +!los_demo.ewt +!los_demo.dep +!*.icf targets/cortex-m7_nucleo_f767zi_gcc/build *.o *.d diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 00000000..35e88fcb --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, 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. + +declare_args() { + enable_ohos_kernel_liteos_m_cppsupport = true + enable_ohos_kernel_liteos_m_cpup = true + enable_ohos_kernel_liteos_m_exchook = true + enable_ohos_kernel_liteos_m_kal = true + enable_ohos_kernel_liteos_m_fs = true + enable_ohos_kernel_liteos_m_backtrace = true +} + +group("kernel") { + deps = [ + "components/bounds_checking_function:sec", + "kernel:kernel", + "utils:utils", + ] + if (enable_ohos_kernel_liteos_m_cppsupport == true) { + deps += [ "components/cppsupport:cppsupport" ] + } + if (enable_ohos_kernel_liteos_m_cpup == true) { + deps += [ "components/cpup:cpup" ] + } + if (enable_ohos_kernel_liteos_m_exchook == true) { + deps += [ "components/exchook:exchook" ] + } + if (enable_ohos_kernel_liteos_m_backtrace == true) { + deps += [ "components/backtrace:backtrace" ] + } + if (enable_ohos_kernel_liteos_m_fs == true) { + deps += [ "components/fs:fs" ] + } + if (enable_ohos_kernel_liteos_m_kal == true) { + deps += [ "kal:kal" ] + } +} diff --git a/LICENSE b/LICENSE index 61fa69e3..208b4cd3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. -Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +Copyright (c) 2020-2021 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: @@ -25,4 +25,4 @@ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..54e56597 --- /dev/null +++ b/NOTICE @@ -0,0 +1,8 @@ +1、In kernel/liteos_m/targets/cortex-m4_stm32f429ig_fire-challenger_iar directory, the files including main.c, +target_config.h, dprintf.c, board/iar_stm32f429ig_fire-challenger.c and board/iar_stm32f429ig_fire-challenger.h, +are under the terms of the licence: kernel/liteos_m/LICENSE file, +and other files are under the terms of the licence: kernel/liteos_m/targets/cortex-m4_stm32f429ig_fire-challenger_iar/LICENSE.pdf file. + +2、In kernel/liteos_m/targets/cortex-m7_nucleo_f767zi_gcc directory, the files including target_config.h, +Core/Inc/task_sample.h and Core/Src/task_sample.c, are under the terms of the licence: kernel/liteos_m/LICENSE file, +and other files are under the terms of the licence: kernel/liteos_m/targets/cortex-m7_nucleo_f767zi_gcc/LICENSE.pdf file. diff --git a/README.md b/README.md new file mode 100644 index 00000000..3d3ad085 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# LiteOS Cortex-M + +- [Introduction](#section11660541593) +- [Directory Structure](#section161941989596) +- [Constraints](#section119744591305) +- [Usage](#section3732185231214) +- [Repositories Involved](#section1371113476307) + +## Introduction + +The OpenHarmony LiteOS Cortex-M is the kernel designed for the lightweight operating system \(OS\) for the Internet of Things \(IoT\) field. It features small size, low power consumption, and high performance. In addition, it has a simple code structure, including the minimum kernel function set, kernel abstraction layer, optional components, and project directory, and is divided into the hardware-related and hardware-irrelevant layers. The hardware-related layers provide unified hardware abstraction layer \(HAL\) interfaces to improve hardware adaptability. The combination and classification of different compilation toolchains and chip architectures meet the requirements of the Artificial Intelligence of Things \(AIoT\) field for rich hardware and compilation toolchains. [Figure1](#fig0865152210223) shows the architecture of the OpenHarmony LiteOS Cortex-M kernel. + +**Figure 1** Architecture of OpenHarmony the LiteOS Cortex-M kernel +![](figures/architecture-of-openharmony-the-liteos-cortex-m-kernel.png "architecture-of-openharmony-the-liteos-cortex-m-kernel") + +## Directory Structure + +``` +/kernel/liteos_m +├── components # Optional components +│ ├── cppsupport # C++ support +│ └── cpup # CPU possession (CPUP) +├── kal # Kernel abstraction layer +│ ├── cmsis # CMSIS-compliant API support +│ └── posix # POSIX API support +├── kernel # Minimum function set support +│ ├── arch # Code of the kernel instruction architecture layer +│ │ ├── arm # Code of the ARM32 architecture +│ │ └── include # APIs exposed externally +│ ├── include # APIs exposed externally +│ └── src # Source code of the minimum function set of the kernel +├── targets # Board-level projects +├── utils # Common code +``` + +## Constraints + +Programming languages: C and C++ + +Currently applicable architectures: Cortex-M3, Cortex-M4, Cortex-M7, and RISC-V + +## Usage + +LiteOS Cortex-M provides projects for three chip architectures, which are located in the **targets** directory. The methods of compiling and using these projects are as follows: + +- Cortex-M3: + +The **kernel/liteos\_m/targets/cortex-m3\_stm32f103\_simulator\_keil** directory is the Keil project directory created based on the STM32F103 chip architecture. You can download and install Keil development tools from the Internet. To compile the Cortex-M3 project, go to the **cortex-m3\_stm32f103\_simulator\_keil/project** directory and double-click the **los\_demo.uvproj** file to open the desired project. After the compilation is successful, burn the file to the corresponding board using JLINK or STM32 ST-LINK Utility. + +- Cortex-M4: + +The **kernel/liteos\_m/targets/cortex-m4\_stm32f429ig\_fire-challenger\_iar** directory is the IAR project directory created based on the STM32F429IG chip architecture. You can download and install IAR development tools from the Internet. To compile the Cortex-M4 project, go to the **cortex-m4\_stm32f429ig\_fire-challenger\_iar/project** directory and double-click the **los\_demo.eww** file to open the desired project. After the compilation is successful, burn the file to the corresponding board using JLINK or STM32 ST-LINK Utility. + +- Cortex-M7: + +The **kernel/liteos\_m/targets/cortex-m7\_nucleo\_f767zi\_gcc** directory is the Makefile project directory created based on the STM32F767ZI chip architecture. The compilation commands are as follows: + +``` +cd kernel/liteos_m/targets/cortex-m7_nucleo_f767zi_gcc +make clean; make +``` + +After the compilation is successful, the executable file **NUCLEO-F767.hex** is generated in the **cortex-m7\_nucleo\_f767zi\_gcc/build** directory. Burn the file to the corresponding board using STM32 ST-LINK Utility. + +## Change Log + +v1.0.1 +1. removed these KAL apis: `KalThreadGetInfo`,`KalDelayUs`,`KalTimerCreate`,`KalTimerStart`,`KalTimerChange`,`KalTimerStop`,`KalTimerDelete`,`KalTimerIsRunning`,`KalTickToMs`,`KalMsToTick`,`KalGetMemInfo` +2. add some POSIX apis + +v1.0 +1. first release + +## Repositories Involved + +**[kernel\_liteos\_m](https://gitee.com/openharmony/kernel_liteos_m)** + diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 00000000..0ec989a5 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,77 @@ +# LiteOS-M内核 + +- [简介](#section11660541593) +- [目录](#section161941989596) +- [约束](#section119744591305) +- [使用说明](#section3732185231214) +- [相关仓](#section1371113476307) + +## 简介 + +OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点,其代码结构简单,主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等,分为硬件相关层以及硬件无关层,硬件相关层提供统一的HAL(Hardware Abstraction Layer)接口,提升硬件易适配性,不同编译工具链和芯片架构的组合分类,满足AIoT类型丰富的硬件和编译工具链的拓展。其架构图如图1所示: + +**图 1** OpenHarmony LiteOS-M核内核架构图 +![](figures/OpenHarmony-LiteOS-M核内核架构图.png "OpenHarmony-LiteOS-M核内核架构图") + +## 目录 + +``` +/kernel/liteos_m +├── components # 可选组件 +│ ├── cppsupport # C++支持 +│ └── cpup # CPUP功能 +├── kal # 内核抽象层 +│ ├── cmsis # cmsis标准接口支持 +│ └── posix # posix标准接口支持 +├── kernel # 内核最小功能集支持 +│ ├── arch # 内核指令架构层代码 +│ │ ├── arm # arm32架构的代码 +│ │ └── include # 对外接口存放目录 +│ ├── include # 对外接口存放目录 +│ └── src # 内核最小功能集源码 +├── targets # 板级工程目录 +├── utils # 通用公共目录 +``` + +## 约束 + +开发语言:C/C++; + +适用架构:当前只适用于cortex-m3、cortex-m4、cortex-m7、risc-v芯片架构。 + +## 使用说明 + +LiteOS-M内核提供了三种芯片架构的工程位于targets目录。三种架构的工程编译及使用方式如下: + +- cortex-m3: + +kernel/liteos\_m/targets/cortex-m3\_stm32f103\_simulator\_keil目录是基于STM32F103芯片架构构建的keil工程目录,keil开发工具可通过网络下载并安装。进入cortex-m3\_stm32f103\_simulator\_keil/project目录,双击los\_demo.uvproj文件即可打开相应工程,编译成功后即可通过JLINK或者STM32 ST-LINK Utility烧录至对应单板。 + +- cortex-m4: + +kernel/liteos\_m/targets/cortex-m4\_stm32f429ig\_fire-challenger\_iar目录是基于STM32F429IG芯片架构构建的IAR工程目录,IAR开发工具可通过网络下载并安装。进入cortex-m4\_stm32f429ig\_fire-challenger\_iar/project目录,双击los\_demo.eww文件即可打开相应工程,编译成功后即可通过JLINK或者STM32 ST-LINK Utility烧录至对应单板。 + +- cortex-m7: + +kernel/liteos\_m/targets/cortex-m7\_nucleo\_f767zi\_gcc目录是基于STM32F767ZI芯片架构构建的Makefile工程目录。编译方式如下: + +``` +cd kernel/liteos_m/targets/cortex-m7_nucleo_f767zi_gcc +make clean; make +``` + +编译成功后在cortex-m7\_nucleo\_f767zi\_gcc/build目录下生成NUCLEO-F767.hex可执行文件,通过烧录工具STM32 ST-LINK Utility烧录到对应的单板。 + +## 修改日志 + +v1.0.1 +1. 删除以下KAL接口: `KalThreadGetInfo`,`KalDelayUs`,`KalTimerCreate`,`KalTimerStart`,`KalTimerChange`,`KalTimerStop`,`KalTimerDelete`,`KalTimerIsRunning`,`KalTickToMs`,`KalMsToTick`,`KalGetMemInfo` +2. 添加部分POSIX接口 + +v1.0 +1. 首次发布 + +## 相关仓 + +**[kernel\_liteos\_m](https://gitee.com/openharmony/kernel_liteos_m)** + diff --git a/components/backtrace/BUILD.gn b/components/backtrace/BUILD.gn new file mode 100644 index 00000000..c6839eac --- /dev/null +++ b/components/backtrace/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("backtrace") { + sources = [ "los_backtrace.c" ] + + include_dirs = [ + "../../kernel/include", + "../../kernel/arch/include", + "../../utils", + "./", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/components/backtrace/los_backtrace.c b/components/backtrace/los_backtrace.c new file mode 100644 index 00000000..11b86f4c --- /dev/null +++ b/components/backtrace/los_backtrace.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_backtrace.h" +#include "los_task.h" +#include "los_debug.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#if (LOSCFG_BACKTRACE_TYPE != 0) +#if (LOSCFG_BACKTRACE_TYPE == 1) +#define OS_BACKTRACE_START 2 +/* Thumb instruction, so the pc must be an odd number */ +#define OS_IS_THUMB_INSTRUCTION(pc) ((pc & 0x1) == 1) + +/* BL or BLX instruction flag. */ +#define OS_BL_INS_MASK 0xF800 +#define OS_BL_INS_HIGH 0xF800 +#define OS_BL_INS_LOW 0xF000 +#define OS_BLX_INX_MASK 0xFF00 +#define OS_BLX_INX 0x4700 + +#if defined(__ICCARM__) || defined(__CC_ARM) +STATIC INLINE UINTPTR HalSpGet(VOID) +{ + UINTPTR sp; + __asm("mov %0, sp" : "=r" (sp)); + return sp; +} + +STATIC INLINE UINTPTR HalPspGet(VOID) +{ + UINTPTR psp; + __asm("mrs %0, psp" : "=r" (psp)); + return psp; +} + +STATIC INLINE UINTPTR HalMspGet(VOID) +{ + UINTPTR msp; + __asm("mrs %0, msp" : "=r" (msp)); + return msp; +} +#elif defined(__CLANG_ARM) || defined(__GNUC__) +STATIC INLINE UINTPTR HalSpGet(VOID) +{ + UINTPTR sp; + __asm volatile("mov %0, sp" : "=r" (sp)); + return sp; +} + +STATIC INLINE UINTPTR HalPspGet(VOID) +{ + UINTPTR psp; + __asm volatile("mrs %0, psp" : "=r" (psp)); + return psp; +} + +STATIC INLINE UINTPTR HalMspGet(VOID) +{ + UINTPTR msp; + __asm volatile("mrs %0, msp" : "=r" (msp)); + return msp; +} +#else +#error Unknown compiler. +#endif + +STATIC INLINE BOOL OsInsIsBlOrBlx(UINTPTR addr) +{ + UINT16 ins1 = *((UINT16 *)addr); + UINT16 ins2 = *((UINT16 *)(addr + 2)); /* 2: Thumb instruction is two bytes. */ + + if (((ins2 & OS_BL_INS_MASK) == OS_BL_INS_HIGH) && + ((ins1 & OS_BL_INS_MASK) == OS_BL_INS_LOW)) { + return TRUE; + } else if ((ins2 & OS_BLX_INX_MASK) == OS_BLX_INX) { + return TRUE; + } else { + return FALSE; + } +} + +STATIC INLINE VOID OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd) +{ + if (HalSpGet() != HalPspGet()) { + *stackStart = HalMspGet(); + *stackEnd = CSTACK_END_ADDR; + } else { + UINT32 taskID = LOS_CurTaskIDGet(); + LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); + *stackStart = HalSpGet(); + *stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize; + } +} + +STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp) +{ + UINTPTR pc; + BOOL ret; + + /* The stack space pointed to by the current SP may store the LR, + so need decrease a word to PC. */ + pc = *((UINTPTR *)sp) - sizeof(UINTPTR); + + if (!OS_IS_THUMB_INSTRUCTION(pc)) { + return 0; + } + + /* PC in thumb mode is an odd number, fix the PC address by decreasing one byte. */ + pc = *((UINTPTR *)sp) - 1; + + ret = OsStackDataIsCodeAddr(pc); + if (ret == FALSE) { + return 0; + } + + ret = OsInsIsBlOrBlx(pc - sizeof(UINTPTR)); + if (ret == FALSE) { + return 0; + } + + return pc; +} + +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount) +{ + if (LR == NULL) { + return; + } + + UINTPTR stackStart; + UINTPTR stackEnd; + UINT32 count = 0; + UINT32 index = 0; + UINTPTR sp; + UINTPTR pc; + + OsStackAddrGet(&stackStart, &stackEnd); + + /* Traverse the stack space and find the LR address. */ + for (sp = stackStart; sp < stackEnd; sp += sizeof(UINTPTR)) { + pc = OsAddrIsValid(sp); + if ((pc != 0) && (count < LRSize)) { + if (index++ < jumpCount) { + continue; + } + LR[count] = pc; + count++; + if (count == LRSize) { + break; + } + } + } + + if (count < LRSize) { + LR[count] = 0; + } +} +#elif (LOSCFG_BACKTRACE_TYPE == 2) +STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value); +#define OS_BACKTRACE_START 1 +#define OS_RA_OFFSET 4 +#define OS_FP_OFFSET 8 +#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0) +#define OS_FP_CHECK(value) (((UINT32)(value) != FP_INIT_VALUE) && OS_FP_ALIGN(value)) + +STATIC INLINE UINTPTR OsFpGet(VOID) +{ + UINTPTR fp = 0; + __asm volatile("mv %0, s0" : "=r"(fp)); + dsb(); + return fp; +} + +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount) +{ + UINT32 backFp = OsFpGet(); + UINT32 tmpFp; + UINT32 backRa; + UINT32 count = 0; + UINT32 index = 0; + + if (LR == NULL) { + return; + } + + while (OS_FP_CHECK(backFp)) { + tmpFp = backFp; + backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET)); + backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET)); + if (index++ < jumpCount) { + continue; + } + + LR[count] = backRa; + count++; + if ((count == LRSize) || (backFp == tmpFp) || + (!OsStackDataIsCodeAddr(backRa))) { + break; + } + } + + if (count < LRSize) { + LR[count] = 0; + } +} +#else +#error Unknown backtrace type. +#endif + +VOID LOS_BackTrace(VOID) +{ + UINTPTR LR[BACKTRACE_MAX_DEPTH] = {0}; + UINT32 index; + + LOS_RecordLR(LR, BACKTRACE_MAX_DEPTH, OS_BACKTRACE_START); + + if (LOS_TaskIsRunning()) { + PRINTK("taskName = %s\n", g_losTask.runTask->taskName); + PRINTK("taskID = %u\n", g_losTask.runTask->taskID); + } + + PRINTK("----- traceback start -----\r\n"); + for (index = 0; index < BACKTRACE_MAX_DEPTH; index++) { + if (LR[index] == 0) { + break; + } + PRINTK("traceback %d -- lr = 0x%x\r\n", index, LR[index]); + } + PRINTK("----- traceback end -----\r\n"); +} + +VOID LOS_BackTraceInit(VOID) +{ + OsBackTraceHookSet(LOS_RecordLR); +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + diff --git a/components/backtrace/los_backtrace.h b/components/backtrace/los_backtrace.h new file mode 100644 index 00000000..1399b091 --- /dev/null +++ b/components/backtrace/los_backtrace.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_BACKTRACE_H +#define _LOS_BACKTRACE_H + +#include "los_config.h" +#include "los_arch_interrupt.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#define BACKTRACE_MAX_DEPTH LOSCFG_BACKTRACE_DEPTH + +#if (LOSCFG_BACKTRACE_TYPE != 0) +#if (LOSCFG_BACKTRACE_TYPE == 1) +/* The default name of the code section and CSTACK section are given below, + and the user can be adjust it according to the linker script file. */ +#if defined(__ICCARM__) +/* The default code section name is .text */ +#define CODE_SECTION_NAME ".text" +/* The default C stack section name is CSTACK */ +#define CSTACK_SECTION_NAME "CSTACK" +#pragma section=CODE_SECTION_NAME +#pragma section=CSTACK_SECTION_NAME + +/* Default only one code section. In fact, there may be more than one. + You can define more than one and modify the OsStackDataIsCodeAddr function + to support searching in multiple code sections */ +#define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME)) +#define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME)) +#define CSTACK_START_ADDR ((UINTPTR)__section_begin(CSTACK_SECTION_NAME)) +#define CSTACK_END_ADDR ((UINTPTR)__section_end(CSTACK_SECTION_NAME)) +#elif defined(__CC_ARM) || defined(__CLANG_ARM) +/* The default code section name is ER_IROM1 */ +#define CODE_SECTION_NAME ER_IROM1 +/* The default C stack section name is STACK */ +#define CSTACK_SECTION_NAME STACK + +#define SECTION_START(_name_) _name_##$$Base +#define SECTION_END(_name_) _name_##$$Limit +#define CSTACK_SECTION_START(_name_) SECTION_START(_name_) +#define CSTACK_SECTION_END(_name_) SECTION_END(_name_) + +#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base +#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit +#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_) +#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_) + +extern CHAR *CSTACK_SECTION_START(CSTACK_SECTION_NAME); +extern CHAR *CSTACK_SECTION_END(CSTACK_SECTION_NAME); +extern CHAR *CODE_SECTION_START(CODE_SECTION_NAME); +extern CHAR *CODE_SECTION_END(CODE_SECTION_NAME); + +/* Default only one code section. In fact, there may be more than one. + You can define more than one and modify the OsStackDataIsCodeAddr function + to support searching in multiple code sections */ +#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START(CODE_SECTION_NAME)) +#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END(CODE_SECTION_NAME)) +#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START(CSTACK_SECTION_NAME)) +#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END(CSTACK_SECTION_NAME)) +#elif defined(__GNUC__) +/* The defalut code section start address */ +#define CODE_SECTION_START _stext +/* The defalut code section end address */ +#define CODE_SECTION_END _etext +/* The default C stack section start address */ +#define CSTACK_SECTION_START _sstack +/* The default C stack section end address */ +#define CSTACK_SECTION_END _estack + +extern CHAR *CODE_SECTION_START; +extern CHAR *CODE_SECTION_END; +extern CHAR *CSTACK_SECTION_START; +extern CHAR *CSTACK_SECTION_END; + +/* Default only one code section. In fact, there may be more than one. + You can define more than one and modify the OsStackDataIsCodeAddr function + to support searching in multiple code sections */ +#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) +#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) +#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) +#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) +#else +#error Unknown compiler. +#endif +#elif (LOSCFG_BACKTRACE_TYPE == 2) +#if defined(__GNUC__) +/* The defalut code section start address */ +#define CODE_SECTION_START __text_start +/* The defalut code section end address */ +#define CODE_SECTION_END __text_end + +extern CHAR *CODE_SECTION_START; +extern CHAR *CODE_SECTION_END; + +#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) +#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) +#else +#error Unknown compiler. +#endif +#endif + +/* This function is used to judge whether the data in the stack is a code section address. + The default code section is only one, but there may be more than one. Modify the + judgment condition to support multiple code sections. */ +STATIC INLINE BOOL OsStackDataIsCodeAddr(UINTPTR value) +{ + if ((value >= CODE_START_ADDR) && (value < CODE_END_ADDR)) { + return TRUE; + } + return FALSE; +} + +/* This function is currently used to register the memory leak check hook, + other uses do not need to be called temporarily. */ +VOID LOS_BackTraceInit(VOID); + +/* This function is used to print the function call stack. */ +VOID LOS_BackTrace(VOID); + +/* This function is used to record the function call stack. */ +VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif \ No newline at end of file diff --git a/components/bounds_checking_function/BUILD.gn b/components/bounds_checking_function/BUILD.gn new file mode 100755 index 00000000..6c03fa4d --- /dev/null +++ b/components/bounds_checking_function/BUILD.gn @@ -0,0 +1,74 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("sec") { + include_dirs = [ "//third_party/bounds_checking_function/include" ] + + sources = [ + "//third_party/bounds_checking_function/src/fscanf_s.c", + "//third_party/bounds_checking_function/src/fwscanf_s.c", + "//third_party/bounds_checking_function/src/gets_s.c", + "//third_party/bounds_checking_function/src/memcpy_s.c", + "//third_party/bounds_checking_function/src/memmove_s.c", + "//third_party/bounds_checking_function/src/memset_s.c", + "//third_party/bounds_checking_function/src/scanf_s.c", + "//third_party/bounds_checking_function/src/securecutil.c", + "//third_party/bounds_checking_function/src/secureinput_a.c", + "//third_party/bounds_checking_function/src/secureinput_w.c", + "//third_party/bounds_checking_function/src/secureprintoutput_a.c", + "//third_party/bounds_checking_function/src/secureprintoutput_w.c", + "//third_party/bounds_checking_function/src/snprintf_s.c", + "//third_party/bounds_checking_function/src/sprintf_s.c", + "//third_party/bounds_checking_function/src/sscanf_s.c", + "//third_party/bounds_checking_function/src/strcat_s.c", + "//third_party/bounds_checking_function/src/strcpy_s.c", + "//third_party/bounds_checking_function/src/strncat_s.c", + "//third_party/bounds_checking_function/src/strncpy_s.c", + "//third_party/bounds_checking_function/src/strtok_s.c", + "//third_party/bounds_checking_function/src/swprintf_s.c", + "//third_party/bounds_checking_function/src/swscanf_s.c", + "//third_party/bounds_checking_function/src/vfscanf_s.c", + "//third_party/bounds_checking_function/src/vfwscanf_s.c", + "//third_party/bounds_checking_function/src/vscanf_s.c", + "//third_party/bounds_checking_function/src/vsnprintf_s.c", + "//third_party/bounds_checking_function/src/vsprintf_s.c", + "//third_party/bounds_checking_function/src/vsscanf_s.c", + "//third_party/bounds_checking_function/src/vswprintf_s.c", + "//third_party/bounds_checking_function/src/vswscanf_s.c", + "//third_party/bounds_checking_function/src/vwscanf_s.c", + "//third_party/bounds_checking_function/src/wcscat_s.c", + "//third_party/bounds_checking_function/src/wcscpy_s.c", + "//third_party/bounds_checking_function/src/wcsncat_s.c", + "//third_party/bounds_checking_function/src/wcsncpy_s.c", + "//third_party/bounds_checking_function/src/wcstok_s.c", + "//third_party/bounds_checking_function/src/wmemcpy_s.c", + "//third_party/bounds_checking_function/src/wmemmove_s.c", + "//third_party/bounds_checking_function/src/wscanf_s.c", + ] +} diff --git a/components/cppsupport/BUILD.gn b/components/cppsupport/BUILD.gn new file mode 100644 index 00000000..d74632fc --- /dev/null +++ b/components/cppsupport/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("cppsupport") { + sources = [ "los_cppsupport.c" ] + + include_dirs = [ + "../../utils", + "./", + ] +} diff --git a/components/cppsupport/los_cppsupport.c b/components/cppsupport/los_cppsupport.c index e0901eb6..dcdbe8bc 100644 --- a/components/cppsupport/los_cppsupport.c +++ b/components/cppsupport/los_cppsupport.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/cppsupport/los_cppsupport.h b/components/cppsupport/los_cppsupport.h index b1229a7e..6ede711b 100644 --- a/components/cppsupport/los_cppsupport.h +++ b/components/cppsupport/los_cppsupport.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/cpup/BUILD.gn b/components/cpup/BUILD.gn new file mode 100644 index 00000000..acd1d086 --- /dev/null +++ b/components/cpup/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("cpup") { + sources = [ "los_cpup.c" ] + + include_dirs = [ + "../../kernel/include", + "../../kernel/arch/include", + "../../utils", + "./", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/components/cpup/los_cpup.c b/components/cpup/los_cpup.c index e077ebae..4456d592 100755 --- a/components/cpup/los_cpup.c +++ b/components/cpup/los_cpup.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/cpup/los_cpup.h b/components/cpup/los_cpup.h index 16dc9d84..b73d67dd 100644 --- a/components/cpup/los_cpup.h +++ b/components/cpup/los_cpup.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/exchook/BUILD.gn b/components/exchook/BUILD.gn new file mode 100644 index 00000000..3550c550 --- /dev/null +++ b/components/exchook/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("exchook") { + sources = [ + "los_exc_info.c", + "los_exchook.c", + ] + include_dirs = [ + "../../kernel/arch/include", + "../../kernel/include", + "../../utils", + "./", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/components/exchook/los_exc_info.c b/components/exchook/los_exc_info.c index 4d74f969..dd412e16 100644 --- a/components/exchook/los_exc_info.c +++ b/components/exchook/los_exc_info.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/exchook/los_exc_info.h b/components/exchook/los_exc_info.h index dc2f98da..27a6bc92 100644 --- a/components/exchook/los_exc_info.h +++ b/components/exchook/los_exc_info.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -41,6 +41,7 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +#if (LOSCFG_PLATFORM_EXC == 1) #define INFO_TYPE_AND_SIZE 8 #define MAX_SCENE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(ExcInfo) + sizeof(EXC_CONTEXT_S)) @@ -108,6 +109,7 @@ typedef struct { VOID OsExcMsgDumpInit(VOID); extern UINT8 g_excMsgArray[MAX_EXC_MEM_SIZE]; +#endif #ifdef __cplusplus #if __cplusplus diff --git a/components/exchook/los_exchook.c b/components/exchook/los_exchook.c old mode 100644 new mode 100755 index 7583f53c..78f5de87 --- a/components/exchook/los_exchook.c +++ b/components/exchook/los_exchook.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/exchook/los_exchook.h b/components/exchook/los_exchook.h old mode 100644 new mode 100755 index 8bc5760a..960fa44a --- a/components/exchook/los_exchook.h +++ b/components/exchook/los_exchook.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/components/fs/BUILD.gn b/components/fs/BUILD.gn new file mode 100644 index 00000000..094d2edc --- /dev/null +++ b/components/fs/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, 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. + +declare_args() { + enable_ohos_kernel_liteos_m_fatfs = true +} + +group("fs") { + deps = [] + if (enable_ohos_kernel_liteos_m_fatfs == true) { + deps += [ "fatfs:fatfs" ] + } +} diff --git a/components/fs/fatfs/BUILD.gn b/components/fs/fatfs/BUILD.gn new file mode 100644 index 00000000..ee0075cd --- /dev/null +++ b/components/fs/fatfs/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("fatfs") { + sources = [ + "fatfs.c", + "fs.c", + ] + + include_dirs = [ + "../../../kernel/arch/include", + "../../../kernel/include", + "../../../utils", + "../../../kal/cmsis", + "../../../kal", + "../../../kal/posix/include", + "./", + "//third_party/bounds_checking_function/include", + "//third_party/FatFs/source/", + ] +} diff --git a/components/fs/fatfs/fatfs.c b/components/fs/fatfs/fatfs.c old mode 100644 new mode 100755 index 4b7d4346..363bc8a9 --- a/components/fs/fatfs/fatfs.c +++ b/components/fs/fatfs/fatfs.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,21 +29,18 @@ * 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 "ff.h" +#if FF_USE_EXPAND +#define _GNU_SOURCE +#endif +#include "fatfs.h" #include "errno.h" +#include "limits.h" #include "pthread.h" #include "time.h" #include "securec.h" -#include "ff.h" +#include "los_compiler.h" #include "los_debug.h" -#include "fatfs.h" #include "cmsis_os.h" #define FS_SUCCESS 0 @@ -55,10 +52,6 @@ #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 */ @@ -327,9 +320,9 @@ static int FatfsErrno(int result) return status; } -int mount(const char *source, const char *target, - const char *filesystemtype, unsigned long mountflags, - const void *data) +int fatfs_mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data) { INT32 index; FRESULT res; @@ -386,7 +379,7 @@ OUT: return ret; } -int umount(const char *target) +int fatfs_umount(const char *target) { FRESULT res; INT32 ret; @@ -482,7 +475,7 @@ static int CloseAll(int index) return FS_SUCCESS; } -int umount2(const char *target, int flag) +int fatfs_umount2(const char *target, int flag) { INT32 index; INT32 ret; @@ -546,7 +539,7 @@ OUT: return ret; } -int open(const char *path, int oflag, ...) +int fatfs_open(const char *path, int oflag, ...) { FRESULT res; UINT32 i; @@ -626,7 +619,7 @@ OUT: return ret; } -int close(int fd) +int fatfs_close(int fd) { FRESULT res; INT32 ret; @@ -667,7 +660,7 @@ int close(int fd) return FS_SUCCESS; } -ssize_t read(int fd, void *buf, size_t nbyte) +ssize_t fatfs_read(int fd, void *buf, size_t nbyte) { FRESULT res; INT32 ret; @@ -699,7 +692,7 @@ ssize_t read(int fd, void *buf, size_t nbyte) return (ssize_t)lenRead; } -ssize_t write(int fd, const void *buf, size_t nbyte) +ssize_t fatfs_write(int fd, const void *buf, size_t nbyte) { FRESULT res; INT32 ret; @@ -743,7 +736,7 @@ ERROUT: return FS_FAILURE; } -off_t lseek(int fd, off_t offset, int whence) +off_t fatfs_lseek(int fd, off_t offset, int whence) { FRESULT res; INT32 ret; @@ -787,7 +780,7 @@ ERROUT: } /* Remove the specified FILE */ -int unlink(const char *path) +int fatfs_unlink(const char *path) { FRESULT res; INT32 ret; @@ -833,7 +826,7 @@ OUT: } /* Return information about a file */ -int fstat(int fd, struct stat *buf) +int fatfs_fstat(int fd, struct stat *buf) { INT32 ret; @@ -864,7 +857,7 @@ int fstat(int fd, struct stat *buf) return FS_SUCCESS; } -int stat(const char *__restrict path, struct stat *__restrict buf) +int fatfs_stat(const char *path, struct stat *buf) { FRESULT res; FILINFO fileInfo = {0}; @@ -918,7 +911,7 @@ OUT: } /* Synchronize all changes to Flash */ -int fsync(int fd) +int fatfs_fsync(int fd) { FRESULT res; INT32 ret; @@ -952,7 +945,7 @@ OUT: return ret; } -int mkdir(const char *path, mode_t mode) +int fatfs_mkdir(const char *path, mode_t mode) { FRESULT res; INT32 ret; @@ -996,7 +989,7 @@ OUT: return ret; } -DIR *opendir(const char *dirName) +DIR *fatfs_opendir(const char *dirName) { FRESULT res; UINT32 openNum = 0; @@ -1058,7 +1051,7 @@ ERROUT: return NULL; } -struct dirent *readdir(DIR *dir) +struct dirent *fatfs_readdir(DIR *dir) { FRESULT res; INT32 ret; @@ -1095,7 +1088,7 @@ struct dirent *readdir(DIR *dir) return &g_retValue; } -int closedir(DIR *dir) +int fatfs_closedir(DIR *dir) { FRESULT res; INT32 ret; @@ -1126,7 +1119,7 @@ int closedir(DIR *dir) return FS_SUCCESS; } -int rmdir(const char *path) +int fatfs_rmdir(const char *path) { FRESULT res; INT32 ret; @@ -1170,7 +1163,7 @@ OUT: return ret; } -int rename(const char *oldName, const char *newName) +int fatfs_rename(const char *oldName, const char *newName) { FRESULT res; INT32 ret; @@ -1214,7 +1207,7 @@ OUT: return ret; } -int statfs(const char *path, struct statfs *buf) +int fatfs_statfs(const char *path, struct statfs *buf) { FATFS *fs = NULL; UINT32 freeClust; @@ -1264,6 +1257,85 @@ OUT: return ret; } +static int do_truncate(int fd, off_t length, UINT count) +{ + FRESULT res; + INT32 ret = FR_OK; + DWORD csz; + + csz = (DWORD)(g_handle[fd].fil.obj.fs)->csize * SS(g_handle[fd].fil.obj.fs); /* Cluster size */ + if (length > csz * count) { +#if FF_USE_EXPAND + res = f_expand(&g_handle[fd].fil, 0, (FSIZE_t)(length), FALLOC_FL_KEEP_SIZE); +#else + errno = ENOSYS; + ret = FS_FAILURE; + return ret; +#endif + } else if (length < csz * count) { + res = f_truncate(&g_handle[fd].fil, (FSIZE_t)length); + } + + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + return ret; + } + + g_handle[fd].fil.obj.objsize = length; /* Set file size to length */ + g_handle[fd].fil.flag |= 0x40; /* Set modified flag */ + + return ret; +} + +int fatfs_ftruncate(int fd, off_t length) +{ + FRESULT res; + INT32 ret; + UINT count; + DWORD fclust; + + if (!IsValidFd(fd)) { + errno = EBADF; + return FS_FAILURE; + } + + if ((length < 0) || (length > UINT_MAX)) { + errno = EINVAL; + 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_getclustinfo(&g_handle[fd].fil, &fclust, &count); + if (res != FR_OK) { + errno = FatfsErrno(res); + ret = FS_FAILURE; + goto OUT; + } + + ret = do_truncate(fd, length, count); + if (ret != FR_OK) { + goto OUT; + } + + ret = FS_SUCCESS; + +OUT: + FsUnlock(); + return ret; +} + int fatfs_fdisk(int pdrv, const unsigned int *partTbl) { INT32 index; @@ -1348,4 +1420,4 @@ int fatfs_format(const char *dev, int sectors, int option) OUT: FsUnlock(); return ret; -} \ No newline at end of file +} diff --git a/components/fs/fatfs/fatfs.h b/components/fs/fatfs/fatfs.h old mode 100644 new mode 100755 index c5c494a9..21ad1e7f --- a/components/fs/fatfs/fatfs.h +++ b/components/fs/fatfs/fatfs.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -32,17 +32,51 @@ #ifndef _FATFS_H #define _FATFS_H +#include "fcntl.h" +#include "dirent.h" +#include "unistd.h" +#include "sys/mount.h" +#include "sys/stat.h" +#include "sys/statfs.h" +#include "fs_config.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ +#ifndef FAT_MAX_OPEN_FILES +#define FAT_MAX_OPEN_FILES 50 +#endif /* FAT_MAX_OPEN_FILES */ + /* Format options */ #define FMT_FAT 0x01 #define FMT_FAT32 0x02 #define FMT_ANY 0x07 +int fatfs_mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data); +int fatfs_umount(const char *target); +int fatfs_umount2(const char *target, int flag); +int fatfs_open(const char *path, int oflag, ...); +int fatfs_close(int fd); +ssize_t fatfs_read(int fd, void *buf, size_t nbyte); +ssize_t fatfs_write(int fd, const void *buf, size_t nbyte); +off_t fatfs_lseek(int fd, off_t offset, int whence); +int fatfs_unlink(const char *path); +int fatfs_fstat(int fd, struct stat *buf); +int fatfs_stat(const char *path, struct stat *buf); +int fatfs_fsync(int fd); +int fatfs_mkdir(const char *path, mode_t mode); +DIR *fatfs_opendir(const char *dirName); +struct dirent *fatfs_readdir(DIR *dir); +int fatfs_closedir(DIR *dir); +int fatfs_rmdir(const char *path); +int fatfs_rename(const char *oldName, const char *newName); +int fatfs_statfs(const char *path, struct statfs *buf); +int fatfs_ftruncate(int fd, off_t length); + /** * @brief divide a physical drive (SD card, U disk, and MMC card), this function is OHOS-specific * @param pdrv physical drive number. @@ -77,4 +111,4 @@ int fatfs_format(const char *dev, int sectors, int option); #endif /* __cplusplus */ #endif /* __cplusplus */ -#endif /* _FATFS_H */ \ No newline at end of file +#endif /* _FATFS_H */ diff --git a/kal/posix/src/file.c b/components/fs/fatfs/fs.c old mode 100644 new mode 100755 similarity index 64% rename from kal/posix/src/file.c rename to components/fs/fatfs/fs.c index ff2d99f4..7435e822 --- a/kal/posix/src/file.c +++ b/components/fs/fatfs/fs.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,14 +29,18 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include -#include - -#include "hks_client.h" +#include "fatfs.h" +#include "dirent.h" +#include "errno.h" +#include "fcntl.h" +#include "securec.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "sys/mount.h" +#include "sys/statfs.h" +#include "sys/stat.h" +#include "unistd.h" #ifdef LOSCFG_NET_LWIP_SACK #include "lwip/lwipopts.h" @@ -44,16 +48,21 @@ #else #define CONFIG_NSOCKET_DESCRIPTORS 0 #endif -#define CONFIG_NFILE_DESCRIPTORS 1 /* only for random currently */ -#define RANDOM_DEV_FD CONFIG_NSOCKET_DESCRIPTORS +#define CONFIG_NFILE_DESCRIPTORS FAT_MAX_OPEN_FILES /* only for random currently */ + +#ifdef LOSCFG_RANDOM_DEV +#include "hks_client.h" +#define RANDOM_DEV_FD CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS #define RANDOM_DEV_PATH "/dev/random" +#endif #define FREE_AND_SET_NULL(ptr) do { \ free(ptr); \ ptr = NULL; \ } while (0) +#ifdef LOSCFG_RANDOM_DEV /** * @brief Get canonical form of a given path based on cwd(Current working directory). * @@ -69,6 +78,7 @@ */ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, size_t bufSize) { + size_t offset; if (!path) { path = ""; } @@ -77,7 +87,8 @@ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, siz cwd = ""; } - size_t tmpLen = strlen(cwd) + strlen(path) + 4; // three '/' and one '\0' + offset = strlen("///") + 1; // three '/' and one '\0' + size_t tmpLen = strlen(cwd) + strlen(path) + offset; char *tmpBuf = (char *)malloc(tmpLen); if (tmpBuf == NULL) { return 0; @@ -90,8 +101,9 @@ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, siz char *p; /* replace /./ to / */ + offset = strlen("/./") - 1; while ((p = strstr(tmpBuf, "/./")) != NULL) { - if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 2, tmpLen - (p - tmpBuf) - 2)) { + if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) { free(tmpBuf); return 0; } @@ -106,18 +118,19 @@ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, siz } /* handle /../ (e.g., replace /aa/bb/../ to /aa/) */ + offset = strlen("/../") - 1; while ((p = strstr(tmpBuf, "/../")) != NULL) { char *start = p; - while (start > tmpBuf && *--start != '/') { + while (start > tmpBuf && *(start - 1) != '/') { + --start; } - if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + 3, tmpLen - (p - tmpBuf) - 3)) { + if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) { free(tmpBuf); return 0; } } size_t totalLen = strlen(tmpBuf); - /* strip the last / */ if (totalLen > 1 && tmpBuf[totalLen - 1] == '/') { tmpBuf[--totalLen] = 0; @@ -128,7 +141,7 @@ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, siz return totalLen; } - if (EOK != memcpy_s(buf, bufSize, tmpBuf, (totalLen + 1 > bufSize) ? bufSize : totalLen + 1)) { + if (EOK != memcpy_s(buf, bufSize, tmpBuf, (((totalLen + 1) > bufSize) ? bufSize : (totalLen + 1)))) { free(tmpBuf); return 0; } @@ -137,25 +150,46 @@ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, siz free(tmpBuf); return totalLen; } +#endif -int open(const char *file, int oflag, ...) +int mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data) { + return fatfs_mount(source, target, filesystemtype, mountflags, data); +} + +int umount(const char *target) +{ + return fatfs_umount(target); +} + +int umount2(const char *target, int flag) +{ + return fatfs_umount2(target, flag); +} + +int open(const char *path, int oflag, ...) +{ +#ifdef LOSCFG_RANDOM_DEV unsigned flags = O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_LARGEFILE | O_TRUNC | O_EXCL | O_DIRECTORY; if ((unsigned)oflag & ~flags) { errno = EINVAL; return -1; } - size_t pathLen = strlen(file) + 1; + + size_t pathLen = strlen(path) + 1; char *canonicalPath = (char *)malloc(pathLen); if (!canonicalPath) { errno = ENOMEM; return -1; } - if (GetCanonicalPath(NULL, file, canonicalPath, pathLen) == 0) { + if (GetCanonicalPath(NULL, path, canonicalPath, pathLen) == 0) { FREE_AND_SET_NULL(canonicalPath); errno = ENOMEM; return -1; } + if (strcmp(canonicalPath, RANDOM_DEV_PATH) == 0) { FREE_AND_SET_NULL(canonicalPath); if ((O_ACCMODE & (unsigned)oflag) != O_RDONLY) { @@ -178,64 +212,132 @@ int open(const char *file, int oflag, ...) return -1; } FREE_AND_SET_NULL(canonicalPath); - errno = ENOENT; - return -1; +#endif + return fatfs_open(path, oflag); } int close(int fd) { +#ifdef LOSCFG_RANDOM_DEV if (fd == RANDOM_DEV_FD) { return 0; } +#endif #ifdef LOSCFG_NET_LWIP_SACK if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) { return closesocket(fd); } #endif - errno = EBADF; - return -1; + return fatfs_close(fd); } -ssize_t read(int fd, void *buf, size_t nbytes) +ssize_t read(int fd, void *buf, size_t nbyte) { +#ifdef LOSCFG_RANDOM_DEV if (fd == RANDOM_DEV_FD) { - if (nbytes == 0) { + if (nbyte == 0) { return 0; } if (buf == NULL) { errno = EINVAL; return -1; } - if (nbytes > 1024) { - nbytes = 1024; /* hks_generate_random: random_size must <= 1024 */ + if (nbyte > 1024) { + nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */ } - struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbytes}; + struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte}; if (hks_generate_random(&key) != 0) { errno = EIO; return -1; } - return (ssize_t)nbytes; - } -#ifdef LOSCFG_NET_LWIP_SACK - if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) { - return recv(fd, buf, nbytes, 0); + return (ssize_t)nbyte; } #endif - errno = EBADF; - return -1; +#ifdef LOSCFG_NET_LWIP_SACK + if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) { + return recv(fd, buf, nbyte, 0); + } +#endif + return fatfs_read(fd, buf, nbyte); } -ssize_t write(int fd, const void *buf, size_t nbytes) +ssize_t write(int fd, const void *buf, size_t nbyte) { +#ifdef LOSCFG_RANDOM_DEV if (fd == RANDOM_DEV_FD) { errno = EBADF; /* "/dev/random" is readonly */ return -1; } +#endif #ifdef LOSCFG_NET_LWIP_SACK if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) { - return send(fd, buf, nbytes, 0); + return send(fd, buf, nbyte, 0); } #endif - errno = EBADF; - return -1; + return fatfs_write(fd, buf, nbyte); +} + +off_t lseek(int fd, off_t offset, int whence) +{ + return fatfs_lseek(fd, offset, whence); +} + +int unlink(const char *path) +{ + return fatfs_unlink(path); +} + +int fstat(int fd, struct stat *buf) +{ + return fatfs_fstat(fd, buf); +} + +int stat(const char *path, struct stat *buf) +{ + return fatfs_stat(path, buf); +} + +int fsync(int fd) +{ + return fatfs_fsync(fd); +} + +int mkdir(const char *path, mode_t mode) +{ + return fatfs_mkdir(path, mode); +} + +DIR *opendir(const char *dirName) +{ + return fatfs_opendir(dirName); +} + +struct dirent *readdir(DIR *dir) +{ + return fatfs_readdir(dir); +} + +int closedir(DIR *dir) +{ + return fatfs_closedir(dir); +} + +int rmdir(const char *path) +{ + return fatfs_rmdir(path); +} + +int rename(const char *oldName, const char *newName) +{ + return fatfs_rename(oldName, newName); +} + +int statfs(const char *path, struct statfs *buf) +{ + return fatfs_statfs(path, buf); +} + +int ftruncate(int fd, off_t length) +{ + return fatfs_ftruncate(fd, length); } diff --git a/components/net/lwip-2.1/enhancement/src/fixme.c b/components/net/lwip-2.1/enhancement/src/fixme.c new file mode 100644 index 00000000..5985736b --- /dev/null +++ b/components/net/lwip-2.1/enhancement/src/fixme.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) +#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) +#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM) +#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) + +static struct netif *netif_find_by_name(const char *name) +{ + struct netif *netif = NULL; + LWIP_ASSERT_CORE_LOCKED(); + if (name == NULL) { + return NULL; + } + NETIF_FOREACH(netif) { + if (strcmp("lo", name) == 0 && (netif->name[0] == 'l' && netif->name[1] == 'o')) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found lo\n")); + return netif; + } + + if (strcmp(netif->full_name, name) == 0) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found %s\n", name)); + return netif; + } + } + + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: didn't find %s\n", name)); + return NULL; +} + +static err_t netifapi_do_find_by_name(struct tcpip_api_call_data *m) +{ + /* cast through void* to silence alignment warnings. + * We know it works because the structs have been instantiated as struct netifapi_msg */ + struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; + msg->netif = netif_find_by_name(msg->msg.ifs.name); + return ERR_OK; +} + +struct netif *netifapi_netif_find_by_name(const char *name) +{ + struct netif *netif = NULL; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + NETIFAPI_VAR_REF(msg).netif = NULL; +#if LWIP_MPU_COMPATIBLE + if (strncpy_s(NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE, name, NETIF_NAMESIZE - 1)) { + NETIFAPI_VAR_FREE(msg); + return netif; + } + NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0'; +#else + NETIFAPI_VAR_REF(msg).msg.ifs.name = (char *)name; +#endif /* LWIP_MPU_COMPATIBLE */ + + (void)tcpip_api_call(netifapi_do_find_by_name, &API_VAR_REF(msg).call); + netif = msg.netif; + NETIFAPI_VAR_FREE(msg); + return netif; +} + +#if LWIP_IPV6 +int ip6addr_aton(const char *cp, ip6_addr_t *addr) +{ + const int ipv6_blocks = 8; + u16_t current_block_index = 0; + u16_t current_block_value = 0; + u16_t addr16[ipv6_blocks]; + u16_t *a16 = (u16_t *)addr->addr; + int squash_pos = ipv6_blocks; + int i; + const char *sc = cp; + const char *ss = cp-1; + + for (; ; sc++) { + if (current_block_index >= ipv6_blocks) { + return 0; // address too long + } + if (*sc == 0) { + if (sc - ss == 1) { + if (squash_pos != current_block_index) { + return 0; // empty address or address ends with a single ':' + } // else address ends with one valid "::" + } else { + addr16[current_block_index++] = current_block_value; + } + break; + } else if (*sc == ':') { + if (sc - ss == 1) { + if (sc != cp || sc[1] != ':') { + return 0; // address begins with a single ':' or contains ":::" + } // else address begins with one valid "::" + } else { + addr16[current_block_index++] = current_block_value; + } + if (sc[1] == ':') { + if (squash_pos != ipv6_blocks) { + return 0; // more than one "::" + } + squash_pos = current_block_index; + sc++; + } + ss = sc; // ss points to the recent ':' position + current_block_value = 0; + } else if (lwip_isxdigit(*sc) && (sc - ss) < 5) { // 4 hex-digits at most + current_block_value = (current_block_value << 4) + + (*sc | ('a' - 'A')) - '0' - ('a' - '9' - 1) * (*sc >= 'A'); +#if LWIP_IPV4 + } else if (*sc == '.' && current_block_index < ipv6_blocks - 1) { + ip4_addr_t ip4; + int ret = ip4addr_aton(ss+1, &ip4); + if (!ret) { + return 0; + } + ip4.addr = lwip_ntohl(ip4.addr); + addr16[current_block_index++] = (u16_t)(ip4.addr >> 16); + addr16[current_block_index++] = (u16_t)(ip4.addr); + break; +#endif /* LWIP_IPV4 */ + } else { + return 0; // unexpected char or too many digits + } + } + + if (squash_pos == ipv6_blocks && current_block_index != ipv6_blocks) { + return 0; // address too short + } + if (squash_pos != ipv6_blocks && current_block_index == ipv6_blocks) { + return 0; // unexpected "::" in address + } + + for (i = 0; i < squash_pos; ++i) { + a16[i] = lwip_htons(addr16[i]); + } + for (; i < ipv6_blocks - current_block_index + squash_pos; ++i) { + a16[i] = 0; + } + for (; i < ipv6_blocks; ++i) { + a16[i] = lwip_htons(addr16[i - ipv6_blocks + current_block_index]); + } + + return 1; +} +#endif /* LWIP_IPV6 */ diff --git a/components/net/lwip-2.1/porting/include/arch/cc.h b/components/net/lwip-2.1/porting/include/arch/cc.h new file mode 100644 index 00000000..746bf9e9 --- /dev/null +++ b/components/net/lwip-2.1/porting/include/arch/cc.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _LWIP_PORTING_CC_H_ +#define _LWIP_PORTING_CC_H_ + +#include +#include +#include "securec.h" +#include "log.h" + +#ifdef htons +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS +#endif + +#define LWIP_PROVIDE_ERRNO 1 +#define __SIZEOF_POINTER__ 4 // 32位系统 + +#define LOS_TASK_STATUS_DETACHED 0x0100 // 预留字段 + +#if defined(__arm__) && defined(__ARMCC_VERSION) + /* Keil uVision4 tools */ + #define PACK_STRUCT_BEGIN __packed + #define PACK_STRUCT_STRUCT + #define PACK_STRUCT_END + #define PACK_STRUCT_FIELD(fld) fld + #define ALIGNED(n) __align(n) +#elif defined (__IAR_SYSTEMS_ICC__) + /* IAR Embedded Workbench tools */ + #define PACK_STRUCT_BEGIN __packed + #define PACK_STRUCT_STRUCT + #define PACK_STRUCT_END + #define PACK_STRUCT_FIELD(fld) fld + // #error NEEDS ALIGNED +#else + /* GCC tools (CodeSourcery) */ + #define PACK_STRUCT_BEGIN + #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) + #define PACK_STRUCT_END + #define PACK_STRUCT_FIELD(fld) fld + #define ALIGNED(n) __attribute__((aligned (n))) +#endif + +#define LWIP_RAND rand + +extern void HilogPrintf(const char *fmt, ...); + +#ifndef HILOG_INFO +#define HILOG_INFO(...) +#ifndef HILOG_MODULE_APP +#define HILOG_MODULE_APP 0 +#endif +#endif + +#ifndef HILOG_ERROR +#define HILOG_ERROR(...) +#endif + +#define LWIP_PLATFORM_DIAG(vars) HilogPrintf vars +#define LWIP_PLATFORM_ASSERT(x) do {HILOG_ERROR(HILOG_MODULE_APP, \ + "Assertion \"%s\" errno %d line %d in %s\n", \ + x, errno, __LINE__, __FILE__);} while (0) + +#define mem_clib_malloc LWIP_MEM_ALLOC +#define mem_clib_free LWIP_MEM_FREE +#define mem_clib_calloc LWIP_MEM_CALLOC + +#define init_waitqueue_head(...) +#define poll_check_waiters(...) +#define IOCTL_CMD_CASE_HANDLER() +#define DF_NADDR(addr) + +#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.114.114"))) +#define DNS_SERVER_ADDRESS_SECONDARY(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.115.115"))) + +#endif /* _LWIP_PORTING_CC_H_ */ diff --git a/components/net/lwip-2.1/porting/include/arch/perf.h b/components/net/lwip-2.1/porting/include/arch/perf.h new file mode 100644 index 00000000..43147ef7 --- /dev/null +++ b/components/net/lwip-2.1/porting/include/arch/perf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _LWIP_PORTING_PERF_H_ +#define _LWIP_PORTING_PERF_H_ + +#if LWIP_PERF + +#define PERF_START do { /* something to do */ } while (0) +#define PERF_STOP(x) do { /* something to do */ } while (0) + +#endif + +#endif /* _LWIP_PORTING_PERF_H_ */ diff --git a/kal/posix/src/pthread_impl.h b/components/net/lwip-2.1/porting/include/arch/sys_arch.h similarity index 69% rename from kal/posix/src/pthread_impl.h rename to components/net/lwip-2.1/porting/include/arch/sys_arch.h index 1ede97de..95f7f80a 100644 --- a/kal/posix/src/pthread_impl.h +++ b/components/net/lwip-2.1/porting/include/arch/sys_arch.h @@ -1,69 +1,72 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PTHREAD_IMPL_H_ -#define PTHREAD_IMPL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct __pthread_attr_s pthread_attr_t; -#define __DEFINED_pthread_attr_t - -#ifdef __cplusplus -} -#endif - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct __pthread_attr_s { - unsigned int detachstate; - unsigned int schedpolicy; - struct sched_param schedparam; - unsigned int inheritsched; - unsigned int scope; - unsigned int stackaddr_set; - void* stackaddr; - unsigned int stacksize_set; - size_t stacksize; -} pthread_attr_t; - -#ifdef __cplusplus -} -#endif - -#endif // PTHREAD_IMPL_H_ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _LWIP_PORTING_SYS_ARCH_H_ +#define _LWIP_PORTING_SYS_ARCH_H_ + +#include +#include "memory_pool.h" +#include "los_mux.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Mutex + */ +typedef uint32_t sys_mutex_t; + +/** + * Semaphore + */ +typedef uint32_t sys_sem_t; + +/** + * MessageBox + */ +typedef uint32_t sys_mbox_t; + +/** + * Protector + */ +typedef void *sys_prot_t; + +/** + * Thread + */ +typedef uint32_t sys_thread_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_SYS_ARCH_H_ */ diff --git a/components/net/lwip-2.1/porting/include/lwip/lwipopts.h b/components/net/lwip-2.1/porting/include/lwip/lwipopts.h new file mode 100644 index 00000000..7d077758 --- /dev/null +++ b/components/net/lwip-2.1/porting/include/lwip/lwipopts.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _LWIP_PORTING_LWIPOPTS_H_ +#define _LWIP_PORTING_LWIPOPTS_H_ + +// lwIP debug options, comment the ones you don't want +#define LWIP_DEBUG 0 +#if LWIP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define IGMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define DRIVERIF_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TIMERS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_ERR_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_SACK_DEBUG LWIP_DBG_OFF +#define TCP_TLP_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF +#define AUTOIP_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF +#define TFTP_DEBUG LWIP_DBG_OFF +#define SYS_ARCH_DEBUG LWIP_DBG_OFF +#define SNTP_DEBUG LWIP_DBG_OFF +#define IP6_DEBUG LWIP_DBG_OFF +#define DHCP6_DEBUG LWIP_DBG_OFF +#define DRV_STS_DEBUG LWIP_DBG_OFF +#endif + +// Options only in new opt.h +#define LWIP_SOCKET_SELECT 0 +#define LWIP_SOCKET_POLL 1 + +// Options in old opt.h that differs from new opt.h +#define MEM_ALIGNMENT __SIZEOF_POINTER__ +#define MEMP_NUM_NETDB 8 +#define IP_REASS_MAXAGE 3 +#define IP_SOF_BROADCAST 1 +#define IP_SOF_BROADCAST_RECV 1 +#define LWIP_MULTICAST_PING 1 +#define LWIP_RAW 1 +#define LWIP_DHCP_AUTOIP_COOP_TRIES 64 +#define TCP_LISTEN_BACKLOG 1 +#define TCP_DEFAULT_LISTEN_BACKLOG 16 + +#define LWIP_WND_SCALE 1 +#define TCP_RCV_SCALE 7 + +#define LWIP_NETIF_HOSTNAME 1 +#define LWIP_NETIF_TX_SINGLE_PBUF 1 +#define LWIP_NETCONN_FULLDUPLEX 1 // Caution +#define LWIP_COMPAT_SOCKETS 2 +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#define LWIP_TCP_KEEPALIVE 1 +#define RECV_BUFSIZE_DEFAULT 65535 +#define SO_REUSE_RXTOALL 1 + +#define LWIP_CHECKSUM_ON_COPY 1 +#define LWIP_IPV6 1 +#define LWIP_IPV6_NUM_ADDRESSES 5 +#define LWIP_ND6_NUM_PREFIXES 10 +#define LWIP_IPV6_DHCP6 1 +#define LWIP_IPV6_DHCP6_STATEFUL 1 + +// Options in old lwipopts.h +#define ARP_QUEUEING 1 +#define DEFAULT_ACCEPTMBOX_SIZE 32 +#define DEFAULT_RAW_RECVMBOX_SIZE 128 +#define DEFAULT_TCP_RECVMBOX_SIZE 128 +#define DEFAULT_UDP_RECVMBOX_SIZE 128 +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 +#define ETH_PAD_SIZE 2 +#define IP_REASS_MAX_PBUFS (((65535) / (IP_FRAG_MAX_MTU - 20 - 8) + 1) * MEMP_NUM_REASSDATA) +#define LWIP_COMPAT_SOCKETS 2 +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF +#define LWIP_DHCP 1 +#define LWIP_DNS 1 +#define LWIP_ETHERNET 1 +#define LWIP_HAVE_LOOPIF 1 +#define LWIP_IGMP 1 +#define LWIP_NETIF_API 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_LOOPBACK 1 +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#define LWIP_RAW 1 +#define CONFIG_NFILE_DESCRIPTORS 1 +#define LWIP_SOCKET_OFFSET CONFIG_NFILE_DESCRIPTORS +#define LWIP_SO_RCVBUF 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +#define LWIP_STATS_DISPLAY 1 +#define MEM_LIBC_MALLOC 1 +#define MEMP_NUM_ARP_QUEUE (65535 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8)) +#define MEMP_NUM_NETBUF (65535 * 3 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8)) +#define MEMP_NUM_NETCONN LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_PBUF LWIP_CONFIG_NUM_SOCKETS*2 +#define MEMP_NUM_RAW_PCB LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_REASSDATA (IP_REASS_MAX_MEM_SIZE / 65535) +#define MEMP_NUM_TCPIP_MSG_API 64 +#define MEMP_NUM_TCPIP_MSG_INPKT 512 +#define MEMP_NUM_TCP_PCB LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_TCP_PCB_LISTEN LWIP_CONFIG_NUM_SOCKETS +#define MEMP_NUM_TCP_SEG (((TCP_SND_BUF * 3 / 2) + TCP_WND) * LWIP_CONFIG_NUM_SOCKETS / TCP_MSS) +#define MEMP_NUM_UDP_PCB LWIP_CONFIG_NUM_SOCKETS +#define MEM_SIZE (4*1024*1024) // (512*1024) +#define PBUF_POOL_BUFSIZE 1550 +#define PBUF_POOL_SIZE 64 +#define SO_REUSE 1 +#define TCPIP_MBOX_SIZE 512 +#define TCPIP_THREAD_PRIO 5 +#define TCPIP_THREAD_STACKSIZE 0x6000 +#define TCP_MAXRTX 64 +#define TCP_MSS 1400 +#define TCP_SND_BUF 65535 +#define TCP_SND_QUEUELEN (8 * TCP_SND_BUF) / TCP_MSS +#define TCP_TTL 255 +#define TCP_WND 32768 +#define UDP_TTL 255 + +// Options in old lwipopts.h but kept in Defaults with new opt.h +#define IP_FORWARD 0 +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#define LWIP_ICMP 1 +#define LWIP_NETCONN 1 +#define LWIP_SOCKET 1 +#define LWIP_STATS 1 +#define LWIP_TCP 1 +#define LWIP_UDP 1 +#define NO_SYS 0 +#define TCP_QUEUE_OOSEQ LWIP_TCP + +// Change some options for lwIP 2.1.2 +#undef TCP_MAXRTX +#define TCP_MAXRTX 12 + +#undef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 0 + +#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + (LWIP_IPV6 * LWIP_IPV6_DHCP6)) + +#undef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE LWIP_CONFIG_NUM_SOCKETS + +#undef TCP_MSS +#define TCP_MSS (IP_FRAG_MAX_MTU - 20 - 20) + +#undef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 + +/** + * Defines whether to enable debugging for driver module. + */ +#ifndef DRIVERIF_DEBUG +#define DRIVERIF_DEBUG LWIP_DBG_OFF +#endif + +// Options for old lwipopts.h +#define IP_FRAG_MAX_MTU 1500 +#define LWIP_CONFIG_NUM_SOCKETS 128 +#define IP_REASS_MAX_MEM_SIZE (MEM_SIZE / 4) + +// Options for enhancement code, same for old lwipopts.h +#define LWIP_NETIF_PROMISC 1 +#define LWIP_TFTP LOSCFG_NET_LWIP_SACK_TFTP +#define LWIP_DHCPS 1 +#define LWIP_ENABLE_NET_CAPABILITY 1 +#define LWIP_ENABLE_CAP_NET_BROADCAST 0 + +// Options for GT +#undef LWIP_NETIF_PROMISC +#define LWIP_NETIF_PROMISC 0 + +#undef LWIP_ICMP +#define LWIP_ICMP 0 + +#undef LWIP_DHCP +#define LWIP_DHCP 0 + +#undef LWIP_IGMP +#define LWIP_IGMP 0 + +#undef LWIP_IPV6 +#define LWIP_IPV6 0 + +#undef LWIP_IPV6_DHCP6 +#define LWIP_IPV6_DHCP6 0 + +#undef TCP_SND_BUF +#define TCP_SND_BUF (65535 / 3) + +#undef TCP_WND +#define TCP_WND ((TCP_SND_BUF * 2) / 3) + +#undef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN (2 * (TCP_SND_BUF / TCP_MSS)) + +#undef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 1 + +#undef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 4 + +#undef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 12 + +#undef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 32 + +#undef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 0 + +#undef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 0 + +#undef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 8 + +#undef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 12 + +#undef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 32 + +#undef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 32 + +#undef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 8 + +#undef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 4 + +#undef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 64 + +#undef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 + +#undef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0x1000 + +#undef LWIP_SOCKET_SELECT +#define LWIP_SOCKET_SELECT 1 + +// use PBUF_RAM instead of PBUF_POOL in udp_input +#define USE_PBUF_RAM_UDP_INPUT 1 + +#endif /* _LWIP_PORTING_LWIPOPTS_H_ */ diff --git a/components/net/lwip-2.1/porting/include/lwip/netif.h b/components/net/lwip-2.1/porting/include/lwip/netif.h new file mode 100644 index 00000000..421a5fb6 --- /dev/null +++ b/components/net/lwip-2.1/porting/include/lwip/netif.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _LWIP_PORTING_NETIF_H_ +#define _LWIP_PORTING_NETIF_H_ + +#define netif_find netifapi_netif_find_by_name + +#if LWIP_DHCPS +#define LWIP_NETIF_CLIENT_DATA_INDEX_DHCP LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, \ + LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS +#endif + +#define LWIP_NETIF_FULLNAME 16 +#define linkoutput linkoutput; \ + void (*drv_send)(struct netif *netif, struct pbuf *p); \ + u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \ + void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \ + char full_name[LWIP_NETIF_FULLNAME]; \ + u16_t link_layer_type +#include_next +#undef linkoutput +#if LWIP_DHCPS +#undef LWIP_NETIF_CLIENT_DATA_INDEX_DHCP +#endif + +#include // For ETHARP_HWADDR_LEN, by `hieth-sf src/interface.c' and `wal/wal_net.c' + +#ifdef __cplusplus +extern "C" { +#endif + +// redefine NETIF_NAMESIZE which was defined in netif.h +#undef NETIF_NAMESIZE +#define NETIF_NAMESIZE LWIP_NETIF_FULLNAME + +#define LOOPBACK_IF 0 // 772 +#define ETHERNET_DRIVER_IF 1 +#define WIFI_DRIVER_IF 801 +#define BT_PROXY_IF 802 + +err_t driverif_init(struct netif *netif); +void driverif_input(struct netif *netif, struct pbuf *p); + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_NETIF_H_ */ diff --git a/components/net/lwip-2.1/porting/include/lwip/netifapi.h b/components/net/lwip-2.1/porting/include/lwip/netifapi.h new file mode 100644 index 00000000..44858b7c --- /dev/null +++ b/components/net/lwip-2.1/porting/include/lwip/netifapi.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _LWIP_PORTING_NETIFAPI_H_ +#define _LWIP_PORTING_NETIFAPI_H_ + +#include_next + +#ifdef __cplusplus +extern "C" { +#endif + +err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num); +err_t netifapi_dhcps_stop(struct netif *netif); + +#define netifapi_dhcp_cleanup(n) netifapi_netif_common(n, dhcp_cleanup, NULL) +#define netifapi_dhcp_is_bound(n) netifapi_netif_common(n, NULL, dhcp_is_bound) + +void netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr); +struct netif *netifapi_netif_find_by_name(const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* _LWIP_PORTING_NETIFAPI_H_ */ diff --git a/components/net/lwip-2.1/porting/include/lwipopts.h b/components/net/lwip-2.1/porting/include/lwipopts.h new file mode 100644 index 00000000..4f1ab721 --- /dev/null +++ b/components/net/lwip-2.1/porting/include/lwipopts.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 __LITEOS_M_LWIPOPTS_H__ +#define __LITEOS_M_LWIPOPTS_H__ + +// Just redirect +#include "lwip/lwipopts.h" + +#endif // __LITEOS_M_LWIPOPTS_H__ diff --git a/components/net/lwip-2.1/porting/include/netdb.h b/components/net/lwip-2.1/porting/include/netdb.h new file mode 100644 index 00000000..5043cf0a --- /dev/null +++ b/components/net/lwip-2.1/porting/include/netdb.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 __LITEOS_NETDB_PORTING_H__ +#define __LITEOS_NETDB_PORTING_H__ + +#include "lwip/netdb.h" + +struct hostent *gethostbyname(const char *name); + +#endif // __LITEOS_NETDB_PORTING_H__ \ No newline at end of file diff --git a/components/net/lwip-2.1/porting/include/sys/socket.h b/components/net/lwip-2.1/porting/include/sys/socket.h new file mode 100644 index 00000000..c5f27a60 --- /dev/null +++ b/components/net/lwip-2.1/porting/include/sys/socket.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 _SYS_SOCKET_PORTING_H +#define _SYS_SOCKET_PORTING_H + +#include "lwip/sockets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int socket (int, int, int); + +int bind (int, const struct sockaddr *, socklen_t); +int connect (int, const struct sockaddr *, socklen_t); +int listen (int, int); +int accept (int, struct sockaddr *__restrict, socklen_t *__restrict); + +int getsockname (int, struct sockaddr *__restrict, socklen_t *__restrict); +int getpeername (int, struct sockaddr *__restrict, socklen_t *__restrict); + +ssize_t send (int, const void *, size_t, int); +ssize_t recv (int, void *, size_t, int); +ssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t); +ssize_t recvfrom (int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict); +ssize_t sendmsg (int, const struct msghdr *, int); +ssize_t recvmsg (int, struct msghdr *, int); + +int getsockopt (int, int, int, void *__restrict, socklen_t *__restrict); +int setsockopt (int, int, int, const void *, socklen_t); + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); +int inet_pton(int af, const char *src, void *dst); + +int shutdown (int, int); +int closesocket(int sockfd); + +int ioctlsocket(int s, long cmd, void *argp); + +#if LWIP_SOCKET_SELECT +int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout); +#endif +#if LWIP_SOCKET_POLL +int poll(struct pollfd *fds, nfds_t nfds, int timeout); +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/components/net/lwip-2.1/porting/src/driverif.c b/components/net/lwip-2.1/porting/src/driverif.c new file mode 100644 index 00000000..d16ba5cc --- /dev/null +++ b/components/net/lwip-2.1/porting/src/driverif.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LWIP_NETIF_HOSTNAME_DEFAULT "default" +#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 // 100Mbps + +#define link_rx_drop cachehit +#define link_rx_overrun cachehit + +#define LWIP_STATIC static + +#define NETIF_NAME_PREFIX_MAX_LENGTH 10 +#define NETIF_NAME_PREFIX_ETH "eth" +#define NETIF_NAME_PREFIX_WIFI "wlan" +#define NETIF_NAME_PREFIX_BT "bt" + +#ifndef LWIP_NETIF_IFINDEX_MAX_EX +#define LWIP_NETIF_IFINDEX_MAX_EX 255 +#endif + +LWIP_STATIC void driverif_get_ifname_prefix(struct netif *netif, char *prefix, int prefixLen) +{ + if (prefix == NULL || netif == NULL) { + LWIP_ASSERT("invalid param", 0); + return; + } + switch (netif->link_layer_type) { + case ETHERNET_DRIVER_IF: + strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_ETH); + break; + case WIFI_DRIVER_IF: + strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_WIFI); + break; + case BT_PROXY_IF: + strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_BT); + break; + default: + LWIP_ASSERT("invalid link_layer_type", 0); + break; + } +} + +LWIP_STATIC void driverif_init_ifname(struct netif *netif) +{ + struct netif *tmpnetif = NULL; + char prefix[NETIF_NAME_PREFIX_MAX_LENGTH] = {0}; + + driverif_get_ifname_prefix(netif, prefix, NETIF_NAME_PREFIX_MAX_LENGTH); + netif->name[0] = prefix[0]; + netif->name[1] = prefix[1]; + + if (netif->full_name[0] != '\0') { + LWIP_DEBUGF(DRIVERIF_DEBUG, ("netif already has fullname %s\n", netif->full_name)); + return; + } + for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) { + if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1, + "%s%d", prefix, i) < 0) { + break; + } + NETIF_FOREACH(tmpnetif) { + if (strcmp(tmpnetif->full_name, netif->full_name) == 0) { + break; + } + } + if (tmpnetif == NULL) { + LWIP_DEBUGF(DRIVERIF_DEBUG, ("set fullname success %s\n", netif->full_name)); + return; + } + } + netif->full_name[0] = '\0'; +} + +/* + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this driverif + * @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +LWIP_STATIC err_t driverif_output(struct netif *netif, struct pbuf *p) +{ + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \ + (void *)p, p->tot_len, (void *)netif)); + +#if PF_PKT_SUPPORT + if (all_pkt_raw_pcbs != NULL) { + p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST)); + p->flags |= PBUF_FLAG_OUTGOING; + (void)raw_pkt_input(p, netif, NULL); + } +#endif + +#if ETH_PAD_SIZE + (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + netif->drv_send(netif, p); + +#if ETH_PAD_SIZE + (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +void driverif_input_proc(struct netif *netif, struct pbuf *p) +{ + u16_t ethhdr_type; + struct eth_hdr *ethhdr = NULL; + err_t ret = ERR_VAL; + + ethhdr = (struct eth_hdr *)p->payload; + ethhdr_type = ntohs(ethhdr->type); + + switch (ethhdr_type) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_IPV6: + case ETHTYPE_ARP: +#if ETHARP_SUPPORT_VLAN + case ETHTYPE_VLAN: +#endif /* ETHARP_SUPPORT_VLAN */ + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type)); + /* full packet send to tcpip_thread to process */ + if (netif->input != NULL) { + ret = netif->input(p, netif); + } + + if (ret != ERR_OK) { + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n")); + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + if (ret == ERR_MEM) { + MIB2_STATS_NETIF_INC(netif, ifinoverruns); + LINK_STATS_INC(link.link_rx_overrun); + } + } else { + LINK_STATS_INC(link.recv); + } + break; + + default: + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", \ + ethhdr_type)); + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + break; + } +} + +/* + * This function should be called by network driver to pass the input packet to LwIP. + * Before calling this API, driver has to keep the packet in pbuf structure. Driver has to + * call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver + * has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread. + * Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to + * free the pbuf. + * + * @param netif the lwip network interface structure for this driverif + * @param p packet in pbuf structure format + */ +void driverif_input(struct netif *netif, struct pbuf *p) +{ +#if PF_PKT_SUPPORT +#if (DRIVERIF_DEBUG & LWIP_DBG_OFF) + u16_t ethhdr_type; + struct eth_hdr* ethhdr = NULL; +#endif + err_t ret = ERR_VAL; +#endif + + LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return); + + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \ + packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len)); + + /* points to packet payload, which starts with an Ethernet header */ + MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); + if (p->len < SIZEOF_ETH_HDR) { + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + return; + } + +#if PF_PKT_SUPPORT +#if (DRIVERIF_DEBUG & LWIP_DBG_OFF) + ethhdr = (struct eth_hdr *)p->payload; + ethhdr_type = ntohs(ethhdr->type); + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", \ + ethhdr_type, netif->input)); +#endif + + /* full packet send to tcpip_thread to process */ + if (netif->input) { + ret = netif->input(p, netif); + } + if (ret != ERR_OK) { + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n")); + (void)pbuf_free(p); + LINK_STATS_INC(link.drop); + LINK_STATS_INC(link.link_rx_drop); + if (ret == ERR_MEM) { + LINK_STATS_INC(link.link_rx_overrun); + } + } else { + LINK_STATS_INC(link.recv); + } + +#else + driverif_input_proc(netif, p); +#endif + + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n")); +} + +/* + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this driverif + * @return ERR_OK if the loopif is initialized + * ERR_MEM on Allocation Failure + * any other err_t on error + */ +err_t driverif_init(struct netif *netif) +{ + u16_t link_layer_type; + + if (netif == NULL) { + return ERR_IF; + } + link_layer_type = netif->link_layer_type; + LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \ + ((link_layer_type == ETHERNET_DRIVER_IF) \ + || (link_layer_type == WIFI_DRIVER_IF \ + || link_layer_type == BT_PROXY_IF)), \ + return ERR_IF); + + LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \ + (netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF); + + LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF); + +#if LWIP_NETIF_PROMISC + LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF); +#endif + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->output = etharp_output; + netif->linkoutput = driverif_output; + + /* init the netif's full name */ + driverif_init_ifname(netif); + + /* maximum transfer unit */ + netif->mtu = IP_FRAG_MAX_MTU; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | +#if DRIVER_STATUS_CHECK + NETIF_FLAG_DRIVER_RDY | +#endif +#if LWIP_IGMP + NETIF_FLAG_IGMP | +#endif + + /** + @page RFC-2710 RFC-2710 + @par Compliant Sections + Section 5. Node State Transition Diagram + @par Behavior Description + MLD messages are sent for multicast addresses whose scope is 2 + (link-local), including Solicited-Node multicast addresses.\n + Behavior:Stack will send MLD6 report /Done to solicited node multicast address + if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled. + */ + /* Enable sending MLD report /done for solicited address during neighbour discovery */ +#if LWIP_IPV6 && LWIP_IPV6_MLD +#if LWIP_MLD6_ENABLE_MLD_ON_DAD + NETIF_FLAG_MLD6 | +#endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */ +#endif + NETIF_FLAG_LINK_UP; + +#if DRIVER_STATUS_CHECK + netif->waketime = -1; +#endif /* DRIVER_STATUS_CHECK */ + LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif)); + return ERR_OK; +} diff --git a/components/net/lwip-2.1/porting/src/lwip_init.c b/components/net/lwip-2.1/porting/src/lwip_init.c new file mode 100644 index 00000000..88e7ed81 --- /dev/null +++ b/components/net/lwip-2.1/porting/src/lwip_init.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "lwip/tcpip.h" +#include "ohos_init.h" +void TcpIpPortingInit() +{ + tcpip_init(NULL, NULL); +} +SYSEX_SERVICE_INIT(TcpIpPortingInit); diff --git a/components/net/lwip-2.1/porting/src/netdb_porting.c b/components/net/lwip-2.1/porting/src/netdb_porting.c new file mode 100644 index 00000000..df905f71 --- /dev/null +++ b/components/net/lwip-2.1/porting/src/netdb_porting.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "netdb.h" + +struct hostent *gethostbyname(const char *name) +{ + if (name == NULL) { + return NULL; + } + return lwip_gethostbyname(name); +} \ No newline at end of file diff --git a/components/net/lwip-2.1/porting/src/sockets_porting.c b/components/net/lwip-2.1/porting/src/sockets_porting.c new file mode 100644 index 00000000..32deb8fd --- /dev/null +++ b/components/net/lwip-2.1/porting/src/sockets_porting.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip/priv/sockets_priv.h" +#include + +#if !LWIP_COMPAT_SOCKETS + +#define CHECK_NULL_PTR(ptr) do { if ((ptr) == NULL) { set_errno(EFAULT); return -1; } } while (0) + +int accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + return lwip_accept(s, addr, addrlen); +} + +int bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + CHECK_NULL_PTR(name); + if (namelen < sizeof(*name)) { + set_errno(EINVAL); + return -1; + } + return lwip_bind(s, name, namelen); +} + +int shutdown(int s, int how) +{ + return lwip_shutdown(s, how); +} + +int getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + CHECK_NULL_PTR(name); + CHECK_NULL_PTR(namelen); + return lwip_getpeername(s, name, namelen); +} + +int getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + CHECK_NULL_PTR(name); + CHECK_NULL_PTR(namelen); + return lwip_getsockname(s, name, namelen); +} + +int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + return lwip_getsockopt(s, level, optname, optval, optlen); +} + +int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + return lwip_setsockopt(s, level, optname, optval, optlen); +} + +int closesocket(int s) +{ + return lwip_close(s); +} + +int connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + CHECK_NULL_PTR(name); + if (namelen < sizeof(*name)) { + set_errno(EINVAL); + return -1; + } + return lwip_connect(s, name, namelen); +} + +int listen(int s, int backlog) +{ + return lwip_listen(s, backlog); +} + +ssize_t recv(int s, void *mem, size_t len, int flags) +{ + CHECK_NULL_PTR(mem); + return lwip_recv(s, mem, len, flags); +} + +ssize_t recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + CHECK_NULL_PTR(mem); + return lwip_recvfrom(s, mem, len, flags, from, fromlen); +} + +ssize_t recvmsg(int s, struct msghdr *message, int flags) +{ + CHECK_NULL_PTR(message); + if (message->msg_iovlen) { + CHECK_NULL_PTR(message->msg_iov); + } + return lwip_recvmsg(s, message, flags); +} + +ssize_t send(int s, const void *dataptr, size_t size, int flags) +{ + CHECK_NULL_PTR(dataptr); + return lwip_send(s, dataptr, size, flags); +} + +ssize_t sendmsg(int s, const struct msghdr *message, int flags) +{ + return lwip_sendmsg(s, message, flags); +} + +ssize_t sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + CHECK_NULL_PTR(dataptr); + if (to && tolen < sizeof(*to)) { + set_errno(EINVAL); + return -1; + } + return lwip_sendto(s, dataptr, size, flags, to, tolen); +} + +int socket(int domain, int type, int protocol) +{ + return lwip_socket(domain, type, protocol); +} + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + return lwip_inet_ntop(af, src, dst, size); +} + +int inet_pton(int af, const char *src, void *dst) +{ + return lwip_inet_pton(af, src, dst); +} + +int ioctlsocket(int s, long cmd, void *argp) +{ + return lwip_ioctl(s, cmd, argp); +} + +#if LWIP_SOCKET_SELECT +int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) +{ + return lwip_select(maxfdp1, readset, writeset, exceptset, timeout); +} +#endif + +#if LWIP_SOCKET_POLL +int poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + return lwip_poll(fds, nfds, timeout); +} +#endif + +#endif /* !LWIP_COMPAT_SOCKETS */ \ No newline at end of file diff --git a/components/net/lwip-2.1/porting/src/sys_arch.c b/components/net/lwip-2.1/porting/src/sys_arch.c new file mode 100755 index 00000000..1c1ae6f3 --- /dev/null +++ b/components/net/lwip-2.1/porting/src/sys_arch.c @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "cmsis_os2.h" +#include +#include + +#define YES 1 +#define NO 0 +#define LOSCFG_KERNEL_SMP NO + +#if (LOSCFG_KERNEL_SMP == YES) +SPIN_LOCK_INIT(arch_protect_spin); +static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID; +static int lwprot_count = 0; +#endif /* LOSCFG_KERNEL_SMP == YES */ + +#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div)) +#define LWIP_LOG_BUF_SIZE 64 + +/** + * Thread and System misc + */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio) +{ + UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID; + UINT32 ret; + TSK_INIT_PARAM_S task = {0}; + + /* Create host Task */ + task.pfnTaskEntry = (TSK_ENTRY_FUNC)thread; + task.uwStackSize = stackSize; + task.pcName = (char *)name; + task.usTaskPrio = prio; + task.uwArg = (UINTPTR)arg; + task.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&taskID, &task); + if (ret != LOS_OK) { + LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret)); + return -1; + } + + return taskID; +} + +void sys_init(void) +{ + /* set rand seed to make random sequence diff on every startup */ + UINT32 seedhsb, seedlsb; + HalGetCpuCycle(&seedhsb, &seedlsb); + srand(seedlsb); +} + +u32_t sys_now(void) +{ + /* Lwip docs mentioned like wraparound is not a problem in this funtion */ + return (u32_t)osKernelGetTickCount(); +} + +/** + * Protector + */ +sys_prot_t sys_arch_protect(void) +{ +#if (LOSCFG_KERNEL_SMP == YES) + /* Note that we are using spinlock instead of mutex for LiteOS-SMP here: + * 1. spinlock is more effective for short critical region protection. + * 2. this function is called only in task context, not in interrupt handler. + * so it's not needed to disable interrupt. + */ + if (lwprot_thread != LOS_CurTaskIDGet()) { + /* We are locking the spinlock where it has not been locked before + * or is being locked by another thread */ + LOS_SpinLock(&arch_protect_spin); + lwprot_thread = LOS_CurTaskIDGet(); + lwprot_count = 1; + } else { + /* It is already locked by THIS thread */ + lwprot_count++; + } +#else + LOS_TaskLock(); +#endif /* LOSCFG_KERNEL_SMP == YES */ + return 0; /* return value is unused */ +} + +void sys_arch_unprotect(sys_prot_t pval) +{ + LWIP_UNUSED_ARG(pval); +#if (LOSCFG_KERNEL_SMP == YES) + if (lwprot_thread == LOS_CurTaskIDGet()) { + lwprot_count--; + if (lwprot_count == 0) { + lwprot_thread = LOS_ERRNO_TSK_ID_INVALID; + LOS_SpinUnlock(&arch_protect_spin); + } + } +#else + LOS_TaskUnlock(); +#endif /* LOSCFG_KERNEL_SMP == YES */ +} + +/** + * MessageBox + */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + CHAR qName[] = "lwIP"; + UINT32 ret = LOS_QueueCreate(qName, (UINT16)size, mbox, 0, sizeof(void *)); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_CB_UNAVAILABLE: + case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY: + return ERR_MEM; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueCreate error %u\n", __FUNCTION__, ret)); + return ERR_ARG; +} + +void sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + /* Caution: the second parameter is NOT &msg */ + UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), LOS_WAIT_FOREVER); + if (ret != LOS_OK) { + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret)); + } +} + +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + /* Caution: the second parameter is NOT &msg */ + UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), 0); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_ISFULL: + return ERR_MEM; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret)); + return ERR_ARG; +} + +err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg); + +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs) +{ + void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */ + UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND); + UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), tick ? (UINT32)tick : LOS_WAIT_FOREVER); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_ISEMPTY: + case LOS_ERRNO_QUEUE_TIMEOUT: + return SYS_ARCH_TIMEOUT; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret)); + return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */ +} + +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ + void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */ + UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), 0); + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_QUEUE_ISEMPTY: + return SYS_MBOX_EMPTY; + case LOS_ERRNO_QUEUE_TIMEOUT: + return SYS_ARCH_TIMEOUT; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret)); + return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */ +} + +void sys_mbox_free(sys_mbox_t *mbox) +{ + (void)LOS_QueueDelete(*mbox); +} + +int sys_mbox_valid(sys_mbox_t *mbox) +{ + QUEUE_INFO_S queueInfo; + return LOS_OK == LOS_QueueInfoGet(*mbox, &queueInfo); +} + +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = LOSCFG_BASE_IPC_QUEUE_LIMIT; +} + +/** + * Semaphore + */ +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + UINT32 ret = LOS_SemCreate(count, sem); + if (ret != LOS_OK) { + return ERR_ARG; + } + + return ERR_OK; +} + +void sys_sem_signal(sys_sem_t *sem) +{ + (void)LOS_SemPost(*sem); +} + +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs) +{ + UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND); + UINT32 ret = LOS_SemPend(*sem, tick ? (UINT32)tick : LOS_WAIT_FOREVER); // timeoutMs 0 means wait forever + switch (ret) { + case LOS_OK: + return ERR_OK; + case LOS_ERRNO_SEM_TIMEOUT: + return SYS_ARCH_TIMEOUT; + default: + break; + } + LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_SemPend error %u\n", __FUNCTION__, ret)); + return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */ +} + +void sys_sem_free(sys_sem_t *sem) +{ + (void)LOS_SemDelete(*sem); +} + +int sys_sem_valid(sys_sem_t *sem) +{ + return *sem != LOSCFG_BASE_IPC_SEM_LIMIT; +} + +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = LOSCFG_BASE_IPC_SEM_LIMIT; +} + +/** + * Mutex + */ +err_t sys_mutex_new(sys_mutex_t *mutex) +{ + UINT32 ret = LOS_MuxCreate(mutex); + if (ret != LOS_OK) { + return ERR_ARG; + } + + return ERR_OK; +} + +void sys_mutex_lock(sys_mutex_t *mutex) +{ + (void)LOS_MuxPend(*mutex, LOS_WAIT_FOREVER); +} + +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + (void)LOS_MuxPost(*mutex); +} + +void sys_mutex_free(sys_mutex_t *mutex) +{ + (void)LOS_MuxDelete(*mutex); +} + +int sys_mutex_valid(sys_mutex_t *mutex) +{ + return *mutex != LOSCFG_BASE_IPC_MUX_LIMIT; +} + +void sys_mutex_set_invalid(sys_mutex_t *mutex) +{ + *mutex = LOSCFG_BASE_IPC_MUX_LIMIT; +} + +void HilogPrintf(const char *fmt, ...) +{ + if ((fmt == NULL) || (strlen(fmt) == 0)) { + return; + } + + int len; + char buf[LWIP_LOG_BUF_SIZE] = {0}; + va_list ap; + va_start(ap, fmt); + len = vsprintf_s(buf, sizeof(buf) - 1, fmt, ap); + va_end(ap); + if (len < 0) { + HILOG_INFO(HILOG_MODULE_APP, "log param invalid or buf is not enough."); + return; + } + HILOG_INFO(HILOG_MODULE_APP, buf); +} diff --git a/components/net/test/lwip_test.h b/components/net/test/lwip_test.h new file mode 100644 index 00000000..a873a59d --- /dev/null +++ b/components/net/test/lwip_test.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 LWIP_TEST_H +#define LWIP_TEST_H + +#include +#include "log.h" +#include "securec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int g_testCase; +extern int g_testError; +extern int g_testTemp; +#define LWIP_TEST_RET_OK 0 +#define LWIP_TEST_RET_ERR 1 + +#define LOCALHOST "127.0.0.1" +#define STACK_IP LOCALHOST +#define STACK_PORT 2277 +#define PEER_PORT STACK_PORT +#define SERVER_PORT STACK_PORT +#define CLIENT_PORT 2288 +#define PEER_IP LOCALHOST +#define BUF_SIZE (128 * 1) +#define IOV_LENGTH 2 +#define STACK_TEST_SIZE (0x800UL) + +#define ICUNIT_ASSERT_NOT_EQUAL(a, b, c) if ((a) == (b)) { \ + g_testError = (c); \ + LWIP_ASSERT("lwip test", 0); \ + } +#define ICUNIT_ASSERT_EQUAL(a, b, c) if ((a) != (b)) { \ + g_testError = (c); \ + LWIP_ASSERT("lwip test", 0); \ + } + +#define LogPrintln(fmt, ...) \ + HILOG_INFO(HILOG_MODULE_APP, fmt "%c", \ + ##__VA_ARGS__, \ + ('\n' == " "fmt[sizeof(" "fmt)-2]) ? '\0' : '\n') // trailing newline is auto appended + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TEST_H */ diff --git a/components/net/test/net_socket_test_001.c b/components/net/test/net_socket_test_001.c new file mode 100644 index 00000000..a92e9ba2 --- /dev/null +++ b/components/net/test/net_socket_test_001.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" + +#define TEST_CASE 110 + +int SocketTest(void) +{ + LogPrintln("net_socket_test_001.c enter"); + g_testCase = TEST_CASE; + int fd = socket(0, 0, 0); + LWIP_ASSERT("socket invalid param.", fd == -1); + return LWIP_TEST_RET_OK; +} diff --git a/components/net/test/net_socket_test_002.c b/components/net/test/net_socket_test_002.c new file mode 100644 index 00000000..7abdfb13 --- /dev/null +++ b/components/net/test/net_socket_test_002.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" + +#define MSG "Hi, I am UDP" +#define TEST_CASE 120 + +static char g_buf[BUF_SIZE + 1] = { 0 }; + +int UdpTest(void) +{ + LogPrintln("net_socket_test_002.c enter"); + g_testCase = TEST_CASE; + int sfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret; + struct msghdr msg = { 0 }; + struct iovec iov[IOV_LENGTH] = { 0 }; + int recvCount = 0; + + /* socket creation */ + sfd = socket(AF_INET, SOCK_DGRAM, 0); + LWIP_ASSERT("socket invalid param.", sfd != -1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT); + ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LWIP_ASSERT("socket invalid param.", ret == 0); + + /* send */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), MSG); + ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr, + (socklen_t)sizeof(clnAddr)); + LWIP_ASSERT("socket invalid param.", ret != -1); + + ret = ioctlsocket(sfd, FIONREAD, &recvCount); + ICUNIT_ASSERT_EQUAL(ret, 0, 1); + LogPrintln("udp recv count %d", recvCount); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr, + &clnAddrLen); + LWIP_ASSERT("socket invalid param.", ret == strlen(MSG)); + + /* sendmsg */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), MSG); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = IOV_LENGTH; + iov[0].iov_base = g_buf; + iov[0].iov_len = strlen(MSG); + iov[1].iov_base = g_buf; + iov[1].iov_len = strlen(MSG); + ret = sendmsg(sfd, &msg, 0); + LWIP_ASSERT("socket invalid param.", ret == IOV_LENGTH * strlen(MSG)); + + /* recvmsg */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg)); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + iov[0].iov_base = g_buf; + iov[0].iov_len = sizeof(g_buf); + ret = recvmsg(sfd, &msg, 0); + LWIP_ASSERT("socket invalid param.", ret == IOV_LENGTH * strlen(MSG)); + + /* close socket */ + ret = closesocket(sfd); + LWIP_ASSERT("socket invalid param.", ret != -1); + return LWIP_TEST_RET_OK; +} + diff --git a/components/net/test/net_socket_test_003.c b/components/net/test/net_socket_test_003.c new file mode 100644 index 00000000..120d5822 --- /dev/null +++ b/components/net/test/net_socket_test_003.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +#define SRV_MSG "Hi, I am TCP server" +#define CLI_MSG "Hi, I am TCP client" +#define TEST_CASE 130 + +static char g_buf[BUF_SIZE + 1] = { 0 }; +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); + +static int SampleTcpServer() +{ + g_testCase++; + int sfd, lsfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + struct msghdr msg = { 0 }; + struct iovec iov[IOV_LENGTH] = { 0 }; + int ret; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create server socket inet stream: %d", lsfd); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT); + ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + + ret = listen(lsfd, 0); + LogPrintln("listen socket %d: %d", lsfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 3); + + sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen); + LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port)); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4); + + /* send */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG); + ret = send(sfd, g_buf, strlen(SRV_MSG), 0); + LogPrintln("server send on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 5); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recv(sfd, g_buf, sizeof(g_buf), 0); + LogPrintln("server recv on socket %d: %d", sfd, ret); + LogPrintln("ser:%s", g_buf); + ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 6); + + /* sendmsg */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = IOV_LENGTH; + iov[0].iov_base = g_buf; + iov[0].iov_len = strlen(SRV_MSG); + iov[1].iov_base = g_buf; + iov[1].iov_len = strlen(SRV_MSG); + ret = sendmsg(sfd, &msg, 0); + LogPrintln("sendmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(SRV_MSG), 7); + + /* recvmsg */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg)); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + iov[0].iov_base = g_buf; + iov[0].iov_len = sizeof(g_buf); + ret = recvmsg(sfd, &msg, 0); + LogPrintln("recvmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(CLI_MSG), 8); + + ret = shutdown(sfd, SHUT_RDWR); + LogPrintln("shutdown socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 9); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10); + ret = closesocket(lsfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 11); + + return 0; +} + +static int SampleTcpClient() +{ + g_testCase++; + int sfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + int ret; + struct msghdr msg = { 0 }; + struct iovec iov[IOV_LENGTH] = { 0 }; + struct sockaddr addr; + socklen_t addrLen = sizeof(addr); + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create client socket inet stream: %d", sfd); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(PEER_PORT); + ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 11); + + /* test getpeername */ + ret = getpeername(sfd, &addr, &addrLen); + LogPrintln("getpeername %d %s:%d: %d", \ + sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 12); + ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 13); + ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \ + inet_addr(PEER_IP), 14); + + /* test getsockname */ + ret = getsockname(sfd, &addr, &addrLen); + LogPrintln("getsockname %d %s:%d: %d", \ + sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 15); + ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 16); + ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \ + inet_addr(STACK_IP), 17); + + /* send */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG); + ret = send(sfd, g_buf, strlen(CLI_MSG), 0); + LogPrintln("client send on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 18); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recv(sfd, g_buf, sizeof(g_buf), 0); + LogPrintln("client recv on socket %d: %d", sfd, ret); + LogPrintln("cli:%s", g_buf); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 19); + + /* sendmsg */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = IOV_LENGTH; + iov[0].iov_base = g_buf; + iov[0].iov_len = strlen(CLI_MSG); + iov[1].iov_base = g_buf; + iov[1].iov_len = strlen(CLI_MSG); + ret = sendmsg(sfd, &msg, 0); + LogPrintln("sendmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), 20); + + /* recvmsg */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg)); + msg.msg_name = &clnAddr; + msg.msg_namelen = sizeof(clnAddr); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + iov[0].iov_base = g_buf; + iov[0].iov_len = sizeof(g_buf); + ret = recvmsg(sfd, &msg, 0); + LogPrintln("recvmsg on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(SRV_MSG), 21); + + ret = shutdown(sfd, SHUT_RDWR); + LogPrintln("shutdown socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 22); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + return 0; +} + +static void TcpServerRoutine(void *p) +{ + (void)p; + (void)SampleTcpServer(); +} + +static void TcpClientRoutine(void *p) +{ + (void)p; + (void)SampleTcpClient(); +} + +void TcpTest() +{ + LogPrintln("net_socket_test_003.c enter"); + g_testCase = TEST_CASE; + int ret; + ret = sys_thread_new("tcp_server", TcpServerRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + + ret = sys_thread_new("tcp_client", TcpClientRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24); +} diff --git a/components/net/test/net_socket_test_004.c b/components/net/test/net_socket_test_004.c new file mode 100644 index 00000000..e1a84101 --- /dev/null +++ b/components/net/test/net_socket_test_004.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" + +#define TEST_CASE 140 +#define OPT_TIMEOUT 1000 + +int SockOptTest() +{ + LogPrintln("net_socket_test_004.c enter"); + g_testCase = TEST_CASE; + int ret, error, flag; + struct timeval timeout; + socklen_t len; + + int fd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(fd, -1, 1); + + error = -1; + len = sizeof(error); + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); + LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", \ + fd, ret, error, len, errno); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + ICUNIT_ASSERT_EQUAL(error, 0, 3); + + len = sizeof(timeout); + ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len); + ICUNIT_ASSERT_EQUAL(ret, 0, 4); + + timeout.tv_sec = OPT_TIMEOUT; + len = sizeof(timeout); + ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, len); + ICUNIT_ASSERT_EQUAL(ret, 0, 5); + + (void)memset_s(&timeout, len, 0, len); + ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len); + ICUNIT_ASSERT_EQUAL(ret, 0, 6); + ICUNIT_ASSERT_EQUAL(timeout.tv_sec, OPT_TIMEOUT, 7); + + error = -1; + len = sizeof(error); + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); + LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", \ + fd, ret, error, len, errno); + ICUNIT_ASSERT_EQUAL(ret, 0, 8); + ICUNIT_ASSERT_EQUAL(error, 0, 9); + + flag = 1; + ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); + LogPrintln("setsockopt(TCP_NODELAY) ret=%d", ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 10); + + ret = closesocket(fd); + ICUNIT_ASSERT_EQUAL(ret, 0, 11); + + return LWIP_TEST_RET_OK; +} diff --git a/components/net/test/net_socket_test_005.c b/components/net/test/net_socket_test_005.c new file mode 100644 index 00000000..c7ec4289 --- /dev/null +++ b/components/net/test/net_socket_test_005.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" + +#define TEST_CASE 150 + +int ByteOrderTest(void) +{ + LogPrintln("net_socket_test_005.c enter"); +#if BYTE_ORDER == LITTLE_ENDIAN + g_testCase = TEST_CASE + 1; + uint32_t hl = ntohl(0x12345678); + ICUNIT_ASSERT_EQUAL(hl, 0x78563412, 1); + + uint32_t nl = htonl(0x12345678); + ICUNIT_ASSERT_EQUAL(nl, 0x78563412, 2); + + uint16_t hs = ntohs(0x1234); + ICUNIT_ASSERT_EQUAL(hs, 0x3412, 3); + + uint16_t ns = htons(0x1234); + ICUNIT_ASSERT_EQUAL(ns, 0x3412, 4); +#else + g_testCase = TEST_CASE; + uint32_t hl = ntohl(0x12345678); + ICUNIT_ASSERT_EQUAL(hl, 0x12345678, 5); + + uint32_t nl = htonl(0x12345678); + ICUNIT_ASSERT_EQUAL(nl, 0x12345678, 6); + + uint16_t hs = ntohs(0x1234); + ICUNIT_ASSERT_EQUAL(hs, 0x1234, 7); + + uint16_t ns = htons(0x1234); + ICUNIT_ASSERT_EQUAL(ns, 0x1234, 8); +#endif + return LWIP_TEST_RET_OK; +} diff --git a/components/net/test/net_socket_test_006.c b/components/net/test/net_socket_test_006.c new file mode 100644 index 00000000..59a2789b --- /dev/null +++ b/components/net/test/net_socket_test_006.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" + +#define TEST_CASE 160 +#define TEMP_BUF_SIZE 32 +int InetTest() +{ + LogPrintln("net_socket_test_006.c enter"); + g_testCase = TEST_CASE; + struct in_addr in; + int ret = inet_pton(AF_INET, "300.10.10.10", &in); + ICUNIT_ASSERT_EQUAL(ret, 0, 1); + + ret = inet_pton(AF_INET, "10.11.12.13", &in); + ICUNIT_ASSERT_EQUAL(ret, 1, 2); +#if BYTE_ORDER == LITTLE_ENDIAN + g_testCase++; + ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, 3); +#else + ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, 4); +#endif + + const char *p = inet_ntoa(in); + ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, 5); + + char buf[TEMP_BUF_SIZE]; + p = inet_ntop(AF_INET, &in, buf, sizeof(buf)); + ICUNIT_ASSERT_EQUAL(p, buf, 6); + ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, 7); + + return LWIP_TEST_RET_OK; +} diff --git a/components/net/test/net_socket_test_007.c b/components/net/test/net_socket_test_007.c new file mode 100644 index 00000000..70845d1f --- /dev/null +++ b/components/net/test/net_socket_test_007.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +static char g_buf[BUF_SIZE + 1] = { 0 }; +static char g_buf_temp[BUF_SIZE + 1] = { 0 }; + +#define SEND_UDP_COUNT 10000 // send count +#define TEST_CASE 170 + +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); +static void UdpTestMoreTask(void *p) +{ + (void)p; + LogPrintln("net_socket_test_007.c enter"); + if (g_testCase < TEST_CASE) { + g_testCase = TEST_CASE; + } else { + g_testCase++; + } + + int sfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret; + int i; + + /* socket creation */ + sfd = socket(AF_INET, SOCK_DGRAM, 0); + LWIP_ASSERT("socket invalid param.", sfd != -1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT); + ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LWIP_ASSERT("socket invalid param.", ret == 0); + + /* send */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP); + clnAddr.sin_port = htons(PEER_PORT); + if (g_buf_temp[0] == '\0') { + for (i = 0; i < BUF_SIZE; i++) { + g_buf_temp[i] = 'U'; + } + g_buf_temp[BUF_SIZE] = '\0'; + } + + LogPrintln("udp begin send"); + for (i = 0; i < SEND_UDP_COUNT; i++) { + ret = memcpy_s(g_buf, sizeof(g_buf), g_buf_temp, sizeof(g_buf_temp)); + ICUNIT_ASSERT_EQUAL(ret, EOK, 1); + ret = sendto(sfd, g_buf, BUF_SIZE, 0, (struct sockaddr*)&clnAddr, (socklen_t)sizeof(clnAddr)); + LWIP_ASSERT("socket invalid param.", ret != -1); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr, + &clnAddrLen); + LWIP_ASSERT("socket invalid param.", ret == BUF_SIZE); + } + LogPrintln("udp end send"); + + /* close socket */ + ret = closesocket(sfd); + LWIP_ASSERT("socket invalid param.", ret != -1); +} + +void UdpTestMore() +{ + int ret; + ret = sys_thread_new("udp_more", UdpTestMoreTask, NULL, + STACK_TEST_SIZE * 2, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10); +} + diff --git a/components/net/test/net_socket_test_008.c b/components/net/test/net_socket_test_008.c new file mode 100644 index 00000000..6248d53d --- /dev/null +++ b/components/net/test/net_socket_test_008.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +#define SEND_TCP_COUNT 1000 // send count +#define STACK_PORT_8 2288 +#define TEST_CASE 180 + +static char g_serverSendBuf[BUF_SIZE + 1] = { 0 }; +static char g_clientRecvBuf[BUF_SIZE + 1] = { 0 }; + +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); + +static void InitMsgBuf() +{ + int i; + if (g_serverSendBuf[0] != '\0') { + return; + } + for (i = 0; i < BUF_SIZE; i++) { + g_serverSendBuf[i] = 'S'; + } + g_serverSendBuf[BUF_SIZE] = '\0'; +} + +static int SampleTcpServer() +{ + g_testCase++; + int sfd, lsfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret; + int i; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create server socket inet stream: %d", lsfd); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT_8); + ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + + ret = listen(lsfd, 0); + LogPrintln("listen socket %d: %d", lsfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 3); + + sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen); + LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port)); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4); + + for (i = 0; i < SEND_TCP_COUNT; i++) { + /* send */ + ret = send(sfd, g_serverSendBuf, BUF_SIZE, 0); + ICUNIT_ASSERT_EQUAL(ret, BUF_SIZE, 5); + } + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 7); + ret = closesocket(lsfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8); + return 0; +} + +static int SampleTcpClient() +{ + g_testCase++; + int sfd; + struct sockaddr_in srvAddr = { 0 }; + int ret; + int i; + struct sockaddr addr; + socklen_t addrLen = sizeof(addr); + int recvCount = 0; + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create client socket inet stream: %d", sfd); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 7); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(STACK_PORT_8); + ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 8); + + /* test getpeername */ + ret = getpeername(sfd, &addr, &addrLen); + LogPrintln("getpeername %d %s:%d: %d", + sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 9); + ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 10); + ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \ + inet_addr(PEER_IP), 11); + + /* test getsockname */ + ret = getsockname(sfd, &addr, &addrLen); + LogPrintln("getsockname %d %s:%d: %d", + sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 12); + ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 13); + ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \ + inet_addr(STACK_IP), 14); + + LogPrintln("tcp begin recv"); + for (i = 0; i < 2 * SEND_TCP_COUNT; i++) { + /* recv */ + (void)memset_s(g_clientRecvBuf, sizeof(g_clientRecvBuf), 0, sizeof(g_clientRecvBuf)); + ret = recv(sfd, g_clientRecvBuf, BUF_SIZE, 0); + recvCount += ret; + if (recvCount >= BUF_SIZE * SEND_TCP_COUNT) { + LogPrintln("client recv on socket %d: %d, i = %d", sfd, recvCount, i); + break; + } + } + ICUNIT_ASSERT_EQUAL(recvCount, BUF_SIZE * SEND_TCP_COUNT, recvCount); + LogPrintln("tcp end recv"); + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 17); + return 0; +} + +static void TcpServerRoutine(void *p) +{ + (void)p; + (void)SampleTcpServer(); +} + +static void TcpClientRoutine(void *p) +{ + (void)p; + (void)SampleTcpClient(); +} + +void TcpTestMore() +{ + LogPrintln("net_socket_test_008.c enter"); + if (g_testCase < TEST_CASE) { + g_testCase = TEST_CASE; + } + + int ret; + InitMsgBuf(); + ret = sys_thread_new("tcp_server_more", TcpServerRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 17); + + ret = sys_thread_new("tcp_client_more", TcpClientRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 18); +} diff --git a/components/net/test/net_socket_test_009.c b/components/net/test/net_socket_test_009.c new file mode 100644 index 00000000..282d1a10 --- /dev/null +++ b/components/net/test/net_socket_test_009.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +#define SRV_MSG "Hi, I am TCP server" +#define CLI_MSG "Hi, I am TCP client" + +#define TEST_CASE 190 +#define STACK_PORT_9 2299 +#define TIME_OUT 10 // timeout 10s + +static char g_buf[BUF_SIZE + 1] = { 0 }; + +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); + +static int SampleTcpServer() +{ +#if LWIP_SOCKET_SELECT + g_testCase++; + int sfd, lsfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + fd_set fdsr; + struct timeval tv; + int ret; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create server socket inet stream: %d", lsfd); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT_9); + ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + + ret = listen(lsfd, 0); + LogPrintln("listen socket %d: %d", lsfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 3); + + FD_ZERO(&fdsr); + FD_SET(lsfd, &fdsr); + // timeout setting + tv.tv_sec = TIME_OUT; + tv.tv_usec = 0; + + ret = select(lsfd + 1, &fdsr, NULL, NULL, &tv); + if (ret < 0) { + LogPrintln("select error"); + ICUNIT_ASSERT_EQUAL(-1, 0, 4); + } else if (ret == 0) { + LogPrintln("select timeout"); + ICUNIT_ASSERT_EQUAL(-1, 0, 5); + } + + sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen); + LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port)); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 6); + + /* send */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG); + ret = send(sfd, g_buf, strlen(SRV_MSG), 0); + LogPrintln("server send on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 7); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8); + ret = closesocket(lsfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 9); +#endif + return 0; +} + +static int SampleTcpClient() +{ +#if LWIP_SOCKET_SELECT + g_testCase++; + int sfd; + struct sockaddr_in srvAddr = { 0 }; + int ret; + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create client socket inet stream: %d", sfd); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(STACK_PORT_9); + ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 11); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recv(sfd, g_buf, sizeof(g_buf), 0); + LogPrintln("client recv on socket %d: %d", sfd, ret); + LogPrintln("cli:%s", g_buf); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 12); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13); +#endif + return 0; +} + +static void TcpServerRoutine(void *p) +{ + (void)p; + (void)SampleTcpServer(); +} + +static void TcpClientRoutine(void *p) +{ + (void)p; + (void)SampleTcpClient(); +} + +void TcpTestSelect() +{ + LogPrintln("net_socket_test_009.c enter"); + g_testCase = TEST_CASE; + int ret; + ret = sys_thread_new("tcp_server_select", TcpServerRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + + ret = sys_thread_new("tcp_client_select", TcpClientRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24); +} diff --git a/components/net/test/net_socket_test_010.c b/components/net/test/net_socket_test_010.c new file mode 100644 index 00000000..9b5d8434 --- /dev/null +++ b/components/net/test/net_socket_test_010.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +#define SRV_MSG "Hi, I am TCP server" +#define CLI_MSG "Hi, I am TCP client" + +#define TEST_CASE 200 +#define STACK_PORT_10 2230 +#define POLL_OPEN_MAX 10 +#define TIME_OUT (1000 * 10) // timeout 10s +static char g_buf[BUF_SIZE + 1] = { 0 }; + +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); + +static int SampleTcpServer() +{ +#if LWIP_SOCKET_POLL + g_testCase++; + int sfd, lsfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + struct pollfd client[POLL_OPEN_MAX] = {0}; + int ret; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create server socket inet stream: %d", lsfd); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT_10); + ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + + ret = listen(lsfd, 0); + LogPrintln("listen socket %d: %d", lsfd, ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 3); + + client[0].fd = lsfd; + client[0].events = POLLIN; + ret = poll(client, 1, TIME_OUT); + if (ret < 0) { + LogPrintln("poll error"); + ICUNIT_ASSERT_EQUAL(-1, 0, 4); + } else if (ret == 0) { + LogPrintln("poll timeout"); + ICUNIT_ASSERT_EQUAL(-1, 0, 5); + } + + sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen); + LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port)); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 6); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recv(sfd, g_buf, sizeof(g_buf), 0); + LogPrintln("server recv on socket %d: %d", sfd, ret); + LogPrintln("ser:%s", g_buf); + ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 7); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8); + ret = closesocket(lsfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 9); +#endif + return 0; +} + +static int SampleTcpClient() +{ +#if LWIP_SOCKET_POLL + g_testCase++; + int sfd; + struct sockaddr_in srvAddr = { 0 }; + int ret; + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + LogPrintln("create client socket inet stream: %d", sfd); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(STACK_PORT_10); + ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret); + ICUNIT_ASSERT_EQUAL(ret, 0, 11); + + /* send */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG); + ret = send(sfd, g_buf, strlen(CLI_MSG), 0); + LogPrintln("client send on socket %d: %d", sfd, ret); + ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 12); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13); +#endif + return 0; +} + +static void TcpServerRoutine(void *p) +{ + (void)p; + (void)SampleTcpServer(); +} + +static void TcpClientRoutine(void *p) +{ + (void)p; + (void)SampleTcpClient(); +} + +void TcpTestPoll() +{ + LogPrintln("net_socket_test_010.c enter"); + g_testCase = TEST_CASE; + int ret; + ret = sys_thread_new("tcp_server_poll", TcpServerRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + + ret = sys_thread_new("tcp_client_poll", TcpClientRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24); +} diff --git a/components/net/test/net_socket_test_011.c b/components/net/test/net_socket_test_011.c new file mode 100644 index 00000000..e324143b --- /dev/null +++ b/components/net/test/net_socket_test_011.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lwip/prot/iana.h" + +#define MSG "Hi, I am testing BT netif." +#define STACK_IP_BT "192.168.167.1" +#define PEER_IP_BT "100.100.100.100" +#define GATEWAY_IP_BT "192.168.167.239" +#define NETIF_MAC "121212" +#define PEER_MAC "454545" +#define NETIF_NAME_BT "bt1000" +#define TEST_CASE 210 +static char g_buf[BUF_SIZE + 1] = { 0 }; +struct netif *btProxyNf = NULL; + +static void ReplayArpTask(); +static void ArpPackageProc(struct netif *netif, struct pbuf *p); +extern void driverif_input(struct netif *netif, struct pbuf *p); +static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p); + +static void ReplayUdpEncodeEthernet(struct netif *netif, struct pbuf *p) +{ + int ret; + ret = pbuf_add_header(p, SIZEOF_ETH_HDR); + ICUNIT_ASSERT_EQUAL(ret, 0, 1); + + struct eth_hdr *ethhdr; + ethhdr = (struct eth_hdr *)p->payload; + ethhdr->type = lwip_htons(ETHTYPE_IP); + SMEMCPY(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN); + SMEMCPY(ðhdr->src, PEER_MAC, ETH_HWADDR_LEN); + + driverif_input(netif, p); +} + +static void ReplayUdpEncodeIp(struct pbuf *p, ip4_addr_t *src, ip4_addr_t *dest) +{ + struct ip_hdr *iphdr; + int ret; +#if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + // ip header + ret = pbuf_add_header(p, IP_HLEN); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + iphdr = (struct ip_hdr *)p->payload; + IPH_TTL_SET(iphdr, UDP_TTL); + IPH_PROTO_SET(iphdr, IP_PROTO_UDP); + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += PP_NTOHS(IP_PROTO_UDP | (ttl << 8)); +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* dest cannot be NULL here */ + ip4_addr_copy(iphdr->dest, *dest); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + u16_t ip_hlen = IP_HLEN; + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + IPH_TOS_SET(iphdr, 0); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8)); +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_LEN_SET(iphdr, lwip_htons(p->tot_len)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_len; +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_OFFSET_SET(iphdr, 0); + IPH_ID_SET(iphdr, lwip_htons(0)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_id; +#endif /* CHECKSUM_GEN_IP_INLINE */ + ip4_addr_copy(iphdr->src, *src); + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; + chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); + chk_sum = (chk_sum >> 16) + chk_sum; + chk_sum = ~chk_sum; + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { + iphdr->_chksum = (u16_t)chk_sum; /* network order */ + } +#if LWIP_CHECKSUM_CTRL_PER_NETIF + else { + IPH_CHKSUM_SET(iphdr, 0); + } +#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ +#else /* CHECKSUM_GEN_IP_INLINE */ + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); + } +#endif /* CHECKSUM_GEN_IP */ +#endif /* CHECKSUM_GEN_IP_INLINE */ + + ReplayUdpEncodeEthernet(btProxyNf, p); +} + +static void ReplayUdp(void *ptemp) +{ + struct udp_hdr *udphdr; + ip4_addr_t sipaddr, dipaddr; + int size = strlen(MSG); + int ret; + (void)ptemp; + + LogPrintln("encode udp replay packet"); + inet_pton(AF_INET, PEER_IP_BT, &sipaddr); + inet_pton(AF_INET, STACK_IP_BT, &dipaddr); + + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); + u16_t chksum = LWIP_CHKSUM_COPY(p->payload, MSG, size); + + // udp header + ret = pbuf_add_header(p, UDP_HLEN); + ICUNIT_ASSERT_EQUAL(ret, 0, 1); + udphdr = (struct udp_hdr *)p->payload; + udphdr->src = lwip_htons(STACK_PORT); + udphdr->dest = lwip_htons(STACK_PORT); + udphdr->len = lwip_htons(p->tot_len); + /* in UDP, 0 checksum means 'no checksum' */ + u16_t udpchksum = ip_chksum_pseudo_partial(p, IP_PROTO_UDP, p->tot_len, UDP_HLEN, &sipaddr, &dipaddr); + u32_t acc = udpchksum + (u16_t)~(chksum); + udpchksum = FOLD_U32T(acc); + if (udpchksum == 0x0000) { + udpchksum = 0xffff; + } + udphdr->chksum = udpchksum; + udphdr->chksum = 0; + + ReplayUdpEncodeIp(p, &sipaddr, &dipaddr); +} + +static void ReplayUdpTask() +{ + int ret; + ret = sys_thread_new("replay_udp", ReplayUdp, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 3); +} + +static void ParsePackageIpUdp(struct netif *netif, struct pbuf *btBuf) +{ + // get scr_addr and dest_addr from ip head + const struct ip_hdr *iphdr; + iphdr = (const struct ip_hdr *)btBuf->payload; + ip4_addr_p_t ip4_addr_scr = iphdr->src; + ip4_addr_p_t ip4_addr_dest = iphdr->dest; + char buf[32]; + int dataLen; + + // get scr_port and dest port from tcp head + u16_t scr_port, dest_port; + void *data; + struct udp_hdr *udphdr; + udphdr = (struct udp_hdr *)((u8_t *)iphdr + IPH_HL_BYTES(iphdr)); + scr_port = udphdr->src; + dest_port = udphdr->dest; + data = (void *)((u8_t *)udphdr + UDP_HLEN); + + LogPrintln("======Bt netif send package======"); + LogPrintln("netif full name %s", netif->full_name); + (void)inet_ntop(AF_INET, &ip4_addr_scr.addr, buf, sizeof(buf)); + LogPrintln("package src ip %s", buf); + (void)inet_ntop(AF_INET, &ip4_addr_dest.addr, buf, sizeof(buf)); + LogPrintln("package dest ip %s", buf); + LogPrintln("package src port %d", lwip_ntohs(scr_port)); + LogPrintln("package dest port %d", lwip_ntohs(dest_port)); + LogPrintln("send data %s", (char *)data); + dataLen = lwip_ntohs(udphdr->len) - UDP_HLEN; + LogPrintln("send data length %d", dataLen); + ICUNIT_ASSERT_EQUAL(dataLen, strlen(MSG), 4); + LogPrintln("================================="); + + // 回应udp报文 + ReplayUdpTask(); +} + +static void ParsePackageEthernet(struct netif *netif, struct pbuf *p) +{ + u16_t next_hdr_offset = SIZEOF_ETH_HDR; + // get src mac and dest mac + struct eth_hdr *ethhdr; + ethhdr = (struct eth_hdr *)p->payload; + u16_t type = ethhdr->type; + + LogPrintln("ParsePackageEthernet type is %d", type); + switch (type) { +#if LWIP_IPV4 && LWIP_ARP + /* IP packet? */ + case PP_HTONS(ETHTYPE_IP): // 0x0008 + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + return; + } + /* skip Ethernet header (min. size checked above) */ + if (pbuf_remove_header(p, next_hdr_offset)) { + return; + } else { + /* pass to IP layer */ + ParsePackageIpUdp(netif, p); + } + break; + + case PP_HTONS(ETHTYPE_ARP): // 0x0608 + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + return; + } + /* skip Ethernet header (min. size checked above) */ + if (pbuf_remove_header(p, next_hdr_offset)) { + return; + } else { + /* pass p to ARP module */ + LogPrintln("recv arp packet"); + ArpPackageProc(netif, p); + } + break; +#endif /* LWIP_IPV4 && LWIP_ARP */ + + default: + LogPrintln("type is other %d", type); + break; + } +} + +static void BtProxySend(struct netif *netif, struct pbuf *p) +{ + if (netif == NULL || p == NULL) { + LogPrintln("%s : netif = NUll or p = NULL!", __func__); + return; + } +#if ETH_PAD_SIZE + (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + ParsePackageEthernet(netif, p); +} + +static struct netif *CreateBtNetIf() +{ + struct netif *btNetif = NULL; + btNetif = (struct netif *)malloc(sizeof(struct netif)); + if (btNetif == NULL) { + LogPrintln("%s fail : netif malloc fail!", __func__); + LWIP_ASSERT("btNetif malloc fail.", 0); + return NULL; + } + (void)memset_s(btNetif, sizeof(struct netif), 0, sizeof(struct netif)); + btNetif->drv_send = BtProxySend; + btNetif->link_layer_type = BT_PROXY_IF; + btNetif->hwaddr_len = ETH_HWADDR_LEN; + (void)memcpy_s(&btNetif->hwaddr, sizeof(btNetif->hwaddr), NETIF_MAC, ETH_HWADDR_LEN); + (void)memcpy_s(&btNetif->full_name, sizeof(btNetif->full_name), NETIF_NAME_BT, sizeof(NETIF_NAME_BT)); + ip4_addr_t gw, ipaddr, netmask; + IP4_ADDR(&gw, 192, 168, 167, 239); + IP4_ADDR(&ipaddr, 192, 168, 167, 1); + IP4_ADDR(&netmask, 255, 255, 255, 255); + int ret = 0; + if ((ret = netifapi_netif_add(btNetif, &ipaddr, &netmask, &gw, btNetif, driverif_init, tcpip_input)) != ERR_OK) { + LogPrintln("%s : netifapi_netif_add fail!,ret=%d", __func__, ret); + LWIP_ASSERT("btNetif add fail.", 0); + return NULL; + } + LogPrintln("netifapi_netif_add success!"); + netif_set_link_up(btNetif); + netifapi_netif_set_up(btNetif); + return btNetif; +} + +int UdpTestNetif(void) +{ + LogPrintln("net_socket_test_011.c enter"); + g_testCase = TEST_CASE; + int sfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + struct ifreq nif; + int ret; + + // 注册网卡 + btProxyNf = CreateBtNetIf(); + + /* socket creation */ + sfd = socket(AF_INET, SOCK_DGRAM, 0); + LWIP_ASSERT("socket invalid param.", sfd != -1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP_BT); + srvAddr.sin_port = htons(STACK_PORT); + ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + LWIP_ASSERT("socket invalid param.", ret == 0); + + /* 指定网卡接口 */ + char *inface = NETIF_NAME_BT; + (void)strcpy_s(nif.ifr_name, sizeof(nif.ifr_name), inface); + if (setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&nif, sizeof(nif)) < 0) { + LogPrintln("set intaface fail"); + LWIP_ASSERT("set intaface fail.", 0); + } + + /* send */ + clnAddr.sin_family = AF_INET; + clnAddr.sin_addr.s_addr = inet_addr(PEER_IP_BT); + clnAddr.sin_port = htons(PEER_PORT); + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + (void)strcpy_s(g_buf, sizeof(g_buf), MSG); + ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr, + (socklen_t)sizeof(clnAddr)); + LogPrintln("client send success: %d", sfd); + LWIP_ASSERT("socket invalid param.", ret != -1); + + /* recv */ + (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf)); + ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr, + &clnAddrLen); + LWIP_ASSERT("socket invalid param.", ret == strlen(MSG)); + LogPrintln("cli recv: %s", g_buf); + + /* close socket */ + ret = closesocket(sfd); + LWIP_ASSERT("socket invalid param.", ret != -1); + return LWIP_TEST_RET_OK; +} + +static void ArpPackageProc(struct netif *netif, struct pbuf *p) +{ + struct etharp_hdr *hdr; + ip4_addr_t sipaddr, dipaddr; + hdr = (struct etharp_hdr *)p->payload; + + if (hdr->opcode != PP_HTONS(ARP_REQUEST)) { + LogPrintln("opcode %d is not arp request", hdr->opcode); + return; + } + + inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr); + inet_pton(AF_INET, STACK_IP_BT, &dipaddr); + if (memcmp(&hdr->dipaddr, &sipaddr, sizeof(ip4_addr_t)) != EOK) { + LogPrintln("hdr->dipaddr %u is invalid", hdr->dipaddr); + return; + } + + // 回应arp报文 + ReplayArpTask(); +} + +static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p) +{ + int ret; + ret = pbuf_add_header(p, SIZEOF_ETH_HDR); + ICUNIT_ASSERT_EQUAL(ret, 0, 1); + + struct eth_hdr *ethhdr; + ethhdr = (struct eth_hdr *)p->payload; + ethhdr->type = lwip_htons(ETHTYPE_ARP); + SMEMCPY(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN); + SMEMCPY(ðhdr->src, PEER_MAC, ETH_HWADDR_LEN); + + driverif_input(netif, p); +} + +static void ReplayArp(void *ptemp) +{ + struct etharp_hdr *hdr; + ip4_addr_t sipaddr, dipaddr; + + (void)ptemp; + LogPrintln("encode arp replay packet"); + inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr); + inet_pton(AF_INET, STACK_IP_BT, &dipaddr); + struct pbuf *p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM); + hdr = (struct etharp_hdr *)p->payload; + hdr->opcode = PP_HTONS(ARP_REPLY); + /* Write the ARP MAC-Addresses */ + SMEMCPY(&hdr->shwaddr, PEER_MAC, ETH_HWADDR_LEN); + SMEMCPY(&hdr->dhwaddr, NETIF_MAC, ETH_HWADDR_LEN); + /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without + * structure packing. */ + IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, &sipaddr); + IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, &dipaddr); + hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET); + hdr->proto = PP_HTONS(ETHTYPE_IP); + /* set hwlen and protolen */ + hdr->hwlen = ETH_HWADDR_LEN; + hdr->protolen = sizeof(ip4_addr_t); + + ReplayArpEncodeEthernet(btProxyNf, p); +} + +static void ReplayArpTask() +{ + int ret; + ret = sys_thread_new("replay_arp", ReplayArp, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); +} \ No newline at end of file diff --git a/components/net/test/net_socket_test_012.c b/components/net/test/net_socket_test_012.c new file mode 100755 index 00000000..63073535 --- /dev/null +++ b/components/net/test/net_socket_test_012.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +#define SRV_MSG "Hi, I am TCP server" +#define CLI_MSG "Hi, I am TCP client" +#define TEST_CASE 220 +#define TEST_COUNT 100 +#define STACK_PORT_TCP_DUP_START 3000 + +static int g_portServer = STACK_PORT_TCP_DUP_START; +static int g_portClient = STACK_PORT_TCP_DUP_START; + +static char g_bufServer[BUF_SIZE + 1] = { 0 }; +static char g_bufClient[BUF_SIZE + 1] = { 0 }; +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); + +static int SampleTcpServer() +{ + int sfd, lsfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(g_portServer); + g_portServer++; + ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + + ret = listen(lsfd, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, 3); + + sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4); + + /* send */ + (void)memset_s(g_bufServer, sizeof(g_bufServer), 0, sizeof(g_bufServer)); + (void)strcpy_s(g_bufServer, sizeof(g_bufServer), SRV_MSG); + ret = send(sfd, g_bufServer, strlen(SRV_MSG), 0); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 5); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10); + ret = closesocket(lsfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 11); + + return 0; +} + +static int SampleTcpClient() +{ + int sfd; + struct sockaddr_in srvAddr = { 0 }; + int ret; + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(g_portClient); + g_portClient++; + ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + ICUNIT_ASSERT_EQUAL(ret, 0, 11); + + /* recv */ + (void)memset_s(g_bufClient, sizeof(g_bufClient), 0, sizeof(g_bufClient)); + ret = recv(sfd, g_bufClient, sizeof(g_bufClient), 0); + ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 19); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + return 0; +} + +static void TcpServerRoutine(void *p) +{ + (void)p; + g_testCase++; + + int i; + for (i = 0; i < TEST_COUNT; i++) { + (void)SampleTcpServer(); + } + LogPrintln("tcp server g_portServer = %d", g_portServer); +} + +static void TcpClientRoutine(void *p) +{ + (void)p; + g_testCase++; + + int i; + for (i = 0; i < TEST_COUNT; i++) { + (void)SampleTcpClient(); + } + LogPrintln("tcp server g_portClient = %d", g_portClient); +} + +void TcpTestDup() +{ + LogPrintln("net_socket_test_012.c enter"); + g_testCase = TEST_CASE; + int ret; + ret = sys_thread_new("tcp_server_dup", TcpServerRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + + ret = sys_thread_new("tcp_client_dup", TcpClientRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24); +} diff --git a/components/net/test/net_socket_test_013.c b/components/net/test/net_socket_test_013.c new file mode 100755 index 00000000..325393ac --- /dev/null +++ b/components/net/test/net_socket_test_013.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "lwip_test.h" +#include "lwipopts.h" +#include +#include + +#define TEST_CASE 230 +#define STACK_PORT_TCP_LONG 2231 +#define TCP_LONG_BUF_SIZE (2 * 1024) + +extern sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio); + +static int SampleTcpServer() +{ + int sfd, lsfd; + struct sockaddr_in srvAddr = { 0 }; + struct sockaddr_in clnAddr = { 0 }; + socklen_t clnAddrLen = sizeof(clnAddr); + int ret; + static char serverBuf[TCP_LONG_BUF_SIZE] = {0}; + + /* tcp server */ + lsfd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(STACK_IP); + srvAddr.sin_port = htons(STACK_PORT_TCP_LONG); + ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + ICUNIT_ASSERT_EQUAL(ret, 0, 2); + + ret = listen(lsfd, 0); + ICUNIT_ASSERT_EQUAL(ret, 0, 3); + + sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4); + + /* send */ + ret = send(sfd, serverBuf, TCP_LONG_BUF_SIZE, 0); + ICUNIT_ASSERT_EQUAL(ret, TCP_LONG_BUF_SIZE, 6); + + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 7); + ret = closesocket(lsfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8); + + return 0; +} + +static int SampleTcpClient() +{ + int sfd; + struct sockaddr_in srvAddr = { 0 }; + int ret, i; + int recvCount = 0; + static char clientBuf[TCP_LONG_BUF_SIZE] = {0}; + + /* tcp client connection */ + sfd = socket(AF_INET, SOCK_STREAM, 0); + ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 9); + + srvAddr.sin_family = AF_INET; + srvAddr.sin_addr.s_addr = inet_addr(PEER_IP); + srvAddr.sin_port = htons(STACK_PORT_TCP_LONG); + ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr)); + ICUNIT_ASSERT_EQUAL(ret, 0, 10); + + /* recv */ + for (i = 0; i < TCP_LONG_BUF_SIZE; i++) { + ret = recv(sfd, clientBuf, TCP_LONG_BUF_SIZE, 0); + recvCount += ret; + if (recvCount >= TCP_LONG_BUF_SIZE) { + LogPrintln("client recv on socket %d: %d, i = %d", sfd, recvCount, i); + break; + } + } + ICUNIT_ASSERT_NOT_EQUAL(i, TCP_LONG_BUF_SIZE, 12); + ret = closesocket(sfd); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13); + return 0; +} + +static void TcpServerRoutine(void *p) +{ + (void)p; + g_testCase++; + (void)SampleTcpServer(); +} + +static void TcpClientRoutine(void *p) +{ + (void)p; + g_testCase++; + (void)SampleTcpClient(); +} + +void TcpTestLong() +{ + LogPrintln("net_socket_test_013.c enter"); + g_testCase = TEST_CASE; + int ret; + ret = sys_thread_new("tcp_server_long", TcpServerRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23); + + ret = sys_thread_new("tcp_client_long", TcpClientRoutine, NULL, + STACK_TEST_SIZE, TCPIP_THREAD_PRIO); + ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24); +} diff --git a/components/net/test/test_main.c b/components/net/test/test_main.c new file mode 100644 index 00000000..125b9dd0 --- /dev/null +++ b/components/net/test/test_main.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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 "sys/socket.h" +#include "hos_cmsis_adp.h" + +#define LWIP_TEST_TIMEOUT 1000 // timeout 1s +#define LWIP_TEST_COUNT_FLAG 100 + +#define SOCKET_TEST 310 +#define UDP_TEST 320 +#define TCP_TEST 330 +#define OPT_TEST 340 +#define ORDER_TEST 350 +#define INET_TEST 360 +#define UDP_MORE_TEST 370 +#define TCP_MORE_TEST 380 +#define TCP_SELECT_TEST 390 +#define TCP_POLL_TEST 400 +#define NETIF_TEST 410 +#define TCP_DUP_TEST 420 +#define TCP_LONG_TEST 430 + +int g_lwipTimerCount = 0; +int g_testCase = LWIP_TEST_COUNT_FLAG; +int g_testError = 0; +int g_testTemp = LWIP_TEST_COUNT_FLAG; +extern void abort(void); +extern int SocketTest(void); +extern int UdpTest(void); +extern void TcpTest(); +extern int SockOptTest(); +extern int ByteOrderTest(void); +extern int InetTest(); +extern int UdpTestMore(void); +extern void TcpTestMore(); +extern void TcpTestSelect(); +extern void TcpTestPoll(); +extern int UdpTestNetif(void); +extern void TcpTestDup(); +extern void TcpTestLong(); + +// time out 1s +static void LwipTestTimeoutCallback(void const *argument) +{ + g_lwipTimerCount++; + switch (g_lwipTimerCount) { + case SOCKET_TEST: + SocketTest(); + break; + case UDP_TEST: + UdpTest(); + break; + case TCP_TEST: + TcpTest(); + break; + case OPT_TEST: + SockOptTest(); + break; + case ORDER_TEST: + ByteOrderTest(); + break; + case INET_TEST: + InetTest(); + break; + case UDP_MORE_TEST: + UdpTestMore(); + break; + case TCP_MORE_TEST: + TcpTestMore(); + break; + case TCP_SELECT_TEST: + TcpTestSelect(); + break; + case TCP_POLL_TEST: + TcpTestPoll(); + break; + case NETIF_TEST: + UdpTestNetif(); + break; + case TCP_DUP_TEST: + TcpTestDup(); + break; + case TCP_LONG_TEST: + TcpTestLong(); + break; + default: + break; + } +} + +osTimerId_t g_lwipTestTimerId = NULL; + +void LwipTestStartTimer(uint32 timeout) +{ + osStatus_t status; + if (g_lwipTestTimerId != NULL) { + status = osTimerStart(g_lwipTestTimerId, timeout); + if (status != osOK) { + return; + } + } else { + g_lwipTestTimerId = osTimerNew((osTimerFunc_t)LwipTestTimeoutCallback, osTimerPeriodic, NULL, NULL); + if (g_lwipTestTimerId == NULL) { + return; + } + status = osTimerStart(g_lwipTestTimerId, timeout); + if (status != osOK) { + return; + } + } +} + +void LwipTestEnter() +{ + LwipTestStartTimer(LWIP_TEST_TIMEOUT); +} diff --git a/figures/OpenHarmony-LiteOS-M核内核架构图.png b/figures/OpenHarmony-LiteOS-M核内核架构图.png new file mode 100644 index 0000000000000000000000000000000000000000..63a10e4e899d2bff697158fff9c869eb278bca59 GIT binary patch literal 17197 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 O=boC*oswI2PyatkKj;bo literal 0 HcmV?d00001 diff --git a/figures/architecture-of-openharmony-the-liteos-cortex-m-kernel.png b/figures/architecture-of-openharmony-the-liteos-cortex-m-kernel.png new file mode 100644 index 0000000000000000000000000000000000000000..63a10e4e899d2bff697158fff9c869eb278bca59 GIT binary patch literal 17197 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 O=boC*oswI2PyatkKj;bo literal 0 HcmV?d00001 diff --git a/kal/BUILD.gn b/kal/BUILD.gn new file mode 100644 index 00000000..05c2d2ad --- /dev/null +++ b/kal/BUILD.gn @@ -0,0 +1,55 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, 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. + +declare_args() { + enable_ohos_kernel_liteos_m_cmsis = true + enable_ohos_kernel_liteos_m_posix = true +} + +static_library("kal") { + sources = [ "kal.c" ] + + include_dirs = [ + "../kernel/arch/include", + "../kernel/include", + "../utils", + "../kal/cmsis", + "../kal", + ] + + deps = [] + + if (enable_ohos_kernel_liteos_m_cmsis == true) { + deps += [ "cmsis/" ] + } + + if (enable_ohos_kernel_liteos_m_posix == true) { + deps += [ "posix/" ] + } +} diff --git a/kal/cmsis/BUILD.gn b/kal/cmsis/BUILD.gn new file mode 100644 index 00000000..7cb21e4e --- /dev/null +++ b/kal/cmsis/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("cmsis") { + sources = [ "cmsis_liteos.c" ] + + include_dirs = [ + "//third_party/bounds_checking_function/include", + "../../kernel/include", + "../../kernel/arch/include", + "../../utils", + "../../kal/cmsis", + "../../kal", + ] +} diff --git a/kal/cmsis/LICENSE.txt b/kal/cmsis/LICENSE.txt new file mode 100644 index 00000000..8dada3ed --- /dev/null +++ b/kal/cmsis/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/kal/cmsis/README.OpenSource b/kal/cmsis/README.OpenSource new file mode 100644 index 00000000..c05284e1 --- /dev/null +++ b/kal/cmsis/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name" : "CMSIS", + "License" : "Apache License V2.0", + "License File" : "LICENSE.txt", + "Version Number" : "5.7.0", + "Owner" : "denny.shenwei@huawei.com", + "Upstream URL" : "http://www.arm.com/zh/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php", + "Description" : "The Cortex Microcontroller Software Interface Standard (CMSIS) is a vendor-independent hardware abstraction layer for microcontrollers that are based on Arm® Cortex® processors" + } +] diff --git a/kal/cmsis/cmsis_liteos.c b/kal/cmsis/cmsis_liteos.c index ab11efd3..0b745fc5 100644 --- a/kal/cmsis/cmsis_liteos.c +++ b/kal/cmsis/cmsis_liteos.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/cmsis/cmsis_liteos2.c b/kal/cmsis/cmsis_liteos2.c index 88e4eef0..c37552a8 100755 --- a/kal/cmsis/cmsis_liteos2.c +++ b/kal/cmsis/cmsis_liteos2.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/cmsis/cmsis_os.h b/kal/cmsis/cmsis_os.h index d1763533..7363fe79 100644 --- a/kal/cmsis/cmsis_os.h +++ b/kal/cmsis/cmsis_os.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/cmsis/hos_cmsis_adp.h b/kal/cmsis/hos_cmsis_adp.h index ac477169..d513d6f9 100644 --- a/kal/cmsis/hos_cmsis_adp.h +++ b/kal/cmsis/hos_cmsis_adp.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/kal.c b/kal/kal.c index 4cbc6b2f..4e8e5b14 100755 --- a/kal/kal.c +++ b/kal/kal.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/kal.h b/kal/kal.h index daa19c8f..2dbcd1eb 100755 --- a/kal/kal.h +++ b/kal/kal.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/BUILD.gn b/kal/posix/BUILD.gn new file mode 100644 index 00000000..aaacb08c --- /dev/null +++ b/kal/posix/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("posix") { + sources = [ + "src/errno.c", + "src/libc.c", + "src/malloc.c", + "src/pthread.c", + "src/pthread_attr.c", + "src/pthread_mutex.c", + "src/semaphore.c", + "src/time.c", + ] + + include_dirs = [ + "include", + "../../kernel/arch/include", + "../../kernel/include", + "../../utils", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kal/posix/include/COPYRIGHT b/kal/posix/include/COPYRIGHT new file mode 100644 index 00000000..e6472371 --- /dev/null +++ b/kal/posix/include/COPYRIGHT @@ -0,0 +1,190 @@ +musl as a whole is licensed under the following standard MIT license: + +---------------------------------------------------------------------- +Copyright © 2005-2020 Rich Felker, et al. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------------------------------------------------------------- + +Authors/contributors include: + +A. Wilcox +Ada Worcester +Alex Dowad +Alex Suykov +Alexander Monakov +Andre McCurdy +Andrew Kelley +Anthony G. Basile +Aric Belsito +Arvid Picciani +Bartosz Brachaczek +Benjamin Peterson +Bobby Bingham +Boris Brezillon +Brent Cook +Chris Spiegel +Clément Vasseur +Daniel Micay +Daniel Sabogal +Daurnimator +David Carlier +David Edelsohn +Denys Vlasenko +Dmitry Ivanov +Dmitry V. Levin +Drew DeVault +Emil Renner Berthing +Fangrui Song +Felix Fietkau +Felix Janda +Gianluca Anzolin +Hauke Mehrtens +He X +Hiltjo Posthuma +Isaac Dunham +Jaydeep Patil +Jens Gustedt +Jeremy Huntwork +Jo-Philipp Wich +Joakim Sindholt +John Spencer +Julien Ramseier +Justin Cormack +Kaarle Ritvanen +Khem Raj +Kylie McClain +Leah Neukirchen +Luca Barbato +Luka Perkov +M Farkas-Dyck (Strake) +Mahesh Bodapati +Markus Wichmann +Masanori Ogino +Michael Clark +Michael Forney +Mikhail Kremnyov +Natanael Copa +Nicholas J. Kain +orc +Pascal Cuoq +Patrick Oppenlander +Petr Hosek +Petr Skocik +Pierre Carrier +Reini Urban +Rich Felker +Richard Pennington +Ryan Fairfax +Samuel Holland +Segev Finer +Shiz +sin +Solar Designer +Stefan Kristiansson +Stefan O'Rear +Szabolcs Nagy +Timo Teräs +Trutz Behn +Valentin Ochs +Will Dietz +William Haddon +William Pitcock + +Portions of this software are derived from third-party works licensed +under terms compatible with the above MIT license: + +The TRE regular expression implementation (src/regex/reg* and +src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed +under a 2-clause BSD license (license text in the source files). The +included version has been heavily modified by Rich Felker in 2012, in +the interests of size, simplicity, and namespace cleanliness. + +Much of the math library code (src/math/* and src/complex/*) is +Copyright © 1993,2004 Sun Microsystems or +Copyright © 2003-2011 David Schultz or +Copyright © 2003-2009 Steven G. Kargl or +Copyright © 2003-2009 Bruce D. Evans or +Copyright © 2008 Stephen L. Moshier or +Copyright © 2017-2018 Arm Limited +and labelled as such in comments in the individual source files. All +have been licensed under extremely permissive terms. + +The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright © 2008 +The Android Open Source Project and is licensed under a two-clause BSD +license. It was taken from Bionic libc, used on Android. + +The implementation of DES for crypt (src/crypt/crypt_des.c) is +Copyright © 1994 David Burren. It is licensed under a BSD license. + +The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was +originally written by Solar Designer and placed into the public +domain. The code also comes with a fallback permissive license for use +in jurisdictions that may not recognize the public domain. + +The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 +Valentin Ochs and is licensed under an MIT-style license. + +The x86_64 port was written by Nicholas J. Kain and is licensed under +the standard MIT terms. + +The mips and microblaze ports were originally written by Richard +Pennington for use in the ellcc project. The original code was adapted +by Rich Felker for build system and code conventions during upstream +integration. It is licensed under the standard MIT terms. + +The mips64 port was contributed by Imagination Technologies and is +licensed under the standard MIT terms. + +The powerpc port was also originally written by Richard Pennington, +and later supplemented and integrated by John Spencer. It is licensed +under the standard MIT terms. + +All other files which have no copyright comments are original works +produced specifically for use as part of this library, written either +by Rich Felker, the main author of the library, or by one or more +contibutors listed above. Details on authorship of individual files +can be found in the git version control history of the project. The +omission of copyright and license comments in each file is in the +interest of source tree size. + +In addition, permission is hereby granted for all public header files +(include/* and arch/*/bits/*) and crt files intended to be linked into +applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit +the copyright notice and permission notice otherwise required by the +license, and to use these files without any requirement of +attribution. These files include substantial contributions from: + +Bobby Bingham +John Spencer +Nicholas J. Kain +Rich Felker +Richard Pennington +Stefan Kristiansson +Szabolcs Nagy + +all of whom have explicitly granted such permission. + +This file previously contained text expressing a belief that most of +the files covered by the above exception were sufficiently trivial not +to be subject to copyright, resulting in confusion over whether it +negated the permissions granted in the license. In the spirit of +permissive licensing, and of not having licensing issues being an +obstacle to adoption, that text has been removed. diff --git a/kal/posix/include/README b/kal/posix/include/README index 2b0dffc5..43a29cc1 100644 --- a/kal/posix/include/README +++ b/kal/posix/include/README @@ -1,28 +1,3 @@ ** DO NOT EDIT FILES HERE ** - -These header files are copied from musl ("//third_party/musl") except `libc.h'. - -musl as a whole is licensed under the following standard MIT license: - ----------------------------------------------------------------------- -Copyright © 2005-2020 Rich Felker, et al. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- +These header files are copied from musl ("//third_party/musl") except `libc.h', +you can see the license information of MUSL in COPYRIGHT file. diff --git a/kal/posix/include/README.OpenSource b/kal/posix/include/README.OpenSource new file mode 100644 index 00000000..e426562c --- /dev/null +++ b/kal/posix/include/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name" : "musl", + "License" : "MIT License", + "License File" : "COPYRIGHT", + "Version Number" : "1.2.0", + "Owner" : "jianghan2@huawei.com", + "Upstream URL" : "http://www.musl-libc.org/", + "Description" : "musl is an MIT-licensed implementation of the standard C library" + } +] diff --git a/kal/posix/include/bits/alltypes.h b/kal/posix/include/bits/alltypes.h old mode 100644 new mode 100755 index 696ed211..909d60d5 --- a/kal/posix/include/bits/alltypes.h +++ b/kal/posix/include/bits/alltypes.h @@ -492,9 +492,35 @@ typedef unsigned short sa_family_t; #define __DEFINED_sa_family_t #endif +#if (defined(__NEED_sched_param) || defined(__NEED_pthread_attr_t)) && !defined(__DEFINED_sched_param) +struct sched_param { + int sched_priority; + int __reserved1; +#if _REDIR_TIME64 + long __reserved2[4]; +#else + struct { + time_t __reserved1; + long __reserved2; + } __reserved2[2]; +#endif + int __reserved3; +}; +#define __DEFINED_sched_param +#endif #if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) -typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t; +typedef struct { + unsigned int detachstate; + unsigned int schedpolicy; + struct sched_param schedparam; + unsigned int inheritsched; + unsigned int scope; + unsigned int stackaddr_set; + void *stackaddr; + unsigned int stacksize_set; + size_t stacksize; +} pthread_attr_t; #define __DEFINED_pthread_attr_t #endif diff --git a/kal/posix/include/libc.h b/kal/posix/include/libc.h old mode 100755 new mode 100644 index cfec7955..d021fc6b --- a/kal/posix/include/libc.h +++ b/kal/posix/include/libc.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/include/limits.h b/kal/posix/include/limits.h index 20fda4a1..5b40fda7 100644 --- a/kal/posix/include/limits.h +++ b/kal/posix/include/limits.h @@ -2,6 +2,7 @@ #define _LIMITS_H #ifdef __ICCARM__ /* for iar */ +#define PTHREAD_STACK_MIN LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE #include_next #else @@ -68,7 +69,7 @@ /* Implementation choices... */ #define PTHREAD_KEYS_MAX 128 -#define PTHREAD_STACK_MIN 2048 +#define PTHREAD_STACK_MIN LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE #define PTHREAD_DESTRUCTOR_ITERATIONS 4 #define SEM_VALUE_MAX 0x7fffffff #define SEM_NSEMS_MAX 256 diff --git a/kal/posix/include/pthread.h b/kal/posix/include/pthread.h index 5dd71ec0..8291cdef 100644 --- a/kal/posix/include/pthread.h +++ b/kal/posix/include/pthread.h @@ -26,7 +26,6 @@ extern "C" { #define __NEED_size_t #include - #include #include @@ -82,7 +81,7 @@ extern "C" { int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict); int pthread_detach(pthread_t); -_Noreturn void pthread_exit(void *); +void pthread_exit(void *); int pthread_join(pthread_t, void **); #ifdef __GNUC__ diff --git a/kal/posix/include/sched.h b/kal/posix/include/sched.h index 822f464e..605bf91b 100644 --- a/kal/posix/include/sched.h +++ b/kal/posix/include/sched.h @@ -9,6 +9,7 @@ extern "C" { #define __NEED_struct_timespec #define __NEED_pid_t #define __NEED_time_t +#define __NEED_sched_param #ifdef _GNU_SOURCE #define __NEED_size_t @@ -16,20 +17,6 @@ extern "C" { #include -struct sched_param { - int sched_priority; - int __reserved1; -#if _REDIR_TIME64 - long __reserved2[4]; -#else - struct { - time_t __reserved1; - long __reserved2; - } __reserved2[2]; -#endif - int __reserved3; -}; - int sched_get_priority_max(int); int sched_get_priority_min(int); int sched_getparam(pid_t, struct sched_param *); diff --git a/kal/posix/include/signal.h b/kal/posix/include/signal.h old mode 100644 new mode 100755 diff --git a/kal/posix/include/sys/capability.h b/kal/posix/include/sys/capability.h index 23e9bb07..b7dd8f72 100644 --- a/kal/posix/include/sys/capability.h +++ b/kal/posix/include/sys/capability.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/src/errno.c b/kal/posix/src/errno.c index 0d3bda0d..790cc5e0 100644 --- a/kal/posix/src/errno.c +++ b/kal/posix/src/errno.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/src/libc.c b/kal/posix/src/libc.c index dd48eba0..a4018d5e 100644 --- a/kal/posix/src/libc.c +++ b/kal/posix/src/libc.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/src/libc_config.h b/kal/posix/src/libc_config.h index eca96f86..0529ba33 100644 --- a/kal/posix/src/libc_config.h +++ b/kal/posix/src/libc_config.h @@ -1,51 +1,51 @@ -/* - * 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_CONFIG_H_ -#define LIBC_CONFIG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LIBC_VERSION_STR -#define LIBC_VERSION_STR "1.0.0-LiteOS_M" -#endif - -#ifndef LIBC_VERSION_NUM -#define LIBC_VERSION_NUM 0x00010000 -#endif - -#ifdef __cplusplus -} -#endif - -#endif // LIBC_CONFIG_H_ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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_CONFIG_H_ +#define LIBC_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LIBC_VERSION_STR +#define LIBC_VERSION_STR "1.0.0-LiteOS_M" +#endif + +#ifndef LIBC_VERSION_NUM +#define LIBC_VERSION_NUM 0x00010000 +#endif + +#ifdef __cplusplus +} +#endif + +#endif // LIBC_CONFIG_H_ diff --git a/kal/posix/src/malloc.c b/kal/posix/src/malloc.c index c594837c..8b9a26f8 100644 --- a/kal/posix/src/malloc.c +++ b/kal/posix/src/malloc.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -27,93 +27,93 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "securec.h" -#include "los_config.h" -#include "los_memory.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -void *calloc(size_t nitems, size_t size) -{ - size_t real_size; - void *ptr = NULL; - - if (nitems == 0 || size == 0) { - return NULL; - } - - real_size = (size_t)(nitems * size); - ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, real_size); - if (ptr != NULL) { - (void)memset_s(ptr, real_size, 0, real_size); - } - return ptr; -} - -void free(void *ptr) -{ - if (ptr == NULL) { - return; - } - - LOS_MemFree(OS_SYS_MEM_ADDR, ptr); -} - -void *malloc(size_t size) -{ - if (size == 0) { - return NULL; - } - - return LOS_MemAlloc(OS_SYS_MEM_ADDR, size); -} - -void *zalloc(size_t size) -{ - void *ptr = NULL; - - if (size == 0) { - return NULL; - } - - ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size); - if (ptr != NULL) { - (void)memset_s(ptr, size, 0, size); - } - return ptr; -} - -void *memalign(size_t boundary, size_t size) -{ - if (size == 0) { - return NULL; - } - - return LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, boundary); -} - -void *realloc(void *ptr, size_t size) -{ - if (ptr == NULL) { - return malloc(size); - } - - if (size == 0) { - free(ptr); - return NULL; - } - - return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size); -} - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ + */ + +#include "securec.h" +#include "los_config.h" +#include "los_memory.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ + +void *calloc(size_t nitems, size_t size) +{ + size_t real_size; + void *ptr = NULL; + + if (nitems == 0 || size == 0) { + return NULL; + } + + real_size = (size_t)(nitems * size); + ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, real_size); + if (ptr != NULL) { + (void)memset_s(ptr, real_size, 0, real_size); + } + return ptr; +} + +void free(void *ptr) +{ + if (ptr == NULL) { + return; + } + + LOS_MemFree(OS_SYS_MEM_ADDR, ptr); +} + +void *malloc(size_t size) +{ + if (size == 0) { + return NULL; + } + + return LOS_MemAlloc(OS_SYS_MEM_ADDR, size); +} + +void *zalloc(size_t size) +{ + void *ptr = NULL; + + if (size == 0) { + return NULL; + } + + ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size); + if (ptr != NULL) { + (void)memset_s(ptr, size, 0, size); + } + return ptr; +} + +void *memalign(size_t boundary, size_t size) +{ + if (size == 0) { + return NULL; + } + + return LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, boundary); +} + +void *realloc(void *ptr, size_t size) +{ + if (ptr == NULL) { + return malloc(size); + } + + if (size == 0) { + free(ptr); + return NULL; + } + + return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cpluscplus */ +#endif /* __cpluscplus */ diff --git a/kal/posix/src/pthread.c b/kal/posix/src/pthread.c index 2ef0dcc5..a7e8893e 100644 --- a/kal/posix/src/pthread.c +++ b/kal/posix/src/pthread.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,7 +29,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "pthread_impl.h" +#include "pthread.h" #include #include #include @@ -91,6 +91,8 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, return ENOMEM; } + pthreadData->startRoutine = startRoutine; + pthreadData->param = arg; taskInitParam.pcName = pthreadData->name; taskInitParam.pfnTaskEntry = PthreadEntry; taskInitParam.uwArg = (UINT32)(UINTPTR)pthreadData; @@ -176,7 +178,7 @@ int pthread_join(pthread_t thread, void **retval) } while (LOS_TaskStatusGet((UINT32)thread, &taskStatus) == LOS_OK) { - usleep(10000); + (void)LOS_TaskDelay(10); /* 10: Waiting for the end of thread execution. */ } return 0; diff --git a/kal/posix/src/pthread_attr.c b/kal/posix/src/pthread_attr.c index c5dfeda6..d5e6d7b4 100644 --- a/kal/posix/src/pthread_attr.c +++ b/kal/posix/src/pthread_attr.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,7 +29,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "pthread_impl.h" +#include "pthread.h" #include #include #include "los_config.h" diff --git a/kal/posix/src/pthread_mutex.c b/kal/posix/src/pthread_mutex.c old mode 100644 new mode 100755 index 98b7ba2d..1b71d9ab --- a/kal/posix/src/pthread_mutex.c +++ b/kal/posix/src/pthread_mutex.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/src/semaphore.c b/kal/posix/src/semaphore.c index a640df62..395ed30b 100644 --- a/kal/posix/src/semaphore.c +++ b/kal/posix/src/semaphore.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kal/posix/src/time.c b/kal/posix/src/time.c index 8c61d8c6..e9fdb3af 100755 --- a/kal/posix/src/time.c +++ b/kal/posix/src/time.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,6 +29,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define _GNU_SOURCE #include #include #include @@ -88,7 +89,7 @@ STATIC const UINT8 g_montbl[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, #ifndef OFFSET_TO_MINUTE #define OFFSET_TO_MINUTE(time) (((time) < 0) ? (-(time)) : (time)) #endif -/* The highest 31 bytes, 1 indicates eastern time zone0 indicates western time zone */ +/* 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 @@ -96,8 +97,7 @@ STATIC const UINT8 g_montbl[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, #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_rtcTimeBase = 0; static UINT64 g_systickBase = 0; /* @@ -291,7 +291,7 @@ int timer_gettime(timer_t timerID, struct itimerspec *value) { UINT32 tick = 0; SWTMR_CTRL_S *swtmr = NULL; - UINT32 swtmrID = (UINT16)(UINTPTR)timerID; + UINT32 swtmrID = (UINT32)(UINTPTR)timerID; UINT32 ret; if (value == NULL) { @@ -491,8 +491,6 @@ 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) { @@ -507,12 +505,7 @@ time_t time(time_t *timer) } 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; } @@ -727,4 +720,4 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) HalSetRtcTime(g_rtcTimeBase, &usec); HalSetRtcTimeZone(g_rtcTimeZone); return 0; -} \ No newline at end of file +} diff --git a/kernel/BUILD.gn b/kernel/BUILD.gn new file mode 100644 index 00000000..1853f638 --- /dev/null +++ b/kernel/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("kernel") { + sources = [ + "src/los_event.c", + "src/los_init.c", + "src/los_mux.c", + "src/los_queue.c", + "src/los_sem.c", + "src/los_swtmr.c", + "src/los_task.c", + "src/los_tick.c", + "src/mm/los_membox.c", + "src/mm/los_memory.c", + ] + + include_dirs = [ + "include", + "arch/include", + "../components/cpup", + "../components/exchook", + "../utils", + "//third_party/bounds_checking_function/include", + ] + + if ("$board_cpu" == "cortex-m3") { + deps = [ "arch/arm/cortex-m3/gcc/:arch" ] + } else if ("$board_cpu" == "cortex-m4") { + deps = [ "arch/arm/cortex-m4/gcc/:arch" ] + } else if ("$board_cpu" == "cortex-m7") { + deps = [ "arch/arm/cortex-m7/gcc/:arch" ] + } else if ("$board_cpu" == "cortex-m33") { + deps = [ "arch/arm/cortex-m33/gcc/:arch" ] + } else if ("$board_cpu" == "") { + if ("$board_arch" == "rv32imac" || "$board_arch" == "rv32imafdc") { + deps = [ "arch/risc-v/riscv32/gcc:arch" ] + } + } +} diff --git a/kernel/arch/arm/cortex-m3/keil/cmsis/CMSIS END USER LICENCE AGREEMENT.pdf b/kernel/arch/arm/cortex-m3/keil/cmsis/CMSIS END USER LICENCE AGREEMENT.pdf new file mode 100644 index 0000000000000000000000000000000000000000..aabdddc5d9c5804f9b983d2d50ae8e0812fd21d0 GIT binary patch literal 24914 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
  • 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) { @@ -92,7 +91,6 @@ STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) * @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) { @@ -129,7 +127,6 @@ STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) * @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) { diff --git a/kernel/arch/arm/cortex-m3/keil/los_arch_context.h b/kernel/arch/arm/cortex-m3/keil/los_arch_context.h index 4759cb69..972f2fde 100644 --- a/kernel/arch/arm/cortex-m3/keil/los_arch_context.h +++ b/kernel/arch/arm/cortex-m3/keil/los_arch_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h b/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h index 3ffd4bff..b3ab442f 100755 --- a/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m3/keil/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -309,45 +309,18 @@ extern UINT32 _BootVectors[]; */ #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); #endif /* * diff --git a/kernel/arch/arm/cortex-m3/keil/los_arch_timer.h b/kernel/arch/arm/cortex-m3/keil/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/arm/cortex-m3/keil/los_arch_timer.h +++ b/kernel/arch/arm/cortex-m3/keil/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m3/keil/los_context.c b/kernel/arch/arm/cortex-m3/keil/los_context.c index 0534d705..72e33a02 100755 --- a/kernel/arch/arm/cortex-m3/keil/los_context.c +++ b/kernel/arch/arm/cortex-m3/keil/los_context.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -149,17 +149,6 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI return (VOID *)context; } -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_dispatch.S b/kernel/arch/arm/cortex-m3/keil/los_dispatch.S index be6145e1..ba53feb6 100644 --- a/kernel/arch/arm/cortex-m3/keil/los_dispatch.S +++ b/kernel/arch/arm/cortex-m3/keil/los_dispatch.S @@ -1,6 +1,6 @@ ; -; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. -; Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +; Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m3/keil/los_exc.S b/kernel/arch/arm/cortex-m3/keil/los_exc.S index 65e17a52..2da36fb4 100644 --- a/kernel/arch/arm/cortex-m3/keil/los_exc.S +++ b/kernel/arch/arm/cortex-m3/keil/los_exc.S @@ -1,6 +1,6 @@ ; -; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. -; Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +; Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m3/keil/los_interrupt.c b/kernel/arch/arm/cortex-m3/keil/los_interrupt.c index 824c20e5..3ac32488 100755 --- a/kernel/arch/arm/cortex-m3/keil/los_interrupt.c +++ b/kernel/arch/arm/cortex-m3/keil/los_interrupt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -51,12 +51,56 @@ UINT32 g_intCount = 0; #pragma data_alignment=0x100 LITE_OS_SEC_VEC #endif -HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +STATIC 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 }}; + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + #else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} #endif __weak VOID SysTick_Handler(VOID) @@ -132,12 +176,12 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) HalPreInterruptHandler(hwiIndex); #if (OS_HWI_WITH_ARG == 1) - if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { - g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); } #else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); } #endif diff --git a/kernel/arch/arm/cortex-m3/keil/los_startup.s b/kernel/arch/arm/cortex-m3/keil/los_startup.s index 876e597e..04b99451 100644 --- a/kernel/arch/arm/cortex-m3/keil/los_startup.s +++ b/kernel/arch/arm/cortex-m3/keil/los_startup.s @@ -1,26 +1,38 @@ -;/*---------------------------------------------------------------------------- -;* Huawei - LiteOS +; +; Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020-2021 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. +; ;*---------------------------------------------------------------------------- ;* Name: LOS_VENDOR.S ;* Purpose: Thread scheduler ;* Rev.: V1.0.0 ;*---------------------------------------------------------------------------- -;* - -;* Copyright (c) 2014, Huawei Technologies Co., Ltd. -;* All rights reserved. -;* Permission to use, copy, modify, and distribute this software for any -;* purpose with or without fee is hereby granted, provided that the above -;* copyright notice and this permission notice appear in all copies. - -;*THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -;*WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -;*MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -;*ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -;*WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -;*ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -;*OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -;*---------------------------------------------------------------------------*/ PRESERVE8 diff --git a/kernel/arch/arm/cortex-m3/keil/los_timer.c b/kernel/arch/arm/cortex-m3/keil/los_timer.c index 572ffe18..dd0e4a46 100755 --- a/kernel/arch/arm/cortex-m3/keil/los_timer.c +++ b/kernel/arch/arm/cortex-m3/keil/los_timer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -67,6 +67,7 @@ WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) #endif #endif + g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; g_ullTickCount = 0; diff --git a/kernel/arch/arm/cortex-m33/gcc/BUILD.gn b/kernel/arch/arm/cortex-m33/gcc/BUILD.gn new file mode 100644 index 00000000..d289c391 --- /dev/null +++ b/kernel/arch/arm/cortex-m33/gcc/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("arch") { + sources = [ + "los_context.c", + "los_dispatch.S", + "los_exc.S", + "los_interrupt.c", + "los_timer.c", + ] + + include_dirs = [ + "../../../../../kernel/arch/include", + "../../../../../kernel/include", + "../../../../../utils", + "./", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kernel/arch/arm/cortex-m33/gcc/los_arch_atomic.h b/kernel/arch/arm/cortex-m33/gcc/los_arch_atomic.h index 2e6121c3..e57c6a9b 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_arch_atomic.h +++ b/kernel/arch/arm/cortex-m33/gcc/los_arch_atomic.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -56,7 +56,6 @@ extern "C" { * @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) { @@ -92,7 +91,6 @@ STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) * @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) { @@ -129,7 +127,6 @@ STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) * @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) { diff --git a/kernel/arch/arm/cortex-m33/gcc/los_arch_context.h b/kernel/arch/arm/cortex-m33/gcc/los_arch_context.h index 4759cb69..972f2fde 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_arch_context.h +++ b/kernel/arch/arm/cortex-m33/gcc/los_arch_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m33/gcc/los_arch_interrupt.h b/kernel/arch/arm/cortex-m33/gcc/los_arch_interrupt.h index 3ffd4bff..b3ab442f 100755 --- a/kernel/arch/arm/cortex-m33/gcc/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m33/gcc/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -309,45 +309,18 @@ extern UINT32 _BootVectors[]; */ #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); #endif /* * diff --git a/kernel/arch/arm/cortex-m33/gcc/los_arch_timer.h b/kernel/arch/arm/cortex-m33/gcc/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_arch_timer.h +++ b/kernel/arch/arm/cortex-m33/gcc/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m33/gcc/los_context.c b/kernel/arch/arm/cortex-m33/gcc/los_context.c index f15654fa..a9f795b3 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_context.c +++ b/kernel/arch/arm/cortex-m33/gcc/los_context.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m33/gcc/los_dispatch.S b/kernel/arch/arm/cortex-m33/gcc/los_dispatch.S index aa56c140..298e7409 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_dispatch.S +++ b/kernel/arch/arm/cortex-m33/gcc/los_dispatch.S @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m33/gcc/los_exc.S b/kernel/arch/arm/cortex-m33/gcc/los_exc.S index 36d25456..16116b09 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_exc.S +++ b/kernel/arch/arm/cortex-m33/gcc/los_exc.S @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c index dfd3135e..1313dc7a 100755 --- a/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c +++ b/kernel/arch/arm/cortex-m33/gcc/los_interrupt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -46,12 +46,56 @@ UINT32 g_intCount = 0; /*lint -restore*/ -HWI_PROC_FUNC __attribute__((aligned(0x100))) g_hwiForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +STATIC HWI_PROC_FUNC __attribute__((aligned(0x100))) 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 }}; + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + #else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} #endif /* **************************************************************************** @@ -122,12 +166,12 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) HalPreInterruptHandler(hwiIndex); #if (OS_HWI_WITH_ARG == 1) - if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { - g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); } #else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); } #endif diff --git a/kernel/arch/arm/cortex-m33/gcc/los_timer.c b/kernel/arch/arm/cortex-m33/gcc/los_timer.c index de38c3b0..5e7cffa1 100644 --- a/kernel/arch/arm/cortex-m33/gcc/los_timer.c +++ b/kernel/arch/arm/cortex-m33/gcc/los_timer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -66,6 +66,7 @@ WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) #endif #endif + g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; g_ullTickCount = 0; diff --git a/kernel/arch/arm/cortex-m4/gcc/BUILD.gn b/kernel/arch/arm/cortex-m4/gcc/BUILD.gn new file mode 100644 index 00000000..d97c5a6d --- /dev/null +++ b/kernel/arch/arm/cortex-m4/gcc/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("arch") { + sources = [ + "los_context.c", + "los_dispatch.S", + "los_exc.S", + "los_interrupt.c", + "los_mpu.c", + "los_timer.c", + ] + + include_dirs = [ + "../../../../../kernel/arch/include", + "../../../../../kernel/include", + "../../../../../utils", + "./", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h index 2e6121c3..e57c6a9b 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_atomic.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -56,7 +56,6 @@ extern "C" { * @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) { @@ -92,7 +91,6 @@ STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) * @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) { @@ -129,7 +127,6 @@ STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) * @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) { diff --git a/kernel/arch/arm/cortex-m4/gcc/los_arch_context.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_context.h index 4759cb69..9dd2a874 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_arch_context.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -41,7 +41,7 @@ extern "C" { #endif /* __cpluscplus */ #endif /* __cpluscplus */ -typedef struct tagTskContext { +typedef struct TagTskContext { #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) UINT32 S16; @@ -128,4 +128,3 @@ extern VOID HalStartToRun(VOID); #endif /* __cpluscplus */ #endif /* _LOS_ARCH_CONTEXT_H */ - diff --git a/kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h index 6a271023..7582b28f 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -309,45 +309,18 @@ extern UINT32 _BootVectors[]; */ #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); #endif /* * @@ -461,6 +434,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 @@ -474,15 +449,14 @@ extern VOID HalPendSV(VOID); #define OS_EXC_EVENT 0x00000001 /** - *@ingroup los_exc + * @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 +typedef struct TagExcContext { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) UINT32 S16; @@ -511,7 +485,7 @@ typedef struct tagExcContext { UINT32 uwR10; UINT32 uwR11; UINT32 uwPriMask; - //auto save + /* auto save */ UINT32 uwSP; UINT32 uwR0; UINT32 uwR1; @@ -557,7 +531,7 @@ VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT * @attention: *
    • None.
    * - *@param uwArraySize [IN] Memory size of exception. + * @param uwArraySize [IN] Memory size of exception. * * @retval: None * @par Dependency: @@ -576,202 +550,164 @@ VOID HalHwiInit(); /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器入栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the bus status register was being pushed. */ #define OS_EXC_BF_STKERR 1 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器出栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the bus status register was out of the stack. */ #define OS_EXC_BF_UNSTKERR 2 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器不精确的数据访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Bus status register imprecise data access violation. */ #define OS_EXC_BF_IMPRECISERR 3 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器精确的数据访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Bus status register exact data access violation. */ #define OS_EXC_BF_PRECISERR 4 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器取指时的访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Bus status register access violation while pointing. */ #define OS_EXC_BF_IBUSERR 5 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器入栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the memory management status register was being pushed. */ #define OS_EXC_MF_MSTKERR 6 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器出栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the memory management status register was out of the stack. */ #define OS_EXC_MF_MUNSTKERR 7 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器数据访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Memory management status register data access violation. */ #define OS_EXC_MF_DACCVIOL 8 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器取指访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Memory management status register access violation. */ #define OS_EXC_MF_IACCVIOL 9 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,表示除法运算时除数为零 + * @ingroup los_exc + * Cortex-M4 exception types: ncorrect usage indicating that the divisor is zero during the division operation. */ #define OS_EXC_UF_DIVBYZERO 10 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,未对齐访问导致的错误 + * @ingroup los_exc + * Cortex-M4 exception types: Usage error, error caused by unaligned access. */ #define OS_EXC_UF_UNALIGNED 11 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,试图执行协处理器相关指令 + * @ingroup los_exc + * Cortex-M4 exception types: Incorrect usage attempting to execute coprocessor related instruction. */ #define OS_EXC_UF_NOCP 12 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,在异常返回时试图非法地加载EXC_RETURN到PC + * @ingroup los_exc + * Cortex-M4 exception types: Usage error attempting to load EXC_RETURN to PC illegally on exception return. */ #define OS_EXC_UF_INVPC 13 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,试图切入ARM状态 + * @ingroup los_exc + * Cortex-M4 exception types: Incorrect usage, attempting to cut to ARM state. */ #define OS_EXC_UF_INVSTATE 14 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,执行的指令其编码是未定义的——解码不能 + * @ingroup los_exc + * Cortex-M4 exception types: Incorrect usage. Executed instruction whose code is undefined. */ #define OS_EXC_UF_UNDEFINSTR 15 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:NMI中断 + * @ingroup los_exc + * Cortex-M4 exception types: NMI */ #define OS_EXC_CAUSE_NMI 16 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:硬fault + * @ingroup los_exc + * Cortex-M4 exception types: hard fault */ #define OS_EXC_CAUSE_HARDFAULT 17 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:任务处理函数退出 + * @ingroup los_exc + * Cortex-M4 exception types: The task handler exits. */ #define OS_EXC_CAUSE_TASK_EXIT 18 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:致命错误 + * @ingroup los_exc + * Cortex-M4 exception types: A fatal error. */ #define OS_EXC_CAUSE_FATAL_ERR 19 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:调试事件导致的硬fault + * @ingroup los_exc + * Cortex-M4 exception types: Hard Fault caused by a debug event. */ #define OS_EXC_CAUSE_DEBUGEVT 20 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:取向量时发生的硬fault + * @ingroup los_exc + * Cortex-M4 exception types: A hard fault that occurs when a quantity is oriented. */ #define OS_EXC_CAUSE_VECTBL 21 /** - *@ingroup los_exc - * 异常信息结构体 + * @ingroup los_exc + * Exception information structure * - * 描述:M4平台下的异常触发时保存的异常信息 + * Description: Exception information saved when an exception is triggered on the Cortex-M4 platform. * */ -typedef struct tagExcInfo { - /**< 异常发生阶段: 0表示异常发生在初始化中,1表示异常发生在任务中,2表示异常发生在中断中 */ +typedef struct TagExcInfo { + /**< Exception occurrence phase: 0 means that an exception occurs in initialization, 1 means that an exception occurs in a task, and 2 means that an exception occurs in an interrupt */ UINT16 phase; - /**< 异常类型,出异常时对照上面列出的1-19号 */ + /**< Exception type. When exceptions occur, check the numbers 1 - 19 listed above */ UINT16 type; - /**< 若为精确地址访问错误表示异常发生时的错误访问地址 */ + /**< If the exact address access error indicates the wrong access address when the exception occurred */ UINT32 faultAddr; - /**< 在中断中发生异常,表示中断号。在任务中发生异常,表示任务id,如果发生在初始化中,则为0xffffffff */ + /**< An exception occurs in an interrupt, indicating the interrupt number. An exception occurs in the task, indicating the task ID, or 0xFFFFFFFF if it occurs during initialization */ UINT32 thrdPid; - /**< 异常嵌套个数,目前仅支持第一次进入异常时执行注册的钩子函数 */ + /**< Number of nested exceptions. Currently only registered hook functions are supported when an exception is entered for the first time */ UINT16 nestCnt; - /**< 保留 */ + /**< reserve */ UINT16 reserved; - /**< 自动压栈浮点寄存器的异常发生时刻的硬件上下文 */ - EXC_CONTEXT_S * context; + /**< Hardware context at the time an exception to the automatic stack floating-point register occurs */ + EXC_CONTEXT_S *context; } ExcInfo; 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 } @@ -779,4 +715,3 @@ typedef struct tagExcInfoCallBackArray { #endif /* __cpluscplus */ #endif /* _LOS_EXC_H */ - diff --git a/kernel/arch/arm/cortex-m4/gcc/los_arch_timer.h b/kernel/arch/arm/cortex-m4/gcc/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_arch_timer.h +++ b/kernel/arch/arm/cortex-m4/gcc/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m4/gcc/los_context.c b/kernel/arch/arm/cortex-m4/gcc/los_context.c index f15654fa..52dd0013 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_context.c +++ b/kernel/arch/arm/cortex-m4/gcc/los_context.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -28,11 +28,12 @@ * 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_context.h" #include "securec.h" -#include "los_interrupt.h" #include "los_arch_context.h" +#include "los_task.h" +#include "los_interrupt.h" #include "los_arch_interrupt.h" #include "los_arch_timer.h" @@ -64,7 +65,8 @@ LITE_OS_SEC_TEXT_INIT VOID HalArchInit() LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) { LOS_IntLock(); - for(;;); + while (1) { + } } /* **************************************************************************** @@ -149,11 +151,6 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI return (VOID *)context; } -void HalBackTrace() -{ - -} - LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) { UINT32 ret; @@ -170,5 +167,3 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) } #endif /* __cplusplus */ #endif /* __cplusplus */ - - diff --git a/kernel/arch/arm/cortex-m4/gcc/los_dispatch.S b/kernel/arch/arm/cortex-m4/gcc/los_dispatch.S index 78523d94..648cb7c9 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_dispatch.S +++ b/kernel/arch/arm/cortex-m4/gcc/los_dispatch.S @@ -1,7 +1,40 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ .syntax unified .arch armv7e-m +.fpu fpv5-d16 .thumb +.equ OS_FPU_CPACR, 0xE000ED88 +.equ OS_FPU_CPACR_ENABLE, 0x00F00000 .equ OS_NVIC_INT_CTRL, 0xE000ED04 .equ OS_NVIC_SYSPRI2, 0xE000ED20 .equ OS_NVIC_PENDSV_PRI, 0xF0F00000 @@ -42,15 +75,31 @@ HalStartToRun: 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 - .fnend @@ -111,11 +160,17 @@ HalPendSV: 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] @@ -137,13 +192,16 @@ HalTaskSwitch: orr r7, r7, r8 strh r7, [r0 , #4] - ldr r1, [r0] + 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 .fnend diff --git a/kernel/arch/arm/cortex-m4/gcc/los_exc.S b/kernel/arch/arm/cortex-m4/gcc/los_exc.S index 2b6df84e..5de06ad5 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_exc.S +++ b/kernel/arch/arm/cortex-m4/gcc/los_exc.S @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -224,7 +224,7 @@ HalExcUsageFault: LDR R0, =OS_NVIC_FSR LDR R0, [R0] - MOV R1, #0x030F + MOVW R1, #0x030F LSL R1, R1, #16 AND R0, R0, R1 MOV R12, #0 @@ -281,7 +281,7 @@ _ExcInMSP: PUSH {R3} MRS R12, PRIMASK // store message-->exc: disable int? PUSH {R4-R12} // store message-->exc: {R4-R12} - #VPUSH {D8-D15} // FPU + #VPUSH {D8-D15} // FPU B _handleEntry .fnend @@ -291,10 +291,10 @@ _NoFloatInMsp: .fnstart .cantunwind ADD R3, R13, #32 - PUSH {R3} // save IRQ SP // store message-->exc: MSP(R13) + PUSH {R3} // store message-->exc: MSP(R13) - MRS R12, PRIMASK // store message-->exc: disable int? - PUSH {R4-R12} // store message-->exc: {R4-R12} + MRS R12, PRIMASK // store message-->exc: disable int? + PUSH {R4-R12} // store message-->exc: {R4-R12} ORR R0, R0, #FLAG_NO_FLOAT B _handleEntry .fnend @@ -320,7 +320,7 @@ _hwiActiveCheckNext: LDR R2, =g_taskScheduled LDR R2, [R2] - TST R2, #1 // OS_FLG_BGD_ACTIVE + TST R2, #1 // OS_FLG_BGD_ACTIVE BEQ _ExcInMSP // if exc occured in Init then branch @@ -333,7 +333,7 @@ _hwiActiveCheckNext: MRS R3, PSP ADD R12, R3, #104 - PUSH {R12} // save task SP + PUSH {R12} // save task SP MRS R12, PRIMASK PUSH {R4-R12} @@ -341,8 +341,8 @@ _hwiActiveCheckNext: // copy auto saved task register LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) - #VLDMIA R3!, {D8-D15} // FPU - #VSTMDB R2!, {D8-D15} // FPU + #VLDMIA R3!, {D8-D15} // FPU + #VSTMDB R2!, {D8-D15} // FPU STMFD R2!, {R4-R11} B _handleEntry .fnend @@ -352,12 +352,12 @@ _hwiActiveCheckNext: _NoFloatInPsp: .fnstart .cantunwind - MOV R2, R13 //no auto push floating registers + 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 + PUSH {R12} // save task SP MRS R12, PRIMASK PUSH {R4-R12} diff --git a/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c index 132c00c8..e9306787 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c +++ b/kernel/arch/arm/cortex-m4/gcc/los_interrupt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,12 +29,11 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "los_interrupt.h" +#include #include "los_context.h" #include "los_arch_interrupt.h" -#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" @@ -52,14 +51,63 @@ UINT32 g_intCount = 0; #elif defined(__CC_ARM) || defined(__GNUC__) LITE_OS_SEC_VEC #endif -HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +STATIC 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 }}; + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + #else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} #endif +WEAK VOID SysTick_Handler(VOID) +{ + return; +} + /* **************************************************************************** Function : HalIntNumGet Description : Get a interrupt number @@ -91,6 +139,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,15 +173,20 @@ 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); + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); } #else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); } #endif + + HalAftInterruptHandler(hwiIndex); + intSave = LOS_IntLock(); g_intCount--; LOS_IntRestore(intSave); @@ -141,10 +204,10 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) 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) + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) { UINTPTR intSave; @@ -204,8 +267,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 +274,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,15 +283,20 @@ 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; - UINT32 len = 0, i, j; + UINT32 len, 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}; + 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"; @@ -240,7 +304,10 @@ UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) char strRgException[] = "exception"; char strRgShcsr[] = "shcsr"; char strRgIntCtrl[] = "control"; - char *strRgs[] = {strRgEnable, strRgPending, strRgActive, strRgPriority, strRgException, strRgShcsr, strRgIntCtrl}; + char *strRgs[] = { + strRgEnable, strRgPending, strRgActive, strRgPriority, + strRgException, strRgShcsr, strRgIntCtrl + }; (VOID)index; (VOID)excContent; @@ -249,7 +316,7 @@ UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) 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); + len = (len >> 2); /* 2: Gets the next register offset */ for (j = 0; j < len; j++) { PRINTK("0x%x ", *(base + j)); } @@ -257,6 +324,7 @@ UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) } return 0; } +#endif UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) { @@ -288,20 +356,9 @@ 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; + UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; /* 16: Get Exception Type */ g_intCount++; g_excInfo.nestCnt++; @@ -329,22 +386,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(); } /* **************************************************************************** @@ -360,7 +404,7 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() 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++) { + for (index = 2; index < OS_VECTOR_CNT; index++) { /* 2: The starting position of the interrupt */ g_hwiForm[index] = (HWI_PROC_FUNC)HalHwiDefaultHandler; } /* Exception handler register */ @@ -371,6 +415,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 +429,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/gcc/los_mpu.c b/kernel/arch/arm/cortex-m4/gcc/los_mpu.c new file mode 100644 index 00000000..07c4991c --- /dev/null +++ b/kernel/arch/arm/cortex-m4/gcc/los_mpu.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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/gcc/los_timer.c b/kernel/arch/arm/cortex-m4/gcc/los_timer.c index 2486a29e..1a75deb0 100644 --- a/kernel/arch/arm/cortex-m4/gcc/los_timer.c +++ b/kernel/arch/arm/cortex-m4/gcc/los_timer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -28,19 +28,19 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "los_timer.h" #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 @@ -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; @@ -65,6 +65,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalTickStart(OS_TICK_HANDLER *handler) OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler); #endif #endif + + g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; g_ullTickCount = 0; @@ -76,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 @@ -186,46 +197,59 @@ static BOOL g_sysSleepFlag = FALSE; VOID HalTickLock(VOID) { - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; } VOID HalTickUnlock(VOID) { - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } BOOL HalGetSysSleepFlag(VOID) { - return g_sysSleepFlag; + return g_sysSleepFlag; } VOID HalClearSysSleepFlag(VOID) { - g_sysSleepFlag = FALSE; + g_sysSleepFlag = FALSE; } VOID HalEnterSleep(LOS_SysSleepEnum sleep) { - __DSB(); - __WFI(); - __ISB(); + __DSB(); + __WFI(); + __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 + return; +} + +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_atomic.h b/kernel/arch/arm/cortex-m4/iar/los_arch_atomic.h index 2e6121c3..e57c6a9b 100644 --- a/kernel/arch/arm/cortex-m4/iar/los_arch_atomic.h +++ b/kernel/arch/arm/cortex-m4/iar/los_arch_atomic.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -56,7 +56,6 @@ extern "C" { * @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) { @@ -92,7 +91,6 @@ STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) * @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) { @@ -129,7 +127,6 @@ STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) * @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) { diff --git a/kernel/arch/arm/cortex-m4/iar/los_arch_context.h b/kernel/arch/arm/cortex-m4/iar/los_arch_context.h index 4759cb69..afd1810a 100644 --- a/kernel/arch/arm/cortex-m4/iar/los_arch_context.h +++ b/kernel/arch/arm/cortex-m4/iar/los_arch_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -41,7 +41,7 @@ extern "C" { #endif /* __cpluscplus */ #endif /* __cpluscplus */ -typedef struct tagTskContext { +typedef struct TagTskContext { #if ((defined(__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined(__FPU_USED) && (__FPU_USED == 1U))) UINT32 S16; diff --git a/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h b/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h index 3ffd4bff..8353a4e0 100755 --- a/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m4/iar/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -309,45 +309,18 @@ extern UINT32 _BootVectors[]; */ #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); #endif /* * @@ -476,15 +449,14 @@ extern VOID HalPendSV(VOID); #define OS_EXC_EVENT 0x00000001 /** - *@ingroup los_exc + * @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 +typedef struct TagExcContext { #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) UINT32 S16; @@ -513,7 +485,7 @@ typedef struct tagExcContext { UINT32 uwR10; UINT32 uwR11; UINT32 uwPriMask; - //auto save + /* auto save */ UINT32 uwSP; UINT32 uwR0; UINT32 uwR1; @@ -559,7 +531,7 @@ VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT * @attention: *
    • None.
    * - *@param uwArraySize [IN] Memory size of exception. + * @param uwArraySize [IN] Memory size of exception. * * @retval: None * @par Dependency: @@ -578,155 +550,155 @@ VOID HalHwiInit(); /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器入栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the bus status register was being pushed. */ #define OS_EXC_BF_STKERR 1 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器出栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the bus status register was out of the stack. */ #define OS_EXC_BF_UNSTKERR 2 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器不精确的数据访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Bus status register imprecise data access violation. */ #define OS_EXC_BF_IMPRECISERR 3 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器精确的数据访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Bus status register exact data access violation. */ #define OS_EXC_BF_PRECISERR 4 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:总线状态寄存器取指时的访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Bus status register access violation while pointing. */ #define OS_EXC_BF_IBUSERR 5 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器入栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the memory management status register was being pushed. */ #define OS_EXC_MF_MSTKERR 6 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器出栈时发生错误 + * @ingroup los_exc + * Cortex-M4 exception types: An error occurred while the memory management status register was out of the stack. */ #define OS_EXC_MF_MUNSTKERR 7 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器数据访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Memory management status register data access violation. */ #define OS_EXC_MF_DACCVIOL 8 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:存储器管理状态寄存器取指访问违例 + * @ingroup los_exc + * Cortex-M4 exception types: Memory management status register access violation. */ #define OS_EXC_MF_IACCVIOL 9 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,表示除法运算时除数为零 + * @ingroup los_exc + * Cortex-M4 exception types: ncorrect usage indicating that the divisor is zero during the division operation. */ #define OS_EXC_UF_DIVBYZERO 10 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,未对齐访问导致的错误 + * @ingroup los_exc + * Cortex-M4 exception types: Usage error, error caused by unaligned access. */ #define OS_EXC_UF_UNALIGNED 11 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,试图执行协处理器相关指令 + * @ingroup los_exc + * Cortex-M4 exception types: Incorrect usage attempting to execute coprocessor related instruction. */ #define OS_EXC_UF_NOCP 12 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,在异常返回时试图非法地加载EXC_RETURN到PC + * @ingroup los_exc + * Cortex-M4 exception types: Usage error attempting to load EXC_RETURN to PC illegally on exception return. */ #define OS_EXC_UF_INVPC 13 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,试图切入ARM状态 + * @ingroup los_exc + * Cortex-M4 exception types: Incorrect usage, attempting to cut to ARM state. */ #define OS_EXC_UF_INVSTATE 14 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:用法错误,执行的指令其编码是未定义的——解码不能 + * @ingroup los_exc + * Cortex-M4 exception types: Incorrect usage. Executed instruction whose code is undefined. */ #define OS_EXC_UF_UNDEFINSTR 15 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:NMI中断 + * @ingroup los_exc + * Cortex-M4 exception types: NMI */ #define OS_EXC_CAUSE_NMI 16 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:硬fault + * @ingroup los_exc + * Cortex-M4 exception types: hard fault */ #define OS_EXC_CAUSE_HARDFAULT 17 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:任务处理函数退出 + * @ingroup los_exc + * Cortex-M4 exception types: The task handler exits. */ #define OS_EXC_CAUSE_TASK_EXIT 18 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:致命错误 + * @ingroup los_exc + * Cortex-M4 exception types: A fatal error. */ #define OS_EXC_CAUSE_FATAL_ERR 19 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:调试事件导致的硬fault + * @ingroup los_exc + * Cortex-M4 exception types: Hard Fault caused by a debug event. */ #define OS_EXC_CAUSE_DEBUGEVT 20 /** - *@ingroup los_exc - *Cortex-M3异常具体类型:取向量时发生的硬fault + * @ingroup los_exc + * Cortex-M4 exception types: A hard fault that occurs when a quantity is oriented. */ #define OS_EXC_CAUSE_VECTBL 21 /** - *@ingroup los_exc - * 异常信息结构体 + * @ingroup los_exc + * Exception information structure * - * 描述:M4平台下的异常触发时保存的异常信息 + * Description: Exception information saved when an exception is triggered on the Cortex-M4 platform. * */ -typedef struct tagExcInfo { - /**< 异常发生阶段: 0表示异常发生在初始化中,1表示异常发生在任务中,2表示异常发生在中断中 */ +typedef struct TagExcInfo { + /**< Exception occurrence phase: 0 means that an exception occurs in initialization, 1 means that an exception occurs in a task, and 2 means that an exception occurs in an interrupt */ UINT16 phase; - /**< 异常类型,出异常时对照上面列出的1-19号 */ + /**< Exception type. When exceptions occur, check the numbers 1 - 19 listed above */ UINT16 type; - /**< 若为精确地址访问错误表示异常发生时的错误访问地址 */ + /**< If the exact address access error indicates the wrong access address when the exception occurred */ UINT32 faultAddr; - /**< 在中断中发生异常,表示中断号。在任务中发生异常,表示任务id,如果发生在初始化中,则为0xffffffff */ + /**< An exception occurs in an interrupt, indicating the interrupt number. An exception occurs in the task, indicating the task ID, or 0xFFFFFFFF if it occurs during initialization */ UINT32 thrdPid; - /**< 异常嵌套个数,目前仅支持第一次进入异常时执行注册的钩子函数 */ + /**< Number of nested exceptions. Currently only registered hook functions are supported when an exception is entered for the first time */ UINT16 nestCnt; - /**< 保留 */ + /**< reserve */ UINT16 reserved; - /**< 自动压栈浮点寄存器的异常发生时刻的硬件上下文 */ - EXC_CONTEXT_S * context; + /**< Hardware context at the time an exception to the automatic stack floating-point register occurs */ + EXC_CONTEXT_S *context; } ExcInfo; extern UINT32 g_curNestCount; diff --git a/kernel/arch/arm/cortex-m4/iar/los_arch_timer.h b/kernel/arch/arm/cortex-m4/iar/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/arm/cortex-m4/iar/los_arch_timer.h +++ b/kernel/arch/arm/cortex-m4/iar/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m4/iar/los_context.c b/kernel/arch/arm/cortex-m4/iar/los_context.c index 1c6b2935..52dd0013 100755 --- a/kernel/arch/arm/cortex-m4/iar/los_context.c +++ b/kernel/arch/arm/cortex-m4/iar/los_context.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -28,11 +28,12 @@ * 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_context.h" #include "securec.h" -#include "los_interrupt.h" #include "los_arch_context.h" +#include "los_task.h" +#include "los_interrupt.h" #include "los_arch_interrupt.h" #include "los_arch_timer.h" @@ -64,7 +65,8 @@ LITE_OS_SEC_TEXT_INIT VOID HalArchInit() LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID) { LOS_IntLock(); - for(;;); + while (1) { + } } /* **************************************************************************** @@ -149,78 +151,6 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI return (VOID *)context; } -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; @@ -237,5 +167,3 @@ LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) } #endif /* __cplusplus */ #endif /* __cplusplus */ - - diff --git a/kernel/arch/arm/cortex-m4/iar/los_dispatch.S b/kernel/arch/arm/cortex-m4/iar/los_dispatch.S index 09b88b9c..e4c88527 100755 --- a/kernel/arch/arm/cortex-m4/iar/los_dispatch.S +++ b/kernel/arch/arm/cortex-m4/iar/los_dispatch.S @@ -1,6 +1,6 @@ ; -; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. -; Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +; Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m4/iar/los_exc.S b/kernel/arch/arm/cortex-m4/iar/los_exc.S index cb112a49..b28b112a 100644 --- a/kernel/arch/arm/cortex-m4/iar/los_exc.S +++ b/kernel/arch/arm/cortex-m4/iar/los_exc.S @@ -1,6 +1,6 @@ ; -; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. -; Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +; Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m4/iar/los_interrupt.c b/kernel/arch/arm/cortex-m4/iar/los_interrupt.c index f8a3898b..e9306787 100755 --- a/kernel/arch/arm/cortex-m4/iar/los_interrupt.c +++ b/kernel/arch/arm/cortex-m4/iar/los_interrupt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,9 +29,9 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "los_interrupt.h" +#include #include "los_context.h" #include "los_arch_interrupt.h" -#include #include "los_debug.h" #include "los_task.h" @@ -51,15 +51,59 @@ UINT32 g_intCount = 0; #elif defined(__CC_ARM) || defined(__GNUC__) LITE_OS_SEC_VEC #endif -HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +STATIC 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 }}; + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + #else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} #endif -__weak VOID SysTick_Handler(VOID) +WEAK VOID SysTick_Handler(VOID) { return; } @@ -132,12 +176,12 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) HalPreInterruptHandler(hwiIndex); #if (OS_HWI_WITH_ARG == 1) - if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { - g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); } #else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); } #endif @@ -160,10 +204,10 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) 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) + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg) { UINTPTR intSave; @@ -243,12 +287,16 @@ UINT8 g_uwExcTbl[FAULT_STATUS_REG_BIT] = { UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) { UINT32 *base = NULL; - UINT32 len = 0, i, j; + UINT32 len, 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}; + 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"; @@ -256,7 +304,10 @@ UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) char strRgException[] = "exception"; char strRgShcsr[] = "shcsr"; char strRgIntCtrl[] = "control"; - char *strRgs[] = {strRgEnable, strRgPending, strRgActive, strRgPriority, strRgException, strRgShcsr, strRgIntCtrl}; + char *strRgs[] = { + strRgEnable, strRgPending, strRgActive, strRgPriority, + strRgException, strRgShcsr, strRgIntCtrl + }; (VOID)index; (VOID)excContent; @@ -265,7 +316,7 @@ UINT32 HalExcNvicDump(UINT32 index, UINT32 *excContent) 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); + len = (len >> 2); /* 2: Gets the next register offset */ for (j = 0; j < len; j++) { PRINTK("0x%x ", *(base + j)); } @@ -307,7 +358,7 @@ UINT32 HalExcContextDump(UINT32 index, UINT32 *excContent) LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(UINT32 excType, UINT32 faultAddr, UINT32 pid, EXC_CONTEXT_S *excBufAddr) { - UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; + UINT16 tmpFlag = (excType >> 16) & OS_NULL_SHORT; /* 16: Get Exception Type */ g_intCount++; g_excInfo.nestCnt++; @@ -353,7 +404,7 @@ LITE_OS_SEC_TEXT_INIT VOID HalHwiInit() 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++) { + for (index = 2; index < OS_VECTOR_CNT; index++) { /* 2: The starting position of the interrupt */ g_hwiForm[index] = (HWI_PROC_FUNC)HalHwiDefaultHandler; } /* Exception handler register */ diff --git a/kernel/arch/arm/cortex-m4/iar/los_mpu.c b/kernel/arch/arm/cortex-m4/iar/los_mpu.c old mode 100644 new mode 100755 index 5e4194d7..07c4991c --- a/kernel/arch/arm/cortex-m4/iar/los_mpu.c +++ b/kernel/arch/arm/cortex-m4/iar/los_mpu.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m4/iar/los_timer.c b/kernel/arch/arm/cortex-m4/iar/los_timer.c index 77a418b6..1a75deb0 100755 --- a/kernel/arch/arm/cortex-m4/iar/los_timer.c +++ b/kernel/arch/arm/cortex-m4/iar/los_timer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -28,19 +28,19 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include "los_timer.h" #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 @@ -65,6 +65,8 @@ WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) OsSetVector(SysTick_IRQn, (HWI_PROC_FUNC)handler); #endif #endif + + g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; g_ullTickCount = 0; @@ -195,34 +197,34 @@ static BOOL g_sysSleepFlag = FALSE; VOID HalTickLock(VOID) { - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; } VOID HalTickUnlock(VOID) { - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; } BOOL HalGetSysSleepFlag(VOID) { - return g_sysSleepFlag; + return g_sysSleepFlag; } VOID HalClearSysSleepFlag(VOID) { - g_sysSleepFlag = FALSE; + g_sysSleepFlag = FALSE; } VOID HalEnterSleep(LOS_SysSleepEnum sleep) { - __DSB(); - __WFI(); - __ISB(); + __DSB(); + __WFI(); + __ISB(); } WEAK VOID HalDelay(UINT32 ticks) { - + return; } WEAK UINT64 HalGetExpandTick(VOID) diff --git a/kernel/arch/arm/cortex-m7/gcc/BUILD.gn b/kernel/arch/arm/cortex-m7/gcc/BUILD.gn new file mode 100644 index 00000000..d289c391 --- /dev/null +++ b/kernel/arch/arm/cortex-m7/gcc/BUILD.gn @@ -0,0 +1,46 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("arch") { + sources = [ + "los_context.c", + "los_dispatch.S", + "los_exc.S", + "los_interrupt.c", + "los_timer.c", + ] + + include_dirs = [ + "../../../../../kernel/arch/include", + "../../../../../kernel/include", + "../../../../../utils", + "./", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kernel/arch/arm/cortex-m7/gcc/los_arch_atomic.h b/kernel/arch/arm/cortex-m7/gcc/los_arch_atomic.h index 2e6121c3..e57c6a9b 100644 --- a/kernel/arch/arm/cortex-m7/gcc/los_arch_atomic.h +++ b/kernel/arch/arm/cortex-m7/gcc/los_arch_atomic.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -56,7 +56,6 @@ extern "C" { * @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) { @@ -92,7 +91,6 @@ STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) * @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) { @@ -129,7 +127,6 @@ STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) * @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) { diff --git a/kernel/arch/arm/cortex-m7/gcc/los_arch_context.h b/kernel/arch/arm/cortex-m7/gcc/los_arch_context.h index 4759cb69..972f2fde 100644 --- a/kernel/arch/arm/cortex-m7/gcc/los_arch_context.h +++ b/kernel/arch/arm/cortex-m7/gcc/los_arch_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h b/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h index 3ffd4bff..b3ab442f 100755 --- a/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m7/gcc/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -309,45 +309,18 @@ extern UINT32 _BootVectors[]; */ #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); #endif /* * diff --git a/kernel/arch/arm/cortex-m7/gcc/los_arch_timer.h b/kernel/arch/arm/cortex-m7/gcc/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/arm/cortex-m7/gcc/los_arch_timer.h +++ b/kernel/arch/arm/cortex-m7/gcc/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/gcc/los_context.c b/kernel/arch/arm/cortex-m7/gcc/los_context.c index f15654fa..e4da9f80 100644 --- a/kernel/arch/arm/cortex-m7/gcc/los_context.c +++ b/kernel/arch/arm/cortex-m7/gcc/los_context.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -149,11 +149,6 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI return (VOID *)context; } -void HalBackTrace() -{ - -} - LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler) { UINT32 ret; diff --git a/kernel/arch/arm/cortex-m7/gcc/los_dispatch.S b/kernel/arch/arm/cortex-m7/gcc/los_dispatch.S index aa56c140..298e7409 100644 --- a/kernel/arch/arm/cortex-m7/gcc/los_dispatch.S +++ b/kernel/arch/arm/cortex-m7/gcc/los_dispatch.S @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/gcc/los_exc.S b/kernel/arch/arm/cortex-m7/gcc/los_exc.S index 46f01bf8..927ed35e 100644 --- a/kernel/arch/arm/cortex-m7/gcc/los_exc.S +++ b/kernel/arch/arm/cortex-m7/gcc/los_exc.S @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c b/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c index 40ac32bf..173c6d52 100755 --- a/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c +++ b/kernel/arch/arm/cortex-m7/gcc/los_interrupt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -46,12 +46,56 @@ UINT32 g_intCount = 0; /*lint -restore*/ -HWI_PROC_FUNC __attribute__((aligned(0x100))) g_hwiForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +STATIC HWI_PROC_FUNC __attribute__((aligned(0x100))) 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 }}; + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + #else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} #endif /* **************************************************************************** @@ -122,12 +166,12 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) HalPreInterruptHandler(hwiIndex); #if (OS_HWI_WITH_ARG == 1) - if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { - g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); } #else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); } #endif diff --git a/kernel/arch/arm/cortex-m7/gcc/los_timer.c b/kernel/arch/arm/cortex-m7/gcc/los_timer.c index 9cfbdfa8..dfbf29bf 100755 --- a/kernel/arch/arm/cortex-m7/gcc/los_timer.c +++ b/kernel/arch/arm/cortex-m7/gcc/los_timer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -66,6 +66,7 @@ WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) #endif #endif + g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; g_ullTickCount = 0; diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h b/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h index 2e6121c3..e57c6a9b 100644 --- a/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_atomic.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -56,7 +56,6 @@ extern "C" { * @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) { @@ -92,7 +91,6 @@ STATIC INLINE INT32 HalAtomicXchg32bits(volatile INT32 *v, INT32 val) * @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) { @@ -129,7 +127,6 @@ STATIC INLINE INT32 HalAtomicDecRet(volatile INT32 *v) * @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) { diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_context.h b/kernel/arch/arm/cortex-m7/iar/los_arch_context.h index 4759cb69..972f2fde 100644 --- a/kernel/arch/arm/cortex-m7/iar/los_arch_context.h +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h b/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h old mode 100644 new mode 100755 index 3ffd4bff..b3ab442f --- a/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -309,45 +309,18 @@ extern UINT32 _BootVectors[]; */ #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg); #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) +extern VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector); #endif /* * diff --git a/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h b/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h +++ b/kernel/arch/arm/cortex-m7/iar/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/iar/los_context.c b/kernel/arch/arm/cortex-m7/iar/los_context.c index 2c12e0ab..e4da9f80 100644 --- a/kernel/arch/arm/cortex-m7/iar/los_context.c +++ b/kernel/arch/arm/cortex-m7/iar/los_context.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -149,80 +149,6 @@ LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOI 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; diff --git a/kernel/arch/arm/cortex-m7/iar/los_dispatch.S b/kernel/arch/arm/cortex-m7/iar/los_dispatch.S old mode 100644 new mode 100755 index 09b88b9c..e4c88527 --- a/kernel/arch/arm/cortex-m7/iar/los_dispatch.S +++ b/kernel/arch/arm/cortex-m7/iar/los_dispatch.S @@ -1,6 +1,6 @@ ; -; Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. -; Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. +; Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. +; Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/iar/los_exc.S b/kernel/arch/arm/cortex-m7/iar/los_exc.S index 45e11851..59d7dd57 100644 --- a/kernel/arch/arm/cortex-m7/iar/los_exc.S +++ b/kernel/arch/arm/cortex-m7/iar/los_exc.S @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/arm/cortex-m7/iar/los_interrupt.c b/kernel/arch/arm/cortex-m7/iar/los_interrupt.c old mode 100644 new mode 100755 index 3efcfdc0..d0985d9d --- a/kernel/arch/arm/cortex-m7/iar/los_interrupt.c +++ b/kernel/arch/arm/cortex-m7/iar/los_interrupt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -47,12 +47,56 @@ UINT32 g_intCount = 0; /*lint -restore*/ #pragma location = ".data.vector" #pragma data_alignment=0x100 -HWI_PROC_FUNC g_hwiForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt form mapping handling function array. + */ +STATIC 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 }}; + +typedef struct { + HWI_PROC_FUNC pfnHandler; + VOID *pParm; +} HWI_HANDLER_FUNC; + +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_HANDLER_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {{ (HWI_PROC_FUNC)0, (HWI_ARG_T)0 }}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector, VOID *arg) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = (HWI_PROC_FUNC)HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pfnHandler = vector; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT].pParm = arg; + } +} + #else -HWI_PROC_FUNC g_hwiSlaveForm[OS_VECTOR_CNT] = {0}; +/* * + * @ingroup los_hwi + * hardware interrupt handler form mapping handling function array. + */ +STATIC HWI_PROC_FUNC g_hwiHandlerForm[OS_VECTOR_CNT] = {0}; + +/* * + * @ingroup los_hwi + * Set interrupt vector table. + */ +VOID OsSetVector(UINT32 num, HWI_PROC_FUNC vector) +{ + if ((num + OS_SYS_VECTOR_CNT) < OS_VECTOR_CNT) { + g_hwiForm[num + OS_SYS_VECTOR_CNT] = HalInterrupt; + g_hwiHandlerForm[num + OS_SYS_VECTOR_CNT] = vector; + } +} #endif WEAK VOID SysTick_Handler(VOID) @@ -128,12 +172,12 @@ LITE_OS_SEC_TEXT VOID HalInterrupt(VOID) HalPreInterruptHandler(hwiIndex); #if (OS_HWI_WITH_ARG == 1) - if (g_hwiSlaveForm[hwiIndex].pfnHandler != 0) { - g_hwiSlaveForm[hwiIndex].pfnHandler((VOID *)g_hwiSlaveForm[hwiIndex].pParm); + if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) { + g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm); } #else - if (g_hwiSlaveForm[hwiIndex] != 0) { - g_hwiSlaveForm[hwiIndex](); + if (g_hwiHandlerForm[hwiIndex] != 0) { + g_hwiHandlerForm[hwiIndex](); } #endif diff --git a/kernel/arch/arm/cortex-m7/iar/los_mpu.c b/kernel/arch/arm/cortex-m7/iar/los_mpu.c old mode 100644 new mode 100755 index 5e4194d7..5970e8ae --- a/kernel/arch/arm/cortex-m7/iar/los_mpu.c +++ b/kernel/arch/arm/cortex-m7/iar/los_mpu.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,7 +29,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "los_mpu.h" -#include "los_config.h" #include "los_context.h" #ifdef __cplusplus diff --git a/kernel/arch/arm/cortex-m7/iar/los_timer.c b/kernel/arch/arm/cortex-m7/iar/los_timer.c old mode 100644 new mode 100755 index 9cfbdfa8..dfbf29bf --- a/kernel/arch/arm/cortex-m7/iar/los_timer.c +++ b/kernel/arch/arm/cortex-m7/iar/los_timer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -66,6 +66,7 @@ WEAK UINT32 HalTickStart(OS_TICK_HANDLER *handler) #endif #endif + g_sysClock = OS_SYS_CLOCK; g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND; g_ullTickCount = 0; diff --git a/kernel/arch/include/los_arch.h b/kernel/arch/include/los_arch.h index 37775978..7ba4f7ae 100755 --- a/kernel/arch/include/los_arch.h +++ b/kernel/arch/include/los_arch.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -41,15 +41,7 @@ extern "C" { #endif /* __cpluscplus */ #endif /* __cpluscplus */ - -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 +VOID HalArchInit(VOID); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/arch/include/los_atomic.h b/kernel/arch/include/los_atomic.h index 6ff27f8d..1fc14913 100644 --- a/kernel/arch/include/los_atomic.h +++ b/kernel/arch/include/los_atomic.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/include/los_context.h b/kernel/arch/include/los_context.h index ebb1a4c4..058d7104 100644 --- a/kernel/arch/include/los_context.h +++ b/kernel/arch/include/los_context.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/include/los_interrupt.h b/kernel/arch/include/los_interrupt.h index 0125f1dd..fb13b5d2 100755 --- a/kernel/arch/include/los_interrupt.h +++ b/kernel/arch/include/los_interrupt.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -58,16 +58,10 @@ typedef UINT32 HWI_ARG_T; #if (OS_HWI_WITH_ARG == 1) typedef VOID (*HWI_PROC_FUNC)(VOID *parm); -typedef struct { - HWI_PROC_FUNC pfnHandler; - VOID *pParm; -} HWI_SLAVE_FUNC; - #else - typedef VOID (*HWI_PROC_FUNC)(void); - #endif + UINT32 HalIsIntAcvive(VOID); #define OS_INT_ACTIVE (HalIsIntAcvive()) #define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) @@ -128,10 +122,10 @@ extern UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum); * @see None. */ extern UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum, - HWI_PRIOR_T hwiPrio, - HWI_MODE_T mode, - HWI_PROC_FUNC handler, - HWI_ARG_T arg); + HWI_PRIOR_T hwiPrio, + HWI_MODE_T mode, + HWI_PROC_FUNC handler, + HWI_ARG_T arg); #ifdef __cplusplus #if __cplusplus diff --git a/kernel/arch/include/los_mpu.h b/kernel/arch/include/los_mpu.h old mode 100644 new mode 100755 index 7e4f1da4..17f1cc70 --- a/kernel/arch/include/los_mpu.h +++ b/kernel/arch/include/los_mpu.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/include/los_timer.h b/kernel/arch/include/los_timer.h index e27cb40f..e216c3f4 100755 --- a/kernel/arch/include/los_timer.h +++ b/kernel/arch/include/los_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -53,8 +53,8 @@ extern "C" { #define MACHINE_CYCLE_DEALAY_TIMES (LOSCFG_BASE_CORE_TICK_PER_SECOND << 2) typedef enum { - OS_SYS_NORMAL_SLEEP = 0, - OS_SYS_DEEP_SLEEP, + OS_SYS_NORMAL_SLEEP = 0, + OS_SYS_DEEP_SLEEP, } LOS_SysSleepEnum; VOID HalTickLock(VOID); diff --git a/kernel/arch/risc-v/riscv32/gcc/BUILD.gn b/kernel/arch/risc-v/riscv32/gcc/BUILD.gn new file mode 100644 index 00000000..03d5a9cb --- /dev/null +++ b/kernel/arch/risc-v/riscv32/gcc/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. +# Copyright (c) 2020-2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +static_library("arch") { + sources = [ + "los_context.c", + "los_dispatch.S", + "los_exc.S", + "los_interrupt.c", + "los_timer.c", + ] + + include_dirs = [ + "../../../../../kernel/arch/include", + "../../../../../kernel/include", + "../../../../../utils", + "./", + "./asm", + "//third_party/bounds_checking_function/include", + ] +} diff --git a/kernel/arch/risc-v/asm/soc_common.h b/kernel/arch/risc-v/riscv32/gcc/asm/soc_common.h similarity index 98% rename from kernel/arch/risc-v/asm/soc_common.h rename to kernel/arch/risc-v/riscv32/gcc/asm/soc_common.h index 7247e6cb..7032ada1 100644 --- a/kernel/arch/risc-v/asm/soc_common.h +++ b/kernel/arch/risc-v/riscv32/gcc/asm/soc_common.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/risc-v/los_arch_context.h b/kernel/arch/risc-v/riscv32/gcc/los_arch_context.h similarity index 96% rename from kernel/arch/risc-v/los_arch_context.h rename to kernel/arch/risc-v/riscv32/gcc/los_arch_context.h index 864d8a40..5eb0ee0e 100644 --- a/kernel/arch/risc-v/los_arch_context.h +++ b/kernel/arch/risc-v/riscv32/gcc/los_arch_context.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -148,7 +148,6 @@ extern VOID HalStartToRun(VOID); * @par Dependency: * los_hw.h: the header file that contains the API declaration. * @see None. - * @since Huawei LiteOS V200R002C00 */ extern VOID wfi(VOID); @@ -168,7 +167,6 @@ extern VOID wfi(VOID); * @par Dependency: *
    • los_hw.h: the header file that contains the API declaration.
    * @see None. - * @since Huawei LiteOS V200R002C00 */ extern VOID mb(VOID); @@ -188,7 +186,6 @@ extern VOID mb(VOID); * @par Dependency: *
    • los_hw.h: the header file that contains the API declaration.
    * @see None. - * @since Huawei LiteOS V200R002C00 */ extern VOID dsb(VOID); diff --git a/kernel/arch/risc-v/los_arch_interrupt.h b/kernel/arch/risc-v/riscv32/gcc/los_arch_interrupt.h similarity index 95% rename from kernel/arch/risc-v/los_arch_interrupt.h rename to kernel/arch/risc-v/riscv32/gcc/los_arch_interrupt.h index f318311d..a0ec90b0 100755 --- a/kernel/arch/risc-v/los_arch_interrupt.h +++ b/kernel/arch/risc-v/riscv32/gcc/los_arch_interrupt.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/risc-v/los_arch_timer.h b/kernel/arch/risc-v/riscv32/gcc/los_arch_timer.h similarity index 92% rename from kernel/arch/risc-v/los_arch_timer.h rename to kernel/arch/risc-v/riscv32/gcc/los_arch_timer.h index 2f38c220..59159c0c 100644 --- a/kernel/arch/risc-v/los_arch_timer.h +++ b/kernel/arch/risc-v/riscv32/gcc/los_arch_timer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/risc-v/los_context.c b/kernel/arch/risc-v/riscv32/gcc/los_context.c similarity index 98% rename from kernel/arch/risc-v/los_context.c rename to kernel/arch/risc-v/riscv32/gcc/los_context.c index 79e5f445..ed79418d 100644 --- a/kernel/arch/risc-v/los_context.c +++ b/kernel/arch/risc-v/riscv32/gcc/los_context.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/risc-v/los_dispatch.S b/kernel/arch/risc-v/riscv32/gcc/los_dispatch.S similarity index 99% rename from kernel/arch/risc-v/los_dispatch.S rename to kernel/arch/risc-v/riscv32/gcc/los_dispatch.S index b0edbadb..cf49ae8b 100644 --- a/kernel/arch/risc-v/los_dispatch.S +++ b/kernel/arch/risc-v/riscv32/gcc/los_dispatch.S @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/risc-v/los_exc.S b/kernel/arch/risc-v/riscv32/gcc/los_exc.S similarity index 98% rename from kernel/arch/risc-v/los_exc.S rename to kernel/arch/risc-v/riscv32/gcc/los_exc.S index b90375ff..70703a41 100755 --- a/kernel/arch/risc-v/los_exc.S +++ b/kernel/arch/risc-v/riscv32/gcc/los_exc.S @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/arch/risc-v/los_interrupt.c b/kernel/arch/risc-v/riscv32/gcc/los_interrupt.c similarity index 80% rename from kernel/arch/risc-v/los_interrupt.c rename to kernel/arch/risc-v/riscv32/gcc/los_interrupt.c index 8983ec37..6d0faf94 100755 --- a/kernel/arch/risc-v/los_interrupt.c +++ b/kernel/arch/risc-v/riscv32/gcc/los_interrupt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -67,12 +67,6 @@ const CHAR g_excInformation[RISCV_EXC_TYPE_NUM][50] = { { "Store/AMO page fault!" }, }; -#define RA_OFFSET 4 -#define FP_OFFSET 8 -#define OS_MAX_BACKTRACE 15 -#define FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0) -#define FP_CHECK(value) (HalBackTraceFpCheck(value) && ((UINT32)(value) != FP_INIT_VALUE) && FP_ALIGN(value)) - LITE_OS_SEC_BSS UINT32 g_intCount = 0; LITE_OS_SEC_BSS UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM]; LITE_OS_SEC_DATA_INIT HWI_HANDLE_FORM_S g_hwiForm[OS_HWI_MAX_NUM] = { @@ -223,50 +217,6 @@ LITE_OS_SEC_TEXT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum) return LOS_OK; } -STATIC VOID BackTraceSub(UINT32 fp) -{ - UINT32 backFp = fp; - UINT32 tmpFp; - UINT32 backRa; - UINT32 count = 0; - - while (FP_CHECK(backFp)) { - tmpFp = backFp; - backRa = *((UINT32 *)(UINTPTR)(tmpFp - RA_OFFSET)); - backFp = *((UINT32 *)(UINTPTR)(tmpFp - FP_OFFSET)); - PRINTK("traceback %u -- ra = 0x%x fp = 0x%x\n", count, backRa, backFp); - - count++; - - if ((count == OS_MAX_BACKTRACE) || (backFp == tmpFp) || \ - (!HalBackTraceRaCheck(backRa))) { - break; - } - } - PRINTK("*******backtrace end*******\n"); -} - -STATIC VOID BackTrace(UINT32 fp) -{ - PRINTK("*******backtrace begin*******\n"); - - BackTraceSub(fp); -} - -STATIC VOID ExcBackTrace(UINT32 fp, UINT32 ra) -{ - UINT32 backFp; - if (FP_CHECK(fp)) { - backFp = *((UINT32 *)(UINTPTR)(fp - RA_OFFSET)); - if ((backFp != ra) && FP_CHECK(backFp)) { - fp = backFp; - } - BackTrace(fp); - } else { - PRINTK("fp error, back trace failed!\n"); - } -} - STATIC VOID DisplayTaskInfo(VOID) { TSK_INFO_S taskInfo; @@ -287,6 +237,23 @@ STATIC VOID DisplayTaskInfo(VOID) return; } +STATIC VOID ExcBackTrace(VOID) +{ + UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0}; + UINT32 index; + + OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 1); /* 1: Ignore the one layer call relationship within the function. */ + + PRINTK("----- traceback start -----\r\n"); + for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) { + if (LR[index] == 0) { + break; + } + PRINTK("traceback %d -- lr = 0x%x\r\n", index, LR[index]); + } + PRINTK("----- traceback end -----\r\n"); +} + STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc) { const TaskContext *taskContext = &(exc->context->taskContext); @@ -327,7 +294,7 @@ STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc) PRINTK("t5 = 0x%x\n", taskContext->t5); PRINTK("t6 = 0x%x\n", taskContext->t6); - ExcBackTrace(taskContext->s0, taskContext->ra); + ExcBackTrace(); } STATIC VOID ExcInfoDisplay(const LosExcContext *excBufAddr) @@ -358,7 +325,6 @@ VOID HalExcEntry(const LosExcContext *excBufAddr) UINT32 ret; g_excInfo.type = excBufAddr->mcause & 0x1FF; g_excInfo.context = (LosExcContext *)excBufAddr; - if (g_excInfo.nestCnt > 2) { /* 2: Number of layers of exception nesting */ PRINTK("hard faule!\n\r"); goto SYSTEM_DEATH; @@ -384,60 +350,6 @@ SYSTEM_DEATH: } } -LITE_OS_SEC_TEXT VOID HalTaskBackTrace(UINT32 taskID) -{ - LosTaskCB *taskCB = NULL; - - if (taskID >= g_taskMaxNum) { - PRINT_ERR("\r\nTask PID is invalid!\n"); - return; - } - - taskCB = OS_TCB_FROM_TID(taskID); - if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED) || (taskCB->taskEntry == NULL) || - (taskCB->taskName == NULL)) { - PRINT_ERR("\r\nThe task is not created!\n"); - return; - } - - if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { - HalBackTrace(); - return; - } - - PRINTK("taskName = %s\n", taskCB->taskName); - PRINTK("taskID = 0x%x\n", taskCB->taskID); - PRINTK("curr ra = 0x%08x\n", ((TaskContext *)(taskCB->stackPointer))->ra); - ExcBackTrace(((TaskContext *)(taskCB->stackPointer))->s0, ((TaskContext *)(taskCB->stackPointer))->ra); -} - -LITE_OS_SEC_TEXT VOID HalBackTrace(VOID) -{ - UINT32 fp = GetFp(); - PRINTK("taskName = %s\n", g_losTask.runTask->taskName); - PRINTK("taskID = %u\n", g_losTask.runTask->taskID); - PRINTK("curr fp = 0x%08x \n", fp); - 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)); -} - #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/arch/risc-v/los_timer.c b/kernel/arch/risc-v/riscv32/gcc/los_timer.c similarity index 94% rename from kernel/arch/risc-v/los_timer.c rename to kernel/arch/risc-v/riscv32/gcc/los_timer.c index 495372bf..9c6e4585 100755 --- a/kernel/arch/risc-v/los_timer.c +++ b/kernel/arch/risc-v/riscv32/gcc/los_timer.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/include/los_config.h b/kernel/include/los_config.h index 9767d117..04290cde 100755 --- a/kernel/include/los_config.h +++ b/kernel/include/los_config.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -433,11 +433,35 @@ extern UINT8 *m_aucSysMem0; /** * @ingroup los_config * Configuration memory leak detection + * @attention + * Need to enable backtrace module synchronously by configuration LOSCFG_BACKTRACE_TYPE, + * and call LOS_BackTraceInit to complete initialization before the memory pool is initialized. */ #ifndef LOSCFG_MEM_LEAKCHECK #define LOSCFG_MEM_LEAKCHECK 0 #endif +/** + * @ingroup los_config + * The default is 4, 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. + * @attention + * The default is in the IAR tool. Under different compilation environments, this value needs to be adjusted. + */ +#ifndef LOSCFG_MEM_OMIT_LR_CNT +#define LOSCFG_MEM_OMIT_LR_CNT 4 +#endif + +/** + * @ingroup los_config + * The record number of layers of the function call relationship starting from the number of + * ignored layers(LOSCFG_MEM_OMIT_LR_CNT). + */ +#ifndef LOSCFG_MEM_RECORD_LR_CNT +#define LOSCFG_MEM_RECORD_LR_CNT 3 +#endif + /** * @ingroup los_config * Configuration memory leak recorded num @@ -546,6 +570,29 @@ extern UINT8 *m_aucSysMem0; #define LOSCFG_KERNEL_PRINTF 1 #endif +/* ============================================================================= + backtrace configuration +============================================================================= */ +/** + * @ingroup los_config + * Configuration backtrace type + * 0: Close stack analysis module. + * 1: Call stack analysis for cortex-m series. + * 2: Call stack analysis for risc-v. + * others: Not currently supported. + */ +#ifndef LOSCFG_BACKTRACE_TYPE +#define LOSCFG_BACKTRACE_TYPE 0 +#endif + +/** + * @ingroup los_config + * Configuration backtrace depth. + */ +#ifndef LOSCFG_BACKTRACE_DEPTH +#define LOSCFG_BACKTRACE_DEPTH 15 +#endif + #ifdef __cplusplus #if __cplusplus } diff --git a/kernel/include/los_event.h b/kernel/include/los_event.h index 7e0c0cf1..933215af 100644 --- a/kernel/include/los_event.h +++ b/kernel/include/los_event.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/include/los_membox.h b/kernel/include/los_membox.h index ba6e990b..cc65225e 100755 --- a/kernel/include/los_membox.h +++ b/kernel/include/los_membox.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -236,7 +236,7 @@ extern VOID LOS_ShowBox(VOID *pool); * be abnormal. * * - * @param boxMem [IN] Type #VOID* Pointer to the calculate membox. + * @param boxMem [IN] Type #VOID* Pointer to the calculate membox. * @param maxBlk [OUT] Type #UINT32* Record membox max block. * @param blkCnt [OUT] Type #UINT32* Record membox block count alreay allocated. * @param blkSize [OUT] Type #UINT32* Record membox block size. diff --git a/kernel/include/los_memory.h b/kernel/include/los_memory.h index 667b6956..ee95e3d6 100755 --- a/kernel/include/los_memory.h +++ b/kernel/include/los_memory.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -58,23 +58,6 @@ UINT32 OsMemExcInfoGet(UINT32 memNumMax, MemInfoCB *memExcInfo); #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. diff --git a/kernel/include/los_mux.h b/kernel/include/los_mux.h index 0a8ad6aa..8e5a1295 100644 --- a/kernel/include/los_mux.h +++ b/kernel/include/los_mux.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/include/los_queue.h b/kernel/include/los_queue.h index fb6cff77..68c1cc50 100644 --- a/kernel/include/los_queue.h +++ b/kernel/include/los_queue.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/include/los_sem.h b/kernel/include/los_sem.h index 3da51967..ebe148cb 100644 --- a/kernel/include/los_sem.h +++ b/kernel/include/los_sem.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/include/los_swtmr.h b/kernel/include/los_swtmr.h old mode 100755 new mode 100644 index bce51ff9..9842e48f --- a/kernel/include/los_swtmr.h +++ b/kernel/include/los_swtmr.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h old mode 100755 new mode 100644 index d3d135aa..5ef1a695 --- a/kernel/include/los_task.h +++ b/kernel/include/los_task.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -1651,8 +1651,8 @@ typedef struct { typedef struct { LOS_DL_LIST *sortLink; - UINT16 cursor; - UINT16 reserved; + UINT16 cursor; + UINT16 reserved; } TaskSortLinkAttr; /** diff --git a/kernel/include/los_tick.h b/kernel/include/los_tick.h index 36b2f50b..ea8f51d1 100644 --- a/kernel/include/los_tick.h +++ b/kernel/include/los_tick.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/src/los_event.c b/kernel/src/los_event.c index 3862a173..f1ab2af6 100644 --- a/kernel/src/los_event.c +++ b/kernel/src/los_event.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/src/los_init.c b/kernel/src/los_init.c index bf932d40..50a344cc 100755 --- a/kernel/src/los_init.c +++ b/kernel/src/los_init.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -192,6 +192,14 @@ 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; + //} +#endif + #if (LOSCFG_PLATFORM_EXC == 1) OsExcMsgDumpInit(); #endif diff --git a/kernel/src/los_mux.c b/kernel/src/los_mux.c index b0395f98..87cdf5a1 100644 --- a/kernel/src/los_mux.c +++ b/kernel/src/los_mux.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -30,7 +30,6 @@ */ #include "los_config.h" #include "los_interrupt.h" -#include "los_arch.h" #include "los_mux.h" #include "los_memory.h" #include "los_debug.h" @@ -170,9 +169,6 @@ STATIC_INLINE UINT32 OsMuxValidCheck(LosMuxCB *muxPended) if (g_losTaskLock) { PRINT_ERR("!!!LOS_ERRNO_MUX_PEND_IN_LOCK!!!\n"); -#if (LOSCFG_PLATFORM_EXC == 1) - LOS_BackTrace(); -#endif return LOS_ERRNO_MUX_PEND_IN_LOCK; } diff --git a/kernel/src/los_queue.c b/kernel/src/los_queue.c index 66320371..c68ace3f 100755 --- a/kernel/src/los_queue.c +++ b/kernel/src/los_queue.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/src/los_sem.c b/kernel/src/los_sem.c index e9b89420..830625a1 100755 --- a/kernel/src/los_sem.c +++ b/kernel/src/los_sem.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -29,7 +29,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "los_config.h" -#include "los_arch.h" #include "los_sem.h" #include "los_memory.h" #include "los_interrupt.h" @@ -195,17 +194,11 @@ STATIC_INLINE UINT32 OsSemValidCheck(LosSemCB *semPended) if (OS_INT_ACTIVE) { PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n"); -#if (LOSCFG_PLATFORM_EXC == 1) - LOS_BackTrace(); -#endif return LOS_ERRNO_SEM_PEND_INTERR; } if (g_losTaskLock) { PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n"); -#if (LOSCFG_PLATFORM_EXC == 1) - LOS_BackTrace(); -#endif return LOS_ERRNO_SEM_PEND_IN_LOCK; } diff --git a/kernel/src/los_swtmr.c b/kernel/src/los_swtmr.c old mode 100755 new mode 100644 index 82fcccf0..1d02a048 --- a/kernel/src/los_swtmr.c +++ b/kernel/src/los_swtmr.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/src/los_task.c b/kernel/src/los_task.c index dc017313..9a86444a 100755 --- a/kernel/src/los_task.c +++ b/kernel/src/los_task.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -39,6 +39,7 @@ #include "los_cpup.h" #endif #include "los_debug.h" + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -240,7 +241,7 @@ LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID) { while (1) { OsRecyleFinishedTask(); -#if (LOSCFG_KERNEL_RUNSTOP == YES) +#if (LOSCFG_KERNEL_RUNSTOP == 1) HalEnterSleep(OS_SYS_NORMAL_SLEEP); #endif } @@ -1656,8 +1657,6 @@ 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 100755 new mode 100644 index ab01331d..ea4e66d7 --- a/kernel/src/los_tick.c +++ b/kernel/src/los_tick.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -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 index f007aa8d..a4c12015 100755 --- a/kernel/src/mm/los_membox.c +++ b/kernel/src/mm/los_membox.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/kernel/src/mm/los_memory.c b/kernel/src/mm/los_memory.c index 73499c4f..7f12d9fa 100755 --- a/kernel/src/mm/los_memory.c +++ b/kernel/src/mm/los_memory.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -36,7 +36,6 @@ #include "los_memory.h" #include "los_task.h" #include "los_debug.h" -#include "los_timer.h" #ifdef LOSCFG_LIB_LIBC #endif @@ -48,21 +47,7 @@ extern "C" { /* Used to cut non-essential functions. */ #define OS_MEM_EXPAND_ENABLE 0 -#define OS_MEM_PRINT_DEBUG 0 - -#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 +#define OS_MEM_TRACE 0 UINT8 *m_aucSysMem0 = NULL; @@ -81,9 +66,8 @@ 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 OS_MEM_FREE_LIST_NUM free lists for each large bucket. */ +/* Giving 2^OS_MEM_SLI 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 @@ -109,7 +93,7 @@ STATIC INLINE UINT16 OsMemFLS(UINT32 bitmap) STATIC INLINE UINT32 OsMemLog2(UINT32 size) { - return OsMemFLS(size); + return (size > 0) ? OsMemFLS(size) : 0; } /* Get the first level: f = log2(size). */ @@ -118,13 +102,19 @@ 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); + return (OsMemLog2(size) - OS_MEM_LARGE_START_BUCKET + OS_MEM_SMALL_BUCKET_COUNT); } /* Get the second level: s = (size - 2^f) * 2^SLI / 2^f. */ STATIC INLINE UINT32 OsMemSlGet(UINT32 size, UINT32 fl) { - return (((size << OS_MEM_SLI) >> fl) - OS_MEM_FREE_LIST_NUM); + 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)); } /* The following is the memory algorithm related macro definition and interface implementation. */ @@ -134,7 +124,7 @@ struct OsMemNodeHead { UINT32 magic; #endif #if (LOSCFG_MEM_LEAKCHECK == 1) - UINTPTR linkReg[LOS_RECORD_LR_CNT]; + UINTPTR linkReg[LOSCFG_MEM_RECORD_LR_CNT]; #endif union { struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */ @@ -197,49 +187,67 @@ struct OsMemPoolHead { #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) +#define OS_MEM_NODE_LEAK_FLAG (1U << 23) +#else +#define OS_MEM_NODE_LEAK_FLAG 0 +#endif +#if (OS_MEM_EXPAND_ENABLE == 1) +#define OS_MEM_NODE_LAST_FLAG (1U << 22) /* Sentinel Node */ +#else +#define OS_MEM_NODE_LAST_FLAG 0 #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) +#define OS_MEM_NODE_LEAK_FLAG (1U << 29) +#else +#define OS_MEM_NODE_LEAK_FLAG 0 +#endif +#if (OS_MEM_EXPAND_ENABLE == 1) +#define OS_MEM_NODE_LAST_FLAG (1U << 28) /* Sentinel Node */ +#else +#define OS_MEM_NODE_LAST_FLAG 0 #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 + (OS_MEM_NODE_USED_FLAG | OS_MEM_NODE_ALIGNED_FLAG | OS_MEM_NODE_LEAK_FLAG | OS_MEM_NODE_LAST_FLAG) #define OS_MEM_NODE_GET_ALIGNED_FLAG(sizeAndFlag) \ ((sizeAndFlag) & OS_MEM_NODE_ALIGNED_FLAG) #define OS_MEM_NODE_SET_ALIGNED_FLAG(sizeAndFlag) \ - ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_ALIGNED_FLAG)) -#define OS_MEM_NODE_GET_ALIGNED_GAPSIZE(sizeAndFlag) \ - ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_FLAG) + (sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_ALIGNED_FLAG) #define OS_MEM_NODE_GET_USED_FLAG(sizeAndFlag) \ ((sizeAndFlag) & OS_MEM_NODE_USED_FLAG) #define OS_MEM_NODE_SET_USED_FLAG(sizeAndFlag) \ - ((sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_USED_FLAG)) + (sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_USED_FLAG) #define OS_MEM_NODE_GET_SIZE(sizeAndFlag) \ ((sizeAndFlag) & ~OS_MEM_NODE_ALIGNED_AND_USED_FLAG) + +#define OS_MEM_GAPSIZE_USED_FLAG 0x80000000U +#define OS_MEM_GAPSIZE_ALIGNED_FLAG 0x40000000U +#define OS_MEM_GET_ALIGNED_GAPSIZE(gapsize) \ + ((gapsize) & ~OS_MEM_GAPSIZE_ALIGNED_FLAG) +#define OS_MEM_GET_GAPSIZE_ALIGNED_FLAG(gapsize) \ + ((gapsize) & OS_MEM_GAPSIZE_ALIGNED_FLAG) +#define OS_MEM_SET_GAPSIZE_ALIGNED_FLAG(gapsize) \ + (gapsize) = ((gapsize) | OS_MEM_GAPSIZE_ALIGNED_FLAG) +#define OS_MEM_GET_GAPSIZE_USED_FLAG(gapsize) \ + ((gapsize) & OS_MEM_GAPSIZE_USED_FLAG) +#define OS_MEM_GAPSIZE_CHECK(gapsize) \ + (OS_MEM_GET_GAPSIZE_ALIGNED_FLAG(gapsize) && \ + OS_MEM_GET_GAPSIZE_USED_FLAG(gapsize)) + #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 + (sizeAndFlag) = ((sizeAndFlag) | OS_MEM_NODE_LEAK_FLAG) #define OS_MEM_ALIGN_SIZE sizeof(UINTPTR) #define OS_MEM_IS_POW_TWO(value) ((((UINTPTR)(value)) & ((UINTPTR)(value) - 1)) == 0) @@ -468,7 +476,7 @@ VOID LOS_MemExpandEnable(VOID *pool) #if (LOSCFG_MEM_LEAKCHECK == 1) struct OsMemLeakCheckInfo { struct OsMemNodeHead *node; - UINTPTR linkReg[LOS_RECORD_LR_CNT]; + UINTPTR linkReg[LOSCFG_MEM_RECORD_LR_CNT]; }; struct OsMemLeakCheckInfo g_leakCheckRecord[LOSCFG_MEM_LEAKCHECK_RECORD_MAX_NUM] = {0}; @@ -498,16 +506,8 @@ STATIC INLINE VOID OsMemLeakCheckInit(VOID) 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); + (VOID)memset_s(node->linkReg, sizeof(node->linkReg), 0, sizeof(node->linkReg)); + OsBackTraceHookCall(node->linkReg, LOSCFG_MEM_RECORD_LR_CNT, LOSCFG_MEM_OMIT_LR_CNT); } STATIC INLINE VOID OsMemUsedNodePrint(struct OsMemNodeHead *node) @@ -515,8 +515,8 @@ 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: 0x%x ", node, OS_MEM_NODE_GET_SIZE(node->sizeAndFlag)); + for (count = 0; count < LOSCFG_MEM_RECORD_LR_CNT; count++) { PRINTK(" 0x%x ", node->linkReg[count]); } PRINTK("\n"); @@ -541,8 +541,8 @@ VOID LOS_MemUsedNodeShow(VOID *pool) UINT32 intSave; UINT32 count; - PRINTK("\n\rnode "); - for (count = 0; count < LOS_RECORD_LR_CNT; count++) { + PRINTK("\n\rnode size "); + for (count = 0; count < LOSCFG_MEM_RECORD_LR_CNT; count++) { PRINTK(" LR[%u] ", count); } PRINTK("\n"); @@ -582,12 +582,12 @@ STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, { int i; PRINTK("\n broken node head LR info: \n"); - for (i = 0; i < LOS_RECORD_LR_CNT; i++) { + for (i = 0; i < LOSCFG_MEM_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++) { + for (i = 0; i < LOSCFG_MEM_RECORD_LR_CNT; i++) { PRINTK(" LR[%d]:0x%x\n", i, preNode->linkReg[i]); } } @@ -597,12 +597,12 @@ STATIC VOID OsMemNodeBacktraceInfo(const struct OsMemNodeHead *tmpNode, STATIC INLINE UINT32 OsMemFreeListIndexGet(UINT32 size) { UINT32 fl = OsMemFlGet(size); - if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { + if (fl < OS_MEM_SMALL_BUCKET_COUNT) { return fl; } UINT32 sl = OsMemSlGet(size, fl); - return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl); + return (OS_MEM_SMALL_BUCKET_COUNT + ((fl - OS_MEM_SMALL_BUCKET_COUNT) << OS_MEM_SLI) + sl); } STATIC INLINE struct OsMemFreeNodeHead *OsMemFindCurSuitableBlock(struct OsMemPoolHead *poolHead, @@ -641,11 +641,11 @@ STATIC INLINE struct OsMemFreeNodeHead *OsMemFindNextSuitableBlock(VOID *pool, U UINT32 mask; do { - if (size < OS_MEM_SMALL_BUCKET_MAX_SIZE) { + if (fl < OS_MEM_SMALL_BUCKET_COUNT) { index = fl; } else { sl = OsMemSlGet(size, fl); - curIndex = ((fl - OS_MEM_LARGE_START_BUCKET) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT; + curIndex = ((fl - OS_MEM_SMALL_BUCKET_COUNT) << OS_MEM_SLI) + sl + OS_MEM_SMALL_BUCKET_COUNT; index = curIndex + 1; } @@ -906,6 +906,11 @@ 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; } @@ -922,6 +927,11 @@ 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; } @@ -993,8 +1003,8 @@ retry: VOID *LOS_MemAlloc(VOID *pool, UINT32 size) { -#if OS_MEM_PRINT_DEBUG - UINT64 start = OsMemClockGetCycles(); +#if OS_MEM_TRACE + UINT64 start = HalClockGetCycles(); #endif if ((pool == NULL) || (size == 0)) { @@ -1018,17 +1028,17 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_PRINT_DEBUG - UINT64 end = OsMemClockGetCycles(); - UINT32 timeUsed = end - start; - PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_MALLOC, timeUsed); +#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); LOS_MEM_POOL_STATUS poolStatus = {0}; (VOID)LOS_MemInfoGet(pool, &poolStatus); UINT8 fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; /* 100: percent denominator. */ UINT8 usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); /* 100: percent denominator. */ - PRINTK("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d\n", usage, fragment, - poolStatus.maxFreeNodeSize, poolStatus.totalFreeSize); + LOS_Trace(LOS_TRACE_MEM_INFO, (UINTPTR)pool & MEM_POOL_ADDR_MASK, fragment, usage, poolStatus.totalFreeSize, + poolStatus.maxFreeNodeSize, poolStatus.usedNodeNum, poolStatus.freeNodeNum); #endif return ptr; @@ -1036,8 +1046,8 @@ VOID *LOS_MemAlloc(VOID *pool, UINT32 size) VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) { -#if OS_MEM_PRINT_DEBUG - UINT64 start = OsMemClockGetCycles(); +#if OS_MEM_TRACE + UINT64 start = HalClockGetCycles(); #endif UINT32 gapSize; @@ -1082,16 +1092,16 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary) gapSize = (UINT32)((UINTPTR)alignedPtr - (UINTPTR)ptr); struct OsMemUsedNodeHead *allocNode = (struct OsMemUsedNodeHead *)ptr - 1; OS_MEM_NODE_SET_ALIGNED_FLAG(allocNode->header.sizeAndFlag); - OS_MEM_NODE_SET_ALIGNED_FLAG(gapSize); + OS_MEM_SET_GAPSIZE_ALIGNED_FLAG(gapSize); *(UINT32 *)((UINTPTR)alignedPtr - sizeof(gapSize)) = gapSize; ptr = alignedPtr; } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_PRINT_DEBUG - UINT64 end = OsMemClockGetCycles(); - UINT32 timeUsed = end - start; - PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_MEMALIGN, timeUsed); +#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); #endif return ptr; @@ -1239,10 +1249,32 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead return ret; } +STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) +{ + VOID *realPtr = ptr; + UINT32 gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32))); + + if (OS_MEM_GAPSIZE_CHECK(gapSize)) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + + if (OS_MEM_GET_GAPSIZE_ALIGNED_FLAG(gapSize)) { + gapSize = OS_MEM_GET_ALIGNED_GAPSIZE(gapSize); + if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || + (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE - (UINTPTR)pool))) { + PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + return NULL; + } + realPtr = (VOID *)((UINTPTR)ptr - (UINTPTR)gapSize); + } + return realPtr; +} + UINT32 LOS_MemFree(VOID *pool, VOID *ptr) { -#if OS_MEM_PRINT_DEBUG - UINT64 start = OsMemClockGetCycles(); +#if OS_MEM_TRACE + UINT64 start = HalClockGetCycles(); #endif if ((pool == NULL) || (ptr == NULL) || !OS_MEM_IS_ALIGNED(pool, sizeof(VOID *)) || @@ -1257,30 +1289,19 @@ UINT32 LOS_MemFree(VOID *pool, VOID *ptr) MEM_LOCK(poolHead, intSave); do { - UINT32 gapSize = *(UINT32 *)((UINTPTR)ptr - sizeof(UINT32)); - if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { - PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); + ptr = OsGetRealPtr(pool, ptr); + if (ptr == NULL) { break; } - node = (struct OsMemNodeHead *)((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE); - - if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { - gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); - if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE))) { - PRINT_ERR("illegal gapSize: 0x%x\n", gapSize); - break; - } - node = (struct OsMemNodeHead *)((UINTPTR)ptr - gapSize - OS_MEM_NODE_HEAD_SIZE); - } ret = OsMemFree(poolHead, node); } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_PRINT_DEBUG - UINT64 end = OsMemClockGetCycles(); - UINT32 timeUsed = end - start; - PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_FREE, timeUsed); +#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); #endif return ret; @@ -1291,13 +1312,14 @@ STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, struct OsMe #if (LOSCFG_MEM_WATERLINE == 1) struct OsMemPoolHead *poolInfo = (struct OsMemPoolHead *)pool; #endif + node->sizeAndFlag = nodeSize; if ((allocSize + OS_MEM_MIN_LEFT_SIZE) <= nodeSize) { OsMemSplitNode(pool, node, allocSize); - OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); #if (LOSCFG_MEM_WATERLINE == 1) poolInfo->info.curUsedSize -= nodeSize - allocSize; #endif } + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); #if (LOSCFG_MEM_LEAKCHECK == 1) OsMemLinkRegisterRecord(node); #endif @@ -1312,33 +1334,13 @@ STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize, if ((allocSize + OS_MEM_MIN_LEFT_SIZE) <= node->sizeAndFlag) { OsMemSplitNode(pool, node, allocSize); } + OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag); OsMemWaterUsedRecord((struct OsMemPoolHead *)pool, node->sizeAndFlag - nodeSize); #if (LOSCFG_MEM_LEAKCHECK == 1) OsMemLinkRegisterRecord(node); #endif } -STATIC INLINE VOID *OsGetRealPtr(const VOID *pool, VOID *ptr) -{ - VOID *realPtr = ptr; - UINT32 gapSize = *((UINT32 *)((UINTPTR)ptr - sizeof(UINT32))); - - if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize) && OS_MEM_NODE_GET_USED_FLAG(gapSize)) { - PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); - return NULL; - } - if (OS_MEM_NODE_GET_ALIGNED_FLAG(gapSize)) { - gapSize = OS_MEM_NODE_GET_ALIGNED_GAPSIZE(gapSize); - if ((gapSize & (OS_MEM_ALIGN_SIZE - 1)) || - (gapSize > ((UINTPTR)ptr - OS_MEM_NODE_HEAD_SIZE - (UINTPTR)pool))) { - PRINT_ERR("[%s:%d]gapSize:0x%x error\n", __FUNCTION__, __LINE__, gapSize); - return NULL; - } - realPtr = (VOID *)((UINTPTR)ptr - (UINTPTR)gapSize); - } - return realPtr; -} - STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, struct OsMemNodeHead *node, UINT32 size, UINT32 intSave) { @@ -1374,8 +1376,8 @@ STATIC INLINE VOID *OsMemRealloc(struct OsMemPoolHead *pool, const VOID *ptr, VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) { -#if OS_MEM_PRINT_DEBUG - UINT64 start = OsMemClockGetCycles(); +#if OS_MEM_TRACE + UINT64 start = HalClockGetCycles(); #endif if ((pool == NULL) || OS_MEM_NODE_GET_USED_FLAG(size) || OS_MEM_NODE_GET_ALIGNED_FLAG(size)) { @@ -1416,10 +1418,10 @@ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size) } while (0); MEM_UNLOCK(poolHead, intSave); -#if OS_MEM_PRINT_DEBUG - UINT64 end = OsMemClockGetCycles(); - UINT32 timeUsed = end - start; - PRINTK("type = %d, timeUsed = %d\n", MEM_TRACE_REALLOC, timeUsed); +#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); #endif return newPtr; diff --git a/readme.md b/readme.md deleted file mode 100644 index fd4a7930..00000000 --- a/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -详见:https://gitee.com/openharmony/docs/blob/master/readme/内核子系统README.md - -see: https://gitee.com/openharmony/docs/blob/master/docs-en/readme/kernel-subsystem.md diff --git a/targets/cortex-m3_stm32f103_simulator_keil/Driver/STM32F103/uart.c b/targets/cortex-m3_stm32f103_simulator_keil/Driver/STM32F103/uart.c index cba8a6e5..afd2b73e 100644 --- a/targets/cortex-m3_stm32f103_simulator_keil/Driver/STM32F103/uart.c +++ b/targets/cortex-m3_stm32f103_simulator_keil/Driver/STM32F103/uart.c @@ -1,3 +1,34 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include #include "los_compiler.h" diff --git a/targets/cortex-m3_stm32f103_simulator_keil/main.c b/targets/cortex-m3_stm32f103_simulator_keil/main.c index b5d61ca1..ac576ab0 100755 --- a/targets/cortex-m3_stm32f103_simulator_keil/main.c +++ b/targets/cortex-m3_stm32f103_simulator_keil/main.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/targets/cortex-m3_stm32f103_simulator_keil/target_config.h b/targets/cortex-m3_stm32f103_simulator_keil/target_config.h index 34ede252..7d797435 100755 --- a/targets/cortex-m3_stm32f103_simulator_keil/target_config.h +++ b/targets/cortex-m3_stm32f103_simulator_keil/target_config.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -92,6 +92,10 @@ extern unsigned char g_memStart[]; #define LOSCFG_SYS_HEAP_SIZE 0x00013000 #define LOSCFG_MEM_MUL_POOL 1 #define OS_SYS_MEM_NUM 20 +/*============================================================================= + Exception module configuration +=============================================================================*/ +#define LOSCFG_PLATFORM_EXC 1 /* ============================================================================= printf module configuration ============================================================================= */ diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/LICENSE.pdf b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/LICENSE.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9d4bdbc0b5affb4fbcc80a68c4d432e8fca4a257 GIT binary patch literal 89685 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 z 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 = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif - SystemCoreClockUpdate(); } /** diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/Libraries/CMSIS/README.txt b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/Libraries/CMSIS/README.txt new file mode 100644 index 00000000..44bef569 --- /dev/null +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/Libraries/CMSIS/README.txt @@ -0,0 +1,42 @@ +* ------------------------------------------------------------------- +* Copyright (C) 2011-2014 ARM Limited. All rights reserved. +* +* Date: 17 February 2014 +* Revision: V4.00 +* +* Project: Cortex Microcontroller Software Interface Standard (CMSIS) +* Title: Release Note for CMSIS +* +* ------------------------------------------------------------------- + + +NOTE - Open the index.html file to access CMSIS documentation + + +The Cortex Microcontroller Software Interface Standard (CMSIS) provides a single standard across all +Cortex-Mx processor series vendors. It enables code re-use and code sharing across software projects +and reduces time-to-market for new embedded applications. + +CMSIS is released under the terms of the end user license agreement ("CMSIS_END_USER_LICENCE_AGREEMENT.pdf"). +Any user of the software package is bound to the terms and conditions of the end user license agreement. + + +You will find the following sub-directories: + +Documentation - Contains CMSIS documentation. + +DSP_Lib - MDK project files, Examples and source files etc.. to build the + CMSIS DSP Software Library for Cortex-M0, Cortex-M3, Cortex-M4 processors. + +Include - CMSIS Core Support and CMSIS DSP Include Files. + +Lib - CMSIS DSP Libraries. + +RTOS - CMSIS RTOS API template header file. + +Driver - CMSIS Peripheral Driver Interface. + +Pack - CMSIS Software Packs. + Mechanism to install software, device support, APIs, and example projects. + +SVD - CMSIS SVD Schema files and Conversion Utility. diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/MCD-ST Liberty SW License Agreement V2.pdf b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/MCD-ST Liberty SW License Agreement V2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d61f43008d2c9b3d59d4726b09854c0c7933436f GIT binary patch literal 17797 zcmch92RvO%*S8>A^b$hC(Yxc|=)DuYcMgu;OO%M-dnbq%o#=un(M1rVMhl{sh#H;m zkb7@(Z=UCU-uL_7-?z_i|IX~0HM7>5|C*V-X3q?@lDH%@h=l`#`peSLCv@rm#{l0KZ=tXzor>vs+FeP7E~GKQ36-+YrF+uQ+a2*5BfI*ulTW z-LU;fUJxsY{kJ#}2k5srHZb>Zah%}a__DEb{+5>w%=KGdHf|8dKg(lh1@rtC$Hwzp zUUqh_-|}*@{;n@4i2E1aT$~`5Hc%%FG#Fs2FsuM<+(0EK=#v{*xH*6-_VzA-8<_wq zKnXh&Cl3eMBP=`YQO3^99sq)=brTlXU6 zfZ2?V1^G>QI9Rzjpr#xU2-w7ggM$ZR$^izkK~11+JUpflF2Nh*(VSf%PA)$%X2n3G zrj}5YgrN!(#8eq1eCOaxIo3BCibS#8#`lT1*!tLI0Xfr zU7Vm0TMRU0cb(WgOAA*mTuz+efE6)4`yU7v4=~5&+@FTT2_Q_b^;$PirNe| z5e5ddU5)2}2m6%2Ql)r0D)UwWK2w>=9eFy&g%fyJ$5~s6YHp}l;?B|?$5lT2{Q8lD zTviO%g|J>71{%z4|6uxu0pHfu54lxf*8ZpLuuA?zc2yUMohii06sSlyLbS9_$-qeN z?$qsEj@u?XPQWb9Sxlq(tlhwT1)6C|4^#p$gV;G(f$DVLD6evk#lp((43eNPJnu+= z`^QBO)Bv#kY)7{U{t!b6Vh(i%z$^*|o0^9M6etF9f!Nra18)-KAjVJ|X8_l2syx&M zVhT%yRrSsDFQviS%O7Bf+1t55?OdDzY&QV?QQ}QWu;QFx34btBv3G$%1YiZqLrpCq zqW12(H$`&7dJ8TdHhrL&lfA=lkt$GUdsinDn6RK*d4A!4^ZY{_Nf>{aO{l4{!FrA# z5~y(iK!2#G#tC4%l^sUF4Pd(w8>R-#zU@s^p)R^WSmy;)gSxxu10~#Dq+n3EKw*VR zse%A(whVk@@g>Dot$07EFew*b~d0K?o2S3${PD!ec~h&u|9;SOvE6j+ zf2aJfa@_K~>3?sz-^lZ)6l{N$#0``7&)6Hv8|lHYJU^tr3H{&-3;i-A++zDb$3e}~ z7V4}3byKmoh1e;nGK<>VnErb_Ks^5$kDCfnfdT&mkDEUK-~QPC%haFwZuGsW)tmo6 z!B`oEJ>PLOu)ab8efM7%0A4xwM-Gpu`m=(YQ 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 2 - 4111223328 + 207883413 Debug - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_tick.c - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_interrupt.c - $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.c - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw.c - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc.S + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_context.c + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_exc.S $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch.S - $PROJ_DIR$\Debug\Obj\los_membox.pbi - $PROJ_DIR$\Debug\Obj\los_memstat.pbi - $PROJ_DIR$\Debug\Obj\stm32f4xx_usart.o - $PROJ_DIR$\..\..\..\kernel\src\los_sys.c - $PROJ_DIR$\Debug\Obj\los_memcheck.__cstat.et - $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.o - $PROJ_DIR$\..\..\..\kernel\src\los_priqueue.c - $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h - $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.pbi - $PROJ_DIR$\Debug\Obj\stm32f4xx_wwdg.o - $PROJ_DIR$\Debug\Obj\los_memory.o - $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.pbi - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_hash.h - $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.pbi - $PROJ_DIR$\Debug\Obj\los_hw_exc.o - $PROJ_DIR$\Debug\Obj\los_priqueue.o - $PROJ_DIR$\Debug\Obj\los_memory.__cstat.et - $PROJ_DIR$\Debug\Obj\stm32f4xx_wwdg.pbi - $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.o - $PROJ_DIR$\Debug\Obj\los_cpup.__cstat.et - $PROJ_DIR$\Debug\Obj\stm32f4xx_usart.pbi - $PROJ_DIR$\Debug\Obj\los_queue.pbi - $PROJ_DIR$\Debug\Obj\los_dispatch.o - $PROJ_DIR$\Debug\Obj\los_mux.o - $PROJ_DIR$\Debug\Obj\los_cpup.pbi - $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.h - $PROJ_DIR$\..\..\..\utils\los_compiler.h - $PROJ_DIR$\Debug\Obj\los_memcheck.pbi - $PROJ_DIR$\Debug\Obj\los_interrupt.o - $PROJ_DIR$\Debug\Obj\los_interrupt.pbi - $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.o - $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.pbi - $TOOLKIT_DIR$\lib\dl7M_tlf.a - $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.o - $PROJ_DIR$\Debug\Obj\dprintf.pbi - $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.h - $TOOLKIT_DIR$\inc\c\yvals.h - $PROJ_DIR$\Debug\Obj\misc.o - $PROJ_DIR$\Debug\Obj\los_init.__cstat.et - $TOOLKIT_DIR$\inc\c\DLib_Product.h - $TOOLKIT_DIR$\inc\c\DLib_Defaults.h + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_interrupt.c + $PROJ_DIR$\..\..\..\components\cpup\los_cpup.c + $PROJ_DIR$\..\..\..\utils\los_debug.c + $PROJ_DIR$\..\..\..\utils\los_error.c + $PROJ_DIR$\..\..\..\kernel\src\los_event.c + $PROJ_DIR$\..\..\..\kernel\src\mm\los_membox.c + $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.c + $PROJ_DIR$\..\..\..\kernel\src\los_init.c + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memory.c + $PROJ_DIR$\..\..\..\kernel\src\los_mux.c + $PROJ_DIR$\..\..\..\kernel\src\los_queue.c + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_timer.c + $PROJ_DIR$\..\..\..\kernel\src\los_sem.c $PROJ_DIR$\..\..\..\components\cpup\los_cpup.h - $TOOLKIT_DIR$\inc\c\stdio.h $PROJ_DIR$\..\..\..\kernel\include\los_swtmr.h - $PROJ_DIR$\Debug\Obj\los_cppsupport.__cstat.et - $PROJ_DIR$\Debug\Obj\los_hw.o - $PROJ_DIR$\..\Utilities\STM32_EVAL\Common\stm32_eval_legacy.h $PROJ_DIR$\Debug\Obj\misc.pbi - $PROJ_DIR$\Debug\Obj\los_hw.pbi - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_rng.h $TOOLKIT_DIR$\inc\c\ycheck.h - $PROJ_DIR$\Debug\Obj\los_hw_tick.o + $TOOLKIT_DIR$\inc\c\stdio.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_rng.h $PROJ_DIR$\Debug\Obj\los_hw_exc_iar.o - $PROJ_DIR$\Debug\Obj\main.pbi - $PROJ_DIR$\config\stm32f429xG.icf - $PROJ_DIR$\Debug\Obj\los_dispatch_iar.o + $PROJ_DIR$\Debug\Obj\los_hw.o $PROJ_DIR$\Debug\Obj\los_memory.pbi - $PROJ_DIR$\..\..\..\kernel\include\los_sem.h - $PROJ_DIR$\Debug\Obj\los_err.__cstat.et $TOOLKIT_DIR$\inc\c\ysizet.h - $PROJ_DIR$\Debug\Obj\los_exc.__cstat.et + $PROJ_DIR$\Debug\Obj\los_err.__cstat.et $PROJ_DIR$\Debug\Exe\los_demo.out - $PROJ_DIR$\Debug\Obj\los_hw.__cstat.et $PROJ_DIR$\Debug\Obj\los_exc.pbi + $PROJ_DIR$\Debug\Obj\los_cppsupport.__cstat.et + $PROJ_DIR$\Debug\Obj\los_hw.pbi + $PROJ_DIR$\..\..\..\kernel\include\los_sem.h + $PROJ_DIR$\Debug\Obj\los_hw.__cstat.et $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_ltdc.h $PROJ_DIR$\Debug\Obj\los_cppsupport.o + $PROJ_DIR$\config\stm32f429xG.icf $PROJ_DIR$\..\..\..\kernel\include\los_config.h $PROJ_DIR$\Debug\Obj\dprintf.o $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_rtc.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_tim.h - $PROJ_DIR$\Debug\Obj\los_hw_tick.pbi $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_wwdg.h + $PROJ_DIR$\Debug\Obj\main.pbi + $PROJ_DIR$\..\Utilities\STM32_EVAL\Common\stm32_eval_legacy.h + $PROJ_DIR$\Debug\Obj\los_dispatch_iar.o + $PROJ_DIR$\Debug\Obj\los_exc.__cstat.et + $PROJ_DIR$\Debug\Obj\los_hw_tick.pbi $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_syscfg.h - $PROJ_DIR$\Debug\Obj\los_membox.__cstat.et - $PROJ_DIR$\Debug\Obj\los_memstat.__cstat.et - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_flash.h - $PROJ_DIR$\Debug\Obj\los_cppsupport.pbi - $PROJ_DIR$\..\..\..\utils\los_debug.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_exti.h - $PROJ_DIR$\Debug\Obj\dprintf.__cstat.et - $PROJ_DIR$\Debug\Obj\los_event.__cstat.et - $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_pwr.h - $TOOLKIT_DIR$\inc\c\DLib_Config_Full.h - $PROJ_DIR$\..\..\..\kernel\include\los_task.h - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_interrupt.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dma2d.h - $TOOLKIT_DIR$\CMSIS\Include\core_cm4.h - $TOOLKIT_DIR$\CMSIS\Include\cmsis_compiler.h - $PROJ_DIR$\Debug\Obj\los_timeslice.pbi - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_rcc.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_usart.h - $PROJ_DIR$\Debug\Obj\los_misc.__cstat.et + $PROJ_DIR$\Debug\Obj\los_hw_tick.o + $TOOLKIT_DIR$\inc\c\DLib_Defaults.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.pbi + $PROJ_DIR$\Debug\Obj\los_memory.o + $PROJ_DIR$\Debug\Obj\los_memcheck.pbi + $TOOLKIT_DIR$\lib\dl7M_tlf.a + $PROJ_DIR$\Debug\Obj\los_cpup.pbi + $PROJ_DIR$\Debug\Obj\los_interrupt.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.pbi + $PROJ_DIR$\Debug\Obj\los_memory.__cstat.et + $PROJ_DIR$\Debug\Obj\los_cpup.__cstat.et + $PROJ_DIR$\Debug\Obj\los_dispatch.o + $PROJ_DIR$\Debug\Obj\los_mux.o + $PROJ_DIR$\Debug\Obj\los_hw_exc.o + $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.h + $PROJ_DIR$\..\..\..\utils\los_compiler.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.o + $TOOLKIT_DIR$\inc\c\yvals.h + $PROJ_DIR$\Debug\Obj\misc.o + $PROJ_DIR$\Debug\Obj\los_interrupt.pbi + $PROJ_DIR$\Debug\Obj\los_init.__cstat.et + $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.h + $TOOLKIT_DIR$\inc\c\DLib_Product.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.pbi + $PROJ_DIR$\Debug\Obj\los_queue.pbi + $PROJ_DIR$\Debug\Obj\los_priqueue.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_wwdg.pbi + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_hash.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_usart.pbi + $PROJ_DIR$\Debug\Obj\dprintf.pbi $TOOLKIT_DIR$\inc\c\iccarm_builtin.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_usart.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_crc.h - $PROJ_DIR$\..\..\..\kernel\src\mm\los_membox.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c - $PROJ_DIR$\..\..\..\kernel\src\los_mux.c - $PROJ_DIR$\Debug\Obj\main.o - $PROJ_DIR$\..\..\..\components\cpup\los_cpup.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_wwdg.c - $PROJ_DIR$\..\..\..\utils\los_error.c - $PROJ_DIR$\..\..\..\kernel\src\los_tick.c - $PROJ_DIR$\..\..\..\kernel\src\los_swtmr.c - $PROJ_DIR$\..\..\..\kernel\src\los_task.c - $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c - $PROJ_DIR$\..\..\..\kernel\src\mm\los_memcheck.c - $PROJ_DIR$\..\..\..\kernel\src\los_init.c - $PROJ_DIR$\..\..\..\kernel\src\mm\los_memstat.c - $PROJ_DIR$\..\..\..\kernel\src\los_queue.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c - $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.c - $PROJ_DIR$\..\..\..\kernel\src\los_sem.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c - $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\iar\startup_stm32f429_439xx.s - $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c - $PROJ_DIR$\..\dprintf.c - $PROJ_DIR$\..\..\..\kernel\src\los_event.c - $PROJ_DIR$\..\..\..\kernel\src\mm\los_memory.c - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c - $PROJ_DIR$\..\target_config.h - $PROJ_DIR$\..\..\..\kernel\src\los_err.c - $PROJ_DIR$\..\main.c - $TOOLKIT_DIR$\inc\c\stdlib.h - $PROJ_DIR$\..\..\..\kernel\include\los_memory.h - $PROJ_DIR$\..\..\..\kernel\include\los_event.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_sdio.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_adc.h + $TOOLKIT_DIR$\inc\c\DLib_Config_Full.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_exti.h + $PROJ_DIR$\Debug\Obj\main.o $PROJ_DIR$\Debug\Obj\los_tick.__cstat.et - $PROJ_DIR$\Debug\Obj\iar_stm32f429ig_fire-challenger.o - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dbgmcu.h - $PROJ_DIR$\Debug\Obj\los_demo.pbd - $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.__cstat.et - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_can.h + $PROJ_DIR$\Debug\Obj\los_cppsupport.pbi + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_interrupt.h + $TOOLKIT_DIR$\inc\c\stdlib.h + $PROJ_DIR$\Debug\Obj\dprintf.__cstat.et + $PROJ_DIR$\..\..\..\utils\los_debug.h + $PROJ_DIR$\Debug\Obj\los_event.__cstat.et + $PROJ_DIR$\Debug\Obj\los_timeslice.pbi + $PROJ_DIR$\Debug\Obj\los_misc.__cstat.et + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memcheck.c + $PROJ_DIR$\..\..\..\kernel\src\los_err.c + $PROJ_DIR$\Debug\Obj\los_membox.__cstat.et + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_rcc.h + $TOOLKIT_DIR$\CMSIS\Include\cmsis_compiler.h + $PROJ_DIR$\..\..\..\kernel\include\los_task.h + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memstat.c + $PROJ_DIR$\..\..\..\kernel\include\los_memory.h + $TOOLKIT_DIR$\CMSIS\Include\core_cm4.h + $PROJ_DIR$\Debug\Obj\los_memstat.__cstat.et + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_flash.h + $PROJ_DIR$\..\..\..\kernel\include\los_event.h + $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Include\system_stm32f4xx.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dma2d.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_pwr.h $PROJ_DIR$\..\..\..\kernel\include\los_membox.h $PROJ_DIR$\Debug\Obj\los_cpup.o - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_fmc.h - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_exc.c $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_spi.h - $PROJ_DIR$\Debug\Obj\main.__cstat.et - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dma.h + $PROJ_DIR$\Debug\Obj\iar_stm32f429ig_fire-challenger.o + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dbgmcu.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.__cstat.et $PROJ_DIR$\..\..\..\components\bounds_checking_function\include\securec.h - $PROJ_DIR$\..\..\..\kernel\include\los_queue.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dac.h - $PROJ_DIR$\..\..\..\kernel\include\los_tick.h - $PROJ_DIR$\..\..\..\utils\los_list.h + $TOOLKIT_DIR$\inc\c\stddef.h + $TOOLKIT_DIR$\inc\c\string.h + $PROJ_DIR$\Debug\Obj\los_demo.pbd + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_can.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_sai.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.__cstat.et + $PROJ_DIR$\Debug\Obj\main.__cstat.et + $PROJ_DIR$\..\..\..\kernel\include\los_queue.h $PROJ_DIR$\..\..\..\utils\los_error.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_iwdg.h - $TOOLKIT_DIR$\inc\c\stddef.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dac.h $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dcmi.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_i2c.h - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\misc.h - $TOOLKIT_DIR$\inc\c\string.h + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_exc.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_dma.h + $PROJ_DIR$\..\..\..\kernel\include\los_tick.h $TOOLKIT_DIR$\inc\c\errno.h - $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.__cstat.et - $PROJ_DIR$\Debug\Obj\system_stm32f4xx.pbi + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_fmc.h $PROJ_DIR$\Debug\Obj\misc.__cstat.et + $PROJ_DIR$\Debug\Obj\system_stm32f4xx.pbi + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\misc.h + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_i2c.h $PROJ_DIR$\Debug\Obj\iar_stm32f429ig_fire-challenger.pbi $PROJ_DIR$\Debug\Obj\los_queue.o - $PROJ_DIR$\Debug\Obj\stm32f4xx_usart.__cstat.et - $PROJ_DIR$\Debug\Obj\los_mux.pbi - $PROJ_DIR$\Debug\Obj\los_sys.__cstat.et - $PROJ_DIR$\Debug\Obj\los_error.pbi - $TOOLKIT_DIR$\lib\m7M_tls.a - $PROJ_DIR$\..\..\..\kernel\include\los_mux.h - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch_iar.S - $PROJ_DIR$\Debug\Obj\los_task.__cstat.et - $PROJ_DIR$\Debug\Obj\los_sys.pbi - $PROJ_DIR$\Debug\Obj\system_stm32f4xx.__cstat.et - $PROJ_DIR$\Debug\Obj\los_queue.__cstat.et - $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.__cstat.et - $TOOLKIT_DIR$\inc\c\stdarg.h - $PROJ_DIR$\Debug\Obj\los_error.o - $PROJ_DIR$\Debug\Obj\startup_stm32f429_439xx.o - $PROJ_DIR$\Debug\Obj\los_timeslice.__cstat.et - $PROJ_DIR$\..\stm32f4xx_conf.h - $TOOLKIT_DIR$\inc\c\cmsis_iar.h - $PROJ_DIR$\Debug\Obj\stm324x9i_eval.__cstat.et - $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.__cstat.et - $TOOLKIT_DIR$\inc\c\DLib_Product_string.h - $PROJ_DIR$\Debug\Obj\los_mux.__cstat.et - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_gpio.h - $PROJ_DIR$\..\..\..\components\bounds_checking_function\include\securectype.h - $PROJ_DIR$\Debug\List\los_demo.map - $PROJ_DIR$\Debug\Obj\los_swtmr.__cstat.et + $PROJ_DIR$\..\..\..\utils\los_list.h $PROJ_DIR$\Debug\Obj\los_event.pbi $PROJ_DIR$\Debug\Obj\los_sem.pbi - $PROJ_DIR$\Debug\Obj\los_err.pbi + $TOOLKIT_DIR$\inc\c\cmsis_iar.h $PROJ_DIR$\Debug\Obj\stm324x9i_eval.pbi $PROJ_DIR$\Debug\Obj\los_swtmr.pbi - $PROJ_DIR$\Debug\Obj\los_tick.pbi - $PROJ_DIR$\Debug\Obj\stm324x9i_eval.o - $PROJ_DIR$\Debug\Obj\iar_stm32f429ig_fire-challenger.__cstat.et - $PROJ_DIR$\Debug\Obj\los_sem.__cstat.et - $PROJ_DIR$\Debug\Obj\los_event.o - $PROJ_DIR$\Debug\Obj\los_err.o - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_cryp.h - $PROJ_DIR$\Debug\Obj\los_misc.pbi - $PROJ_DIR$\Debug\Obj\los_membox.o + $PROJ_DIR$\..\stm32f4xx_conf.h + $PROJ_DIR$\..\..\..\kernel\include\los_mux.h + $PROJ_DIR$\Debug\Obj\los_task.__cstat.et + $TOOLKIT_DIR$\lib\m7M_tls.a + $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.__cstat.et + $TOOLKIT_DIR$\inc\c\stdarg.h + $PROJ_DIR$\Debug\Obj\los_sys.__cstat.et + $PROJ_DIR$\Debug\Obj\los_timeslice.__cstat.et + $PROJ_DIR$\Debug\Obj\stm324x9i_eval.__cstat.et + $PROJ_DIR$\Debug\Obj\los_mux.__cstat.et + $PROJ_DIR$\Debug\List\los_demo.map + $PROJ_DIR$\Debug\Obj\los_err.pbi + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch_iar.S + $PROJ_DIR$\Debug\Obj\stm32f4xx_usart.__cstat.et + $PROJ_DIR$\Debug\Obj\los_mux.pbi + $PROJ_DIR$\Debug\Obj\los_error.pbi + $PROJ_DIR$\Debug\Obj\los_sys.pbi + $PROJ_DIR$\Debug\Obj\los_queue.__cstat.et + $PROJ_DIR$\Debug\Obj\los_error.o + $TOOLKIT_DIR$\inc\c\DLib_Product_string.h + $PROJ_DIR$\Debug\Obj\los_swtmr.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.__cstat.et + $PROJ_DIR$\Debug\Obj\startup_stm32f429_439xx.o + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_gpio.h + $PROJ_DIR$\Debug\Obj\system_stm32f4xx.__cstat.et + $PROJ_DIR$\..\..\..\components\bounds_checking_function\include\securectype.h $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.o - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc_iar.S - $PROJ_DIR$\Debug\Obj\los_sys.o - $TOOLKIT_DIR$\inc\c\DLib_Product_stdlib.h - $TOOLKIT_DIR$\lib\rt7M_tl.a - $PROJ_DIR$\Debug\Obj\los_memstat.o - $PROJ_DIR$\Debug\Obj\los_tick.o + $PROJ_DIR$\Debug\Obj\stm324x9i_eval.o $PROJ_DIR$\Debug\Obj\los_misc.o $PROJ_DIR$\Debug\Obj\los_task.o + $PROJ_DIR$\..\..\..\kernel\src\los_misc.c + $TOOLKIT_DIR$\CMSIS\Core\Include\cmsis_version.h + $PROJ_DIR$\Debug\Obj\los_err.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.__cstat.et + $PROJ_DIR$\Debug\Obj\los_event.o + $PROJ_DIR$\Debug\Obj\los_sys.o + $PROJ_DIR$\Debug\Obj\los_swtmr.o + $PROJ_DIR$\Debug\Obj\los_sem.__cstat.et + $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.h + $PROJ_DIR$\Debug\Obj\los_memcheck.o + $PROJ_DIR$\Debug\Obj\los_tick.pbi + $PROJ_DIR$\Debug\Obj\los_membox.o + $TOOLKIT_DIR$\inc\c\DLib_Product_stdlib.h $PROJ_DIR$\Debug\Obj\los_task.pbi + $PROJ_DIR$\Debug\Obj\los_memstat.o + $PROJ_DIR$\Debug\Obj\los_misc.pbi + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc_iar.S + $PROJ_DIR$\Debug\Obj\los_tick.o $PROJ_DIR$\Debug\Obj\los_hw_tick.__cstat.et $PROJ_DIR$\Debug\Obj\los_priqueue.pbi - $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.h - $PROJ_DIR$\Debug\Obj\los_swtmr.o $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.pbi - $PROJ_DIR$\Debug\Obj\los_memcheck.o + $PROJ_DIR$\Debug\Obj\iar_stm32f429ig_fire-challenger.__cstat.et $TOOLKIT_DIR$\inc\c\stdint.h + $TOOLKIT_DIR$\lib\rt7M_tl.a $PROJ_DIR$\Debug\Obj\stm32f4xx_wwdg.__cstat.et - $PROJ_DIR$\..\..\..\kernel\src\los_misc.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\inc\stm32f4xx_cryp.h $TOOLKIT_DIR$\CMSIS\Core\Include\cmsis_compiler.h $PROJ_DIR$\..\..\..\kernel\src\los_timeslice.c - $TOOLKIT_DIR$\CMSIS\Core\Include\cmsis_version.h - $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.__cstat.et - $PROJ_DIR$\Debug\Obj\los_timeslice.o - $TOOLKIT_DIR$\lib\shb_l.a - $PROJ_DIR$\Debug\Obj\los_sem.o $TOOLKIT_DIR$\CMSIS\Core\Include\core_cm4.h - $TOOLKIT_DIR$\CMSIS\Core\Include\mpu_armv7.h - $PROJ_DIR$\Debug\Obj\los_priqueue.__cstat.et - $PROJ_DIR$\Debug\Obj\los_init.o - $PROJ_DIR$\Debug\Obj\system_stm32f4xx.o - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_context.h - $TOOLKIT_DIR$\CMSIS\Core\Include\cmsis_iccarm.h + $PROJ_DIR$\Debug\Obj\los_sem.o $PROJ_DIR$\Debug\Obj\los_init.pbi + $PROJ_DIR$\Debug\Obj\los_context.o + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_context.h + $TOOLKIT_DIR$\lib\shb_l.a + $TOOLKIT_DIR$\CMSIS\Core\Include\cmsis_iccarm.h + $PROJ_DIR$\Debug\Obj\los_priqueue.__cstat.et + $PROJ_DIR$\Debug\Obj\system_stm32f4xx.o + $PROJ_DIR$\Debug\Obj\los_timer.o + $TOOLKIT_DIR$\CMSIS\Core\Include\mpu_armv7.h + $PROJ_DIR$\Debug\Obj\los_debug.o + $PROJ_DIR$\Debug\Obj\los_init.o + $PROJ_DIR$\Debug\Obj\los_timeslice.o + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c + $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c + $PROJ_DIR$\Debug\Obj\los_memstat.pbi + $PROJ_DIR$\Debug\Obj\stm32f4xx_usart.o + $PROJ_DIR$\..\..\..\kernel\src\los_sys.c + $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.o + $PROJ_DIR$\..\..\..\kernel\src\los_priqueue.c + $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Include\stm32f4xx.h + $PROJ_DIR$\Debug\Obj\los_memcheck.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.pbi + $PROJ_DIR$\Debug\Obj\stm32f4xx_wwdg.o + $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\iar\startup_stm32f429_439xx.s + $PROJ_DIR$\..\..\..\kernel\src\los_swtmr.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c + $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.c + $PROJ_DIR$\..\dprintf.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_wwdg.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c + $PROJ_DIR$\..\target_config.h + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_tick.c + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c + $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\..\kernel\src\los_tick.c + $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.c + $PROJ_DIR$\..\..\..\kernel\src\los_task.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc.S + $PROJ_DIR$\Debug\Obj\los_membox.pbi + $PROJ_DIR$\Debug\Obj\los_debug.pbi + $PROJ_DIR$\Debug\Obj\los_timer.pbi + $PROJ_DIR$\Debug\Obj\los_exc.o + $PROJ_DIR$\Debug\Obj\los_context.pbi + $PROJ_DIR$\..\..\..\kernel\arch\include\los_interrupt.h + $PROJ_DIR$\..\..\..\kernel\arch\include\los_context.h - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_tick.c + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_context.c BICOMP - 76 + 253 ICCARM - 57 - - - __cstat - 219 + 208 - + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_exc.S + - BICOMP - 225 46 185 92 96 13 99 139 161 42 241 191 78 55 156 72 235 236 136 84 157 135 97 206 152 70 91 32 89 45 129 87 230 228 56 100 149 81 160 88 74 147 75 77 18 142 159 145 155 153 + AARM + 252 + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch.S + - ICCARM - 153 156 32 99 42 46 89 45 91 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 + AARM + 58 - + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_interrupt.c BICOMP - 35 + 66 + + + ICCARM + 54 + + + + + BICOMP + 199 131 36 64 38 134 226 62 69 205 215 138 39 121 92 79 84 147 81 106 110 113 40 76 129 122 19 152 101 239 48 108 178 203 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 209 89 132 107 126 141 + + + ICCARM + 89 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 92 101 132 126 209 107 141 + + + + + $PROJ_DIR$\..\..\..\components\cpup\los_cpup.c + + + BICOMP + 53 + + + __cstat + 57 + + + ICCARM + 112 + + + + + BICOMP + 203 39 48 138 121 226 64 19 131 38 134 101 62 239 108 178 81 106 110 113 40 76 129 122 92 89 36 79 84 69 205 199 147 215 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 209 16 132 107 126 141 + + + ICCARM + 16 89 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 101 132 126 209 107 141 92 + + + + + $PROJ_DIR$\..\..\..\utils\los_debug.c + + + BICOMP + 250 + + + ICCARM + 216 + + + + + $PROJ_DIR$\..\..\..\utils\los_error.c + + + BICOMP + 162 + + + ICCARM + 165 + + + + + BICOMP + 64 69 62 79 84 126 48 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_event.c + + + BICOMP + 142 + + + __cstat + 93 + + + ICCARM + 181 + + + + + BICOMP + 113 62 122 226 239 178 106 76 126 108 81 110 40 129 209 64 48 203 19 131 138 38 39 121 134 89 132 107 79 84 69 141 36 205 199 147 215 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 101 + + + ICCARM + 101 132 126 62 79 64 48 84 69 209 107 141 89 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\..\..\kernel\src\mm\los_membox.c + + + BICOMP + 249 + + + __cstat + 98 + + + ICCARM + 188 + + + + + BICOMP + 19 39 103 64 189 138 121 92 166 25 62 239 199 147 131 38 134 226 36 111 152 133 205 215 81 106 110 113 40 76 129 122 89 172 20 119 90 118 48 84 69 79 108 178 203 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 117 141 + + + ICCARM + 117 172 20 19 64 48 84 69 25 119 166 90 189 118 133 89 36 239 62 79 226 104 199 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 111 103 141 92 + + + + + $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.c + + + BICOMP + 88 + + + __cstat + 29 ICCARM @@ -291,211 +448,65 @@ BICOMP - 225 149 72 42 74 145 13 32 45 235 236 160 75 142 83 99 89 185 100 81 88 147 77 18 159 155 56 181 90 129 46 87 230 228 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 240 91 153 134 156 154 + 69 64 62 79 48 84 61 ICCARM - 91 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 83 90 153 156 240 134 154 + 61 62 79 64 48 84 69 - $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.c + $PROJ_DIR$\..\..\..\kernel\src\los_init.c BICOMP - 82 - - - ICCARM - 71 + 207 __cstat + 67 + + + ICCARM + 217 + + + + + BICOMP + 48 138 226 121 203 39 64 19 131 38 134 141 107 103 89 92 239 62 108 178 81 106 110 113 40 76 129 122 126 36 125 148 79 84 69 205 199 147 215 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 101 132 209 + + + ICCARM + 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 125 141 103 148 101 132 126 209 107 89 92 + + + + + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memory.c + + + BICOMP + 24 + + + __cstat + 56 + + + ICCARM 50 BICOMP - 45 42 32 99 46 89 31 + 25 108 226 83 64 19 80 92 119 69 178 127 128 101 172 20 90 118 48 84 36 79 203 199 85 82 202 33 132 141 103 89 111 152 133 166 189 239 62 205 147 211 115 170 99 46 137 21 109 107 126 117 215 81 131 106 138 110 38 113 39 40 76 121 129 134 122 209 ICCARM - 31 32 99 42 46 89 45 - - - - - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw.c - - - BICOMP - 54 - - - ICCARM - 51 - - - __cstat - 68 - - - - - BICOMP - 99 240 32 65 42 46 89 56 150 153 134 156 45 154 192 90 181 163 48 162 132 158 189 212 - - - ICCARM - 90 153 156 32 99 42 46 89 45 240 134 154 150 192 48 56 65 162 189 132 212 158 163 - - - - - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc.S - - - AARM - 20 - - - - - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch.S - - - AARM - 28 - - - - - [ROOT_NODE] - - - ILINK - 67 193 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_sys.c - - - BICOMP - 177 - - - ICCARM - 211 - - - __cstat - 171 - - - - - BICOMP - 142 99 129 160 13 32 75 87 149 74 145 42 46 186 100 81 88 147 77 18 159 155 72 156 89 45 93 225 185 94 56 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 153 - - - ICCARM - 153 156 32 99 42 46 89 45 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_priqueue.c - - - BICOMP - 220 - - - ICCARM - 21 - - - __cstat - 237 - - - - - ICCARM - 151 154 32 99 42 46 89 45 90 153 156 240 134 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\Debug\Exe\los_demo.out - - - ILINK - 193 - - - - - ILINK - 60 73 138 71 144 28 205 204 51 20 57 238 34 208 224 16 214 216 29 168 234 222 217 215 104 43 183 201 39 24 209 11 36 8 15 239 233 213 173 38 - - - - - $PROJ_DIR$\..\..\..\kernel\src\mm\los_membox.c - - - BICOMP - 6 - - - ICCARM - 208 - - - __cstat - 79 - - - - - BICOMP - 56 75 133 42 212 160 142 83 189 65 32 129 225 185 149 74 145 13 72 143 181 163 235 236 100 81 88 147 77 18 159 155 91 192 48 162 132 158 46 89 45 99 87 230 228 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 150 154 - - - ICCARM - 150 192 48 56 42 46 89 45 65 162 189 132 212 158 163 91 72 129 32 99 13 93 225 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 143 133 154 83 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c - - - BICOMP - 26 - - - ICCARM - 8 - - - __cstat - 169 - - - - - BICOMP - 160 13 142 75 225 185 46 89 149 74 145 235 236 42 45 241 99 100 81 88 147 77 18 159 155 96 87 230 228 56 136 139 84 191 157 135 78 97 161 206 55 152 92 70 - - - ICCARM - 97 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 77 161 206 18 55 142 152 159 92 145 70 155 + 117 172 20 19 64 48 84 69 25 119 166 90 189 118 133 103 36 239 62 79 226 104 199 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 141 101 132 126 209 107 89 92 111 @@ -504,88 +515,333 @@ BICOMP - 170 - - - ICCARM - 29 + 161 __cstat - 190 + 156 + + + ICCARM + 59 BICOMP - 32 228 75 42 160 142 13 240 46 56 149 74 145 133 156 129 87 230 100 81 88 147 77 18 159 155 91 83 90 153 134 99 89 45 154 72 235 225 185 236 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 174 + 62 203 39 64 138 121 226 209 48 19 131 38 134 103 126 239 108 178 81 106 110 113 40 76 129 122 89 92 101 132 107 79 84 69 141 36 205 199 147 215 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 148 ICCARM - 174 90 153 156 32 99 42 46 89 45 240 134 154 91 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 133 83 + 148 101 132 126 62 79 64 48 84 69 209 107 141 89 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 103 92 - $PROJ_DIR$\..\..\..\components\cpup\los_cpup.c + $PROJ_DIR$\..\..\..\kernel\src\los_queue.c BICOMP - 30 - - - ICCARM - 144 + 71 __cstat - 25 + 164 + + + ICCARM + 140 BICOMP - 228 75 46 160 142 13 42 56 149 74 145 90 32 129 87 230 100 81 88 147 77 18 159 155 83 91 72 99 89 45 235 225 185 236 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 240 47 153 134 156 154 + 226 106 62 76 103 92 84 113 122 64 101 79 199 147 81 110 40 129 19 36 209 125 69 205 215 131 138 38 39 121 134 117 111 89 239 48 108 178 203 211 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 172 25 152 133 20 119 90 118 166 189 141 132 107 126 ICCARM - 47 91 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 90 153 156 240 134 154 83 + 89 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 117 172 20 25 119 166 90 189 118 133 125 141 111 103 101 132 126 209 107 92 - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_wwdg.c + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_timer.c BICOMP - 23 + 251 ICCARM - 15 + 214 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_sem.c + + + BICOMP + 143 __cstat - 226 + 184 + + + ICCARM + 206 BICOMP - 136 13 97 228 42 157 152 56 84 135 206 70 87 230 139 191 96 78 161 55 92 235 225 185 236 46 89 45 241 99 100 149 81 160 88 74 147 75 77 18 142 159 145 155 + 64 82 84 33 132 199 85 202 226 89 79 205 215 83 127 80 128 107 62 69 141 36 147 211 115 170 99 46 137 21 109 103 92 101 209 126 48 239 108 178 203 19 81 131 106 138 110 38 113 39 40 76 121 129 134 122 31 ICCARM - 77 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 161 206 18 55 142 152 159 92 145 70 155 + 31 101 132 126 62 79 64 48 84 69 209 107 141 103 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 89 92 - $PROJ_DIR$\..\..\..\utils\los_error.c + [ROOT_NODE] + + + ILINK + 27 157 + + + + + $PROJ_DIR$\Debug\Exe\los_demo.out + + + ILINK + 157 + + + + + ILINK + 35 37 114 34 112 58 179 181 23 60 47 217 54 188 186 50 191 175 59 140 206 183 176 194 86 65 169 174 73 63 173 224 74 222 229 213 210 200 150 52 + + + + + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memcheck.c BICOMP - 172 + 51 + + + __cstat + 227 + + + ICCARM + 186 + + + + + ICCARM + 111 103 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 141 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_err.c + + + BICOMP + 158 + + + __cstat + 26 + + + ICCARM + 179 + + + + + ICCARM + 126 62 79 64 48 84 69 + + + + + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memstat.c + + + BICOMP + 221 + + + __cstat + 105 + + + ICCARM + 191 + + + + + ICCARM + 92 62 79 64 48 84 69 89 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_exc.c + + + BICOMP + 28 + + + __cstat + 44 + + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch_iar.S + + + AARM + 43 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_misc.c + + + BICOMP + 192 + + + __cstat + 95 + + + ICCARM + 175 + + + + + ICCARM + 89 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 101 132 126 209 107 141 + + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc_iar.S + + + AARM + 22 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_timeslice.c + + + BICOMP + 94 + + + __cstat + 154 + + + ICCARM + 218 + + + + + BICOMP + 79 131 108 38 134 226 62 138 39 121 64 48 144 81 106 110 113 40 76 129 122 101 36 239 84 69 104 199 147 100 19 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 209 89 132 107 126 141 + + + ICCARM + 89 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 101 132 126 209 107 141 + + + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c + + + BICOMP + 70 + + + __cstat + 151 + + + ICCARM + 74 + + + + + BICOMP + 226 83 80 203 64 127 128 19 85 82 202 33 108 178 115 170 99 46 137 21 109 205 199 147 215 48 84 69 211 79 81 131 106 138 110 38 113 39 40 76 121 129 134 122 + + + ICCARM + 39 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c + + + BICOMP + 136 + + + __cstat + 171 + + + ICCARM + 213 + + + + + BICOMP + 110 226 215 129 205 79 81 40 199 64 69 211 106 113 76 122 147 48 84 131 138 38 39 121 134 108 178 203 19 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 + + + ICCARM + 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_sys.c + + + BICOMP + 163 + + + __cstat + 153 ICCARM @@ -595,392 +851,34 @@ BICOMP - 42 45 32 99 89 156 46 + 121 79 239 138 226 62 39 108 131 38 134 64 48 144 81 106 110 113 40 76 129 122 36 126 84 69 104 199 147 100 19 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 132 + + + ICCARM + 132 126 62 79 64 48 84 69 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 - $PROJ_DIR$\..\..\..\kernel\src\los_tick.c - - - BICOMP - 200 - - - ICCARM - 215 - - - __cstat - 137 - - - - - ICCARM - 153 156 32 99 42 46 89 45 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 90 240 134 154 49 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_swtmr.c - - - BICOMP - 199 - - - ICCARM - 222 - - - __cstat - 194 - - - - - ICCARM - 150 192 48 56 42 46 89 45 65 162 189 132 212 158 163 91 72 129 32 99 13 93 225 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 49 90 153 156 240 134 154 133 151 83 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_task.c - - - BICOMP - 218 - - - ICCARM - 217 - - - __cstat - 176 - - - - - ICCARM - 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 150 192 48 65 162 189 132 212 158 163 63 90 153 156 240 134 154 174 133 91 47 83 - - - - - $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.c - - - BICOMP - 167 - - - ICCARM - 138 - - - __cstat - 202 - - - - - BICOMP - 70 135 13 56 84 206 228 42 136 157 97 152 87 230 139 191 96 78 161 55 92 52 235 225 185 236 46 89 45 241 99 100 149 81 160 88 74 147 75 77 18 142 159 145 155 221 - - - ICCARM - 221 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 52 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c - - - BICOMP - 37 - - - ICCARM - 39 - - - __cstat - 141 - - - - - BICOMP - 88 236 159 13 235 99 100 77 225 42 45 241 81 147 18 155 185 46 89 149 160 74 75 142 145 87 230 228 56 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 - - - ICCARM - 84 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c - - - BICOMP - 223 - - - ICCARM - 24 - - - __cstat - 188 - - - - - BICOMP - 88 236 159 13 235 99 100 77 225 42 45 241 81 147 18 155 185 46 89 149 160 74 75 142 145 96 87 230 228 56 136 139 84 191 157 135 78 97 161 206 55 152 92 70 - - - ICCARM - 191 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c - - - BICOMP - 19 - - - ICCARM - 209 - - - __cstat - 231 - - - - - BICOMP - 157 228 42 152 136 97 13 56 84 135 206 70 87 230 139 191 96 78 161 55 92 235 225 185 236 46 89 45 241 99 100 149 81 160 88 74 147 75 77 18 142 159 145 155 - - - ICCARM - 96 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\..\..\kernel\src\mm\los_memcheck.c - - - BICOMP - 33 - - - ICCARM - 224 - - - __cstat - 10 - - - - - ICCARM - 143 133 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 154 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_init.c - - - BICOMP - 242 - - - ICCARM - 238 - - - __cstat - 44 - - - - - BICOMP - 46 160 13 142 228 75 42 56 149 74 145 154 134 133 91 83 129 32 87 230 100 81 88 147 77 18 159 155 156 72 151 174 99 89 45 235 225 185 236 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 90 153 240 - - - ICCARM - 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 151 154 133 174 90 153 156 240 134 91 83 - - - - - $PROJ_DIR$\..\..\..\kernel\src\mm\los_memstat.c - - - BICOMP - 7 - - - ICCARM - 214 - - - __cstat - 80 - - - - - ICCARM - 83 32 99 42 46 89 45 91 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_queue.c - - - BICOMP - 27 - - - ICCARM - 168 - - - __cstat - 179 - - - - - BICOMP - 13 81 32 18 133 83 89 147 155 42 90 99 225 185 100 88 77 159 56 72 240 151 45 235 236 149 160 74 75 142 145 150 143 91 129 46 87 230 228 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 192 65 181 163 48 162 132 158 189 212 154 153 134 156 - - - ICCARM - 91 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 150 192 48 65 162 189 132 212 158 163 151 154 143 133 90 153 156 240 134 83 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c - - - BICOMP - 14 - - - ICCARM - 11 - - - __cstat - 164 - - - - - BICOMP - 70 135 13 56 84 206 228 42 136 157 97 152 87 230 139 191 96 78 161 55 92 235 225 185 236 46 89 45 241 99 100 149 81 160 88 74 147 75 77 18 142 159 145 155 - - - ICCARM - 78 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.c - - - BICOMP - 198 - - - ICCARM - 201 - - - __cstat - 187 - - - - - BICOMP - 96 92 87 139 161 13 230 191 78 55 149 52 228 56 42 136 84 157 135 97 206 152 70 160 235 225 185 236 46 89 45 241 99 100 81 88 74 147 75 77 18 142 159 145 155 221 - - - ICCARM - 221 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 52 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_sem.c + $PROJ_DIR$\..\..\..\kernel\src\los_priqueue.c BICOMP 196 - ICCARM - 234 + __cstat + 212 - __cstat - 203 + ICCARM + 72 - - BICOMP - 42 135 89 70 153 225 84 206 13 91 99 235 236 136 157 97 152 134 32 45 154 72 185 241 139 191 96 78 161 55 92 133 83 90 240 156 46 129 87 230 228 56 100 149 81 160 88 74 147 75 77 18 142 159 145 155 63 - ICCARM - 63 90 153 156 32 99 42 46 89 45 240 134 154 133 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 91 83 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c - - - BICOMP - 53 - - - ICCARM - 43 - - - __cstat - 166 - - - - - BICOMP - 92 96 13 87 139 161 230 191 78 55 228 56 42 136 84 157 135 97 206 152 70 235 225 185 236 46 89 45 241 99 100 149 81 160 88 74 147 75 77 18 142 159 145 155 - - - ICCARM - 161 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 206 18 55 142 152 159 92 145 70 155 + 125 141 62 79 64 48 84 69 101 132 126 209 107 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 @@ -989,34 +887,84 @@ AARM - 183 + 169 - $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c + $PROJ_DIR$\..\..\..\kernel\src\los_swtmr.c BICOMP - 165 - - - ICCARM - 239 + 146 __cstat - 178 + 167 + + + ICCARM + 183 + + + + + ICCARM + 117 172 20 19 64 48 84 69 25 119 166 90 189 118 133 89 36 239 62 79 226 104 199 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 17 101 132 126 209 107 141 103 125 92 + + + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c + + + BICOMP + 18 + + + __cstat + 135 + + + ICCARM + 65 BICOMP - 88 13 236 159 235 99 100 77 225 42 45 241 81 147 18 155 185 46 89 149 160 74 75 142 145 87 230 228 56 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 + 109 99 226 108 115 137 178 170 46 21 203 19 64 83 85 127 82 80 202 128 33 205 199 147 215 48 84 69 211 79 81 131 106 138 110 38 113 39 40 76 121 129 134 122 ICCARM - 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 + 137 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.c + + + BICOMP + 145 + + + __cstat + 155 + + + ICCARM + 174 + + + + + BICOMP + 99 109 108 115 137 226 178 170 46 21 131 42 203 19 64 83 85 127 82 80 202 128 33 138 205 199 147 215 48 84 69 211 79 81 106 110 38 113 39 40 76 121 129 134 122 185 + + + ICCARM + 185 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 42 @@ -1025,129 +973,214 @@ BICOMP - 40 - - - ICCARM - 73 + 78 __cstat - 85 + 91 + + + ICCARM + 37 BICOMP - 99 149 42 225 185 74 145 13 221 65 160 75 142 83 56 235 236 100 81 88 147 77 18 159 155 48 97 46 89 45 32 87 230 228 241 136 139 84 191 157 96 135 78 161 206 55 152 92 70 181 52 + 79 131 64 199 147 38 134 226 185 25 138 39 121 92 19 205 215 81 106 110 113 40 76 129 122 20 80 48 84 69 62 108 178 203 211 83 115 85 170 127 99 82 46 137 202 21 128 109 33 152 42 ICCARM - 48 56 42 46 89 45 65 83 32 99 97 13 93 225 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 77 161 206 18 55 142 152 159 92 145 70 155 221 52 + 20 19 64 48 84 69 25 92 62 79 80 226 104 199 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 40 137 202 76 21 121 128 129 109 134 33 122 185 42 - $PROJ_DIR$\..\..\..\kernel\src\los_event.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c BICOMP - 195 - - - ICCARM - 204 - - - __cstat - 86 - - - - - BICOMP - 147 32 155 13 129 230 81 18 156 87 100 88 77 159 240 42 46 228 56 149 160 74 75 142 145 91 153 134 99 89 45 154 72 235 225 185 236 241 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 90 - - - ICCARM - 90 153 156 32 99 42 46 89 45 240 134 154 91 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 - - - - - $PROJ_DIR$\..\..\..\kernel\src\mm\los_memory.c - - - BICOMP - 62 - - - ICCARM - 16 - - - __cstat - 22 - - - - - BICOMP - 65 87 13 136 42 56 97 83 162 45 230 157 152 90 192 48 132 158 46 89 72 99 228 225 84 135 206 70 153 154 133 91 143 181 163 189 212 129 32 235 185 241 139 191 96 78 161 55 92 134 156 150 236 100 149 81 160 88 74 147 75 77 18 142 159 145 155 240 - - - ICCARM - 150 192 48 56 42 46 89 45 65 162 189 132 212 158 163 133 72 129 32 99 13 93 225 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 154 90 153 156 240 134 91 83 143 - - - - - $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c - - - BICOMP - 17 - - - ICCARM - 36 + 55 __cstat 180 + + ICCARM + 173 + BICOMP - 13 136 97 228 42 157 152 56 84 135 206 70 87 230 139 191 96 78 161 55 92 235 225 185 236 46 89 45 241 99 100 149 81 160 88 74 147 75 77 18 142 159 145 155 + 127 203 64 128 83 80 226 19 85 82 202 33 108 178 115 170 99 46 137 21 109 205 199 147 215 48 84 69 211 79 81 131 106 138 110 38 113 39 40 76 121 129 134 122 ICCARM - 75 13 93 225 56 42 46 89 45 94 186 99 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 97 77 161 206 18 55 142 152 159 92 145 70 155 + 99 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 - $PROJ_DIR$\..\..\..\kernel\src\los_err.c + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c + + + BICOMP + 77 + + + __cstat + 160 + + + ICCARM + 222 + + + + + BICOMP + 138 226 121 39 199 147 48 84 131 38 134 205 215 64 69 211 79 81 106 110 113 40 76 129 122 99 108 178 203 19 83 115 85 170 127 82 46 80 137 202 21 128 109 33 + + + ICCARM + 80 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_wwdg.c + + + BICOMP + 75 + + + __cstat + 201 + + + ICCARM + 229 + + + + + BICOMP + 83 226 80 203 64 127 128 19 85 82 202 33 108 178 115 170 99 46 137 21 109 205 199 147 215 48 84 69 211 79 81 131 106 138 110 38 113 39 40 76 121 129 134 122 + + + ICCARM + 40 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c BICOMP 197 - ICCARM - 205 + __cstat + 168 - __cstat - 64 + ICCARM + 63 + + BICOMP + 110 215 129 226 205 79 81 40 199 64 69 211 106 113 76 122 147 48 84 131 138 38 39 121 134 99 108 178 203 19 83 115 85 170 127 82 46 80 137 202 21 128 109 33 + ICCARM - 156 32 99 42 46 89 45 + 170 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_tick.c + + + BICOMP + 45 + + + __cstat + 195 + + + ICCARM + 47 + + + + + BICOMP + 199 48 147 109 99 226 79 115 137 64 211 170 46 21 126 36 205 215 83 85 127 82 80 202 128 33 89 62 84 69 239 108 178 203 19 81 131 106 138 110 38 113 39 40 76 121 129 134 122 132 + + + ICCARM + 132 126 62 79 64 48 84 69 89 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw.c + + + BICOMP + 30 + + + __cstat + 32 + + + ICCARM + 23 + + + + + BICOMP + 79 209 62 25 64 48 84 19 117 132 107 126 69 141 172 101 152 133 20 119 90 118 166 189 + + + ICCARM + 101 132 126 62 79 64 48 84 69 209 107 141 117 172 20 19 25 119 166 90 189 118 133 + + + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c + + + BICOMP + 49 + + + __cstat + 116 + + + ICCARM + 73 + + + + + BICOMP + 110 215 129 226 205 79 81 40 199 64 69 211 106 113 76 122 147 48 84 131 138 38 39 121 134 108 178 203 19 83 115 85 170 127 99 82 46 80 137 202 21 128 109 33 + + + ICCARM + 85 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 @@ -1156,113 +1189,261 @@ BICOMP - 59 - - - ICCARM - 104 + 41 __cstat - 148 + 124 + + + ICCARM + 86 BICOMP - 13 139 32 99 161 225 185 96 92 83 45 241 191 78 55 72 41 89 240 235 236 42 136 84 157 135 97 206 152 70 90 91 156 46 153 134 154 129 87 230 228 56 100 149 81 160 88 74 147 75 77 18 142 159 145 155 + 80 226 100 19 83 48 127 128 36 92 79 64 107 199 147 85 82 202 33 68 126 62 132 239 104 115 170 99 46 137 21 109 101 254 84 69 255 141 108 144 81 131 106 138 110 38 113 39 40 76 121 129 134 122 ICCARM - 153 156 32 99 42 46 89 45 90 240 134 154 72 129 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 91 83 41 + 132 126 62 79 64 48 84 69 101 209 107 141 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 89 92 68 - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_exc.c + $PROJ_DIR$\..\..\..\kernel\src\los_tick.c BICOMP - 69 + 187 __cstat - 66 + 87 + + + ICCARM + 194 + + + ICCARM + 132 126 62 79 64 48 84 69 36 239 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 101 209 107 141 17 + + - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_dispatch_iar.S + $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.c + + + BICOMP + 139 + + + __cstat + 198 + + + ICCARM + 114 + + + + + BICOMP + 33 82 226 19 85 202 203 64 83 127 80 128 108 178 115 170 99 46 137 21 109 42 205 199 147 215 48 84 69 211 79 81 131 106 138 110 38 113 39 40 76 121 129 134 122 185 + + + ICCARM + 185 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 42 + + + + + $PROJ_DIR$\..\..\..\kernel\src\los_task.c + + + BICOMP + 190 + + + __cstat + 149 + + + ICCARM + 176 + + + + + ICCARM + 36 239 62 79 64 48 84 69 226 104 199 19 100 144 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 46 39 80 40 137 202 76 21 121 128 129 109 134 33 122 117 172 20 25 119 166 90 189 118 133 31 101 132 126 209 107 141 148 103 89 16 92 + + + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c + + + BICOMP + 228 + + + __cstat + 123 + + + ICCARM + 224 + + + + + BICOMP + 33 82 226 19 85 202 203 64 83 127 80 128 108 178 115 170 99 46 137 21 109 205 199 147 215 48 84 69 211 79 81 131 106 138 110 38 113 39 40 76 121 129 134 122 + + + ICCARM + 46 226 104 199 19 64 48 84 69 100 144 79 108 147 83 81 115 131 85 106 170 138 127 110 99 38 82 113 39 80 40 137 202 76 21 121 128 129 109 134 33 122 + + + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc.S AARM - 61 + 60 - - $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_hw_exc_iar.S - - - AARM - 58 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_misc.c - - - BICOMP - 207 - - - ICCARM - 216 - - - __cstat - 98 - - - - - ICCARM - 91 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 90 153 156 240 134 154 - - - - - $PROJ_DIR$\..\..\..\kernel\src\los_timeslice.c - - - BICOMP - 95 - - - ICCARM - 232 - - - __cstat - 184 - - - - - BICOMP - 99 149 87 74 145 13 32 160 75 142 42 46 186 100 81 88 147 77 18 159 155 90 72 129 89 45 93 225 185 94 56 136 139 84 191 157 96 135 78 97 161 206 55 152 92 70 240 91 153 134 156 154 - - - ICCARM - 91 72 129 32 99 42 46 89 45 13 93 225 56 94 186 87 185 136 100 139 149 84 81 191 160 157 88 96 74 135 147 78 75 97 77 161 206 18 55 142 152 159 92 145 70 155 90 153 156 240 134 154 - - - [MULTI_TOOL] ILINK + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_context.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_interrupt.c + ICCARM + + + $PROJ_DIR$\..\..\..\components\cpup\los_cpup.c + ICCARM + + + $PROJ_DIR$\..\..\..\utils\los_debug.c + ICCARM + + + $PROJ_DIR$\..\..\..\utils\los_error.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_event.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\mm\los_membox.c + ICCARM + + + $PROJ_DIR$\..\..\..\components\cppsupport\los_cppsupport.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_init.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\mm\los_memory.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_mux.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_queue.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\arch\arm\cortex-m4\iar\los_timer.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_sem.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c + ICCARM + + + $PROJ_DIR$\..\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_swtmr.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c + ICCARM + + + $PROJ_DIR$\..\Utilities\STM32_EVAL\STM324x9I_EVAL\stm324x9i_eval.c + ICCARM + + + $PROJ_DIR$\..\dprintf.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_wwdg.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c + ICCARM + + + $PROJ_DIR$\..\main.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_tick.c + ICCARM + + + $PROJ_DIR$\..\board\iar_stm32f429ig_fire-challenger.c + ICCARM + + + $PROJ_DIR$\..\..\..\kernel\src\los_task.c + ICCARM + + + $PROJ_DIR$\..\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c + ICCARM + [REBUILD_ALL] 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 index 0439b2fb..8f1086bc 100755 --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/project/los_demo.ewp @@ -312,7 +312,7 @@

    © COPYRIGHT 2016 STMicroelectronics

    + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. * - *

    © COPYRIGHT 2011 STMicroelectronics

    ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_it.h" +#include "main.h" /** @addtogroup Template_Project * @{ @@ -40,7 +47,7 @@ /******************************************************************************/ /** - * @brief This function handles NMI exception. + * @brief This function handles NMI exception. * @param None * @retval None */ @@ -105,7 +112,7 @@ void UsageFault_Handler(void) * @param None * @retval None */ -__weak void SVC_Handler(void) +void SVC_Handler(void) { } @@ -123,7 +130,7 @@ void DebugMon_Handler(void) * @param None * @retval None */ -__weak void PendSV_Handler(void) +void PendSV_Handler(void) { } @@ -132,27 +139,30 @@ __weak void PendSV_Handler(void) * @param None * @retval None */ -__weak void SysTick_Handler(void) +void SysTick_Handler(void) { - + TimingDelay_Decrement(); } +/******************************************************************************/ +/* STM32F4xx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32f4xx.s). */ +/******************************************************************************/ + /** - * @brief This function handles EXTI 3 interrupt request. + * @brief This function handles PPP interrupt request. * @param None * @retval None */ -__weak void EXTI9_5_IRQHandler(void) +/*void PPP_IRQHandler(void) { -} +}*/ /** - * @brief This function handles EXTI 15-10 interrupt request. - * @param None - * @retval None - */ -__weak void EXTI15_10_IRQHandler(void) -{ -} + * @} + */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/stm32f4xx_it.h b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/stm32f4xx_it.h index 77a61e50..f4c2ef42 100644 --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/stm32f4xx_it.h +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/stm32f4xx_it.h @@ -2,22 +2,28 @@ ****************************************************************************** * @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_it.h * @author MCD Application Team - * @version V1.0.0 - * @date 30-September-2011 + * @version V1.8.0 + * @date 04-November-2016 * @brief This file contains the headers of the interrupt handlers. ****************************************************************************** * @attention * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + *

    © COPYRIGHT 2016 STMicroelectronics

    + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. * - *

    © COPYRIGHT 2011 STMicroelectronics

    ****************************************************************************** - */ + */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F4xx_IT_H @@ -51,4 +57,4 @@ void SysTick_Handler(void); #endif /* __STM32F4xx_IT_H */ -/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h index 50b8fcd0..6f6b8721 100755 --- a/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h +++ b/targets/cortex-m4_stm32f429ig_fire-challenger_iar/target_config.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: @@ -48,7 +48,7 @@ extern "C" { /*============================================================================= System clock module configuration =============================================================================*/ -#define OS_SYS_CLOCK 180000000 +#define OS_SYS_CLOCK 64000000 #define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL) #define LOSCFG_BASE_CORE_TICK_HW_TIME 0 /*============================================================================= @@ -92,6 +92,10 @@ extern "C" { =============================================================================*/ #define LOSCFG_MEM_MUL_POOL 1 #define OS_SYS_MEM_NUM 20 +/*============================================================================= + Exception module configuration +=============================================================================*/ +#define LOSCFG_PLATFORM_EXC 1 /* ============================================================================= printf module configuration ============================================================================= */ diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/Core/Inc/task_sample.h b/targets/cortex-m7_nucleo_f767zi_gcc/Core/Inc/task_sample.h index bd8cc782..408f7ff8 100644 --- a/targets/cortex-m7_nucleo_f767zi_gcc/Core/Inc/task_sample.h +++ b/targets/cortex-m7_nucleo_f767zi_gcc/Core/Inc/task_sample.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/syscalls.c b/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/syscalls.c deleted file mode 100644 index 1b4932cb..00000000 --- a/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/syscalls.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Support files for GNU libc. Files in the system namespace go here. - Files in the C namespace (ie those that do not start with an - underscore) go in .c. */ - -#include <_ansi.h> -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#define FreeRTOS -#define MAX_STACK_SIZE 0x2000 - -extern int __io_putchar(int ch) __attribute__((weak)); -extern int __io_getchar(void) __attribute__((weak)); - -#ifndef FreeRTOS - register char * stack_ptr asm("sp"); -#endif - - - - -caddr_t _sbrk(int incr) -{ - extern char end asm("end"); - static char *heap_end; - char *prev_heap_end,*min_stack_ptr; - - if (heap_end == 0) - heap_end = &end; - - prev_heap_end = heap_end; - -#ifdef FreeRTOS - /* Use the NVIC offset register to locate the main stack pointer. */ - min_stack_ptr = (char*)(*(unsigned int *)*(unsigned int *)0xE000ED08); - /* Locate the STACK bottom address */ - min_stack_ptr -= MAX_STACK_SIZE; - - if (heap_end + incr > min_stack_ptr) -#else - if (heap_end + incr > stack_ptr) -#endif - { -// write(1, "Heap and stack collision\n", 25); -// abort(); - errno = ENOMEM; - return (caddr_t) -1; - } - - heap_end += incr; - - return (caddr_t) prev_heap_end; -} - -/* - * _gettimeofday primitive (Stub function) - * */ -int _gettimeofday (struct timeval * tp, struct timezone * tzp) -{ - /* Return fixed data for the timezone. */ - if (tzp) - { - tzp->tz_minuteswest = 0; - tzp->tz_dsttime = 0; - } - - return 0; -} -void initialise_monitor_handles() -{ -} - -int _getpid(void) -{ - return 1; -} - -int _kill(int pid, int sig) -{ - errno = EINVAL; - return -1; -} - -void _exit (int status) -{ - _kill(status, -1); - while (1) {} -} - -int _write(int file, char *ptr, int len) -{ - int DataIdx; - - for (DataIdx = 0; DataIdx < len; DataIdx++) - { - __io_putchar( *ptr++ ); - } - return len; -} - -int _close(int file) -{ - return -1; -} - -int _fstat(int file, struct stat *st) -{ - st->st_mode = S_IFCHR; - return 0; -} - -int _isatty(int file) -{ - return 1; -} - -int _lseek(int file, int ptr, int dir) -{ - return 0; -} - -int _read(int file, char *ptr, int len) -{ - int DataIdx; - - for (DataIdx = 0; DataIdx < len; DataIdx++) - { - *ptr++ = __io_getchar(); - } - - return len; -} - -int _open(char *path, int flags, ...) -{ - /* Pretend like we always fail */ - return -1; -} - -int _wait(int *status) -{ - errno = ECHILD; - return -1; -} - -int _unlink(char *name) -{ - errno = ENOENT; - return -1; -} - -int _times(struct tms *buf) -{ - return -1; -} - -int _stat(char *file, struct stat *st) -{ - st->st_mode = S_IFCHR; - return 0; -} - -int _link(char *old, char *new) -{ - errno = EMLINK; - return -1; -} - -int _fork(void) -{ - errno = EAGAIN; - return -1; -} - -int _execve(char *name, char **argv, char **env) -{ - errno = ENOMEM; - return -1; -} diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/task_sample.c b/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/task_sample.c index 8835b5c6..5729406b 100644 --- a/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/task_sample.c +++ b/targets/cortex-m7_nucleo_f767zi_gcc/Core/Src/task_sample.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 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: diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/LICENSE.txt b/targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/LICENSE.txt new file mode 100644 index 00000000..c0ee8129 --- /dev/null +++ b/targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/README.md b/targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/README.md new file mode 100644 index 00000000..08861a65 --- /dev/null +++ b/targets/cortex-m7_nucleo_f767zi_gcc/Drivers/CMSIS/README.md @@ -0,0 +1,104 @@ +# CMSIS Version 5 + +The branch *master* of this GitHub repository contains the CMSIS Version 5.4.0. The [documentation](http://arm-software.github.io/CMSIS_5/General/html/index.html) is available under http://arm-software.github.io/CMSIS_5/General/html/index.html + +Use [Issues](https://github.com/ARM-software/CMSIS_5#issues-and-labels) to provide feedback and report problems for CMSIS Version 5. + +**Note:** The branch *develop* of this GitHub repository reflects our current state of development and is constantly updated. It gives our users and partners contiguous access to the CMSIS development. It allows you to review the work and provide feedback or create pull requests for contributions. + +A [pre-built documentation](http://www.keil.com/pack/doc/CMSIS_Dev/index.html) is updated from time to time, but may be also generated using the instructions under [Generate CMSIS Pack for Release](https://github.com/ARM-software/CMSIS_5#generate-cmsis-pack-for-release). + +## Implemented Enhancements + - CMSIS-Core-A, RTX5: implementation for Cortex-A5/A7/A9 + - Support for Armv8-M Architecture (Mainline and Baseline) as well as devices Cortex-M23 and Cortex-M33 + - CMSIS-RTOS2: RTX 5 is now available for IAR, GCC, Arm Compiler 5, Arm Compiler 6 + - CMSIS-RTOS2: FreeRTOS adoption (release) is available https://github.com/ARM-software/CMSIS-FreeRTOS + - CMSIS-NN: Bare metal Neural Network function library. + - CMSIS-DAP v2: with WinUSB for faster communication and separate pipe for SWO support + - Config Wizard extension: access enum’s for configuration information + +## Further Planned Enhancements + - CMSIS-Zone: management of complex system + - CMSIS-Pack: + - System Description SDF Format: describe more complex debug topologies than with a Debug Description in a tool agnostic way + - Github based workflow: allows to develop software packs using github infra-structure + - Flash algorithm via debugger: Some TurstZone enable devices cannot execute RAM. Commands that allow flash programming will be added to Debug Description. + - CPDSC project file format: allows project templates that are agnostic of an IDE + - Minimize need for IDE specific settings: CMSIS-Pack supports IDE specific parameters. Analyze and minimize + +For further details see also the [Slides of the Embedded World CMSIS Partner Meeting](https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS_EW2018.pdf). + +## Directory Structure + +| Directory | Content | +| --------------- | ---------------------------------------------- | +| CMSIS/Core | CMSIS-Core related files (for release) | +| CMSIS/DAP | CMSIS-DAP related files and examples | +| CMSIS/Driver | CMSIS-Driver API headers and template files | +| CMSIS/DSP | CMSIS-DSP related files | +| CMSIS/NN | CMSIS-NN related files | +| CMSIS/RTOS | RTOS v1 related files (for Cortex-M) | +| CMSIS/RTOS2 | RTOS v2 related files (for Cortex-M & Armv8-M) | +| CMSIS/Pack | CMSIS-Pack examples and tutorials | +| CMSIS/DoxyGen | Source of the documentation | +| CMSIS/Utilities | Utility programs | + +## Generate CMSIS Pack for Release + +This GitHub development repository contains already pre-built libraries of various software components (DSP, RTOS, RTOS2). +These libraries are validated for release. + +To build a complete CMSIS pack for installation the following additional tools are required: + - **doxygen.exe** Version: 1.8.6 (Documentation Generator) + - **mscgen.exe** Version: 0.20 (Message Sequence Chart Converter) + - **7z.exe (7-Zip)** Version: 16.02 (File Archiver) + +Using these tools, you can generate on a Windows PC: + - **CMSIS Software Pack** using the batch file **gen_pack.bat** (located in ./CMSIS/Utilities). This batch file also generates the documentation. + + - **CMSIS Documentation** using the batch file **genDoc.bat** (located in ./CMSIS/Doxygen). + +The file ./CMSIS/DoxyGen/How2Doc.txt describes the rules for creating API documentation. + +## License + +Arm CMSIS is licensed under Apache-2.0. + +## Contributions and Pull Requests + +Contributions are accepted under Apache-2.0. Only submit contributions where you have authored all of the code. + +### Issues and Labels + +Please feel free to raise an [issue on GitHub](https://github.com/ARM-software/CMSIS_5/issues) +to report misbehavior (i.e. bugs) or start discussions about enhancements. This +is your best way to interact directly with the maintenance team and the community. +We encourage you to append implementation suggestions as this helps to decrease the +workload of the very limited maintenance team. + +We will be monitoring and responding to issues as best we can. +Please attempt to avoid filing duplicates of open or closed items when possible. +In the spirit of openness we will be tagging issues with the following: + +- **bug** – We consider this issue to be a bug that will be investigated. + +- **wontfix** - We appreciate this issue but decided not to change the current behavior. + +- **enhancement** – Denotes something that will be implemented soon. + +- **future** - Denotes something not yet schedule for implementation. + +- **out-of-scope** - We consider this issue loosely related to CMSIS. It might by implemented outside of CMSIS. Let us know about your work. + +- **question** – We have further questions to this issue. Please review and provide feedback. + +- **documentation** - This issue is a documentation flaw that will be improved in future. + +- **review** - This issue is under review. Please be patient. + +- **DONE** - We consider this issue as resolved - please review and close it. In case of no further activity this issues will be closed after a week. + +- **duplicate** - This issue is already addressed elsewhere, see comment with provided references. + +- **Important Information** - We provide essential informations regarding planned or resolved major enhancements. + diff --git a/targets/cortex-m7_nucleo_f767zi_gcc/LICENSE.pdf b/targets/cortex-m7_nucleo_f767zi_gcc/LICENSE.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9d4bdbc0b5affb4fbcc80a68c4d432e8fca4a257 GIT binary patch literal 89685 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