diff -rupN ./Source_org/include/FreeRTOS.h ./Source_new/include/FreeRTOS.h --- ./Source_org/include/FreeRTOS.h 2015-10-16 15:12:58.000000000 +0200 +++ ./Source_new/include/FreeRTOS.h 2015-11-13 18:08:30.000000000 +0100 @@ -203,6 +203,10 @@ extern "C" { #define INCLUDE_uxTaskGetStackHighWaterMark 0 #endif +#ifndef INCLUDE_pxTaskGetStackStart + #define INCLUDE_pxTaskGetStackStart 0 +#endif + #ifndef INCLUDE_eTaskGetState #define INCLUDE_eTaskGetState 0 #endif @@ -405,6 +409,22 @@ extern "C" { #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) #endif +#ifndef traceREADDED_TASK_TO_READY_STATE + #define traceREADDED_TASK_TO_READY_STATE( pxTCB ) traceMOVED_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 @@ -645,6 +665,19 @@ extern "C" { #define traceTASK_NOTIFY_GIVE_FROM_ISR() #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 configGENERATE_RUN_TIME_STATS #define configGENERATE_RUN_TIME_STATS 0 #endif diff -rupN ./Source_org/include/task.h ./Source_new/include/task.h --- ./Source_org/include/task.h 2015-10-17 19:12:22.000000000 +0200 +++ ./Source_new/include/task.h 2015-11-13 18:08:30.000000000 +0100 @@ -1131,6 +1131,25 @@ char *pcTaskGetTaskName( TaskHandle_t xT */ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +/** + * task.h + *
uint8_t* pxTaskGetStackStart( TaskHandle_t xTask);
+ * + * 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; + /* 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 diff -rupN ./Source_org/portable/GCC/ARM_CM4F/port.c ./Source_new/portable/GCC/ARM_CM4F/port.c --- ./Source_org/portable/GCC/ARM_CM4F/port.c 2015-10-16 15:12:58.000000000 +0200 +++ ./Source_new/portable/GCC/ARM_CM4F/port.c 2015-11-12 10:35:25.000000000 +0100 @@ -493,14 +493,20 @@ void xPortSysTickHandler( void ) save and then restore the interrupt mask value as its value is already known. */ ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + 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(); + } } portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); } diff -rupN ./Source_org/portable/GCC/ARM_CM4F/portmacro.h ./Source_new/portable/GCC/ARM_CM4F/portmacro.h --- ./Source_org/portable/GCC/ARM_CM4F/portmacro.h 2015-10-16 15:12:58.000000000 +0200 +++ ./Source_new/portable/GCC/ARM_CM4F/portmacro.h 2015-11-11 18:49:58.000000000 +0100 @@ -131,7 +131,7 @@ typedef unsigned long UBaseType_t; #define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) -#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() +#define portEND_SWITCHING_ISR( xSwitchRequired ) { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else { traceISR_EXIT(); } } #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ diff -rupN ./Source_org/tasks.c ./Source_new/tasks.c --- ./Source_org/tasks.c 2015-10-16 15:12:59.000000000 +0200 +++ ./Source_new/tasks.c 2015-11-13 18:14:04.000000000 +0100 @@ -390,6 +390,16 @@ count overflows. */ traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) ) + +/* + * Place the task represented by pxTCB which has been in a ready list before + * into the appropriate ready list for the task. + * It is inserted at the end of the list. + */ +#define prvReaddTaskToReadyList( pxTCB ) \ + traceREADDED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) ) /*-----------------------------------------------------------*/ /* @@ -1252,7 +1262,7 @@ StackType_t *pxTopOfStack; { mtCOVERAGE_TEST_MARKER(); } - prvAddTaskToReadyList( pxTCB ); + prvReaddTaskToReadyList( pxTCB ); } else { @@ -1313,7 +1323,7 @@ StackType_t *pxTopOfStack; { mtCOVERAGE_TEST_MARKER(); } - + traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB); vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); } taskEXIT_CRITICAL(); @@ -2295,6 +2305,7 @@ TickType_t xTimeToWake; /* Add the task to the suspended task list instead of a delayed task list to ensure the task is not woken by a timing event. It will block indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); } else @@ -2361,6 +2372,7 @@ TickType_t xTimeToWake; /* Add the task to the suspended task list instead of a delayed task list to ensure it is not woken by a timing event. It will block indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); } else @@ -2432,6 +2444,7 @@ TickType_t xTimeToWake; /* Add the task to the suspended task list instead of a delayed task list to ensure the task is not woken by a timing event. It will block indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); } else @@ -3075,11 +3088,13 @@ static void prvAddCurrentTaskToDelayedLi if( xTimeToWake < xTickCount ) { + traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST(); /* Wake time has overflowed. Place this item in the overflow list. */ vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); } else { + traceMOVED_TASK_TO_DELAYED_LIST(); /* The wake time has not overflowed, so the current block list is used. */ vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); @@ -3306,6 +3321,19 @@ TCB_t *pxNewTCB; #endif /* INCLUDE_uxTaskGetStackHighWaterMark */ /*-----------------------------------------------------------*/ +#if (INCLUDE_pxTaskGetStackStart == 1) + uint8_t* pxTaskGetStackStart( TaskHandle_t xTask) + { + TCB_t *pxTCB; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + return ( uint8_t * ) pxTCB->pxStack; + } + +#endif /* INCLUDE_pxTaskGetStackStart */ +/*-----------------------------------------------------------*/ + #if ( INCLUDE_vTaskDelete == 1 ) static void prvDeleteTCB( TCB_t *pxTCB ) @@ -3455,7 +3483,7 @@ TCB_t *pxTCB; /* Inherit the priority before being moved into the new list. */ pxTCB->uxPriority = pxCurrentTCB->uxPriority; - prvAddTaskToReadyList( pxTCB ); + prvReaddTaskToReadyList( pxTCB ); } else { @@ -3527,7 +3555,7 @@ TCB_t *pxTCB; any other purpose if this task is running, and it must be running to give back the mutex. */ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - prvAddTaskToReadyList( pxTCB ); + prvReaddTaskToReadyList( pxTCB ); /* Return true to indicate that a context switch is required. This is only actually required in the corner case whereby @@ -3935,6 +3963,7 @@ TickType_t uxReturn; of a delayed task list to ensure the task is not woken by a timing event. It will block indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); } else @@ -4053,6 +4082,7 @@ TickType_t uxReturn; of a delayed task list to ensure the task is not woken by a timing event. It will block indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); } else