add support for RTOS

This commit is contained in:
Gabriel Wang 2021-12-20 16:22:09 +00:00
parent 2b8e1dbc75
commit 075b52f5ee
4 changed files with 154 additions and 19 deletions

View File

@ -16,6 +16,10 @@
<repository type="git">https://github.com/GorgonMeducer/perf_counter.git</repository> <repository type="git">https://github.com/GorgonMeducer/perf_counter.git</repository>
<releases> <releases>
<release date="2021-12-20" version="1.7.0" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.6.4.pack">
- Add new feature for RTOS. Now you can get cycle information for the current thread.
- Other minor update
</release>
<release date="2021-11-13" version="1.6.4" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.6.4.pack"> <release date="2021-11-13" version="1.6.4" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.6.4.pack">
- Improve support for IAR - Improve support for IAR
- Fix issues found in foreach - Fix issues found in foreach
@ -74,6 +78,12 @@
<require Cclass="CMSIS" Cgroup="CORE"/> <require Cclass="CMSIS" Cgroup="CORE"/>
</condition> </condition>
<condition id="CMSIS-RTOS2-RTX5">
<description>Require CMSIS-RTOS2-RTX5 Support</description>
<require Cclass="CMSIS" Cgroup="CORE"/>
<require Cclass="CMSIS" Cgroup="RTOS2 (API)" Csub="Keil RTX5">
</condition>
<condition id="Cortex-M Arm GCC"> <condition id="Cortex-M Arm GCC">
<description>Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors.</description> <description>Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors.</description>
<require condition="Arm GCC"/> <require condition="Arm GCC"/>
@ -98,6 +108,7 @@
<require condition="CMSIS-CORE"/> <require condition="CMSIS-CORE"/>
</condition> </condition>
</conditions> </conditions>
<!-- apis section (optional - for Application Programming Interface descriptions) --> <!-- apis section (optional - for Application Programming Interface descriptions) -->
<!-- <!--
@ -130,21 +141,23 @@
--> -->
<components> <components>
<component Cclass="Utilities" Cgroup="Performance" Csub="perf_counter" Cvariant="Library" Cversion="1.6.4" isDefaultVariant="true"> <component Cclass="Utilities" Cgroup="Performance" Csub="perf_counter" Cvariant="Library" Cversion="1.7.0" isDefaultVariant="true">
<description>A dedicated performance counter for Cortex-M systick.</description> <description>A dedicated performance counter for Cortex-M systick.</description>
<files> <files>
<file category="header" name="lib/perf_counter.h"/> <file category="header" name="lib/perf_counter.h"/>
<file category="library" name="lib/perf_counter.lib" condition="Cortex-M Arm Compiler"/> <file category="library" name="lib/perf_counter.lib" condition="Cortex-M Arm Compiler"/>
<file category="library" name="lib/libperf_counter_gcc.a" condition="Cortex-M Arm GCC"/> <file category="library" name="lib/libperf_counter_gcc.a" condition="Cortex-M Arm GCC"/>
<file category="source" name="lib/perf_os_patch_rtx5.c" condition="CMSIS-RTOS2-RTX5"/>
</files> </files>
</component> </component>
<component Cclass="Utilities" Cgroup="Performance" Csub="perf_counter" Cvariant="Source" Cversion="1.6.4" condition="CMSIS-CORE"> <component Cclass="Utilities" Cgroup="Performance" Csub="perf_counter" Cvariant="Source" Cversion="1.7.0" condition="CMSIS-CORE">
<description>A dedicated performance counter for Cortex-M systick.</description> <description>A dedicated performance counter for Cortex-M systick.</description>
<files> <files>
<file category="header" name="lib/perf_counter.h"/> <file category="header" name="lib/perf_counter.h"/>
<file category="source" name="perf_counter.c" /> <file category="source" name="perf_counter.c" />
<file category="source" name="systick_wrapper_ual.s" condition="Cortex-M Arm Compiler CMSIS-CORE"/> <file category="source" name="systick_wrapper_ual.s" condition="Cortex-M Arm Compiler CMSIS-CORE"/>
<file category="source" name="systick_wrapper_gcc.s" condition="Cortex-M Arm GCC CMSIS-CORE"/> <file category="source" name="systick_wrapper_gcc.s" condition="Cortex-M Arm GCC CMSIS-CORE"/>
<file category="source" name="lib/perf_os_patch_rtx5.c" condition="CMSIS-RTOS2-RTX5"/>
</files> </files>
</component> </component>
</components> </components>

View File

@ -53,6 +53,7 @@ PACK_BASE_FILES="
perf_counter.h perf_counter.h
systick_wrapper_gcc.s systick_wrapper_gcc.s
systick_wrapper_ual.s systick_wrapper_ual.s
perf_os_patch_rtx5.c
LICENSE LICENSE
README.md README.md
" "
@ -199,6 +200,8 @@ if [ $errorlevel -ne 0 ]; then
fi fi
cp -f ./$PACK_VENDOR.$PACK_NAME.pdsc ${PACK_WAREHOUSE} cp -f ./$PACK_VENDOR.$PACK_NAME.pdsc ${PACK_WAREHOUSE}
cp -f ./perf_os_patch_rtx5.c ./lib
cp -f ./perf_counter.h ./lib
echo "build of pack succeeded" echo "build of pack succeeded"
# Clean up # Clean up

View File

@ -30,42 +30,41 @@
//! @{ //! @{
//! \note for IAR //! \note for IAR
#ifdef __IS_COMPILER_IAR__
#undef __IS_COMPILER_IAR__ #undef __IS_COMPILER_IAR__
#endif
#if defined(__IAR_SYSTEMS_ICC__) #if defined(__IAR_SYSTEMS_ICC__)
# define __IS_COMPILER_IAR__ 1 # define __IS_COMPILER_IAR__ 1
#endif #endif
//! \note for arm compiler 5 //! \note for arm compiler 5
#ifdef __IS_COMPILER_ARM_COMPILER_5__
#undef __IS_COMPILER_ARM_COMPILER_5__ #undef __IS_COMPILER_ARM_COMPILER_5__
#endif
#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000)) #if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
# define __IS_COMPILER_ARM_COMPILER_5__ 1 # define __IS_COMPILER_ARM_COMPILER_5__ 1
#endif #endif
//! @} //! @}
//! \note for arm compiler 6 //! \note for arm compiler 6
#ifdef __IS_COMPILER_ARM_COMPILER_6__
#undef __IS_COMPILER_ARM_COMPILER_6__ #undef __IS_COMPILER_ARM_COMPILER_6__
#endif
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
# define __IS_COMPILER_ARM_COMPILER_6__ 1 # define __IS_COMPILER_ARM_COMPILER_6__ 1
#endif #endif
#ifdef __IS_COMPILER_LLVM__ #undef __IS_COMPILER_ARM_COMPILER__
# undef __IS_COMPILER_LLVM__ #if defined(__IS_COMPILER_ARM_COMPILER_5__) && __IS_COMPILER_ARM_COMPILER_5__ \
|| defined(__IS_COMPILER_ARM_COMPILER_6__) && __IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_ARM_COMPILER__ 1
#endif #endif
#undef __IS_COMPILER_LLVM__
#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__ #if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_LLVM__ 1 # define __IS_COMPILER_LLVM__ 1
#else #else
//! \note for gcc //! \note for gcc
# ifdef __IS_COMPILER_GCC__
# undef __IS_COMPILER_GCC__ # undef __IS_COMPILER_GCC__
# endif # if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER__) \
# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER_5__) \
|| defined(__IS_COMPILER_ARM_COMPILER_6__) \
|| defined(__IS_COMPILER_LLVM__)) || defined(__IS_COMPILER_LLVM__))
# define __IS_COMPILER_GCC__ 1 # define __IS_COMPILER_GCC__ 1
# endif # endif
@ -253,6 +252,13 @@
}) })
/*============================ TYPES =========================================*/ /*============================ TYPES =========================================*/
typedef struct {
uint64_t dwStart;
uint64_t dwUsedTotal;
uint32_t dwUsedRecent;
uint32_t wActiveCount;
} task_cycle_info_t;
/*============================ GLOBAL VARIABLES ==============================*/ /*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/ /*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/ /*============================ PROTOTYPES ====================================*/
@ -312,6 +318,15 @@ __attribute__((nothrow))
extern int64_t get_system_ticks(void); extern int64_t get_system_ticks(void);
/*! \brief provide cycle information for target thread if perf_counter is used
*! together with an RTOS in the support list.
*!
*! Support RTOS List:
*! - RTX5
*/
extern task_cycle_info_t * get_rtos_thread_cycle_info(void);
/*----------------------------------------------------------------------------* /*----------------------------------------------------------------------------*
* Please ignore the following APIs unless you have encountered some known * * Please ignore the following APIs unless you have encountered some known *
* special conditions * * special conditions *

104
perf_os_patch_rtx5.c Normal file
View File

@ -0,0 +1,104 @@
/****************************************************************************
* Copyright 2021 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. *
* *
****************************************************************************/
/*============================ INCLUDES ======================================*/
#include "rtx_os.h"
#include "perf_counter.h"
/*============================ MACROS ========================================*/
#undef __WRAP_FUNC
#undef WRAP_FUNC
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
#elif (defined(__IS_COMPILER_LLVM__) && __IS_COMPILER_LLVM__) \
|| (defined(__IS_COMPILER_GCC__) && __IS_COMPILER_GCC__)
# define __WRAP_FUNC(__NAME) __wrap_##__NAME
# define __ORIG_FUNC(__NAME) __real_##__NAME
#endif
#define WRAP_FUNC(__NAME) __WRAP_FUNC(__NAME)
#define ORIG_FUNC(__NAME) __ORIG_FUNC(__NAME)
struct __task_cycle_info_t {
uint64_t dwLastTimeStamp;
task_cycle_info_t tInfo;
} ;
/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
/*============================ IMPLEMENTATION ================================*/
__attribute__((used))
/*! \brief wrapper function for rtos context switching */
void WRAP_FUNC(osRtxThreadSwitch) (osRtxThread_t *thread)
{
extern void ORIG_FUNC(osRtxThreadSwitch) (osRtxThread_t *thread);
//assert(NULL != ptThread);
do {
struct __task_cycle_info_t *ptFrame = NULL;
uint64_t dwTimeStamp;
osRtxThread_t *curr = osRtxInfo.thread.run.curr;
if (curr == thread) {
break;
}
//! get current system ticks
dwTimeStamp = get_system_ticks();
if (NULL != curr) {
ptFrame = (struct __task_cycle_info_t *)curr->stack_mem;
ptFrame->tInfo.dwUsedRecent = dwTimeStamp - ptFrame->dwLastTimeStamp;
ptFrame->tInfo.dwUsedTotal += ptFrame->tInfo.dwUsedRecent;
}
//! inital target thread
ptFrame = (struct __task_cycle_info_t *)thread->stack_mem;
if (0 == ptFrame->tInfo.dwStart) {
ptFrame->tInfo.dwStart = dwTimeStamp;
}
ptFrame->dwLastTimeStamp = dwTimeStamp;
ptFrame->tInfo.wActiveCount++;
} while(0);
ORIG_FUNC(osRtxThreadSwitch)(thread);
}
task_cycle_info_t * get_rtos_thread_cycle_info(void)
{
osRtxThread_t *curr = osRtxInfo.thread.run.curr;
if (NULL == curr) {
return NULL;
}
return &(((struct __task_cycle_info_t *)curr->stack_mem)->tInfo);
}