diff --git a/Source/include/FreeRTOS.h b/Source/include/FreeRTOS.h
index ceb469a..ef5c618 100644
--- a/Source/include/FreeRTOS.h
+++ b/Source/include/FreeRTOS.h
@@ -160,6 +160,10 @@ extern "C" {
 	#define INCLUDE_uxTaskGetStackHighWaterMark2 0
 #endif
 
+#ifndef INCLUDE_pxTaskGetStackStart
+  #define INCLUDE_pxTaskGetStackStart 0
+#endif
+
 #ifndef INCLUDE_eTaskGetState
 	#define INCLUDE_eTaskGetState 0
 #endif
@@ -416,6 +420,19 @@ hold explicit before calling the code. */
 	#define tracePOST_MOVED_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
@@ -660,6 +677,16 @@ hold explicit before calling the code. */
 	#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 traceSTREAM_BUFFER_CREATE_FAILED
 	#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer )
 #endif
diff --git a/Source/include/task.h b/Source/include/task.h
index b0cc60b..3d1cbe0 100644
--- a/Source/include/task.h
+++ b/Source/include/task.h
@@ -1468,6 +1468,25 @@ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTIO
  */
 configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 
+/**
+ * task.h
+ * <PRE>uint8_t* pxTaskGetStackStart( TaskHandle_t xTask);</PRE>
+ *
+ * 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 --git a/Source/portable/GCC/ARM_CM4F/port.c b/Source/portable/GCC/ARM_CM4F/port.c
index 89a912c..42ba14b 100644
--- a/Source/portable/GCC/ARM_CM4F/port.c
+++ b/Source/portable/GCC/ARM_CM4F/port.c
@@ -492,14 +492,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();
 }
diff --git a/Source/portable/GCC/ARM_CM4F/portmacro.h b/Source/portable/GCC/ARM_CM4F/portmacro.h
index d0a566a..04d4f82 100644
--- a/Source/portable/GCC/ARM_CM4F/portmacro.h
+++ b/Source/portable/GCC/ARM_CM4F/portmacro.h
@@ -89,7 +89,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 --git a/Source/tasks.c b/Source/tasks.c
index f6a6a9b..c6b6d05 100644
--- a/Source/tasks.c
+++ b/Source/tasks.c
@@ -220,6 +220,17 @@ count overflows. */
 	taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );												\
 	vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
 	tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
+
+/*
+ * 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 )->xStateListItem ) ); \
+	tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
 /*-----------------------------------------------------------*/
 
 /*
@@ -1672,7 +1683,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
 					{
 						mtCOVERAGE_TEST_MARKER();
 					}
-					prvAddTaskToReadyList( pxTCB );
+					prvReaddTaskToReadyList( pxTCB );
 				}
 				else
 				{
@@ -1733,7 +1744,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
 			{
 				mtCOVERAGE_TEST_MARKER();
 			}
-
+      traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB);
 			vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );
 
 			#if( configUSE_TASK_NOTIFICATIONS == 1 )
@@ -3882,6 +3893,20 @@ 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 )
@@ -4056,7 +4081,7 @@ TCB_t *pxTCB;
 
 					/* Inherit the priority before being moved into the new list. */
 					pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority;
-					prvAddTaskToReadyList( pxMutexHolderTCB );
+					prvReaddTaskToReadyList( pxMutexHolderTCB );
 				}
 				else
 				{
@@ -4146,7 +4171,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
@@ -5208,6 +5233,7 @@ const TickType_t xConstTickCount = xTickCount;
 			/* 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->xStateListItem ) );
 		}
 		else
@@ -5224,12 +5250,14 @@ const TickType_t xConstTickCount = xTickCount;
 			{
 				/* 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
@@ -5259,11 +5287,13 @@ const TickType_t xConstTickCount = xTickCount;
 		if( xTimeToWake < xConstTickCount )
 		{
 			/* 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 head of the
