remove lib folder

This commit is contained in:
Gabriel Wang 2024-02-28 20:37:58 +00:00
parent c213ffd46d
commit 15d26f61d8
10 changed files with 5 additions and 1759 deletions

View File

@ -6,7 +6,7 @@
<description>A dedicated performance counter for the Cortex-M Systick. It shares the SysTick with users' original SysTick function without interfering with it. This library will bring new functionalities, such as performance counter, APIs for delay, clock() defined in time.h etc.</description>
<url>https://raw.githubusercontent.com/GorgonMeducer/perf_counter/CMSIS-Pack/cmsis-pack/</url>
<supportContact>https://github.com/GorgonMeducer/perf_counter/issues</supportContact>
<license>lib/LICENSE</license>
<license>LICENSE</license>
<!-- optional license file -->
<!--
<license>
@ -322,7 +322,7 @@
</Pre_Include_Global_h>
</component>
<component Cclass="Utilities" Cversion="1.0.0" Cgroup="perf_counter" Csub="Porting" Cvariant="PMU" isDefaultVariant="true" condition="PMU Devices">
<component Cclass="Utilities" Cversion="1.1.0" Cgroup="perf_counter" Csub="Porting" Cvariant="PMU" isDefaultVariant="true" condition="PMU Devices">
<description>Using the Performande Monitor Unit</description>
<files>
<file category="sourceC" name="perfc_port_pmu.c"/>
@ -343,12 +343,12 @@
</component>
<component Cclass="Utilities" Cgroup="perf_counter" Csub="Benchmark" Cvariant="Coremark" Cversion="1.1.2" condition="perf_counter">
<component Cclass="Utilities" Cgroup="perf_counter" Csub="Benchmark" Cvariant="Coremark" Cversion="1.1.3" condition="perf_counter">
<description>Coremark</description>
<files>
<file category="sourceC" name="benchmark/coremark_port/core_main.c"/>
<file category="sourceC" name="benchmark/coremark_port/core_portme.c" attr="config" version="1.1.2" />
<file category="header" name="benchmark/coremark_port/core_portme.h" attr="config" version="1.1.2" />
<file category="sourceC" name="benchmark/coremark_port/core_portme.c" attr="config" version="1.1.3" />
<file category="header" name="benchmark/coremark_port/core_portme.h" attr="config" version="1.1.3" />
<file category="include" name="benchmark/coremark/" />
<file category="sourceC" name="benchmark/coremark/core_list_join.c"/>

View File

@ -32,7 +32,6 @@ DEFAULT_ARGS=(-c "v")
benchmark
documents
os
lib
template
"

View File

@ -1,201 +0,0 @@
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.

Binary file not shown.

View File

@ -1,973 +0,0 @@
/****************************************************************************
* Copyright 2024 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. *
* *
****************************************************************************/
#ifndef __PERFORMANCE_COUNTER_H__
#define __PERFORMANCE_COUNTER_H__
/*============================ INCLUDES ======================================*/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifndef __PERFC_CFG_PORTING_INCLUDE__
# include "perfc_port_default.h"
#else
# include __PERFC_CFG_PORTING_INCLUDE__
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*============================ MACROS ========================================*/
/*!
* \addtogroup gBasic 1 Basic
* @{
*/
#define __PERF_COUNTER_VER_MAJOR__ 2
#define __PERF_COUNTER_VER_MINOR__ 3
#define __PERF_COUNTER_VER_REVISE__ 0
#define __PERF_COUNTER_VER_STR__ "dev"
#define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \
+__PERF_COUNTER_VER_MINOR__ * 100ul \
+__PERF_COUNTER_VER_REVISE__)
/*! @} */
/*!
* \addtogroup gHelper 4 Helper
* @{
*/
// for IAR
#undef __IS_COMPILER_IAR__
#if defined(__IAR_SYSTEMS_ICC__)
# define __IS_COMPILER_IAR__ 1
#endif
// for arm compiler 5
#undef __IS_COMPILER_ARM_COMPILER_5__
#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
# define __IS_COMPILER_ARM_COMPILER_5__ 1
#endif
//for arm compiler 6
#undef __IS_COMPILER_ARM_COMPILER_6__
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
# define __IS_COMPILER_ARM_COMPILER_6__ 1
#endif
#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
// for clang
#undef __IS_COMPILER_LLVM__
#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_LLVM__ 1
#else
// for gcc
# undef __IS_COMPILER_GCC__
# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER__) \
|| defined(__IS_COMPILER_LLVM__) \
|| defined(__IS_COMPILER_IAR__))
# define __IS_COMPILER_GCC__ 1
# endif
#endif
#ifdef __PERF_COUNT_PLATFORM_SPECIFIC_HEADER__
# include __PERF_COUNT_PLATFORM_SPECIFIC_HEADER__
#endif
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-warning-option"
# pragma clang diagnostic ignored "-Wreserved-identifier"
# pragma clang diagnostic ignored "-Wdeclaration-after-statement"
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
# pragma clang diagnostic ignored "-Wgnu-statement-expression"
# pragma clang diagnostic ignored "-Wunused-but-set-variable"
# pragma clang diagnostic ignored "-Wshadow"
# pragma clang diagnostic ignored "-Wshorten-64-to-32"
# pragma clang diagnostic ignored "-Wcompound-token-split-by-macro"
# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#elif defined(__IS_COMPILER_ARM_COMPILER_5__)
# pragma diag_suppress 550
#elif defined(__IS_COMPILER_GCC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic"
# pragma GCC diagnostic ignored "-Wunused-variable"
# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
# pragma GCC diagnostic ignored "-Wformat="
#endif
#ifndef __PLOOC_VA_NUM_ARGS_IMPL
# define __PLOOC_VA_NUM_ARGS_IMPL( _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11, \
_12,_13,_14,_15,_16,__N,...) __N
#endif
#ifndef __PLOOC_VA_NUM_ARGS
#define __PLOOC_VA_NUM_ARGS(...) \
__PLOOC_VA_NUM_ARGS_IMPL( 0,##__VA_ARGS__,16,15,14,13,12,11,10,9, \
8,7,6,5,4,3,2,1,0)
#endif
#ifndef UNUSED_PARAM
# define UNUSED_PARAM(__VAR) (void)(__VAR)
#endif
#ifndef MIN
# define MIN(__a, __b) ((__a) <= (__b) ? (__a) : (__b))
#endif
#ifndef MAX
# define MAX(__a, __b) ((__a) >= (__b) ? (__a) : (__b))
#endif
/*!
* \brief an attribute for static variables that no initialisation is required
* in the C startup process.
*/
#ifndef PERF_NOINIT
# if defined(__IS_COMPILER_ARM_COMPILER_5__)
# define PERF_NOINIT __attribute__(( section( ".bss.noinit"),zero_init))
# elif defined(__IS_COMPILER_ARM_COMPILER_6__)
# define PERF_NOINIT __attribute__(( section( ".bss.noinit")))
# elif defined(__IS_COMPILER_IAR__)
# define PERF_NOINIT __no_init
# elif (defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)) && !defined(__APPLE__)
# define PERF_NOINIT __attribute__(( section( ".bss.noinit")))
# else
# define PERF_NOINIT
# endif
#endif
#undef __CONNECT2
#undef __CONNECT3
#undef __CONNECT4
#undef __CONNECT5
#undef __CONNECT6
#undef __CONNECT7
#undef __CONNECT8
#undef __CONNECT9
#undef CONNECT2
#undef CONNECT3
#undef CONNECT4
#undef CONNECT5
#undef CONNECT6
#undef CONNECT7
#undef CONNECT8
#undef CONNECT9
#undef CONNECT
#undef __MACRO_EXPANDING
#define __MACRO_EXPANDING(...) __VA_ARGS__
#define __CONNECT2(__A, __B) __A##__B
#define __CONNECT3(__A, __B, __C) __A##__B##__C
#define __CONNECT4(__A, __B, __C, __D) __A##__B##__C##__D
#define __CONNECT5(__A, __B, __C, __D, __E) __A##__B##__C##__D##__E
#define __CONNECT6(__A, __B, __C, __D, __E, __F) __A##__B##__C##__D##__E##__F
#define __CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
__A##__B##__C##__D##__E##__F##__G
#define __CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
__A##__B##__C##__D##__E##__F##__G##__H
#define __CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
__A##__B##__C##__D##__E##__F##__G##__H##__I
#define ALT_CONNECT2(__A, __B) __CONNECT2(__A, __B)
#define CONNECT2(__A, __B) __CONNECT2(__A, __B)
#define CONNECT3(__A, __B, __C) __CONNECT3(__A, __B, __C)
#define CONNECT4(__A, __B, __C, __D) __CONNECT4(__A, __B, __C, __D)
#define CONNECT5(__A, __B, __C, __D, __E) __CONNECT5(__A, __B, __C, __D, __E)
#define CONNECT6(__A, __B, __C, __D, __E, __F) \
__CONNECT6(__A, __B, __C, __D, __E, __F)
#define CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
__CONNECT7(__A, __B, __C, __D, __E, __F, __G)
#define CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
__CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H)
#define CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
__CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I)
#define CONNECT(...) \
ALT_CONNECT2(CONNECT, __PLOOC_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#undef __using1
#undef __using2
#undef __using3
#undef __using4
#undef using
#define __using1(__declare) \
for (__declare, *CONNECT3(__using_, __LINE__,_ptr) = NULL; \
CONNECT3(__using_, __LINE__,_ptr)++ == NULL; \
)
#define __using2(__declare, __on_leave_expr) \
for (__declare, *CONNECT3(__using_, __LINE__,_ptr) = NULL; \
CONNECT3(__using_, __LINE__,_ptr)++ == NULL; \
(__on_leave_expr) \
)
#define __using3(__declare, __on_enter_expr, __on_leave_expr) \
for (__declare, *CONNECT3(__using_, __LINE__,_ptr) = NULL; \
CONNECT3(__using_, __LINE__,_ptr)++ == NULL ? \
((__on_enter_expr),1) : 0; \
(__on_leave_expr) \
)
#define __using4(__dcl1, __dcl2, __on_enter_expr, __on_leave_expr) \
for (__dcl1, __dcl2, *CONNECT3(__using_, __LINE__,_ptr) = NULL; \
CONNECT3(__using_, __LINE__,_ptr)++ == NULL ? \
((__on_enter_expr),1) : 0; \
(__on_leave_expr) \
)
#define using(...) \
CONNECT2(__using, __PLOOC_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#undef __with2
#undef __with3
#undef with
#define __with2(__type, __addr) \
using(__type *_=(__addr))
#define __with3(__type, __addr, __item) \
using(__type *_=(__addr), *__item = _, _=_,_=_ )
#define with(...) \
CONNECT2(__with, __PLOOC_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#undef _
#ifndef dimof
# define dimof(__array) (sizeof(__array)/sizeof(__array[0]))
#endif
#define SAFE_NAME(__NAME) CONNECT3(__,__NAME,__LINE__)
#undef foreach2
#undef foreach3
#undef foreach
#define foreach2(__type, __array) \
using(__type *_ = __array) \
for ( uint_fast32_t SAFE_NAME(count) = dimof(__array); \
SAFE_NAME(count) > 0; \
_++, SAFE_NAME(count)-- \
)
#define foreach3(__type, __array, __item) \
using(__type *_ = __array, *__item = _, _ = _, _ = _ ) \
for ( uint_fast32_t SAFE_NAME(count) = dimof(__array); \
SAFE_NAME(count) > 0; \
_++, __item = _, SAFE_NAME(count)-- \
)
#define foreach(...) \
CONNECT2(foreach, __PLOOC_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#ifndef safe_atom_code
# define safe_atom_code() \
using( perfc_global_interrupt_status_t SAFE_NAME(temp) = \
perfc_port_disable_global_interrupt(), \
perfc_port_resume_global_interrupt(SAFE_NAME(temp)))
#endif
#ifndef __IRQ_SAFE
# define __IRQ_SAFE \
using( perfc_global_interrupt_status_t SAFE_NAME(temp) = \
perfc_port_disable_global_interrupt(), \
perfc_port_resume_global_interrupt(SAFE_NAME(temp)))
#endif
#ifndef __perf_counter_printf__
# define __perf_counter_printf__ printf
#endif
#if __PLOOC_VA_NUM_ARGS() != 0
#warning Please enable GNU extensions, it is required by __cycleof__() and \
__super_loop_monitor__()
#endif
#if defined(__PERF_COUNTER_CFG_USE_SYSTICK_WRAPPER__)
# if defined(__IS_COMPILER_ARM_COMPILER_5__) && __IS_COMPILER_ARM_COMPILER_5__
# pragma import(__ensure_systick_wrapper)
# elif (defined(__GNUC__) || defined(__clang__)) \
&& (!defined(__IS_COMPILER_IAR__) || !__IS_COMPILER_IAR__)
__asm(".global __ensure_systick_wrapper\n\t");
# endif
#endif
/*! @} */
/*============================ MACROFIED FUNCTIONS ===========================*/
/*!
* \addtogroup gBasic 1 Basic
* @{
*/
/*!
* \brief measure the cycle count of a given code segment
* \param[in] __STR a description string for the measurement
* \param[in] ... an optional code segement, in which we can read the measured
* result from __cycle_count__.
* \details Here is an example:
E.g.
\code
__cycleof__("printf") {
printf("hello world\r\n");
}
\endcode
*/
#define __cycleof__(__STR, ...) \
using(int64_t _ = get_system_ticks(), __cycle_count__ = _, \
_=_, { \
_ = get_system_ticks() - _ - g_nOffset; \
__cycle_count__ = _; \
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
__perf_counter_printf__("\r\n"); \
__perf_counter_printf__("-[Cycle Report]"); \
__perf_counter_printf__( \
"--------------------------------------------\r\n"); \
__perf_counter_printf__( \
__STR " total cycle count: %ld [%016lx]\r\n", \
(long)_, (long)_); \
} else { \
__VA_ARGS__ \
}; \
})
/*!
* \brief measure the cpu usage for a given code segment and print out the
* result in percentage.
* \param[in] __CNT generate result on every given iterations
* \param[in] ... an optional code segement, in which we can read the measured
* result from __usage__ which is a float value.
* \details Here is an example, 50% cpu time:
E.g.
\code
while (1) {
__cpu_time__(100) {
delay_us(5000);
}
delay_us(5000);
}
\endcode
*/
#define __cpu_time__(__CNT, ...) \
static int64_t SAFE_NAME(s_lTimestamp) = 0, SAFE_NAME(s_lTotal) = 0; \
static uint32_t s_wLoopCounter = (__CNT); \
using(float __usage__ = 0, ({ \
if (0 == s_wLoopCounter) { \
__usage__ = (float)((double)SAFE_NAME(s_lTotal) \
/ (double)( get_system_ticks() \
- SAFE_NAME(s_lTimestamp))); \
__usage__ *= 100.0f; \
SAFE_NAME(s_lTimestamp) = 0; \
SAFE_NAME(s_lTotal) = 0; \
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
__perf_counter_printf__("CPU Usage %3.2f%%\r\n", (double)__usage__); \
} else { \
__VA_ARGS__ \
} \
} \
if (0 == SAFE_NAME(s_lTimestamp)) { \
SAFE_NAME(s_lTimestamp) = get_system_ticks(); \
s_wLoopCounter = (__CNT); \
} \
start_task_cycle_counter();}), \
({SAFE_NAME(s_lTotal) += stop_task_cycle_counter(); \
s_wLoopCounter--;}))
/*!
* \addtogroup gBasicTimerService 1.2 Timer Service
* \ingroup gBasic
* @{
*/
/*!
* \brief should not use
*/
#define perfc_is_time_out_ms0() true
/*!
* \brief set an alarm with given period in ms and check the status
*
* \param[in] __ms a time period in millisecond
* \param[in] __timestamp_ptr an optional timestamp holder
* \param[in] __auto_reload whether starting next period after a timeout event
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_ms3(__ms, __timestamp_ptr, __auto_reload) \
({ static int64_t SAFE_NAME(s_lTimestamp); (void)SAFE_NAME(s_lTimestamp); \
__perfc_is_time_out(perfc_convert_ms_to_ticks(__ms), \
(__timestamp_ptr), (__auto_reload));})
/*!
* \brief set an alarm with given period in ms and check the status
*
* \param[in] __ms a time period in millisecond
* \param[in] __timestamp_ptr an optional timestamp holder
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_ms2(__ms, __timestamp_ptr) \
perfc_is_time_out_ms3((__ms), (__timestamp_ptr), true)
/*!
* \brief set an alarm with given period in ms and check the status
*
* \param[in] __ms a time period in millisecond
* \param[in] __timestamp_ptr an optional timestamp holder
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_ms1(__ms) \
perfc_is_time_out_ms3((__ms), &SAFE_NAME(s_lTimestamp), true)
/*!
* \brief set an alarm with given period in ms and check the status
*
* \param[in] __ms a time period in millisecond
* \param[in] ... an optional timestamp holder
* \param[in] ... an optional indicator for whether starting next period after a timeout event
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_ms(...) \
CONNECT2(perfc_is_time_out_ms, __PLOOC_VA_NUM_ARGS(__VA_ARGS__)) \
(__VA_ARGS__)
/*!
* \brief set an alarm with given period in us and check the status
*
* \param[in] __us a time period in microsecond
* \param[in] __timestamp_ptr an optional timestamp holder
* \param[in] __auto_reload whether starting next period after a timeout event
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_us3(__us, __timestamp_ptr, __auto_reload) \
({ static int64_t SAFE_NAME(s_lTimestamp); (void)SAFE_NAME(s_lTimestamp); \
__perfc_is_time_out(perfc_convert_us_to_ticks(__us), \
(__timestamp_ptr), (__auto_reload));})
/*!
* \brief set an alarm with given period in us and check the status
*
* \param[in] __us a time period in microsecond
* \param[in] __timestamp_ptr an optional timestamp holder
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_us2(__us, __timestamp_ptr) \
perfc_is_time_out_us3((__us), (__timestamp_ptr), true)
/*!
* \brief set an alarm with given period in us and check the status
*
* \param[in] __us a time period in microsecond
* \param[in] __timestamp_ptr an optional timestamp holder
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_us1(__us) \
perfc_is_time_out_us3((__us), &SAFE_NAME(s_lTimestamp), true)
/*!
* \brief set an alarm with given period in us and check the status
*
* \param[in] __us a time period in microsecond
* \param[in] ... an optional timestamp holder
* \param[in] ... an optional indicator for whether starting next period after a timeout event
*
* \return bool whether it is timeout
*/
#define perfc_is_time_out_us(...) \
CONNECT2(perfc_is_time_out_us, __PLOOC_VA_NUM_ARGS(__VA_ARGS__)) \
(__VA_ARGS__)
/*! @} */
/*! @} */
/*!
* \addtogroup gRTOS 2 RTOS Support
* @{
*/
#define __super_loop_monitor__(__N, ...) \
using( \
struct { \
int64_t lStart; \
int64_t lTaskUsedCycles; \
int64_t lTimeElapsed; \
} __cpu_usage__ = {.lStart = get_system_ticks()}) \
using(int SAFE_NAME(cnt) = (__N)) \
for(start_task_cycle_counter();; ({ \
if (!(--SAFE_NAME(cnt))) { \
__cpu_usage__.lTimeElapsed \
= get_system_ticks() - __cpu_usage__.lStart - g_nOffset; \
__cpu_usage__.lTaskUsedCycles = stop_task_cycle_counter(); \
\
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
__perf_counter_printf__( \
"%s CPU Usage %2.3f%%\r\n", __func__, \
(float)((double)__cpu_usage__.lTaskUsedCycles * 100.0 / \
(double)__cpu_usage__.lTimeElapsed)); \
} else { \
__VA_ARGS__; \
} \
SAFE_NAME(cnt) = (__N); \
__cpu_usage__.lStart = get_system_ticks(); \
start_task_cycle_counter(); \
}; \
}))
/*============================ TYPES =========================================*/
typedef struct {
int64_t lStart;
int64_t lUsedTotal;
int32_t nUsedRecent;
uint16_t hwActiveCount;
uint16_t : 15;
uint16_t bEnabled : 1;
} task_cycle_info_t;
typedef struct task_cycle_info_agent_t task_cycle_info_agent_t;
struct task_cycle_info_agent_t {
task_cycle_info_t *ptInfo;
task_cycle_info_agent_t *ptNext;
task_cycle_info_agent_t *ptPrev;
};
/*! @} */
/*============================ GLOBAL VARIABLES ==============================*/
extern volatile int64_t g_lLastTimeStamp;
extern volatile int32_t g_nOffset;
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
/*!
* \addtogroup gBasicTicks 1.1 Ticks APIs
* \ingroup gBasic
* @{
*/
/*!
* \brief get the elapsed cycles since perf_counter is initialised
* \return int64_t the elpased cycles
*/
__attribute__((noinline))
extern int64_t get_system_ticks(void);
#ifdef __PERF_CNT_USE_LONG_CLOCK__
/*! \note the prototype of this clock() is different from the one defined in
*! time.h. As clock_t is usually defined as unsigned int, it is
*! not big enough in Cortex-M system to hold a time-stamp. clock()
*! defined here returns the timestamp since the begining of main()
*! and its unit is clock cycle (rather than 1ms). Hence, for a system
*! running under several hundreds MHz or even 1GHz, e.g. RT10xx from
*! NXP, it is very easy to see a counter overflow as clock_t is
*! defined as uint32_t in timer.h.
*! Since we are not allowed to change the defintion of clock_t in
*! official header file, i.e. time.h, I use a compatible prototype
*! after I checked the AAPCS spec. So, the return of the clock() is
*! int64_t, which will use the R0 to store the lower 32bits and R1
*! to store the higher 32bits. When you are using the prototype from
*! timer.h, caller will only take the lower 32bits stored in R0 and
*! the higher 32bits stored in R1 will be ignored.
*!
*! If you want to use the non-overflow version of this clock(), please
*! 1) define the MACRO: __PERF_CNT_USE_LONG_CLOCK__ in your project
*! and 2) do not include system header file <time.h>
*!
*/
#if !defined(__IS_COMPILER_IAR__)
__attribute__((nothrow))
#endif
__attribute__((noinline))
extern int64_t clock(void);
#endif
/*!
* \brief try to set a start pointer for the performance counter
*/
static inline
void start_cycle_counter(void)
{
g_lLastTimeStamp = get_system_ticks();
}
/*!
* \brief calculate the elapsed cycle count since the last start point
* \note you can have multiple stop_cycle_counter following one start point
* \return int32_t the elapsed cycle count
*/
static inline
int64_t stop_cycle_counter(void)
{
int64_t lTemp = (get_system_ticks() - g_lLastTimeStamp);
return lTemp - g_nOffset;
}
/*! @} */
/*!
* \addtogroup gBasicTimerService 1.2 Timer Service
* \ingroup gBasic
* @{
*/
/*!
* \brief get the elapsed milliseconds since perf_counter is initialised
* \return uint32_t the elapsed milliseconds
*/
extern uint32_t get_system_ms(void);
/*!
* \brief get the elapsed microsecond since perf_counter is initialised
* \return uint32_t the elapsed microsecond
*/
extern uint32_t get_system_us(void);
/*!
* \brief delay specified time in microsecond
* \param[in] wUs time in microsecond
*/
extern void delay_us(uint32_t wUs);
/*!
* \brief delay specified time in millisecond
* \param[in] wMs time in millisecond
*/
extern void delay_ms(uint32_t nMs);
/*!
* \brief convert ticks of a reference timer to millisecond
*
* \param[in] lTick the tick count
* \return int64_t the millisecond
*/
extern
int64_t perfc_convert_ticks_to_ms(int64_t lTick);
/*!
* \brief convert millisecond into ticks of the reference timer
*
* \param[in] wMS the target time in millisecond
* \return int64_t the ticks
*/
extern
int64_t perfc_convert_ms_to_ticks(uint32_t wMS);
/*!
* \brief convert ticks of a reference timer to microsecond
*
* \param[in] lTick the tick count
* \return int64_t the microsecond
*/
extern
int64_t perfc_convert_ticks_to_us(int64_t lTick);
/*!
* \brief convert microsecond into ticks of the reference timer
*
* \param[in] wUS the target time in microsecond
* \return int64_t the ticks
*/
extern
int64_t perfc_convert_us_to_ticks(uint32_t wUS);
/*!
* \brief set an alarm with given period and check the status
*
* \param[in] lPeriod a time period in ticks
* \param[in] plTimestamp a pointer points to an int64_t integer, if NULL is
* passed, an static local variable inside the function will be used
* \param[in] bAutoReload whether starting next period after a timeout event.
* \return bool whether it is timeout or not
*/
extern
bool __perfc_is_time_out(int64_t lPeriod, int64_t *plTimestamp, bool bAutoReload);
/*! @} */
/*!
* \addtogroup gRTOS 2 RTOS Support
* @{
*/
#if defined(__PERF_CNT_USE_RTOS__)
/*! \brief initialize the default virtual cycle counter for the current task
*/
extern void init_task_cycle_counter(void);
/*! \brief check whether the task stack canary is safe or not
* \retval false likely to be a stack-overflow
* \retval true task stack is safe
*/
extern
bool perfc_check_task_stack_canary_safe(void);
/*! \brief provide cycle information for target task
* \details Support RTOS List:
* - RTX5
* - RT-Thread
* - ThreadX
* - FreeRTOS
*
* \return task_cycle_info_t* the cycle info object passed to this function
*/
extern task_cycle_info_t * get_rtos_task_cycle_info(void);
/*!
* \brief intialize a given task_cycle_info_t object and enable it before
* registering it.
* \return task_cycle_info_t* the cycle info object passed to this function
*/
extern task_cycle_info_t *init_task_cycle_info(task_cycle_info_t *ptInfo);
/*! \brief enable a given task_cycle_info_t object
*
* \param[in] ptInfo the address of target task_cycle_info_t object
* \return bool previous status
*/
extern bool enable_task_cycle_info(task_cycle_info_t *ptInfo);
/*! \brief disable a given task_cycle_info_t object
*
* \param[in] ptInfo the address of target task_cycle_info_t object
* \return bool previous status
*/
extern bool disable_task_cycle_info(task_cycle_info_t *ptInfo);
/*! \brief resume the enabled status of a given task_cycle_info_t object
*
* \param[in] ptInfo the address of target task_cycle_info_t object
* \param[in] bEnabledStatus the previous status
*/
extern
void resume_task_cycle_info(task_cycle_info_t *ptInfo, bool bEnabledStatus);
/*!
* \brief register a global virtual cycle counter agent to the current task
* \param[in] ptInfo the address of target task_cycle_info_t object
* \param[in] ptAgent an list node for the task_cycle_info_t object
* \note the ptAgent it is better to be allocated as a static variable, global
* variable or comes from heap or pool
*
* \return task_cycle_info_agent_t* the agent passed to this function
*/
extern
task_cycle_info_agent_t *register_task_cycle_agent(
task_cycle_info_t *ptInfo,
task_cycle_info_agent_t *ptAgent);
/*!
* \brief remove a global virtual cycle counter agent from the current task
* \param[in] ptAgent the list node currently in use
* \return task_cycle_info_agent_t* the agent passed to this function
*/
extern
task_cycle_info_agent_t *
unregister_task_cycle_agent(task_cycle_info_agent_t *ptAgent);
/*! \brief reset and start the virtual cycle counter for the current task
*
* \param[in] ptInfo the target task_cycle_info_t object
*/
__attribute__((noinline))
extern void __start_task_cycle_counter(task_cycle_info_t *ptInfo);
/*! \brief calculate the elapsed cycle count for current task since the last
* start point
*
* \note you can call stop_cycle_counter() multiple times following one
* start_task_cycle_counter()
*
* \param[in] ptInfo the target task_cycle_info_t object
*
* \note When ptInfo is NULL, it returns current task cycle info, when ptInfo
* is non-NULL, it returns the total used cycles of the specified
* task_cycle_info_t object.
*
* \return int64_t the elapsed cycle count.
*/
__attribute__((noinline))
extern int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo);
#define start_task_cycle_counter(...) \
__start_task_cycle_counter((NULL,##__VA_ARGS__))
#define stop_task_cycle_counter(...) \
__stop_task_cycle_counter((NULL,##__VA_ARGS__))
#elif !defined(__IMPLEMENT_PERF_COUNTER)
# define start_task_cycle_counter(...) start_cycle_counter()
# define stop_task_cycle_counter(...) stop_cycle_counter()
# define init_task_cycle_counter()
# define register_task_cycle_agent(...)
# define unregister_task_cycle_agent(...)
# define init_task_cycle_info(...) (NULL)
# define enable_task_cycle_info(...) (false)
# define disable_task_cycle_info(...) (false)
# define resume_task_cycle_info(...)
# define perfc_check_task_stack_canary_safe() (false)
#endif
/*! @} */
/*!
* \addtogroup gBasic 1 Basic
* @{
*/
/*----------------------------------------------------------------------------*
* Please ignore the following APIs unless you have encountered some known *
* special conditions *
*----------------------------------------------------------------------------*/
/*! \brief initialise cycle counter service
* \note - don't forget to tell the function whether the systick is already
* used by user applications.
* Don't worry, this cycle counter service won't affect your existing
* systick service.
*
* \note - Usually the perf_counter can initialise itself with the help of
* __attribute__((constructor(255))), this works fine in Arm Compiler
* 5 (armcc), Arm Compiler 6 (armclang), arm gcc and llvm. It doesn't
* work for IAR. So, when you are using IAR, please call this function
* manually to initialise the perf_counter service.
*
* \note - Perf_counter library assumes that:
* 1. Your project has already using SysTick
* 2. It assumes that you have already implemented the SysTick_Handler
* 3. It assumes that you have enabled the exception handling for
* SysTick.
* If these are not the case, please:
* 1. Add an empty SysTick_Handler to your project if you don't have
* one
* 2. Make sure you have the SysTick Exception handling enabled
* 3. And call function init_cycle_counter(false) if you doesn't
* use SysTick in your project at all.
*
* \param[in] bIsSysTickOccupied A boolean value which indicates whether SysTick
* is already used by user application.
*/
extern void init_cycle_counter(bool bIsSysTickOccupied);
/*!
* \brief a system timer handler inserted to the SysTick_Handler
*
* \note - if you are using a compiler other than armcc or armclang, e.g. iar,
* arm gcc etc, the systick_wrapper_ual.o doesn't work with the linker
* of your target toolchain as it use the $Super$$ which is only supported
* by armlink. For this condition, you have to manually put this function
* into your existing SysTick_Handler to make the perf_counter library
* work.
*
* \note - if you are using Arm Compiler 5 (armcc) or Arm Compiler 6 (armclang)
* you do NOT have to insert this function into your SysTick_Handler,
* the systick_wrapper_ual.s will do the work for you.
*/
extern void user_code_insert_to_systick_handler(void);
/*!
* \brief update perf_counter as SystemCoreClock has been updated.
*/
extern void update_perf_counter(void);
/*!
* \brief prepare for reconfiguration of SysTick timer.
*
* \note some systems (e.g. FreeRTOS) might reconfigure the systick timer to
* fulfil the requirement of their feature. To support this, just
* before the reconfiguration, please call this function in order
* to make the perf_counter works correctly later.
*
* \note after the reconfiguration, please call update_perf_counter() to apply
* the changes to perf_counter.
*
* \note this function will stop the SysTick, clear the pending bit and set
* the Load register and Current Value register to zero.
*/
extern void before_cycle_counter_reconfiguration(void);
/*! @} */
/*!
* \addtogroup gBenchmark 3 Benchmark
* @{
*/
#ifdef __PERF_COUNTER_COREMARK__
/*!
* \brief entry for coremark
*/
void coremark_main(void);
#endif
/*! @} */
//#if defined(__clang__)
//# pragma clang diagnostic pop
//#elif defined(__IS_COMPILER_GCC__)
//# pragma GCC diagnostic pop
//#endif
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

View File

@ -1,240 +0,0 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/*============================ INCLUDES ======================================*/
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "stack_macros.h"
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
for the header files above, but not in this file, in order to generate the
correct privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
#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)
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
int64_t lLastTimeStamp;
task_cycle_info_agent_t tList;
uint32_t wMagicWord;
} ;
/*============================ TYPES =========================================*/
/*
* Task control block. A task control block (TCB) is allocated for each task,
* and stores task state information, including a pointer to the task's context
* (the task's run time environment, including register values)
*/
typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */
{
volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
#endif
ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
ListItem_t xEventListItem; /*< Used to reference a task from an event list. */
UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */
StackType_t *pxStack; /*< Points to the start of the stack. */
char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t *pxEndOfStack; /*< Points to the highest valid address for the stack. */
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
#endif
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */
UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */
UBaseType_t uxMutexesHeld;
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
/* Allocate a Newlib reent structure that is specific to this task.
Note Newlib support has been included by popular demand, but is not
used by the FreeRTOS maintainers themselves. FreeRTOS is not
responsible for resulting newlib operation. User must be familiar with
newlib and must provide system-wide implementations of the necessary
stubs. Be warned that (at the time of writing) the current newlib design
implements a system-wide malloc() that must be provided with locks.
See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
for additional information. */
struct _reent xNewLib_reent;
#endif
#if( configUSE_TASK_NOTIFICATIONS == 1 )
volatile uint32_t ulNotifiedValue;
volatile uint8_t ucNotifyState;
#endif
/* See the comments in FreeRTOS.h with the definition of
tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */
#endif
#if( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
#if( configUSE_POSIX_ERRNO == 1 )
int iTaskErrno;
#endif
} tskTCB;
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
below to enable the use of older kernel aware debuggers. */
typedef tskTCB TCB_t;
/*lint -save -e956 A manual analysis and inspection has been used to determine
which static variables must be declared volatile. */
PRIVILEGED_DATA
extern TCB_t * volatile pxCurrentTCB;
/*! \note if you aren't using perf_counter inside KEIL with RTE, please create
*! a header file called "Pre_Include_Global.h", copy the following
*! content into the header file and and put following option
*! to your command line (supposing you are using arm compiler 6):
*! -include "Pre_Include_Global.h"
*/
/*
//! \brief Enable RTOS Patch for perf_counter
#define __PERF_CNT_USE_RTOS__
#define traceTASK_SWITCHED_OUT_DISABLE
#define traceTASK_SWITCHED_IN_DISABLE
extern void __freertos_evr_on_task_switched_out (void *ptTCB);
extern void __freertos_evr_on_task_switched_in(void *ptTCB, unsigned int uxTopPriority) ;
# define traceTASK_SWITCHED_OUT() \
__freertos_evr_on_task_switched_out(pxCurrentTCB)
# define traceTASK_SWITCHED_IN() \
__freertos_evr_on_task_switched_in(pxCurrentTCB, uxTopReadyPriority)
*/
/*============================ 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(RTE_Compiler_EventRecorder)
# include "EventRecorder.h"
#endif
#define EvtFreeRTOSTasksNo (0xF0U)
#define EvtFreeRTOSTasks_TaskSwitchedOut \
EventID(EventLevelOp, EvtFreeRTOSTasksNo, 0x0BU)
#define EvtFreeRTOSTasks_TaskSwitchedIn \
EventID(EventLevelOp, EvtFreeRTOSTasksNo, 0x0CU)
void __freertos_evr_on_task_switched_out (void *ptTCB) {
#if defined(RTE_Compiler_EventRecorder)
EventRecord2(EvtFreeRTOSTasks_TaskSwitchedOut, (uint32_t)ptTCB, 0U);
#else
(void)pxCurrentTCB;
#endif
__on_context_switch_out(((TCB_t *)ptTCB)->pxStack);
}
void __freertos_evr_on_task_switched_in(void *ptTCB, uint32_t uxTopPriority) {
#if defined(RTE_Compiler_EventRecorder)
EventRecord2(EvtFreeRTOSTasks_TaskSwitchedIn, (uint32_t)ptTCB, uxTopPriority);
#else
(void)pxCurrentTCB;
(void)uxTopPriority;
#endif
__on_context_switch_in(((TCB_t *)ptTCB)->pxStack);
}
task_cycle_info_t * get_rtos_task_cycle_info(void)
{
return &(((struct __task_cycle_info_t *)pxCurrentTCB->pxStack)->tInfo);
}

View File

@ -1,112 +0,0 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/*============================ INCLUDES ======================================*/
#include <rtthread.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)
struct __task_cycle_info_t {
task_cycle_info_t tInfo;
int64_t lLastTimeStamp;
task_cycle_info_agent_t tList;
uint32_t wMagicWord;
} ;
#ifndef RT_USING_HOOK
#error "In order to use perf_counter:RT-Thread-Patch, please define RT_USING_HOOK \
in rtconfig.h. If you don't want to use this patch, please un-select it in RTE."
#endif
/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
extern void __on_context_switch_in(uint32_t *pwStack);
extern void __on_context_switch_out(uint32_t *pwStack);
extern struct rt_thread *rt_current_thread;
/*============================ IMPLEMENTATION ================================*/
void __rt_thread_scheduler_hook(struct rt_thread *from, struct rt_thread *to)
{
if (NULL != from) {
__on_context_switch_out(from->stack_addr);
}
__on_context_switch_in(to->stack_addr);
}
task_cycle_info_t * get_rtos_task_cycle_info(void)
{
return &(((struct __task_cycle_info_t *)rt_current_thread->stack_addr)->tInfo);
}
void __perf_os_patch_init(void)
{
#if defined(RTTHREAD_VERSION) && (RTTHREAD_VERSION >= (4 * 10000))
rt_tick_sethook(user_code_insert_to_systick_handler);
#endif
#if !defined(PKG_USING_PERF_COUNTER) || (defined(PKG_PERF_COUNTER_USING_THREAD_STATISTIC))
rt_scheduler_sethook(__rt_thread_scheduler_hook);
#endif
}
#ifdef PKG_USING_PERF_COUNTER
#if defined(RTTHREAD_VERSION) && (RTTHREAD_VERSION >= (4 * 10000))
void __ensure_systick_wrapper(void)
{
}
#endif
#define DBG_TAG "perf_counter"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static int _perf_counter_init(void)
{
extern uint32_t SystemCoreClock;
init_cycle_counter(true);
LOG_I("perf_counter init, SystemCoreClock:%d", SystemCoreClock);
return 0;
}
INIT_PREV_EXPORT(_perf_counter_init);
#endif /* PKG_USING_PERF_COUNTER */

View File

@ -1,99 +0,0 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/*============================ INCLUDES ======================================*/
#include "rtx_os.h"
#include "perf_counter.h"
#include "cmsis_compiler.h"
#include "rtx_evr.h" // RTX Event Recorder definitions
/*============================ 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 {
task_cycle_info_t tInfo;
int64_t lLastTimeStamp;
task_cycle_info_agent_t tList;
uint32_t wMagicWord;
} ;
/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
extern void __on_context_switch_in(uint32_t *pwStack);
extern void __on_context_switch_out(uint32_t *pwStack);
/*============================ IMPLEMENTATION ================================*/
/*! \brief wrapper function for rtos context switching */
void __on_context_switch (osRtxThread_t *thread)
{
if (NULL != osRtxInfo.thread.run.curr) {
__on_context_switch_out(osRtxInfo.thread.run.curr->stack_mem);
}
__on_context_switch_in(thread->stack_mem);
}
__attribute__((used))
void EvrRtxThreadSwitched (osThreadId_t thread_id)
{
__on_context_switch((osRtxThread_t *)thread_id);
#if defined(RTE_Compiler_EventRecorder)
# define EvtRtxThreadSwitched \
EventID(EventLevelOp, EvtRtxThreadNo, 0x19U)
(void)EventRecord2(EvtRtxThreadSwitched, (uint32_t)thread_id, 0U);
#else
(void)thread_id;
#endif
}
task_cycle_info_t * get_rtos_task_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);
}

View File

@ -1,128 +0,0 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/*============================ 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)
#if defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) && defined(TX_EXECUTION_PROFILE_ENABLE)
#error In order to use perf_counter:ThreadX-Patch, please define \
TX_ENABLE_EXECUTION_CHANGE_NOTIFY or TX_EXECUTION_PROFILE_ENABLE \
in the project configuration, according to the version of thread.\
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;
task_cycle_info_agent_t tList;
uint32_t wMagicWord;
} ;
/*============================ 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_in(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);
if (NULL != ptThread) {
__on_context_switch_out(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
}
#if !defined(TX_EXECUTION_PROFILE_ENABLE)
void _tx_execution_isr_exit(void)
{
}
void _tx_execution_isr_enter(void)
{
}
#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);
}