Skip to content

Add Trace Hook Macros and function that returns the start of the stack. #659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 7, 2023
28 changes: 28 additions & 0 deletions include/FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@
#define INCLUDE_uxTaskGetStackHighWaterMark2 0
#endif

#ifndef INCLUDE_pxTaskGetStackStart
#define INCLUDE_pxTaskGetStackStart 0
#endif

#ifndef INCLUDE_eTaskGetState
#define INCLUDE_eTaskGetState 0
#endif
Expand Down Expand Up @@ -511,6 +515,18 @@
#define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
#endif

#ifndef traceMOVED_TASK_TO_DELAYED_LIST
#define traceMOVED_TASK_TO_DELAYED_LIST()
#endif

#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST()
#endif

#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST
#define traceMOVED_TASK_TO_SUSPENDED_LIST( pxTCB )
#endif

#ifndef traceQUEUE_CREATE
#define traceQUEUE_CREATE( pxNewQueue )
#endif
Expand Down Expand Up @@ -759,6 +775,18 @@
#define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify )
#endif

#ifndef traceISR_EXIT_TO_SCHEDULER
#define traceISR_EXIT_TO_SCHEDULER()
#endif

#ifndef traceISR_EXIT
#define traceISR_EXIT()
#endif

#ifndef traceISR_ENTER
#define traceISR_ENTER()
#endif

#ifndef traceSTREAM_BUFFER_CREATE_FAILED
#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
#endif
Expand Down
21 changes: 21 additions & 0 deletions include/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,27 @@ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTIO
*/
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;

/**
* task.h
* @code{c}
* uint8_t* pxTaskGetStackStart( TaskHandle_t xTask);
* @endcode
*
* INCLUDE_pxTaskGetStackStart must be set to 1 in FreeRTOSConfig.h for
* this function to be available.
*
* Returns the start of the stack associated with xTask. That is,
* the highest stack memory address on architectures where the stack grows down
* from high memory, and the lowest memory address on architectures where the
* stack grows up from low memory.
*
* @param xTask Handle of the task associated with the stack returned.
* Set xTask to NULL to return the stack of the calling task.
*
* @return A pointer to the start of the stack.
*/
uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) PRIVILEGED_FUNCTION;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Removed it from the patchset.


/* When using trace macros it is sometimes necessary to include task.h before
* FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined,
* so the following two prototypes will cause a compilation error. This can be
Expand Down
6 changes: 6 additions & 0 deletions portable/GCC/ARM_CM7/r0p1/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,20 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already
* known. */
portDISABLE_INTERRUPTS();
traceISR_ENTER();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
else
{
traceISR_EXIT();
}
}
portENABLE_INTERRUPTS();
}
Expand Down
2 changes: 1 addition & 1 deletion portable/GCC/ARM_CM7/r0p1/portmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else { traceISR_EXIT(); } } while( 0 )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit only - I wonder if this could result in confusion when reading the resultant trace if the interrupts is preempted between the execution of the trace macro and the portYIELD.

#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/

Expand Down
20 changes: 20 additions & 0 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
mtCOVERAGE_TEST_MARKER();
}

traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this macro needed? A few lines earlier is the traceTASK_SUSPEND(pxTCB) macro (line 1688) So we already know that the function is called and the task is being suspended. Is it necessary to know that the suspension is happening 23 lines of code later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this macro is not necessarily needed.

vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );

#if ( configUSE_TASK_NOTIFICATIONS == 1 )
Expand Down Expand Up @@ -3988,6 +3989,21 @@ static void prvCheckTasksWaitingTermination( void )
#endif /* INCLUDE_uxTaskGetStackHighWaterMark */
/*-----------------------------------------------------------*/

#if (INCLUDE_pxTaskGetStackStart == 1)
uint8_t* pxTaskGetStackStart( TaskHandle_t xTask)
{
TCB_t *pxTCB;
UBaseType_t uxReturn;
(void)uxReturn;

pxTCB = prvGetTCBFromHandle( xTask );
return ( uint8_t * ) pxTCB->pxStack;
}

#endif /* INCLUDE_pxTaskGetStackStart */
/*-----------------------------------------------------------*/


#if ( INCLUDE_vTaskDelete == 1 )

static void prvDeleteTCB( TCB_t * pxTCB )
Expand Down Expand Up @@ -5412,12 +5428,14 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
{
/* Wake time has overflowed. Place this item in the overflow
* list. */
traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
}
else
{
/* The wake time has not overflowed, so the current block list
* is used. */
traceMOVED_TASK_TO_DELAYED_LIST();
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );

/* If the task entering the blocked state was placed at the
Expand Down Expand Up @@ -5446,11 +5464,13 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,

if( xTimeToWake < xConstTickCount )
{
traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST();
/* Wake time has overflowed. Place this item in the overflow list. */
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
}
else
{
traceMOVED_TASK_TO_DELAYED_LIST();
/* The wake time has not overflowed, so the current block list is used. */
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );

Expand Down