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>
<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">
- Improve support for IAR
- Fix issues found in foreach
@ -74,6 +78,12 @@
<require Cclass="CMSIS" Cgroup="CORE"/>
</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">
<description>Compile Cortex-M Processors with GNU Tools for Arm Embedded Processors.</description>
<require condition="Arm GCC"/>
@ -98,6 +108,7 @@
<require condition="CMSIS-CORE"/>
</condition>
</conditions>
<!-- apis section (optional - for Application Programming Interface descriptions) -->
<!--
@ -130,21 +141,23 @@
-->
<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>
<files>
<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/libperf_counter_gcc.a" condition="Cortex-M Arm GCC"/>
<file category="source" name="lib/perf_os_patch_rtx5.c" condition="CMSIS-RTOS2-RTX5"/>
</files>
</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>
<files>
<file category="header" name="lib/perf_counter.h"/>
<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_gcc.s" condition="Cortex-M Arm GCC CMSIS-CORE"/>
<file category="source" name="lib/perf_os_patch_rtx5.c" condition="CMSIS-RTOS2-RTX5"/>
</files>
</component>
</components>

View File

@ -53,6 +53,7 @@ PACK_BASE_FILES="
perf_counter.h
systick_wrapper_gcc.s
systick_wrapper_ual.s
perf_os_patch_rtx5.c
LICENSE
README.md
"
@ -198,7 +199,9 @@ if [ $errorlevel -ne 0 ]; then
exit
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"
# Clean up

View File

@ -30,42 +30,41 @@
//! @{
//! \note for IAR
#ifdef __IS_COMPILER_IAR__
# undef __IS_COMPILER_IAR__
#endif
#undef __IS_COMPILER_IAR__
#if defined(__IAR_SYSTEMS_ICC__)
# define __IS_COMPILER_IAR__ 1
#endif
//! \note for arm compiler 5
#ifdef __IS_COMPILER_ARM_COMPILER_5__
# undef __IS_COMPILER_ARM_COMPILER_5__
#endif
#undef __IS_COMPILER_ARM_COMPILER_5__
#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
# define __IS_COMPILER_ARM_COMPILER_5__ 1
#endif
//! @}
//! \note for arm compiler 6
#ifdef __IS_COMPILER_ARM_COMPILER_6__
# undef __IS_COMPILER_ARM_COMPILER_6__
#endif
#undef __IS_COMPILER_ARM_COMPILER_6__
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
# define __IS_COMPILER_ARM_COMPILER_6__ 1
#endif
#ifdef __IS_COMPILER_LLVM__
# undef __IS_COMPILER_LLVM__
#undef __IS_COMPILER_ARM_COMPILER__
#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
#undef __IS_COMPILER_LLVM__
#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_LLVM__ 1
#else
//! \note for gcc
# ifdef __IS_COMPILER_GCC__
# undef __IS_COMPILER_GCC__
# endif
# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER_5__) \
|| defined(__IS_COMPILER_ARM_COMPILER_6__) \
# undef __IS_COMPILER_GCC__
# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER__) \
|| defined(__IS_COMPILER_LLVM__))
# define __IS_COMPILER_GCC__ 1
# endif
@ -253,6 +252,13 @@
})
/*============================ TYPES =========================================*/
typedef struct {
uint64_t dwStart;
uint64_t dwUsedTotal;
uint32_t dwUsedRecent;
uint32_t wActiveCount;
} task_cycle_info_t;
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
@ -312,6 +318,15 @@ __attribute__((nothrow))
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 *
* 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);
}