mirror of
https://github.com/GorgonMeducer/perf_counter.git
synced 2025-01-17 19:13:03 +08:00
format code
This commit is contained in:
parent
7f4bc4c59f
commit
2bff1d5c43
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@ -8,7 +8,7 @@
|
||||
* 2017-07-24 Tanek the first version
|
||||
* 2018-11-12 Ernest Chen modify copyright
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
@ -20,12 +20,12 @@
|
||||
#define _SYSTICK_CALIB (*(rt_uint32_t *)(_SCB_BASE + 0xC))
|
||||
#define _SYSTICK_PRI (*(rt_uint8_t *)(0xE000ED23UL))
|
||||
|
||||
// Updates the variable SystemCoreClock and must be called
|
||||
// Updates the variable SystemCoreClock and must be called
|
||||
// whenever the core clock is changed during program execution.
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
// Holds the system core clock, which is the system clock
|
||||
// frequency supplied to the SysTick timer and the processor
|
||||
// Holds the system core clock, which is the system clock
|
||||
// frequency supplied to the SysTick timer and the processor
|
||||
// core clock.
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
@ -35,12 +35,12 @@ static uint32_t _SysTick_Config(rt_uint32_t ticks)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
_SYSTICK_LOAD = ticks - 1;
|
||||
|
||||
_SYSTICK_LOAD = ticks - 1;
|
||||
_SYSTICK_PRI = 0xFF;
|
||||
_SYSTICK_VAL = 0;
|
||||
_SYSTICK_CTRL = 0x07;
|
||||
|
||||
_SYSTICK_CTRL = 0x07;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ void rt_hw_board_init()
|
||||
{
|
||||
/* System Clock Update */
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
|
||||
/* System Tick Configuration */
|
||||
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Auto generated Run-Time-Environment Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'gcc_example'
|
||||
* Target: 'example'
|
||||
* Project: 'gcc_example'
|
||||
* Target: 'example'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Auto generated Run-Time-Environment Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'example'
|
||||
* Target: 'example_arm compiler_5'
|
||||
* Project: 'example'
|
||||
* Target: 'example_arm compiler_5'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Auto generated Run-Time-Environment Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'example'
|
||||
* Target: 'example_arm_compiler_6'
|
||||
* Project: 'example'
|
||||
* Target: 'example_arm_compiler_6'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Auto generated Run-Time-Environment Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'gcc_example'
|
||||
* Target: 'gcc_lib'
|
||||
* Project: 'gcc_example'
|
||||
* Target: 'gcc_lib'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* Auto generated Run-Time-Environment Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'example'
|
||||
* Target: 'library'
|
||||
* Project: 'example'
|
||||
* Target: 'library'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
|
@ -43,7 +43,7 @@ typedef struct example_lv1_t {
|
||||
|
||||
|
||||
typedef struct example_lv0_t {
|
||||
|
||||
|
||||
uint32_t wA;
|
||||
uint16_t hwB;
|
||||
uint8_t chC;
|
||||
@ -66,15 +66,15 @@ static example_lv0_t s_tItem[8] = {
|
||||
/*----------------------------------------------------------------------------
|
||||
Main function
|
||||
*----------------------------------------------------------------------------*/
|
||||
int main (void)
|
||||
int main (void)
|
||||
{
|
||||
int32_t iCycleResult = 0;
|
||||
|
||||
|
||||
/*! demo of using() block */
|
||||
using(int a = 0,printf("========= On Enter =======\r\n"),
|
||||
using(int a = 0,printf("========= On Enter =======\r\n"),
|
||||
printf("========= On Leave =======\r\n")) {
|
||||
printf("\t In Body a=%d \r\n", ++a);
|
||||
}
|
||||
}
|
||||
|
||||
__cycleof__("Calibration") {}
|
||||
|
||||
@ -88,14 +88,14 @@ int main (void)
|
||||
}
|
||||
|
||||
/* measure cycles and store it in a dedicated variable without printf */
|
||||
__cycleof__("delay_us(1000ul)",
|
||||
__cycleof__("delay_us(1000ul)",
|
||||
/* insert code to __cycleof__ body, "{}" can be omitted */
|
||||
{
|
||||
iCycleResult = __cycle_count__; /*< "__cycle_count__" stores the result */
|
||||
}) {
|
||||
delay_us(1000ul);
|
||||
}
|
||||
|
||||
|
||||
printf("\r\n delay_us(1000ul) takes %d cycles\r\n", (int)iCycleResult);
|
||||
|
||||
/*! demo of with block */
|
||||
@ -103,7 +103,7 @@ int main (void)
|
||||
_->wA = 1;
|
||||
_->hwB = 2;
|
||||
_->chC = 3;
|
||||
|
||||
|
||||
with(example_lv1_t, &pitem->tLV1) {
|
||||
_->wLV1A = 4;
|
||||
_->hwLV1B = 5;
|
||||
@ -119,7 +119,7 @@ int main (void)
|
||||
}
|
||||
printf("used clock cycle: %d", (int32_t)(get_system_ticks() - tStart));
|
||||
} while(0);
|
||||
|
||||
|
||||
while (1) {
|
||||
printf("\r\nhello world\r\n");
|
||||
delay_ms(1000);
|
||||
|
@ -38,7 +38,7 @@ static volatile uint32_t s_wMSCounter = 0;
|
||||
SysTick / Timer0 IRQ Handler
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
void SysTick_Handler (void)
|
||||
void SysTick_Handler (void)
|
||||
{
|
||||
if (s_wMSCounter) {
|
||||
s_wMSCounter--;
|
||||
@ -53,11 +53,11 @@ __attribute__((constructor(101)))
|
||||
void platform_init(void)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
|
||||
uart_config(25000000ul);
|
||||
|
||||
|
||||
/* Generate interrupt each 1 ms */
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,8 +116,8 @@ typedef struct
|
||||
/* ================ Peripheral declaration ================ */
|
||||
/* ================================================================================ */
|
||||
|
||||
//#define CMSDK_UART0_BASE_ADDRESS (0x41303000ul)
|
||||
#define CMSDK_UART0_BASE_ADDRESS (0x40004000ul)
|
||||
//#define CMSDK_UART0_BASE_ADDRESS (0x41303000ul)
|
||||
#define CMSDK_UART0_BASE_ADDRESS (0x40004000ul)
|
||||
#define CMSDK_UART0 ((CMSDK_UART_TypeDef *) CMSDK_UART0_BASE_ADDRESS)
|
||||
|
||||
|
||||
@ -125,7 +125,7 @@ void uart_config(uint32_t wUARTFrequency)
|
||||
{
|
||||
CMSDK_UART0->CTRL = 0; /* Disable UART when changing configuration */
|
||||
CMSDK_UART0->BAUDDIV = wUARTFrequency / 115200ul; /* 25MHz / 38400 = 651 */
|
||||
CMSDK_UART0->CTRL = CMSDK_UART_CTRL_TXEN_Msk|CMSDK_UART_CTRL_RXEN_Msk;
|
||||
CMSDK_UART0->CTRL = CMSDK_UART_CTRL_TXEN_Msk|CMSDK_UART_CTRL_RXEN_Msk;
|
||||
}
|
||||
|
||||
char stdin_getchar(void)
|
||||
@ -152,26 +152,26 @@ int _write (int fd, char *ptr, int len)
|
||||
do {
|
||||
stdout_putchar(*ptr++);
|
||||
} while(--n);
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int stderr_putchar(char txchar)
|
||||
{
|
||||
return stdout_putchar(txchar);
|
||||
return stdout_putchar(txchar);
|
||||
}
|
||||
|
||||
void ttywrch (int ch)
|
||||
{
|
||||
stdout_putchar(ch);
|
||||
stdout_putchar(ch);
|
||||
}
|
||||
|
||||
|
||||
#define log_str(...) \
|
||||
#define log_str(...) \
|
||||
do { \
|
||||
const char *pchSrc = __VA_ARGS__; \
|
||||
uint_fast16_t hwSize = sizeof(__VA_ARGS__); \
|
||||
@ -184,11 +184,11 @@ __NO_RETURN
|
||||
void _sys_exit(int n)
|
||||
{
|
||||
UNUSED_PARAM(n);
|
||||
log_str("\r\n");
|
||||
log_str("_[TEST COMPLETE]_________________________________________________\r\n");
|
||||
log_str("\r\n\r\n");
|
||||
log_str("\r\n");
|
||||
log_str("_[TEST COMPLETE]_________________________________________________\r\n");
|
||||
log_str("\r\n\r\n");
|
||||
|
||||
while(1) {
|
||||
while(1) {
|
||||
__asm volatile ("nop");
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ extern "C" {
|
||||
#define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \
|
||||
+__PERF_COUNTER_VER_MINOR__ * 100ul \
|
||||
+__PERF_COUNTER_VER_REVISE__)
|
||||
|
||||
|
||||
//! \name The macros to identify the compiler
|
||||
//! @{
|
||||
|
||||
@ -156,21 +156,21 @@ extern "C" {
|
||||
__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 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)
|
||||
__CONNECT6(__A, __B, __C, __D, __E, __F)
|
||||
#define CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
|
||||
__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)
|
||||
__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__)
|
||||
|
||||
@ -197,14 +197,14 @@ extern "C" {
|
||||
((__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__)
|
||||
|
||||
@ -259,7 +259,7 @@ extern "C" {
|
||||
SAFE_NAME(temp2);}), \
|
||||
__set_PRIMASK(SAFE_NAME(temp)))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __IRQ_SAFE
|
||||
# define __IRQ_SAFE \
|
||||
using( uint32_t SAFE_NAME(temp) = \
|
||||
@ -331,7 +331,7 @@ typedef struct {
|
||||
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 {
|
||||
@ -355,11 +355,11 @@ struct task_cycle_info_agent_t {
|
||||
extern bool start_cycle_counter(void);
|
||||
|
||||
/*! \brief calculate the elapsed cycle count since the last start point
|
||||
*!
|
||||
*!
|
||||
*! \note you can have multiple stop_cycle_counter following one start point
|
||||
*!
|
||||
*!
|
||||
*! \return the elapsed cycle count.
|
||||
*/
|
||||
*/
|
||||
extern int32_t stop_cycle_counter(void);
|
||||
|
||||
/* Function : delay specified us with the help from systick
|
||||
@ -375,25 +375,25 @@ extern void delay_ms(int32_t nMs);
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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
|
||||
*! 1) define the MACRO: __PERF_CNT_USE_LONG_CLOCK__ in your project
|
||||
*! and 2) do not include system header file <time.h>
|
||||
*!
|
||||
*/
|
||||
#ifdef __PERF_CNT_USE_LONG_CLOCK__
|
||||
#if !defined(__IS_COMPILER_IAR__)
|
||||
__attribute__((nothrow))
|
||||
__attribute__((nothrow))
|
||||
#endif
|
||||
extern int64_t clock(void);
|
||||
#endif
|
||||
@ -411,27 +411,27 @@ extern void init_task_cycle_counter(void);
|
||||
|
||||
/*! \brief provide cycle information for target task if perf_counter is used
|
||||
*! together with an RTOS in the support list.
|
||||
*!
|
||||
*!
|
||||
*! Support RTOS List:
|
||||
*! - RTX5
|
||||
*/
|
||||
extern task_cycle_info_t * get_rtos_task_cycle_info(void);
|
||||
|
||||
|
||||
/*! \brief intialize a given task_cycle_info_t object and enable it before
|
||||
/*! \brief intialize a given task_cycle_info_t object and enable it before
|
||||
*! registering it.
|
||||
*/
|
||||
extern task_cycle_info_t *init_task_cycle_info(task_cycle_info_t *ptInfo);
|
||||
|
||||
/*! \brief enable a given task_cycle_info_t object
|
||||
*!
|
||||
*!
|
||||
*! \param ptInfo the address of target task_cycle_info_t object
|
||||
*! \return previous status
|
||||
*/
|
||||
extern bool enable_task_cycle_info(task_cycle_info_t *ptInfo);
|
||||
|
||||
/*! \brief disable a given task_cycle_info_t object
|
||||
*!
|
||||
*!
|
||||
*! \param ptInfo the address of target task_cycle_info_t object
|
||||
*! \return previous status
|
||||
*/
|
||||
@ -442,11 +442,11 @@ extern bool disable_task_cycle_info(task_cycle_info_t *ptInfo);
|
||||
*! \param ptInfo the address of target task_cycle_info_t object
|
||||
*! \param bEnabledStatus the previous status
|
||||
*/
|
||||
extern
|
||||
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
|
||||
*!
|
||||
*!
|
||||
*! \note the ptAgent it is better to be allocated as a static variable, global
|
||||
*! variable or comes from heap or pool
|
||||
*/
|
||||
@ -456,7 +456,7 @@ task_cycle_info_agent_t *register_task_cycle_agent(
|
||||
task_cycle_info_agent_t *ptAgent);
|
||||
|
||||
/*! \brief remove a global virtual cycle counter agent from the current task
|
||||
*!
|
||||
*!
|
||||
*/
|
||||
extern
|
||||
task_cycle_info_agent_t *
|
||||
@ -468,16 +468,16 @@ unregister_task_cycle_agent(task_cycle_info_agent_t *ptAgent);
|
||||
*/
|
||||
extern void __start_task_cycle_counter(task_cycle_info_t *ptInfo);
|
||||
|
||||
/*! \brief calculate the elapsed cycle count for current task since the last
|
||||
/*! \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
|
||||
*!
|
||||
*! \note you can call stop_cycle_counter() multiple times following one
|
||||
*! start_task_cycle_counter()
|
||||
*!
|
||||
*! \param 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
|
||||
*! is non-NULL, it returns the total used cycles of the specified
|
||||
*! task_cycle_info_t object.
|
||||
*!
|
||||
*! \return the elapsed cycle count.
|
||||
@ -506,12 +506,12 @@ extern int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo);
|
||||
/*----------------------------------------------------------------------------*
|
||||
* Please ignore the following APIs unless you have encountered some known *
|
||||
* special conditions *
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*! \brief initialise cycle counter service
|
||||
*! and don't forget to tell the function whether the systick is already
|
||||
*! used by user applications.
|
||||
*! used by user applications.
|
||||
*! Don't worry, this cycle counter service won't affect your existing
|
||||
*! systick service.
|
||||
*!
|
||||
@ -524,13 +524,13 @@ extern int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo);
|
||||
*! \note Perf_counter library assumes that:
|
||||
*! a. Your project has already using SysTick
|
||||
*! b. It assumes that you have already implemented the SysTick_Handler
|
||||
*! c. It assumes that you have enabled the exception handling for
|
||||
*! c. It assumes that you have enabled the exception handling for
|
||||
*! SysTick.
|
||||
*! If these are not the case, please:
|
||||
*! a. Add an empty SysTick_Handler to your project if you don't have
|
||||
*! a. Add an empty SysTick_Handler to your project if you don't have
|
||||
*! one
|
||||
*! b. Make sure you have the SysTick Exception handling enabled
|
||||
*! c. And call function init_cycle_counter(false) if you doesn't
|
||||
*! c. And call function init_cycle_counter(false) if you doesn't
|
||||
*! use SysTick in your project at all.
|
||||
*!
|
||||
*! \param bIsSysTickOccupied A boolean value which indicates whether SysTick
|
||||
@ -545,7 +545,7 @@ extern void init_cycle_counter(bool bIsSysTickOccupied);
|
||||
*! 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.
|
||||
|
@ -43,7 +43,7 @@ correct privileged Vs unprivileged linkage and placement. */
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -74,82 +74,82 @@ struct __task_cycle_info_t {
|
||||
* 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. */
|
||||
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. */
|
||||
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
|
||||
#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. */
|
||||
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 ( ( 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 ( 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_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_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 ( 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( 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( 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.
|
||||
#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
|
||||
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
|
||||
#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
|
||||
/* 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( INCLUDE_xTaskAbortDelay == 1 )
|
||||
uint8_t ucDelayAborted;
|
||||
#endif
|
||||
|
||||
#if( configUSE_POSIX_ERRNO == 1 )
|
||||
int iTaskErrno;
|
||||
#endif
|
||||
#if( configUSE_POSIX_ERRNO == 1 )
|
||||
int iTaskErrno;
|
||||
#endif
|
||||
|
||||
} tskTCB;
|
||||
|
||||
@ -159,11 +159,11 @@ 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
|
||||
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
|
||||
/*! \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"
|
||||
@ -172,8 +172,8 @@ extern TCB_t * volatile pxCurrentTCB;
|
||||
/*
|
||||
//! \brief Enable RTOS Patch for perf_counter
|
||||
#define __PERF_CNT_USE_RTOS__
|
||||
|
||||
#define traceTASK_SWITCHED_OUT_DISABLE
|
||||
|
||||
#define traceTASK_SWITCHED_OUT_DISABLE
|
||||
#define traceTASK_SWITCHED_IN_DISABLE
|
||||
|
||||
extern void __freertos_evr_on_task_switched_out (void *ptTCB);
|
||||
@ -216,9 +216,9 @@ void __freertos_evr_on_task_switched_out (void *ptTCB) {
|
||||
#else
|
||||
(void)pxCurrentTCB;
|
||||
#endif
|
||||
|
||||
|
||||
__on_context_switch_out(((TCB_t *)ptTCB)->pxStack);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -229,12 +229,12 @@ void __freertos_evr_on_task_switched_in(void *ptTCB, uint32_t uxTopPriority) {
|
||||
(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);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -71,7 +71,7 @@ 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);
|
||||
}
|
||||
|
||||
@ -83,6 +83,6 @@ void __perf_os_patch_init(void)
|
||||
#endif
|
||||
|
||||
task_cycle_info_t * get_rtos_task_cycle_info(void)
|
||||
{
|
||||
{
|
||||
return &(((struct __task_cycle_info_t *)rt_current_thread->stack_addr)->tInfo);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -67,19 +67,19 @@ 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)
|
||||
void EvrRtxThreadSwitched (osThreadId_t thread_id)
|
||||
{
|
||||
__on_context_switch((osRtxThread_t *)thread_id);
|
||||
|
||||
|
||||
#if defined(RTE_Compiler_EventRecorder)
|
||||
# define EvtRtxThreadSwitched \
|
||||
EventID(EventLevelOp, EvtRtxThreadNo, 0x19U)
|
||||
|
||||
EventID(EventLevelOp, EvtRtxThreadNo, 0x19U)
|
||||
|
||||
(void)EventRecord2(EvtRtxThreadSwitched, (uint32_t)thread_id, 0U);
|
||||
#else
|
||||
(void)thread_id;
|
||||
@ -88,12 +88,12 @@ void EvrRtxThreadSwitched (osThreadId_t thread_id)
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -70,9 +70,9 @@ extern void __on_context_switch_out(uint32_t *pwStack);
|
||||
/*============================ IMPLEMENTATION ================================*/
|
||||
|
||||
#if defined(TX_EXECUTION_PROFILE_ENABLE)
|
||||
void WRAP_FUNC(_tx_execution_thread_enter)(void)
|
||||
void WRAP_FUNC(_tx_execution_thread_enter)(void)
|
||||
#else
|
||||
void _tx_execution_thread_enter (void)
|
||||
void _tx_execution_thread_enter (void)
|
||||
#endif
|
||||
{
|
||||
TX_THREAD * ptThread = NULL;
|
||||
@ -82,44 +82,44 @@ void _tx_execution_thread_enter (void)
|
||||
|
||||
#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)
|
||||
void WRAP_FUNC(_tx_execution_thread_exit)(void)
|
||||
#else
|
||||
void _tx_execution_thread_exit(void)
|
||||
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_exit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void _tx_execution_isr_enter(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);
|
||||
|
||||
|
@ -43,7 +43,7 @@ correct privileged Vs unprivileged linkage and placement. */
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -74,82 +74,82 @@ struct __task_cycle_info_t {
|
||||
* 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. */
|
||||
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. */
|
||||
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
|
||||
#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. */
|
||||
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 ( ( 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 ( 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_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_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 ( 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( 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( 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.
|
||||
#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
|
||||
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
|
||||
#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
|
||||
/* 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( INCLUDE_xTaskAbortDelay == 1 )
|
||||
uint8_t ucDelayAborted;
|
||||
#endif
|
||||
|
||||
#if( configUSE_POSIX_ERRNO == 1 )
|
||||
int iTaskErrno;
|
||||
#endif
|
||||
#if( configUSE_POSIX_ERRNO == 1 )
|
||||
int iTaskErrno;
|
||||
#endif
|
||||
|
||||
} tskTCB;
|
||||
|
||||
@ -159,11 +159,11 @@ 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
|
||||
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
|
||||
/*! \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"
|
||||
@ -172,8 +172,8 @@ extern TCB_t * volatile pxCurrentTCB;
|
||||
/*
|
||||
//! \brief Enable RTOS Patch for perf_counter
|
||||
#define __PERF_CNT_USE_RTOS__
|
||||
|
||||
#define traceTASK_SWITCHED_OUT_DISABLE
|
||||
|
||||
#define traceTASK_SWITCHED_OUT_DISABLE
|
||||
#define traceTASK_SWITCHED_IN_DISABLE
|
||||
|
||||
extern void __freertos_evr_on_task_switched_out (void *ptTCB);
|
||||
@ -216,9 +216,9 @@ void __freertos_evr_on_task_switched_out (void *ptTCB) {
|
||||
#else
|
||||
(void)pxCurrentTCB;
|
||||
#endif
|
||||
|
||||
|
||||
__on_context_switch_out(((TCB_t *)ptTCB)->pxStack);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -229,12 +229,12 @@ void __freertos_evr_on_task_switched_in(void *ptTCB, uint32_t uxTopPriority) {
|
||||
(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);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -71,12 +71,12 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -67,19 +67,19 @@ 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)
|
||||
void EvrRtxThreadSwitched (osThreadId_t thread_id)
|
||||
{
|
||||
__on_context_switch((osRtxThread_t *)thread_id);
|
||||
|
||||
|
||||
#if defined(RTE_Compiler_EventRecorder)
|
||||
# define EvtRtxThreadSwitched \
|
||||
EventID(EventLevelOp, EvtRtxThreadNo, 0x19U)
|
||||
|
||||
EventID(EventLevelOp, EvtRtxThreadNo, 0x19U)
|
||||
|
||||
(void)EventRecord2(EvtRtxThreadSwitched, (uint32_t)thread_id, 0U);
|
||||
#else
|
||||
(void)thread_id;
|
||||
@ -88,12 +88,12 @@ void EvrRtxThreadSwitched (osThreadId_t thread_id)
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#undef __WRAP_FUNC
|
||||
#undef WRAP_FUNC
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER__) && __IS_COMPILER_ARM_COMPILER__
|
||||
|
||||
# define __WRAP_FUNC(__NAME) $Sub$$##__NAME
|
||||
# define __ORIG_FUNC(__NAME) $Super$$##__NAME
|
||||
@ -70,9 +70,9 @@ extern void __on_context_switch_out(uint32_t *pwStack);
|
||||
/*============================ IMPLEMENTATION ================================*/
|
||||
|
||||
#if defined(TX_EXECUTION_PROFILE_ENABLE)
|
||||
void WRAP_FUNC(_tx_execution_thread_enter)(void)
|
||||
void WRAP_FUNC(_tx_execution_thread_enter)(void)
|
||||
#else
|
||||
void _tx_execution_thread_enter (void)
|
||||
void _tx_execution_thread_enter (void)
|
||||
#endif
|
||||
{
|
||||
TX_THREAD * ptThread = NULL;
|
||||
@ -82,44 +82,44 @@ void _tx_execution_thread_enter (void)
|
||||
|
||||
#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)
|
||||
void WRAP_FUNC(_tx_execution_thread_exit)(void)
|
||||
#else
|
||||
void _tx_execution_thread_exit(void)
|
||||
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_exit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void _tx_execution_isr_enter(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);
|
||||
|
||||
|
172
perf_counter.c
172
perf_counter.c
@ -154,8 +154,8 @@ typedef struct
|
||||
} SCB_Type;
|
||||
|
||||
/*!
|
||||
* \name __task_cycle_info_t
|
||||
*
|
||||
* \name __task_cycle_info_t
|
||||
*
|
||||
*/
|
||||
//! @{
|
||||
struct __task_cycle_info_t {
|
||||
@ -178,7 +178,7 @@ volatile static int32_t s_nMSUnit = 1;
|
||||
volatile static int32_t s_nMSResidule = 0;
|
||||
volatile static int32_t s_nSystemMS = 0;
|
||||
|
||||
volatile static int64_t s_lSystemClockCounts = 0;
|
||||
volatile static int64_t s_lSystemClockCounts = 0;
|
||||
|
||||
|
||||
/*============================ PROTOTYPES ====================================*/
|
||||
@ -203,10 +203,10 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
|
||||
//__IRQ_SAFE {
|
||||
SysTick->CTRL = 0;
|
||||
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
//NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
@ -225,7 +225,7 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
* 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.
|
||||
@ -235,7 +235,7 @@ void user_code_insert_to_systick_handler(void)
|
||||
uint32_t wLoad = SysTick->LOAD + 1;
|
||||
s_nCycleCounts += wLoad;
|
||||
s_lSystemClockCounts += wLoad;
|
||||
|
||||
|
||||
//! update system ms counter
|
||||
s_nMSResidule += wLoad;
|
||||
int32_t nMS = s_nMSResidule / s_nMSUnit;
|
||||
@ -244,7 +244,7 @@ void user_code_insert_to_systick_handler(void)
|
||||
|
||||
}
|
||||
|
||||
__WEAK
|
||||
__WEAK
|
||||
void __perf_os_patch_init(void)
|
||||
{
|
||||
}
|
||||
@ -260,28 +260,28 @@ void update_perf_counter(void)
|
||||
|
||||
/*! \brief initialise cycle counter service
|
||||
* \note - don't forget to tell the function whether the systick is already
|
||||
* used by user applications.
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 3. And call function init_cycle_counter(false) if you doesn't
|
||||
* use SysTick in your project at all.
|
||||
*
|
||||
*
|
||||
* \param bIsSysTickOccupied A boolean value which indicates whether SysTick
|
||||
* is already used by user application.
|
||||
*/
|
||||
@ -293,15 +293,15 @@ void init_cycle_counter(bool bIsSysTickOccupied)
|
||||
}
|
||||
SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
|
||||
start_cycle_counter();
|
||||
//s_nSystemClockCounts = s_nCycleCounts;
|
||||
s_nOffset = stop_cycle_counter();
|
||||
|
||||
|
||||
update_perf_counter();
|
||||
s_lSystemClockCounts = 0; // reset system cycle counter
|
||||
s_nSystemMS = 0; // reset system millisecond counter
|
||||
|
||||
|
||||
#if defined(__IS_COMPILER_ARM_COMPILER_5__) \
|
||||
|| defined(__IS_COMPILER_ARM_COMPILER_6__) \
|
||||
|| defined(__IS_COMPILER_GCC__) \
|
||||
@ -313,7 +313,7 @@ void init_cycle_counter(bool bIsSysTickOccupied)
|
||||
__perf_os_patch_init();
|
||||
}
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief try to set a start pointer for the performance counter
|
||||
*
|
||||
* \retval false the LOAD register is too small
|
||||
@ -325,7 +325,7 @@ bool start_cycle_counter(void)
|
||||
if (SysTick->LOAD < PERF_CNT_COMPENSATION_THRESHOLD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
__IRQ_SAFE {
|
||||
s_nCycleCounts = (int32_t)SysTick->VAL - (int32_t)SysTick->LOAD;
|
||||
}
|
||||
@ -334,28 +334,28 @@ bool start_cycle_counter(void)
|
||||
|
||||
/*! \note this function should only be called when irq is disabled
|
||||
* hence SysTick-LOAD and (SCB->ICSR & SCB_ICSR_PENDSTSET_Msk)
|
||||
* won't change.
|
||||
* won't change.
|
||||
*/
|
||||
__STATIC_INLINE int32_t check_systick(void)
|
||||
{
|
||||
int32_t nTemp = (int32_t)SysTick->LOAD - (int32_t)SysTick->VAL;
|
||||
|
||||
/*! \note Since we cannot stop counting temporarily, there are several
|
||||
/*! \note Since we cannot stop counting temporarily, there are several
|
||||
* conditions which we should take into consideration:
|
||||
* - Condition 1: when assigning nTemp with the register value (LOAD-VAL),
|
||||
* - Condition 1: when assigning nTemp with the register value (LOAD-VAL),
|
||||
* the underflow didn't happen but when we check the PENDSTSET bit,
|
||||
* the underflow happens, for this condition, we should not
|
||||
* do any compensation. When this happens, the (LOAD-nTemp) is
|
||||
* do any compensation. When this happens, the (LOAD-nTemp) is
|
||||
* smaller than PERF_CNT_COMPENSATION_THRESHOLD (a small value) as
|
||||
* long as LOAD is bigger than (or equals to) the
|
||||
* long as LOAD is bigger than (or equals to) the
|
||||
* PERF_CNT_COMPENSATION_THRESHOLD;
|
||||
* - Condition 2: when assigning nTemp with the register value (LOAD-VAL),
|
||||
* - Condition 2: when assigning nTemp with the register value (LOAD-VAL),
|
||||
* the VAL is zero and underflow happened and the PENDSTSET bit
|
||||
* is set, for this condition, we should not do any compensation.
|
||||
* When this happens, the (LOAD-nTemp) is equals to zero.
|
||||
* - Condition 3: when assigning nTemp with the register value (LOAD-VAL),
|
||||
* the underflow has already happened, hence the PENDSTSET
|
||||
* is set, for this condition, we should compensate the return
|
||||
* the underflow has already happened, hence the PENDSTSET
|
||||
* is set, for this condition, we should compensate the return
|
||||
* value. When this happens, the (LOAD-nTemp) is bigger than (or
|
||||
* equals to) PERF_CNT_COMPENSATION_THRESHOLD.
|
||||
* The following code implements an equivalent logic.
|
||||
@ -363,9 +363,9 @@ __STATIC_INLINE int32_t check_systick(void)
|
||||
if (SCB->ICSR & SCB_ICSR_PENDSTSET_Msk){
|
||||
if (((int32_t)SysTick->LOAD - nTemp) >= PERF_CNT_COMPENSATION_THRESHOLD) {
|
||||
nTemp += SysTick->LOAD + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nTemp;
|
||||
}
|
||||
|
||||
@ -399,38 +399,38 @@ void __perf_counter_init(void)
|
||||
|
||||
/*!
|
||||
* \brief delay specified time in microsecond
|
||||
*
|
||||
*
|
||||
* \param nUs time in microsecond
|
||||
*/
|
||||
void delay_us(int32_t nUs)
|
||||
{
|
||||
int64_t lUs = nUs * s_nUSUnit;
|
||||
|
||||
|
||||
if (lUs <= PERF_CNT_DELAY_US_COMPENSATION) {
|
||||
return ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lUs -= PERF_CNT_DELAY_US_COMPENSATION;
|
||||
|
||||
|
||||
lUs += get_system_ticks();
|
||||
while(get_system_ticks() < lUs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief delay specified time in millisecond
|
||||
*
|
||||
*
|
||||
* \param nUs time in millisecond
|
||||
*/
|
||||
void delay_ms(int32_t nMs)
|
||||
{
|
||||
int64_t lUs = nMs * s_nMSUnit;
|
||||
|
||||
|
||||
if (lUs <= PERF_CNT_DELAY_US_COMPENSATION) {
|
||||
return ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lUs -= PERF_CNT_DELAY_US_COMPENSATION;
|
||||
|
||||
|
||||
lUs += get_system_ticks();
|
||||
while(get_system_ticks() < lUs);
|
||||
}
|
||||
@ -440,30 +440,30 @@ void delay_ms(int32_t nMs)
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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))
|
||||
__attribute__((nothrow))
|
||||
#endif
|
||||
|
||||
int64_t clock(void)
|
||||
{
|
||||
int64_t lTemp = 0;
|
||||
|
||||
|
||||
__IRQ_SAFE {
|
||||
lTemp = check_systick() + s_lSystemClockCounts;
|
||||
}
|
||||
@ -473,13 +473,13 @@ int64_t clock(void)
|
||||
|
||||
/*!
|
||||
* \brief get the elapsed cycles since perf_counter is initialised
|
||||
*
|
||||
*
|
||||
* \return int64_t the elpased cycles
|
||||
*/
|
||||
int64_t get_system_ticks(void)
|
||||
{
|
||||
int64_t lTemp = 0;
|
||||
|
||||
|
||||
__IRQ_SAFE {
|
||||
lTemp = check_systick() + s_lSystemClockCounts;
|
||||
}
|
||||
@ -489,22 +489,22 @@ int64_t get_system_ticks(void)
|
||||
|
||||
/*!
|
||||
* \brief get the elapsed milliseconds since perf_counter is initialised
|
||||
*
|
||||
*
|
||||
* \return int32_t the elapsed milliseconds
|
||||
*/
|
||||
int32_t get_system_ms(void)
|
||||
{
|
||||
int32_t nTemp = 0;
|
||||
|
||||
|
||||
__IRQ_SAFE {
|
||||
nTemp = s_nSystemMS + (check_systick() + s_nMSResidule) / s_nMSUnit;
|
||||
}
|
||||
|
||||
|
||||
return nTemp;
|
||||
}
|
||||
|
||||
|
||||
__WEAK
|
||||
__WEAK
|
||||
task_cycle_info_t * get_rtos_task_cycle_info(void)
|
||||
{
|
||||
return NULL;
|
||||
@ -512,14 +512,14 @@ task_cycle_info_t * get_rtos_task_cycle_info(void)
|
||||
|
||||
void init_task_cycle_counter(void)
|
||||
{
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
(struct __task_cycle_info_t *)get_rtos_task_cycle_info();
|
||||
if (NULL == ptRootAgent) {
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
memset(ptRootAgent, 0, sizeof(struct __task_cycle_info_t));
|
||||
|
||||
|
||||
ptRootAgent->tList.ptInfo = &(ptRootAgent->tInfo);
|
||||
ptRootAgent->tInfo.lStart = get_system_ticks();
|
||||
ptRootAgent->wMagicWord = MAGIC_WORD_CANARY;
|
||||
@ -536,7 +536,7 @@ task_cycle_info_t *init_task_cycle_info(task_cycle_info_t *ptInfo)
|
||||
|
||||
ptInfo->bEnabled = true;
|
||||
} while(0);
|
||||
|
||||
|
||||
return ptInfo;
|
||||
}
|
||||
|
||||
@ -584,33 +584,33 @@ task_cycle_info_agent_t *register_task_cycle_agent(task_cycle_info_t *ptInfo,
|
||||
if (NULL == ptAgent || NULL == ptInfo) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
(struct __task_cycle_info_t *)get_rtos_task_cycle_info();
|
||||
if (NULL == ptRootAgent) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ptRootAgent->wMagicWord = MAGIC_WORD_AGENT_LIST_VALID;
|
||||
|
||||
|
||||
ptAgent->ptInfo = ptInfo;
|
||||
|
||||
|
||||
//! push to the stack
|
||||
do {
|
||||
//! set next-list
|
||||
ptAgent->ptNext = ptRootAgent->tList.ptNext;
|
||||
ptRootAgent->tList.ptNext = ptAgent;
|
||||
|
||||
|
||||
//! set prev-list
|
||||
ptAgent->ptPrev = &(ptRootAgent->tList);
|
||||
if (NULL != ptAgent->ptNext) {
|
||||
ptAgent->ptNext->ptPrev = ptAgent;
|
||||
}
|
||||
} while(0);
|
||||
|
||||
|
||||
} while(0);
|
||||
}
|
||||
|
||||
|
||||
return ptAgent;
|
||||
}
|
||||
|
||||
@ -622,7 +622,7 @@ unregister_task_cycle_agent(task_cycle_info_agent_t *ptAgent)
|
||||
if (NULL == ptAgent) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
task_cycle_info_agent_t *ptPrev = ptAgent->ptPrev;
|
||||
if (NULL == ptPrev) {
|
||||
break; /* this should not happen */
|
||||
@ -631,21 +631,21 @@ unregister_task_cycle_agent(task_cycle_info_agent_t *ptAgent)
|
||||
//! already removed
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//! remove agent from the next-list
|
||||
ptPrev->ptNext = ptAgent->ptNext;
|
||||
|
||||
|
||||
if (NULL != ptAgent->ptNext) {
|
||||
//! remove agent from the prev-list
|
||||
//! remove agent from the prev-list
|
||||
ptAgent->ptNext->ptPrev = ptPrev;
|
||||
}
|
||||
|
||||
|
||||
ptAgent->ptNext = NULL;
|
||||
ptAgent->ptPrev = NULL;
|
||||
|
||||
|
||||
} while(0);
|
||||
}
|
||||
|
||||
|
||||
return ptAgent;
|
||||
}
|
||||
|
||||
@ -654,7 +654,7 @@ void __on_context_switch_in(uint32_t *pwStack)
|
||||
{
|
||||
struct __task_cycle_info_t *ptRootAgent = (struct __task_cycle_info_t *)pwStack;
|
||||
uint64_t dwTimeStamp = get_system_ticks();
|
||||
|
||||
|
||||
ptRootAgent->lLastTimeStamp = dwTimeStamp;
|
||||
ptRootAgent->tInfo.hwActiveCount++;
|
||||
|
||||
@ -676,10 +676,10 @@ void __on_context_switch_out(uint32_t *pwStack)
|
||||
{
|
||||
struct __task_cycle_info_t *ptRootAgent = (struct __task_cycle_info_t *)pwStack;
|
||||
int64_t lCycleUsed = get_system_ticks() - ptRootAgent->lLastTimeStamp;
|
||||
|
||||
|
||||
ptRootAgent->tInfo.nUsedRecent = lCycleUsed;
|
||||
ptRootAgent->tInfo.lUsedTotal += lCycleUsed;
|
||||
|
||||
|
||||
if (MAGIC_WORD_AGENT_LIST_VALID == ptRootAgent->wMagicWord) {
|
||||
//! update all agents
|
||||
task_cycle_info_agent_t *ptAgent = ptRootAgent->tList.ptNext;
|
||||
@ -697,16 +697,16 @@ void __on_context_switch_out(uint32_t *pwStack)
|
||||
|
||||
void __start_task_cycle_counter(task_cycle_info_t *ptInfo)
|
||||
{
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
(struct __task_cycle_info_t *)get_rtos_task_cycle_info();
|
||||
if (NULL == ptRootAgent) {
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
__IRQ_SAFE {
|
||||
ptRootAgent->lLastTimeStamp = get_system_ticks();
|
||||
ptRootAgent->tInfo.lUsedTotal = 0;
|
||||
|
||||
|
||||
if (NULL != ptInfo) {
|
||||
ptInfo->lUsedTotal = 0;
|
||||
ptInfo->bEnabled = true;
|
||||
@ -717,14 +717,14 @@ void __start_task_cycle_counter(task_cycle_info_t *ptInfo)
|
||||
|
||||
int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo)
|
||||
{
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
struct __task_cycle_info_t * ptRootAgent =
|
||||
(struct __task_cycle_info_t *)get_rtos_task_cycle_info();
|
||||
if (NULL == ptRootAgent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int64_t lCycles = 0;
|
||||
|
||||
|
||||
__IRQ_SAFE {
|
||||
int64_t lCycleUsed = get_system_ticks() - ptRootAgent->lLastTimeStamp;
|
||||
ptRootAgent->tInfo.lUsedTotal += lCycleUsed;
|
||||
@ -735,13 +735,13 @@ int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo)
|
||||
ptInfo->lUsedTotal += lCycleUsed;
|
||||
ptInfo->bEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
lCycles = ptInfo->lUsedTotal;
|
||||
} else {
|
||||
lCycles = ptRootAgent->tInfo.lUsedTotal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return lCycles;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ extern "C" {
|
||||
#define __PER_COUNTER_VER__ (__PERF_COUNTER_VER_MAJOR__ * 10000ul \
|
||||
+__PERF_COUNTER_VER_MINOR__ * 100ul \
|
||||
+__PERF_COUNTER_VER_REVISE__)
|
||||
|
||||
|
||||
//! \name The macros to identify the compiler
|
||||
//! @{
|
||||
|
||||
@ -156,21 +156,21 @@ extern "C" {
|
||||
__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 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)
|
||||
__CONNECT6(__A, __B, __C, __D, __E, __F)
|
||||
#define CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
|
||||
__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)
|
||||
__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__)
|
||||
|
||||
@ -197,14 +197,14 @@ extern "C" {
|
||||
((__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__)
|
||||
|
||||
@ -259,7 +259,7 @@ extern "C" {
|
||||
SAFE_NAME(temp2);}), \
|
||||
__set_PRIMASK(SAFE_NAME(temp)))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __IRQ_SAFE
|
||||
# define __IRQ_SAFE \
|
||||
using( uint32_t SAFE_NAME(temp) = \
|
||||
@ -331,7 +331,7 @@ typedef struct {
|
||||
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 {
|
||||
@ -346,7 +346,7 @@ struct task_cycle_info_agent_t {
|
||||
/*============================ PROTOTYPES ====================================*/
|
||||
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \brief try to set a start pointer for the performance counter
|
||||
*
|
||||
* \retval false the LOAD register is too small
|
||||
@ -366,14 +366,14 @@ extern int32_t stop_cycle_counter(void);
|
||||
|
||||
/*!
|
||||
* \brief delay specified time in microsecond
|
||||
*
|
||||
*
|
||||
* \param nUs time in microsecond
|
||||
*/
|
||||
extern void delay_us(int32_t nUs);
|
||||
|
||||
/*!
|
||||
* \brief delay specified time in millisecond
|
||||
*
|
||||
*
|
||||
* \param nUs time in millisecond
|
||||
*/
|
||||
extern void delay_ms(int32_t nMs);
|
||||
@ -384,38 +384,38 @@ extern void delay_ms(int32_t nMs);
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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
|
||||
*! 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))
|
||||
__attribute__((nothrow))
|
||||
#endif
|
||||
extern int64_t clock(void);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief get the elapsed cycles since perf_counter is initialised
|
||||
*
|
||||
*
|
||||
* \return int64_t the elpased cycles
|
||||
*/
|
||||
extern int64_t get_system_ticks(void);
|
||||
|
||||
/*!
|
||||
* \brief get the elapsed milliseconds since perf_counter is initialised
|
||||
*
|
||||
*
|
||||
* \return int32_t the elapsed milliseconds
|
||||
*/
|
||||
extern int32_t get_system_ms(void);
|
||||
@ -434,14 +434,14 @@ extern void init_task_cycle_counter(void);
|
||||
*! - 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
|
||||
/*!
|
||||
*! \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
|
||||
@ -449,14 +449,14 @@ extern task_cycle_info_t * get_rtos_task_cycle_info(void);
|
||||
extern task_cycle_info_t *init_task_cycle_info(task_cycle_info_t *ptInfo);
|
||||
|
||||
/*! \brief enable a given task_cycle_info_t object
|
||||
*!
|
||||
*!
|
||||
*! \param 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 ptInfo the address of target task_cycle_info_t object
|
||||
*! \return bool previous status
|
||||
*/
|
||||
@ -467,14 +467,14 @@ extern bool disable_task_cycle_info(task_cycle_info_t *ptInfo);
|
||||
*! \param ptInfo the address of target task_cycle_info_t object
|
||||
*! \param bEnabledStatus the previous status
|
||||
*/
|
||||
extern
|
||||
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
|
||||
*!
|
||||
*!
|
||||
*! \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
|
||||
@ -482,7 +482,7 @@ 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
|
||||
*!
|
||||
*! \return task_cycle_info_agent_t* the agent passed to this function
|
||||
@ -497,16 +497,16 @@ unregister_task_cycle_agent(task_cycle_info_agent_t *ptAgent);
|
||||
*/
|
||||
extern void __start_task_cycle_counter(task_cycle_info_t *ptInfo);
|
||||
|
||||
/*! \brief calculate the elapsed cycle count for current task since the last
|
||||
/*! \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
|
||||
*!
|
||||
*! \note you can call stop_cycle_counter() multiple times following one
|
||||
*! start_task_cycle_counter()
|
||||
*!
|
||||
*! \param 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
|
||||
*! is non-NULL, it returns the total used cycles of the specified
|
||||
*! task_cycle_info_t object.
|
||||
*!
|
||||
*! \return int64_t the elapsed cycle count.
|
||||
@ -535,33 +535,33 @@ extern int64_t __stop_task_cycle_counter(task_cycle_info_t *ptInfo);
|
||||
/*----------------------------------------------------------------------------*
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 3. And call function init_cycle_counter(false) if you doesn't
|
||||
* use SysTick in your project at all.
|
||||
*
|
||||
*
|
||||
* \param bIsSysTickOccupied A boolean value which indicates whether SysTick
|
||||
* is already used by user application.
|
||||
*/
|
||||
@ -575,7 +575,7 @@ extern void init_cycle_counter(bool bIsSysTickOccupied);
|
||||
* 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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user