Skip to content

Commit ddc840f

Browse files
authored
Make the type used to hold run-time counter values configurable (#350)
* Introduce configRUN_TIME_COUNTER_TYPE which enables developers to define the type used to hold run time statistic counters. Defaults to uint32_t for backward compatibility. #define configRUN_TIME_COUNTER_TYPE to a type (for example, uint64_t) in FreeRTOSConfig.h to override the default. Introduce ulTaskGetIdleRunTimePercent() to complement the pre-existing ulTaskGetIdleRunTimeCounter(). Whereas the pre-existing function returns the raw run time counter value, the new function returns the percentage of the entire run time consumed by the idle task. Note the amount of idle time is only a good measure of the slack time in a system if there are no other tasks executing at the idle priority, tickless idle is not used, and configIDLE_SHOULD_YIELD is set to 0. * Add ultaskgetidleruntimepercent to lexicon.txt. * Update History file. Add the MPU version of ulTaskGetIdleRunTimePercent(). * Update include/FreeRTOS.h to correct comment as per aggarg@ suggestion. * Fix alignment in mpu_wrappers.h. Commit changes to mpu_prototypes.h which were missed from the original commit.
1 parent 6a84f2c commit ddc840f

File tree

8 files changed

+109
-35
lines changed

8 files changed

+109
-35
lines changed

.github/lexicon.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,6 +2332,7 @@ ulstatsaspercentage
23322332
ulstoppedtimercompensation
23332333
ultablebase
23342334
ultaskgetidleruntimecounter
2335+
ultaskgetidleruntimepercent
23352336
ultaskhasfpucontext
23362337
ultasknotificationtakeindexed
23372338
ultasknotifystateclear

History.txt

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
Changes between FreeRTOS V10.4.4 and TBD
2+
3+
+ Introduce configRUN_TIME_COUNTER_TYPE which enables developers to define
4+
the type used to hold run time statistic counters. Defaults to uint32_t
5+
for backward compatibility. #define configRUN_TIME_COUNTER_TYPE to a type
6+
(for example, uint64_t) in FreeRTOSConfig.h to override the default.
7+
+ Introduce ulTaskGetIdleRunTimePercent() to complement the pre-existing
8+
ulTaskGetIdleRunTimeCounter(). Whereas the pre-existing function returns
9+
the raw run time counter value, the new function returns the percentage of
10+
the entire run time consumed by the idle task. Note the amount of idle
11+
time is only a good measure of the slack time in a system if there are no
12+
other tasks executing at the idle priority, tickless idle is not used, and
13+
configIDLE_SHOULD_YIELD is set to 0.
14+
15+
116
Documentation and download available at https://www.FreeRTOS.org/
217

318
Changes between FreeRTOS V10.4.3 and FreeRTOS V10.4.4 released May 28 2021
@@ -38,7 +53,7 @@ Changes between FreeRTOS V10.4.3 and FreeRTOS V10.4.4 released May 28 2021
3853
correcting and improving code comments.
3954
+ Go look at the smp branch to see the progress towards the Symetric
4055
Multiprocessing Kernel. https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp
41-
56+
4257
Changes between FreeRTOS V10.4.2 and FreeRTOS V10.4.3 released December 14 2020
4358

4459
V10.4.3 is included in the 202012.00 LTS release. Learn more at https:/freertos.org/lts-libraries.html
@@ -54,14 +69,14 @@ Changes between FreeRTOS V10.4.2 and FreeRTOS V10.4.3 released December 14 2020
5469

5570

5671
Changes between FreeRTOS V10.4.1 and FreeRTOS V10.4.2 released November 10 2020
57-
72+
5873
See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html
5974

60-
+ Fix an issue in the ARMv8-M ports that caused BASEPRI to be masked
61-
between the first task starting to execute and that task making
75+
+ Fix an issue in the ARMv8-M ports that caused BASEPRI to be masked
76+
between the first task starting to execute and that task making
6277
a FreeRTOS API call.
6378
+ Introduced xTaskDelayUntil(), which is functionally equivalent to
64-
vTaskDelayUntil(), with the addition of returning a value to
79+
vTaskDelayUntil(), with the addition of returning a value to
6580
indicating whether or not the function placed the calling task into
6681
the Blocked state or not.
6782
+ Update WolfSSL to 4.5.0 and add the FIPS ready demo.
@@ -75,8 +90,8 @@ Changes between FreeRTOS V10.4.0 and FreeRTOS V10.4.1 released September 17 2020
7590

7691
See https://www.FreeRTOS.org/FreeRTOS-V10.4.x.html
7792

78-
+ Fixed an incorrectly named parameter that prevented the
79-
ulTaskNotifyTakeIndexed macro compiling, and the name space clash in the
93+
+ Fixed an incorrectly named parameter that prevented the
94+
ulTaskNotifyTakeIndexed macro compiling, and the name space clash in the
8095
test code that prevented this error causing test failures.
8196

8297

@@ -117,7 +132,7 @@ Changes between FreeRTOS V10.3.1 and FreeRTOS V10.4.0 released September 10 2020
117132
+ Added new POSIX port layer that allows FreeRTOS to run on Linux hosts in
118133
the same way the Windows port layer enables FreeRTOS to run on Windows
119134
hosts.
120-
+ Many other minor optimisations and enhancements. For full details
135+
+ Many other minor optimisations and enhancements. For full details
121136
see https://github.com/FreeRTOS/FreeRTOS-Kernel/commits/main
122137

123138

include/FreeRTOS.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,13 @@
905905
#define configSTACK_DEPTH_TYPE uint16_t
906906
#endif
907907

908+
#ifndef configRUN_TIME_COUNTER_TYPE
909+
/* Defaults to uint32_t for backward compatibility, but can be overridden in
910+
* FreeRTOSConfig.h if uint32_t is too restrictive. */
911+
912+
#define configRUN_TIME_COUNTER_TYPE uint32_t
913+
#endif
914+
908915
#ifndef configMESSAGE_BUFFER_LENGTH_TYPE
909916

910917
/* Defaults to size_t for backward compatibility, but can be overridden
@@ -1197,7 +1204,7 @@ typedef struct xSTATIC_TCB
11971204
void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
11981205
#endif
11991206
#if ( configGENERATE_RUN_TIME_STATS == 1 )
1200-
uint32_t ulDummy16;
1207+
configRUN_TIME_COUNTER_TYPE ulDummy16;
12011208
#endif
12021209
#if ( configUSE_NEWLIB_REENTRANT == 1 )
12031210
struct _reent xDummy17;

include/mpu_prototypes.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
8989
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
9090
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
9191
const UBaseType_t uxArraySize,
92-
uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
93-
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
92+
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
93+
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
94+
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL;
9495
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
9596
void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
9697
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,

include/mpu_wrappers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#define vTaskList MPU_vTaskList
7878
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
7979
#define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
80+
#define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent
8081
#define xTaskGenericNotify MPU_xTaskGenericNotify
8182
#define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait
8283
#define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake

include/task.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
*
5353
* The tskKERNEL_VERSION_MAJOR, tskKERNEL_VERSION_MINOR, tskKERNEL_VERSION_BUILD
5454
* values will reflect the last released version number.
55-
*/
55+
*/
5656
#define tskKERNEL_VERSION_NUMBER "V10.4.4+"
5757
#define tskKERNEL_VERSION_MAJOR 10
5858
#define tskKERNEL_VERSION_MINOR 4
@@ -159,7 +159,7 @@ typedef struct xTASK_STATUS
159159
eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */
160160
UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
161161
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
162-
uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See https://www.FreeRTOS.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
162+
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See https://www.FreeRTOS.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
163163
StackType_t * pxStackBase; /* Points to the lowest address of the task's stack area. */
164164
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
165165
} TaskStatus_t;
@@ -1723,7 +1723,7 @@ TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
17231723
* {
17241724
* TaskStatus_t *pxTaskStatusArray;
17251725
* volatile UBaseType_t uxArraySize, x;
1726-
* uint32_t ulTotalRunTime, ulStatsAsPercentage;
1726+
* configRUN_TIME_COUNTER_TYPE ulTotalRunTime, ulStatsAsPercentage;
17271727
*
17281728
* // Make sure the write buffer does not contain a string.
17291729
* pcWriteBuffer = 0x00;
@@ -1779,7 +1779,7 @@ TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
17791779
*/
17801780
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
17811781
const UBaseType_t uxArraySize,
1782-
uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION;
1782+
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION;
17831783

17841784
/**
17851785
* task. h
@@ -1886,11 +1886,12 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin
18861886

18871887
/**
18881888
* task. h
1889-
* <PRE>uint32_t ulTaskGetIdleRunTimeCounter( void );</PRE>
1889+
* <PRE>configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void );</PRE>
1890+
* <PRE>configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void );</PRE>
18901891
*
1891-
* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS
1892-
* must both be defined as 1 for this function to be available. The application
1893-
* must also then provide definitions for
1892+
* configGENERATE_RUN_TIME_STATS, configUSE_STATS_FORMATTING_FUNCTIONS and
1893+
* INCLUDE_xTaskGetIdleTaskHandle must all be defined as 1 for these functions
1894+
* to be available. The application must also then provide definitions for
18941895
* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE()
18951896
* to configure a peripheral timer/counter and return the timers current count
18961897
* value respectively. The counter should be at least 10 times the frequency of
@@ -1902,17 +1903,25 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lin
19021903
* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
19031904
* While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total
19041905
* execution time of each task into a buffer, ulTaskGetIdleRunTimeCounter()
1905-
* returns the total execution time of just the idle task.
1906+
* returns the total execution time of just the idle task and
1907+
* ulTaskGetIdleRunTimePercent() returns the percentage of the CPU time used by
1908+
* just the idle task.
1909+
*
1910+
* Note the amount of idle time is only a good measure of the slack time in a
1911+
* system if there are no other tasks executing at the idle priority, tickless
1912+
* idle is not used, and configIDLE_SHOULD_YIELD is set to 0.
19061913
*
1907-
* @return The total run time of the idle task. This is the amount of time the
1914+
* @return The total run time of the idle task or the percentage of the total
1915+
* run time consumed by the idle task. This is the amount of time the
19081916
* idle task has actually been executing. The unit of time is dependent on the
19091917
* frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
19101918
* portGET_RUN_TIME_COUNTER_VALUE() macros.
19111919
*
19121920
* \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter
19131921
* \ingroup TaskUtils
19141922
*/
1915-
uint32_t ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION;
1923+
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION;
1924+
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) PRIVILEGED_FUNCTION;
19161925

19171926
/**
19181927
* task. h

portable/Common/mpu_wrappers.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,22 @@ char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */
349349
/*-----------------------------------------------------------*/
350350

351351
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
352-
uint32_t MPU_ulTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */
352+
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* FREERTOS_SYSTEM_CALL */
353353
{
354-
uint32_t xReturn;
354+
configRUN_TIME_COUNTER_TYPE xReturn;
355+
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
356+
357+
xReturn = ulTaskGetIdleRunTimePercent();
358+
vPortResetPrivilege( xRunningPrivileged );
359+
return xReturn;
360+
}
361+
#endif
362+
/*-----------------------------------------------------------*/
363+
364+
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
365+
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */
366+
{
367+
configRUN_TIME_COUNTER_TYPE xReturn;
355368
BaseType_t xRunningPrivileged = xPortRaisePrivilege();
356369

357370
xReturn = ulTaskGetIdleRunTimeCounter();
@@ -430,7 +443,7 @@ char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */
430443
#if ( configUSE_TRACE_FACILITY == 1 )
431444
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * pxTaskStatusArray,
432445
UBaseType_t uxArraySize,
433-
uint32_t * pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */
446+
configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */
434447
{
435448
UBaseType_t uxReturn;
436449
BaseType_t xRunningPrivileged = xPortRaisePrivilege();

tasks.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
293293
#endif
294294

295295
#if ( configGENERATE_RUN_TIME_STATS == 1 )
296-
uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
296+
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
297297
#endif
298298

299299
#if ( configUSE_NEWLIB_REENTRANT == 1 )
@@ -399,8 +399,8 @@ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t
399399

400400
/* Do not move these variables to function scope as doing so prevents the
401401
* code working with debuggers that need to remove the static qualifier. */
402-
PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
403-
PRIVILEGED_DATA static volatile uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
402+
PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
403+
PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
404404

405405
#endif
406406

@@ -958,7 +958,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
958958

959959
#if ( configGENERATE_RUN_TIME_STATS == 1 )
960960
{
961-
pxNewTCB->ulRunTimeCounter = 0UL;
961+
pxNewTCB->ulRunTimeCounter = ( configRUN_TIME_COUNTER_TYPE ) 0;
962962
}
963963
#endif /* configGENERATE_RUN_TIME_STATS */
964964

@@ -2523,7 +2523,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char
25232523

25242524
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
25252525
const UBaseType_t uxArraySize,
2526-
uint32_t * const pulTotalRunTime )
2526+
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime )
25272527
{
25282528
UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
25292529

@@ -3748,7 +3748,7 @@ static void prvCheckTasksWaitingTermination( void )
37483748
}
37493749
#else
37503750
{
3751-
pxTaskStatus->ulRunTimeCounter = 0;
3751+
pxTaskStatus->ulRunTimeCounter = ( configRUN_TIME_COUNTER_TYPE ) 0;
37523752
}
37533753
#endif
37543754

@@ -4538,7 +4538,7 @@ static void prvResetNextTaskUnblockTime( void )
45384538
{
45394539
TaskStatus_t * pxTaskStatusArray;
45404540
UBaseType_t uxArraySize, x;
4541-
uint32_t ulTotalTime, ulStatsAsPercentage;
4541+
configRUN_TIME_COUNTER_TYPE ulTotalTime, ulStatsAsPercentage;
45424542

45434543
#if ( configUSE_TRACE_FACILITY != 1 )
45444544
{
@@ -4599,7 +4599,7 @@ static void prvResetNextTaskUnblockTime( void )
45994599
{
46004600
/* What percentage of the total run time has the task used?
46014601
* This will always be rounded down to the nearest integer.
4602-
* ulTotalRunTimeDiv100 has already been divided by 100. */
4602+
* ulTotalRunTime has already been divided by 100. */
46034603
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
46044604

46054605
/* Write the task name to the string, padding with
@@ -5263,15 +5263,42 @@ TickType_t uxTaskResetEventItemValue( void )
52635263

52645264
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
52655265

5266-
uint32_t ulTaskGetIdleRunTimeCounter( void )
5266+
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void )
52675267
{
52685268
return xIdleTaskHandle->ulRunTimeCounter;
52695269
}
52705270

52715271
#endif
52725272
/*-----------------------------------------------------------*/
52735273

5274-
static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
5274+
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
5275+
5276+
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void )
5277+
{
5278+
configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn;
5279+
5280+
ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE();
5281+
5282+
/* For percentage calculations. */
5283+
ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100;
5284+
5285+
/* Avoid divide by zero errors. */
5286+
if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 )
5287+
{
5288+
ulReturn = xIdleTaskHandle->ulRunTimeCounter / ulTotalTime;
5289+
}
5290+
else
5291+
{
5292+
ulReturn = 0;
5293+
}
5294+
5295+
return ulReturn;
5296+
}
5297+
5298+
#endif
5299+
/*-----------------------------------------------------------*/
5300+
5301+
static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
52755302
const BaseType_t xCanBlockIndefinitely )
52765303
{
52775304
TickType_t xTimeToWake;

0 commit comments

Comments
 (0)