diff --git a/GorgonMeducer.perf_counter.pdsc b/GorgonMeducer.perf_counter.pdsc index a9b303a..ce019bd 100644 --- a/GorgonMeducer.perf_counter.pdsc +++ b/GorgonMeducer.perf_counter.pdsc @@ -16,7 +16,11 @@ https://github.com/GorgonMeducer/perf_counter.git - + + - Fix the source variant support for Armv8-M processors + - Other minor fixes + + - Fix the support for RT-Thread @@ -85,27 +89,37 @@ GNU Tools for Arm Embedded Processors. - - Support All Cortex-M based processors + + + + + + + + + + + + + + + - - - - - - - - - - + + + Support All Cortex-M based processors + + + + Require CMSIS-CORE Support @@ -139,6 +153,18 @@ + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. @@ -152,6 +178,19 @@ + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + + @@ -185,7 +224,7 @@ --> - + A dedicated performance counter for Cortex-M systick. documents/Doxygen/html/index.html @@ -211,8 +250,9 @@ - + + diff --git a/README.md b/README.md index 141f833..e0c8350 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# perf_counter (v1.9.9) +# perf_counter (v1.9.11) A dedicated performance counter for Cortex-M Systick. It shares the SysTick with users' original SysTick function(s) without interfering with it. This library will bring new functionalities, such as performance counter,` delay_us` and `clock()` service defined in `time.h`. ### Features: diff --git a/cmsis-pack/GorgonMeducer.perf_counter.1.9.10.pack b/cmsis-pack/GorgonMeducer.perf_counter.1.9.11.pack similarity index 77% rename from cmsis-pack/GorgonMeducer.perf_counter.1.9.10.pack rename to cmsis-pack/GorgonMeducer.perf_counter.1.9.11.pack index 9c2aa65..e4a7b76 100644 Binary files a/cmsis-pack/GorgonMeducer.perf_counter.1.9.10.pack and b/cmsis-pack/GorgonMeducer.perf_counter.1.9.11.pack differ diff --git a/cmsis-pack/GorgonMeducer.perf_counter.pdsc b/cmsis-pack/GorgonMeducer.perf_counter.pdsc index a9b303a..ce019bd 100644 --- a/cmsis-pack/GorgonMeducer.perf_counter.pdsc +++ b/cmsis-pack/GorgonMeducer.perf_counter.pdsc @@ -16,7 +16,11 @@ https://github.com/GorgonMeducer/perf_counter.git - + + - Fix the source variant support for Armv8-M processors + - Other minor fixes + + - Fix the support for RT-Thread @@ -85,27 +89,37 @@ GNU Tools for Arm Embedded Processors. - - Support All Cortex-M based processors + + + + + + + + + + + + + + + - - - - - - - - - - + + + Support All Cortex-M based processors + + + + Require CMSIS-CORE Support @@ -139,6 +153,18 @@ + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. @@ -152,6 +178,19 @@ + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + + + Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors. + + + + + @@ -185,7 +224,7 @@ --> - + A dedicated performance counter for Cortex-M systick. documents/Doxygen/html/index.html @@ -211,8 +250,9 @@ - + + diff --git a/example/ArInp.bat b/example/ArInp.bat deleted file mode 100644 index 5be070c..0000000 --- a/example/ArInp.bat +++ /dev/null @@ -1 +0,0 @@ -"C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021-07\bin\arm-none-eabi-ar" -M Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ; -Stack_Size EQU 0x00000400 +;Stack_Size EQU 0x00000400 - AREA STACK, NOINIT, READWRITE, ALIGN=3 -__stack_limit -Stack_Mem SPACE Stack_Size -__initial_sp +; AREA STACK, NOINIT, READWRITE, ALIGN=3 +;__stack_limit +;Stack_Mem SPACE Stack_Size +;__initial_sp -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; +;; Heap Configuration +;; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +;; -Heap_Size EQU 0x00000C00 +;Heap_Size EQU 0x00000C00 - IF Heap_Size != 0 ; Heap is provided - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - ENDIF +; IF Heap_Size != 0 ; Heap is provided +; AREA HEAP, NOINIT, READWRITE, ALIGN=3 +;__heap_base +;Heap_Mem SPACE Heap_Size +;__heap_limit +; ENDIF PRESERVE8 @@ -62,8 +62,9 @@ __heap_limit EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size - -__Vectors DCD __initial_sp ; Top of Stack + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit| + +__Vectors DCD |Image$$ARM_LIB_STACK$$ZI$$Limit| ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; -14 NMI Handler DCD HardFault_Handler ; -13 Hard Fault Handler @@ -154,15 +155,15 @@ $Handler_Name PROC ; User setup Stack & Heap - IF :LNOT::DEF:__MICROLIB - IMPORT __use_two_region_memory - ENDIF +; IF :LNOT::DEF:__MICROLIB +; IMPORT __use_two_region_memory +; ENDIF - EXPORT __stack_limit - EXPORT __initial_sp - IF Heap_Size != 0 ; Heap is provided - EXPORT __heap_base - EXPORT __heap_limit - ENDIF +; EXPORT __stack_limit +; EXPORT __initial_sp +; IF Heap_Size != 0 ; Heap is provided +; EXPORT __heap_base +; EXPORT __heap_limit +; ENDIF END diff --git a/example/example.sct b/example/example.sct new file mode 100644 index 0000000..acdf9df --- /dev/null +++ b/example/example.sct @@ -0,0 +1,36 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0 -E -xc +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + + +#define RAM1_SIZE 0x00020000 +#define RAM1_BASE 0x20000000 +#define RAM1_LIMIT (RAM1_BASE + RAM1_SIZE) + +#define STACK_SIZE 0x800 + +#define HEAP_ALIGN 8 +#define HEAP_SIZE (RAM1_LIMIT - AlignExpr(ImageLimit(RW_IRAM1), HEAP_ALIGN)) + + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ARM_LIB_STACK RAM1_BASE ALIGN 8 EMPTY FILL 0xDEADBEEF STACK_SIZE {} + + RW_IRAM1 +0 { ; RW data + .ANY (+RW +ZI) + } + + ARM_LIB_HEAP +0 ALIGN HEAP_ALIGN EMPTY HEAP_SIZE {} + + ScatterAssert(ImageLimit(ARM_LIB_HEAP) <= RAM1_LIMIT) +} + + diff --git a/example/example.uvoptx b/example/example.uvoptx index f42dba7..9e68388 100644 --- a/example/example.uvoptx +++ b/example/example.uvoptx @@ -165,7 +165,7 @@ 1 1 - 0x00 + 0x20000000 0 @@ -364,54 +364,6 @@ 0 0 - 94 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - <1>.\main.c - - -
- - 1 - 0 - 93 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - <1>.\main.c - - -
- - 2 - 0 - 92 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - <1>.\main.c - - -
- - 3 - 0 62 1
0
@@ -741,7 +693,7 @@ application - 0 + 1 0 0 0 @@ -849,7 +801,7 @@ ::Compiler - 1 + 0 0 0 1 diff --git a/example/example.uvprojx b/example/example.uvprojx index 13c5bce..ffe5702 100644 --- a/example/example.uvprojx +++ b/example/example.uvprojx @@ -10,7 +10,7 @@ example_arm_compiler_6 0x4 ARM-ADS - 6180000::V6.18::ARMCLANG + 6190000::V6.19::ARMCLANG 1 @@ -52,7 +52,7 @@ example 1 0 - 0 + 1 1 1 .\ @@ -190,7 +190,7 @@ 0 0 8 - 1 + 0 1 0 0 @@ -337,7 +337,7 @@ 0 0 - -Wno-missing-prototypes -Wno-reserved-identifier -Wno-sign-conversion -Wno-c11-extensions -Wno-implicit-int-conversion + -Wno-missing-prototypes -Wno-reserved-identifier -Wno-sign-conversion -Wno-c11-extensions -Wno-implicit-int-conversion -Wno-invalid-utf8 __PERF_COUNTER_CFG_USE_SYSTICK_WRAPPER__ .. @@ -371,7 +371,7 @@ - Blinky.sct + example.sct @@ -530,7 +530,7 @@ library 0x4 ARM-ADS - 6180000::V6.18::ARMCLANG + 6190000::V6.19::ARMCLANG 1 @@ -1548,7 +1548,7 @@ - Blinky.sct + .\example.sct diff --git a/example/main.c b/example/main.c index 26192c0..7190989 100644 --- a/example/main.c +++ b/example/main.c @@ -62,6 +62,66 @@ static example_lv0_t s_tItem[8] = { {.chID = 6}, {.chID = 7}, }; +#if __IS_COMPILER_ARM_COMPILER__ +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" +# pragma clang diagnostic ignored "-Wdouble-promotion" +#endif +uint32_t calculate_stack_usage_topdown(void) +{ + extern uint32_t Image$$ARM_LIB_STACK$$Limit[]; + extern uint32_t Image$$ARM_LIB_STACK$$Length; + + uint32_t *pwStack = Image$$ARM_LIB_STACK$$Limit; + uint32_t wStackSize = (uintptr_t)&Image$$ARM_LIB_STACK$$Length / 4; + uint32_t wStackUsed = 0; + + + do { + if (*--pwStack == 0xDEADBEEF) { + break; + } + wStackUsed++; + } while(--wStackSize); + + + printf("\r\nStack Usage: [%d/%d] %2.2f%%\r\n", + wStackUsed * 4, + (uintptr_t)&Image$$ARM_LIB_STACK$$Length, + ( (float)wStackUsed * 400.0f + / (float)(uintptr_t)&Image$$ARM_LIB_STACK$$Length)); + + return wStackUsed * 4; +} + +uint32_t calculate_stack_usage_bottomup(void) +{ + extern uint32_t Image$$ARM_LIB_STACK$$Base[]; + extern uint32_t Image$$ARM_LIB_STACK$$Length; + + uint32_t *pwStack = Image$$ARM_LIB_STACK$$Base; + uint32_t wStackSize = (uintptr_t)&Image$$ARM_LIB_STACK$$Length; + uint32_t wStackUsed = wStackSize / 4; + + do { + if (*pwStack++ != 0xDEADBEEF) { + break; + } + } while(--wStackUsed); + + printf("\r\nStack Usage: [%d/%d] %2.2f%%\r\n", + wStackUsed * 4, + wStackSize, + ( (float)wStackUsed * 400.0f / (float)wStackSize)); + + return wStackUsed * 4; +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +#endif /*---------------------------------------------------------------------------- Main function @@ -120,6 +180,11 @@ int main (void) printf("used clock cycle: %d", (int32_t)(get_system_ticks() - tStart)); } while(0); +#if __IS_COMPILER_ARM_COMPILER__ + calculate_stack_usage_topdown(); + calculate_stack_usage_bottomup(); +#endif + while (1) { printf("\r\nhello world\r\n"); delay_ms(1000); diff --git a/gen_pack.sh b/gen_pack.sh index b79d5ff..bef2f5f 100644 --- a/gen_pack.sh +++ b/gen_pack.sh @@ -54,6 +54,7 @@ PACK_BASE_FILES=" perf_counter.c perf_counter.h systick_wrapper_gcc.s + systick_wrapper_gnu.s systick_wrapper_ual.s LICENSE README.md diff --git a/lib/perf_counter.h b/lib/perf_counter.h index 77ad411..cbcba09 100644 --- a/lib/perf_counter.h +++ b/lib/perf_counter.h @@ -35,9 +35,9 @@ extern "C" { */ #define __PERF_COUNTER_VER_MAJOR__ 1 #define __PERF_COUNTER_VER_MINOR__ 9 -#define __PERF_COUNTER_VER_REVISE__ 10 +#define __PERF_COUNTER_VER_REVISE__ 11 -#define __PERF_COUNTER_VER_STR__ "dev" +#define __PERF_COUNTER_VER_STR__ "" #define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \ +__PERF_COUNTER_VER_MINOR__ * 100ul \ @@ -285,7 +285,7 @@ extern "C" { #endif #if __PLOOC_VA_NUM_ARGS() != 0 -#warning Please enable GNC extensions, it is required by __cycleof__() and \ +#warning Please enable GNU extensions, it is required by __cycleof__() and \ __super_loop_monitor__() #endif @@ -472,9 +472,6 @@ __attribute__((noinline)) extern int64_t clock(void); #endif - - - /*! @} */ /*! @@ -607,7 +604,6 @@ extern int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo); * special conditions * *----------------------------------------------------------------------------*/ - /*! \brief initialise cycle counter service * \note - don't forget to tell the function whether the systick is already * used by user applications. diff --git a/lib/perf_counter.lib b/lib/perf_counter.lib index 591357e..12866c9 100644 Binary files a/lib/perf_counter.lib and b/lib/perf_counter.lib differ diff --git a/perf_counter.h b/perf_counter.h index 77ad411..cbcba09 100644 --- a/perf_counter.h +++ b/perf_counter.h @@ -35,9 +35,9 @@ extern "C" { */ #define __PERF_COUNTER_VER_MAJOR__ 1 #define __PERF_COUNTER_VER_MINOR__ 9 -#define __PERF_COUNTER_VER_REVISE__ 10 +#define __PERF_COUNTER_VER_REVISE__ 11 -#define __PERF_COUNTER_VER_STR__ "dev" +#define __PERF_COUNTER_VER_STR__ "" #define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \ +__PERF_COUNTER_VER_MINOR__ * 100ul \ @@ -285,7 +285,7 @@ extern "C" { #endif #if __PLOOC_VA_NUM_ARGS() != 0 -#warning Please enable GNC extensions, it is required by __cycleof__() and \ +#warning Please enable GNU extensions, it is required by __cycleof__() and \ __super_loop_monitor__() #endif @@ -472,9 +472,6 @@ __attribute__((noinline)) extern int64_t clock(void); #endif - - - /*! @} */ /*! @@ -607,7 +604,6 @@ extern int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo); * special conditions * *----------------------------------------------------------------------------*/ - /*! \brief initialise cycle counter service * \note - don't forget to tell the function whether the systick is already * used by user applications. diff --git a/systick_wrapper_gnu.s b/systick_wrapper_gnu.s new file mode 100644 index 0000000..ee2dbca --- /dev/null +++ b/systick_wrapper_gnu.s @@ -0,0 +1,47 @@ +;/**************************************************************************** +;* Copyright 2022 Gorgon Meducer (Email:embedded_zhuoran@hotmail.com) * +;* * +;* 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. * +;* * +;****************************************************************************/ + + + .syntax unified + .arch armv6-m + + + .eabi_attribute Tag_ABI_align_preserved, 1 + .text + .thumb + .thumb_func + .align 2 + .globl $Sub$$SysTick_Handler + .type $Sub$$SysTick_Handler, %function + +$Sub$$SysTick_Handler: + push {r4, r5} + push {r4, lr} + ldr R0, =user_code_insert_to_systick_handler + blx R0 + pop {r4, r5} + mov lr, r5 + pop {r4, r5} + ldr R0, =$Super$$SysTick_Handler + bx R0 + + + .globl __ensure_systick_wrapper + .type __ensure_systick_wrapper, %function + +__ensure_systick_wrapper: + bx lr