#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/FreeRTOS.h"
#include "include/task.h"
#include "include/timers.h"
#include "include/StackMacros.h"
Data Structures | |
struct | tskTaskControlBlock |
Macros | |
#define | MPU_WRAPPERS_INCLUDED_FROM_API_FILE |
#define | prvAddTaskToReadyQueue(pxTCB) |
#define | prvCheckDelayedTasks() |
#define | prvGetTCBFromHandle(pxHandle) ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) ) |
#define | tskBLOCKED_CHAR ( ( signed char ) 'B' ) |
#define | tskDELETED_CHAR ( ( signed char ) 'D' ) |
#define | tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE |
#define | tskREADY_CHAR ( ( signed char ) 'R' ) |
#define | tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) ) |
#define | tskSTACK_FILL_BYTE ( 0xa5U ) |
#define | tskSUSPENDED_CHAR ( ( signed char ) 'S' ) |
#define | vWriteTraceToBuffer() |
Typedefs | |
typedef struct tskTaskControlBlock | tskTCB |
Functions | |
static | portTASK_FUNCTION (prvIdleTask, pvParameters) |
static void | prvAddCurrentTaskToDelayedList (portTickType xTimeToWake) |
static tskTCB * | prvAllocateTCBAndStack (unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer) |
static void | prvCheckTasksWaitingTermination (void) |
static void | prvInitialiseTaskLists (static void prvCheckTasksWaitingTermination void) |
static void | prvInitialiseTaskLists (void) |
static void | prvInitialiseTCBVariables (tskTCB *pxTCB, const signed char *const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion *const xRegions, unsigned short usStackDepth) PRIVILEGED_FUNCTION |
static void | prvListTaskWithinSingleList (const signed char *pcWriteBuffer, xList *pxList, signed char cStatus) |
unsigned long | ulTaskEndTrace (void) |
static unsigned short | usTaskCheckFreeStackSpace (const unsigned char *pucStackByte) |
unsigned portBASE_TYPE | uxTaskGetNumberOfTasks (void) |
unsigned portBASE_TYPE | uxTaskGetStackHighWaterMark (xTaskHandle xTask) |
task.h More... | |
void | vApplicationStackOverflowHook (xTaskHandle *pxTask, signed char *pcTaskName) |
Called if stack overflow during execution. More... | |
void | vApplicationTickHook (void) |
This function is called by FreeRTOS each tick. More... | |
void | vTaskDelay (portTickType xTicksToDelay) |
void | vTaskEndScheduler (void) |
void | vTaskIncrementTick (void) |
void | vTaskList (signed char *pcWriteBuffer) |
void | vTaskMissedYield (void) |
void | vTaskPlaceOnEventList (const xList *const pxEventList, portTickType xTicksToWait) |
void | vTaskPriorityDisinherit (xTaskHandle *const pxMutexHolder) |
void | vTaskPriorityInherit (xTaskHandle *const pxMutexHolder) |
void | vTaskPrioritySet (xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority) |
void | vTaskResume (xTaskHandle pxTaskToResume) |
void | vTaskSetTimeOutState (xTimeOutType *const pxTimeOut) |
void | vTaskStartScheduler (void) |
void | vTaskStartTrace (signed char *pcBuffer, unsigned long ulBufferSize) |
void | vTaskSuspend (xTaskHandle pxTaskToSuspend) |
void | vTaskSuspendAll (void) |
void | vTaskSwitchContext (void) |
portBASE_TYPE | xTaskCheckForTimeOut (xTimeOutType *const pxTimeOut, portTickType *const pxTicksToWait) |
xTaskHandle | xTaskGetCurrentTaskHandle (void) |
portTickType | xTaskGetTickCount (void) |
portTickType | xTaskGetTickCountFromISR (void) |
signed portBASE_TYPE | xTaskIsTaskSuspended (xTaskHandle xTask) |
task. More... | |
signed portBASE_TYPE | xTaskRemoveFromEventList (const xList *const pxEventList) |
signed portBASE_TYPE | xTaskResumeAll (void) |
portBASE_TYPE | xTaskResumeFromISR (xTaskHandle pxTaskToResume) |
Variables | |
static PRIVILEGED_DATA char | pcStatusString [50] |
static PRIVILEGED_DATA volatile signed char *volatile | pcTraceBuffer |
static PRIVILEGED_DATA signed char * | pcTraceBufferEnd |
static PRIVILEGED_DATA signed char * | pcTraceBufferStart |
PRIVILEGED_DATA tskTCB *volatile | pxCurrentTCB = NULL |
static PRIVILEGED_DATA xList *volatile | pxDelayedTaskList |
static PRIVILEGED_DATA xList *volatile | pxOverflowDelayedTaskList |
static PRIVILEGED_DATA xList | pxReadyTasksLists [configMAX_PRIORITIES] |
static PRIVILEGED_DATA volatile unsigned portBASE_TYPE | uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0 |
static PRIVILEGED_DATA volatile unsigned portBASE_TYPE | uxMissedTicks = ( unsigned portBASE_TYPE ) 0 |
static unsigned portBASE_TYPE | uxPreviousTask = 255U |
static PRIVILEGED_DATA volatile unsigned portBASE_TYPE | uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE |
static PRIVILEGED_DATA unsigned portBASE_TYPE | uxTaskNumber = ( unsigned portBASE_TYPE ) 0 |
static PRIVILEGED_DATA volatile unsigned portBASE_TYPE | uxTopReadyPriority = tskIDLE_PRIORITY |
static PRIVILEGED_DATA unsigned portBASE_TYPE | uxTopUsedPriority = tskIDLE_PRIORITY |
static PRIVILEGED_DATA xList | xDelayedTaskList1 |
static PRIVILEGED_DATA xList | xDelayedTaskList2 |
static PRIVILEGED_DATA volatile portBASE_TYPE | xMissedYield = ( portBASE_TYPE ) pdFALSE |
static PRIVILEGED_DATA portTickType | xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY |
static PRIVILEGED_DATA volatile portBASE_TYPE | xNumOfOverflows = ( portBASE_TYPE ) 0 |
static PRIVILEGED_DATA xList | xPendingReadyList |
static PRIVILEGED_DATA volatile signed portBASE_TYPE | xSchedulerRunning = pdFALSE |
static PRIVILEGED_DATA xList | xSuspendedTaskList |
static PRIVILEGED_DATA volatile portTickType | xTickCount = ( portTickType ) 0 |
static PRIVILEGED_DATA signed portBASE_TYPE | xTracing = pdFALSE |
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE |
#define prvAddTaskToReadyQueue | ( | pxTCB | ) |
Referenced by prvInitialiseTaskLists(), vTaskPriorityDisinherit(), vTaskPriorityInherit(), vTaskPrioritySet(), vTaskResume(), xTaskRemoveFromEventList(), xTaskResumeAll(), and xTaskResumeFromISR().
#define prvCheckDelayedTasks | ( | ) |
Referenced by vTaskIncrementTick().
#define prvGetTCBFromHandle | ( | pxHandle | ) | ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) ) |
Referenced by uxTaskGetStackHighWaterMark(), vTaskPrioritySet(), and vTaskSuspend().
#define tskBLOCKED_CHAR ( ( signed char ) 'B' ) |
Referenced by vTaskList().
#define tskDELETED_CHAR ( ( signed char ) 'D' ) |
Referenced by vTaskList().
#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE |
Referenced by vTaskStartScheduler().
#define tskREADY_CHAR ( ( signed char ) 'R' ) |
Referenced by vTaskList().
#define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned long ) ( sizeof( unsigned long ) + sizeof( unsigned long ) ) ) |
Referenced by vTaskStartTrace().
#define tskSTACK_FILL_BYTE ( 0xa5U ) |
Referenced by prvAllocateTCBAndStack(), and usTaskCheckFreeStackSpace().
#define tskSUSPENDED_CHAR ( ( signed char ) 'S' ) |
Referenced by vTaskList().
#define vWriteTraceToBuffer | ( | ) |
Referenced by vTaskSwitchContext().
typedef struct tskTaskControlBlock tskTCB |
|
static |
|
static |
References listSET_LIST_ITEM_VALUE, pxCurrentTCB, pxDelayedTaskList, pxOverflowDelayedTaskList, vListInsert(), tskTaskControlBlock::xGenericListItem, xNextTaskUnblockTime, and xTickCount.
Referenced by vTaskDelay(), and vTaskPlaceOnEventList().
|
static |
References pvPortMalloc(), pvPortMallocAligned, tskTaskControlBlock::pxStack, tskSTACK_FILL_BYTE, and vPortFree().
Referenced by prvInitialiseTaskLists().
|
static |
|
static |
References configASSERT, configMAX_PRIORITIES, errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, pdFALSE, pdPASS, pdTRUE, portPRIVILEGE_BIT, portYIELD_WITHIN_API, prvAddTaskToReadyQueue, prvAllocateTCBAndStack(), prvInitialiseTCBVariables(), pxCurrentTCB, pxPortInitialiseStack(), tskTaskControlBlock::pxStack, tskTaskControlBlock::pxTopOfStack, taskENTER_CRITICAL, taskEXIT_CRITICAL, traceTASK_CREATE, traceTASK_CREATE_FAILED, uxCurrentNumberOfTasks, tskTaskControlBlock::uxPriority, uxTaskNumber, tskTaskControlBlock::uxTCBNumber, uxTopUsedPriority, and xSchedulerRunning.
|
static |
|
static |
References configMAX_PRIORITIES, configMAX_TASK_NAME_LEN, listSET_LIST_ITEM_OWNER, listSET_LIST_ITEM_VALUE, tskTaskControlBlock::pcTaskName, tskTaskControlBlock::pxStack, tskTaskControlBlock::uxBasePriority, tskTaskControlBlock::uxPriority, vListInitialiseItem(), tskTaskControlBlock::xEventListItem, and tskTaskControlBlock::xGenericListItem.
Referenced by prvInitialiseTaskLists().
|
static |
unsigned long ulTaskEndTrace | ( | void | ) |
References pcTraceBuffer, pcTraceBufferStart, pdFALSE, taskENTER_CRITICAL, taskEXIT_CRITICAL, and xTracing.
|
static |
References tskSTACK_FILL_BYTE.
Referenced by prvListTaskWithinSingleList(), and uxTaskGetStackHighWaterMark().
unsigned portBASE_TYPE uxTaskGetNumberOfTasks | ( | void | ) |
References uxCurrentNumberOfTasks.
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark | ( | xTaskHandle | xTask | ) |
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for this function to be available.
Returns the high water mark of the stack associated with xTask. That is, the minimum free stack space there has been (in words, so on a 32 bit machine a value of 1 means 4 bytes) since the task started. The smaller the returned number the closer the task has come to overflowing its stack.
xTask | Handle of the task associated with the stack to be checked. Set xTask to NULL to check the stack of the calling task. |
References prvGetTCBFromHandle, tskTaskControlBlock::pxStack, and usTaskCheckFreeStackSpace().
void vApplicationStackOverflowHook | ( | xTaskHandle * | pxTask, |
signed char * | pcTaskName | ||
) |
Called if stack overflow during execution.
void vApplicationTickHook | ( | void | ) |
This function is called by FreeRTOS each tick.
Referenced by vTaskIncrementTick().
void vTaskDelay | ( | portTickType | xTicksToDelay | ) |
References pdFALSE, portYIELD_WITHIN_API, prvAddCurrentTaskToDelayedList(), pxCurrentTCB, traceTASK_DELAY, vListRemove(), vTaskSuspendAll(), tskTaskControlBlock::xGenericListItem, xTaskResumeAll(), and xTickCount.
Referenced by task_win().
void vTaskEndScheduler | ( | void | ) |
References pdFALSE, vPortEndScheduler(), and xSchedulerRunning.
void vTaskIncrementTick | ( | void | ) |
References configASSERT, listGET_LIST_ITEM_VALUE, listGET_OWNER_OF_HEAD_ENTRY, listLIST_IS_EMPTY, pdFALSE, prvCheckDelayedTasks, pxDelayedTaskList, pxOverflowDelayedTaskList, traceTASK_INCREMENT_TICK, uxMissedTicks, uxSchedulerSuspended, vApplicationTickHook(), tskTaskControlBlock::xGenericListItem, xNextTaskUnblockTime, xNumOfOverflows, and xTickCount.
Referenced by xTaskResumeAll().
void vTaskList | ( | signed char * | pcWriteBuffer | ) |
References listLIST_IS_EMPTY, pdFALSE, prvListTaskWithinSingleList(), pxDelayedTaskList, pxOverflowDelayedTaskList, pxReadyTasksLists, tskBLOCKED_CHAR, tskDELETED_CHAR, tskIDLE_PRIORITY, tskREADY_CHAR, tskSUSPENDED_CHAR, uxTopUsedPriority, vTaskSuspendAll(), xSuspendedTaskList, and xTaskResumeAll().
void vTaskMissedYield | ( | void | ) |
References pdTRUE, and xMissedYield.
Referenced by prvUnlockQueue().
void vTaskPlaceOnEventList | ( | const xList *const | pxEventList, |
portTickType | xTicksToWait | ||
) |
void vTaskPriorityDisinherit | ( | xTaskHandle *const | pxMutexHolder | ) |
void vTaskPriorityInherit | ( | xTaskHandle *const | pxMutexHolder | ) |
References configASSERT, configMAX_PRIORITIES, listIS_CONTAINED_WITHIN, listSET_LIST_ITEM_VALUE, prvAddTaskToReadyQueue, pxCurrentTCB, pxReadyTasksLists, tskTaskControlBlock::uxPriority, vListRemove(), tskTaskControlBlock::xEventListItem, and tskTaskControlBlock::xGenericListItem.
Referenced by xQueueGenericReceive().
void vTaskPrioritySet | ( | xTaskHandle | pxTask, |
unsigned portBASE_TYPE | uxNewPriority | ||
) |
References configASSERT, configMAX_PRIORITIES, listIS_CONTAINED_WITHIN, listSET_LIST_ITEM_VALUE, pdFALSE, pdTRUE, portYIELD_WITHIN_API, prvAddTaskToReadyQueue, prvGetTCBFromHandle, pxCurrentTCB, pxReadyTasksLists, taskENTER_CRITICAL, taskEXIT_CRITICAL, traceTASK_PRIORITY_SET, tskTaskControlBlock::uxBasePriority, tskTaskControlBlock::uxPriority, vListRemove(), tskTaskControlBlock::xEventListItem, and tskTaskControlBlock::xGenericListItem.
void vTaskResume | ( | xTaskHandle | pxTaskToResume | ) |
void vTaskSetTimeOutState | ( | xTimeOutType *const | pxTimeOut | ) |
References configASSERT, xNumOfOverflows, xTIME_OUT::xOverflowCount, xTickCount, and xTIME_OUT::xTimeOnEntering.
Referenced by xQueueGenericReceive(), xQueueGenericSend(), and xTaskCheckForTimeOut().
void vTaskStartScheduler | ( | void | ) |
References configASSERT, pdPASS, pdTRUE, portCONFIGURE_TIMER_FOR_RUN_TIME_STATS, portPRIVILEGE_BIT, tskIDLE_PRIORITY, tskIDLE_STACK_SIZE, xPortStartScheduler(), xSchedulerRunning, xTaskCreate, xTickCount, and xTimerCreateTimerTask().
Referenced by main().
void vTaskStartTrace | ( | signed char * | pcBuffer, |
unsigned long | ulBufferSize | ||
) |
void vTaskSuspend | ( | xTaskHandle | pxTaskToSuspend | ) |
References pdFALSE, portYIELD_WITHIN_API, prvGetTCBFromHandle, xLIST_ITEM::pvContainer, pxCurrentTCB, taskENTER_CRITICAL, taskEXIT_CRITICAL, traceTASK_SUSPEND, uxCurrentNumberOfTasks, vListInsertEnd(), vListRemove(), vTaskSwitchContext(), tskTaskControlBlock::xEventListItem, tskTaskControlBlock::xGenericListItem, xSchedulerRunning, and xSuspendedTaskList.
void vTaskSuspendAll | ( | void | ) |
References uxSchedulerSuspended.
Referenced by prvCheckTasksWaitingTermination(), pvPortMalloc(), vPortFree(), vTaskDelay(), vTaskList(), xQueueGenericReceive(), and xQueueGenericSend().
void vTaskSwitchContext | ( | void | ) |
References configASSERT, listGET_OWNER_OF_NEXT_ENTRY, listLIST_IS_EMPTY, pdFALSE, pdTRUE, pxCurrentTCB, pxReadyTasksLists, taskFIRST_CHECK_FOR_STACK_OVERFLOW, taskSECOND_CHECK_FOR_STACK_OVERFLOW, traceTASK_SWITCHED_IN, traceTASK_SWITCHED_OUT, uxSchedulerSuspended, uxTopReadyPriority, vWriteTraceToBuffer, and xMissedYield.
Referenced by vTaskSuspend().
portBASE_TYPE xTaskCheckForTimeOut | ( | xTimeOutType *const | pxTimeOut, |
portTickType *const | pxTicksToWait | ||
) |
References configASSERT, pdFALSE, pdTRUE, taskENTER_CRITICAL, taskEXIT_CRITICAL, vTaskSetTimeOutState(), xNumOfOverflows, xTIME_OUT::xOverflowCount, xTickCount, and xTIME_OUT::xTimeOnEntering.
Referenced by xQueueGenericReceive(), and xQueueGenericSend().
xTaskHandle xTaskGetCurrentTaskHandle | ( | void | ) |
References pxCurrentTCB.
Referenced by xQueueGenericReceive().
portTickType xTaskGetTickCount | ( | void | ) |
References taskENTER_CRITICAL, taskEXIT_CRITICAL, and xTickCount.
Referenced by prvCheckDelayedList().
portTickType xTaskGetTickCountFromISR | ( | void | ) |
References portCLEAR_INTERRUPT_MASK_FROM_ISR, portSET_INTERRUPT_MASK_FROM_ISR, and xTickCount.
signed portBASE_TYPE xTaskIsTaskSuspended | ( | xTaskHandle | xTask | ) |
task.
h
signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );
Utility task that simply returns pdTRUE if the task referenced by xTask is currently in the Suspended state, or pdFALSE if the task referenced by xTask is in any other state.
References configASSERT, listIS_CONTAINED_WITHIN, pdFALSE, pdTRUE, tskTaskControlBlock::xEventListItem, tskTaskControlBlock::xGenericListItem, xPendingReadyList, and xSuspendedTaskList.
Referenced by vTaskResume(), and xTaskResumeFromISR().
signed portBASE_TYPE xTaskRemoveFromEventList | ( | const xList *const | pxEventList | ) |
References configASSERT, listGET_OWNER_OF_HEAD_ENTRY, pdFALSE, pdTRUE, prvAddTaskToReadyQueue, pxCurrentTCB, tskTaskControlBlock::uxPriority, uxSchedulerSuspended, vListInsertEnd(), vListRemove(), tskTaskControlBlock::xEventListItem, tskTaskControlBlock::xGenericListItem, and xPendingReadyList.
Referenced by prvUnlockQueue(), xQueueGenericReceive(), xQueueGenericSend(), xQueueGenericSendFromISR(), and xQueueReceiveFromISR().
signed portBASE_TYPE xTaskResumeAll | ( | void | ) |
References configASSERT, listGET_OWNER_OF_HEAD_ENTRY, listLIST_IS_EMPTY, pdFALSE, pdTRUE, portYIELD_WITHIN_API, prvAddTaskToReadyQueue, pxCurrentTCB, taskENTER_CRITICAL, taskEXIT_CRITICAL, uxCurrentNumberOfTasks, uxMissedTicks, tskTaskControlBlock::uxPriority, uxSchedulerSuspended, vListRemove(), vTaskIncrementTick(), tskTaskControlBlock::xEventListItem, tskTaskControlBlock::xGenericListItem, xMissedYield, and xPendingReadyList.
Referenced by prvCheckTasksWaitingTermination(), pvPortMalloc(), vPortFree(), vTaskDelay(), vTaskList(), xQueueGenericReceive(), and xQueueGenericSend().
portBASE_TYPE xTaskResumeFromISR | ( | xTaskHandle | pxTaskToResume | ) |
References configASSERT, pdFALSE, pdTRUE, portCLEAR_INTERRUPT_MASK_FROM_ISR, portSET_INTERRUPT_MASK_FROM_ISR, prvAddTaskToReadyQueue, pxCurrentTCB, traceTASK_RESUME_FROM_ISR, tskTaskControlBlock::uxPriority, uxSchedulerSuspended, vListInsertEnd(), vListRemove(), tskTaskControlBlock::xEventListItem, tskTaskControlBlock::xGenericListItem, xPendingReadyList, and xTaskIsTaskSuspended().
|
static |
Referenced by prvListTaskWithinSingleList().
|
static |
Referenced by ulTaskEndTrace(), and vTaskStartTrace().
|
static |
Referenced by vTaskStartTrace().
|
static |
Referenced by ulTaskEndTrace(), and vTaskStartTrace().
PRIVILEGED_DATA tskTCB* volatile pxCurrentTCB = NULL |
Referenced by prvAddCurrentTaskToDelayedList(), prvInitialiseTaskLists(), vTaskDelay(), vTaskPlaceOnEventList(), vTaskPriorityInherit(), vTaskPrioritySet(), vTaskResume(), vTaskSuspend(), vTaskSwitchContext(), xTaskGetCurrentTaskHandle(), xTaskRemoveFromEventList(), xTaskResumeAll(), and xTaskResumeFromISR().
|
static |
Referenced by prvAddCurrentTaskToDelayedList(), prvInitialiseTaskLists(), vTaskIncrementTick(), and vTaskList().
|
static |
Referenced by prvAddCurrentTaskToDelayedList(), prvInitialiseTaskLists(), vTaskIncrementTick(), and vTaskList().
|
static |
Referenced by portTASK_FUNCTION(), prvInitialiseTaskLists(), vTaskList(), vTaskPriorityInherit(), vTaskPrioritySet(), and vTaskSwitchContext().
|
static |
|
static |
Referenced by vTaskIncrementTick(), and xTaskResumeAll().
|
static |
|
static |
|
static |
Referenced by prvInitialiseTaskLists().
|
static |
Referenced by vTaskSwitchContext().
|
static |
Referenced by prvInitialiseTaskLists(), and vTaskList().
|
static |
Referenced by prvInitialiseTaskLists().
|
static |
Referenced by prvInitialiseTaskLists().
|
static |
Referenced by vTaskMissedYield(), vTaskSwitchContext(), and xTaskResumeAll().
|
static |
Referenced by prvAddCurrentTaskToDelayedList(), and vTaskIncrementTick().
|
static |
Referenced by vTaskIncrementTick(), vTaskSetTimeOutState(), and xTaskCheckForTimeOut().
|
static |
Referenced by prvInitialiseTaskLists(), xTaskIsTaskSuspended(), xTaskRemoveFromEventList(), xTaskResumeAll(), and xTaskResumeFromISR().
|
static |
Referenced by prvInitialiseTaskLists(), vTaskEndScheduler(), vTaskStartScheduler(), and vTaskSuspend().
|
static |
Referenced by prvInitialiseTaskLists(), vTaskList(), vTaskPlaceOnEventList(), vTaskSuspend(), and xTaskIsTaskSuspended().
|
static |
|
static |
Referenced by ulTaskEndTrace(), and vTaskStartTrace().