add support for ThreadX

This commit is contained in:
Gabriel Wang 2021-12-29 14:18:41 +00:00
parent dd1c72ae08
commit 2a566561dd
16 changed files with 293 additions and 29 deletions

View File

@ -16,6 +16,10 @@
<repository type="git">https://github.com/GorgonMeducer/perf_counter.git</repository>
<releases>
<release date="2021-12-29" version="1.7.4" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.7.4.pack">
- Add support for ThreadX
- Other minor update
</release>
<release date="2021-12-28" version="1.7.3" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.7.3.pack">
- Fix an issue that cycle information might lose when there is no context switching.
- Other minor update
@ -167,7 +171,7 @@
-->
<components>
<bundle Cbundle="Performance Counter" Cclass="Utilities" Cversion="1.7.3">
<bundle Cbundle="Performance Counter" Cclass="Utilities" Cversion="1.7.4">
<description>A dedicated performance counter for Cortex-M systick.</description>
<doc></doc>
<component Cgroup="perf_counter" Csub="Core" Cvariant="Library" isDefaultVariant="true">
@ -236,6 +240,20 @@ extern void __freertos_evr_on_task_switched_in(void *ptTCB, unsigned int uxTopPr
</Pre_Include_Global_h>
</component>
<component Cgroup="perf_counter" Csub="ThreadX Patch" condition="perf_counter">
<description>A Patch for ThreadX</description>
<files>
<file category="source" name="lib/perf_os_patch_threadx.c"/>
</files>
<Pre_Include_Global_h>
//! \brief Enable RTOS Patch for perf_counter
#define __PERF_CNT_USE_RTOS__
#define TX_ENABLE_EXECUTION_CHANGE_NOTIFY
</Pre_Include_Global_h>
</component>
</bundle>
</components>

Binary file not shown.

View File

@ -16,6 +16,10 @@
<repository type="git">https://github.com/GorgonMeducer/perf_counter.git</repository>
<releases>
<release date="2021-12-29" version="1.7.4" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.7.4.pack">
- Add support for ThreadX
- Other minor update
</release>
<release date="2021-12-28" version="1.7.3" url="https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/GorgonMeducer.perf_counter.1.7.3.pack">
- Fix an issue that cycle information might lose when there is no context switching.
- Other minor update
@ -167,7 +171,7 @@
-->
<components>
<bundle Cbundle="Performance Counter" Cclass="Utilities" Cversion="1.7.3">
<bundle Cbundle="Performance Counter" Cclass="Utilities" Cversion="1.7.4">
<description>A dedicated performance counter for Cortex-M systick.</description>
<doc></doc>
<component Cgroup="perf_counter" Csub="Core" Cvariant="Library" isDefaultVariant="true">
@ -236,6 +240,20 @@ extern void __freertos_evr_on_task_switched_in(void *ptTCB, unsigned int uxTopPr
</Pre_Include_Global_h>
</component>
<component Cgroup="perf_counter" Csub="ThreadX Patch" condition="perf_counter">
<description>A Patch for ThreadX</description>
<files>
<file category="source" name="lib/perf_os_patch_threadx.c"/>
</files>
<Pre_Include_Global_h>
//! \brief Enable RTOS Patch for perf_counter
#define __PERF_CNT_USE_RTOS__
#define TX_ENABLE_EXECUTION_CHANGE_NOTIFY
</Pre_Include_Global_h>
</component>
</bundle>
</components>

View File

@ -56,6 +56,7 @@ PACK_BASE_FILES="
perf_os_patch_rtx5.c
perf_os_patch_freertos.c
perf_os_patch_rt_thread.c
perf_os_patch_threadx.c
LICENSE
README.md
"
@ -143,6 +144,7 @@ cp -f ./$PACK_VENDOR.$PACK_NAME.pdsc ${PACK_BUILD}
cp -f ./perf_os_patch_rtx5.c ./lib
cp -f ./perf_os_patch_freertos.c ./lib
cp -f ./perf_os_patch_rt_thread.c ./lib
cp -f ./perf_os_patch_threadx.c ./lib
cp -f ./perf_counter.h ./lib
# directories

View File

@ -254,9 +254,9 @@
/*============================ TYPES =========================================*/
typedef struct {
uint64_t dwStart;
uint64_t dwUsedTotal;
uint32_t dwUsedRecent;
int64_t lStart;
int64_t lUsedTotal;
int32_t nUsedRecent;
uint32_t wActiveCount;
} task_cycle_info_t;
@ -339,7 +339,7 @@ extern void start_task_cycle_counter(void);
*!
*! \return the elapsed cycle count.
*/
extern int32_t stop_task_cycle_counter(void);
extern int64_t stop_task_cycle_counter(void);
#elif !defined(__IMPLEMENT_PERF_COUNTER)

Binary file not shown.

View File

@ -60,7 +60,7 @@ correct privileged Vs unprivileged linkage and placement. */
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;
/*============================ TYPES =========================================*/

View File

@ -44,7 +44,7 @@
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;

View File

@ -45,7 +45,7 @@
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;
/*============================ TYPES =========================================*/

113
lib/perf_os_patch_threadx.c Normal file
View File

@ -0,0 +1,113 @@
/****************************************************************************
* 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 "tx_api.h"
#include "tx_thread.h"
#include "perf_counter.h"
#include "cmsis_compiler.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)
#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#error In order to use perf_counter:ThreadX-Patch, please define\
TX_ENABLE_EXECUTION_CHANGE_NOTIFY in the project configuration.\
If you don't want to use this patch, please un-select it in RTE\
or remove this patch from the compilation.
#endif
/*============================ TYPES =========================================*/
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
int64_t lLastTimeStamp;
} ;
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
extern void __on_context_switch_in(uint32_t *pwStack);
extern void __on_context_switch_out(uint32_t *pwStack);
/*============================ IMPLEMENTATION ================================*/
#if defined(TX_EXECUTION_PROFILE_ENABLE)
void WRAP_FUNC(_tx_execution_thread_enter)(void)
#else
void _tx_execution_thread_enter (void)
#endif
{
TX_THREAD * ptThread = NULL;
TX_THREAD_GET_CURRENT(ptThread);
__on_context_switch_out(ptThread->tx_thread_stack_start);
#if defined(TX_EXECUTION_PROFILE_ENABLE)
extern void ORIG_FUNC(_tx_execution_thread_enter)(void);
ORIG_FUNC(_tx_execution_thread_enter)();
#endif
}
#if defined(TX_EXECUTION_PROFILE_ENABLE)
void WRAP_FUNC(_tx_execution_thread_exit)(void)
#else
void _tx_execution_thread_exit(void)
#endif
{
TX_THREAD * ptThread = NULL;
TX_THREAD_GET_CURRENT(ptThread);
__on_context_switch_in(ptThread->tx_thread_stack_start);
#if defined(TX_EXECUTION_PROFILE_ENABLE)
extern void ORIG_FUNC(_tx_execution_thread_exit)(void);
ORIG_FUNC(_tx_execution_thread_exit)();
#endif
}
task_cycle_info_t * get_rtos_task_cycle_info(void)
{
TX_THREAD * ptThread = NULL;
TX_THREAD_GET_CURRENT(ptThread);
return &(((struct __task_cycle_info_t *)ptThread->tx_thread_stack_start)->tInfo);
}

View File

@ -157,7 +157,7 @@ typedef struct
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;
/*============================ GLOBAL VARIABLES ==============================*/
@ -408,10 +408,10 @@ void __on_context_switch_in(uint32_t *pwStack)
struct __task_cycle_info_t *ptFrame = (struct __task_cycle_info_t *)pwStack;
uint64_t dwTimeStamp = get_system_ticks();
if (0 == ptFrame->tInfo.dwStart) {
ptFrame->tInfo.dwStart = dwTimeStamp;
if (0 == ptFrame->tInfo.lStart) {
ptFrame->tInfo.lStart = dwTimeStamp;
}
ptFrame->dwLastTimeStamp = dwTimeStamp;
ptFrame->lLastTimeStamp = dwTimeStamp;
ptFrame->tInfo.wActiveCount++;
}
@ -422,8 +422,8 @@ void __on_context_switch_out(uint32_t *pwStack)
uint64_t dwTimeStamp = get_system_ticks();
struct __task_cycle_info_t *ptFrame = (struct __task_cycle_info_t *)pwStack;
ptFrame->tInfo.dwUsedRecent = dwTimeStamp - ptFrame->dwLastTimeStamp;
ptFrame->tInfo.dwUsedTotal += ptFrame->tInfo.dwUsedRecent;
ptFrame->tInfo.nUsedRecent = dwTimeStamp - ptFrame->lLastTimeStamp;
ptFrame->tInfo.lUsedTotal += ptFrame->tInfo.nUsedRecent;
}
@ -436,12 +436,12 @@ void start_task_cycle_counter(void)
}
__IRQ_SAFE {
ptInfo->dwLastTimeStamp = get_system_ticks();
ptInfo->tInfo.dwUsedTotal = 0;
ptInfo->lLastTimeStamp = get_system_ticks();
ptInfo->tInfo.lUsedTotal = 0;
}
}
int32_t stop_task_cycle_counter(void)
int64_t stop_task_cycle_counter(void)
{
struct __task_cycle_info_t * ptInfo =
(struct __task_cycle_info_t *)get_rtos_task_cycle_info();
@ -449,13 +449,13 @@ int32_t stop_task_cycle_counter(void)
return 0;
}
int32_t nCycles = 0;
int64_t lCycles = 0;
__IRQ_SAFE {
nCycles = ptInfo->tInfo.dwUsedTotal
+ (get_system_ticks() - ptInfo->dwLastTimeStamp);
lCycles = ptInfo->tInfo.lUsedTotal
+ (get_system_ticks() - ptInfo->lLastTimeStamp);
}
return nCycles;
return lCycles;
}

View File

@ -254,9 +254,9 @@
/*============================ TYPES =========================================*/
typedef struct {
uint64_t dwStart;
uint64_t dwUsedTotal;
uint32_t dwUsedRecent;
int64_t lStart;
int64_t lUsedTotal;
int32_t nUsedRecent;
uint32_t wActiveCount;
} task_cycle_info_t;
@ -339,7 +339,7 @@ extern void start_task_cycle_counter(void);
*!
*! \return the elapsed cycle count.
*/
extern int32_t stop_task_cycle_counter(void);
extern int64_t stop_task_cycle_counter(void);
#elif !defined(__IMPLEMENT_PERF_COUNTER)

View File

@ -60,7 +60,7 @@ correct privileged Vs unprivileged linkage and placement. */
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;
/*============================ TYPES =========================================*/

View File

@ -44,7 +44,7 @@
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;

View File

@ -45,7 +45,7 @@
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
uint64_t dwLastTimeStamp;
int64_t lLastTimeStamp;
} ;
/*============================ TYPES =========================================*/

113
perf_os_patch_threadx.c Normal file
View File

@ -0,0 +1,113 @@
/****************************************************************************
* 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 "tx_api.h"
#include "tx_thread.h"
#include "perf_counter.h"
#include "cmsis_compiler.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)
#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
#error In order to use perf_counter:ThreadX-Patch, please define\
TX_ENABLE_EXECUTION_CHANGE_NOTIFY in the project configuration.\
If you don't want to use this patch, please un-select it in RTE\
or remove this patch from the compilation.
#endif
/*============================ TYPES =========================================*/
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
int64_t lLastTimeStamp;
} ;
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
extern void __on_context_switch_in(uint32_t *pwStack);
extern void __on_context_switch_out(uint32_t *pwStack);
/*============================ IMPLEMENTATION ================================*/
#if defined(TX_EXECUTION_PROFILE_ENABLE)
void WRAP_FUNC(_tx_execution_thread_enter)(void)
#else
void _tx_execution_thread_enter (void)
#endif
{
TX_THREAD * ptThread = NULL;
TX_THREAD_GET_CURRENT(ptThread);
__on_context_switch_out(ptThread->tx_thread_stack_start);
#if defined(TX_EXECUTION_PROFILE_ENABLE)
extern void ORIG_FUNC(_tx_execution_thread_enter)(void);
ORIG_FUNC(_tx_execution_thread_enter)();
#endif
}
#if defined(TX_EXECUTION_PROFILE_ENABLE)
void WRAP_FUNC(_tx_execution_thread_exit)(void)
#else
void _tx_execution_thread_exit(void)
#endif
{
TX_THREAD * ptThread = NULL;
TX_THREAD_GET_CURRENT(ptThread);
__on_context_switch_in(ptThread->tx_thread_stack_start);
#if defined(TX_EXECUTION_PROFILE_ENABLE)
extern void ORIG_FUNC(_tx_execution_thread_exit)(void);
ORIG_FUNC(_tx_execution_thread_exit)();
#endif
}
task_cycle_info_t * get_rtos_task_cycle_info(void)
{
TX_THREAD * ptThread = NULL;
TX_THREAD_GET_CURRENT(ptThread);
return &(((struct __task_cycle_info_t *)ptThread->tx_thread_stack_start)->tInfo);
}