From 64bd0689c764091e99ef5214366892cfdfb22c5c Mon Sep 17 00:00:00 2001
From: Richard Barry <ribarry@amazon.com>
Date: Wed, 5 Jun 2013 16:26:04 +0000
Subject: [PATCH] Update the standard Win32 demo to use the latest version of
 the trace recorder code.
---
 FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h     |   4 +-
 .../Trace_Recorder_Configuration/trcConfig.h  | 265 ++++++++++++------
 .../{trcPort.h => trcHardwarePort.h}          | 150 +++++-----
 FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj        |   5 +-
 .../Demo/WIN32-MSVC/WIN32.vcxproj.filters     |  17 +-
 FreeRTOS/Demo/WIN32-MSVC/main.c               |  64 ++++-
 6 files changed, 325 insertions(+), 180 deletions(-)
 rename FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/{trcPort.h => trcHardwarePort.h} (74%)
diff --git a/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h b/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
index 9327e89532..3640edc45f 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/WIN32-MSVC/FreeRTOSConfig.h
@@ -152,7 +152,7 @@ version of the Win32 simulator projects.  It will be ignored in the GCC
 version. */
 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
 
-/* Include the FreeRTOS+Trace recorder hooks. */
-#include "trcHooks.h"
+/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
+#include "trcKernelPort.h"
 
 #endif /* FREERTOS_CONFIG_H */
diff --git a/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h b/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h
index a2188b209e..7a38d67ae8 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h
+++ b/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h
@@ -1,6 +1,6 @@
 /*******************************************************************************
- * FreeRTOS+Trace v2.2.2 Recorder Library
- * Percepio AB, www.percepio.se
+ * Tracealyzer v2.4.1 Recorder Library
+ * Percepio AB, www.percepio.com
  *
  * trcConfig.h
  *
@@ -9,12 +9,12 @@
  * appropriate for your system, and if necessary adjust these. Most likely, you 
  * will need to adjust the NTask, NISR, NQueue, NMutex and NSemaphore values to 
  * reflect the number of such objects in your system. These may be 
- * overapproximated, although larger values values implies more RAM usage.
+ * over-approximated, although larger values values implies more RAM usage.
  *
  * Terms of Use
  * This software is copyright Percepio AB. The recorder library is free for
  * use together with Percepio products. You may distribute the recorder library
- * in its original form, including modifications in trcPort.c and trcPort.h
+ * in its original form, including modifications in trcHardwarePort.c/.h
  * given that these modification are clearly marked as your own modifications
  * and documented in the initial comment section of these source files. 
  * This software is the intellectual property of Percepio AB and may not be 
@@ -36,17 +36,15 @@
  * damages, or the exclusion of implied warranties or limitations on how long an 
  * implied warranty may last, so the above limitations may not apply to you.
  *
- * FreeRTOS+Trace is available as Free Edition and in two premium editions.
- * You may use the premium features during 30 days for evaluation.
- * Download FreeRTOS+Trace at http://www.percepio.se/index.php?page=downloads
- *
- * Copyright Percepio AB, 2012.
- * www.percepio.se
+ * Copyright Percepio AB, 2013.
+ * www.percepio.com
  ******************************************************************************/
 
 #ifndef TRCCONFIG_H
 #define TRCCONFIG_H
 
+#include <stdint.h>
+
 /*******************************************************************************
  * CONFIGURATION RELATED TO CAPACITY AND ALLOCATION 
  ******************************************************************************/
@@ -61,11 +59,30 @@
  * vTracePrintF may use multiple records depending on the number of data args.
  ******************************************************************************/
 
-#if WIN32
-    #define EVENT_BUFFER_SIZE 3000
-#else
-    #define EVENT_BUFFER_SIZE 1000 /* Adjust wrt. to available RAM */
-#endif
+#define EVENT_BUFFER_SIZE 100000 /* Adjust wrt. to available RAM */
+
+
+/*******************************************************************************
+ * USE_LINKER_PRAGMA
+ *
+ * Macro which should be defined as an integer value, default is 0.
+ *
+ * If this is 1, the header file "recorderdata_linker_pragma.h" is included just
+ * before the declaration of RecorderData (in trcBase.c), i.e., the trace data 
+ * structure. This allows the user to specify a pragma with linker options. 
+ *
+ * Example (for IAR Embedded Workbench and NXP LPC17xx):
+ * #pragma location="AHB_RAM_MEMORY"
+ * 
+ * This example instructs the IAR linker to place RecorderData in another RAM 
+ * bank, the AHB RAM. This can also be used for other compilers with a similar
+ * pragmas for linker options.
+ * 
+ * Note that this only applies if using static allocation, see below.
+ ******************************************************************************/
+
+#define USE_LINKER_PRAGMA 0
+
 
 /*******************************************************************************
  * SYMBOL_TABLE_SIZE
@@ -78,7 +95,44 @@
  * Object Table. Thus, if you don't use User Events or delete any kernel 
  * objects you set this to zero (0) to minimize RAM usage.
  ******************************************************************************/
-#define SYMBOL_TABLE_SIZE 1000
+#define SYMBOL_TABLE_SIZE 5000
+
+/*******************************************************************************
+ * USE_SEPARATE_USER_EVENT_BUFFER
+ *
+ * Macro which should be defined as an integer value.
+ * Default is zero (0).
+ *
+ * This enables and disables the use of the separate user event buffer.
+ *
+ * Note: When using the separate user event buffer, you may get an artificial
+ * task instance named "Unknown actor". This is added as a placeholder when the 
+ * user event history is longer than the task scheduling history.
+ ******************************************************************************/
+#define USE_SEPARATE_USER_EVENT_BUFFER 0
+
+/*******************************************************************************
+ * USER_EVENT_BUFFER_SIZE
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * This defines the capacity of the user event buffer, in number of slots.
+ * A single user event can use between 1 and X slots, depending on the data.
+ *
+ * Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
+ ******************************************************************************/
+#define USER_EVENT_BUFFER_SIZE 500
+
+/*******************************************************************************
+ * USER_EVENT_CHANNELS
+ *
+ * Macro which should be defined as an integer value.
+ *
+ * This defines the number of allowed user event channels.
+ *
+ * Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
+ ******************************************************************************/
+#define CHANNEL_FORMAT_PAIRS 32
 
 /*******************************************************************************
  * NTask, NISR, NQueue, NSemaphore, NMutex
@@ -95,32 +149,33 @@
  *
  * Using too small values will give an error message through the vTraceError
  * routine, which makes the error message appear when opening the trace data
- * in FreeRTOS+Trace. If you are using the recorder status monitor task,
+ * in Tracealyzer. If you are using the recorder status monitor task,
  * any error messages are displayed in console prints, assuming that the
- * print macro has been defined properly (vConsolePrintMessage).
+ * print macro has been defined properly (vConsolePrintMessage). 
+ *
+ * It can be wise to start with very large values for these constants, 
+ * unless you are very confident on these numbers. Then do a recording and
+ * check the actual usage in Tracealyzer. This is shown by selecting
+ * View -> Trace Details -> Resource Usage -> Object Table
  * 
- * NOTE 2: If you include the monitor task (USE_TRACE_PROGRESS_MONITOR_TASK)
- * make sure to dimension NTask with this task accounted for.
+ * NOTE 2: Remember to account for all tasks created by the kernel, such as the 
+ * IDLE task, timer task, and any tasks created by other 3rd party 
+ * software components, such as communication stacks. The recorder also has an 
+ * optional monitor task to account for, if this is used.
+ * Moreover, one task slot is used to indicate "(startup)", i.e., a fictive 
+ * task that represent the time before the scheduler starts. 
+ * NTask should thus be at least 2-3 slots larger than your application task count.
  *
- * Also remember to account for all tasks created by FreeRTOS, such as the 
- * IDLE task, the FreeRTOS timer task, and any tasks created by other 3rd party 
- * software components, such as communication stacks.
- * Moreover, one task slot is used to indicate "(startup)", i.e., a "task" that 
- * represent the time before the first task starts. NTask should thus be at 
- * least 2-3 slots larger than your application task count.
- *
- * NOTE 3: The FreeRTOS timer task creates a Queue, that should be accounted 
- * for in NQueue.
  ******************************************************************************/
-#define NTask             ( 200 )
-#define NISR              ( 200 )
-#define NQueue            ( 200 )
-#define NSemaphore        ( 200 )
-#define NMutex            ( 200 )
+#define NTask             100
+#define NISR              20
+#define NQueue            60
+#define NSemaphore        60
+#define NMutex            60
 
 /* Maximum object name length for each class (includes zero termination) */
-#define NameLenTask       configMAX_TASK_NAME_LEN
-#define NameLenISR        10
+#define NameLenTask       15
+#define NameLenISR        15
 #define NameLenQueue      15
 #define NameLenSemaphore  15
 #define NameLenMutex      15
@@ -130,12 +185,12 @@
  *
  * Macro which should be defined as a string.
  *
- * This string is stored in the trace and displayed in FreeRTOS+Trace. Can be
+ * This string is stored in the trace and displayed in Tracealyzer. Can be
  * used to store, e.g., system version or build date. This is also used to store
  * internal error messages from the recorder, which if occurs overwrites the
  * value defined here. This may be maximum 256 chars.
  *****************************************************************************/
-#define TRACE_DESCRIPTION "FreeRTOS+Trace Demo"
+#define TRACE_DESCRIPTION "Tracealyzer Recorder Test Program"
 
 /******************************************************************************
  * TRACE_DESCRIPTION_MAX_LENGTH
@@ -173,6 +228,33 @@
  * CONFIGURATION REGARDING WHAT CODE/FEATURES TO INCLUDE
  *****************************************************************************/
 
+/******************************************************************************
+ * USE_TRACE_ASSERT
+ *
+ * Macro which should be defined as either zero (0) or one (1). 
+ * Default is 0.
+ *
+ * If this is one (1), the TRACE_ASSERT macro will verify that a condition is 
+ * true. If the condition is false, vTraceError() will be called.
+ *****************************************************************************/
+#define USE_TRACE_ASSERT 1
+
+/******************************************************************************
+ * INCLUDE_FLOAT_SUPPORT
+ *
+ * Macro which should be defined as either zero (0) or one (1). 
+ * Default is 1.
+ *
+ * If this is zero (0), all references to floating point values are removed,
+ * in case floating point values are not supported by the platform used.
+ * Floating point values are only used in vTracePrintF and its subroutines, to 
+ * store float (%f) or double (%lf) argments. 
+ *
+ * Note: vTracePrintF can still be used with integer and string arguments in
+ * either case.
+ *****************************************************************************/
+#define INCLUDE_FLOAT_SUPPORT 0
+
 /******************************************************************************
  * INCLUDE_USER_EVENTS
  *
@@ -185,11 +267,34 @@
  * much faster than a printf and can therefore be used in timing critical code.
  * See vTraceUserEvent() and vTracePrintF() in trcUser.h
  * 
- * Note that FreeRTOS+Trace Standard Edition or Professional Edition is required
- * for User Events, they are not displayed in FreeRTOS+Trace Free Edition.
+ * Note that Tracealyzer Standard Edition or Professional Edition is required
+ * for User Events, they are not displayed in Tracealyzer Free Edition.
  *****************************************************************************/
 #define INCLUDE_USER_EVENTS 1
 
+/*****************************************************************************
+ * INCLUDE_READY_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1). 
+ * Default is 1.
+ *
+ * If this is zero (0), the code for recording Ready events is 
+ * excluded. Note, this will make it impossible to calculate the correct
+ * response times.
+ *****************************************************************************/
+#define INCLUDE_READY_EVENTS 1
+
+/*****************************************************************************
+ * INCLUDE_NEW_TIME_EVENTS
+ *
+ * Macro which should be defined as either zero (0) or one (1). 
+ * Default is 0.
+ *
+ * If this is zero (1), events will be generated whenever the os clock is
+ * increased.
+ *****************************************************************************/
+#define INCLUDE_NEW_TIME_EVENTS 0
+
 /*****************************************************************************
  * INCLUDE_ISR_TRACING
  *
@@ -197,10 +302,11 @@
  * Default is 1.
  *
  * If this is zero (0), the code for recording Interrupt Service Routines is 
- * excluded to reduce code size. Note, recording ISRs require that you insert
- * calls to vTraceStoreISRBegin and vTraceStoreISREnd in your interrupt handlers.
- * There is no automatic recording of ISRs like for task scheduling, since 
- * FreeRTOS does not have a central interrupt dispatcher.
+ * excluded to reduce code size.
+ * 
+ * Note, if the kernel has no central interrupt dispatcher, recording ISRs 
+ * require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd 
+ * in your interrupt handlers.
  *****************************************************************************/
 #define INCLUDE_ISR_TRACING 1
 
@@ -211,43 +317,42 @@
  * Default is 1.
  *
  * This must be enabled (1) if tasks, queues or other 
- * traced kernel objects are deleted at runtime, e.g., using vTaskDelete or 
- * vQueueDelete. If no deletes are made, this can be set to 0 in order to
- * exclude the delete-handling code. 
+ * traced kernel objects are deleted at runtime. If no deletes are made, this 
+ * can be set to 0 in order to exclude the delete-handling code.
  *****************************************************************************/
-#define INCLUDE_OBJECT_DELETE 1
+#define INCLUDE_OBJECT_DELETE 0
 
 /******************************************************************************
  * CONFIGURATION RELATED TO BEHAVIOR
  *****************************************************************************/
 
 /******************************************************************************
- * RECORDER_STORE_MODE
+ * TRACE_RECORDER_STORE_MODE
  *
  * Macro which should be defined as one of:
- * - STORE_MODE_RING_BUFFER
- * - STORE_MODE_STOP_WHEN_FULL
- * Default is STORE_MODE_RING_BUFFER.
+ * - TRACE_STORE_MODE_RING_BUFFER
+ * - TRACE_STORE_MODE_STOP_WHEN_FULL
+ * Default is TRACE_STORE_MODE_RING_BUFFER.
  *
- * With RECORDER_STORE_MODE set to STORE_MODE_RING_BUFFER, the events are stored
- * in a ring buffer, i.e., where the oldest events are overwritten when the
- * buffer becomes full. This allows you to get the last events leading up to an
- * interesting state, e.g., an error, without having a large trace buffer for
- * string the whole run since startup. In this mode, the recorder can run
+ * With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the events are 
+ * stored in a ring buffer, i.e., where the oldest events are overwritten when 
+ * the buffer becomes full. This allows you to get the last events leading up 
+ * to an interesting state, e.g., an error, without having a large trace buffer
+ * for string the whole run since startup. In this mode, the recorder can run
  * "forever" as the buffer never gets full, i.e., in the sense that it always
  * has room for more events.
  *
- * To fetch the trace in mode STORE_MODE_RING_BUFFER, you need to first halt the
+ * To fetch the trace in mode TRACE_STORE_MODE_RING_BUFFER, you need to first halt the
  * system using your debugger and then do a RAM dump, or to explicitly stop the
  * recorder using vTraceStop() and then store/upload the trace data using a
- * FreeRTOS task that you need to provide yourself. The trace data is found in
- * the struct RecorderData, initialized in trcBase.c.
+ * task that you need to provide yourself. The trace data is found in the struct
+ * RecorderData, initialized in trcBase.c.
  *
  * Note that, if you upload the trace using a RAM dump, i.e., when the system is 
  * halted on a breakpoint or by a debugger command, there is no need to stop the 
  * recorder first.
  *
- * When RECORDER_STORE_MODE is STORE_MODE_STOP_WHEN_FULL, the recording is
+ * When TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the recording is
  * stopped when the buffer becomes full. When the recorder stops itself this way
  * vTracePortEnd() is called which allows for custom actions, such as triggering
  * a task that stores the trace buffer, i.e., in case taking a RAM dump
@@ -255,8 +360,8 @@
  * saves the trace to file directly, but this is not recommended in a real-time
  * system since the scheduler is blocked during the processing of vTracePortEnd.
  *****************************************************************************/
-#define RECORDER_STORE_MODE STORE_MODE_RING_BUFFER
-/*#define RECORDER_STORE_MODE STORE_MODE_STOP_WHEN_FULL*/
+
+#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
 
 /******************************************************************************
  * STOP_AFTER_N_EVENTS
@@ -283,27 +388,21 @@
  *
  * For tasks with "infinite" main loops (non-terminating tasks), the concept
  * of a task instance has no clear definition, it is an application-specific
- * thing. FreeRTOS+Trace allows you to define Instance Finish Events (IFEs),
+ * thing. Tracealyzer allows you to define Instance Finish Events (IFEs),
  * which marks the point in a cyclic task when the "task instance" ends.
  * The IFE is a blocking kernel call, typically in the main loop of a task
  * which typically reads a message queue, waits for a semaphore or performs
  * an explicit delay.
  *
- * If USE_IMPLICIT_IFE_RULES is one (1), the following FreeRTOS kernel calls
- * are considered by default to be IFEs (Implicit IFEs):
- *  - vTaskDelay
- *  - vTaskDelayUntil
- *  - vTaskSuspend
- *  - xQueueReceive (blocking cases only)
- *  - xSemaphoreTake (blocking cases only)
+ * If USE_IMPLICIT_IFE_RULES is one (1), the kernel macros (trcKernelPort.h)
+ * will define what kernel calls are considered by default to be IFEs.
  *
- * However, Implicit IFEs only applies to blocking kernel calls. If an
- * xQueueReceive reads a message without blocking, it does not create a new
+ * However, Implicit IFEs only applies to blocking kernel calls. If a
+ * service reads a message without blocking, it does not create a new
  * instance since no blocking occurred.
  *
- * Moreover, the actual IFE might sometimes be another blocking call such as
- * xQueueSend or xSemaphoreGive. We therefore allow for user-defined
- * Explicit IFEs by calling
+ * Moreover, the actual IFE might sometimes be another blocking call. We 
+ * therefore allow for user-defined Explicit IFEs by calling
  *
  *     vTraceTaskInstanceIsFinished()
  *
@@ -311,8 +410,8 @@
  * additional event but instead stores the service code and object handle
  * of the IFE call as properties of the task.
  *
- * If using Explicit IFEs and the task also calls an Implicit IFE like
- * vTaskDelay, this may result in additional incorrect task instances.
+ * If using Explicit IFEs and the task also calls an Implicit IFE, this may 
+ * result in additional incorrect task instances.
  * This is solved by disabling the Implicit IFEs for the task, by adding
  * a call to
  * 
@@ -360,7 +459,7 @@
  * 
  * See vTraceMonitorTask in trcUser.c
  *****************************************************************************/
-#define TRACE_PROGRESS_MONITOR_TASK_PRIORITY (tskIDLE_PRIORITY + 3)
+#define TRACE_PROGRESS_MONITOR_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
 
 /******************************************************************************
  * TRACE_PROGRESS_MONITOR_TASK_STACKSIZE
@@ -386,13 +485,13 @@
  * be mapped to your console "printf" routine. The task is named TraceMon but 
  * is intentionally excluded from the demo trace.
  *
- * Default is 1000 FreeRTOS ticks (typically 1 second). On the Windows port, a 
- * lower value is suggested since the Windows port runs very slowly, often 20-40
- * times slower than the simulated FreeRTOS time.
+ * Default is 1000 ticks (typically 1 second). On the Windows port, a lower 
+ * value is suggested since the Windows port runs very slowly, often 20-40
+ * times slower than the simulated time.
  *
  * See vTraceMonitorTask in trcUser.c
  *****************************************************************************/
-#if WIN32
+#ifdef WIN32
     #define TRACE_PROGRESS_MONITOR_TASK_PERIOD 100
 #else
     #define TRACE_PROGRESS_MONITOR_TASK_PERIOD 1000
diff --git a/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcPort.h b/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcHardwarePort.h
similarity index 74%
rename from FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcPort.h
rename to FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcHardwarePort.h
index c343d51340..ac8347765a 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcPort.h
+++ b/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcHardwarePort.h
@@ -1,11 +1,11 @@
 /******************************************************************************* 
- * FreeRTOS+Trace v2.3.0 Recorder Library
+ * Tracealyzer v2.4.1 Recorder Library
  * Percepio AB, www.percepio.com
  *
- * trcPort.h
+ * trcHardwarePort.h
  *
- * Contains together with trcPort.c all portability issues of the trace recorder 
- * library.
+ * Contains together with trcHardwarePort.c all hardware portability issues of 
+ * the trace recorder library.
  *
  * Terms of Use
  * This software is copyright Percepio AB. The recorder library is free for
@@ -32,18 +32,16 @@
  * damages, or the exclusion of implied warranties or limitations on how long an 
  * implied warranty may last, so the above limitations may not apply to you.
  *
- * FreeRTOS+Trace is available as Free Edition and in two premium editions.
- * You may use the premium features during 30 days for evaluation.
- * Download FreeRTOS+Trace at http://www.percepio.com/products/downloads/
- *
- * Copyright Percepio AB, 2012.
+ * Copyright Percepio AB, 2013.
  * www.percepio.com
  ******************************************************************************/
 
 #ifndef TRCPORT_H
 #define TRCPORT_H
 
-/* If FreeRTOS Win32 port */
+#include "trcKernelPort.h"
+
+/* If Win32 port */
 #ifdef WIN32
 
    #undef _WIN32_WINNT
@@ -61,9 +59,7 @@
  ******************************************************************************/
    #define WIN32_PORT_SAVE_WHEN_STOPPED 1
    #define WIN32_PORT_EXIT_WHEN_STOPPED 1
-#else
-	#define WIN32_PORT_SAVE_WHEN_STOPPED 0
-	#define WIN32_PORT_EXIT_WHEN_STOPPED 0
+
 #endif
 
 #define DIRECTION_INCREMENTING 1
@@ -76,16 +72,13 @@
  * A hardware independent fallback option for event timestamping. Provides low 
  * resolution timestamps based on the OS tick.
  * This may be used on the Win32 port, but may also be used on embedded hardware 
- * platforms. Note that this gives suboptimal display in FreeRTOS+Trace. All 
- * time durations will be truncated to the OS tick frequency, typically 1 KHz. 
- * This means that a task or ISR that executes in less than 1 ms get an exection 
- * time of zero. They are however still visible in FreeRTOS+Trace. 
+ * platforms. All time durations will be truncated to the OS tick frequency, 
+ * typically 1 KHz. This means that a task or ISR that executes in less than 
+ * 1 ms get an execution time of zero.
  *
  * PORT_Win32
- * "Accurate" timestamping based on the Windows permance counter. Note that
- * this gives the host machine time, not the simulated FreeRTOS time (tick 
- * count). The timing of the Win32 FreeRTOS build is not real-time, since it 
- * depends on the scheduling and tick rate of Windows, which is very slow.
+ * "Accurate" timestamping based on the Windows performance counter. Note that
+ * this gives the host machine time.
  *
  * Officially supported hardware timer ports:
  * - PORT_Atmel_AT91SAM7
@@ -98,7 +91,7 @@
  * been developed by external contributors, and have not yet been verified 
  * by Percepio AB. Let us know if you have problems getting these to work.
  * 
- * Unoffical hardware specific ports provided are:
+ * Unofficial hardware specific ports provided are:
  * - PORT_TEXAS_INSTRUMENTS_TMS570
  * - PORT_TEXAS_INSTRUMENTS_MSP430
  * - PORT_MICROCHIP_PIC32
@@ -142,29 +135,29 @@
  *
  * Macro which should be defined as an integer of 0 or 1.
  *
- * This should be 0 if lower irq priority values implies higher priority 
+ * This should be 0 if lower IRQ priority values implies higher priority 
  * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., 
- * if higher irq priority values means higher priority, this should be 1.
+ * if higher IRQ priority values means higher priority, this should be 1.
  *
  * This setting is not critical. It is used only to sort and colorize the 
  * interrupts in priority order, in case you record interrupts using
  * the vTraceStoreISRBegin and vTraceStoreISREnd routines.
  *
  * We provide this setting for some hardware architectures below:
- * - ARM Cortex M:       0 (lower irq priority values are more significant)
- * - Atmel AT91SAM7x:    1 (higher irq priority values are more significant)
- * - Atmel AVR32:        1 (higher irq priority values are more significant)
- * - Renesas RX600:      1 (higher irq priority values are more significant)
- * - Microchip PIC24:    0 (lower irq priority values are more significant)
- * - Microchip dsPIC:    0 (lower irq priority values are more significant)
- * - TI TMS570:          0 (lower irq priority values are more significant)
- * - Freescale HCS08:    0 (lower irq priority values are more significant)
- * - Freescale HCS12:    0 (lower irq priority values are more significant)
- * - PowerPC 405:        0 (lower irq priority values are more significant)
- * - PowerPC 440:        0 (lower irq priority values are more significant)
- * - Freescale ColdFire: 1 (higher irq priority values are more significant)
- * - NXP LPC210x:        0 (lower irq priority values are more significant)
- * - MicroBlaze:        0  (lower irq priority values are more significant)
+ * - ARM Cortex M:       0 (lower IRQ priority values are more significant)
+ * - Atmel AT91SAM7x:    1 (higher IRQ priority values are more significant)
+ * - Atmel AVR32:        1 (higher IRQ priority values are more significant)
+ * - Renesas RX600:      1 (higher IRQ priority values are more significant)
+ * - Microchip PIC24:    0 (lower IRQ priority values are more significant)
+ * - Microchip dsPIC:    0 (lower IRQ priority values are more significant)
+ * - TI TMS570:          0 (lower IRQ priority values are more significant)
+ * - Freescale HCS08:    0 (lower IRQ priority values are more significant)
+ * - Freescale HCS12:    0 (lower IRQ priority values are more significant)
+ * - PowerPC 405:        0 (lower IRQ priority values are more significant)
+ * - PowerPC 440:        0 (lower IRQ priority values are more significant)
+ * - Freescale ColdFire: 1 (higher IRQ priority values are more significant)
+ * - NXP LPC210x:        0 (lower IRQ priority values are more significant)
+ * - MicroBlaze:        0  (lower IRQ priority values are more significant)
  *
  * If your chip is not on the above list, and you perhaps know this detail by 
  * heart, please inform us by e-mail to support@percepio.com.
@@ -208,17 +201,9 @@
  * Cortex M chip running at 72 MHZ should use a HWTC_DIVISOR of 2, while a 
  * faster chip require a higher HWTC_DIVISOR value. 
  *
- * The HWTC macros and uiTracePortGetTimeStamp is the main porting issue
+ * The HWTC macros and vTracePortGetTimeStamp is the main porting issue
  * or the trace recorder library. Typically you should not need to change
- * the code of uiTracePortGetTimeStamp if using the HWTC macros.
- *
- * FREE LICENSE OFFER FROM PERCEPIO
- *
- * For silicon companies and non-corporate FreeRTOS users (researchers, students,
- * hobbyists or early-phase startups) we have the following offer: 
- * Provide a hardware port for our FreeRTOS recorder and get a FREE single-user
- * license for FreeRTOS+Trace Professional Edition. Read more about this offer
- * at www.percepio.com or contact us directly at support@percepio.com.
+ * the code of vTracePortGetTimeStamp if using the HWTC macros.
  *
  ******************************************************************************/
 
@@ -250,7 +235,7 @@
     #define HWTC_PERIOD 2995 
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 1  // higher irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_Atmel_UC3A0) 
   
@@ -258,10 +243,10 @@
   
     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
     #define HWTC_COUNT sysreg_read(AVR32_COUNT)
-    #define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
+    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
     #define HWTC_DIVISOR 1    
 
-    #define IRQ_PRIORITY_ORDER 1  // higher irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_ARM_CortexM)
 
@@ -272,7 +257,7 @@
     #define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)
     #define HWTC_DIVISOR 2
     
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_Renesas_RX600)    
 
@@ -280,10 +265,10 @@
 
     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
     #define HWTC_COUNT (CMT0.CMCNT)
-    #define HWTC_PERIOD ((((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/8))
+    #define HWTC_PERIOD ((((TRACE_PERIPHERAL_CLOCK_HZ/TRACE_TICK_RATE_HZ)-1)/8))
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 1  // higher irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_Microchip_dsPIC_AND_PIC24) 
 
@@ -292,7 +277,7 @@
     /* Note: The trace library was originally designed for 32-bit MCUs, and is slower
        than intended on 16-bit MCUs. Storing an event on a PIC24 takes about 70 �s. 
        In comparison, 32-bit MCUs are often 10-20 times faster. If recording overhead 
-       becomes a problem on PIC24, use the filters to exclude less interresting tasks 
+       becomes a problem on PIC24, use the filters to exclude less interesting tasks 
        or system calls. */
 
     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
@@ -300,21 +285,19 @@
     #define HWTC_PERIOD (PR1+1)
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_NXP_LPC210X)
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
     
-    /* Tested with LPC2106, but should work with most LPC21XX chips.
-       Assumption: prescaler is 1:1 (this setting is hardcoded in 
-       FreeRTOS port for LPC21XX) */
+    /* Tested with LPC2106, but should work with most LPC21XX chips. */
       
     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
     #define HWTC_COUNT  *((uint32_t *)0xE0004008 )
-    #define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) 
+    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ ) 
     #define HWTC_DIVISOR 1    
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_TMS570)
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
@@ -327,17 +310,17 @@
     #define HWTC_PERIOD (RTIUDCP0)
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_MSP430)
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
 
     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
     #define HWTC_COUNT (TA0R)
-    #define HWTC_PERIOD configCPU_CLOCKS_PER_TICK      
+    #define HWTC_PERIOD TRACE_CPU_CLOCKS_PER_TICK      
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 1  // higher irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_MICROCHIP_PIC32)
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
@@ -347,17 +330,17 @@
     #define HWTC_PERIOD (ReadPeriod1()+1) /* Should be available in BSP */
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_XILINX_PPC405) 
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
 
     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
     #define HWTC_COUNT  mfspr( 0x3db)
-    #define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
+    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
     #define HWTC_DIVISOR 1
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT == PORT_XILINX_PPC440) 
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
@@ -366,16 +349,15 @@
     
     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
     #define HWTC_COUNT  mfspr( 0x016 )
-    #define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
+    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
     #define HWTC_DIVISOR 1    
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
     
 #elif (SELECTED_PORT == PORT_XILINX_MICROBLAZE)
     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
 
-    /* This should work with most Microblaze configurations
-     * This port is based on the official FreeRTOS Microlaze port and example application.
+    /* This should work with most Microblaze configurations.
      * It uses the AXI Timer 0 - the tick interrupt source.
      * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
      */
@@ -383,10 +365,10 @@
 
     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
     #define HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
-    #define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
+    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
     #define HWTC_DIVISOR 16
 
-    #define IRQ_PRIORITY_ORDER 0  // lower irq priority values are more significant
+    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant
 
 #elif (SELECTED_PORT != PORT_NOT_SET)
 
@@ -436,26 +418,20 @@
 #include "console.h"
 #endif
 
-#define vTraceConsoleMessage printf
+#define vTraceConsoleMessage(x)
 
 /*******************************************************************************
- * uiTracePortGetTimeStamp
+ * vTracePortGetTimeStamp
  *
  * Returns the current time based on the HWTC macros which provide a hardware
  * isolation layer towards the hardware timer/counter.
  *
- * The HWTC macros and uiTracePortGetTimeStamp is the main porting issue
+ * The HWTC macros and vTracePortGetTimeStamp is the main porting issue
  * or the trace recorder library. Typically you should not need to change
- * the code of uiTracePortGetTimeStamp if using the HWTC macros.
+ * the code of vTracePortGetTimeStamp if using the HWTC macros.
  *
- * OFFER FROM PERCEPIO:
- * For silicon companies and non-corporate FreeRTOS users (researchers, 
- * students, hobbyists or early-phase startups) we have an attractive offer: 
- * Provide a hardware timer port and get a FREE single-user licence for
- * FreeRTOS+Trace Professional Edition. Read more about this offer at 
- * www.percepio.com or contact us directly at support@percepio.com.
  ******************************************************************************/
-void uiTracePortGetTimeStamp(uint32_t *puiTimestamp);
+void vTracePortGetTimeStamp(uint32_t *puiTimestamp);
 
 /*******************************************************************************
  * vTracePortEnd
@@ -487,6 +463,12 @@ void vTracePortSetOutFile(char* path);
  ******************************************************************************/
 void vTracePortSave(void);
 
+#else
+
+#define vTraceConsoleMessage(x)
+#define vTracePortSetOutFile(path)
+#define vTracePortSave(void)
+
 #endif
 
 #endif
diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
index 68d8a4b5c1..5dc922e254 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
+++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj
@@ -126,8 +126,9 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcBase.c" />
+    <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcHardwarePort.c" />
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcKernel.c" />
-    <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcPort.c" />
+    <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcKernelPort.c" />
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcUser.c" />
     <ClCompile Include="..\..\Source\croutine.c" />
     <ClCompile Include="..\..\Source\portable\MemMang\heap_4.c" />
@@ -187,7 +188,7 @@
     <ClInclude Include="..\..\Source\include\semphr.h" />
     <ClInclude Include="..\..\Source\include\task.h" />
     <ClInclude Include="Trace_Recorder_Configuration\trcConfig.h" />
-    <ClInclude Include="Trace_Recorder_Configuration\trcPort.h" />
+    <ClInclude Include="Trace_Recorder_Configuration\trcHardwarePort.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
index 0f54ca0806..9717019cfc 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
+++ b/FreeRTOS/Demo/WIN32-MSVC/WIN32.vcxproj.filters
@@ -109,15 +109,18 @@
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcKernel.c">
       <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcPort.c">
-      <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcUser.c">
       <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
     </ClCompile>
     <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcBase.c">
       <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcKernelPort.c">
+      <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-Trace\trcHardwarePort.c">
+      <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="FreeRTOSConfig.h">
@@ -156,11 +159,11 @@
     <ClInclude Include="..\..\Source\include\timer_test.h">
       <Filter>FreeRTOS Source\Include</Filter>
     </ClInclude>
-    <ClInclude Include="Trace_Recorder_Configuration\trcConfig.h">
-      <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
+    <ClInclude Include="Trace_Recorder_Configuration\trcHardwarePort.h">
+      <Filter>Configuration Files</Filter>
     </ClInclude>
-    <ClInclude Include="Trace_Recorder_Configuration\trcPort.h">
-      <Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
+    <ClInclude Include="Trace_Recorder_Configuration\trcConfig.h">
+      <Filter>Configuration Files</Filter>
     </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/FreeRTOS/Demo/WIN32-MSVC/main.c b/FreeRTOS/Demo/WIN32-MSVC/main.c
index e0099ea5fc..1160a05eac 100644
--- a/FreeRTOS/Demo/WIN32-MSVC/main.c
+++ b/FreeRTOS/Demo/WIN32-MSVC/main.c
@@ -79,6 +79,12 @@
  * application.  It is provided as a convenient development and demonstration
  * test bed only.  This was tested using Windows XP on a dual core laptop.
  *
+ * In this example, one simulated millisecond will take approximately 40ms to
+ * execute, and Windows will not be running the FreeRTOS simulator threads
+ * continuously, so the timing information in the FreeRTOS+Trace logs have no
+ * meaningful units.  See the documentation page for the Windows simulator for
+ * an explanation of the slow timing:
+ * http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
  * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -
  *******************************************************************************
  *
@@ -103,6 +109,7 @@
 /* Standard includes. */
 #include <stdio.h>
 #include <stdlib.h>
+#include <conio.h>
 
 /* Kernel includes. */
 #include <FreeRTOS.h>
@@ -147,6 +154,14 @@ static void prvCheckTask( void *pvParameters );
 eTaskStateGet(). */
 static void prvTestTask( void *pvParameters );
 
+/*
+ * Writes trace data to a disk file when the trace recording is stopped.
+ * This function will simply overwrite any trace files that already exist.
+ */
+static void prvSaveTraceFile( void );
+
+/*-----------------------------------------------------------*/
+
 /* The variable into which error messages are latched. */
 static char *pcStatusMessage = "OK";
 
@@ -154,10 +169,21 @@ static char *pcStatusMessage = "OK";
 semaphore tracing API functions.  It has no other purpose. */
 static xSemaphoreHandle xMutexToDelete = NULL;
 
+/* The user trace event posted to the trace recording on each tick interrupt.
+Note tick events will not appear in the trace recording with regular period
+because this project runs in a Windows simulator, and does not therefore
+exhibit deterministic behaviour. */
+traceLabel xTickTraceUserEvent;
+
 /*-----------------------------------------------------------*/
 
 int main( void )
 {
+	/* Initialise the trace recorder and create the label used to post user
+	events to the trace recording on each tick interrupt. */
+	vTraceInitTraceData();
+	xTickTraceUserEvent = xTraceOpenLabel( "tick" );
+
 	/* Start the check task as described at the top of this file. */
 	xTaskCreate( prvCheckTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
 
@@ -187,7 +213,8 @@ int main( void )
 
 	/* Start the trace recording - the recording is written to a file if
 	configASSERT() is called. */
-	vTraceStart();
+	printf( "\r\nTrace started.  Hit a key to dump trace file to disk.\r\n" );
+	uiTraceStart();
 
 	/* Start the scheduler itself. */
 	vTaskStartScheduler();
@@ -300,6 +327,7 @@ xTaskHandle xIdleTaskHandle, xTimerTaskHandle, xTestTask;
 signed char *pcTaskName;
 const unsigned char ucConstQueueNumber = 0xaaU, ucConstTaskNumber = 0x55U;
 void *pvAllocated;
+static portBASE_TYPE xTraceRunning = pdTRUE;
 
 /* These three functions are only meant for use by trace code, and not for
 direct use from application code, hence their prototypes are not in queue.h. */
@@ -399,6 +427,15 @@ extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );
 	allocations so there is no need to test here. */
 	pvAllocated = pvPortMalloc( ( rand() % 100 ) + 1 );
 	vPortFree( pvAllocated );
+
+	if( _kbhit() != pdFALSE )
+	{
+		if( xTraceRunning == pdTRUE )
+		{
+			prvSaveTraceFile();
+			xTraceRunning = pdFALSE;
+		}
+	}
 }
 /*-----------------------------------------------------------*/
 
@@ -424,6 +461,12 @@ void vApplicationTickHook( void )
 	/* Write to a queue that is in use as part of the queue set demo to 
 	demonstrate using queue sets from an ISR. */
 	vQueueSetAccessQueueSetFromISR();
+
+	/* Write a user event to the trace log.  
+	Note tick events will not appear in the trace recording with regular period
+	because this project runs in a Windows simulator, and does not therefore
+	exhibit deterministic behaviour. */
+	vTraceUserEvent( xTickTraceUserEvent );
 }
 /*-----------------------------------------------------------*/
 
@@ -433,9 +476,26 @@ void vAssertCalled( void )
 
 	/* Stop the trace recording. */
 	vTraceStop();
-	vTracePortSave();
+	prvSaveTraceFile();
 		
 	for( ;; );
 }
 /*-----------------------------------------------------------*/
 
+static void prvSaveTraceFile( void )
+{
+FILE* pxOutputFile;
+
+	fopen_s( &pxOutputFile, "Trace.dump", "wb");
+
+	if( pxOutputFile != NULL )
+	{
+		fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );
+		fclose( pxOutputFile );
+		printf( "\r\nTrace output saved to Trace.dump\r\n" );
+	}
+	else
+	{
+		printf( "\r\nFailed to create trace dump file\r\n" );
+	}
+}