Remove old trace recorder source from LPC18xx project.

pull/1/head
Richard Barry 12 years ago
parent 0ca2110982
commit d8248c49fc

@ -1,22 +0,0 @@
FreeRTOS+Trace v2.3.0
---------------------
This directory contains the recorder files that the typical FreeRTOS+Trace user needs to be aware of.
- trcPort.h - contains the hardware ports and the setting of what port to use.
- trcConfig.h - contains the recorder configuration.
The files in this directory are however not referenced by any of the demo projects.
Copies of these files are instead found in each Demo project directory.
These copies are included here to make the TraceRecorderSrc directory complete.
If you use this template, you will need to update the following macro definitions in trcPort.h:
- SELECTED_PORT
- IRQ_PRIORITY_ORDER
- vTraceConsoleMessage (optional, if console prints are desired)
Always remember to check the settings used in trcConfig.h.
Percepio AB
www.percepio.com

@ -1,465 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcConfig.h
*
* Configuration parameters for the trace recorder library. Before using the
* trace recorder library, please check that the default settings are
* 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.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCCONFIG_H
#define TRCCONFIG_H
/*******************************************************************************
* CONFIGURATION RELATED TO CAPACITY AND ALLOCATION
******************************************************************************/
/*******************************************************************************
* EVENT_BUFFER_SIZE
*
* Macro which should be defined as an integer value.
*
* This defines the capacity of the event buffer, i.e., the number of records
* it may store. Each registered event typically use one record (4 byte), but
* vTracePrintF may use multiple records depending on the number of data args.
******************************************************************************/
#define EVENT_BUFFER_SIZE 1000 /* 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
*
* Macro which should be defined as an integer value.
*
* This defines the capacity of the symbol table, in bytes. This symbol table
* stores User Events labels and names of deleted tasks, queues, or other kernel
* objects. Note that the names of active objects not stored here but in the
* 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
/*******************************************************************************
* NTask, NISR, NQueue, NSemaphore, NMutex
*
* A group of Macros which should be defined as an integer value of zero (0)
* or larger.
*
* This defines the capacity of the Object Property Table - the maximum number
* of objects active at any given point within each object class.
*
* NOTE: In case objects are deleted and created during runtime, this setting
* does not limit the total amount of objects, only the number of concurrently
* active objects.
*
* 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,
* any error messages are displayed in console prints, assuming that the
* 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 FreeRTOS+Trace. This is shown by selecting
* View -> Trace Details -> Resource Usage -> Object Table
*
* NOTE 2: 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. 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 FreeRTOS scheduler 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 15
#define NISR 4
#define NQueue 3
#define NSemaphore 4
#define NMutex 2
/* Maximum object name length for each class (includes zero termination) */
#define NameLenTask configMAX_TASK_NAME_LEN
#define NameLenISR 10
#define NameLenQueue 15
#define NameLenSemaphore 15
#define NameLenMutex 15
/******************************************************************************
* TRACE_DESCRIPTION
*
* Macro which should be defined as a string.
*
* This string is stored in the trace and displayed in FreeRTOS+Trace. 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"
/******************************************************************************
* TRACE_DESCRIPTION_MAX_LENGTH
*
* The maximum length (including zero termination) for the TRACE_DESCRIPTION
* string. Since this string also is used for internal error messages from the
* recorder do not make it too short, as this may truncate the error messages.
* Default is 80.
* Maximum allowed length is 256 - the trace will fail to load if longer.
*****************************************************************************/
#define TRACE_DESCRIPTION_MAX_LENGTH 80
/******************************************************************************
* TRACE_DATA_ALLOCATION
*
* This defines how to allocate the recorder data structure, i.e., using a
* static declaration or using a dynamic allocation in runtime (malloc).
*
* Should be one of these two options:
* - TRACE_DATA_ALLOCATION_STATIC (default)
* - TRACE_DATA_ALLOCATION_DYNAMIC
*
* Using static allocation has the benefits of compile-time errors if the buffer
* is too large (too large constants in trcConfig.h) and no need to call the
* initialization routine (xTraceInitTraceData).
*
* Using dynamic allocation may give more flexibility in some cases.
*****************************************************************************/
#define TRACE_DATA_ALLOCATION TRACE_DATA_ALLOCATION_STATIC
/******************************************************************************
* CONFIGURATION REGARDING WHAT CODE/FEATURES TO INCLUDE
*****************************************************************************/
/******************************************************************************
* 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 1
/******************************************************************************
* INCLUDE_USER_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
* Default is 1.
*
* If this is zero (0) the code for creating User Events is excluded to
* reduce code size. User Events are application-generated events, like
* "printf" but for the trace log instead of console output. User Events are
* 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.
*****************************************************************************/
#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_ISR_TRACING
*
* Macro which should be defined as either zero (0) or one (1).
* 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.
*****************************************************************************/
#define INCLUDE_ISR_TRACING 1
/******************************************************************************
* INCLUDE_OBJECT_DELETE
*
* Macro which should be defined as either zero (0) or one (1).
* 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.
*****************************************************************************/
#define INCLUDE_OBJECT_DELETE 1
/******************************************************************************
* CONFIGURATION RELATED TO BEHAVIOR
*****************************************************************************/
/******************************************************************************
* 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.
*
* 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
* "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
* 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.
*
* 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
* 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
* using an on-chip debugger is not possible. In the Windows port, vTracePortEnd
* 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.
*****************************************************************************/
#ifndef WIN32
#define RECORDER_STORE_MODE STORE_MODE_RING_BUFFER
#else
/* Default in the Win32 demo */
#define RECORDER_STORE_MODE STORE_MODE_STOP_WHEN_FULL
#endif
/******************************************************************************
* STOP_AFTER_N_EVENTS
*
* Macro which should be defined as an integer value, or not defined.
* Default is -1
*
* STOP_AFTER_N_EVENTS is intended for tests of the ring buffer mode (when
* RECORDER_STORE_MODE is STORE_MODE_RING_BUFFER). It stops the recording when
* the specified number of events has been observed. This value can be larger
* than the buffer size, to allow for test of the "wrapping around" that occurs
* in ring buffer mode . A negative value (or no definition of this macro)
* disables this feature.
*****************************************************************************/
#define STOP_AFTER_N_EVENTS -1
/******************************************************************************
* USE_IMPLICIT_IFE_RULES
*
* Macro which should be defined as either zero (0) or one (1).
* Default is 1.
*
* ### Instance Finish Events (IFE) ###
*
* 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),
* 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)
*
* However, Implicit IFEs only applies to blocking kernel calls. If an
* xQueueReceive 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
*
* vTraceTaskInstanceIsFinished()
*
* right before the kernel call considered as IFE. This does not create an
* 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.
* This is solved by disabling the Implicit IFEs for the task, by adding
* a call to
*
* vTraceTaskSkipDefaultInstanceFinishedEvents()
*
* in the very beginning of that task. This allows you to combine Explicit IFEs
* for some tasks with Implicit IFEs for the rest of the tasks, if
* USE_IMPLICIT_IFE_RULES is 1.
*
* By setting USE_IMPLICIT_IFE_RULES to zero (0), the implicit IFEs are disabled
* for all tasks. Tasks will then be considered to have a single instance only,
* covering all execution fragments, unless you define an explicit IFE in each
* task by calling vTraceTaskInstanceIsFinished before the blocking call.
*****************************************************************************/
#define USE_IMPLICIT_IFE_RULES 1
/******************************************************************************
* INCLUDE_SAVE_TO_FILE
*
* Macro which should be defined as either zero (0) or one (1).
* Default is 0.
*
* If enabled (1), the recorder will include code for saving the trace
* to a local file system.
******************************************************************************/
#ifdef WIN32
#define INCLUDE_SAVE_TO_FILE 1
#else
#define INCLUDE_SAVE_TO_FILE 0
#endif
/******************************************************************************
* TRACE_PROGRESS_MONITOR_TASK_PRIORITY
*
* Macro which sets the priority of the "recorder status monitor" task.
*
* This task, vTraceMonitorTask in trcUser.c, periodically writes
* the recorder status using the vTraceConsoleMessage macro, which is to
* be mapped to your console "printf" routine. The task is named TraceMon but
* is intentionally excluded from the demo trace.
*
* Default is tskIDLE_PRIORITY + 1
* Note that if your system constantly has a high CPU load from high-priority
* tasks, this might not be get a chance to execute.
*
* See vTraceMonitorTask in trcUser.c
*****************************************************************************/
#define TRACE_PROGRESS_MONITOR_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
/******************************************************************************
* TRACE_PROGRESS_MONITOR_TASK_STACKSIZE
*
* Macro which sets the stack size of the "recorder status monitor" task.
*
* This task, vTraceMonitorTask in trcUser.c, periodically writes
* the recorder status using the vTraceConsoleMessage macro, which is to
* be mapped to your console "printf" routine. The task is intentionally
* excluded from the demo trace.
*
* See vTraceMonitorTask in trcUser.c
*****************************************************************************/
#define TRACE_PROGRESS_MONITOR_TASK_STACKSIZE 500
/******************************************************************************
* TRACE_PROGRESS_MONITOR_TASK_PERIOD
*
* Macro which sets the period of the "recorder status monitor" task.
*
* This task, vTraceMonitorTask in trcUser.c, periodically writes
* the recorder status using the vTraceConsoleMessage macro, which is to
* 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.
*
* See vTraceMonitorTask in trcUser.c
*****************************************************************************/
#ifdef WIN32
#define TRACE_PROGRESS_MONITOR_TASK_PERIOD 100
#else
#define TRACE_PROGRESS_MONITOR_TASK_PERIOD 1000
#endif
/******************************************************************************
* TEAM_LICENSE_CODE
*
* Macro which defines a string - the team license code.
* If no team license is available, this should be an empty string "".
* This should be maximum 32 chars, including zero-termination.
*****************************************************************************/
#define TEAM_LICENSE_CODE ""
#endif

@ -1,490 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcPort.h
*
* Contains together with trcPort.c all portability issues of the trace recorder
* library.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCPORT_H
#define TRCPORT_H
/* If FreeRTOS Win32 port */
#ifdef WIN32
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
/* Standard includes. */
#include <stdio.h>
#include <windows.h>
#include <direct.h>
/*******************************************************************************
* The Win32 port by default saves the trace to file and then kills the
* program when the recorder is stopped, to facilitate quick, simple tests
* of the recorder.
******************************************************************************/
#define WIN32_PORT_SAVE_WHEN_STOPPED 1
#define WIN32_PORT_EXIT_WHEN_STOPPED 1
#endif
#define DIRECTION_INCREMENTING 1
#define DIRECTION_DECREMENTING 2
/******************************************************************************
* Supported ports
*
* PORT_HWIndependent
* 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.
*
* 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.
*
* Officially supported hardware timer ports:
* - PORT_Atmel_AT91SAM7
* - PORT_Atmel_UC3A0
* - PORT_ARM_CortexM
* - PORT_Renesas_RX600
* - PORT_Microchip_dsPIC_AND_PIC24
*
* We also provide several "unofficial" hardware-specific ports. There have
* 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:
* - PORT_TEXAS_INSTRUMENTS_TMS570
* - PORT_TEXAS_INSTRUMENTS_MSP430
* - PORT_MICROCHIP_PIC32
* - PORT_XILINX_PPC405
* - PORT_XILINX_PPC440
* - PORT_XILINX_MICROBLAZE
* - PORT_NXP_LPC210X
*
*****************************************************************************/
#define PORT_NOT_SET -1
/*** Officially supported hardware timer ports *******************************/
#define PORT_HWIndependent 0
#define PORT_Win32 1
#define PORT_Atmel_AT91SAM7 2
#define PORT_Atmel_UC3A0 3
#define PORT_ARM_CortexM 4
#define PORT_Renesas_RX600 5
#define PORT_Microchip_dsPIC_AND_PIC24 6
/*** Unofficial ports, provided by external developers, not yet verified *****/
#define PORT_TEXAS_INSTRUMENTS_TMS570 7
#define PORT_TEXAS_INSTRUMENTS_MSP430 8
#define PORT_MICROCHIP_PIC32 9
#define PORT_XILINX_PPC405 10
#define PORT_XILINX_PPC440 11
#define PORT_XILINX_MICROBLAZE 12
#define PORT_NXP_LPC210X 13
/*** Select your port here! **************************************************/
#define SELECTED_PORT PORT_NOT_SET
/*****************************************************************************/
#if (SELECTED_PORT == PORT_NOT_SET)
#error "You need to define SELECTED_PORT here!"
#endif
/*******************************************************************************
* IRQ_PRIORITY_ORDER
*
* Macro which should be defined as an integer of 0 or 1.
*
* 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.
*
* 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)
*
* 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.
*
******************************************************************************
*
* HWTC Macros
*
* These four HWTC macros provides a hardware isolation layer representing a
* generic hardware timer/counter used for driving the operating system tick,
* such as the SysTick feature of ARM Cortex M3/M4, or the PIT of the Atmel
* AT91SAM7X.
*
* HWTC_COUNT: The current value of the counter. This is expected to be reset
* a each tick interrupt. Thus, when the tick handler starts, the counter has
* already wrapped.
*
* HWTC_COUNT_DIRECTION: Should be one of:
* - DIRECTION_INCREMENTING - for hardware timer/counters of incrementing type
* such as the PIT on Atmel AT91SAM7X.
* When the counter value reach HWTC_PERIOD, it is reset to zero and the
* interrupt is signaled.
* - DIRECTION_DECREMENTING - for hardware timer/counters of decrementing type
* such as the SysTick on ARM Cortex M3/M4 chips.
* When the counter value reach 0, it is reset to HWTC_PERIOD and the
* interrupt is signaled.
*
* HWTC_PERIOD: The number of increments or decrements of HWTC_COUNT between
* two tick interrupts. This should preferably be mapped to the reload
* register of the hardware timer, to make it more portable between chips in the
* same family. The macro should in most cases be (reload register + 1).
*
* HWTC_DIVISOR: If the timer frequency is very high, like on the Cortex M chips
* (where the SysTick runs at the core clock frequency), the "differential
* timestamping" used in the recorder will more frequently insert extra XTS
* events to store the timestamps, which increases the event buffer usage.
* In such cases, to reduce the number of XTS events and thereby get longer
* traces, you use HWTC_DIVISOR to scale down the timestamps and frequency.
* Assuming a OS tick rate of 1 KHz, it is suggested to keep the effective timer
* frequency below 65 MHz to avoid an excessive amount of XTS events. Thus, a
* 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
* 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.
*
******************************************************************************/
#if (SELECTED_PORT == PORT_Win32)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (ulGetRunTimeCounterValue())
#define HWTC_PERIOD 0
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // Please update according to your hardware...
#elif (SELECTED_PORT == PORT_HWIndependent)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT 0
#define HWTC_PERIOD 1
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // Please update according to your hardware...
#elif (SELECTED_PORT == PORT_Atmel_AT91SAM7)
/* HWTC_PERIOD is hardcoded for AT91SAM7X256-EK Board (48 MHz)
A more generic solution is to get the period from pxPIT->PITC_PIMR */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)
#define HWTC_PERIOD 2995
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
#elif (SELECTED_PORT == PORT_Atmel_UC3A0)
/* For Atmel AVR32 (AT32UC3A) */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT sysreg_read(AVR32_COUNT)
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
#elif (SELECTED_PORT == PORT_ARM_CortexM)
/* For all chips using ARM Cortex M cores */
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
#define HWTC_COUNT (*((uint32_t*)0xE000E018))
#define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)
#define HWTC_DIVISOR 2
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
#elif (SELECTED_PORT == PORT_Renesas_RX600)
#include "iodefine.h"
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (CMT0.CMCNT)
#define HWTC_PERIOD ((((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/8))
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
#elif (SELECTED_PORT == PORT_MICROCHIP_dsPIC_AND_PIC24)
/* For Microchip PIC24 and dsPIC (16 bit) */
/* 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
or system calls. */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (TMR1)
#define HWTC_PERIOD (PR1+1)
#define HWTC_DIVISOR 1
#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) */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT *((uint32_t *)0xE0004008 )
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define HWTC_DIVISOR 1
#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 */
#define RTIFRC0 *((uint32_t *)0xFFFFFC10)
#define RTICOMP0 *((uint32_t *)0xFFFFFC50)
#define RTIUDCP0 *((uint32_t *)0xFFFFFC54)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))
#define HWTC_PERIOD (RTIUDCP0)
#define HWTC_DIVISOR 1
#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_DIVISOR 1
#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 */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (ReadTimer1()) /* Should be available in BSP */
#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
#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_DIVISOR 1
#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 */
/* This should work with most PowerPC chips */
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
#define HWTC_COUNT mfspr( 0x016 )
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define HWTC_DIVISOR 1
#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.
* 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.
*/
#include "xtmrctr_l.h"
#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_DIVISOR 16
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
#elif (SELECTED_PORT != PORT_NOT_SET)
#error "SELECTED_PORT had unsupported value!"
#define SELECTED_PORT PORT_NOT_SET
#endif
#if (SELECTED_PORT != PORT_NOT_SET)
#ifndef HWTC_COUNT_DIRECTION
#error "HWTC_COUNT_DIRECTION is not set!"
#endif
#ifndef HWTC_COUNT
#error "HWTC_COUNT is not set!"
#endif
#ifndef HWTC_PERIOD
#error "HWTC_PERIOD is not set!"
#endif
#ifndef HWTC_DIVISOR
#error "HWTC_DIVISOR is not set!"
#endif
#ifndef IRQ_PRIORITY_ORDER
#error "IRQ_PRIORITY_ORDER is not set!"
#elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)
#error "IRQ_PRIORITY_ORDER has bad value!"
#endif
#if (HWTC_DIVISOR < 1)
#error "HWTC_DIVISOR must be a non-zero positive value!"
#endif
#endif
/*******************************************************************************
* vTraceConsoleMessage
*
* A wrapper for your system-specific console "printf" console output function.
* This needs to be correctly defined to see status reports from the trace
* status monitor task (this is defined in trcUser.c).
******************************************************************************/
#if (SELECTED_PORT == PORT_Atmel_AT91SAM7)
/* Port specific includes */
#include "console.h"
#endif
#define vTraceConsoleMessage(x)
/*******************************************************************************
* uiTracePortGetTimeStamp
*
* 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
* or the trace recorder library. Typically you should not need to change
* the code of uiTracePortGetTimeStamp 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);
/*******************************************************************************
* vTracePortEnd
*
* This function is called when the recorder is stopped due to full buffer.
* Mainly intended to show a message in the console.
* This is used by the Win32 port to store the trace to a file. The file path is
* set using vTracePortSetFileName.
******************************************************************************/
void vTracePortEnd(void);
#if (INCLUDE_SAVE_TO_FILE == 1)
/*******************************************************************************
* vTracePortSetOutFile
*
* Sets the filename/path used in vTracePortSave.
* This is set in a separate function, since the Win32 port calls vTracePortSave
* in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.
******************************************************************************/
void vTracePortSetOutFile(char* path);
/******************************************************************************
* vTracePortSave
*
* Saves the trace to a file on a target-side file system. The path is set in a
* separate function, vTracePortSetOutFile, since the Win32 port may call
* vTracePortSave in vTracePortEnd, if using WIN32_PORT_SAVE_WHEN_STOPPED.
******************************************************************************/
void vTracePortSave(void);
#endif
#endif

@ -1,524 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcBase.h
*
* Core functionallity of the FreeRTOS+Trace recorder library.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCBASE_H
#define TRCBASE_H
#include <stdio.h>
#include <string.h>
#include "FreeRTOS.h"
#include "trcConfig.h"
#include "trcTypes.h"
#include "trcPort.h"
extern volatile int recorder_busy;
#define trcCRITICAL_SECTION_BEGIN() {taskENTER_CRITICAL(); recorder_busy++;}
#define trcCRITICAL_SECTION_END() {recorder_busy--; taskEXIT_CRITICAL();}
#define NCLASSES 5
#define VERSION 0x1AA1
#define MINOR_VERSION 1
#define STORE_MODE_STOP_WHEN_FULL 1
#define STORE_MODE_RING_BUFFER 2
#define TRACE_DATA_ALLOCATION_STATIC 1
#define TRACE_DATA_ALLOCATION_DYNAMIC 2
/******************************************************************************
* Object Property Table
* The Object Table contains name and other properties of the objects (tasks,
* queues, mutexes, etc). The below data structures defines the properties of
* each object class and are used to cast the byte buffer into a cleaner format.
*
* The values in the object table are continously overwritten and always
* represent the current state. If a property is changed during runtime, the OLD
* value should be stored in the trace buffer, not the new value (since the new
* value is found in the Object Property Table).
* For close events this mechanism is the old names are stored in the symbol
* table), for "priority set" (the old priority is stored in the event data)
* and for "isActive", where the value decides is the taskswitch event type
* should be "new" or "resume".
******************************************************************************/
/* The size of the Object Property Table entries, in bytes, per object */
/* Queue properties (except name): current number of message in queue */
#define PropertyTableSizeQueue (NameLenQueue + 1)
/* Semaphore properties (except name): state (signaled = 1, cleared = 0) */
#define PropertyTableSizeSemaphore (NameLenSemaphore + 1)
/* Mutex properties (except name): owner (task handle, 0 = free) */
#define PropertyTableSizeMutex (NameLenMutex + 1)
/* Task properties (except name): Byte 0: Current priority
Byte 1: state (if already active)
Byte 2: InstanceFinishEvent_ServiceCode
Byte 3: InstanceFinishEvent_ObjHandle */
#define PropertyTableSizeTask (NameLenTask + 4)
/* ISR properties: Byte 0: priority
Byte 1: state (if already active) */
#define PropertyTableSizeISR (NameLenISR + 2)
/* The layout of the byte array representing the Object Property Table */
#define StartIndexQueue 0
#define StartIndexSemaphore StartIndexQueue + NQueue * PropertyTableSizeQueue
#define StartIndexMutex StartIndexSemaphore + NSemaphore * PropertyTableSizeSemaphore
#define StartIndexTask StartIndexMutex + NMutex * PropertyTableSizeMutex
#define StartIndexISR StartIndexTask + NTask * PropertyTableSizeTask
#define DynObjTableSize StartIndexISR + NISR * PropertyTableSizeISR
typedef struct
{
/* = NCLASSES */
uint32_t NumberOfObjectClasses;
uint32_t ObjectPropertyTableSizeInBytes;
/* This is used to calculate the index in the dynamic object table
(handle - 1 - nofStaticObjects = index)*/
uint8_t NumberOfObjectsPerClass[ 4*((NCLASSES+3)/4)];
/* Allocation size rounded up to the closest multiple of 4 */
uint8_t NameLengthPerClass[ 4*((NCLASSES+3)/4) ];
uint8_t TotalPropertyBytesPerClass[ 4*((NCLASSES+3)/4) ];
/* Allocation size rounded up to the closest multiple of 2 */
uint16_t StartIndexOfClass[ 2*((NCLASSES+1)/2) ];
/* The actual handles issued, should be Initiated to all zeros */
uint8_t objbytes[ 4*((DynObjTableSize+3)/4) ];
} ObjectPropertyTableType;
/* Symbol table data structure */
typedef struct
{
/* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */
uint32_t symTableSize;
/* Entry 0 is reserved. Any reference to entry 0 implies NULL*/
uint32_t nextFreeSymbolIndex;
/* Size rounded up to closest multiple of 4, to avoid alignment issues*/
uint8_t symbytes[4*((SYMBOL_TABLE_SIZE+3)/4)];
/* Used for lookups - Up to 64 linked lists within the symbol table
connecting all entries with the same 6 bit checksum.
This field holds the current list heads. Should be initiated to zeros */
uint16_t latestEntryOfChecksum[64];
} symbolTableType;
/*******************************************************************************
* The data structures of the different events, all 4 bytes long
******************************************************************************/
typedef struct
{
uint8_t type;
objectHandleType objHandle;
uint16_t dts; /* differential timestamp - time since last event */
} TSEvent, TREvent;
typedef struct
{
uint8_t type;
uint8_t objHandle;
uint16_t dts;
} KernelCall;
typedef struct
{
uint8_t type;
objectHandleType objHandle;
uint8_t param;
uint8_t dts;
} KernelCallWithParamAndHandle;
typedef struct
{
uint8_t type;
uint8_t dts;
uint16_t param;
} KernelCallWithParam16;
typedef struct
{
uint8_t type;
objectHandleType objHandle; /* the handle of the closed object */
uint16_t symbolIndex; /* the name of the closed object */
} ObjCloseNameEvent;
typedef struct
{
uint8_t type;
uint8_t arg1;
uint8_t arg2;
uint8_t arg3;
} ObjClosePropEvent;
typedef struct
{
uint8_t type;
uint8_t dts;
uint16_t payload; /* the name of the user event */
} UserEvent;
typedef struct
{
uint8_t type;
/* 8 bits extra for storing DTS, if it does not fit in ordinary event
(this one is always MSB if used) */
uint8_t xts_8;
/* 16 bits extra for storing DTS, if it does not fit in ordinary event. */
uint16_t xts_16;
} XTSEvent;
/*******************************************************************************
* The main datastructure, read by FreeRTOS+Trace from the RAM dump
******************************************************************************/
typedef struct
{
uint8_t startmarker0;
uint8_t startmarker1;
uint8_t startmarker2;
uint8_t startmarker3;
uint8_t startmarker4;
uint8_t startmarker5;
uint8_t startmarker6;
uint8_t startmarker7;
uint8_t startmarker8;
uint8_t startmarker9;
uint8_t startmarker10;
uint8_t startmarker11;
/* For FreeRTOS: 0x1AA1 */
uint16_t version;
/* Currently 1 for v2.2.2 (0 earlier)*/
uint8_t minor_version;
/* 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. */
uint8_t irq_priority_order;
/* sizeof(RecorderDataType) - just for control */
uint32_t filesize;
/* Current number of events recorded */
uint32_t numEvents;
/* The buffer size, in number of event records */
uint32_t maxEvents;
/* The event buffer index, where to write the next event */
uint32_t nextFreeIndex;
/* 1 if the buffer is full, 0 otherwise */
uint32_t bufferIsFull;
/* The frequency of the clock/timer/counter used as time base */
uint32_t frequency;
/* The absolute timestamp of the last stored event, in the native
timebase, modulo frequency! */
uint32_t absTimeLastEvent;
/* The number of seconds in total - lasts for 136 years */
uint32_t absTimeLastEventSecond;
/* 1 if the recorder has been started, 0 if not yet started or stopped.
This is a 32 bit variable due to alignment issues. */
uint32_t recorderActive;
/* For storing a Team License key */
uint8_t teamLicenceKey[32];
/* 0xF0F0F0F0 - for control only */
int32_t debugMarker0;
/* The Object Property Table holds information about currently active
tasks, queues, and other recorded objects. This is updated on each
create call and includes object name and other properties. */
ObjectPropertyTableType ObjectPropertyTable;
/* 0xF1F1F1F1 - for control only */
int32_t debugMarker1;
/* The Symbol Table stores strings for User Events and is also used to
store names of deleted objects, which still may be in the trace but no
longer are available. */
symbolTableType SymbolTable;
/* For includsion of float support, and for endian detection of floats.
The value should be (float)1 or (uint32_t)0 */
#if (INCLUDE_FLOAT_SUPPORT == 1)
float exampleFloatEncoding;
#else
uint32_t exampleFloatEncoding;
#endif
/* This is non-zero if an internal error occured in the recorder, e.g., if
one of the Nxxx constants was too small. The systemInfo string will then
contain an error message that is displayed when attempting to view the
trace file. */
uint32_t internalErrorOccured;
/* 0xF2F2F2F2 - for control only */
int32_t debugMarker2;
/* Generic system information string, presented in the tool. Note that this
is also used for storing any internal error messages from the recorder, so
do not make TRACE_DESCRIPTION_MAX_LENGTH too small. 80 is recommended. */
char systemInfo[TRACE_DESCRIPTION_MAX_LENGTH];
/* 0xF3F3F3F3 - for control only */
int32_t debugMarker3;
/* The event data, in 4-byte records */
uint8_t eventData[ EVENT_BUFFER_SIZE * 4 ];
uint8_t endmarker0;
uint8_t endmarker1;
uint8_t endmarker2;
uint8_t endmarker3;
uint8_t endmarker4;
uint8_t endmarker5;
uint8_t endmarker6;
uint8_t endmarker7;
uint8_t endmarker8;
uint8_t endmarker9;
uint8_t endmarker10;
uint8_t endmarker11;
} RecorderDataType;
extern RecorderDataType* RecorderDataPtr;
/******************************************************************************
* ObjectHandleStack
* This data-structure is used to provide a mechanism for 1-byte trace object
* handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer)
* when storing a reference to an object. This allows for up to 255 objects of
* each object class - Task, ISR, Semaphore, CountingSemaphore, Mutex and Queue,
* active at any given moment. There can be more "historic" objects, that have
* been deleted - that number is only limited by the size of the symbol table.
* Note that handle zero (0) is not used, it is a code for an invalid handle.
*
* This data structure keeps track of the FREE handles, not the handles in use.
* This datastructure contains one stack per object class. When a handle is
* allocated to an object, the next free handle is popped from the stack. When
* a handle is released (on object delete), it is pushed back on the stack.
* Note that there is no initialization code that pushed the free handles
* initially, that is not necessary due to the following optimization:
*
* The stack of handles (objectHandles) is initially all zeros. Since zero
* is not a valid handle, that is a signal of additional handles needed.
* If a zero is received when popping a new handle, it is replaced by the
* index of the popped handle instead.
*
*****************************************************************************/
typedef struct
{
/* For each object class, the index of the next handle to allocate */
int16_t indexOfNextAvailableHandle[ NCLASSES ];
/* The lowest index of this class (constant) */
int16_t lowestIndexOfClass[ NCLASSES ];
/* The highest index of this class (constant) */
int16_t highestIndexOfClass[ NCLASSES ];
/* The highest use count for this class (for statistics) */
int16_t handleCountWaterMarksOfClass[ NCLASSES ];
/* The free object handles - a set of stacks within this array */
objectHandleType objectHandles[ NTask+NISR+NSemaphore+NMutex+NQueue ];
} objectHandleStackType;
/* Internal data */
extern objectHandleStackType objectHandleStacks;
/* Structures to handle the exclude flags for all objects, tasks and event codes */
#define NEventCodes 0x100
extern uint8_t excludedFlags[(NEventCodes+NQueue+NSemaphore+NMutex+NTask) / 8 + 1];
extern uint8_t ifeFlags[NTask / 8 + 1];
/* Internal functions */
uint16_t prvTraceGetDTS(uint16_t param_maxDTS);
void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength);
traceLabel prvTraceCreateSymbolTableEntry(const char* name,
uint8_t crc6,
uint8_t len,
traceLabel channel);
traceLabel prvTraceLookupSymbolTableEntry(const char* name,
uint8_t crc6,
uint8_t len,
traceLabel channel);
traceLabel prvTraceOpenSymbol(const char* name, traceLabel userEventChannel);
void prvTraceUpdateCounters(void);
void prvCheckDataToBeOverwrittenForMultiEntryUserEvents(uint8_t nEntries);
objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass);
void vTraceFreeObjectHandle(traceObjectClass objectclass,
objectHandleType handle);
void vTraceSetObjectName(traceObjectClass objectclass,
objectHandleType handle,
const char* name);
void* xTraceNextFreeEventBufferSlot(void);
uint16_t uiIndexOfObject(objectHandleType objecthandle,
uint8_t objectclass);
/*******************************************************************************
* vTraceError
*
* Called by various parts in the recorder. Stops the recorder and stores a
* pointer to an error message, which is printed by the monitor task.
******************************************************************************/
void vTraceError(const char* msg);
/*******************************************************************************
* xTraceGetLastError
*
* Gives the last error message, if any. NULL if no error message is stored.
* The message is cleared on read.
******************************************************************************/
char* xTraceGetLastError(void);
/*******************************************************************************
* xTraceInitTraceData
*
* Allocates and initializes the recorder datastructure, based on the constants
* in trcConfig.h. This allows for allocating the data on the heap, instead of
* using a static declaration.
******************************************************************************/
RecorderDataType* xTraceInitTraceData(void);
/* Internal macros */
#define PROPERTY_NAME_GET(objectclass, objecthandle) \
(const char*)(& RecorderDataPtr->ObjectPropertyTable.objbytes \
[uiIndexOfObject(objecthandle, objectclass)])
#define PROPERTY_OBJECT_STATE(objectclass, handle) \
RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass]]
#define PROPERTY_ACTOR_PRIORITY(objectclass, handle) \
RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1]
#define PROPERTY_TASK_IFE_SERVICECODE(handle) \
RecorderDataPtr->ObjectPropertyTable.objbytes \
[uiIndexOfObject(handle, TRACE_CLASS_TASK) \
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[TRACE_CLASS_TASK]+2]
#define PROPERTY_TASK_IFE_OBJHANDLE(handle) \
RecorderDataPtr->ObjectPropertyTable.objbytes \
[uiIndexOfObject(handle, TRACE_CLASS_TASK) \
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[TRACE_CLASS_TASK]+3]
#define SET_FLAG_ISEXCLUDED(bitIndex) excludedFlags[(bitIndex) >> 3] |= (1 << ((bitIndex) & 7))
#define CLEAR_FLAG_ISEXCLUDED(bitIndex) excludedFlags[(bitIndex) >> 3] &= ~(1 << ((bitIndex) & 7))
#define GET_FLAG_ISEXCLUDED(bitIndex) (excludedFlags[(bitIndex) >> 3] & (1 << ((bitIndex) & 7)))
#define SET_FLAG_MARKIFE(bitIndex) ifeFlags[(bitIndex) >> 3] |= (1 << ((bitIndex) & 7))
#define CLEAR_FLAG_MARKIFE(bitIndex) ifeFlags[(bitIndex) >> 3] &= ~(1 << ((bitIndex) & 7))
#define GET_FLAG_MARKIFE(bitIndex) (ifeFlags[(bitIndex) >> 3] & (1 << ((bitIndex) & 7)))
#define SET_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) SET_FLAG_ISEXCLUDED(eventCode)
#define CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) CLEAR_FLAG_ISEXCLUDED(eventCode)
#define GET_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) GET_FLAG_ISEXCLUDED(eventCode)
#define SET_QUEUE_FLAG_ISEXCLUDED(queueHandle) SET_FLAG_ISEXCLUDED(NEventCodes+queueHandle-1)
#define CLEAR_QUEUE_FLAG_ISEXCLUDED(queueHandle) CLEAR_FLAG_ISEXCLUDED(NEventCodes+queueHandle-1)
#define GET_QUEUE_FLAG_ISEXCLUDED(queueHandle) GET_FLAG_ISEXCLUDED(NEventCodes+queueHandle-1)
#define SET_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreHandle) SET_FLAG_ISEXCLUDED(NEventCodes+NQueue+semaphoreHandle-1)
#define CLEAR_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreHandle) CLEAR_FLAG_ISEXCLUDED(NEventCodes+NQueue+semaphoreHandle-1)
#define GET_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreHandle) GET_FLAG_ISEXCLUDED(NEventCodes+NQueue+semaphoreHandle-1)
#define SET_MUTEX_FLAG_ISEXCLUDED(mutexHandle) SET_FLAG_ISEXCLUDED(NEventCodes+NQueue+NSemaphore+mutexHandle-1)
#define CLEAR_MUTEX_FLAG_ISEXCLUDED(mutexHandle) CLEAR_FLAG_ISEXCLUDED(NEventCodes+NQueue+NSemaphore+mutexHandle-1)
#define GET_MUTEX_FLAG_ISEXCLUDED(mutexHandle) GET_FLAG_ISEXCLUDED(NEventCodes+NQueue+NSemaphore+mutexHandle-1)
#define SET_TASK_FLAG_ISEXCLUDED(taskHandle) SET_FLAG_ISEXCLUDED(NEventCodes+NQueue+NSemaphore+NMutex+taskHandle-1)
#define CLEAR_TASK_FLAG_ISEXCLUDED(taskHandle) CLEAR_FLAG_ISEXCLUDED(NEventCodes+NQueue+NSemaphore+NMutex+taskHandle-1)
#define GET_TASK_FLAG_ISEXCLUDED(taskHandle) GET_FLAG_ISEXCLUDED(NEventCodes+NQueue+NSemaphore+NMutex+taskHandle-1)
#define SET_TASK_FLAG_MARKIFE(bitIndex) SET_FLAG_MARKIFE(bitIndex-1)
#define CLEAR_TASK_FLAG_MARKIFE(bitIndex) CLEAR_FLAG_MARKIFE(bitIndex-1)
#define GET_TASK_FLAG_MARKIFE(bitIndex) GET_FLAG_MARKIFE(bitIndex-1)
/* For debug printouts - the names of the object classes */
extern char OBJECTCLASSNAME[NCLASSES][10];
/*=
{
"QUEUE"
"SEMAPHORE",
"MUTEX",
"TASK",
"ISR"
};*/
#endif

@ -1,308 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcHooks.h
*
* The kernel integration hooks for FreeRTOS (v7.1.0 or later). This file should
* be included in the end of FreeRTOSConfig.h, together with:
*
* #define configUSE_TRACE_FACILITY 1
*
* NOTE:
* For IAR Embedded Workbench for ARM, you need to have a preprocessor condition
* on the include, to except it from the assembler step which otherwise give
* compile-time errors.
*
* #ifdef __ICCARM__
* #include "percepio/Include/trcHooks.h"
* #endif
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCHOOKS_H
#define TRCHOOKS_H
#if (configUSE_TRACE_FACILITY == 1)
#include "trcUser.h"
#undef INCLUDE_xTaskGetSchedulerState
#define INCLUDE_xTaskGetSchedulerState 1
#undef INCLUDE_xTaskGetCurrentTaskHandle
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
/* Called for each task that becomes ready */
#undef traceMOVED_TASK_TO_READY_STATE
#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
vTraceStoreTaskReady((unsigned char)pxTCB->uxTaskNumber);
#endif
/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */
#undef traceTASK_INCREMENT_TICK
#define traceTASK_INCREMENT_TICK( xTickCount ) \
if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) {extern uint32_t uiTraceTickCount; uiTraceTickCount++; uiTracePortGetTimeStamp(0);}
/* Called on each task-switch */
#undef traceTASK_SWITCHED_IN
#define traceTASK_SWITCHED_IN() \
vTraceStoreTaskswitch();
/* Called on vTaskSuspend */
#undef traceTASK_SUSPEND
#define traceTASK_SUSPEND( pxTaskToSuspend ) \
vTraceStoreKernelCall(TASK_SUSPEND, TRACE_CLASS_TASK, pxTaskToSuspend->uxTaskNumber); \
vTraceSetTaskInstanceFinished((uint8_t)pxTaskToSuspend->uxTaskNumber);
/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
#undef traceTASK_DELAY
#define traceTASK_DELAY() \
portENTER_CRITICAL(); \
vTraceStoreKernelCallWithNumericParamOnly(TASK_DELAY, (uint16_t)xTicksToDelay);\
vTraceSetTaskInstanceFinished((uint8_t)pxCurrentTCB->uxTaskNumber);\
portEXIT_CRITICAL();
/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
#undef traceTASK_DELAY_UNTIL
#define traceTASK_DELAY_UNTIL() \
portENTER_CRITICAL(); \
vTraceStoreKernelCallWithNumericParamOnly(TASK_DELAY_UNTIL, (uint16_t)xTimeToWake); \
vTraceSetTaskInstanceFinished((uint8_t)pxCurrentTCB->uxTaskNumber); \
portEXIT_CRITICAL();
#ifndef INCLUDE_OBJECT_DELETE
#define INCLUDE_OBJECT_DELETE 0
#endif
#if (INCLUDE_OBJECT_DELETE == 1)
/* Called on vTaskDelete */
#undef traceTASK_DELETE
#define traceTASK_DELETE( pxTaskToDelete ) \
trcCRITICAL_SECTION_BEGIN(); \
vTraceStoreKernelCall(EVENTGROUP_DELETE + TRACE_CLASS_TASK, TRACE_CLASS_TASK, pxTaskToDelete->uxTaskNumber); \
vTraceStoreObjectNameOnCloseEvent((objectHandleType)pxTaskToDelete->uxTaskNumber, TRACE_CLASS_TASK); \
vTraceStoreObjectPropertiesOnCloseEvent((objectHandleType)pxTaskToDelete->uxTaskNumber, TRACE_CLASS_TASK); \
vTraceSetPriorityProperty(TRACE_CLASS_TASK, (objectHandleType)pxTaskToDelete->uxTaskNumber, (uint8_t)pxTaskToDelete->uxPriority); \
vTraceSetObjectState(TRACE_CLASS_TASK, (objectHandleType)pxTaskToDelete->uxTaskNumber, TASK_STATE_INSTANCE_NOT_ACTIVE); \
vTraceFreeObjectHandle(TRACE_CLASS_TASK, (objectHandleType)pxTaskToDelete->uxTaskNumber); \
trcCRITICAL_SECTION_END();
#endif
/* Called on vTaskCreate */
#undef traceTASK_CREATE
#define traceTASK_CREATE( pxNewTCB ) \
if (pxNewTCB != NULL){ \
pxNewTCB->uxTaskNumber = xTraceGetObjectHandle(TRACE_CLASS_TASK); \
vTraceSetObjectName(TRACE_CLASS_TASK, (objectHandleType)pxNewTCB->uxTaskNumber, (char*)pxNewTCB->pcTaskName); \
vTraceSetPriorityProperty(TRACE_CLASS_TASK, (objectHandleType)pxNewTCB->uxTaskNumber, (uint8_t)pxNewTCB->uxPriority); \
vTraceStoreKernelCall(EVENTGROUP_CREATE + TRACE_CLASS_TASK, TRACE_CLASS_TASK, pxNewTCB->uxTaskNumber);\
}
/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */
#undef traceTASK_CREATE_FAILED
#define traceTASK_CREATE_FAILED() \
portENTER_CRITICAL();\
vTraceStoreKernelCall(EVENTGROUP_FAILED_CREATE + TRACE_CLASS_TASK, TRACE_CLASS_TASK, 0); \
portEXIT_CRITICAL();
/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */
#undef traceQUEUE_CREATE
#define traceQUEUE_CREATE( pxNewQueue )\
portENTER_CRITICAL(); \
pxNewQueue->ucQueueNumber = xTraceGetObjectHandle(TraceObjectClassTable[pxNewQueue->ucQueueType]);\
vTraceStoreKernelCall(EVENTGROUP_CREATE + TraceObjectClassTable[pxNewQueue->ucQueueType], TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber); \
vTraceSetObjectState(TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber, 0); \
portEXIT_CRITICAL();
/* Called in xQueueCreate, if the queue creation fails */
#undef traceQUEUE_CREATE_FAILED
#define traceQUEUE_CREATE_FAILED( queueType ) \
portENTER_CRITICAL();\
vTraceStoreKernelCall((uint8_t)(EVENTGROUP_FAILED_CREATE + TraceObjectClassTable[queueType]), TraceObjectClassTable[queueType], 0); \
portEXIT_CRITICAL();
/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */
#undef traceCREATE_MUTEX
#define traceCREATE_MUTEX( pxNewQueue ) \
portENTER_CRITICAL();\
pxNewQueue->ucQueueNumber = xTraceGetObjectHandle(TRACE_CLASS_MUTEX); \
vTraceStoreKernelCall(EVENTGROUP_CREATE + TraceObjectClassTable[pxNewQueue->ucQueueType], TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber); \
vTraceSetObjectState(TraceObjectClassTable[pxNewQueue->ucQueueType], pxNewQueue->ucQueueNumber, 0); \
portEXIT_CRITICAL();
/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */
#undef traceCREATE_MUTEX_FAILED
#define traceCREATE_MUTEX_FAILED() \
portENTER_CRITICAL();\
vTraceStoreKernelCall(EVENTGROUP_FAILED_CREATE + TRACE_CLASS_MUTEX, TRACE_CLASS_MUTEX, 0);\
portEXIT_CRITICAL();
/* Called when the Mutex can not be given, since not holder */
#undef traceGIVE_MUTEX_RECURSIVE_FAILED
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \
portENTER_CRITICAL();\
vTraceStoreKernelCall(EVENTGROUP_FAILED_SEND + TRACE_CLASS_MUTEX, TRACE_CLASS_MUTEX, pxMutex->ucQueueNumber); \
portEXIT_CRITICAL();
/* Called when a message is sent to a queue */
#undef traceQUEUE_SEND
#define traceQUEUE_SEND( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_SEND + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
if (TraceObjectClassTable[pxQueue->ucQueueType] == TRACE_CLASS_MUTEX){\
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (uint8_t)pxQueue->ucQueueNumber, (uint8_t)0); \
}else{\
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (uint8_t)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); \
}
/* Called when a message failed to be sent to a queue (timeout) */
#undef traceQUEUE_SEND_FAILED
#define traceQUEUE_SEND_FAILED( pxQueue ) \
portENTER_CRITICAL();\
vTraceStoreKernelCall(EVENTGROUP_FAILED_SEND + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
portEXIT_CRITICAL();
/* Called when the task is blocked due to a send operation on a full queue */
#undef traceBLOCKING_ON_QUEUE_SEND
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \
portENTER_CRITICAL();\
vTraceStoreKernelCall(EVENTGROUP_BLOCK_ON_SEND + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
portEXIT_CRITICAL();
/* Called when a message is received from a queue */
#undef traceQUEUE_RECEIVE
#define traceQUEUE_RECEIVE( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_RECEIVE + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
if (TraceObjectClassTable[pxQueue->ucQueueType] == TRACE_CLASS_MUTEX){\
extern volatile void * volatile pxCurrentTCB; \
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (objectHandleType)uxTaskGetTaskNumber((xTaskHandle)pxCurrentTCB)); /*For mutex, store the new owner rather than queue length */ \
}else{\
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting - 1)); \
}
/* Called when the task is blocked due to a receive operation on an empty queue */
#undef traceBLOCKING_ON_QUEUE_RECEIVE
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \
portENTER_CRITICAL(); \
vTraceStoreKernelCall(EVENTGROUP_BLOCK_ON_RECEIVE + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
if (TraceObjectClassTable[pxQueue->ucQueueType] != TRACE_CLASS_MUTEX){\
extern volatile void * volatile pxCurrentTCB; \
vTraceSetTaskInstanceFinished((objectHandleType)uxTaskGetTaskNumber((xTaskHandle)pxCurrentTCB)); \
}\
portEXIT_CRITICAL();
/* Called on xQueuePeek */
#undef traceQUEUE_PEEK
#define traceQUEUE_PEEK( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_PEEK + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber);
/* Called when a receive operation on a queue fails (timeout) */
#undef traceQUEUE_RECEIVE_FAILED
#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \
portENTER_CRITICAL(); \
vTraceStoreKernelCall(EVENTGROUP_FAILED_RECEIVE + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
portEXIT_CRITICAL();
/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */
#undef traceQUEUE_SEND_FROM_ISR
#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_SEND_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting + 1));
/* Called when a message send from interrupt context fails (since the queue was full) */
#undef traceQUEUE_SEND_FROM_ISR_FAILED
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_FAILED_SEND_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber);
/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */
#undef traceQUEUE_RECEIVE_FROM_ISR
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_RECEIVE_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)(pxQueue->uxMessagesWaiting - 1));
/* Called when a message receive from interrupt context fails (since the queue was empty) */
#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \
vTraceStoreKernelCall(EVENTGROUP_FAILED_RECEIVE_FROM_ISR + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber);
#if (INCLUDE_OBJECT_DELETE == 1)
/* Called on vQueueDelete */
#undef traceQUEUE_DELETE
#define traceQUEUE_DELETE( pxQueue ) \
{ \
portENTER_CRITICAL();\
vTraceStoreKernelCall(EVENTGROUP_DELETE + TraceObjectClassTable[pxQueue->ucQueueType], TraceObjectClassTable[pxQueue->ucQueueType], pxQueue->ucQueueNumber); \
vTraceStoreObjectNameOnCloseEvent((objectHandleType)pxQueue->ucQueueNumber, TraceObjectClassTable[pxQueue->ucQueueType]); \
vTraceStoreObjectPropertiesOnCloseEvent((objectHandleType)pxQueue->ucQueueNumber, TraceObjectClassTable[pxQueue->ucQueueType]); \
if (TraceObjectClassTable[pxQueue->ucQueueType] == TRACE_CLASS_MUTEX){ \
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (objectHandleType)uxTaskGetTaskNumber((xTaskHandle)pxQueue->pxMutexHolder)); \
}else{ \
vTraceSetObjectState(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber, (uint8_t)uxQueueMessagesWaiting(pxQueue)); \
} \
vTraceFreeObjectHandle(TraceObjectClassTable[pxQueue->ucQueueType], (objectHandleType)pxQueue->ucQueueNumber); \
portEXIT_CRITICAL();\
}
#endif
/* Called in vTaskPrioritySet */
#undef traceTASK_PRIORITY_SET
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \
vTraceStoreKernelCallWithParam(TASK_PRIORITY_SET, TRACE_CLASS_TASK, pxTask->uxTaskNumber, uiTraceGetPriorityProperty(TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber));\
vTraceSetPriorityProperty( TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber, (uint8_t)uxNewPriority);
/* Called in vTaskPriorityInherit, which is called by Mutex operations */
#undef traceTASK_PRIORITY_INHERIT
#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \
vTraceStoreKernelCallWithParam(TASK_PRIORITY_INHERIT, TRACE_CLASS_TASK, pxTask->uxTaskNumber, uiTraceGetPriorityProperty(TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber));\
vTraceSetPriorityProperty( TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber, (uint8_t)uxNewPriority );
/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */
#undef traceTASK_PRIORITY_DISINHERIT
#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \
vTraceStoreKernelCallWithParam(TASK_PRIORITY_DISINHERIT, TRACE_CLASS_TASK, pxTask->uxTaskNumber, uiTraceGetPriorityProperty(TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber));\
vTraceSetPriorityProperty( TRACE_CLASS_TASK, (uint8_t)pxTask->uxTaskNumber, (uint8_t)uxNewPriority );
/* Called in vTaskResume */
#undef traceTASK_RESUME
#define traceTASK_RESUME( pxTaskToResume ) \
vTraceStoreKernelCall(TASK_RESUME, TRACE_CLASS_TASK, pxTaskToResume->uxTaskNumber);
/* Called in vTaskResumeFromISR */
#undef traceTASK_RESUME_FROM_ISR
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )\
vTraceStoreKernelCall(TASK_RESUME_FROM_ISR, TRACE_CLASS_TASK, pxTaskToResume->uxTaskNumber);
#endif
#endif

@ -1,274 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.h
*
* Functions used by trcHooks.h, for the FreeRTOS kernel integration.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCKERNEL_H
#define TRCKERNEL_H
#include "trcBase.h"
/* Internal functions */
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
void vTraceStoreTaskReady(objectHandleType handle);
#endif
void vTraceStoreTaskswitch(void);
void vTraceStoreKernelCall(uint32_t eventcode, traceObjectClass objectClass, uint32_t byteParam);
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode,
uint16_t param);
void vTraceStoreKernelCallWithParam(uint32_t evtcode, traceObjectClass objectClass,
uint32_t objectNumber, uint8_t param);
void vTraceSetTaskInstanceFinished(objectHandleType handle);
void vTraceSetPriorityProperty(uint8_t objectclass, uint8_t id, uint8_t value);
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, uint8_t id);
void vTraceSetObjectState(uint8_t objectclass, uint8_t id, uint8_t value);
uint8_t uiTraceGetObjectState(uint8_t objectclass, uint8_t id);
#if (INCLUDE_OBJECT_DELETE == 1)
void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,
traceObjectClass objectclass);
void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
traceObjectClass objectclass);
#endif
/* Internal constants for task state */
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
#define TASK_STATE_INSTANCE_ACTIVE 1
#define TASK_STATE_INSTANCE_MARKED_FINISHED 2
extern objectHandleType handle_of_running_task;
/* This defines the mapping between FreeRTOS queue types and our internal
class IDs */
extern traceObjectClass TraceObjectClassTable[5];
/*******************************************************************************
* The event codes - should match the offline config file.
*
* Some sections below are encoded to allow for constructions like:
*
* vTraceStoreKernelCall(EVENTGROUP_CREATE + objectclass, ...
*
* The object class ID is given by the three LSB bits, in such cases. Since each
* object class has a separate object property table, the class ID is needed to
* know what section in the object table to use for getting an object name from
* an object handle.
******************************************************************************/
#define NULL_EVENT (0x00) /* Ignored in the analysis*/
/*******************************************************************************
* EVENTGROUP_RE
*
* Events that indicate that something is ready to execute.
******************************************************************************/
#define EVENTGROUP_RE (NULL_EVENT + 2) /*0x02*/
#define TR_TASK_READY (EVENTGROUP_RE + 0) /*0x02*/
/*******************************************************************************
* EVENTGROUP_TS
*
* Events for storing task-switches and interrupts. The RESUME events are
* generated if the task/interrupt is already marked active.
******************************************************************************/
#define EVENTGROUP_TS (EVENTGROUP_RE + 2) /*0x04*/
#define TS_ISR_BEGIN (EVENTGROUP_TS + 0) /*0x04*/
#define TS_ISR_RESUME (EVENTGROUP_TS + 1) /*0x05*/
#define TS_TASK_BEGIN (EVENTGROUP_TS + 2) /*0x06*/
#define TS_TASK_RESUME (EVENTGROUP_TS + 3) /*0x07*/
/*******************************************************************************
* EVENTGROUP_OBJCLOSE_NAME
*
* About Close Events
* When an object is evicted from the object property table (object close), two
* internal events are stored (EVENTGROUP_OBJCLOSE_NAME and
* EVENTGROUP_OBJCLOSE_PROP), containg the handle-name mapping and object
* properties valid up to this point.
******************************************************************************/
#define EVENTGROUP_OBJCLOSE_NAME (EVENTGROUP_TS + 4) /*0x08*/
/*******************************************************************************
* EVENTGROUP_OBJCLOSE_PROP
*
* The internal event carrying properties of deleted objects
* The handle and object class of the closed object is not stored in this event,
* but is assumed to be the same as in the preceeding CLOSE event. Thus, these
* two events must be generated from within a critical section.
* When queues are closed, arg1 is the "state" property (i.e., number of
* buffered messages/signals).
* When actors are closed, arg1 is priority, arg2 is handle of the "instance
* finish" event, and arg3 is event code of the "instance finish" event.
* In this case, the lower three bits is the object class of the instance finish
* handle. The lower three bits are not used (always zero) when queues are
* closed since the queue type is given in the previous OBJCLOSE_NAME event.
******************************************************************************/
#define EVENTGROUP_OBJCLOSE_PROP (EVENTGROUP_OBJCLOSE_NAME + 8) /*0x10*/
/*******************************************************************************
* EVENTGROUP_CREATE
*
* The events in this group are used to log Kernel object creations.
* The lower three bits in the event code gives the object class, i.e., type of
* create operation (task, queue, semaphore, etc).
******************************************************************************/
#define EVENTGROUP_CREATE (EVENTGROUP_OBJCLOSE_PROP + 8) /*0x18*/
/*******************************************************************************
* EVENTGROUP_SEND
*
* The events in this group are used to log Send/Give events on queues,
* semaphores and mutexeds The lower three bits in the event code gives the
* object class, i.e., what type of object that is operated on (queue, semaphore
* or mutex).
******************************************************************************/
#define EVENTGROUP_SEND (EVENTGROUP_CREATE + 8) /*0x20*/
/*******************************************************************************
* EVENTGROUP_RECEIVE
*
* The events in this group are used to log Receive/Take events on queues,
* semaphores and mutexes. The lower three bits in the event code gives the
* object class, i.e., what type of object that is operated on (queue, semaphore
* or mutex).
******************************************************************************/
#define EVENTGROUP_RECEIVE (EVENTGROUP_SEND + 8) /*0x28*/
/* Send/Give operations, from ISR */
#define EVENTGROUP_SEND_FROM_ISR (EVENTGROUP_RECEIVE + 8) /*0x30*/
/* Receive/Take operations, from ISR */
#define EVENTGROUP_RECEIVE_FROM_ISR (EVENTGROUP_SEND_FROM_ISR + 8) /*0x38*/
/* "Failed" event type versions of above (timeout, failed allocation, etc) */
#define EVENTGROUP_FAILED_KSE (EVENTGROUP_RECEIVE_FROM_ISR + 8) /*0x40*/
/* Failed create calls - memory allocation failed */
#define EVENTGROUP_FAILED_CREATE (EVENTGROUP_FAILED_KSE) /*0x40*/
/* Failed send/give - timeout! */
#define EVENTGROUP_FAILED_SEND (EVENTGROUP_FAILED_CREATE + 8) /*0x48*/
/* Failed receive/take - timeout! */
#define EVENTGROUP_FAILED_RECEIVE (EVENTGROUP_FAILED_SEND + 8) /*0x50*/
/* Failed non-blocking send/give - queue full */
#define EVENTGROUP_FAILED_SEND_FROM_ISR (EVENTGROUP_FAILED_RECEIVE + 8) /*0x58*/
/* Failed non-blocking receive/take - queue empty */
#define EVENTGROUP_FAILED_RECEIVE_FROM_ISR \
(EVENTGROUP_FAILED_SEND_FROM_ISR + 8) /*0x60*/
/* Events when blocking on receive/take */
#define EVENTGROUP_BLOCK_ON_RECEIVE \
(EVENTGROUP_FAILED_RECEIVE_FROM_ISR + 8) /*0x68*/
/* Events when blocking on send/give */
#define EVENTGROUP_BLOCK_ON_SEND (EVENTGROUP_BLOCK_ON_RECEIVE + 8) /*0x70*/
/* Events on queue peek (receive) */
#define EVENTGROUP_PEEK (EVENTGROUP_BLOCK_ON_SEND + 8) /*0x78*/
/* Events on object delete (vTaskDelete or vQueueDelete) */
#define EVENTGROUP_DELETE (EVENTGROUP_PEEK + 8) /*0x80*/
/* Other events - object class is implied: TASK */
#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE + 8) /*0x88*/
#define TASK_DELAY_UNTIL (EVENTGROUP_OTHERS + 0) /*0x88*/
#define TASK_DELAY (EVENTGROUP_OTHERS + 1) /*0x89*/
#define TASK_SUSPEND (EVENTGROUP_OTHERS + 2) /*0x8A*/
#define TASK_RESUME (EVENTGROUP_OTHERS + 3) /*0x8B*/
#define TASK_RESUME_FROM_ISR (EVENTGROUP_OTHERS + 4) /*0x8C*/
#define TASK_PRIORITY_SET (EVENTGROUP_OTHERS + 5) /*0x8D*/
#define TASK_PRIORITY_INHERIT (EVENTGROUP_OTHERS + 6) /*0x8E*/
#define TASK_PRIORITY_DISINHERIT (EVENTGROUP_OTHERS + 7) /*0x8F*/
/* Not yet used */
#define EVENTGROUP_FTRACE_PLACEHOLDER (EVENTGROUP_OTHERS + 8) /*0x90*/
/* User events */
#define EVENTGROUP_USEREVENT (EVENTGROUP_FTRACE_PLACEHOLDER + 8) /*0x98*/
#define USER_EVENT (EVENTGROUP_USEREVENT + 0)
/* Allow for 0-15 arguments (the number of args is added to event code) */
#define USER_EVENT_LAST (EVENTGROUP_USEREVENT + 15) /*0xA7*/
/*******************************************************************************
* XTS Event - eXtended TimeStamp events
* The timestamps used in the recorder are "differential timestamps" (DTS), i.e.
* the time since the last stored event. The DTS fields are either 1 or 2 bytes
* in the other events, depending on the bytes available in the event struct.
* If the time since the last event (the DTS) is larger than allowed for by
* the DTS field of the current event, an XTS event is inserted immidiatly
* before the original event. The XTS event contains up to 3 additional bytes
* of the DTS value - the higher bytes of the true DTS value. The lower 1-2
* bytes are stored in the normal DTS field.
* There are two types of XTS events, XTS8 and XTS16. An XTS8 event is stored
* when there is only room for 1 byte (8 bit) DTS data in the original event,
* which means a limit of 0xFF (255). The XTS16 is used when the original event
* has a 16 bit DTS field and thereby can handle values up to 0xFFFF (65535).
*
* Using a very high frequency time base can result in many XTS events.
* Preferably, the time between two OS ticks should fit in 16 bits, i.e.,
* at most 65535. If your time base has a higher frequency, you can define
* the TRACE
******************************************************************************/
#define EVENTGROUP_SYS (EVENTGROUP_USEREVENT + 16) /*0xA8*/
#define XTS8 (EVENTGROUP_SYS + 0) /*0xA8*/
#define XTS16 (EVENTGROUP_SYS + 1) /*0xA9*/
#define EVENT_BEING_WRITTEN (EVENTGROUP_SYS + 2) /*0xAA*/
#define RESERVED_DUMMY_CODE (EVENTGROUP_SYS + 3) /*0xAB*/
#endif

@ -1,492 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcPort.h
*
* Contains together with trcPort.c all portability issues of the trace recorder
* library.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCPORT_H
#define TRCPORT_H
/* If FreeRTOS Win32 port */
#ifdef WIN32
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
/* Standard includes. */
#include <stdio.h>
#include <windows.h>
#include <direct.h>
/*******************************************************************************
* The Win32 port by default saves the trace to file and then kills the
* program when the recorder is stopped, to facilitate quick, simple tests
* of the recorder.
******************************************************************************/
#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
#define DIRECTION_DECREMENTING 2
/******************************************************************************
* Supported ports
*
* PORT_HWIndependent
* 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.
*
* 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.
*
* Officially supported hardware timer ports:
* - PORT_Atmel_AT91SAM7
* - PORT_Atmel_UC3A0
* - PORT_ARM_CortexM
* - PORT_Renesas_RX600
* - PORT_Microchip_dsPIC_AND_PIC24
*
* We also provide several "unofficial" hardware-specific ports. There have
* 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:
* - PORT_TEXAS_INSTRUMENTS_TMS570
* - PORT_TEXAS_INSTRUMENTS_MSP430
* - PORT_MICROCHIP_PIC32
* - PORT_XILINX_PPC405
* - PORT_XILINX_PPC440
* - PORT_XILINX_MICROBLAZE
* - PORT_NXP_LPC210X
*
*****************************************************************************/
#define PORT_NOT_SET -1
/*** Officially supported hardware timer ports *******************************/
#define PORT_HWIndependent 0
#define PORT_Win32 1
#define PORT_Atmel_AT91SAM7 2
#define PORT_Atmel_UC3A0 3
#define PORT_ARM_CortexM 4
#define PORT_Renesas_RX600 5
#define PORT_Microchip_dsPIC_AND_PIC24 6
/*** Unofficial ports, provided by external developers, not yet verified *****/
#define PORT_TEXAS_INSTRUMENTS_TMS570 7
#define PORT_TEXAS_INSTRUMENTS_MSP430 8
#define PORT_MICROCHIP_PIC32 9
#define PORT_XILINX_PPC405 10
#define PORT_XILINX_PPC440 11
#define PORT_XILINX_MICROBLAZE 12
#define PORT_NXP_LPC210X 13
/*** Select your port here! **************************************************/
#define SELECTED_PORT PORT_ARM_CortexM
/*****************************************************************************/
#if (SELECTED_PORT == PORT_NOT_SET)
#error "You need to define SELECTED_PORT here!"
#endif
/*******************************************************************************
* IRQ_PRIORITY_ORDER
*
* Macro which should be defined as an integer of 0 or 1.
*
* 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.
*
* 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)
*
* 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.
*
******************************************************************************
*
* HWTC Macros
*
* These four HWTC macros provides a hardware isolation layer representing a
* generic hardware timer/counter used for driving the operating system tick,
* such as the SysTick feature of ARM Cortex M3/M4, or the PIT of the Atmel
* AT91SAM7X.
*
* HWTC_COUNT: The current value of the counter. This is expected to be reset
* a each tick interrupt. Thus, when the tick handler starts, the counter has
* already wrapped.
*
* HWTC_COUNT_DIRECTION: Should be one of:
* - DIRECTION_INCREMENTING - for hardware timer/counters of incrementing type
* such as the PIT on Atmel AT91SAM7X.
* When the counter value reach HWTC_PERIOD, it is reset to zero and the
* interrupt is signaled.
* - DIRECTION_DECREMENTING - for hardware timer/counters of decrementing type
* such as the SysTick on ARM Cortex M3/M4 chips.
* When the counter value reach 0, it is reset to HWTC_PERIOD and the
* interrupt is signaled.
*
* HWTC_PERIOD: The number of increments or decrements of HWTC_COUNT between
* two tick interrupts. This should preferably be mapped to the reload
* register of the hardware timer, to make it more portable between chips in the
* same family. The macro should in most cases be (reload register + 1).
*
* HWTC_DIVISOR: If the timer frequency is very high, like on the Cortex M chips
* (where the SysTick runs at the core clock frequency), the "differential
* timestamping" used in the recorder will more frequently insert extra XTS
* events to store the timestamps, which increases the event buffer usage.
* In such cases, to reduce the number of XTS events and thereby get longer
* traces, you use HWTC_DIVISOR to scale down the timestamps and frequency.
* Assuming a OS tick rate of 1 KHz, it is suggested to keep the effective timer
* frequency below 65 MHz to avoid an excessive amount of XTS events. Thus, a
* 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
* 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.
*
******************************************************************************/
#if (SELECTED_PORT == PORT_Win32)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (ulGetRunTimeCounterValue())
#define HWTC_PERIOD 0
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // Please update according to your hardware...
#elif (SELECTED_PORT == PORT_HWIndependent)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT 0
#define HWTC_PERIOD 1
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // Please update according to your hardware...
#elif (SELECTED_PORT == PORT_Atmel_AT91SAM7)
/* HWTC_PERIOD is hardcoded for AT91SAM7X256-EK Board (48 MHz)
A more generic solution is to get the period from pxPIT->PITC_PIMR */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)
#define HWTC_PERIOD 2995
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
#elif (SELECTED_PORT == PORT_Atmel_UC3A0)
/* For Atmel AVR32 (AT32UC3A) */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT sysreg_read(AVR32_COUNT)
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
#elif (SELECTED_PORT == PORT_ARM_CortexM)
/* For all chips using ARM Cortex M cores */
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
#define HWTC_COUNT (*((uint32_t*)0xE000E018))
#define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)
#define HWTC_DIVISOR 2
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
#elif (SELECTED_PORT == PORT_Renesas_RX600)
#include "iodefine.h"
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (CMT0.CMCNT)
#define HWTC_PERIOD ((((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/8))
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
#elif (SELECTED_PORT == PORT_Microchip_dsPIC_AND_PIC24)
/* For Microchip PIC24 and dsPIC (16 bit) */
/* 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
or system calls. */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (TMR1)
#define HWTC_PERIOD (PR1+1)
#define HWTC_DIVISOR 1
#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) */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT *((uint32_t *)0xE0004008 )
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define HWTC_DIVISOR 1
#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 */
#define RTIFRC0 *((uint32_t *)0xFFFFFC10)
#define RTICOMP0 *((uint32_t *)0xFFFFFC50)
#define RTIUDCP0 *((uint32_t *)0xFFFFFC54)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))
#define HWTC_PERIOD (RTIUDCP0)
#define HWTC_DIVISOR 1
#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_DIVISOR 1
#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 */
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (ReadTimer1()) /* Should be available in BSP */
#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
#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_DIVISOR 1
#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 */
/* This should work with most PowerPC chips */
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
#define HWTC_COUNT mfspr( 0x016 )
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
#define HWTC_DIVISOR 1
#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.
* 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.
*/
#include "xtmrctr_l.h"
#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_DIVISOR 16
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
#elif (SELECTED_PORT != PORT_NOT_SET)
#error "SELECTED_PORT had unsupported value!"
#define SELECTED_PORT PORT_NOT_SET
#endif
#if (SELECTED_PORT != PORT_NOT_SET)
#ifndef HWTC_COUNT_DIRECTION
#error "HWTC_COUNT_DIRECTION is not set!"
#endif
#ifndef HWTC_COUNT
#error "HWTC_COUNT is not set!"
#endif
#ifndef HWTC_PERIOD
#error "HWTC_PERIOD is not set!"
#endif
#ifndef HWTC_DIVISOR
#error "HWTC_DIVISOR is not set!"
#endif
#ifndef IRQ_PRIORITY_ORDER
#error "IRQ_PRIORITY_ORDER is not set!"
#elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)
#error "IRQ_PRIORITY_ORDER has bad value!"
#endif
#if (HWTC_DIVISOR < 1)
#error "HWTC_DIVISOR must be a non-zero positive value!"
#endif
#endif
/*******************************************************************************
* vTraceConsoleMessage
*
* A wrapper for your system-specific console "printf" console output function.
* This needs to be correctly defined to see status reports from the trace
* status monitor task (this is defined in trcUser.c).
******************************************************************************/
#if (SELECTED_PORT == PORT_Atmel_AT91SAM7)
/* Port specific includes */
#include "console.h"
#endif
#define vTraceConsoleMessage(x)
/*******************************************************************************
* uiTracePortGetTimeStamp
*
* 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
* or the trace recorder library. Typically you should not need to change
* the code of uiTracePortGetTimeStamp 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);
/*******************************************************************************
* vTracePortEnd
*
* This function is called when the recorder is stopped due to full buffer.
* Mainly intended to show a message in the console.
* This is used by the Win32 port to store the trace to a file. The file path is
* set using vTracePortSetFileName.
******************************************************************************/
void vTracePortEnd(void);
#if (INCLUDE_SAVE_TO_FILE == 1)
/*******************************************************************************
* vTracePortSetOutFile
*
* Sets the filename/path used in vTracePortSave.
* This is set in a separate function, since the Win32 port calls vTracePortSave
* in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.
******************************************************************************/
void vTracePortSetOutFile(char* path);
/******************************************************************************
* vTracePortSave
*
* Saves the trace to a file on a target-side file system. The path is set in a
* separate function, vTracePortSetOutFile, since the Win32 port may call
* vTracePortSave in vTracePortEnd, if using WIN32_PORT_SAVE_WHEN_STOPPED.
******************************************************************************/
void vTracePortSave(void);
#endif
#endif

@ -1,81 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcTypes.h
*
* Data types used by the trace recorder library.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCTYPES_H
#define TRCTYPES_H
#include <stdint.h>
typedef uint16_t traceLabel;
typedef uint8_t objectHandleType;
typedef uint8_t traceObjectClass;
#define TRACE_CLASS_QUEUE ((traceObjectClass)0)
#define TRACE_CLASS_SEMAPHORE ((traceObjectClass)1)
#define TRACE_CLASS_MUTEX ((traceObjectClass)2)
#define TRACE_CLASS_TASK ((traceObjectClass)3)
#define TRACE_CLASS_ISR ((traceObjectClass)4)
typedef uint8_t traceKernelService;
#define TRACE_KERNEL_SERVICE_TASK_CREATE ((traceKernelService)0)
#define TRACE_KERNEL_SERVICE_TASK_DELETE ((traceKernelService)1)
#define TRACE_KERNEL_SERVICE_TASK_DELAY ((traceKernelService)2)
#define TRACE_KERNEL_SERVICE_PRIORITY_SET ((traceKernelService)3)
#define TRACE_KERNEL_SERVICE_TASK_SUSPEND ((traceKernelService)4)
#define TRACE_KERNEL_SERVICE_TASK_RESUME ((traceKernelService)5)
#define TRACE_KERNEL_SERVICE_QUEUE_CREATE ((traceKernelService)6)
#define TRACE_KERNEL_SERVICE_QUEUE_DELETE ((traceKernelService)7)
#define TRACE_KERNEL_SERVICE_QUEUE_SEND ((traceKernelService)8)
#define TRACE_KERNEL_SERVICE_QUEUE_RECEIVE ((traceKernelService)9)
#define TRACE_KERNEL_SERVICE_QUEUE_PEEK ((traceKernelService)10)
#define TRACE_KERNEL_SERVICE_MUTEX_CREATE ((traceKernelService)11)
#define TRACE_KERNEL_SERVICE_MUTEX_DELETE ((traceKernelService)12)
#define TRACE_KERNEL_SERVICE_MUTEX_GIVE ((traceKernelService)13)
#define TRACE_KERNEL_SERVICE_MUTEX_TAKE ((traceKernelService)14)
#define TRACE_KERNEL_SERVICE_SEMAPHORE_CREATE ((traceKernelService)15)
#define TRACE_KERNEL_SERVICE_SEMAPHORE_DELETE ((traceKernelService)16)
#define TRACE_KERNEL_SERVICE_SEMAPHORE_GIVE ((traceKernelService)17)
#define TRACE_KERNEL_SERVICE_SEMAPHORE_TAKE ((traceKernelService)18)
#endif

@ -1,444 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcUser.h
* The public API of the trace recorder library.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#ifndef TRCUSER_H
#define TRCUSER_H
#include "FreeRTOS.h"
#include "trcKernel.h"
#if (configUSE_TRACE_FACILITY == 1)
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* uiTraceStart
*
* Starts the recorder. The recorder will not be started if an error has been
* indicated using vTraceError, e.g. if any of the Nx constants in trcConfig.h
* has a too small value (NTASK, NQUEUE, etc).
*
* Returns 1 if the recorder was started successfully.
* Returns 0 if the recorder start was prevented due to a previous internal
* error. In that case, check vTraceGetLastError to get the error message.
* Any error message is also presented when opening a trace file in
* FreeRTOS+Trace v2.2.2 or later.
******************************************************************************/
uint32_t uiTraceStart(void);
/*******************************************************************************
* vTraceStart
*
* Starts the recorder. The recorder will not be started if an error has been
* indicated using vTraceError, e.g. if any of the Nx constants in trcConfig.h
* has a too small value (NTASK, NQUEUE, etc).
*
* This function is obsolete, but has been saved for backwards compatibility.
* We recommend using uiTraceStart instead.
******************************************************************************/
void vTraceStart(void);
/*******************************************************************************
* vTraceStartStatusMonitor
*
* This starts a task to monitor the status of the recorder module.
* This task periodically prints a line to the console window, which shows the
* recorder status, the number of events recorded and the latest timestamp.
* This task calls vTracePortEnd (trcPort.c) when it detects that the recorder
* has been stopped. This allows for adding custom actions, e.g., to store the
* trace to a file in case a file system is available on the device.
******************************************************************************/
void vTraceStartStatusMonitor(void);
/*******************************************************************************
* vTraceStop
*
* Stops the recorder. The recording can be resumed by calling vTraceStart.
* This does not reset the recorder. Use vTraceClear is that is desired.
******************************************************************************/
void vTraceStop(void);
/*******************************************************************************
* vTraceClear
*
* Resets the recorder. Only necessary if a restart is desired - this is not
* needed in the startup initialization.
******************************************************************************/
void vTraceClear(void);
/*******************************************************************************
* vTraceSetQueueName
*
* Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This function should
* be called right after creation of the queue/mutex/semaphore. If not using
* this function, the queues/mutexes/semaphores will be presented by their
* numeric handle only.
*
* Example:
* actuatorQ = xQueueCreate(3, sizeof(QueueMessage));
* vTraceSetQueueName(actuatorQ, "ActuatorQueue");
******************************************************************************/
void vTraceSetQueueName(void* queue, const char* name);
#if (INCLUDE_ISR_TRACING == 1)
/*******************************************************************************
* vTraceSetISRProperties
*
* Registers an Interrupt Service Routine in the recorder library, This must be
* called before using vTraceStoreISRBegin to store ISR events. This is
* typically called in the startup of the system, before the scheduler is
* started.
*
* Example:
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
* ...
* vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1);
* ...
* void ISR_handler()
* {
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
* portEXIT_CRITICAL();
* ...
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
* vTraceStoreISREnd();
* portEXIT_CRITICAL();
* }
******************************************************************************/
void vTraceSetISRProperties(objectHandleType handle, const char* name, char priority);
/*******************************************************************************
* vTraceStoreISRBegin
*
* Registers the beginning of an Interrupt Service Routine.
*
* Note! This may only be used for interrupts affected by portENTER_CRITICAL.
* In some FreeRTOS ports, such as ARM Cortex M3, this does not disable all
* interrupts. Interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY are still
* enabled, but may not call the FreeRTOS API. Such may not call the recorder
* API, including this function.
*
* See http://www.freertos.org/a00110.html
*
* If allowing nested ISRs, this must be called with interrupts disabled.
*
* Example:
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
* ...
* vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1);
* ...
* void ISR_handler()
* {
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
* portEXIT_CRITICAL();
* ...
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
* vTraceStoreISREnd();
* portEXIT_CRITICAL();
* }
******************************************************************************/
void vTraceStoreISRBegin(objectHandleType id);
/*******************************************************************************
* vTraceStoreISREnd
*
* Registers the end of an Interrupt Service Routine.
*
* Note! This may only be used for interrupts affected by portENTER_CRITICAL.
* In some FreeRTOS ports, such as ARM Cortex M3, this does not disable all
* interrupts. Interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY are still
* enabled, but may not call the FreeRTOS API. Such may not call the recorder
* API, including this function.
*
* See http://www.freertos.org/a00110.html
*
* If allowing nested ISRs, this must be called with interrupts disabled.
*
* Example:
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
* ...
* vTraceSetISRProperties(ID_ISR_TIMER1, "ISRTimer1", PRIO_OF_ISR_TIMER1);
* ...
* void ISR_handler()
* {
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
* portEXIT_CRITICAL();
* ...
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
* vTraceStoreISREnd();
* portEXIT_CRITICAL();
* }
******************************************************************************/
void vTraceStoreISREnd(void);
#else
/* If not including the ISR recording */
void vTraceIncreaseISRActive(void);
void vTraceDecreaseISRActive(void);
#define vTraceSetISRProperties(handle, name, priority)
#define vTraceStoreISRBegin(id) vTraceIncreaseISRActive()
#define vTraceStoreISREnd() vTraceDecreaseISRActive()
#endif
/*******************************************************************************
* vvTraceTaskSkipDefaultInstanceFinishedEvents
*
* This is useful if there are implicit Instance Finish Events, such as
* vTaskDelayUntil or xQueueReceive, in a task where an explicit Instance Finish
* Event has been defined. This function tells the recorder that only the
* explicitly defined functions (using vTraceTaskInstanceIsFinished) should be
* treated as Instance Finish Events for this task. The implicit Instance Finish
* Events are thus disregarded for this task.
******************************************************************************/
void vTraceTaskSkipDefaultInstanceFinishedEvents(void);
/*******************************************************************************
* vTraceTaskInstanceIsFinished
*
* This defines an explicit Instance Finish Event for the current task. It tells
* the recorder that the current instance of this task is finished at the next
* kernel call of the task, e.g., a taskDelay or a queue receive. This function
* should be called right before the api function call considered to be the end
* of the task instamce, i.e., the Instance Finish Event.
******************************************************************************/
void vTraceTaskInstanceIsFinished(void);
/*******************************************************************************
* vTraceGetTraceBuffer
*
* Returns a pointer to the recorder data structure. Use this together with
* uiTraceGetTraceBufferSize if you wish to implement an own store/upload
* solution, e.g., in case a debugger connection is not available for uploading
* the data.
******************************************************************************/
void* vTraceGetTraceBuffer(void);
/*******************************************************************************
* uiTraceGetTraceBufferSize
*
* Gets the size of the recorder data structure. For use together with
* vTraceGetTraceBuffer if you wish to implement an own store/upload solution,
* e.g., in case a debugger connection is not available for uploading the data.
******************************************************************************/
uint32_t uiTraceGetTraceBufferSize(void);
#if (INCLUDE_USER_EVENTS == 1)
/*******************************************************************************
* xTraceOpenLabel
*
* Creates user event labels for user event channels or for individual events.
* User events can be used to log application events and data for display in
* the visualization tool. A user event is identified by a label, i.e., a string,
* which is stored in the recorder's symbol table.
* When logging a user event, a numeric handle (reference) to this string is
* used to identify the event. This is obtained by calling
*
* xTraceOpenLabel()
*
* whihc adds the string to the symbol table (if not already present)
* and returns the corresponding handle.
*
* This can be used in two ways:
*
* 1. The handle is looked up every time, when storing the user event.
*
* Example:
* vTraceUserEvent(xTraceOpenLabel("MyUserEvent"));
*
* 2. The label is registered just once, with the handle stored in an
* application variable - much like using a file handle.
*
* Example:
* myEventHandle = xTraceOpenLabel("MyUserEvent");
* ...
* vTraceUserEvent(myEventHandle);
*
* The second option is faster since no lookup is required on each event, and
* therefore recommended for user events that are frequently
* executed and/or located in time-critical code. The lookup operation is
* however fairly fast due to the design of the symbol table.
******************************************************************************/
traceLabel xTraceOpenLabel(const char* label);
/******************************************************************************
* vTraceUserEvent
*
* Basic user event (Standard and Professional Edition only)
*
* Generates a User Event with a text label. The label is created/looked up
* in the symbol table using xTraceOpenLabel.
******************************************************************************/
void vTraceUserEvent(traceLabel eventLabel);
/******************************************************************************
* vTracePrintF
*
* Advanced user events (Professional Edition only)
*
* Generates User Event with formatted text and data, similar to a "printf".
* It is very fast compared to a normal "printf" since this function only
* stores the arguments. The actual formatting is done
* on the host PC when the trace is displayed in the viewer tool.
*
* User Event labels are created using xTraceOpenLabel.
* Example:
*
* traceLabel adc_uechannel = xTraceOpenLabel("ADC User Events");
* ...
* vTracePrint(adc_uechannel,
* "ADC channel %d: %lf volts",
* ch, (double)adc_reading/(double)scale);
*
* This can be combined into one line, if desired, but this is slower:
*
* vTracePrint(xTraceOpenLabel("ADC User Events"),
* "ADC channel %d: %lf volts",
* ch, (double)adc_reading/(double)scale);
*
* Calling xTraceOpenLabel multiple times will not create duplicate entries, but
* it is of course faster to just do it once, and then keep the handle for later
* use. If you don´t have any data arguments, only a text label/string, it is
* better to use vTraceUserEvent - it is faster.
*
* Format specifiers supported:
* %d - 32 bit signed integer
* %u - 32 bit unsigned integer
* %f - 32 bit float
* %s - string (is copied to the recorder symbol table)
* %hd - 16 bit signed integer
* %hu - 16 bit unsigned integer
* %bd - 8 bit signed integer
* %bu - 8 bit unsigned integer
* %lf - double-precision float (Note! See below...)
*
* Up to 15 data arguments are allowed, with a total size of maximum 32 byte.
* In case this is exceeded, the user event is changed into an error message.
*
* The data is stored in trace buffer, and is packed to allow storing multiple
* smaller data entries in the same 4-byte record, e.g., four 8-bit values.
* A string requires two bytes, as the symbol table is limited to 64K. Storing
* a double (%lf) uses two records, so this is quite costly. Use float (%f)
* unless the higher precision is really necessary.
*
* Note that the double-precision float (%lf) assumes a 64 bit double
* representation. This does not seem to be the case on e.g. PIC24F.
* Before using a %lf argument on a 16-bit MCU, please verify that
* "sizeof(double)" actually gives 8 as expected. If not, use %f instead.
******************************************************************************/
void vTracePrintF(traceLabel eventLabel, const char* formatStr, ...);
#else
#define vTracePrintF(eventLabel, formatStr, ...);
#define xTraceOpenLabel(label) 0
#define vTraceUserEvent(eventLabel)
#endif
/******************************************************************************
* vTraceExclude______FromTrace
*
* Excludes a task or object from the trace.
* This can be useful if some irrelevant task is very frequent and is "eating
* up the buffer". This should be called after the task has been created, but
* before starting the FreeRTOS scheduler.
*****************************************************************************/
void vTraceExcludeQueueFromTrace(void* handle);
void vTraceExcludeSemaphoreFromTrace(void* handle);
void vTraceExcludeMutexFromTrace(void* handle);
void vTraceExcludeTaskFromTrace(void* handle);
void vTraceExcludeKernelServiceFromTrace(traceKernelService kernelService);
/******************************************************************************
* vTraceInclude______InTrace
*
* Includes a task, object or kernel service in the trace. This is only
* necessary if the task or object has been previously exluded.
*****************************************************************************/
void vTraceIncludeQueueInTrace(void* handle);
void vTraceIncludeSemaphoreInTrace(void* handle);
void vTraceIncludeMutexInTrace(void* handle);
void vTraceIncludeTaskInTrace(void* handle);
void vTraceIncludeKernelServiceInTrace(traceKernelService kernelService);
#ifdef __cplusplus
}
#endif
#else
#include "trcPort.h"
#define vTraceInit()
#define uiTraceStart() (1)
#define vTraceStart()
#define vTraceStop()
#define vTraceClear()
#define vTraceStartStatusMonitor()
#define vTracePortSetOutFile(f)
#define vTraceGetTraceBuffer() ((void*)0)
#define uiTraceGetTraceBufferSize() 0
#define xTraceOpenLabel(label) 0
#define vTraceUserEvent(eventLabel)
#define vTracePrintF(eventLabel,formatStr,...)
#define vTraceExcludeTaskFromSchedulingTrace(name)
#define vTraceSetQueueName(queue, name)
#define vTraceTaskSkipDefaultInstanceFinishedEvents()
#define vTraceSetISRProperties(handle, name, priority)
#define vTraceStoreISRBegin(id)
#define vTraceStoreISREnd()
#endif
#endif

@ -1,126 +0,0 @@
FreeRTOS+Trace - Uploading the trace data
-----------------------------------------
Percepio AB, Nov. 8, 2012
This document decribes how to upload the trace data from the target system to
FreeRTOS+Trace. For information on how to integrate and enable the recorder
library in your FreeRTOS project, see the FreeRTOS+Trace User Manual.
FreeRTOS+Trace uses your existing debugger to upload the trace data from the
chip RAM. This is a plain RAM dump, that is done whenever you want to look at
the trace buffer contents. This means it works with essentially with any debug
probe on the market.
Note that hardware-generated trace is not required (or used by) FreeRTOS+Trace.
We however plan to add support for that in future versions of FreeRTOS+Trace
and other Tracealyzer products.
Built-in support for Segger J-Link/J-Trace and Atmel SAM-ICE
------------------------------------------------------------
FreeRTOS+Trace v2.3 supports Segger J-Link and J-Link compatible debuggers
directly, without any debugger IDE involved. Using other debug probes is
also possible, but requires some extra steps, described below.
If you have a Segger J-Link/J-Trace debug probe or another J-Link compatible
debug probe, just select
"File" menu -> "Upload from <debug probe name>".
This opens a dialog where you get to enter the memory region where
the recorder data structure is located. Normally you select the entire
internal RAM according to the datasheet of your MCU, but the exact address
can be found can by inspecting the "RecorderData" struct or the
"RecorderDataPtr" pointer with your debugger.
Typical values are 0x0, 0x10000000 or 0x20000000 as start address
and 0x10000 or 0x20000 as size (64 KB or 128 KB).
This makes FreeRTOS+Trace reads the chip RAM and locate the trace data.
Note that this option is only available if a compatible debug probe is found.
J-Link compatible debug probes also include Atmel SAM-ICE and many built-in
debug interfaces on demonstration/evaluation boards (where there is a USB
connection directly to the board). Look for a Segger J-Link label on the board.
MemoryLogger extension in Atmel Studio 6
----------------------------------------
Atmel's new MemoryLogger extension provides a superb integration with
FreeRTOS+Trace. Look for "MemoryLogger" in Atmel Gallery, available in
Atmel Studio and at the Atmel website.
This extension automatically detects the path to FreeRTOS+Trace, if
installed, and gives you a single-click upload/refresh. You can use it
while debugging and optionally get an automatic refresh eash time the
MCU is halted, e.g., on each breakpoint.
Using other development environments and debug probes
-----------------------------------------------------
Most debuggers are able to save the RAM contents to a file. FreeRTOS+Trace
supports the following common formats:
- Binary (.bin), supporting gdb, J-Link and Renesas HEW.
- Intel Hex (.hex), supporting IAR Embedded Workbench and Atmel Studio (atprogram.exe)
- MCH (.mch), supporting Microchip MPLAB.
When you store the RAM dump, you must also make sure to select the right region,
i.e., start address and size. The recorder data is stored in a single data
block, identified by the pointer RecorderDataPtr.
It is not necessary to match the begin and end of the recorder data, as long as
it is fully included by the dumped memory region. FreeRTOS+Trace automatically
finds the trace data in the RAM dump, thanks to special signatures. For chips
with on-chip RAM only, we therefore recommend to dump the entire RAM. This is
usually very fast.
For chips with larger amounts of (external) RAM, it is typically possible to
dump a limited region where the data is typically found.
Using IAR Embedded Workbench for ARM, version 6.3
-------------------------------------------------
In the debugger view, when stopped on a breakpoint:
- Select "Debug" menu, "Memory" submenu, "Save..." (keyboard shortcut: ALT,d,y,s)
- In the Save dialog
- Zone: Memory
- Start Adress: 10000000 (for NXP LPC1766 in the demo project)
- End Adress: 1000FFFF (for NXP LPC1766 in the demo project)
- File format: Intel Extended
- Filename: <name>.hex
- Press "Save" button
You can now open <name>.hex in FreeRTOS+Trace.
To find the right Start and End addresses, check the address of the symbol
"RecorderData". The addresses does not need to match this symbol exactly, as
long as the whole data is included.
Using Renesas High-performance Embedded Workshop v4.09
------------------------------------------------------
In the debugger view, when stopped on a breakpoint:
- Select "Debug" menu, "Save Memory..." (keyboard shortcut: ALT,d,a)
- In the Save dialog
- Format: Binary
- Filename: <name>.bin
- Start Address: 00000000 (For RX62N in the demo project)
- End Address: 0000FFFF (For RX62N in the demo project)
- Access size: 1
- Press "Save" button and open <name>.bin in FreeRTOS+Trace.
Using Microchip MPLAB v8.86
------------------------------------------------------
- Select "View" -> "File Registers". This shows you the memory contents.
- Make sure "Hex" is selected in the bottom left (instead of "Symbolic"). Hex mode seems to be default.
- Right click in the view and select "Export Table...".
- In the dialog ("Export As"), make sure "Single Column Output" is selected (seems to be default).
- Select start address 0x0000 and make sure the end address is beyond the RecorderData structure.
The default values seems to be the whole RAM, so you probably don't need to change this.
- Save as a .mch file and open this file in FreeRTOS+Trace v2.2.4 or later (support for the .mch format was added in v2.2.4).
Using STM32 ST-Link
------------------------------------------------------
- Start "ST-Link Utility"
- Connect to the device and view the device memory.
- Set the view to display the entire RAM, or at least the section containing the RecorderData structure.
- Select "Save as" and choose binary (.bin) or Intel Hex (.hex) format.
- Open the resulting file in FreeRTOS+Trace.
In case you have any question, contact support@percepio.com
Percepio AB
www.percepio.com

@ -1,53 +0,0 @@
FreeRTOS+Trace Trace Recorder Library
-------------------------------------
Percepio AB
www.percepio.com
This directory contains the core trace recorder library used by FreeRTOS+Trace v2.3.
Ready-to-run demonstrations projects are found at www.percepio.com.
For information on how to integrate the recorder library in your FreeRTOS build, see
the FreeRTOS+Trace User Manual, section 2.
For information on how to upload the trace data from your target system RAM to
FreeRTOS+Trace, see "debugger trace upload.txt"
NOTE: This trace recorder library requires FreeRTOS v7.3.0 or later.
Files included
--------------
- trcConfig.h - The recorder's configuration file, check this!
- trcUser.c / trcUser.h - The main API towards the application (trcUser.h in the only include necessary).
- trcKernel.c / trcKernel.h - Internal routines for storing kernel events.
- trcBase.c / trcBase.h - Internal routines for manipulating the data structures and calculating timestamps.
- trcPort.c / trcPort.h - The port layer, abstracting the hardware (mainly the timer used for timestamping).
- trcHooks.h - The interface between FreeRTOS and the recorder, containing trace macro defintions.
- trcTypes.h - Type definitions used.
Hardware Timer Ports
--------------------
This release contains hardware timer ports for the following hardware architectures:
- ARM Cortex M3/M4 (all brands, such as Atmel SAM3/SAM4, NXP 17xx, 18xx, 43xx, STM32, Freescale Kinetis, ...)
- Atmel AT91SAM7x
- Atmel AT32UC3 (AVR32)
- Renesas RX600 (e.g., RX62N)
- Microchip dsPIC/PIC24
These are defined in trcPort.h. This also contains several "unofficial" ports, provided by external contributors.
By unofficial, it means that they are not yet verified by Percepio AB. Please refer to trcPort.h for detailed information.
If you use an unofficial port and beleive it is incorrect, please let us know!
In case your MCU is not yet supported directly, developing a new port is quite easy, just a matter of defining a few macros
according to your specific MCU. See trcPort.h for further information.
In case you have any questions, do not hesitate to contact support@percepio.com
Percepio AB
Köpmangatan 1A
72215 Västerås
Sweden
www.percepio.com

@ -1,992 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcBase.c
*
* Core functionality of the trace recorder library.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#include "trcUser.h"
#include "task.h"
#if (configUSE_TRACE_FACILITY == 1)
/*******************************************************************************
* Static data initializations
******************************************************************************/
/*******************************************************************************
* RecorderData
*
* The main data structure. This is the data read by FreeRTOS+Trace, typically
* through a debugger RAM dump. The recorder access this through the pointer
* RecorderDataPtr, to allow for dynamic memory allocation as well.
*
* On the NXP LPC17xx you may use the secondary RAM bank (AHB RAM) for this
* purpose. For instance, the LPC1766 has 32 KB AHB RAM which allows for
* allocating a buffer size of at least 7500 events without affecting the main
* RAM. To place RecorderData in this RAM bank, use the below declaration.
*
* #pragma location="AHB_RAM_MEMORY"
* RecorderDataType RecorderData = ...
*
* This of course works for other hardware architectures with additional RAM
* banks as well, just replace "AHB_RAM_MEMORY" with the name of the right
* address section from the linker file.
*
* However, to keep trcBase.c portable and still have a preconfigured IAR demo
* using AHB RAM, we don't add the pragma directly in trcBase.c but in a header
* included where the pragma should go. This is used depending on the setting
* USE_LINKER_PRAGMA, defined in trcConfig.h.
*
* If using GCC, this is instead done by adding a "section" attribute:
*
* RecorderDataType RecorderData __attribute__ ((section ("name"))) = ...
*
* Remember to replace "name" with the correct section name.
******************************************************************************/
#if (TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_STATIC)
#if (USE_LINKER_PRAGMA == 1)
#include "recorderdata_linker_pragma.h"
#endif
RecorderDataType RecorderData =
{
/* start marker, 12 chars */
0x01, 0x02, 0x03, 0x04,
0x71, 0x72, 0x73, 0x74,
0xF1, 0xF2, 0xF3, 0xF4,
/* version code - also used to determine endianness */
VERSION,
/* minor file format version */
MINOR_VERSION,
/* irq priority order */
IRQ_PRIORITY_ORDER,
/* file size (for control) */
sizeof(RecorderDataType),
/* number of events stored so far */
0,
/* size of events buffer (in event records, each 4 bytes) */
EVENT_BUFFER_SIZE,
/* next free event index (event index, not byte address) */
0,
/* buffer is full */
0,
/* frequency of clock user for timestamps, in Hz - should be 0 here
as this is used to indicate "not yet initialized" - this is instead
initialized on the first taskswitch event. */
0,
/* the absolute timestamp of the last stored event, modulo frequency */
0,
/* the number of seconds so far */
0,
/* is recorder active (yes = 1) - note that "close" events are always
stored to keep the name-handle mapping updated!*/
0,
/* Generated by FreeRTOS+Trace in Team Admin mode. Otherwise this should be "". */
TEAM_LICENSE_CODE,
/* debug marker 0 */
0xF0F0F0F0,
/* The Object Property Table - holds info of all active objects */
{
/* Number of object classes, also those not used */
NCLASSES,
/* The size in bytes of the object table byte pool */
DynObjTableSize,
/* The number of slots/handles available for each class */
{
NQueue,
NSemaphore,
NMutex,
NTask,
NISR
},
/* The maximum name length for each object class */
{
NameLenQueue,
NameLenSemaphore,
NameLenMutex,
NameLenTask,
NameLenISR
},
/* The total length a property table entry of the class */
{
PropertyTableSizeQueue,
PropertyTableSizeSemaphore,
PropertyTableSizeMutex,
PropertyTableSizeTask,
PropertyTableSizeISR
},
/* The start index of each class in the object property table */
{
StartIndexQueue,
StartIndexSemaphore,
StartIndexMutex,
StartIndexTask,
StartIndexISR
},
/* the object property table - encoded in a byte array using above
definitions */
{0}
},
/* debug marker 1 */
0xF1F1F1F1,
/* The Symbol Table - holds all object names used since system
startup. Every string is unique, so objects with same name will share
an entry. Each name entry has four extra bytes: byte 0-1 is a link
reference in an internal linked list, used for fast lookups, byte 2-3
holds a reference to a channel label used for vTracePrintF format
strings, and byte 4.. holds the object name, followed by a
zero-termination.*/
{
SYMBOL_TABLE_SIZE,
/* next free index (0 is reserved to mean NULL) */
1,
/* the symbol table byte pool */
{0},
/* this is a 64 entry array holding 16-bit references (indexes)
to the most recent entry of each checksum - i.e., list heads.*/
{0},
},
#if (INCLUDE_FLOAT_SUPPORT == 1)
/* example float, for float endian detection */
(float)1.0,
#else
/* This code signals that no float support is included */
(uint32_t)0,
#endif
/* internalErrorOccured */
0,
/* debug marker 2 */
0xF2F2F2F2,
/* The trace description string, can hold any information about the system,
e.g., version, configuration. Error messages from the recorder are
copied to this buffer. Also used for internal error messages.*/
TRACE_DESCRIPTION,
/* debug marker 3 */
0xF3F3F3F3,
/* the event data buffer, size EVENT_BUFFER_SIZE*4 */
{0},
/* end markers, used to extract the trace from a RAM dump image */
0x0A, 0x0B, 0x0C, 0x0D,
0x71, 0x72, 0x73, 0x74,
0xF1, 0xF2, 0xF3, 0xF4
};
RecorderDataType* RecorderDataPtr = &RecorderData;
/* This version of the function does nothing as the trace data is statically allocated */
RecorderDataType* xTraceInitTraceData(void)
{
return 0;
}
#elif (TRACE_DATA_ALLOCATION == TRACE_DATA_ALLOCATION_DYNAMIC)
RecorderDataType* RecorderDataPtr = NULL;
/* This version of the function dynamically allocates the trace data */
RecorderDataType* xTraceInitTraceData(void)
{
RecorderDataType* tmp = (RecorderDataType*)pvPortMalloc(sizeof(RecorderDataType));
if (! tmp)
{
vTraceError("Malloc failed in xTraceInitTraceData! Reduce size constants in trcConfig.h");
return NULL;
}
(void)memset(tmp, 0, sizeof(RecorderDataType));
tmp->startmarker0 = 0x01;
tmp->startmarker1 = 0x02;
tmp->startmarker2 = 0x03;
tmp->startmarker3 = 0x04;
tmp->startmarker4 = 0x71;
tmp->startmarker5 = 0x72;
tmp->startmarker6 = 0x73;
tmp->startmarker7 = 0x74;
tmp->startmarker8 = 0xF1;
tmp->startmarker9 = 0xF2;
tmp->startmarker10 = 0xF3;
tmp->startmarker11 = 0xF4;
tmp->version = VERSION;
tmp->minor_version = MINOR_VERSION;
tmp->irq_priority_order = IRQ_PRIORITY_ORDER;
tmp->filesize = sizeof(RecorderDataType);
tmp->maxEvents = EVENT_BUFFER_SIZE;
tmp->debugMarker0 = 0xF0F0F0F0;
tmp->ObjectPropertyTable.NumberOfObjectClasses = NCLASSES;
tmp->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = DynObjTableSize;
tmp->ObjectPropertyTable.NumberOfObjectsPerClass[0] = NQueue;
tmp->ObjectPropertyTable.NumberOfObjectsPerClass[1] = NSemaphore;
tmp->ObjectPropertyTable.NumberOfObjectsPerClass[2] = NMutex;
tmp->ObjectPropertyTable.NumberOfObjectsPerClass[3] = NTask;
tmp->ObjectPropertyTable.NumberOfObjectsPerClass[4] = NISR;
tmp->ObjectPropertyTable.NameLengthPerClass[0] = NameLenQueue;
tmp->ObjectPropertyTable.NameLengthPerClass[1] = NameLenSemaphore;
tmp->ObjectPropertyTable.NameLengthPerClass[2] = NameLenMutex;
tmp->ObjectPropertyTable.NameLengthPerClass[3] = NameLenTask;
tmp->ObjectPropertyTable.NameLengthPerClass[4] = NameLenISR;
tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue;
tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore;
tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex;
tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask;
tmp->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR;
tmp->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue;
tmp->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore;
tmp->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex;
tmp->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask;
tmp->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR;
tmp->debugMarker1 = 0xF1F1F1F1;
tmp->SymbolTable.symTableSize = SYMBOL_TABLE_SIZE;
tmp->SymbolTable.nextFreeSymbolIndex = 1;
#if (INCLUDE_FLOAT_SUPPORT == 1)
tmp->exampleFloatEncoding = (float)1.0; /* otherwize already zero */
#endif
tmp->debugMarker2 = 0xF2F2F2F2;
(void)strncpy(tmp->systemInfo, TRACE_DESCRIPTION, TRACE_DESCRIPTION_MAX_LENGTH);
tmp->debugMarker3 = 0xF3F3F3F3;
tmp->endmarker0 = 0x0A;
tmp->endmarker1 = 0x0B;
tmp->endmarker2 = 0x0C;
tmp->endmarker3 = 0x0D;
tmp->endmarker4 = 0x71;
tmp->endmarker5 = 0x72;
tmp->endmarker6 = 0x73;
tmp->endmarker7 = 0x74;
tmp->endmarker8 = 0xF1;
tmp->endmarker9 = 0xF2;
tmp->endmarker10 = 0xF3;
tmp->endmarker11 = 0xF4;
RecorderDataPtr = tmp;
return (RecorderDataType*)RecorderDataPtr;
}
#endif
volatile int recorder_busy = 0;
char sprintfBuffer[150];
/* For debug printouts - the names of the object classes */
char OBJECTCLASSNAME[NCLASSES][10] =
{
"QUEUE",
"SEMAPHORE",
"MUTEX",
"TASK",
"ISR"
};
/* Initialization of the handle mechanism, see e.g, xTraceGetObjectHandle */
objectHandleStackType objectHandleStacks =
{
/* indexOfNextAvailableHandle */
{
0,
NQueue,
NQueue + NSemaphore,
NQueue + NSemaphore + NMutex,
NQueue + NSemaphore + NMutex + NTask
},
/* lowestIndexOfClass */
{
0,
NQueue,
NQueue + NSemaphore,
NQueue + NSemaphore + NMutex,
NQueue + NSemaphore + NMutex + NTask
},
/* highestIndexOfClass */
{
NQueue - 1,
NQueue + NSemaphore - 1,
NQueue + NSemaphore + NMutex - 1,
NQueue + NSemaphore + NMutex + NTask - 1,
NQueue + NSemaphore + NMutex + NTask + NISR - 1
},
{0},
{0}
};
/* Used for internal state flags of objects */
uint8_t excludedFlags[(NEventCodes+NQueue+NSemaphore+NMutex+NTask) / 8 + 1];
uint8_t ifeFlags[NTask / 8 + 1];
/* Gives the last error message of the recorder. NULL if no error message. */
char* traceErrorMessage = NULL;
void* xTraceNextFreeEventBufferSlot(void)
{
if (RecorderDataPtr->nextFreeIndex >= EVENT_BUFFER_SIZE)
{
vTraceError("Attempt to index outside event buffer!");
return NULL;
}
return (void*)(&RecorderDataPtr->
eventData[RecorderDataPtr->nextFreeIndex*4]);
}
uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)
{
if ((objectclass < NCLASSES) && (objecthandle > 0) && (objecthandle <=
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
{
return (uint16_t)(RecorderDataPtr->
ObjectPropertyTable.StartIndexOfClass[objectclass] +
(RecorderDataPtr->
ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] *
(objecthandle-1)));
}
vTraceError("Object table lookup with invalid object handle or object class!");
return 0;
}
/*******************************************************************************
* Object handle system
* This provides a mechanism to assign each kernel object (tasks, queues, etc)
* with a 1-byte handle, that is used to identify the object in the trace.
* This way, only one byte instead of four is necessary to identify the object.
* This allows for maximum 255 objects, of each object class, active at any
* moment.
* Note that zero is reserved as an error code and is not a valid handle.
*
* In order to allow for fast dynamic allocation and release of object handles,
* the handles of each object class (e.g., TASK) are stored in a stack. When a
* handle is needed, e.g., on task creation, the next free handle is popped from
* the stack. When an object (e.g., task) is deleted, its handle is pushed back
* on the stack and can thereby be reused for other objects.
*
* Since this allows for reuse of object handles, a specific handle (e.g, "8")
* may refer to TASK_X at one point, and later mean "TASK_Y". To resolve this,
* the recorder uses "Close events", which are stored in the main event buffer
* when objects are deleted and their handles are released. The close event
* contains the mapping between object handle and object name which was valid up
* to this point in time. The object name is stored as a symbol table entry.
******************************************************************************/
objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass)
{
static objectHandleType handle;
static int indexOfHandle;
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
{
/* Zero is used to indicate a never before used handle, i.e.,
new slots in the handle stack. The handle slot needs to
be initialized here (starts at 1). */
objectHandleStacks.objectHandles[indexOfHandle] =
(objectHandleType)(1 + indexOfHandle -
objectHandleStacks.lowestIndexOfClass[objectclass]);
}
handle = objectHandleStacks.objectHandles[indexOfHandle];
if ( objectHandleStacks.indexOfNextAvailableHandle[objectclass]
> objectHandleStacks.highestIndexOfClass[objectclass] )
{
/* ERROR */
switch(objectclass)
{
case TRACE_CLASS_TASK:
vTraceError("Not enough TASK handles - increase NTask in trcConfig.h");
break;
case TRACE_CLASS_ISR:
vTraceError("Not enough ISR handles - increase NISR in trcConfig.h");
break;
case TRACE_CLASS_SEMAPHORE:
vTraceError("Not enough SEMAPHORE handles - increase NSemaphore in trcConfig.h");
break;
case TRACE_CLASS_MUTEX:
vTraceError("Not enough MUTEX handles - increase NMutex in trcConfig.h");
break;
case TRACE_CLASS_QUEUE:
vTraceError("Not enough QUEUE handles - increase NQueue in trcConfig.h");
break;
default:
vTraceError("Invalid object class.");
break;
}
handle = 0; /* an invalid/anonymous handle - but the recorder is stopped now... */
}
else
{
int hndCount;
objectHandleStacks.indexOfNextAvailableHandle[objectclass]++;
hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] -
objectHandleStacks.lowestIndexOfClass[objectclass];
if (hndCount >
objectHandleStacks.handleCountWaterMarksOfClass[objectclass])
{
objectHandleStacks.handleCountWaterMarksOfClass[objectclass] =
(objectHandleType)hndCount;
}
}
return handle;
}
void vTraceFreeObjectHandle(traceObjectClass objectclass, objectHandleType handle)
{
int indexOfHandle;
/* Check that there is room to push the handle on the stack */
if ( (objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) <
objectHandleStacks.lowestIndexOfClass[objectclass] )
{
/* Error */
vTraceError("Attempt to free more handles than allocated! (duplicate xTaskDelete or xQueueDelete?)");
}
else
{
objectHandleStacks.indexOfNextAvailableHandle[objectclass]--;
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
objectHandleStacks.objectHandles[indexOfHandle] = handle;
}
}
/*******************************************************************************
* Objects Property Table
*
* This holds the names and properties of the currently active objects, such as
* tasks and queues. This is developed to support "dynamic" objects which might
* be deleted during runtime. Their handles are only valid during their
* lifetime, i.e., from create to delete, as they might be reused on later
* create operations. When an object is deleted from the OPT, its data is moved
* to the trace buffer and/or the symbol table.
* When an object (task, queue, etc.) is created, it receives a handle, which
* together with the object class specifies its location in the OPT. Thus,
* objects of different types may share the same name and/or handle, but still
* be independent objects.
******************************************************************************/
/*******************************************************************************
* vTraceSetObjectName
*
* Registers the names of queues, semaphores and other kernel objects in the
* recorder's Object Property Table, at the given handle and object class.
******************************************************************************/
void vTraceSetObjectName(traceObjectClass objectclass,
objectHandleType handle,
const char* name)
{
static uint16_t idx;
if (handle == 0)
{
vTraceError("Illegal handle (0) in vTraceSetObjectName.");
return;
}
switch(objectclass)
{
case TRACE_CLASS_TASK:
case TRACE_CLASS_ISR:
case TRACE_CLASS_SEMAPHORE:
case TRACE_CLASS_MUTEX:
case TRACE_CLASS_QUEUE:
break;
default:
vTraceError("Illegal object class in vTraceSetObjectName");
break;
}
if (handle >
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])
{
switch(objectclass)
{
case TRACE_CLASS_TASK:
vTraceError("Not enough TASK handles - increase NTask in trcConfig.h");
break;
case TRACE_CLASS_ISR:
vTraceError("Not enough ISR handles - increase NISR in trcConfig.h");
break;
case TRACE_CLASS_SEMAPHORE:
vTraceError("Not enough SEMAPHORE handles - increase NSemaphore in trcConfig.h");
break;
case TRACE_CLASS_MUTEX:
vTraceError("Not enough MUTEX handles - increase NMutex in trcConfig.h");
break;
case TRACE_CLASS_QUEUE:
vTraceError("Not enough QUEUE handles - increase NQueue in trcConfig.h");
break;
}
}
else
{
idx = uiIndexOfObject(handle, objectclass);
if (traceErrorMessage == NULL)
{
(void)strncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]),
name,
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] );
#ifdef WIN32
printf("vTraceSetObjectName(%d, %d, %s)\n", objectclass, handle, name);
#endif
}
}
}
traceLabel prvTraceOpenSymbol(const char* name, traceLabel userEventChannel)
{
static uint16_t result;
static uint8_t len;
static uint8_t crc;
len = 0;
crc = 0;
prvTraceGetChecksum(name, &crc, &len);
trcCRITICAL_SECTION_BEGIN();
result = prvTraceLookupSymbolTableEntry(name, crc, len, userEventChannel);
if (!result)
{
result = prvTraceCreateSymbolTableEntry(name, crc, len, userEventChannel);
}
trcCRITICAL_SECTION_END();
return result;
}
/*******************************************************************************
* Supporting functions
******************************************************************************/
/*******************************************************************************
* vTraceError
*
* Called by various parts in the recorder. Stops the recorder and stores a
* pointer to an error message, which is printed by the monitor task.
* If you are not using the monitor task, you may use xTraceGetLastError()
* from your application to check if the recorder is OK.
*
* Note: If a recorder error is registered before vTraceStart is called, the
* trace start will be aborted. This can occur if any of the Nxxxx constants
* (e.g., NTask) in trcConfig.h is too small.
******************************************************************************/
void vTraceError(const char* msg)
{
vTraceStop();
if (traceErrorMessage == NULL)
{
traceErrorMessage = (char*)msg;
(void)strncpy(RecorderDataPtr->systemInfo,
traceErrorMessage,
TRACE_DESCRIPTION_MAX_LENGTH);
RecorderDataPtr->internalErrorOccured = 1;
}
}
/******************************************************************************
* prvCheckDataToBeOverwrittenForMultiEntryUserEvents
*
* This checks if the next event to be overwritten is a multi-entry user event,
* i.e., a USER_EVENT followed by data entries.
* Such data entries do not have an event code at byte 0, as other events.
* All 4 bytes are user data, so the first byte of such data events must
* not be interpreted as type field. The number of data entries following
* a USER_EVENT is given in the event code of the USER_EVENT.
* Therefore, when overwriting a USER_EVENT (when using in ringbuffer mode)
* any data entries following must be replaced with NULL events (code 0).
*
* This is assumed to execute within a critical section...
*****************************************************************************/
void prvCheckDataToBeOverwrittenForMultiEntryUserEvents(
uint8_t nofEntriesToCheck)
{
/* Generic "int" type is desired - should be 16 bit variable on 16 bit HW */
unsigned int i = 0;
unsigned int e = 0;
while (i < nofEntriesToCheck)
{
e = RecorderDataPtr->nextFreeIndex + i;
if ((RecorderDataPtr->eventData[e*4] > USER_EVENT) &&
(RecorderDataPtr->eventData[e*4] < USER_EVENT + 16))
{
uint8_t nDataEvents = (uint8_t)(RecorderDataPtr->eventData[e*4] - USER_EVENT);
if ((e + nDataEvents) < RecorderDataPtr->maxEvents)
{
(void)memset(& RecorderDataPtr->eventData[e*4], 0, 4 + 4 * nDataEvents);
}
}
i++;
}
}
/*******************************************************************************
* prvTraceUpdateCounters
*
* Updates the index of the event buffer.
******************************************************************************/
void prvTraceUpdateCounters(void)
{
if (RecorderDataPtr->recorderActive == 0)
{
return;
}
RecorderDataPtr->numEvents++;
RecorderDataPtr->nextFreeIndex++;
if (RecorderDataPtr->nextFreeIndex >= EVENT_BUFFER_SIZE)
{
#if (RECORDER_STORE_MODE == STORE_MODE_RING_BUFFER)
RecorderDataPtr->bufferIsFull = 1;
RecorderDataPtr->nextFreeIndex = 0;
#else
vTraceStop();
#endif
}
#if (RECORDER_STORE_MODE == STORE_MODE_RING_BUFFER)
prvCheckDataToBeOverwrittenForMultiEntryUserEvents(1);
#endif
#ifdef STOP_AFTER_N_EVENTS
#if (STOP_AFTER_N_EVENTS > -1)
if (RecorderDataPtr->numEvents >= STOP_AFTER_N_EVENTS)
{
vTraceStop();
}
#endif
#endif
}
/******************************************************************************
* prvTraceGetDTS
*
* Returns a differential timestamp (DTS), i.e., the time since
* last event, and creates an XTS event if the DTS does not fit in the
* number of bits given. The XTS event holds the MSB bytes of the DTS.
*
* The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for
* events with 16-bit dts fields.
*****************************************************************************/
uint16_t prvTraceGetDTS(uint16_t param_maxDTS)
{
static uint32_t old_timestamp = 0;
XTSEvent* xts = 0;
uint32_t dts = 0;
uint32_t timestamp = 0;
if (RecorderDataPtr->frequency == 0)
{
/* If HWTC_PERIOD is mapped to the timer reload register,
such as in the Cortex M port, it is not initialized before
FreeRTOS has been started. We therefore store the frequency
of the timer at the first timestamped event after the
scheduler has started. (Note that this function is called
also by vTraceStart and uiTraceStart, which might be
called before the scheduler has been started.) */
#if (SELECTED_PORT == PORT_Win32)
RecorderDataPtr->frequency = 100000;
#elif (SELECTED_PORT == PORT_HWIndependent)
RecorderDataPtr->frequency = configTICK_RATE_HZ;
#else
if (xTaskGetSchedulerState() != 0) /* Has the scheduler started? */
{
RecorderDataPtr->frequency =
(uint32_t)HWTC_PERIOD * (uint32_t)configTICK_RATE_HZ / (uint32_t)HWTC_DIVISOR;
}
#endif
}
/**************************************************************************
* The below statements read the timestamp from the timer port module.
* If necessary, whole seconds are extracted using division while the rest
* comes from the modulo operation.
**************************************************************************/
uiTracePortGetTimeStamp(&timestamp);
/***************************************************************************
* This condition is only for the Win32 port, since it does not use the tick
* count but instead only HWTC_COUNT (from the performance counter).
* Without this condition, you sometimes get a negative dts value (converted
* into a very large unsiged value) when the performance counter wraps
* around. In other "normal" ports also using the FreeRTOS tick counter, this
* condition can not occur and therefore has no impact.
***************************************************************************/
if (timestamp < old_timestamp)
{
timestamp += RecorderDataPtr->frequency;
}
dts = timestamp - old_timestamp;
old_timestamp = timestamp;
if (RecorderDataPtr->frequency > 0)
{
/* Check if dts > 1 second */
if (dts > RecorderDataPtr->frequency)
{
/* More than 1 second has passed */
RecorderDataPtr->absTimeLastEventSecond += dts / RecorderDataPtr->frequency;
/* The part that is not an entire second is added to absTimeLastEvent */
RecorderDataPtr->absTimeLastEvent += dts % RecorderDataPtr->frequency;
}
else
RecorderDataPtr->absTimeLastEvent += dts;
/* Check if absTimeLastEvent >= 1 second */
if (RecorderDataPtr->absTimeLastEvent >= RecorderDataPtr->frequency)
{
/* RecorderDataPtr->absTimeLastEvent is more than or equal to 1 second, but always less than 2 seconds */
RecorderDataPtr->absTimeLastEventSecond++;
RecorderDataPtr->absTimeLastEvent -= RecorderDataPtr->frequency;
/* RecorderDataPtr->absTimeLastEvent is now less than 1 second */
}
}
else
{
/* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero) */
RecorderDataPtr->absTimeLastEvent = timestamp;
}
/* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */
if (dts > param_maxDTS)
{
/* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/
xts = (XTSEvent*) xTraceNextFreeEventBufferSlot();
if (xts != NULL)
{
if (param_maxDTS == 0xFFFF)
{
xts->type = XTS16;
xts->xts_16 = (uint16_t)((dts / 0x10000) & 0xFFFF);
xts->xts_8 = 0;
}
else if (param_maxDTS == 0xFF)
{
xts->type = XTS8;
xts->xts_16 = (uint16_t)((dts / 0x100) & 0xFFFF);
xts->xts_8 = (uint8_t)((dts / 0x1000000) & 0xFF);
}
else
{
vTraceError("Bad param_maxDTS in prvTraceGetDTS");
}
prvTraceUpdateCounters();
}
}
return (uint16_t)(dts % (param_maxDTS + 1));
}
/*******************************************************************************
* prvTraceLookupSymbolTableEntry
*
* Find an entry in the symbol table, return 0 if not present.
*
* The strings are stored in a byte pool, with four bytes of "meta-data" for
* every string.
* byte 0-1: index of next entry with same checksum (for fast lookup).
* byte 2-3: reference to a symbol table entry, a label for vTracePrintF
* format strings only (the handle of the destination channel).
* byte 4..(4 + length): the string (object name or user event label), with
* zero-termination
******************************************************************************/
traceLabel prvTraceLookupSymbolTableEntry(const char* name,
uint8_t crc6,
uint8_t len,
traceLabel chn)
{
uint16_t i = RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ];
while (i != 0)
{
if (RecorderDataPtr->SymbolTable.symbytes[i + 2] == (chn & 0x00FF))
{
if (RecorderDataPtr->SymbolTable.symbytes[i + 3] == (chn / 0x100))
{
if (RecorderDataPtr->SymbolTable.symbytes[i + 4 + len] == '\0')
{
if (strncmp((char*)(& RecorderDataPtr->SymbolTable.symbytes[i + 4]), name, len) == 0)
{
break; /* found */
}
}
}
}
i = (uint16_t)(RecorderDataPtr->SymbolTable.symbytes[i] + (RecorderDataPtr->SymbolTable.symbytes[i + 1] * 0x100));
}
return i;
}
/*******************************************************************************
* prvTraceCreateSymbolTableEntry
*
* Creates an entry in the symbol table, independent if it exists already.
*
* The strings are stored in a byte pool, with four bytes of "meta-data" for
* every string.
* byte 0-1: index of next entry with same checksum (for fast lookup).
* byte 2-3: reference to a symbol table entry, a label for vTracePrintF
* format strings only (the handle of the destination channel).
* byte 4..(4 + length): the string (object name or user event label), with
* zero-termination
******************************************************************************/
uint16_t prvTraceCreateSymbolTableEntry(const char* name,
uint8_t crc6,
uint8_t len,
traceLabel channel)
{
uint16_t ret = 0;
if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= SYMBOL_TABLE_SIZE)
{
vTraceError("Symbol table full. Increase SYMBOL_TABLE_SIZE in trcConfig.h");
ret = 0;
}
else
{
RecorderDataPtr->SymbolTable.symbytes
[ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex] =
(uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF);
RecorderDataPtr->SymbolTable.symbytes
[ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1] =
(uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100);
RecorderDataPtr->SymbolTable.symbytes
[ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2] =
(uint8_t)(channel & 0x00FF);
RecorderDataPtr->SymbolTable.symbytes
[ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3] =
(uint8_t)(channel / 0x100);
/* set name (bytes 4...4+len-1) */
(void)strncpy((char*)&( RecorderDataPtr->SymbolTable.symbytes
[ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4] ), name, len);
/* Set zero termination (at offest 4+len) */
RecorderDataPtr->SymbolTable.symbytes
[RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len] = '\0';
/* store index of entry (for return value, and as head of LL[crc6]) */
RecorderDataPtr->SymbolTable.latestEntryOfChecksum
[ crc6 ] = (uint16_t)RecorderDataPtr->SymbolTable.nextFreeSymbolIndex;
RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += (len + 5);
ret = (uint16_t)(RecorderDataPtr->SymbolTable.nextFreeSymbolIndex -
(len + 5));
}
return ret;
}
/*******************************************************************************
* prvTraceGetChecksum
*
* Calculates a simple 6-bit checksum from a string, used to index the string
* for fast symbol table lookup.
******************************************************************************/
void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
{
unsigned char c;
int length = 0;
int crc = 0;
if ( pname != (const char *) 0 )
{
for ( ; (c = *pname++) != '\0'; )
{
crc += c;
length++;
}
}
*pcrc = (uint8_t)(crc % 64);
*plength = (uint8_t)length;
}
#endif

@ -1,491 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.c
*
* Functions for integration of the trace recorder library in the FreeRTOS
* kernel (requires FreeRTOS v7.1.0 or later).
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
* www.percepio.com
******************************************************************************/
#include "trcUser.h"
#include "task.h"
#if (configUSE_TRACE_FACILITY == 1)
/******************************************************************************
* TraceObjectClassTable
* Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
* This was added since we want to map both types of Mutex and both types of
* Semaphores on common classes for all Mutexes and all Semaphores respectively.
*
* FreeRTOS Queue types
* #define queueQUEUE_TYPE_BASE ( 0U ) => TRACE_CLASS_QUEUE
* #define queueQUEUE_TYPE_MUTEX ( 1U ) => TRACE_CLASS_MUTEX
* #define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U ) => TRACE_CLASS_SEMAPHORE
* #define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U ) => TRACE_CLASS_SEMAPHORE
* #define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U ) => TRACE_CLASS_MUTEX
******************************************************************************/
traceObjectClass TraceObjectClassTable[5] = {TRACE_CLASS_QUEUE,
TRACE_CLASS_MUTEX,
TRACE_CLASS_SEMAPHORE,
TRACE_CLASS_SEMAPHORE,
TRACE_CLASS_MUTEX };
/* This is defined in FreeRTOS! */
extern volatile void * volatile pxCurrentTCB;
/* Internal variables */
uint8_t nISRactive = 0;
objectHandleType handle_of_last_logged_task = 0;
uint8_t inExcludedTask = 0;
static uint8_t prvTraceIsObjectExcluded(traceObjectClass, uint32_t);
/*******************************************************************************
* prvTraceIsObjectExcluded
*
* Private function that accepts an object class and an object number and uses
* that to determine if the object has been flagged as excluded.
******************************************************************************/
static uint8_t prvTraceIsObjectExcluded(traceObjectClass objectClass, uint32_t objectNumber)
{
switch(objectClass)
{
case TRACE_CLASS_QUEUE:
return GET_QUEUE_FLAG_ISEXCLUDED(objectNumber);
break;
case TRACE_CLASS_SEMAPHORE:
return GET_SEMAPHORE_FLAG_ISEXCLUDED(objectNumber);
break;
case TRACE_CLASS_MUTEX:
return GET_MUTEX_FLAG_ISEXCLUDED(objectNumber);
break;
case TRACE_CLASS_TASK:
return GET_TASK_FLAG_ISEXCLUDED(objectNumber);
break;
}
return 0;
}
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
/*******************************************************************************
* vTraceStoreTaskReady
*
* This function stores a ready state for the task handle sent in as parameter.
******************************************************************************/
void vTraceStoreTaskReady(objectHandleType handle)
{
uint16_t dts3;
TREvent* tr;
if (!GET_TASK_FLAG_ISEXCLUDED(handle))
{
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
{
tr = (TREvent*)xTraceNextFreeEventBufferSlot();
if (tr != NULL)
{
tr->type = TR_TASK_READY;
tr->dts = dts3;
tr->objHandle = handle;
prvTraceUpdateCounters();
}
}
}
}
#endif
/*******************************************************************************
* vTraceStoreKernelCall
*
* This is the main integration point for storing FreeRTOS kernel calls, and
* is called by the hooks in FreeRTOS.h (see trcKernel.h for event codes).
******************************************************************************/
void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
{
KernelCall * kse;
uint16_t dts1;
if (handle_of_last_logged_task == 0)
{
return;
}
if (RecorderDataPtr->recorderActive)
{
/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
if (nISRactive || !inExcludedTask)
{
/* Make sure ISRs never change the IFE flags of tasks */
if (!nISRactive)
{
/* This checks if this is the first kernel call after a call to
vTraceTaskInstanceIsFinished. In that case, calls to this kernel service
with this specific kernel object become the "instance finish event"
(IFE) of the calling task.*/
if (GET_TASK_FLAG_MARKIFE(handle_of_last_logged_task))
{
/* Reset the flag - this has been handled now */
CLEAR_TASK_FLAG_MARKIFE(handle_of_last_logged_task);
/* Store the kernel service tagged as instance finished event */
PROPERTY_TASK_IFE_SERVICECODE(handle_of_last_logged_task) =
(uint8_t)ecode;
/* Store the handle of the specific kernel object */
PROPERTY_TASK_IFE_OBJHANDLE(handle_of_last_logged_task) =
(objectHandleType)objectNumber;
}
}
/* Check if the referenced object or the event code is excluded */
if (!prvTraceIsObjectExcluded(objectClass, objectNumber) && !GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
{
trcCRITICAL_SECTION_BEGIN();
dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
{
kse = (KernelCall*) xTraceNextFreeEventBufferSlot();
if (kse != NULL)
{
kse->dts = dts1;
kse->type = (uint8_t)ecode;
kse->objHandle = (uint8_t)objectNumber;
prvTraceUpdateCounters();
}
}
trcCRITICAL_SECTION_END();
}
}
}
}
/*******************************************************************************
* vTraceStoreKernelCallWithParam
*
* Used for storing kernel calls with a handle and a numeric parameter. This is
* only used for traceTASK_PRIORITY_SET at the moment.
******************************************************************************/
void vTraceStoreKernelCallWithParam(uint32_t evtcode,
traceObjectClass objectClass,
uint32_t objectNumber,
uint8_t param)
{
KernelCallWithParamAndHandle * kse;
uint8_t dts2;
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task &&
(! inExcludedTask || nISRactive))
{
/* Check if the referenced object or the event code is excluded */
if (!prvTraceIsObjectExcluded(objectClass, objectNumber) && !GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
{
trcCRITICAL_SECTION_BEGIN();
dts2 = (uint8_t)prvTraceGetDTS(0xFF);
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
{
kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();
if (kse != NULL)
{
kse->dts = dts2;
kse->type = (uint8_t)evtcode;
kse->objHandle = (uint8_t)objectNumber;
kse->param = param;
prvTraceUpdateCounters();
}
}
trcCRITICAL_SECTION_END();
}
}
}
/*******************************************************************************
* vTraceStoreKernelCallWithNumericParamOnly
*
* Used for storing kernel calls with numeric parameters only. This is
* only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.
******************************************************************************/
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint16_t param)
{
KernelCallWithParam16 * kse;
uint8_t dts6;
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task
&& (! inExcludedTask || nISRactive))
{
/* Check if the event code is excluded */
if (!GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
{
trcCRITICAL_SECTION_BEGIN();
dts6 = (uint8_t)prvTraceGetDTS(0xFF);
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
{
kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
if (kse != NULL)
{
kse->dts = dts6;
kse->type = (uint8_t)evtcode;
kse->param = param;
prvTraceUpdateCounters();
}
}
trcCRITICAL_SECTION_END();
}
}
}
objectHandleType handle_of_running_task = 0;
/*******************************************************************************
* vTraceStoreTaskswitch
* Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.
* At this point interrupts are assumed to be disabled!
******************************************************************************/
void vTraceStoreTaskswitch(void)
{
uint16_t dts3;
TSEvent* ts;
int8_t skipEvent = 0;
uint32_t schedulerState = 0;
/***************************************************************************
This is used to detect if a high-priority ISRs is illegally using the
recorder ISR trace functions (vTraceStoreISRBegin and ...End) while the
recorder is busy with a task-level event or lower priority ISR event.
If this is detected, it triggers a call to vTraceError with the error
"Illegal call to vTraceStoreISRBegin/End". If you get this error, it means
that the macro taskENTER_CRITICAL does not disable this ISR, as required.
You can solve this by adjusting the value of the FreeRTOS constant
configMAX_SYSCALL_INTERRUPT_PRIORITY, which is defined in FreeRTOSConfig.h
Note: Setting recorder_busy is normally handled in our macros
trcCRITICAL_SECTION_BEGIN and _END, but is needed explicitly in this
function since critical sections should not be used in the context switch
event...)
***************************************************************************/
recorder_busy++;
schedulerState = xTaskGetSchedulerState();
if (schedulerState == 0)
{
/* This occurs on the very first taskswitch event, generated by
vTraceStart and uiTraceStart if the scheduler is not yet started.
This creates a dummy "(startup)" task entry internally in the
recorder */
if (handle_of_running_task == 0)
{
handle_of_running_task = xTraceGetObjectHandle(TRACE_CLASS_TASK);
vTraceSetObjectName(TRACE_CLASS_TASK,
handle_of_running_task,
"(startup)");
vTraceSetPriorityProperty(TRACE_CLASS_TASK,
handle_of_running_task,
0);
}
}
else
{
handle_of_running_task =
(objectHandleType)uxTaskGetTaskNumber(xTaskGetCurrentTaskHandle());
}
/* Skip the event if the task has been excluded, using vTraceExcludeTask */
if (GET_TASK_FLAG_ISEXCLUDED(handle_of_running_task))
{
skipEvent = 1;
inExcludedTask = 1;
}
else
inExcludedTask = 0;
/* Skip the event if the same task is scheduled */
if (handle_of_running_task == handle_of_last_logged_task)
{
skipEvent = 1;
}
if (! RecorderDataPtr->recorderActive)
{
skipEvent = 1;
}
/* If this event should be logged, log it! */
if (skipEvent == 0)
{
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
{
handle_of_last_logged_task = handle_of_running_task;
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
if (ts != NULL)
{
if (uiTraceGetObjectState(TRACE_CLASS_TASK,
handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)
{
ts->type = TS_TASK_RESUME;
}
else
{
ts->type = TS_TASK_BEGIN;
}
ts->dts = dts3;
ts->objHandle = handle_of_last_logged_task;
vTraceSetObjectState(TRACE_CLASS_TASK,
handle_of_last_logged_task,
TASK_STATE_INSTANCE_ACTIVE);
prvTraceUpdateCounters();
}
}
}
/* See comment on recorder_busy++ above. */
recorder_busy--;
}
/*******************************************************************************
* vTraceStoreNameCloseEvent
*
* Updates the symbol table with the name of this object from the dynamic
* objects table and stores a "close" event, holding the mapping between handle
* and name (a symbol table handle). The stored name-handle mapping is thus the
* "old" one, valid up until this point.
******************************************************************************/
#if (INCLUDE_OBJECT_DELETE == 1)
void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,
traceObjectClass objectclass)
{
ObjCloseNameEvent * ce;
const char * name;
traceLabel idx;
name = PROPERTY_NAME_GET(objectclass, handle);
idx = prvTraceOpenSymbol(name, 0);
// Interrupt disable not necessary, already done in trcHooks.h macro
ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();
if (ce != NULL)
{
ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;
ce->objHandle = handle;
ce->symbolIndex = idx;
prvTraceUpdateCounters();
}
}
void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
traceObjectClass objectclass)
{
ObjClosePropEvent * pe;
if (objectclass == TRACE_CLASS_ISR)
{
/* ISR handles should not be closed - never called for ISR */
return;
}
// Interrupt disable not necessary, already done in trcHooks.h macro
pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();
if (pe != NULL)
{
if (objectclass == TRACE_CLASS_TASK)
{
pe->arg1 = PROPERTY_ACTOR_PRIORITY(objectclass, handle);
pe->arg2 = PROPERTY_TASK_IFE_SERVICECODE(handle);
pe->arg3 = PROPERTY_TASK_IFE_OBJHANDLE(handle);
PROPERTY_TASK_IFE_SERVICECODE(handle) = 0;
PROPERTY_TASK_IFE_OBJHANDLE(handle) = 0;
}else{
pe->arg1 = PROPERTY_OBJECT_STATE(objectclass, handle);
}
pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
prvTraceUpdateCounters();
}
}
#endif
void vTraceSetPriorityProperty(uint8_t objectclass, uint8_t id, uint8_t value)
{
PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
}
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, uint8_t id)
{
return PROPERTY_ACTOR_PRIORITY(objectclass, id);
}
void vTraceSetObjectState(uint8_t objectclass, uint8_t id, uint8_t value)
{
PROPERTY_OBJECT_STATE(objectclass, id) = value;
}
void vTraceSetTaskInstanceFinished(objectHandleType handle)
{
#if (USE_IMPLICIT_IFE_RULES == 1)
if (PROPERTY_TASK_IFE_SERVICECODE(handle) == 0)
{
PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
}
#endif
}
uint8_t uiTraceGetObjectState(uint8_t objectclass, uint8_t id)
{
return PROPERTY_OBJECT_STATE(objectclass, id);
}
#endif

@ -1,208 +0,0 @@
/*******************************************************************************
* FreeRTOS+Trace v2.3.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcPort.c
*
* Contains all portability issues of the trace recorder library.
* See also trcPort.h, where port-specific macros are defined.
*
* 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
* 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
* sold or in other ways commercially redistributed without explicit written
* permission by Percepio AB.
*
* Disclaimer
* The trace tool and recorder library is being delivered to you AS IS and
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
* not and cannot warrant the performance or results you may obtain by using the
* software or documentation. Percepio AB make no warranties, express or
* implied, as to noninfringement of third party rights, merchantability, or
* fitness for any particular purpose. In no event will Percepio AB, its
* technology partners, or distributors be liable to you for any consequential,
* incidental or special damages, including any lost profits or lost savings,
* even if a representative of Percepio AB has been advised of the possibility
* of such damages, or for any claim by any third party. Some jurisdictions do
* not allow the exclusion or limitation of incidental, consequential or special
* 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.
*
* 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.
*
* 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.
* www.percepio.com
******************************************************************************/
#include "trcUser.h"
#if (configUSE_TRACE_FACILITY == 1)
#if (INCLUDE_SAVE_TO_FILE == 1)
static char* prvFileName = NULL;
#endif
/*******************************************************************************
* uiTraceTickCount
*
* This variable is updated by the traceTASK_INCREMENT_TICK macro in the
* FreeRTOS tick handler. This does not need to be modified when developing a
* new timer port. It is prefered to keep any timer port changes in the HWTC
* macro definitions, which typically give sufficient flexibility.
******************************************************************************/
uint32_t uiTraceTickCount = 0;
/******************************************************************************
* uiTracePortGetTimeStamp
*
* 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
* or the trace recorder library. Typically you should not need to change
* the code of uiTracePortGetTimeStamp 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 license 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 *pTimestamp)
{
static uint32_t last_traceTickCount = 0;
static uint32_t last_hwtc_count = 0;
uint32_t traceTickCount = 0;
uint32_t hwtc_count = 0;
/* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */
#if (HWTC_COUNT_DIRECTION == DIRECTION_INCREMENTING)
hwtc_count = HWTC_COUNT;
#elif (HWTC_COUNT_DIRECTION == DIRECTION_DECREMENTING)
hwtc_count = HWTC_PERIOD - HWTC_COUNT;
#else
Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly!
Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING
#endif
if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
{
/* This means last_traceTickCount is higher than uiTraceTickCount,
so we have previously compensated for a missed tick.
Therefore we use the last stored value because that is more accurate. */
traceTickCount = last_traceTickCount;
}
else
{
/* Business as usual */
traceTickCount = uiTraceTickCount;
}
/* Check for overflow. May occur if the update of uiTraceTickCount has been
delayed due to disabled interrupts. */
if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
{
/* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
traceTickCount++;
}
/* Check if the return address is OK, then we perform the calculation. */
if (pTimestamp)
{
/* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
*pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR);
/* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */
*pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR;
}
/* Store the previous values. */
last_traceTickCount = traceTickCount;
last_hwtc_count = hwtc_count;
}
/*******************************************************************************
* vTracePortEnd
*
* This function is called by the monitor when a recorder stop is detected.
* This is used by the Win32 port to store the trace to a file. The file path is
* set using vTracePortSetOutFile.
******************************************************************************/
void vTracePortEnd()
{
vTraceConsoleMessage("\n\r[FreeRTOS+Trace] Running vTracePortEnd.\n\r");
#if (WIN32_PORT_SAVE_WHEN_STOPPED == 1)
vTracePortSave();
#endif
#if (WIN32_PORT_EXIT_WHEN_STOPPED == 1)
/* In the FreeRTOS/Win32 demo, this allows for killing the application
when the recorder is stopped (e.g., when the buffer is full) */
system("pause");
exit(0);
#endif
}
#if (INCLUDE_SAVE_TO_FILE == 1)
/*******************************************************************************
* vTracePortSetOutFile
*
* Sets the filename/path used in vTracePortSave.
* This is set in a separate function, since the Win32 port calls vTracePortSave
* in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.
******************************************************************************/
void vTracePortSetOutFile(char* path)
{
prvFileName = path;
}
/*******************************************************************************
* vTracePortSave
*
* Saves the trace to a file on a local file system. The path is set in a
* separate function, vTracePortSetOutFile, since the Win32 port calls
* vTracePortSave in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.
******************************************************************************/
void vTracePortSave()
{
char buf[180];
FILE* f;
if (prvFileName == NULL)
{
prvFileName = "FreeRTOSPlusTrace.dump";
sprintf(buf, "No filename specified, using default \"%s\".", prvFileName);
vTraceConsoleMessage(buf);
}
fopen_s(&f, prvFileName, "wb");
if (f)
{
fwrite(RecorderDataPtr, sizeof(RecorderDataType), 1, f);
fclose(f);
sprintf(buf, "\n\r[FreeRTOS+Trace] Saved in: %s\n\r", prvFileName);
vTraceConsoleMessage(buf);
}
else
{
sprintf(buf, "\n\r[FreeRTOS+Trace] Failed to write to output file!\n\r");
vTraceConsoleMessage(buf);
}
}
#endif
#endif
Loading…
Cancel
Save