diff --git a/ch12.md b/ch12.md index 4e03443..d634ce7 100644 --- a/ch12.md +++ b/ch12.md @@ -101,26 +101,26 @@ void vAssertCalled( const char *pcFile, uint32_t ulLine ) /*-----------------------------------------------------------*/ /* These following two lines must be placed in FreeRTOSConfig.h. */ -extern void vAssertCalled( const char *pcFile, uint32_t ulLine ); +extern void vAssertCalled( const char *pcFile, unsigned long ulLine ); #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) ``` * * * *Listing 12.3. A configASSERT() definition that records the source code line that failed an assertion* -## 12.3 FreeRTOS+Trace +## 12.3 Tracealyzer for FreeRTOS -FreeRTOS+Trace is a run-time diagnostic and optimization tool provided +Tracealyzer for FreeRTOS is a run-time diagnostic and optimization tool provided by our partner company, Percepio. -FreeRTOS+Trace captures valuable dynamic behavior information, then +Tracealyzer for FreeRTOS captures valuable dynamic behavior information, then presents the captured information in interconnected graphical views. The tool is also capable of displaying multiple synchronized views. The captured information is invaluable when analyzing, troubleshooting, or simply optimizing a FreeRTOS application. -FreeRTOS+Trace can be used side-by-side with a traditional debugger, and +Tracealyzer for FreeRTOS can be used side-by-side with a traditional debugger, and complements the debugger's view with a higher level time based perspective. @@ -181,7 +181,7 @@ context switch time. To obtain binary run-time statistics information, call the `uxTaskGetSystemState()` API function. To obtain run-time statistics information as a human readable ASCII table, call the -`vTaskGetRunTimeStats()` helper function. +`vTaskGetRunTimeStatistics()` helper function. ### 12.5.2 The Run-Time Statistics Clock @@ -250,8 +250,8 @@ has proven more practical to define them in `FreeRTOSConfig.h`. has been running, in run-time statistics clock units, since the application first booted. - If the first macro is used it must be defined to evaluate to the - current clock value. If the second macro is used it must be defined to + If the first macro is used, it must be defined to evaluate to the + current clock value. If the second macro is used, it must be defined to set its 'Time' parameter to the current clock value. @@ -267,8 +267,9 @@ below. ```c UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, - uint32_t * const pulTotalRunTime ); + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ); ``` +Note: configRUN_TIME_COUNTER_TYPE defaults to uint32_t for backward compatibility, but can be overridden in FreeRTOSConfig.h if uint32_t is too restrictive. * * * *Listing 12.4. The uxTaskGetSystemState() API function prototype* @@ -321,8 +322,16 @@ typedef struct xTASK_STATUS eTaskState eCurrentState; UBaseType_t uxCurrentPriority; UBaseType_t uxBasePriority; - uint32_t ulRunTimeCounter; + configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; + StackType_t * pxStackBase; + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t * pxTopOfStack; + StackType_t * pxEndOfStack; + #endif uint16_t usStackHighWaterMark; + #if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) + UBaseType_t uxCoreAffinityMask; + #endif } TaskStatus_t; ``` * * * @@ -389,6 +398,24 @@ typedef struct xTASK_STATUS provided by the application writer for the collection of run-time statistics. `ulRunTimeCounter` is only valid if `configGENERATE_RUN_TIME_STATS` is set to 1 in FreeRTOSConfig.h. + +- `pxStackBase` + + Points to the base address of the stack region allotted to this task. + +- `pxTopOfStack` + + Points to the current top address of the stack region allotted to this task. + The field `pxTopOfStack` is only valid if either the stack grows upwards (i.e. + `portSTACK_GROWTH` is greater than zero) or `configRECORD_STACK_HIGH_ADDRESS` + is set to 1 in FreeRTOSConfig.h. + +- `pxEndOfStack` + + Points to the end address of the of the stack region allotted to this task. + The field `pxEndOfStack` is only valid if either the stack grows upwards (i.e. + `portSTACK_GROWTH` is greater than zero) or `configRECORD_STACK_HIGH_ADDRESS` + is set to 1 in FreeRTOSConfig.h. - `usStackHighWaterMark` @@ -397,47 +424,61 @@ typedef struct xTASK_STATUS It is an indication of how close the task has come to overflowing its stack; the closer this value is to zero, the closer the task has come to overflowing its stack. `usStackHighWaterMark` is specified in bytes. + +- `uxCoreAffinityMask` + + A bitwise value that indicates the cores on which the task can run. + Cores are numbered from 0 to `configNUMBER_OF_CORES` - 1. For example, a + task that can run on core 0 and core 1 will have its `uxCoreAffinityMask` + set to 0x03. The field `uxCoreAffinityMask` is only available if both + `configUSE_CORE_AFFINITY` is set to 1 and `configNUMBER_OF_CORES` + is set to greater than 1 in FreeRTOSConfig.h. -### 12.5.5 The vTaskList() Helper Function +### 12.5.5 The vTaskListTasks() Helper Function -`vTaskList()` provides similar task status information to that provided by +`vTaskListTasks()` provides similar task status information to that provided by `uxTaskGetSystemState()`, but it presents the information as a human readable ASCII table, rather than an array of binary values. -`vTaskList()` is a very processor intensive function, and leaves the +`vTaskListTasks()` is a very processor intensive function, and leaves the scheduler suspended for an extended period. Therefore, it is recommended the function is used for debug purposes only, and not in a production real-time system. -`vTaskList()` is available if `configUSE_TRACE_FACILITY` and -`configUSE_STATS_FORMATTING_FUNCTIONS` are both set to 1 in +`vTaskListTasks()` is available if `configUSE_TRACE_FACILITY` is set to 1 and +`configUSE_STATS_FORMATTING_FUNCTIONS` is set to greater than 0 in FreeRTOSConfig.h. * * * ```c -void vTaskList( signed char *pcWriteBuffer ); +void vTaskListTasks( char * pcWriteBuffer, size_t uxBufferLength ); ``` * * * -*Listing 12.6. The vTaskList() API function prototype* +*Listing 12.6. The vTaskListTasks() API function prototype* -**vTaskList() parameters** +**vTaskListTasks() parameters** - `pcWriteBuffer` A pointer to a character buffer into which the formatted and human readable table is written. - The buffer must be large enough to hold the entire table, as no boundary checking is performed. + This buffer is assumed to be large enough to contain the generated report. + Approximately 40 bytes per task should be sufficient. + +- `uxBufferLength` + Length of the `pcWriteBuffer`. -An example of the output generated by `vTaskList()` is shown in Figure 12.7. + +An example of the output generated by `vTaskListTasks()` is shown in Figure 12.7. In the output: - Each row provides information on a single task. - The first column is the task's name. -- The second column is the task's state, where 'R' means Ready, 'B' +- The second column is the task's state, where 'X' means Running, 'R' means Ready, 'B' means Blocked, 'S' means Suspended, and 'D' means the task has been deleted. A task will only be reported as being in the deleted state for the short period between the time the task was deleted by a call @@ -455,39 +496,62 @@ In the output: description of `xTaskNumber`. ![](media/image88.png) -*Figure 12.7. Example output generated by vTaskList()* +*Figure 12.7. Example output generated by vTaskListTasks()* + + +Note: + The older version of `vTaskListTasks` is `vTaskList`. `vTaskList` assumes that the + `pcWriteBuffer` is of length `configSTATS_BUFFER_MAX_LENGTH`. This function is there only for + backward compatibility. New applications are recommended to use `vTaskListTasks` and + supply the length of the `pcWriteBuffer` explicitly. + * * * + ```c + void vTaskList( signed char *pcWriteBuffer ); + ``` + * * * + *Listing 12.7. The vTaskList() API function prototype* -### 12.5.6 The vTaskGetRunTimeStats() Helper Function + **vTaskList() parameters** -`vTaskGetRunTimeStats()` formats collected run-time statistics into a + - `pcWriteBuffer` + A pointer to a character buffer into which the formatted and human readable table is written. + The buffer must be large enough to hold the entire table, as no boundary checking is performed. + +### 12.5.6 The vTaskGetRunTimeStatistics() Helper Function + +`vTaskGetRunTimeStatistics()` formats collected run-time statistics into a human readable ASCII table. -`vTaskGetRunTimeStats()` is a very processor intensive function and leaves +`vTaskGetRunTimeStatistics()` is a very processor intensive function and leaves the scheduler suspended for an extended period. Therefore, it is recommended the function is used for debug purposes only, and not in a production real-time system. -`vTaskGetRunTimeStats()` is available when `configGENERATE_RUN_TIME_STATS` -and `configUSE_STATS_FORMATTING_FUNCTIONS` are both set to 1 in -FreeRTOSConfig.h. +`vTaskGetRunTimeStatistics()` is available when `configGENERATE_RUN_TIME_STATS` is set to +1, `configUSE_STATS_FORMATTING_FUNCTIONS` is set greater than 0, and +`configUSE_TRACE_FACILITY` is set to 1 in FreeRTOSConfig.h. * * * ```c -void vTaskGetRunTimeStats( signed char *pcWriteBuffer ); +void vTaskGetRunTimeStatistics( char * pcWriteBuffer, size_t uxBufferLength ); ``` * * * -*Listing 12.7. The vTaskGetRunTimeStats() API function prototype* +*Listing 12.8. The vTaskGetRunTimeStatistics() API function prototype* -**vTaskGetRunTimeStats() parameters** +**vTaskGetRunTimeStatistics() parameters** - `pcWriteBuffer` - A pointer to a character buffer into which the formatted and human readable table is written. The - buffer must be large enough to hold the entire table, as no boundary checking is performed. + A pointer to a character buffer into which the formatted and human readable table is written. + This buffer is assumed to be large enough to contain the generated report. + Approximately 40 bytes per task should be sufficient. +- `uxBufferLength` -An example of the output generated by `vTaskGetRunTimeStats()` is shown in + Length of the `pcWriteBuffer`. + +An example of the output generated by `vTaskGetRunTimeStatistics()` is shown in Figure 12.8. In the output: - Each row provides information on a single task. @@ -506,8 +570,29 @@ Figure 12.8. In the output: integer value. ![](media/image89.png) -*Figure 12.8. Example output generated by vTaskGetRunTimeStats()* +*Figure 12.8. Example output generated by vTaskGetRunTimeStatistics()* + + +Note: + The older version of `vTaskGetRunTimeStatistics` is `vTaskGetRunTimeStats`. + `vTaskGetRunTimeStats`assumes that the pcWriteBuffer is of length + `configSTATS_BUFFER_MAX_LENGTH`. This function is there only for backward compatiblity. + New applications are recommended to use `vTaskGetRunTimeStatistics` and supply the length + of the pcWriteBuffer explicitly. + * * * + ```c + void vTaskGetRunTimeStats( signed char *pcWriteBuffer ); + ``` + * * * + *Listing 12.9. The vTaskGetRunTimeStats() API function prototype* + + **vTaskGetRunTimeStats() parameters** + + - `pcWriteBuffer` + + A pointer to a character buffer into which the formatted and human readable table is written. The + buffer must be large enough to hold the entire table, as no boundary checking is performed. ### 12.5.7 Generating and Displaying Run-Time Statistics, a Worked Example @@ -535,9 +620,9 @@ void TimerOverflowInterruptHandler( void ) } ``` * * * -*Listing 12.8. 16-bit timer overflow interrupt handler used to count timer overflows* +*Listing 12.10. 16-bit timer overflow interrupt handler used to count timer overflows* -Listing 12.9 shows the lines added to FreeRTOSConfig.h to enable the +Listing 12.11 shows the lines added to FreeRTOSConfig.h to enable the collection of run-time statistics. * * * @@ -580,12 +665,15 @@ void vSetupTimerForRunTimeStats( void ); } ``` * * * -*Listing 12.9. Macros added to FreeRTOSConfig.h to enable the collection of run-time statistics* +*Listing 12.11. Macros added to FreeRTOSConfig.h to enable the collection of run-time statistics* -The task shown in Listing 12.10 prints out the collected run-time statistics every 5 seconds. +The task shown in Listing 12.12 prints out the collected run-time statistics every 5 seconds. * * * ```c + +#define RUN_TIME_STATS_STRING_BUFFER_LENGTH 512 + /* For clarity, calls to fflush() have been omitted from this code listing. */ static void prvStatsTask( void *pvParameters ) { @@ -594,7 +682,7 @@ static void prvStatsTask( void *pvParameters ) /* The buffer used to hold the formatted run-time statistics text needs to be quite large. It is therefore declared static to ensure it is not allocated on the task stack. This makes this function non re-entrant. */ - static signed char cStringBuffer[ 512 ]; + static signed char cStringBuffer[ RUN_TIME_STATS_STRING_BUFFER_LENGTH ]; /* The task will run every 5 seconds. */ const TickType_t xBlockPeriod = pdMS_TO_TICKS( 5000 ); @@ -608,11 +696,11 @@ static void prvStatsTask( void *pvParameters ) for( ;; ) { /* Wait until it is time to run this task again. */ - vTaskDelayUntil( &xLastExecutionTime, xBlockPeriod ); + xTaskDelayUntil( &xLastExecutionTime, xBlockPeriod ); /* Generate a text table from the run-time stats. This must fit into the cStringBuffer array. */ - vTaskGetRunTimeStats( cStringBuffer ); + vTaskGetRunTimeStatistics( cStringBuffer, RUN_TIME_STATS_STRING_BUFFER_LENGTH ); /* Print out column headings for the run-time stats table. */ printf( "\nTask\t\tAbs\t\t\t%%\n" ); @@ -628,7 +716,7 @@ static void prvStatsTask( void *pvParameters ) } ``` * * * -*Listing 12.10. The task that prints out the collected run-time statistics* +*Listing 12.12. The task that prints out the collected run-time statistics* ## 12.6 Trace Hook Macros @@ -663,7 +751,7 @@ that is called from the FreeRTOS/Source/tasks.c source file. - `traceTASK_INCREMENT_TICK(xTickCount)` - Called during the tick interrupt, after the tick count is incremented. The `xTickCount` parameter + Called during the tick interrupt, before the tick count is incremented. The `xTickCount` parameter passes the new tick count value into the macro. - `traceTASK_SWITCHED_OUT()` @@ -735,9 +823,9 @@ that is called from the FreeRTOS/Source/tasks.c source file. Called from within `xQueueReceiveFromISR()` when the receive operation fails due to the queue already being empty. The `pxQueue` parameter passes the handle of the target queue into the macro. -- `traceTASK_DELAY_UNTIL()` +- `traceTASK_DELAY_UNTIL( xTimeToWake )` - Called from within `vTaskDelayUntil()` immediately before the calling task enters the Blocked state. + Called from within `xTaskDelayUntil()` immediately before the calling task enters the Blocked state. - `traceTASK_DELAY()` @@ -794,3 +882,4 @@ following IDEs. This list may not be an exhaustive: - iSYSTEM WinIDEA +- STM32CubeIDE \ No newline at end of file