mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
+ New feature added: Task notifications.
+ Optimise Cortex-M4F ports by inlining some critical section macros. + Original ports used a #define to set the path to portmacro.h - that method has been obsolete for years and now all the old definitions have been moved into a separate header files called deprecated_definitions.h. + Cortex-M port now check the active vector bits against 0xff when determining if a function is called from an interrupt - previously only a subset of the bits (0x1f) were checked. + Add in new standard demo/test files TaskNotify.c/h and include the files in the simulator demos. + Update trace recorder code, and some demos to use the new version (more to do). + Introduce uxTaskPriorityGetFromISR(). + Minor typo corrections. + Update MingW simulator demo to match the MSVC simulator demo.
This commit is contained in:
parent
ca22607d14
commit
85fb1cc024
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcConfig.h
|
* trcConfig.h
|
||||||
|
@ -36,16 +36,101 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef TRCCONFIG_H
|
#ifndef TRCCONFIG_H
|
||||||
#define TRCCONFIG_H
|
#define TRCCONFIG_H
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* SELECTED_PORT
|
||||||
|
*
|
||||||
|
* Macro that specifies what hardware port that should be used.
|
||||||
|
* Available ports are:
|
||||||
|
*
|
||||||
|
* Port Name Code Official OS supported
|
||||||
|
* PORT_APPLICATION_DEFINED -2 - -
|
||||||
|
* PORT_NOT_SET -1 - -
|
||||||
|
* PORT_HWIndependent 0 Yes Any
|
||||||
|
* PORT_Win32 1 Yes FreeRTOS on Win32
|
||||||
|
* PORT_Atmel_AT91SAM7 2 No Any
|
||||||
|
* PORT_Atmel_UC3A0 3 No Any
|
||||||
|
* PORT_ARM_CortexM 4 Yes Any
|
||||||
|
* PORT_Renesas_RX600 5 Yes Any
|
||||||
|
* PORT_Microchip_dsPIC_AND_PIC24 6 Yes Any
|
||||||
|
* PORT_TEXAS_INSTRUMENTS_TMS570 7 No Any
|
||||||
|
* PORT_TEXAS_INSTRUMENTS_MSP430 8 No Any
|
||||||
|
* PORT_MICROCHIP_PIC32MX 9 Yes Any
|
||||||
|
* PORT_XILINX_PPC405 10 No FreeRTOS
|
||||||
|
* PORT_XILINX_PPC440 11 No FreeRTOS
|
||||||
|
* PORT_XILINX_MICROBLAZE 12 No Any
|
||||||
|
* PORT_NXP_LPC210X 13 No Any
|
||||||
|
* PORT_MICROCHIP_PIC32MZ 14 Yes Any
|
||||||
|
* PORT_ARM_CORTEX_A9 15 No Any
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
// Set the port setting here!
|
||||||
|
#define SELECTED_PORT PORT_NOT_SET
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_NOT_SET)
|
||||||
|
#error "You need to define SELECTED_PORT here!"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// For Win32 demo projects this is set automatically
|
||||||
|
#define SELECTED_PORT PORT_Win32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FREERTOS_VERSION
|
||||||
|
*
|
||||||
|
* Specify what version of FreeRTOS that is used. This is necessary compensate
|
||||||
|
* for renamed symbols in the FreeRTOS kernel (does not build if incorrect).
|
||||||
|
*
|
||||||
|
* FREERTOS_VERSION_7_3_OR_7_4 (= 1) If using FreeRTOS v7.3.0 - v7.4.2
|
||||||
|
* FREERTOS_VERSION_7_5_OR_7_6 (= 2) If using FreeRTOS v7.5.0 - v7.6.0
|
||||||
|
* FREERTOS_VERSION_8_0_OR_LATER (= 3) If using FreeRTOS v8.0.0 or later
|
||||||
|
*****************************************************************************/
|
||||||
|
#define FREERTOS_VERSION FREERTOS_VERSION_8_0_OR_LATER
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_RECORDER_STORE_MODE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as one of:
|
||||||
|
* - TRACE_STORE_MODE_RING_BUFFER
|
||||||
|
* - TRACE_STORE_MODE_STOP_WHEN_FULL
|
||||||
|
* Default is TRACE_STORE_MODE_RING_BUFFER.
|
||||||
|
*
|
||||||
|
* With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the
|
||||||
|
* events are stored in a ring buffer, i.e., where the oldest events are
|
||||||
|
* overwritten when the buffer becomes full. This allows you to get the last
|
||||||
|
* events leading up to an interesting state, e.g., an error, without having
|
||||||
|
* to store the whole run since startup.
|
||||||
|
*
|
||||||
|
* When TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the
|
||||||
|
* recording is stopped when the buffer becomes full. This is useful for
|
||||||
|
* recording events following a specific state, e.g., the startup sequence.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_STOP_WHEN_FULL
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* CONFIGURATION RELATED TO CAPACITY AND ALLOCATION
|
* TRACE_SCHEDULING_ONLY
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* If this setting is enabled (= 1), only scheduling events are recorded.
|
||||||
|
* If disabled (= 0), all events are recorded.
|
||||||
|
*
|
||||||
|
* Users of FreeRTOS+Trace Free Edition only displays scheduling events, so this
|
||||||
|
* option can be used to avoid storing unsupported events.
|
||||||
|
*
|
||||||
|
* Default value is 0 (store all enabled events).
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define TRACE_SCHEDULING_ONLY 0
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* EVENT_BUFFER_SIZE
|
* EVENT_BUFFER_SIZE
|
||||||
|
@ -53,14 +138,221 @@
|
||||||
* Macro which should be defined as an integer value.
|
* Macro which should be defined as an integer value.
|
||||||
*
|
*
|
||||||
* This defines the capacity of the event buffer, i.e., the number of records
|
* 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
|
* it may store. Most events use one record (4 byte), although some events
|
||||||
* vTracePrintF may use multiple records depending on the number of data args.
|
* require multiple 4-byte records. You should adjust this to the amount of RAM
|
||||||
|
* available in the target system.
|
||||||
|
*
|
||||||
|
* Default value is 1000, which means that 4000 bytes is allocated for the
|
||||||
|
* event buffer.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define EVENT_BUFFER_SIZE 1000
|
||||||
#define EVENT_BUFFER_SIZE 4000 /* Adjust wrt. to available RAM */
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
* NTask, NISR, NQueue, NSemaphore, NMutex
|
||||||
|
*
|
||||||
|
* A group of macros which should be defined as integer values, zero or larger.
|
||||||
|
*
|
||||||
|
* These define the capacity of the Object Property Table, i.e., the maximum
|
||||||
|
* number of objects active at any given point, within each object class (e.g.,
|
||||||
|
* task, queue, semaphore, ...).
|
||||||
|
*
|
||||||
|
* If tasks or other other objects are deleted in your system, this
|
||||||
|
* setting does not limit the total amount of objects created, only the number
|
||||||
|
* of objects that have been successfully created but not yet deleted.
|
||||||
|
*
|
||||||
|
* Using too small values will cause vTraceError to be called, which stores an
|
||||||
|
* error message in the trace that is shown when opening the trace file.
|
||||||
|
*
|
||||||
|
* It can be wise to start with large values for these constants,
|
||||||
|
* unless you are very confident on these numbers. Then do a recording and
|
||||||
|
* check the actual usage by selecting View menu -> Trace Details ->
|
||||||
|
* Resource Usage -> Object Table.
|
||||||
|
******************************************************************************/
|
||||||
|
#define NTask 15
|
||||||
|
#define NISR 5
|
||||||
|
#define NQueue 10
|
||||||
|
#define NSemaphore 10
|
||||||
|
#define NMutex 10
|
||||||
|
#define NTimer 2
|
||||||
|
#define NEventGroup 2
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_MEMMANG_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This controls if malloc and free calls should be traced. Set this to zero to
|
||||||
|
* exclude malloc/free calls, or one (1) to include such events in the trace.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_MEMMANG_EVENTS 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_USER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (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
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note that User Events are only displayed in Professional Edition.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_USER_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_ISR_TRACING
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the code for recording Interrupt Service Routines is
|
||||||
|
* excluded to reduce code size.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note, if the kernel has no central interrupt dispatcher, recording ISRs
|
||||||
|
* require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd
|
||||||
|
* in your interrupt handlers.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_ISR_TRACING 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_READY_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If one (1), events are recorded when tasks enter scheduling state "ready".
|
||||||
|
* This uses a lot of space in the event buffer, so excluding "ready events"
|
||||||
|
* will allow for longer traces. Including ready events however allows for
|
||||||
|
* showing the initial pending time before tasks enter the execution state, and
|
||||||
|
* for presenting accurate response times.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_READY_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_NEW_TIME_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (1), events will be generated whenever the OS clock is
|
||||||
|
* increased.
|
||||||
|
*
|
||||||
|
* Default value is 0.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_NEW_TIME_EVENTS 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_FLOAT_SUPPORT
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (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) arguments.
|
||||||
|
*
|
||||||
|
* vTracePrintF can be used with integer and string arguments in either case.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_FLOAT_SUPPORT 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_OBJECT_DELETE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This must be enabled (1) if tasks, queues or other
|
||||||
|
* traced kernel objects are deleted at runtime. If no deletes are made, this
|
||||||
|
* can be set to 0 in order to exclude the delete-handling code.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_OBJECT_DELETE 1
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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. If you don't use User Events or delete any kernel
|
||||||
|
* objects you set this to a very low value. The minimum recommended value is 4.
|
||||||
|
* A size of zero (0) is not allowed since a zero-sized array may result in a
|
||||||
|
* 32-bit pointer, i.e., using 4 bytes rather than 0.
|
||||||
|
*
|
||||||
|
* Default value is 800.
|
||||||
|
******************************************************************************/
|
||||||
|
#define SYMBOL_TABLE_SIZE 800
|
||||||
|
|
||||||
|
#if (SYMBOL_TABLE_SIZE == 0)
|
||||||
|
#error "SYMBOL_TABLE_SIZE may not be zero!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NameLenTask, NameLenQueue, ...
|
||||||
|
*
|
||||||
|
* Macros that specify the maximum lengths (number of characters) for names of
|
||||||
|
* kernel objects, such as tasks and queues. If longer names are used, they will
|
||||||
|
* be truncated when stored in the recorder.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define NameLenTask 15
|
||||||
|
#define NameLenISR 15
|
||||||
|
#define NameLenQueue 15
|
||||||
|
#define NameLenSemaphore 15
|
||||||
|
#define NameLenMutex 15
|
||||||
|
#define NameLenTimer 15
|
||||||
|
#define NameLenEventGroup 15
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*** ADVANCED SETTINGS ********************************************************
|
||||||
|
******************************************************************************
|
||||||
|
* The remaining settings are not necessary to modify but allows for optimizing
|
||||||
|
* the recorder setup for your specific needs, e.g., to exclude events that you
|
||||||
|
* are not interested in, in order to get longer traces.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* HEAP_SIZE_BELOW_16M
|
||||||
|
*
|
||||||
|
* An integer constant that can be used to reduce the buffer usage of memory
|
||||||
|
* allocation events (malloc/free). This value should be 1 if the heap size is
|
||||||
|
* below 16 MB (2^24 byte), and you can live with reported addresses showing the
|
||||||
|
* lower 24 bits only. If 0, you get the full 32-bit addresses.
|
||||||
|
*
|
||||||
|
* Default value is 0.
|
||||||
|
******************************************************************************/
|
||||||
|
#define HEAP_SIZE_BELOW_16M 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
* USE_LINKER_PRAGMA
|
* USE_LINKER_PRAGMA
|
||||||
*
|
*
|
||||||
* Macro which should be defined as an integer value, default is 0.
|
* Macro which should be defined as an integer value, default is 0.
|
||||||
|
@ -78,28 +370,66 @@
|
||||||
*
|
*
|
||||||
* Note that this only applies if using static allocation, see below.
|
* Note that this only applies if using static allocation, see below.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#define USE_LINKER_PRAGMA 0
|
#define USE_LINKER_PRAGMA 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
/*******************************************************************************
|
* USE_IMPLICIT_IFE_RULES
|
||||||
* SYMBOL_TABLE_SIZE
|
|
||||||
*
|
*
|
||||||
* Macro which should be defined as an integer value.
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 1.
|
||||||
*
|
*
|
||||||
* This defines the capacity of the symbol table, in bytes. This symbol table
|
* Tracealyzer groups the events into actor instances, based on context-switches
|
||||||
* stores User Events labels and names of deleted tasks, queues, or other kernel
|
* and a definition of "Instance Finish Events", or IFEs. These are kernel calls
|
||||||
* objects. Note that the names of active objects not stored here but in the
|
* considered to be the last event in a task instance. Some kernel calls are
|
||||||
* Object Table. Thus, if you don't use User Events or delete any kernel
|
* considered IFEs by default (e.g., delay functions), but it is also possible
|
||||||
* objects you set this to a very low value, e.g. 4, but not zero (0) since
|
* to specify this individually for each task (see vTraceTaskInstanceFinish).
|
||||||
* this causes a declaration of a zero-sized array, for which the C compiler
|
*
|
||||||
* behavior is not standardized and may cause misaligned data.
|
* If USE_IMPLICIT_IFE_RULES is one (1), the default IFEs will be enabled, which
|
||||||
******************************************************************************/
|
* gives a "typical" grouping of events into instances. You can combine this
|
||||||
#define SYMBOL_TABLE_SIZE 800
|
* with calls to vTraceTaskInstanceFinish for specific tasks.
|
||||||
|
*
|
||||||
|
* If USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFEs are disabled and all
|
||||||
|
* events withing each task is then shown as a single instance, unless you call
|
||||||
|
* vTraceTaskInstanceFinish() at suitable locations to mark the IFEs.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define USE_IMPLICIT_IFE_RULES 1
|
||||||
|
|
||||||
#if (SYMBOL_TABLE_SIZE == 0)
|
/******************************************************************************
|
||||||
#error "SYMBOL_TABLE_SIZE may not be zero!"
|
* USE_16BIT_OBJECT_HANDLES
|
||||||
#endif
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
|
||||||
|
* objects such as tasks and queues. This limits the supported number of
|
||||||
|
* concurrently active objects to 255 of each type (object class).
|
||||||
|
*
|
||||||
|
* If set to 1 (one), the recorder uses 16-bit handles to identify kernel
|
||||||
|
* objects such as tasks and queues. This limits the supported number of
|
||||||
|
* concurrent objects to 65535 of each type (object class). However, since the
|
||||||
|
* object property table is limited to 64 KB, the practical limit is about
|
||||||
|
* 3000 objects in total.
|
||||||
|
*
|
||||||
|
* Default is 0.
|
||||||
|
*
|
||||||
|
* NOTE: An object with handle above 255 will use an extra 4-byte record in
|
||||||
|
* the event buffer whenever referenced. Moreover, some internal tables in the
|
||||||
|
* recorder gets larger when using 16-bit handles. The additional RAM usage is
|
||||||
|
* 5-10 byte plus 1 byte per kernel object i.e., task, queue, mutex, etc.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define USE_16BIT_OBJECT_HANDLES 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USE_TRACE_ASSERT
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 1.
|
||||||
|
*
|
||||||
|
* If this is one (1), the TRACE_ASSERT macro will verify that a condition is
|
||||||
|
* true. If the condition is false, vTraceError() will be called.
|
||||||
|
* This is used on several places in the recorder code for sanity checks on
|
||||||
|
* parameters. Can be switched off to reduce CPU usage of the tracing.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define USE_TRACE_ASSERT 1
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* USE_SEPARATE_USER_EVENT_BUFFER
|
* USE_SEPARATE_USER_EVENT_BUFFER
|
||||||
|
@ -107,7 +437,10 @@
|
||||||
* Macro which should be defined as an integer value.
|
* Macro which should be defined as an integer value.
|
||||||
* Default is zero (0).
|
* Default is zero (0).
|
||||||
*
|
*
|
||||||
* This enables and disables the use of the separate user event buffer.
|
* This enables and disables the use of the separate user event buffer. Using
|
||||||
|
* this separate buffer has the benefit of not overwriting the user events with
|
||||||
|
* kernel events (usually generated at a much higher rate), i.e., when using
|
||||||
|
* ring-buffer mode.
|
||||||
*
|
*
|
||||||
* Note: When using the separate user event buffer, you may get an artificial
|
* Note: When using the separate user event buffer, you may get an artificial
|
||||||
* task instance named "Unknown actor". This is added as a placeholder when the
|
* task instance named "Unknown actor". This is added as a placeholder when the
|
||||||
|
@ -138,393 +471,5 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define CHANNEL_FORMAT_PAIRS 32
|
#define CHANNEL_FORMAT_PAIRS 32
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* 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 Tracealyzer. If you are using the recorder status monitor task,
|
|
||||||
* any error messages are displayed in console prints, assuming that the
|
|
||||||
* print macro has been defined properly (vConsolePrintMessage).
|
|
||||||
*
|
|
||||||
* It can be wise to start with very large values for these constants,
|
|
||||||
* unless you are very confident on these numbers. Then do a recording and
|
|
||||||
* check the actual usage in Tracealyzer. This is shown by selecting
|
|
||||||
* View -> Trace Details -> Resource Usage -> Object Table
|
|
||||||
*
|
|
||||||
* NOTE 2: Remember to account for all tasks and other objects created by
|
|
||||||
* the kernel, such as the IDLE task, any timer tasks, and any tasks created
|
|
||||||
* by other 3rd party software components, such as communication stacks.
|
|
||||||
* Moreover, one task slot is used to indicate "(startup)", i.e., a fictive
|
|
||||||
* task that represent the time before the scheduler starts.
|
|
||||||
* NTask should thus be at least 2-3 slots larger than your application task count.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
#define NTask 15
|
|
||||||
#define NISR 5
|
|
||||||
#define NQueue 10
|
|
||||||
#define NSemaphore 10
|
|
||||||
#define NMutex 10
|
|
||||||
#define NTimer 2
|
|
||||||
#define NEventGroup 2
|
|
||||||
|
|
||||||
/* Maximum object name length for each class (includes zero termination) */
|
|
||||||
#define NameLenTask 15
|
|
||||||
#define NameLenISR 15
|
|
||||||
#define NameLenQueue 15
|
|
||||||
#define NameLenSemaphore 15
|
|
||||||
#define NameLenMutex 15
|
|
||||||
#define NameLenTimer 15
|
|
||||||
#define NameLenEventGroup 15
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRACE_DESCRIPTION
|
|
||||||
*
|
|
||||||
* Macro which should be defined as a string.
|
|
||||||
*
|
|
||||||
* This string is stored in the trace and displayed in Tracealyzer. Can be
|
|
||||||
* used to store, e.g., system version or build date. This is also used to store
|
|
||||||
* internal error messages from the recorder, which if occurs overwrites the
|
|
||||||
* value defined here. This may be maximum 256 chars.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRACE_DESCRIPTION "Tracealyzer Recorder Test Program"
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* USE_TRACE_ASSERT
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 0.
|
|
||||||
*
|
|
||||||
* If this is one (1), the TRACE_ASSERT macro will verify that a condition is
|
|
||||||
* true. If the condition is false, vTraceError() will be called.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define USE_TRACE_ASSERT 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* INCLUDE_FLOAT_SUPPORT
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 1.
|
|
||||||
*
|
|
||||||
* If this is zero (0), all references to floating point values are removed,
|
|
||||||
* in case floating point values are not supported by the platform used.
|
|
||||||
* Floating point values are only used in vTracePrintF and its subroutines, to
|
|
||||||
* store float (%f) or double (%lf) argments.
|
|
||||||
*
|
|
||||||
* Note: vTracePrintF can still be used with integer and string arguments in
|
|
||||||
* either case.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_FLOAT_SUPPORT 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 User Events 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_NEW_TIME_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 0.
|
|
||||||
*
|
|
||||||
* If this is zero (1), events will be generated whenever the os clock is
|
|
||||||
* increased.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_NEW_TIME_EVENTS 0
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* INCLUDE_ISR_TRACING
|
|
||||||
*
|
|
||||||
* 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, if the kernel has no central interrupt dispatcher, recording ISRs
|
|
||||||
* require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd
|
|
||||||
* in your interrupt handlers.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_ISR_TRACING 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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. If no deletes are made, this
|
|
||||||
* can be set to 0 in order to exclude the delete-handling code.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_OBJECT_DELETE 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* INCLUDE_MEMMANG_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 1.
|
|
||||||
*
|
|
||||||
* This controls if malloc and free calls should be traced. Set this to zero to
|
|
||||||
* exclude malloc/free calls from the tracing.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_MEMMANG_EVENTS 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* CONFIGURATION RELATED TO BEHAVIOR
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRACE_RECORDER_STORE_MODE
|
|
||||||
*
|
|
||||||
* Macro which should be defined as one of:
|
|
||||||
* - TRACE_STORE_MODE_RING_BUFFER
|
|
||||||
* - TRACE_STORE_MODE_STOP_WHEN_FULL
|
|
||||||
* Default is TRACE_STORE_MODE_RING_BUFFER.
|
|
||||||
*
|
|
||||||
* With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the events are
|
|
||||||
* stored in a ring buffer, i.e., where the oldest events are overwritten when
|
|
||||||
* the buffer becomes full. This allows you to get the last events leading up
|
|
||||||
* to an interesting state, e.g., an error, without having a large trace buffer
|
|
||||||
* for string the whole run since startup. In this mode, the recorder can run
|
|
||||||
* "forever" as the buffer never gets full, i.e., in the sense that it always
|
|
||||||
* has room for more events.
|
|
||||||
*
|
|
||||||
* To fetch the trace in mode TRACE_STORE_MODE_RING_BUFFER, you need to first halt the
|
|
||||||
* system using your debugger and then do a RAM dump, or to explicitly stop the
|
|
||||||
* recorder using vTraceStop() and then store/upload the trace data using a
|
|
||||||
* 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 TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the recording is
|
|
||||||
* stopped when the buffer becomes full. When the recorder stops itself this way
|
|
||||||
* vTracePortEnd() is called which allows for custom actions, such as triggering
|
|
||||||
* a task that stores the trace buffer, i.e., in case taking a RAM dump
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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. Tracealyzer allows you to define Instance Finish Events (IFEs),
|
|
||||||
* which marks the point in a cyclic task when the "task instance" ends.
|
|
||||||
* The IFE is a blocking kernel call, typically in the main loop of a task
|
|
||||||
* which typically reads a message queue, waits for a semaphore or performs
|
|
||||||
* an explicit delay.
|
|
||||||
*
|
|
||||||
* If USE_IMPLICIT_IFE_RULES is one (1), the kernel macros (trcKernelPort.h)
|
|
||||||
* will define what kernel calls are considered by default to be IFEs.
|
|
||||||
*
|
|
||||||
* However, Implicit IFEs only applies to blocking kernel calls. If a
|
|
||||||
* service reads a message without blocking, it does not create a new
|
|
||||||
* instance since no blocking occurred.
|
|
||||||
*
|
|
||||||
* Moreover, the actual IFE might sometimes be another blocking call. 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, 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
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* USE_16BIT_OBJECT_HANDLES
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 0.
|
|
||||||
*
|
|
||||||
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
|
|
||||||
* objects such as tasks and queues. This limits the supported number of
|
|
||||||
* concurrently active objects to 255 of each type (object class).
|
|
||||||
*
|
|
||||||
* If set to 1 (one), the recorder uses 16-bit handles to identify kernel
|
|
||||||
* objects such as tasks and queues. This limits the supported number of
|
|
||||||
* concurrent objects to 65535 of each type (object class). However, since the
|
|
||||||
* object property table is limited to 64 KB, the practical limit is about
|
|
||||||
* 3000 objects in total.
|
|
||||||
*
|
|
||||||
* NOTE: An object with a high ID (> 255) will generate an extra event
|
|
||||||
* (= 4 byte) in the event buffer.
|
|
||||||
*
|
|
||||||
* NOTE: Some internal tables in the recorder gets larger when using 16-bit
|
|
||||||
* handles. The additional RAM usage is 5-10 byte plus 1 byte per kernel object
|
|
||||||
*, i.e., task, queue, semaphore, mutex, etc.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define USE_16BIT_OBJECT_HANDLES 0
|
|
||||||
|
|
||||||
/****** Port Name ******************** Code ** Official ** OS Platform ******
|
|
||||||
* PORT_APPLICATION_DEFINED -2 - -
|
|
||||||
* PORT_NOT_SET -1 - -
|
|
||||||
* PORT_HWIndependent 0 Yes Any
|
|
||||||
* PORT_Win32 1 Yes FreeRTOS Win32
|
|
||||||
* PORT_Atmel_AT91SAM7 2 No Any
|
|
||||||
* PORT_Atmel_UC3A0 3 No Any
|
|
||||||
* PORT_ARM_CortexM 4 Yes Any
|
|
||||||
* PORT_Renesas_RX600 5 Yes Any
|
|
||||||
* PORT_Microchip_dsPIC_AND_PIC24 6 Yes Any
|
|
||||||
* PORT_TEXAS_INSTRUMENTS_TMS570 7 No Any
|
|
||||||
* PORT_TEXAS_INSTRUMENTS_MSP430 8 No Any
|
|
||||||
* PORT_MICROCHIP_PIC32 9 No Any
|
|
||||||
* PORT_XILINX_PPC405 10 No FreeRTOS
|
|
||||||
* PORT_XILINX_PPC440 11 No FreeRTOS
|
|
||||||
* PORT_XILINX_MICROBLAZE 12 No Any
|
|
||||||
* PORT_NXP_LPC210X 13 No Any
|
|
||||||
*****************************************************************************/
|
|
||||||
#define SELECTED_PORT PORT_ARM_CortexM
|
|
||||||
|
|
||||||
#if (SELECTED_PORT == PORT_NOT_SET)
|
|
||||||
#error "You need to define SELECTED_PORT here!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* USE_PRIMASK_CS (for Cortex M devices only)
|
|
||||||
*
|
|
||||||
* An integer constant that selects between two options for the critical
|
|
||||||
* sections of the recorder library.
|
|
||||||
*
|
|
||||||
* 0: The default FreeRTOS critical section (BASEPRI) - default setting
|
|
||||||
* 1: Always disable ALL interrupts (using PRIMASK)
|
|
||||||
*
|
|
||||||
* Option 0 uses the standard FreeRTOS macros for critical sections.
|
|
||||||
* However, on Cortex-M devices they only disable interrupts with priorities
|
|
||||||
* below a certain configurable level, while higher priority ISRs remain active.
|
|
||||||
* Such high-priority ISRs may not use the recorder functions in this mode.
|
|
||||||
*
|
|
||||||
* Option 1 allows you to safely call the recorder from any ISR, independent of
|
|
||||||
* the interrupt priority. This mode may however cause higher IRQ latencies
|
|
||||||
* (some microseconds) since ALL configurable interrupts are disabled during
|
|
||||||
* the recorder's critical sections in this mode, using the PRIMASK register.
|
|
||||||
******************************************************************************/
|
|
||||||
#define USE_PRIMASK_CS 0
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* HEAP_SIZE_BELOW_16M
|
|
||||||
*
|
|
||||||
* An integer constant that can be used to reduce the buffer usage of memory
|
|
||||||
* allocation events (malloc/free). This value should be 1 if the heap size is
|
|
||||||
* below 16 MB (2^24 byte), and you can live with addresses truncated to the
|
|
||||||
* lower 24 bit. Otherwise set it to 0 to get the full 32-bit addresses.
|
|
||||||
******************************************************************************/
|
|
||||||
#define HEAP_SIZE_BELOW_16M 0
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcBase.h
|
* trcBase.h
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -235,6 +237,14 @@ typedef struct
|
||||||
uint8_t arg3;
|
uint8_t arg3;
|
||||||
} ObjClosePropEvent;
|
} ObjClosePropEvent;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t unused1;
|
||||||
|
uint8_t unused2;
|
||||||
|
uint8_t dts;
|
||||||
|
} TaskInstanceStatusEvent;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
@ -403,10 +413,8 @@ typedef struct
|
||||||
/* 0xF2F2F2F2 - for control only */
|
/* 0xF2F2F2F2 - for control only */
|
||||||
int32_t debugMarker2;
|
int32_t debugMarker2;
|
||||||
|
|
||||||
/* Generic system information string, presented in the tool. Note that this
|
/* Error messages from the recorder. */
|
||||||
is also used for storing any internal error messages from the recorder, so
|
char systemInfo[80];
|
||||||
do not make TRACE_DESCRIPTION_MAX_LENGTH too small. 80 is recommended. */
|
|
||||||
char systemInfo[TRACE_DESCRIPTION_MAX_LENGTH];
|
|
||||||
|
|
||||||
/* 0xF3F3F3F3 - for control only */
|
/* 0xF3F3F3F3 - for control only */
|
||||||
int32_t debugMarker3;
|
int32_t debugMarker3;
|
||||||
|
@ -519,9 +527,6 @@ RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclas
|
||||||
#define TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedEventCodes, eventCode)
|
#define TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedEventCodes, eventCode)
|
||||||
#define TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_GET_FLAG_ISEXCLUDED(excludedEventCodes, eventCode)
|
#define TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(eventCode) TRACE_GET_FLAG_ISEXCLUDED(excludedEventCodes, eventCode)
|
||||||
|
|
||||||
#define TRACE_INCR_HEAP_USAGE(change) {if (RecorderDataPtr != NULL) RecorderDataPtr->heapMemUsage += change;}
|
|
||||||
#define TRACE_DECR_HEAP_USAGE(change) {if (RecorderDataPtr != NULL) RecorderDataPtr->heapMemUsage -= change;}
|
|
||||||
|
|
||||||
/* DEBUG ASSERTS */
|
/* DEBUG ASSERTS */
|
||||||
#if defined USE_TRACE_ASSERT && USE_TRACE_ASSERT != 0
|
#if defined USE_TRACE_ASSERT && USE_TRACE_ASSERT != 0
|
||||||
#define TRACE_ASSERT(eval, msg, defRetVal) \
|
#define TRACE_ASSERT(eval, msg, defRetVal) \
|
||||||
|
@ -537,3 +542,7 @@ if (!(eval)) \
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcHardwarePort.h
|
* trcHardwarePort.h
|
||||||
|
@ -32,7 +32,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -91,11 +93,11 @@
|
||||||
* to a certain operating system.
|
* to a certain operating system.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/****** Port Name ******************** Code ** Official ** OS Platform *******/
|
/****** Port Name ********************** Code ***** Official ** OS Platform *********/
|
||||||
#define PORT_APPLICATION_DEFINED -2 /* - - */
|
#define PORT_APPLICATION_DEFINED -2 /* - - */
|
||||||
#define PORT_NOT_SET -1 /* - - */
|
#define PORT_NOT_SET -1 /* - - */
|
||||||
#define PORT_HWIndependent 0 /* Yes Any */
|
#define PORT_HWIndependent 0 /* Yes Any */
|
||||||
#define PORT_Win32 1 /* Yes Windows (FreeRTOS)*/
|
#define PORT_Win32 1 /* Yes FreeRTOS on Win32 */
|
||||||
#define PORT_Atmel_AT91SAM7 2 /* No Any */
|
#define PORT_Atmel_AT91SAM7 2 /* No Any */
|
||||||
#define PORT_Atmel_UC3A0 3 /* No Any */
|
#define PORT_Atmel_UC3A0 3 /* No Any */
|
||||||
#define PORT_ARM_CortexM 4 /* Yes Any */
|
#define PORT_ARM_CortexM 4 /* Yes Any */
|
||||||
|
@ -103,13 +105,15 @@
|
||||||
#define PORT_Microchip_dsPIC_AND_PIC24 6 /* Yes Any */
|
#define PORT_Microchip_dsPIC_AND_PIC24 6 /* Yes Any */
|
||||||
#define PORT_TEXAS_INSTRUMENTS_TMS570 7 /* No Any */
|
#define PORT_TEXAS_INSTRUMENTS_TMS570 7 /* No Any */
|
||||||
#define PORT_TEXAS_INSTRUMENTS_MSP430 8 /* No Any */
|
#define PORT_TEXAS_INSTRUMENTS_MSP430 8 /* No Any */
|
||||||
#define PORT_MICROCHIP_PIC32 9 /* No Any */
|
#define PORT_MICROCHIP_PIC32MX 9 /* Yes Any */
|
||||||
#define PORT_XILINX_PPC405 10 /* No FreeRTOS */
|
#define PORT_XILINX_PPC405 10 /* No FreeRTOS */
|
||||||
#define PORT_XILINX_PPC440 11 /* No FreeRTOS */
|
#define PORT_XILINX_PPC440 11 /* No FreeRTOS */
|
||||||
#define PORT_XILINX_MICROBLAZE 12 /* No Any */
|
#define PORT_XILINX_MICROBLAZE 12 /* No Any */
|
||||||
#define PORT_NXP_LPC210X 13 /* No Any */
|
#define PORT_NXP_LPC210X 13 /* No Any */
|
||||||
|
#define PORT_MICROCHIP_PIC32MZ 14 /* Yes Any */
|
||||||
|
#define PORT_ARM_CORTEX_A9 15 /* No Any */
|
||||||
|
|
||||||
#include "trcConfig.h" // Where SELECTED_PORT is defined
|
#include "trcConfig.h"
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* IRQ_PRIORITY_ORDER
|
* IRQ_PRIORITY_ORDER
|
||||||
|
@ -194,22 +198,34 @@
|
||||||
|
|
||||||
#elif (SELECTED_PORT == PORT_ARM_CortexM)
|
#elif (SELECTED_PORT == PORT_ARM_CortexM)
|
||||||
|
|
||||||
void prvTraceSetIRQMask(uint32_t priMask);
|
|
||||||
uint32_t prvTraceGetIRQMask(void);
|
|
||||||
|
|
||||||
void prvTraceEnableIRQ(void);
|
|
||||||
void prvTraceDisableIRQ(void);
|
|
||||||
|
|
||||||
void prvTraceInitCortexM(void);
|
void prvTraceInitCortexM(void);
|
||||||
|
|
||||||
|
#define REG_DEMCR (*(volatile unsigned int*)0xE000EDFC)
|
||||||
|
#define REG_DWT_CTRL (*(volatile unsigned int*)0xE0001000)
|
||||||
|
#define REG_DWT_CYCCNT (*(volatile unsigned int*)0xE0001004)
|
||||||
|
#define REG_DWT_EXCCNT (*(volatile unsigned int*)0xE000100C)
|
||||||
|
|
||||||
|
/* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */
|
||||||
|
#define DEMCR_TRCENA (1 << 24)
|
||||||
|
|
||||||
|
/* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */
|
||||||
|
#define DWT_CTRL_NOPRFCNT (1 << 24)
|
||||||
|
|
||||||
|
/* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */
|
||||||
|
#define DWT_CTRL_NOCYCCNT (1 << 25)
|
||||||
|
|
||||||
|
/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */
|
||||||
|
#define DWT_CTRL_EXCEVTENA (1 << 18)
|
||||||
|
|
||||||
|
/* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */
|
||||||
|
#define DWT_CTRL_CYCCNTENA (1)
|
||||||
|
|
||||||
#define PORT_SPECIFIC_INIT() prvTraceInitCortexM()
|
#define PORT_SPECIFIC_INIT() prvTraceInitCortexM()
|
||||||
|
|
||||||
extern uint32_t DWT_CYCLES_ADDED;
|
extern uint32_t DWT_CYCLES_ADDED;
|
||||||
#define DWT_CTRL_REG (*((uint32_t*)0xE0001000))
|
|
||||||
#define DWT_CYCLE_COUNTER (*((uint32_t*)0xE0001004))
|
|
||||||
|
|
||||||
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
#define HWTC_COUNT (DWT_CYCLE_COUNTER + DWT_CYCLES_ADDED)
|
#define HWTC_COUNT (REG_DWT_CYCCNT + DWT_CYCLES_ADDED)
|
||||||
#define HWTC_PERIOD 0
|
#define HWTC_PERIOD 0
|
||||||
#define HWTC_DIVISOR 4
|
#define HWTC_DIVISOR 4
|
||||||
|
|
||||||
|
@ -225,15 +241,21 @@
|
||||||
#define HWTC_DIVISOR 1
|
#define HWTC_DIVISOR 1
|
||||||
#define IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
|
#define IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_MICROCHIP_PIC32MX || PORT_MICROCHIP_PIC32MZ)
|
||||||
|
|
||||||
|
#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_Microchip_dsPIC_AND_PIC24)
|
#elif (SELECTED_PORT == PORT_Microchip_dsPIC_AND_PIC24)
|
||||||
|
|
||||||
/* For Microchip PIC24 and dsPIC (16 bit) */
|
/* For Microchip PIC24 and dsPIC (16 bit) */
|
||||||
|
|
||||||
/* Note: The trace library is designed for 32-bit MCUs and is slower than
|
/* Note: The trace library is designed for 32-bit MCUs and is slower than
|
||||||
intended on 16-bit MCUs. Storing an event on a PIC24 takes about 70 usec.
|
intended on 16-bit MCUs. Storing an event on a PIC24 takes about 70 usec.
|
||||||
In comparison, 32-bit MCUs are often 10-20 times faster. If recording overhead
|
In comparison, this is 10-20 times faster on a 32-bit MCU... */
|
||||||
becomes a problem on PIC24, use the filters to exclude less interesting tasks
|
|
||||||
or system calls. */
|
|
||||||
|
|
||||||
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
#define HWTC_COUNT (TMR1)
|
#define HWTC_COUNT (TMR1)
|
||||||
|
@ -297,16 +319,6 @@
|
||||||
#define HWTC_DIVISOR 1
|
#define HWTC_DIVISOR 1
|
||||||
#define IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
|
#define IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
|
||||||
|
|
||||||
#elif (SELECTED_PORT == PORT_MICROCHIP_PIC32)
|
|
||||||
|
|
||||||
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
|
||||||
|
|
||||||
#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)
|
#elif (SELECTED_PORT == PORT_XILINX_PPC405)
|
||||||
|
|
||||||
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
@ -356,6 +368,32 @@
|
||||||
#define HWTC_DIVISOR 16
|
#define HWTC_DIVISOR 16
|
||||||
#define IRQ_PRIORITY_ORDER 0 // lower IRQ priority values are more significant
|
#define IRQ_PRIORITY_ORDER 0 // lower IRQ priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_ARM_CORTEX_A9)
|
||||||
|
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
#define CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00
|
||||||
|
#define CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8
|
||||||
|
|
||||||
|
#define CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(0xF8F00600 + 0))
|
||||||
|
#define CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(0xF8F00600 + 4))
|
||||||
|
#define CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(0xF8F00600 + 8))
|
||||||
|
|
||||||
|
#define CA9_MPCORE_PRIVCTR_PRESCALER (((CA9_MPCORE_PRIVCTR_CONTROL_REG & CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1)
|
||||||
|
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
|
||||||
|
#define HWTC_COUNT CA9_MPCORE_PRIVCTR_COUNTER_REG
|
||||||
|
#define HWTC_PERIOD ((CA9_MPCORE_PRIVCTR_PERIOD_REG * CA9_MPCORE_PRIVCTR_PRESCALER) + 1)
|
||||||
|
|
||||||
|
//NOTE: The private timer ticks with a very high frequency (half the core-clock usually),
|
||||||
|
//but offers the possibility to apply a prescaler. Depending on the prescaler you set the
|
||||||
|
//HWTC_DIVISOR may need to be raised. Refer to the notes at the beginning of this file
|
||||||
|
//for more information.
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower IRQ priority values are more significant
|
||||||
|
|
||||||
#elif (SELECTED_PORT == PORT_APPLICATION_DEFINED)
|
#elif (SELECTED_PORT == PORT_APPLICATION_DEFINED)
|
||||||
|
|
||||||
#if !( defined (HWTC_COUNT_DIRECTION) && defined (HWTC_COUNT) && defined (HWTC_PERIOD) && defined (HWTC_DIVISOR) && defined (IRQ_PRIORITY_ORDER) )
|
#if !( defined (HWTC_COUNT_DIRECTION) && defined (HWTC_COUNT) && defined (HWTC_PERIOD) && defined (HWTC_DIVISOR) && defined (IRQ_PRIORITY_ORDER) )
|
||||||
|
@ -420,14 +458,4 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTracePortGetTimeStamp(uint32_t *puiTimestamp);
|
void vTracePortGetTimeStamp(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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcKernel.h
|
* trcKernel.h
|
||||||
|
@ -82,9 +82,10 @@ void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
|
||||||
/* Internal constants for task state */
|
/* Internal constants for task state */
|
||||||
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
|
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
|
||||||
#define TASK_STATE_INSTANCE_ACTIVE 1
|
#define TASK_STATE_INSTANCE_ACTIVE 1
|
||||||
#define TASK_STATE_INSTANCE_MARKED_FINISHED 2
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcKernelHooks.h
|
* trcKernelHooks.h
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
* compile-time errors.
|
* compile-time errors.
|
||||||
*
|
*
|
||||||
* #ifdef __ICCARM__
|
* #ifdef __ICCARM__
|
||||||
* #include "percepio/Include/trcKernelHooks.h"
|
* #include "trcKernelPort.h"
|
||||||
* #endif
|
* #endif
|
||||||
*
|
*
|
||||||
* Terms of Use
|
* Terms of Use
|
||||||
|
@ -208,3 +208,6 @@ vTraceStoreObjectPropertiesOnCloseEvent(TRACE_GET_TIMER_NUMBER(pxTimer), TRACE_C
|
||||||
vTraceFreeObjectHandle(TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));
|
vTraceFreeObjectHandle(TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(pxTimer));
|
||||||
|
|
||||||
#endif /* TRCKERNELHOOKS_H */
|
#endif /* TRCKERNELHOOKS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcKernelPort.h
|
* trcKernelPort.h
|
||||||
*
|
*
|
||||||
* Kernel-specific functionality for FreeRTOS, used by the recorder library.
|
* Wrapper for kernel-specific port (trcKernelPort<KERNEL>.h)
|
||||||
*
|
*
|
||||||
* Terms of Use
|
* Terms of Use
|
||||||
* This software is copyright Percepio AB. The recorder library is free for
|
* This software is copyright Percepio AB. The recorder library is free for
|
||||||
|
@ -31,947 +31,13 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* Change the included file below, if using the recorder with other kernels */
|
||||||
|
|
||||||
#ifndef TRCKERNELPORT_H_
|
#include "trcKernelPortFreeRTOS.h"
|
||||||
#define TRCKERNELPORT_H_
|
/* #include "trcKernelPort<OTHERKERNEL>.h" */
|
||||||
|
|
||||||
#include "FreeRTOS.h" // Defines configUSE_TRACE_FACILITY
|
|
||||||
#include "trcHardwarePort.h"
|
|
||||||
|
|
||||||
extern int uiInEventGroupSetBitsFromISR;
|
|
||||||
|
|
||||||
#define USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY
|
|
||||||
|
|
||||||
#if (USE_TRACEALYZER_RECORDER == 1)
|
|
||||||
|
|
||||||
/* Defines that must be set for the recorder to work properly */
|
|
||||||
#define TRACE_KERNEL_VERSION 0x1AA1
|
|
||||||
#define TRACE_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */
|
|
||||||
#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */
|
|
||||||
|
|
||||||
#if ((SELECTED_PORT == PORT_ARM_CortexM) && (USE_PRIMASK_CS == 1))
|
|
||||||
|
|
||||||
#define TRACE_SR_ALLOC_CRITICAL_SECTION() int __irq_status;
|
|
||||||
|
|
||||||
#define TRACE_ENTER_CRITICAL_SECTION() { __irq_status = prvTraceGetIRQMask(); prvTraceDisableIRQ(); }
|
|
||||||
|
|
||||||
#define TRACE_EXIT_CRITICAL_SECTION() { prvTraceSetIRQMask(__irq_status); }
|
|
||||||
|
|
||||||
#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN
|
|
||||||
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL()
|
|
||||||
#define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL()
|
|
||||||
|
|
||||||
#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++;
|
|
||||||
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* KERNEL SPECIFIC OBJECT CONFIGURATION */
|
|
||||||
/************************************************************************/
|
|
||||||
#define TRACE_NCLASSES 7
|
|
||||||
#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)
|
|
||||||
#define TRACE_CLASS_TIMER ((traceObjectClass)5)
|
|
||||||
#define TRACE_CLASS_EVENTGROUP ((traceObjectClass)6)
|
|
||||||
|
|
||||||
#define TRACE_KERNEL_OBJECT_COUNT (NQueue + NSemaphore + NMutex + NTask + NISR + NTimer + NEventGroup)
|
|
||||||
|
|
||||||
/* 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: legacy, not used
|
|
||||||
Byte 3: legacy, not used */
|
|
||||||
#define PropertyTableSizeTask (NameLenTask + 4)
|
|
||||||
|
|
||||||
/* ISR properties: Byte 0: priority
|
|
||||||
Byte 1: state (if already active) */
|
|
||||||
#define PropertyTableSizeISR (NameLenISR + 2)
|
|
||||||
|
|
||||||
/* NTimer properties: Byte 0: state (unused for now) */
|
|
||||||
#define PropertyTableSizeTimer (NameLenTimer + 1)
|
|
||||||
|
|
||||||
/* NEventGroup properties: Byte 0-3: state (unused for now)*/
|
|
||||||
#define PropertyTableSizeEventGroup (NameLenEventGroup + 4)
|
|
||||||
|
|
||||||
|
|
||||||
/* 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 StartIndexTimer StartIndexISR + NISR * PropertyTableSizeISR
|
|
||||||
#define StartIndexEventGroup StartIndexTimer + NTimer * PropertyTableSizeTimer
|
|
||||||
|
|
||||||
/* Number of bytes used by the object table */
|
|
||||||
#define TRACE_OBJECT_TABLE_SIZE StartIndexEventGroup + NEventGroup * PropertyTableSizeEventGroup
|
|
||||||
|
|
||||||
/* Includes */
|
|
||||||
#include "trcConfig.h" /* Must be first, even before trcTypes.h */
|
|
||||||
#include "trcHardwarePort.h"
|
|
||||||
#include "trcTypes.h"
|
|
||||||
#include "trcKernelHooks.h"
|
|
||||||
#include "trcBase.h"
|
|
||||||
#include "trcKernel.h"
|
|
||||||
#include "trcUser.h"
|
|
||||||
|
|
||||||
#if (INCLUDE_NEW_TIME_EVENTS == 1 && configUSE_TICKLESS_IDLE != 0)
|
|
||||||
#error "NewTime events can not be used in combination with tickless idle!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialization of the object property table */
|
|
||||||
void vTraceInitObjectPropertyTable(void);
|
|
||||||
|
|
||||||
/* Initialization of the handle mechanism, see e.g, xTraceGetObjectHandle */
|
|
||||||
void vTraceInitObjectHandleStack(void);
|
|
||||||
|
|
||||||
/* Returns the "Not enough handles" error message for the specified object class */
|
|
||||||
const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass);
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* 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_DIV
|
|
||||||
*
|
|
||||||
* Miscellaneous events.
|
|
||||||
******************************************************************************/
|
|
||||||
#define EVENTGROUP_DIV (NULL_EVENT + 1) /*0x01*/
|
|
||||||
#define DIV_XPS (EVENTGROUP_DIV + 0) /*0x01*/
|
|
||||||
#define DIV_TASK_READY (EVENTGROUP_DIV + 1) /*0x02*/
|
|
||||||
#define DIV_NEW_TIME (EVENTGROUP_DIV + 2) /*0x03*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* 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_DIV + 3) /*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), containing 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 preceding 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_OBJ_SUCCESS (EVENTGROUP_OBJCLOSE_PROP + 8) /*0x18*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* EVENTGROUP_SEND
|
|
||||||
*
|
|
||||||
* The events in this group are used to log Send/Give 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_SEND_SUCCESS (EVENTGROUP_CREATE_OBJ_SUCCESS + 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_SUCCESS (EVENTGROUP_SEND_SUCCESS + 8) /*0x28*/
|
|
||||||
|
|
||||||
/* Send/Give operations, from ISR */
|
|
||||||
#define EVENTGROUP_SEND_FROM_ISR_SUCCESS (EVENTGROUP_RECEIVE_SUCCESS + 8) /*0x30*/
|
|
||||||
|
|
||||||
/* Receive/Take operations, from ISR */
|
|
||||||
#define EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS (EVENTGROUP_SEND_FROM_ISR_SUCCESS + 8) /*0x38*/
|
|
||||||
|
|
||||||
/* "Failed" event type versions of above (timeout, failed allocation, etc) */
|
|
||||||
#define EVENTGROUP_KSE_FAILED (EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + 8) /*0x40*/
|
|
||||||
|
|
||||||
/* Failed create calls - memory allocation failed */
|
|
||||||
#define EVENTGROUP_CREATE_OBJ_FAILED (EVENTGROUP_KSE_FAILED) /*0x40*/
|
|
||||||
|
|
||||||
/* Failed send/give - timeout! */
|
|
||||||
#define EVENTGROUP_SEND_FAILED (EVENTGROUP_CREATE_OBJ_FAILED + 8) /*0x48*/
|
|
||||||
|
|
||||||
/* Failed receive/take - timeout! */
|
|
||||||
#define EVENTGROUP_RECEIVE_FAILED (EVENTGROUP_SEND_FAILED + 8) /*0x50*/
|
|
||||||
|
|
||||||
/* Failed non-blocking send/give - queue full */
|
|
||||||
#define EVENTGROUP_SEND_FROM_ISR_FAILED (EVENTGROUP_RECEIVE_FAILED + 8) /*0x58*/
|
|
||||||
|
|
||||||
/* Failed non-blocking receive/take - queue empty */
|
|
||||||
#define EVENTGROUP_RECEIVE_FROM_ISR_FAILED \
|
|
||||||
(EVENTGROUP_SEND_FROM_ISR_FAILED + 8) /*0x60*/
|
|
||||||
|
|
||||||
/* Events when blocking on receive/take */
|
|
||||||
#define EVENTGROUP_RECEIVE_BLOCK \
|
|
||||||
(EVENTGROUP_RECEIVE_FROM_ISR_FAILED + 8) /*0x68*/
|
|
||||||
|
|
||||||
/* Events when blocking on send/give */
|
|
||||||
#define EVENTGROUP_SEND_BLOCK (EVENTGROUP_RECEIVE_BLOCK + 8) /*0x70*/
|
|
||||||
|
|
||||||
/* Events on queue peek (receive) */
|
|
||||||
#define EVENTGROUP_PEEK_SUCCESS (EVENTGROUP_SEND_BLOCK + 8) /*0x78*/
|
|
||||||
|
|
||||||
/* Events on object delete (vTaskDelete or vQueueDelete) */
|
|
||||||
#define EVENTGROUP_DELETE_OBJ_SUCCESS (EVENTGROUP_PEEK_SUCCESS + 8) /*0x80*/
|
|
||||||
|
|
||||||
/* Other events - object class is implied: TASK */
|
|
||||||
#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_SUCCESS + 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*/
|
|
||||||
|
|
||||||
#define EVENTGROUP_MISC_PLACEHOLDER (EVENTGROUP_OTHERS + 8) /*0x90*/
|
|
||||||
#define PEND_FUNC_CALL (EVENTGROUP_MISC_PLACEHOLDER+0) /*0x90*/
|
|
||||||
#define PEND_FUNC_CALL_FROM_ISR (EVENTGROUP_MISC_PLACEHOLDER+1) /*0x91*/
|
|
||||||
#define PEND_FUNC_CALL_FAILED (EVENTGROUP_MISC_PLACEHOLDER+2) /*0x92*/
|
|
||||||
#define PEND_FUNC_CALL_FROM_ISR_FAILED (EVENTGROUP_MISC_PLACEHOLDER+3) /*0x93*/
|
|
||||||
#define MEM_MALLOC_SIZE (EVENTGROUP_MISC_PLACEHOLDER+4) /*0x94*/
|
|
||||||
#define MEM_MALLOC_ADDR (EVENTGROUP_MISC_PLACEHOLDER+5) /*0x95*/
|
|
||||||
#define MEM_FREE_SIZE (EVENTGROUP_MISC_PLACEHOLDER+6) /*0x96*/
|
|
||||||
#define MEM_FREE_ADDR (EVENTGROUP_MISC_PLACEHOLDER+7) /*0x97*/
|
|
||||||
|
|
||||||
/* User events */
|
|
||||||
#define EVENTGROUP_USEREVENT (EVENTGROUP_MISC_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 immediately
|
|
||||||
* 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*/
|
|
||||||
|
|
||||||
#define LOW_POWER_BEGIN (EVENTGROUP_SYS + 4) /*0xAC*/
|
|
||||||
#define LOW_POWER_END (EVENTGROUP_SYS + 5) /*0xAD*/
|
|
||||||
|
|
||||||
#define XID (EVENTGROUP_SYS + 6) /*0xAE*/
|
|
||||||
|
|
||||||
#define XTS16L (EVENTGROUP_SYS + 7) /*0xAF*/
|
|
||||||
|
|
||||||
#define EVENTGROUP_TIMER (EVENTGROUP_SYS + 8) /*0xB0*/
|
|
||||||
|
|
||||||
#define TIMER_CREATE (EVENTGROUP_TIMER + 0) /*0xB0*/
|
|
||||||
#define TIMER_START (EVENTGROUP_TIMER + 1) /*0xB0*/
|
|
||||||
#define TIMER_RESET (EVENTGROUP_TIMER + 2) /*0xB1*/
|
|
||||||
#define TIMER_STOP (EVENTGROUP_TIMER + 3) /*0xB2*/
|
|
||||||
#define TIMER_CHANGE_PERIOD (EVENTGROUP_TIMER + 4) /*0xB3*/
|
|
||||||
#define TIMER_DELETE (EVENTGROUP_TIMER + 5) /*0xB4*/
|
|
||||||
#define TIMER_START_FROM_ISR (EVENTGROUP_TIMER + 6) /*0xB6*/
|
|
||||||
#define TIMER_RESET_FROM_ISR (EVENTGROUP_TIMER + 7) /*0xB7*/
|
|
||||||
#define TIMER_STOP_FROM_ISR (EVENTGROUP_TIMER + 8) /*0xB8*/
|
|
||||||
|
|
||||||
#define TIMER_CREATE_FAILED (EVENTGROUP_TIMER + 9) /*0xB9*/
|
|
||||||
#define TIMER_START_FAILED (EVENTGROUP_TIMER + 10) /*0xBA*/
|
|
||||||
#define TIMER_RESET_FAILED (EVENTGROUP_TIMER + 11) /*0xBB*/
|
|
||||||
#define TIMER_STOP_FAILED (EVENTGROUP_TIMER + 12) /*0xBC*/
|
|
||||||
#define TIMER_CHANGE_PERIOD_FAILED (EVENTGROUP_TIMER + 13) /*0xBD*/
|
|
||||||
#define TIMER_DELETE_FAILED (EVENTGROUP_TIMER + 14) /*0xBE*/
|
|
||||||
#define TIMER_START_FROM_ISR_FAILED (EVENTGROUP_TIMER + 15) /*0xBF*/
|
|
||||||
#define TIMER_RESET_FROM_ISR_FAILED (EVENTGROUP_TIMER + 16) /*0xC0*/
|
|
||||||
#define TIMER_STOP_FROM_ISR_FAILED (EVENTGROUP_TIMER + 17) /*0xC1*/
|
|
||||||
|
|
||||||
#define EVENTGROUP_EG (EVENTGROUP_TIMER + 18) /*0xC2*/
|
|
||||||
#define EVENT_GROUP_CREATE (EVENTGROUP_EG + 0) /*0xC2*/
|
|
||||||
#define EVENT_GROUP_CREATE_FAILED (EVENTGROUP_EG + 1) /*0xC3*/
|
|
||||||
#define EVENT_GROUP_SYNC_BLOCK (EVENTGROUP_EG + 2) /*0xC4*/
|
|
||||||
#define EVENT_GROUP_SYNC_END (EVENTGROUP_EG + 3) /*0xC5*/
|
|
||||||
#define EVENT_GROUP_WAIT_BITS_BLOCK (EVENTGROUP_EG + 4) /*0xC6*/
|
|
||||||
#define EVENT_GROUP_WAIT_BITS_END (EVENTGROUP_EG + 5) /*0xC7*/
|
|
||||||
#define EVENT_GROUP_CLEAR_BITS (EVENTGROUP_EG + 6) /*0xC8*/
|
|
||||||
#define EVENT_GROUP_CLEAR_BITS_FROM_ISR (EVENTGROUP_EG + 7) /*0xC9*/
|
|
||||||
#define EVENT_GROUP_SET_BITS (EVENTGROUP_EG + 8) /*0xCA*/
|
|
||||||
#define EVENT_GROUP_DELETE (EVENTGROUP_EG + 9) /*0xCB*/
|
|
||||||
#define EVENT_GROUP_SYNC_END_FAILED (EVENTGROUP_EG + 10) /*0xCC*/
|
|
||||||
#define EVENT_GROUP_WAIT_BITS_END_FAILED (EVENTGROUP_EG + 11) /*0xCD*/
|
|
||||||
#define EVENT_GROUP_SET_BITS_FROM_ISR (EVENTGROUP_EG + 12) /*0xCE*/
|
|
||||||
#define EVENT_GROUP_SET_BITS_FROM_ISR_FAILED (EVENTGROUP_EG + 13) /*0xCF*/
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* KERNEL SPECIFIC DATA AND FUNCTIONS NEEDED TO PROVIDE THE */
|
|
||||||
/* FUNCTIONALITY REQUESTED BY THE TRACE RECORDER */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
extern traceObjectClass TraceObjectClassTable[5];
|
|
||||||
|
|
||||||
/* These functions are implemented in the .c file since certain header files must not be included in this one */
|
|
||||||
objectHandleType prvTraceGetObjectNumber(void* handle);
|
|
||||||
unsigned char prvTraceGetObjectType(void* handle);
|
|
||||||
objectHandleType prvTraceGetTaskNumber(void* handle);
|
|
||||||
unsigned char prvTraceIsSchedulerActive(void);
|
|
||||||
unsigned char prvTraceIsSchedulerSuspended(void);
|
|
||||||
unsigned char prvTraceIsSchedulerStarted(void);
|
|
||||||
void* prvTraceGetCurrentTaskHandle(void);
|
|
||||||
|
|
||||||
#if (configUSE_TIMERS == 1)
|
|
||||||
#undef INCLUDE_xTimerGetTimerDaemonTaskHandle
|
|
||||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* KERNEL SPECIFIC MACROS USED BY THE TRACE RECORDER */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
#define TRACE_MALLOC(size) pvPortMalloc(size)
|
|
||||||
#define TRACE_IS_SCHEDULER_ACTIVE() prvTraceIsSchedulerActive()
|
|
||||||
#define TRACE_IS_SCHEDULER_STARTED() prvTraceIsSchedulerStarted()
|
|
||||||
#define TRACE_IS_SCHEDULER_SUSPENDED() prvTraceIsSchedulerSuspended()
|
|
||||||
#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle()
|
|
||||||
|
|
||||||
#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority)
|
|
||||||
#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName)
|
|
||||||
#define TRACE_GET_TASK_NUMBER(pxTCB) (prvTraceGetTaskNumber(pxTCB))
|
|
||||||
#define TRACE_SET_TASK_NUMBER(pxTCB) pxTCB->uxTaskNumber = xTraceGetObjectHandle(TRACE_CLASS_TASK);
|
|
||||||
|
|
||||||
#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TraceObjectClassTable[kernelClass]
|
|
||||||
#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_CLASS_TRACE_CLASS(CLASS, prvTraceGetObjectType(pxObject))
|
|
||||||
|
|
||||||
#define TRACE_GET_TIMER_NUMBER(tmr) ( ( objectHandleType ) ((Timer_t*)tmr)->uxTimerNumber )
|
|
||||||
#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = xTraceGetObjectHandle(TRACE_CLASS_TIMER);
|
|
||||||
#define TRACE_GET_TIMER_NAME(pxTimer) pxTimer->pcTimerName
|
|
||||||
#define TRACE_GET_TIMER_PERIOD(pxTimer) pxTimer->xTimerPeriodInTicks
|
|
||||||
|
|
||||||
#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( objectHandleType ) uxEventGroupGetNumber(eg) )
|
|
||||||
#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = xTraceGetObjectHandle(TRACE_CLASS_EVENTGROUP);
|
|
||||||
|
|
||||||
#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) (prvTraceGetObjectNumber(pxObject))
|
|
||||||
#define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) pxObject->uxQueueNumber = xTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject));
|
|
||||||
|
|
||||||
#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass))
|
|
||||||
#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject))
|
|
||||||
#define TRACE_GET_TASK_EVENT_CODE(SERVICE, RESULT, CLASS, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK)
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* KERNEL SPECIFIC WRAPPERS THAT SHOULD BE CALLED BY THE KERNEL */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
#if (configUSE_TICKLESS_IDLE != 0)
|
|
||||||
|
|
||||||
#undef traceLOW_POWER_IDLE_BEGIN
|
|
||||||
#define traceLOW_POWER_IDLE_BEGIN() \
|
|
||||||
{ \
|
|
||||||
extern uint32_t trace_disable_timestamp; \
|
|
||||||
vTraceStoreLowPower(0); \
|
|
||||||
trace_disable_timestamp = 1; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef traceLOW_POWER_IDLE_END
|
|
||||||
#define traceLOW_POWER_IDLE_END() \
|
|
||||||
{ \
|
|
||||||
extern uint32_t trace_disable_timestamp; \
|
|
||||||
trace_disable_timestamp = 0; \
|
|
||||||
vTraceStoreLowPower(1); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* A macro that will update the tick count when returning from tickless idle */
|
|
||||||
#undef traceINCREASE_TICK_COUNT
|
|
||||||
/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/
|
|
||||||
#define traceINCREASE_TICK_COUNT( xCount ) { DWT_CYCLES_ADDED += (xCount * (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ)); }
|
|
||||||
|
|
||||||
/* Called for each task that becomes ready */
|
|
||||||
#undef traceMOVED_TASK_TO_READY_STATE
|
|
||||||
#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \
|
|
||||||
trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB);
|
|
||||||
|
|
||||||
/* 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 == ( UBaseType_t ) pdTRUE || uxPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \
|
|
||||||
if (uxSchedulerSuspended == ( UBaseType_t ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); }
|
|
||||||
|
|
||||||
/* Called on each task-switch */
|
|
||||||
#undef traceTASK_SWITCHED_IN
|
|
||||||
#define traceTASK_SWITCHED_IN() \
|
|
||||||
trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK());
|
|
||||||
|
|
||||||
/* Called on vTaskSuspend */
|
|
||||||
#undef traceTASK_SUSPEND
|
|
||||||
#define traceTASK_SUSPEND( pxTaskToSuspend ) \
|
|
||||||
trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend);
|
|
||||||
|
|
||||||
/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */
|
|
||||||
#undef traceTASK_DELAY
|
|
||||||
#define traceTASK_DELAY() \
|
|
||||||
trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY, pxCurrentTCB, xTicksToDelay); \
|
|
||||||
trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
|
|
||||||
|
|
||||||
/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */
|
|
||||||
#undef traceTASK_DELAY_UNTIL
|
|
||||||
#define traceTASK_DELAY_UNTIL() \
|
|
||||||
trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \
|
|
||||||
trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
|
|
||||||
|
|
||||||
#if (INCLUDE_OBJECT_DELETE == 1)
|
|
||||||
/* Called on vTaskDelete */
|
|
||||||
#undef traceTASK_DELETE
|
|
||||||
#define traceTASK_DELETE( pxTaskToDelete ) \
|
|
||||||
{ TRACE_SR_ALLOC_CRITICAL_SECTION(); \
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION(); \
|
|
||||||
trcKERNEL_HOOKS_TASK_DELETE(DELETE_OBJ, pxTaskToDelete); \
|
|
||||||
TRACE_EXIT_CRITICAL_SECTION(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (INCLUDE_OBJECT_DELETE == 1)
|
|
||||||
/* Called on vQueueDelete */
|
|
||||||
#undef traceQUEUE_DELETE
|
|
||||||
#define traceQUEUE_DELETE( pxQueue ) \
|
|
||||||
{ TRACE_SR_ALLOC_CRITICAL_SECTION(); \
|
|
||||||
TRACE_ENTER_CRITICAL_SECTION(); \
|
|
||||||
trcKERNEL_HOOKS_OBJECT_DELETE(DELETE_OBJ, UNUSED, pxQueue); \
|
|
||||||
TRACE_EXIT_CRITICAL_SECTION(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Called on vTaskCreate */
|
|
||||||
#undef traceTASK_CREATE
|
|
||||||
#define traceTASK_CREATE(pxNewTCB) \
|
|
||||||
if (pxNewTCB != NULL) \
|
|
||||||
{ \
|
|
||||||
trcKERNEL_HOOKS_TASK_CREATE(CREATE_OBJ, UNUSED, pxNewTCB); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */
|
|
||||||
#undef traceTASK_CREATE_FAILED
|
|
||||||
#define traceTASK_CREATE_FAILED() \
|
|
||||||
trcKERNEL_HOOKS_TASK_CREATE_FAILED(CREATE_OBJ, UNUSED);
|
|
||||||
|
|
||||||
/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */
|
|
||||||
#undef traceQUEUE_CREATE
|
|
||||||
#define traceQUEUE_CREATE( pxNewQueue )\
|
|
||||||
trcKERNEL_HOOKS_OBJECT_CREATE(CREATE_OBJ, UNUSED, pxNewQueue);
|
|
||||||
|
|
||||||
/* Called in xQueueCreate, if the queue creation fails */
|
|
||||||
#undef traceQUEUE_CREATE_FAILED
|
|
||||||
#define traceQUEUE_CREATE_FAILED( queueType ) \
|
|
||||||
trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(CREATE_OBJ, UNUSED, queueType);
|
|
||||||
|
|
||||||
/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */
|
|
||||||
#undef traceCREATE_MUTEX
|
|
||||||
#define traceCREATE_MUTEX( pxNewQueue ) \
|
|
||||||
trcKERNEL_HOOKS_OBJECT_CREATE(CREATE_OBJ, UNUSED, pxNewQueue);
|
|
||||||
|
|
||||||
/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */
|
|
||||||
#undef traceCREATE_MUTEX_FAILED
|
|
||||||
#define traceCREATE_MUTEX_FAILED() \
|
|
||||||
trcKERNEL_HOOKS_OBJECT_CREATE_FAILED(CREATE_OBJ, UNUSED, queueQUEUE_TYPE_MUTEX);
|
|
||||||
|
|
||||||
/* Called when the Mutex can not be given, since not holder */
|
|
||||||
#undef traceGIVE_MUTEX_RECURSIVE_FAILED
|
|
||||||
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, FAILED, UNUSED, pxMutex);
|
|
||||||
|
|
||||||
/* Called when a message is sent to a queue */ /* CS IS NEW ! */
|
|
||||||
#undef traceQUEUE_SEND
|
|
||||||
#define traceQUEUE_SEND( pxQueue ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, SUCCESS, UNUSED, pxQueue); \
|
|
||||||
trcKERNEL_HOOKS_SET_OBJECT_STATE(UNUSED, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (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 ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, FAILED, UNUSED, pxQueue);
|
|
||||||
|
|
||||||
/* 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 ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(SEND, BLOCK, UNUSED, pxQueue);
|
|
||||||
|
|
||||||
/* Called when a message is received from a queue */
|
|
||||||
#undef traceQUEUE_RECEIVE
|
|
||||||
#define traceQUEUE_RECEIVE( pxQueue ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE, SUCCESS, UNUSED, pxQueue); \
|
|
||||||
trcKERNEL_HOOKS_SET_OBJECT_STATE(UNUSED, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, pxQueue) == TRACE_CLASS_MUTEX ? TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1));
|
|
||||||
|
|
||||||
/* Called when a receive operation on a queue fails (timeout) */
|
|
||||||
#undef traceQUEUE_RECEIVE_FAILED
|
|
||||||
#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE, FAILED, UNUSED, pxQueue);
|
|
||||||
|
|
||||||
/* 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 ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE, BLOCK, UNUSED, pxQueue); \
|
|
||||||
if (TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, pxQueue) != TRACE_CLASS_MUTEX) \
|
|
||||||
{trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();}
|
|
||||||
|
|
||||||
/* Called on xQueuePeek */
|
|
||||||
#undef traceQUEUE_PEEK
|
|
||||||
#define traceQUEUE_PEEK( pxQueue ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(PEEK, SUCCESS, UNUSED, pxQueue);
|
|
||||||
|
|
||||||
/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */
|
|
||||||
#undef traceQUEUE_SEND_FROM_ISR
|
|
||||||
#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(SEND_FROM_ISR, SUCCESS, UNUSED, pxQueue); \
|
|
||||||
trcKERNEL_HOOKS_SET_OBJECT_STATE(UNUSED, pxQueue, (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 ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(SEND_FROM_ISR, FAILED, UNUSED, pxQueue);
|
|
||||||
|
|
||||||
/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */
|
|
||||||
#undef traceQUEUE_RECEIVE_FROM_ISR
|
|
||||||
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE_FROM_ISR, SUCCESS, UNUSED, pxQueue); \
|
|
||||||
trcKERNEL_HOOKS_SET_OBJECT_STATE(UNUSED, pxQueue, (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 ) \
|
|
||||||
trcKERNEL_HOOKS_KERNEL_SERVICE(RECEIVE_FROM_ISR, FAILED, UNUSED, pxQueue);
|
|
||||||
|
|
||||||
/* Called in vTaskPrioritySet */
|
|
||||||
#undef traceTASK_PRIORITY_SET
|
|
||||||
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \
|
|
||||||
trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_SET, pxTask, uxNewPriority);
|
|
||||||
|
|
||||||
/* Called in vTaskPriorityInherit, which is called by Mutex operations */
|
|
||||||
#undef traceTASK_PRIORITY_INHERIT
|
|
||||||
#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \
|
|
||||||
trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_INHERIT, pxTask, uxNewPriority);
|
|
||||||
|
|
||||||
/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */
|
|
||||||
#undef traceTASK_PRIORITY_DISINHERIT
|
|
||||||
#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \
|
|
||||||
trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_DISINHERIT, pxTask, uxNewPriority);
|
|
||||||
|
|
||||||
/* Called in vTaskResume */
|
|
||||||
#undef traceTASK_RESUME
|
|
||||||
#define traceTASK_RESUME( pxTaskToResume ) \
|
|
||||||
trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME, pxTaskToResume);
|
|
||||||
|
|
||||||
/* Called in vTaskResumeFromISR */
|
|
||||||
#undef traceTASK_RESUME_FROM_ISR
|
|
||||||
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \
|
|
||||||
trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME_FROM_ISR, pxTaskToResume);
|
|
||||||
|
|
||||||
|
|
||||||
/* Called in timer.c - xTimerCreate */
|
|
||||||
#undef traceTIMER_CREATE
|
|
||||||
#define traceTIMER_CREATE(tmr) \
|
|
||||||
trcKERNEL_HOOKS_TIMER_CREATE(TIMER_CREATE, tmr);
|
|
||||||
|
|
||||||
#undef traceTIMER_CREATE_FAILED
|
|
||||||
#define traceTIMER_CREATE_FAILED() \
|
|
||||||
trcKERNEL_HOOKS_TIMER_EVENT(TIMER_CREATE_FAILED, 0);
|
|
||||||
|
|
||||||
/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */
|
|
||||||
#undef traceTIMER_COMMAND_SEND
|
|
||||||
#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \
|
|
||||||
if (xCommandID > tmrCOMMAND_START_DONT_TRACE){\
|
|
||||||
if (xCommandID == tmrCOMMAND_CHANGE_PERIOD) vTraceStoreKernelCallWithParam((xReturn == pdPASS) ? TIMER_CHANGE_PERIOD : TIMER_CHANGE_PERIOD_FAILED, TRACE_CLASS_TIMER, TRACE_GET_TIMER_NUMBER(tmr), xOptionalValue);\
|
|
||||||
else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)){ trcKERNEL_HOOKS_TIMER_DELETE(TIMER_DELETE, tmr); } \
|
|
||||||
else {trcKERNEL_HOOKS_TIMER_EVENT(EVENTGROUP_TIMER + xCommandID + ((xReturn == pdPASS)?0:(TIMER_CREATE_FAILED - TIMER_CREATE)), tmr); }\
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef tracePEND_FUNC_CALL
|
|
||||||
#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \
|
|
||||||
if (ret == pdPASS) \
|
|
||||||
vTraceStoreKernelCall(PEND_FUNC_CALL, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTimerGetTimerDaemonTaskHandle()) ); \
|
|
||||||
else \
|
|
||||||
vTraceStoreKernelCall(PEND_FUNC_CALL_FAILED, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTimerGetTimerDaemonTaskHandle()) );
|
|
||||||
|
|
||||||
#undef tracePEND_FUNC_CALL_FROM_ISR
|
|
||||||
#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \
|
|
||||||
if (! uiInEventGroupSetBitsFromISR) vTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, uxTaskGetTaskNumber(xTimerGetTimerDaemonTaskHandle()) ); \
|
|
||||||
uiInEventGroupSetBitsFromISR = 0;
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_CREATE
|
|
||||||
#define traceEVENT_GROUP_CREATE(eg) \
|
|
||||||
TRACE_SET_EVENTGROUP_NUMBER(eg); \
|
|
||||||
vTraceStoreKernelCall(EVENT_GROUP_CREATE, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg));
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_DELETE
|
|
||||||
#define traceEVENT_GROUP_DELETE(eg) \
|
|
||||||
vTraceStoreKernelCall(EVENT_GROUP_DELETE, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg)); \
|
|
||||||
vTraceStoreObjectNameOnCloseEvent(TRACE_GET_EVENTGROUP_NUMBER(eg), TRACE_CLASS_EVENTGROUP); \
|
|
||||||
vTraceStoreObjectPropertiesOnCloseEvent(TRACE_GET_EVENTGROUP_NUMBER(eg), TRACE_CLASS_EVENTGROUP); \
|
|
||||||
vTraceFreeObjectHandle(TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg));
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_CREATE_FAILED
|
|
||||||
#define traceEVENT_GROUP_CREATE_FAILED() \
|
|
||||||
vTraceStoreKernelCall(EVENT_GROUP_CREATE_FAILED, TRACE_CLASS_EVENTGROUP, 0);
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_SYNC_BLOCK
|
|
||||||
#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \
|
|
||||||
vTraceStoreKernelCallWithParam(EVENT_GROUP_SYNC_BLOCK, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor);
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_SYNC_END
|
|
||||||
#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \
|
|
||||||
if (wasTimeout){ vTraceStoreKernelCallWithParam(EVENT_GROUP_SYNC_END_FAILED, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor);} \
|
|
||||||
else{ vTraceStoreKernelCallWithParam(EVENT_GROUP_SYNC_END, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); }
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_WAIT_BITS_BLOCK
|
|
||||||
#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \
|
|
||||||
vTraceStoreKernelCallWithParam(EVENT_GROUP_WAIT_BITS_BLOCK, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); \
|
|
||||||
trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED();
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_WAIT_BITS_END
|
|
||||||
#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \
|
|
||||||
if (wasTimeout){ vTraceStoreKernelCallWithParam(EVENT_GROUP_WAIT_BITS_END_FAILED, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); } \
|
|
||||||
else{ vTraceStoreKernelCallWithParam(EVENT_GROUP_WAIT_BITS_END, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToWaitFor); }
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_CLEAR_BITS
|
|
||||||
#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \
|
|
||||||
if (bitsToClear) vTraceStoreKernelCallWithParam(EVENT_GROUP_CLEAR_BITS, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToClear);
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
|
|
||||||
#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \
|
|
||||||
if (bitsToClear) vTraceStoreKernelCallWithParam(EVENT_GROUP_CLEAR_BITS_FROM_ISR, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToClear);
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_SET_BITS
|
|
||||||
#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \
|
|
||||||
vTraceStoreKernelCallWithParam(EVENT_GROUP_SET_BITS, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToSet);
|
|
||||||
|
|
||||||
#undef traceEVENT_GROUP_SET_BITS_FROM_ISR
|
|
||||||
#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \
|
|
||||||
vTraceStoreKernelCallWithParam(EVENT_GROUP_SET_BITS_FROM_ISR, TRACE_CLASS_EVENTGROUP, TRACE_GET_EVENTGROUP_NUMBER(eg), bitsToSet); \
|
|
||||||
uiInEventGroupSetBitsFromISR = 1;
|
|
||||||
|
|
||||||
#if (INCLUDE_MEMMANG_EVENTS == 1)
|
|
||||||
|
|
||||||
extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, uint32_t size);
|
|
||||||
|
|
||||||
#undef traceMALLOC
|
|
||||||
#define traceMALLOC( pvAddress, uiSize ) {vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, uiSize); TRACE_INCR_HEAP_USAGE(uiSize);}
|
|
||||||
|
|
||||||
|
|
||||||
#undef traceFREE
|
|
||||||
#define traceFREE( pvAddress, uiSize ) {vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, uiSize); TRACE_DECR_HEAP_USAGE(uiSize);}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* KERNEL SPECIFIC MACROS TO EXCLUDE OR INCLUDE THINGS IN TRACE */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
/* Returns the exclude state of the object */
|
|
||||||
uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType handle);
|
|
||||||
|
|
||||||
#define TRACE_SET_QUEUE_FLAG_ISEXCLUDED(queueIndex) TRACE_SET_FLAG_ISEXCLUDED(excludedObjects, queueIndex)
|
|
||||||
#define TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(queueIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedObjects, queueIndex)
|
|
||||||
#define TRACE_GET_QUEUE_FLAG_ISEXCLUDED(queueIndex) TRACE_GET_FLAG_ISEXCLUDED(excludedObjects, queueIndex)
|
|
||||||
|
|
||||||
#define TRACE_SET_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreIndex) TRACE_SET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+semaphoreIndex)
|
|
||||||
#define TRACE_CLEAR_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+semaphoreIndex)
|
|
||||||
#define TRACE_GET_SEMAPHORE_FLAG_ISEXCLUDED(semaphoreIndex) TRACE_GET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+semaphoreIndex)
|
|
||||||
|
|
||||||
#define TRACE_SET_MUTEX_FLAG_ISEXCLUDED(mutexIndex) TRACE_SET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+mutexIndex)
|
|
||||||
#define TRACE_CLEAR_MUTEX_FLAG_ISEXCLUDED(mutexIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+mutexIndex)
|
|
||||||
#define TRACE_GET_MUTEX_FLAG_ISEXCLUDED(mutexIndex) TRACE_GET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+mutexIndex)
|
|
||||||
|
|
||||||
#define TRACE_SET_TASK_FLAG_ISEXCLUDED(taskIndex) TRACE_SET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+taskIndex)
|
|
||||||
#define TRACE_CLEAR_TASK_FLAG_ISEXCLUDED(taskIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+taskIndex)
|
|
||||||
#define TRACE_GET_TASK_FLAG_ISEXCLUDED(taskIndex) TRACE_GET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+taskIndex)
|
|
||||||
|
|
||||||
#define TRACE_SET_TIMER_FLAG_ISEXCLUDED(timerIndex) TRACE_SET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+NTask+1+timerIndex)
|
|
||||||
#define TRACE_CLEAR_TIMER_FLAG_ISEXCLUDED(timerIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+NTask+1+timerIndex)
|
|
||||||
#define TRACE_GET_TIMER_FLAG_ISEXCLUDED(timerIndex) TRACE_GET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+NTask+1+timerIndex)
|
|
||||||
|
|
||||||
#define TRACE_SET_EVENTGROUP_FLAG_ISEXCLUDED(egIndex) TRACE_SET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+NTask+1+NTimer+1+egIndex)
|
|
||||||
#define TRACE_CLEAR_EVENTGROUP_FLAG_ISEXCLUDED(egIndex) TRACE_CLEAR_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+NTask+1+NTimer+1+egIndex)
|
|
||||||
#define TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(egIndex) TRACE_GET_FLAG_ISEXCLUDED(excludedObjects, NQueue+1+NSemaphore+1+NMutex+1+NTask+1+NTimer+1+egIndex)
|
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_CLEAR_OBJECT_FLAG_ISEXCLUDED(objectclass, handle) \
|
|
||||||
switch (objectclass) \
|
|
||||||
{ \
|
|
||||||
case TRACE_CLASS_QUEUE: \
|
|
||||||
TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_SEMAPHORE: \
|
|
||||||
TRACE_CLEAR_SEMAPHORE_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_MUTEX: \
|
|
||||||
TRACE_CLEAR_MUTEX_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_TASK: \
|
|
||||||
TRACE_CLEAR_TASK_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_TIMER: \
|
|
||||||
TRACE_CLEAR_TIMER_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_EVENTGROUP: \
|
|
||||||
TRACE_CLEAR_EVENTGROUP_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TRACE_SET_OBJECT_FLAG_ISEXCLUDED(objectclass, handle) \
|
|
||||||
switch (objectclass) \
|
|
||||||
{ \
|
|
||||||
case TRACE_CLASS_QUEUE: \
|
|
||||||
TRACE_SET_QUEUE_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_SEMAPHORE: \
|
|
||||||
TRACE_SET_SEMAPHORE_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_MUTEX: \
|
|
||||||
TRACE_SET_MUTEX_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_TASK: \
|
|
||||||
TRACE_SET_TASK_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_TIMER: \
|
|
||||||
TRACE_SET_TIMER_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
case TRACE_CLASS_EVENTGROUP: \
|
|
||||||
TRACE_SET_EVENTGROUP_FLAG_ISEXCLUDED(handle); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Task */
|
|
||||||
#define vTraceExcludeTaskFromTrace(handle) \
|
|
||||||
TRACE_SET_TASK_FLAG_ISEXCLUDED(TRACE_GET_TASK_NUMBER(handle));
|
|
||||||
|
|
||||||
#define vTraceIncludeTaskInTrace(handle) \
|
|
||||||
TRACE_CLEAR_TASK_FLAG_ISEXCLUDED(TRACE_GET_TASK_NUMBER(handle));
|
|
||||||
|
|
||||||
|
|
||||||
/* Queue */
|
|
||||||
#define vTraceExcludeQueueFromTrace(handle) \
|
|
||||||
TRACE_SET_QUEUE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(UNUSED, handle));
|
|
||||||
|
|
||||||
#define vTraceIncludeQueueInTrace(handle) \
|
|
||||||
TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(UNUSED, handle));
|
|
||||||
|
|
||||||
|
|
||||||
/* Semaphore */
|
|
||||||
#define vTraceExcludeSemaphoreFromTrace(handle) \
|
|
||||||
TRACE_SET_SEMAPHORE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(UNUSED, handle));
|
|
||||||
|
|
||||||
#define vTraceIncludeSemaphoreInTrace(handle) \
|
|
||||||
TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(UNUSED, handle));
|
|
||||||
|
|
||||||
|
|
||||||
/* Mutex */
|
|
||||||
#define vTraceExcludeMutexFromTrace(handle) \
|
|
||||||
TRACE_SET_MUTEX_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(UNUSED, handle));
|
|
||||||
|
|
||||||
#define vTraceIncludeMutexInTrace(handle) \
|
|
||||||
TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(TRACE_GET_OBJECT_NUMBER(UNUSED, handle));
|
|
||||||
|
|
||||||
/* Timer */
|
|
||||||
#define vTraceExcludeTimerFromTrace(handle) \
|
|
||||||
TRACE_SET_TIMER_FLAG_ISEXCLUDED(TRACE_GET_TIMER_NUMBER(handle));
|
|
||||||
|
|
||||||
#define vTraceIncludeTimerInTrace(handle) \
|
|
||||||
TRACE_CLEAR_QUEUE_FLAG_ISEXCLUDED(TRACE_GET_TIMER_NUMBER(handle));
|
|
||||||
|
|
||||||
/* Event Group */
|
|
||||||
#define vTraceExcludeEventGroupFromTrace(handle) \
|
|
||||||
TRACE_SET_EVENTGROUP_FLAG_ISEXCLUDED(TRACE_GET_EVENTGROUP_NUMBER(handle));
|
|
||||||
|
|
||||||
#define vTraceIncludeEventGroupInTrace(handle) \
|
|
||||||
TRACE_CLEAR_EVENTGROUP_FLAG_ISEXCLUDED(TRACE_GET_EVENTGROUP_NUMBER(handle));
|
|
||||||
|
|
||||||
|
|
||||||
/* Kernel Services */
|
|
||||||
#define vTraceExcludeKernelServiceDelayFromTrace() \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(TASK_DELAY); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(TASK_DELAY_UNTIL);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceDelayInTrace() \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(TASK_DELAY); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(TASK_DELAY_UNTIL);
|
|
||||||
|
|
||||||
/* HELPER MACROS FOR KERNEL SERVICES FOR OBJECTS */
|
|
||||||
#define vTraceExcludeKernelServiceSendFromTrace_HELPER(class) \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_SUCCESS + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_BLOCK + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_FAILED + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_FROM_ISR_SUCCESS + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_FROM_ISR_FAILED + class);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceSendInTrace_HELPER(class) \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_SUCCESS + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_BLOCK + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_FAILED + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_FROM_ISR_SUCCESS + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_SEND_FROM_ISR_FAILED + class);
|
|
||||||
|
|
||||||
#define vTraceExcludeKernelServiceReceiveFromTrace_HELPER(class) \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_SUCCESS + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_BLOCK + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_FAILED + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + class); \
|
|
||||||
TRACE_SET_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_FROM_ISR_FAILED + class);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceReceiveInTrace_HELPER(class) \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_SUCCESS + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_BLOCK + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_FAILED + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + class); \
|
|
||||||
TRACE_CLEAR_EVENT_CODE_FLAG_ISEXCLUDED(EVENTGROUP_RECEIVE_FROM_ISR_FAILED + class);
|
|
||||||
|
|
||||||
/* EXCLUDE AND INCLUDE FOR QUEUE */
|
|
||||||
#define vTraceExcludeKernelServiceQueueSendFromTrace() \
|
|
||||||
vTraceExcludeKernelServiceSendFromTrace_HELPER(TRACE_CLASS_QUEUE);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceQueueSendInTrace() \
|
|
||||||
vTraceIncludeKernelServiceSendInTrace_HELPER(TRACE_CLASS_QUEUE);
|
|
||||||
|
|
||||||
#define vTraceExcludeKernelServiceQueueReceiveFromTrace() \
|
|
||||||
vTraceExcludeKernelServiceReceiveFromTrace_HELPER(TRACE_CLASS_QUEUE);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceQueueReceiveInTrace() \
|
|
||||||
vTraceIncludeKernelServiceReceiveInTrace_HELPER(TRACE_CLASS_QUEUE);
|
|
||||||
|
|
||||||
/* EXCLUDE AND INCLUDE FOR SEMAPHORE */
|
|
||||||
#define vTraceExcludeKernelServiceSemaphoreSendFromTrace() \
|
|
||||||
vTraceExcludeKernelServiceSendFromTrace_HELPER(TRACE_CLASS_SEMAPHORE);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServicSemaphoreSendInTrace() \
|
|
||||||
vTraceIncludeKernelServiceSendInTrace_HELPER(TRACE_CLASS_SEMAPHORE);
|
|
||||||
|
|
||||||
#define vTraceExcludeKernelServiceSemaphoreReceiveFromTrace() \
|
|
||||||
vTraceExcludeKernelServiceReceiveFromTrace_HELPER(TRACE_CLASS_SEMAPHORE);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceSemaphoreReceiveInTrace() \
|
|
||||||
vTraceIncludeKernelServiceReceiveInTrace_HELPER(TRACE_CLASS_SEMAPHORE);
|
|
||||||
|
|
||||||
/* EXCLUDE AND INCLUDE FOR MUTEX */
|
|
||||||
#define vTraceExcludeKernelServiceMutexSendFromTrace() \
|
|
||||||
vTraceExcludeKernelServiceSendFromTrace_HELPER(TRACE_CLASS_MUTEX);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceMutexSendInTrace() \
|
|
||||||
vTraceIncludeKernelServiceSendInTrace_HELPER(TRACE_CLASS_MUTEX);
|
|
||||||
|
|
||||||
#define vTraceExcludeKernelServiceMutexReceiveFromTrace() \
|
|
||||||
vTraceExcludeKernelServiceReceiveFromTrace_HELPER(TRACE_CLASS_MUTEX);
|
|
||||||
|
|
||||||
#define vTraceIncludeKernelServiceMutexReceiveInTrace() \
|
|
||||||
vTraceIncludeKernelServiceReceiveInTrace_HELPER(TRACE_CLASS_MUTEX);
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* KERNEL SPECIFIC MACROS TO NAME OBJECTS, IF NECESSARY */
|
|
||||||
/************************************************************************/
|
|
||||||
#define vTraceSetQueueName(object, name) \
|
|
||||||
vTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, object), TRACE_GET_OBJECT_NUMBER(UNUSED, object), name);
|
|
||||||
|
|
||||||
#define vTraceSetSemaphoreName(object, name) \
|
|
||||||
vTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, object), TRACE_GET_OBJECT_NUMBER(UNUSED, object), name);
|
|
||||||
|
|
||||||
#define vTraceSetMutexName(object, name) \
|
|
||||||
vTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, object), TRACE_GET_OBJECT_NUMBER(UNUSED, object), name);
|
|
||||||
|
|
||||||
#define vTraceSetEventGroupName(object, name) \
|
|
||||||
vTraceSetObjectName(TRACE_CLASS_EVENTGROUP, uxEventGroupGetNumber(object), name);
|
|
||||||
|
|
||||||
#undef traceQUEUE_REGISTRY_ADD
|
|
||||||
#define traceQUEUE_REGISTRY_ADD(object, name) vTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(UNUSED, object), TRACE_GET_OBJECT_NUMBER(UNUSED, object), name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* TRCKERNELPORT_H_ */
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcTypes.h
|
* trcTypes.h
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcUser.h
|
* trcUser.h
|
||||||
|
@ -30,7 +30,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -82,6 +84,13 @@ void vTraceInitTraceData(void);
|
||||||
void vTraceSetRecorderData(void* pRecorderData);
|
void vTraceSetRecorderData(void* pRecorderData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetStopHook
|
||||||
|
*
|
||||||
|
* Sets a function to be called when the recorder is stopped.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* uiTraceStart
|
* uiTraceStart
|
||||||
*
|
*
|
||||||
|
@ -161,13 +170,9 @@ void vTraceClearError(int resetErrorMessage);
|
||||||
* ...
|
* ...
|
||||||
* void ISR_handler()
|
* void ISR_handler()
|
||||||
* {
|
* {
|
||||||
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
|
|
||||||
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
||||||
* portEXIT_CRITICAL();
|
|
||||||
* ...
|
* ...
|
||||||
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
|
* vTraceStoreISREnd(0);
|
||||||
* vTraceStoreISREnd();
|
|
||||||
* portEXIT_CRITICAL();
|
|
||||||
* }
|
* }
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceSetISRProperties(objectHandleType handle, const char* name, char priority);
|
void vTraceSetISRProperties(objectHandleType handle, const char* name, char priority);
|
||||||
|
@ -186,13 +191,9 @@ void vTraceSetISRProperties(objectHandleType handle, const char* name, char prio
|
||||||
* ...
|
* ...
|
||||||
* void ISR_handler()
|
* void ISR_handler()
|
||||||
* {
|
* {
|
||||||
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
|
|
||||||
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
||||||
* portEXIT_CRITICAL();
|
|
||||||
* ...
|
* ...
|
||||||
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
|
* vTraceStoreISREnd(0);
|
||||||
* vTraceStoreISREnd();
|
|
||||||
* portEXIT_CRITICAL();
|
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -203,7 +204,8 @@ void vTraceStoreISRBegin(objectHandleType id);
|
||||||
*
|
*
|
||||||
* Registers the end of an Interrupt Service Routine.
|
* Registers the end of an Interrupt Service Routine.
|
||||||
*
|
*
|
||||||
* If allowing nested ISRs, this must be called with interrupts disabled.
|
* The parameter pendingISR indicates if the interrupt has requested a
|
||||||
|
* task-switch (= 1) or if the interrupt returns to the earlier context (= 0)
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
|
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
|
||||||
|
@ -213,17 +215,13 @@ void vTraceStoreISRBegin(objectHandleType id);
|
||||||
* ...
|
* ...
|
||||||
* void ISR_handler()
|
* void ISR_handler()
|
||||||
* {
|
* {
|
||||||
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
|
|
||||||
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
||||||
* portEXIT_CRITICAL();
|
|
||||||
* ...
|
* ...
|
||||||
* portENTER_CRITICAL(); // Required if nested ISRs are allowed
|
* vTraceStoreISREnd(0);
|
||||||
* vTraceStoreISREnd();
|
|
||||||
* portEXIT_CRITICAL();
|
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreISREnd(void);
|
void vTraceStoreISREnd(int pendingISR);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* If not including the ISR recording */
|
/* If not including the ISR recording */
|
||||||
|
@ -238,28 +236,59 @@ void vTraceDecreaseISRActive(void);
|
||||||
|
|
||||||
#endif
|
#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
|
* vTraceTaskInstanceFinish(void)
|
||||||
*
|
*
|
||||||
* This defines an explicit Instance Finish Event for the current task. It tells
|
* Marks the current task instance as finished on the next kernel call.
|
||||||
* 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
|
* If that kernel call is blocking, the instance ends after the blocking event
|
||||||
* should be called right before the api function call considered to be the end
|
* and the corresponding return event is then the start of the next instance.
|
||||||
* of the task instamce, i.e., the Instance Finish Event.
|
* If the kernel call is not blocking, the viewer instead splits the current
|
||||||
******************************************************************************/
|
* fragment right before the kernel call, which makes this call the first event
|
||||||
void vTraceTaskInstanceIsFinished(void);
|
* of the next instance.
|
||||||
|
*
|
||||||
|
* See also USE_IMPLICIT_IFE_RULES in trcConfig.h
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* while(1)
|
||||||
|
* {
|
||||||
|
* xQueueReceive(CommandQueue, &command, timeoutDuration);
|
||||||
|
* processCommand(command);
|
||||||
|
* vTraceInstanceFinish();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
void vTraceTaskInstanceFinish(void);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* vTraceTaskInstanceFinishDirect(void)
|
||||||
|
*
|
||||||
|
* Marks the current task instance as finished at this very instant.
|
||||||
|
* This makes the viewer to splits the current fragment at this point and begin
|
||||||
|
* a new actor instance.
|
||||||
|
*
|
||||||
|
* See also USE_IMPLICIT_IFE_RULES in trcConfig.h
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* This example will generate two instances for each loop iteration.
|
||||||
|
* The first instance ends at vTraceInstanceFinishDirect(), while the second
|
||||||
|
* instance ends at the next xQueueReceive call.
|
||||||
|
*
|
||||||
|
* while (1)
|
||||||
|
* {
|
||||||
|
* xQueueReceive(CommandQueue, &command, timeoutDuration);
|
||||||
|
* ProcessCommand(command);
|
||||||
|
* vTraceInstanceFinishDirect();
|
||||||
|
* DoSometingElse();
|
||||||
|
* vTraceInstanceFinish();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
void vTraceTaskInstanceFinishDirect(void);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceGetTraceBuffer
|
* vTraceGetTraceBuffer
|
||||||
|
@ -380,7 +409,7 @@ void vTraceUserEvent(traceLabel eventLabel);
|
||||||
* unless the higher precision is really necessary.
|
* unless the higher precision is really necessary.
|
||||||
*
|
*
|
||||||
* Note that the double-precision float (%lf) assumes a 64 bit double
|
* 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.
|
* representation. This does not seem to be the case on e.g. PIC24 and PIC32.
|
||||||
* Before using a %lf argument on a 16-bit MCU, please verify that
|
* 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.
|
* "sizeof(double)" actually gives 8 as expected. If not, use %f instead.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -417,7 +446,6 @@ void vTraceChannelUserEvent(UserEventChannel channel);
|
||||||
#define vTracePrintF(eventLabel,formatStr,...)
|
#define vTracePrintF(eventLabel,formatStr,...)
|
||||||
#define vTraceExcludeTaskFromSchedulingTrace(name)
|
#define vTraceExcludeTaskFromSchedulingTrace(name)
|
||||||
|
|
||||||
#define vTraceTaskSkipDefaultInstanceFinishedEvents()
|
|
||||||
#define vTraceSetISRProperties(handle, name, priority)
|
#define vTraceSetISRProperties(handle, name, priority)
|
||||||
#define vTraceStoreISRBegin(id)
|
#define vTraceStoreISRBegin(id)
|
||||||
#define vTraceStoreISREnd()
|
#define vTraceStoreISREnd()
|
||||||
|
@ -427,6 +455,7 @@ void vTraceChannelUserEvent(UserEventChannel channel);
|
||||||
#define vTraceSetSemaphoreName(a, b)
|
#define vTraceSetSemaphoreName(a, b)
|
||||||
#define vTraceSetEventGroupName(a, b)
|
#define vTraceSetEventGroupName(a, b)
|
||||||
|
|
||||||
|
#define vTraceSetStopHook(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -4,10 +4,10 @@ Tracealyzer Trace Recorder Library
|
||||||
Percepio AB
|
Percepio AB
|
||||||
www.percepio.com
|
www.percepio.com
|
||||||
|
|
||||||
This directory contains the a generic trace recorder library for Tracealyzer v2.6.
|
This directory contains the a generic trace recorder library for Tracealyzer v2.7.
|
||||||
|
|
||||||
For information on how to upload the trace data from your target system RAM to
|
For information on how to upload the trace data from your target system RAM to
|
||||||
Tracealyzer, see "debugger trace upload.txt"
|
Tracealyzer, see the User Manual (e.g., http://percepio.com/docs/FreeRTOS/manual/Recorder.html)
|
||||||
|
|
||||||
Files included
|
Files included
|
||||||
--------------
|
--------------
|
||||||
|
@ -16,8 +16,9 @@ Files included
|
||||||
- trcKernel.c/.h - Internal routines for storing kernel events.
|
- trcKernel.c/.h - Internal routines for storing kernel events.
|
||||||
- trcBase.c/.h - Internal routines for manipulating the data structures and calculating timestamps.
|
- trcBase.c/.h - Internal routines for manipulating the data structures and calculating timestamps.
|
||||||
- trcHardwarePort.c/.h - The hardware interface, especially for timestamping.
|
- trcHardwarePort.c/.h - The hardware interface, especially for timestamping.
|
||||||
- trcKernelPort.c/.h - Kernel specific implementations of macros and data.
|
- trcKernelPort.h - Wrapper for trcKernelPortFreeRTOS.h (for portability).
|
||||||
- trcKernelHooks.h - The trace macro defines (OS independent).
|
- trcKernelPortFreeRTOS.c/.h - FreeRTOS-specific trace macros and helper functions.
|
||||||
|
- trcKernelHooks.h - Generic trace macros (OS independent), used by trcKernelPortFreeRTOS.
|
||||||
- trcTypes.h - Type definitions used.
|
- trcTypes.h - Type definitions used.
|
||||||
|
|
||||||
Hardware Timer Ports
|
Hardware Timer Ports
|
||||||
|
@ -29,17 +30,19 @@ This release contains hardware timer ports for the following hardware architectu
|
||||||
- Atmel AT32UC3 (AVR32)
|
- Atmel AT32UC3 (AVR32)
|
||||||
- Renesas RX600 (e.g., RX62N)
|
- Renesas RX600 (e.g., RX62N)
|
||||||
- Microchip dsPIC/PIC24
|
- Microchip dsPIC/PIC24
|
||||||
- Microchip PIC32
|
- Microchip PIC32MX
|
||||||
|
- Microchip PIC32MZ
|
||||||
- NXP LPC2106
|
- NXP LPC2106
|
||||||
- Texas Instruments TMS570 (Cortex-R4)
|
- Texas Instruments TMS570 (Cortex-R4)
|
||||||
- Texas Instruments MSP430
|
- Texas Instruments MSP430
|
||||||
- Xilinx PowerPC 405
|
- Xilinx PowerPC 405
|
||||||
- Xilinx PowerPC 440
|
- Xilinx PowerPC 440
|
||||||
- Xilinx Microblaze
|
- Xilinx Microblaze
|
||||||
|
- ARM Cortex-A9
|
||||||
|
|
||||||
These are defined in trcHardwarePort.h. Some of these are "unofficial" ports, provided by external contributors.
|
These are defined in trcHardwarePort.h. Some of these are "unofficial" ports, provided by external contributors.
|
||||||
By unofficial, it means that they are not yet verified by Percepio AB. Please refer to trcHardwarePort.h for detailed information.
|
By unofficial, it means that they are not yet verified by Percepio AB. Please refer to trcHardwarePort.h for detailed information.
|
||||||
If you use an unofficial port and beleive it is incorrect, please let us know! (support@percepio.com)
|
If you use an unofficial port and believe it is incorrect, please let us know! (support@percepio.com)
|
||||||
|
|
||||||
In case your MCU is not yet supported directly, developing a new port is quite easy, just a matter of defining a few macros
|
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 trcHardwarePort.h for further information.
|
according to your specific MCU. See trcHardwarePort.h for further information.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcBase.c
|
* trcBase.c
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -45,42 +47,51 @@
|
||||||
* Static data initializations
|
* Static data initializations
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/* Structure to handle the exclude flags for all objects and tasks. We add some extra objects since index 0 is not used for each object class. */
|
/* Tasks and kernel objects can be explicitly excluded from the trace to reduce
|
||||||
|
buffer usage. This structure handles the exclude flags for all objects and tasks.
|
||||||
|
Note that slot 0 is not used, since not a valid handle. */
|
||||||
uint8_t excludedObjects[(TRACE_KERNEL_OBJECT_COUNT + TRACE_NCLASSES) / 8 + 1] = { 0 };
|
uint8_t excludedObjects[(TRACE_KERNEL_OBJECT_COUNT + TRACE_NCLASSES) / 8 + 1] = { 0 };
|
||||||
|
|
||||||
/* Structure to handle the exclude flags for all event codes */
|
/* Specific events can also be excluded, i.e., by the event code. This can be
|
||||||
|
used to exclude kernel calls that don't refer to a kernel object, like a delay.
|
||||||
|
This structure handle the exclude flags for all event codes */
|
||||||
uint8_t excludedEventCodes[NEventCodes / 8 + 1] = { 0 };
|
uint8_t excludedEventCodes[NEventCodes / 8 + 1] = { 0 };
|
||||||
|
|
||||||
/* Keeps track of available handles */
|
/* A set of stacks that keeps track of available object handles for each class.
|
||||||
|
The stacks are empty initially, meaning that allocation of new handles will be
|
||||||
|
based on a counter (for each object class). Any delete operation will
|
||||||
|
return the handle to the corresponding stack, for reuse on the next allocate.*/
|
||||||
objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
|
objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
|
||||||
|
|
||||||
|
/* Initial HWTC_COUNT value, for detecting if the time-stamping source is
|
||||||
|
enabled. If using the OS periodic timer for time-stamping, this might not
|
||||||
|
have been configured on the earliest events during the startup. */
|
||||||
uint32_t init_hwtc_count;
|
uint32_t init_hwtc_count;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* RecorderData
|
* RecorderData
|
||||||
*
|
*
|
||||||
* The main data structure. This is the data read by Tracealyzer, typically
|
* The main data structure. This is the data read by the Tracealyzer tools,
|
||||||
* through a debugger RAM dump. The recorder access this through the pointer
|
* typically through a debugger RAM dump. The recorder uses the pointer
|
||||||
* RecorderDataPtr, to allow for dynamic memory allocation as well.
|
* RecorderDataPtr for accessing this, to allow for dynamic allocation.
|
||||||
*
|
*
|
||||||
* On the NXP LPC17xx you may use the secondary RAM bank (AHB RAM) for this
|
* 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
|
* 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
|
* 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.
|
* RAM. To place RecorderData in this RAM bank using IAR Embedded Workbench
|
||||||
|
* for ARM, use this pragma right before the declaration:
|
||||||
*
|
*
|
||||||
* #pragma location="AHB_RAM_MEMORY"
|
* #pragma location="AHB_RAM_MEMORY"
|
||||||
* RecorderDataType RecorderData = ...
|
|
||||||
*
|
*
|
||||||
* This of course works for other hardware architectures with additional RAM
|
* 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
|
* banks as well, just replace "AHB_RAM_MEMORY" with the section name from the
|
||||||
* address section from the linker file.
|
* linker .map file, or simply the desired address.
|
||||||
*
|
*
|
||||||
* However, to keep trcBase.c portable and still have a preconfigured IAR demo
|
* For portability reasons, we don't add the pragma directly in trcBase.c, but
|
||||||
* using AHB RAM, we don't add the pragma directly in trcBase.c but in a header
|
* in a header file included below. To include this header, you need to enable
|
||||||
* included where the pragma should go. This is used depending on the setting
|
|
||||||
* USE_LINKER_PRAGMA, defined in trcConfig.h.
|
* USE_LINKER_PRAGMA, defined in trcConfig.h.
|
||||||
*
|
*
|
||||||
* If using GCC, this is instead done by adding a "section" attribute:
|
* If using GCC, you need to modify the declaration as follows:
|
||||||
*
|
*
|
||||||
* RecorderDataType RecorderData __attribute__ ((section ("name"))) = ...
|
* RecorderDataType RecorderData __attribute__ ((section ("name"))) = ...
|
||||||
*
|
*
|
||||||
|
@ -158,7 +169,7 @@ void prvTraceInitTraceData()
|
||||||
RecorderDataPtr->exampleFloatEncoding = (float)1.0; /* otherwise already zero */
|
RecorderDataPtr->exampleFloatEncoding = (float)1.0; /* otherwise already zero */
|
||||||
#endif
|
#endif
|
||||||
RecorderDataPtr->debugMarker2 = 0xF2F2F2F2;
|
RecorderDataPtr->debugMarker2 = 0xF2F2F2F2;
|
||||||
(void)strncpy(RecorderDataPtr->systemInfo, TRACE_DESCRIPTION, TRACE_DESCRIPTION_MAX_LENGTH);
|
(void)strncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80);
|
||||||
RecorderDataPtr->debugMarker3 = 0xF3F3F3F3;
|
RecorderDataPtr->debugMarker3 = 0xF3F3F3F3;
|
||||||
RecorderDataPtr->endmarker0 = 0x0A;
|
RecorderDataPtr->endmarker0 = 0x0A;
|
||||||
RecorderDataPtr->endmarker1 = 0x0B;
|
RecorderDataPtr->endmarker1 = 0x0B;
|
||||||
|
@ -215,6 +226,12 @@ char* traceErrorMessage = NULL;
|
||||||
|
|
||||||
void* xTraceNextFreeEventBufferSlot(void)
|
void* xTraceNextFreeEventBufferSlot(void)
|
||||||
{
|
{
|
||||||
|
if (! RecorderDataPtr->recorderActive)
|
||||||
|
{
|
||||||
|
// If the associated XTS or XPS event prio to the main event has filled the buffer and store mode "stop when full".
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (RecorderDataPtr->nextFreeIndex >= EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->nextFreeIndex >= EVENT_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
vTraceError("Attempt to index outside event buffer!");
|
vTraceError("Attempt to index outside event buffer!");
|
||||||
|
@ -225,12 +242,16 @@ void* xTraceNextFreeEventBufferSlot(void)
|
||||||
|
|
||||||
uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)
|
uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiIndexOfObject: Invalid value for objectclass", 0);
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiIndexOfObject: Invalid value for objecthandle", 0);
|
"uiIndexOfObject: Invalid value for objectclass", 0);
|
||||||
|
TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"uiIndexOfObject: Invalid value for objecthandle", 0);
|
||||||
|
|
||||||
if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) && (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
|
if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) &&
|
||||||
|
(objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]))
|
||||||
{
|
{
|
||||||
return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] + (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));
|
return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] +
|
||||||
|
(RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
vTraceError("Object table lookup with invalid object handle or object class!");
|
vTraceError("Object table lookup with invalid object handle or object class!");
|
||||||
|
@ -265,7 +286,8 @@ objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass)
|
||||||
objectHandleType handle;
|
objectHandleType handle;
|
||||||
static int indexOfHandle;
|
static int indexOfHandle;
|
||||||
|
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "xTraceGetObjectHandle: Invalid value for objectclass", (objectHandleType)0);
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
|
"xTraceGetObjectHandle: Invalid value for objectclass", (objectHandleType)0);
|
||||||
|
|
||||||
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
|
indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass];
|
||||||
if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
|
if (objectHandleStacks.objectHandles[indexOfHandle] == 0)
|
||||||
|
@ -313,8 +335,10 @@ void vTraceFreeObjectHandle(traceObjectClass objectclass, objectHandleType handl
|
||||||
{
|
{
|
||||||
int indexOfHandle;
|
int indexOfHandle;
|
||||||
|
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceFreeObjectHandle: Invalid value for objectclass", );
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceFreeObjectHandle: Invalid value for handle", );
|
"vTraceFreeObjectHandle: Invalid value for objectclass", );
|
||||||
|
TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"vTraceFreeObjectHandle: Invalid value for handle", );
|
||||||
|
|
||||||
/* Check that there is room to push the handle on the stack */
|
/* Check that there is room to push the handle on the stack */
|
||||||
if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) <
|
if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) <
|
||||||
|
@ -401,7 +425,6 @@ traceLabel prvTraceOpenSymbol(const char* name, traceLabel userEventChannel)
|
||||||
len = 0;
|
len = 0;
|
||||||
crc = 0;
|
crc = 0;
|
||||||
|
|
||||||
|
|
||||||
TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceLabel)0);
|
TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceLabel)0);
|
||||||
|
|
||||||
prvTraceGetChecksum(name, &crc, &len);
|
prvTraceGetChecksum(name, &crc, &len);
|
||||||
|
@ -446,7 +469,7 @@ void vTraceError(const char* msg)
|
||||||
if (traceErrorMessage == NULL)
|
if (traceErrorMessage == NULL)
|
||||||
{
|
{
|
||||||
traceErrorMessage = (char*)msg;
|
traceErrorMessage = (char*)msg;
|
||||||
(void)strncpy(RecorderDataPtr->systemInfo, traceErrorMessage, TRACE_DESCRIPTION_MAX_LENGTH);
|
(void)strncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80);
|
||||||
RecorderDataPtr->internalErrorOccured = 1;
|
RecorderDataPtr->internalErrorOccured = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +496,8 @@ void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck)
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned int e = 0;
|
unsigned int e = 0;
|
||||||
|
|
||||||
TRACE_ASSERT(nofEntriesToCheck != 0, "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", );
|
TRACE_ASSERT(nofEntriesToCheck != 0,
|
||||||
|
"prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", );
|
||||||
|
|
||||||
while (i < nofEntriesToCheck)
|
while (i < nofEntriesToCheck)
|
||||||
{
|
{
|
||||||
|
@ -534,15 +558,6 @@ void prvTraceUpdateCounters(void)
|
||||||
#if (TRACE_RECORDER_STORE_MODE == TRACE_STORE_MODE_RING_BUFFER)
|
#if (TRACE_RECORDER_STORE_MODE == TRACE_STORE_MODE_RING_BUFFER)
|
||||||
prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
|
prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STOP_AFTER_N_EVENTS
|
|
||||||
#if (STOP_AFTER_N_EVENTS > -1)
|
|
||||||
if (RecorderDataPtr->numEvents >= STOP_AFTER_N_EVENTS)
|
|
||||||
{
|
|
||||||
vTraceStop();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -782,7 +797,7 @@ uint16_t prvTraceCreateSymbolTableEntry(const char* name,
|
||||||
void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
|
void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
int length = 1;
|
int length = 1; /* Should be 1 to account for '\0' */
|
||||||
int crc = 0;
|
int crc = 0;
|
||||||
|
|
||||||
TRACE_ASSERT(pname != NULL, "prvTraceGetChecksum: pname == NULL", );
|
TRACE_ASSERT(pname != NULL, "prvTraceGetChecksum: pname == NULL", );
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcHardwarePort.c
|
* trcHardwarePort.c
|
||||||
|
@ -32,7 +32,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -56,36 +58,37 @@ uint32_t last_timestamp = 0;
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
uint32_t uiTraceTickCount = 0;
|
uint32_t uiTraceTickCount = 0;
|
||||||
|
|
||||||
uint32_t DWT_CYCLES_ADDED = 0;
|
uint32_t DWT_CYCLES_ADDED = 0; /* Used on ARM Cortex-M only */
|
||||||
|
|
||||||
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
||||||
|
|
||||||
void prvTraceEnableIRQ(void)
|
|
||||||
{
|
|
||||||
asm volatile ("cpsie i");
|
|
||||||
}
|
|
||||||
|
|
||||||
void prvTraceDisableIRQ(void)
|
|
||||||
{
|
|
||||||
asm volatile ("cpsid i");
|
|
||||||
}
|
|
||||||
|
|
||||||
void prvTraceSetIRQMask(uint32_t priMask)
|
|
||||||
{
|
|
||||||
asm volatile ("MSR primask, %0" : : "r" (priMask) );
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t prvTraceGetIRQMask(void)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
asm volatile ("MRS %0, primask" : "=r" (result) );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void prvTraceInitCortexM()
|
void prvTraceInitCortexM()
|
||||||
{
|
{
|
||||||
DWT_CTRL_REG |= 1; /* Enable the cycle counter */
|
/* Make sure DWT is enabled is enabled, if supported */
|
||||||
DWT_CYCLE_COUNTER = 0;
|
REG_DEMCR |= DEMCR_TRCENA;
|
||||||
|
|
||||||
|
do{
|
||||||
|
/* Verify that DWT is supported */
|
||||||
|
if (REG_DEMCR == 0)
|
||||||
|
{
|
||||||
|
vTraceError("DWT not supported by this chip!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify that DWT_CYCCNT is supported */
|
||||||
|
if (REG_DWT_CTRL & DWT_CTRL_NOCYCCNT)
|
||||||
|
{
|
||||||
|
vTraceError("DWT_CYCCNT not supported by this chip!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the cycle counter */
|
||||||
|
REG_DWT_CYCCNT = 0;
|
||||||
|
|
||||||
|
/* Enable the cycle counter */
|
||||||
|
REG_DWT_CTRL |= DWT_CTRL_CYCCNTENA;
|
||||||
|
|
||||||
|
}while(0); /* breaks above jump here */
|
||||||
|
|
||||||
if (RecorderDataPtr->frequency == 0)
|
if (RecorderDataPtr->frequency == 0)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +133,19 @@ void vTracePortGetTimeStamp(uint32_t *pTimestamp)
|
||||||
Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING
|
Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_Win32)
|
||||||
|
/* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn
|
||||||
|
uses QueryPerformanceCounter. That function is not always reliable when used over
|
||||||
|
multiple threads. We must therefore handle rare cases where the timestamp is less
|
||||||
|
than the previous. In practice, the Win32 should "never" roll over since the
|
||||||
|
performance counter is 64 bit wide. */
|
||||||
|
|
||||||
|
if (last_hwtc_count > hwtc_count)
|
||||||
|
{
|
||||||
|
hwtc_count = last_hwtc_count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
|
if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
|
||||||
{
|
{
|
||||||
/* This means last_traceTickCount is higher than uiTraceTickCount,
|
/* This means last_traceTickCount is higher than uiTraceTickCount,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcKernel.c
|
* trcKernel.c
|
||||||
*
|
*
|
||||||
* Functions used by trcKernelHooks.h.
|
* Functions used by trcKernelHooks.h for storing various kernel events.
|
||||||
*
|
*
|
||||||
* Terms of Use
|
* Terms of Use
|
||||||
* This software is copyright Percepio AB. The recorder library is free for
|
* This software is copyright Percepio AB. The recorder library is free for
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -46,7 +48,12 @@ uint8_t nISRactive = 0;
|
||||||
objectHandleType handle_of_last_logged_task = 0;
|
objectHandleType handle_of_last_logged_task = 0;
|
||||||
uint8_t inExcludedTask = 0;
|
uint8_t inExcludedTask = 0;
|
||||||
|
|
||||||
|
/* Current heap usage. Always updated. */
|
||||||
|
static uint32_t heapMemUsage = 0;
|
||||||
|
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
static uint32_t prvTraceGetParam(uint32_t, uint32_t);
|
static uint32_t prvTraceGetParam(uint32_t, uint32_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
|
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -58,9 +65,18 @@ void vTraceStoreTaskReady(objectHandleType handle)
|
||||||
{
|
{
|
||||||
uint16_t dts3;
|
uint16_t dts3;
|
||||||
TREvent* tr;
|
TREvent* tr;
|
||||||
|
uint8_t hnd8;
|
||||||
|
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
TRACE_ASSERT(handle > 0 && handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );
|
if (handle == 0)
|
||||||
|
{
|
||||||
|
/* On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad
|
||||||
|
placement of the trace macro. In that case, the events are ignored. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_ASSERT(handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );
|
||||||
|
|
||||||
if (recorder_busy)
|
if (recorder_busy)
|
||||||
{
|
{
|
||||||
|
@ -80,23 +96,17 @@ void vTraceStoreTaskReady(objectHandleType handle)
|
||||||
if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))
|
if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))
|
||||||
{
|
{
|
||||||
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
hnd8 = prvTraceGet8BitHandle(handle);
|
||||||
{
|
|
||||||
uint8_t hnd8 = prvTraceGet8BitHandle(handle);
|
|
||||||
|
|
||||||
tr = (TREvent*)xTraceNextFreeEventBufferSlot();
|
tr = (TREvent*)xTraceNextFreeEventBufferSlot();
|
||||||
|
|
||||||
if (tr != NULL)
|
if (tr != NULL)
|
||||||
{
|
{
|
||||||
tr->type = DIV_TASK_READY;
|
tr->type = DIV_TASK_READY;
|
||||||
tr->dts = dts3;
|
tr->dts = dts3;
|
||||||
tr->objHandle = hnd8;
|
tr->objHandle = hnd8;
|
||||||
|
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -127,21 +137,17 @@ void vTraceStoreLowPower(uint32_t flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
if (RecorderDataPtr->recorderActive)
|
||||||
{
|
{
|
||||||
dts = (uint16_t)prvTraceGetDTS(0xFFFF);
|
dts = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
|
||||||
lp = (LPEvent*)xTraceNextFreeEventBufferSlot();
|
lp = (LPEvent*)xTraceNextFreeEventBufferSlot();
|
||||||
if (lp != NULL)
|
if (lp != NULL)
|
||||||
{
|
{
|
||||||
lp->type = LOW_POWER_BEGIN + ( uint8_t ) flag; /* BEGIN or END depending on flag */
|
lp->type = LOW_POWER_BEGIN + ( uint8_t ) flag; /* BEGIN or END depending on flag */
|
||||||
lp->dts = dts;
|
lp->dts = dts;
|
||||||
|
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,59 +158,76 @@ void vTraceStoreLowPower(uint32_t flag)
|
||||||
* for size and address respectively. The event code parameter (ecode) is applied
|
* for size and address respectively. The event code parameter (ecode) is applied
|
||||||
* to the first record (size) and the following address record gets event
|
* to the first record (size) and the following address record gets event
|
||||||
* code "ecode + 1", so make sure this is respected in the event code table.
|
* code "ecode + 1", so make sure this is respected in the event code table.
|
||||||
|
* Note: On "free" calls, the signed_size parameter should be negative.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if (INCLUDE_MEMMANG_EVENTS == 1)
|
#if (INCLUDE_MEMMANG_EVENTS == 1)
|
||||||
void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, uint32_t size)
|
void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
uint8_t dts1;
|
uint8_t dts1;
|
||||||
MemEventSize * ms;
|
MemEventSize * ms;
|
||||||
MemEventAddr * ma;
|
MemEventAddr * ma;
|
||||||
uint16_t size_low;
|
uint16_t size_low;
|
||||||
uint16_t addr_low;
|
uint16_t addr_low;
|
||||||
uint8_t addr_high;
|
uint8_t addr_high;
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
if (signed_size < 0)
|
||||||
|
size = (uint32_t)(- signed_size);
|
||||||
|
else
|
||||||
|
size = (uint32_t)(signed_size);
|
||||||
|
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
|
|
||||||
|
heapMemUsage += signed_size;
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive)
|
if (RecorderDataPtr->recorderActive)
|
||||||
{
|
{
|
||||||
/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
|
/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
|
||||||
if (nISRactive || !inExcludedTask)
|
if (nISRactive || !inExcludedTask)
|
||||||
{
|
{
|
||||||
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
|
|
||||||
size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
|
size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
|
||||||
|
|
||||||
ms = (MemEventSize *)xTraceNextFreeEventBufferSlot();
|
ms = (MemEventSize *)xTraceNextFreeEventBufferSlot();
|
||||||
|
|
||||||
if (ms != NULL)
|
if (ms != NULL)
|
||||||
{
|
{
|
||||||
ms->dts = dts1;
|
ms->dts = dts1;
|
||||||
ms->type = (uint8_t)ecode;
|
ms->type = NULL_EVENT; /* Updated when all events are written */
|
||||||
ms->size = size_low;
|
ms->size = size_low;
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
|
|
||||||
/* Storing a second record with address (signals "failed" if null) */
|
/* Storing a second record with address (signals "failed" if null) */
|
||||||
#if (HEAP_SIZE_BELOW_16M)
|
#if (HEAP_SIZE_BELOW_16M)
|
||||||
|
/* If the heap address range is within 16 MB, i.e., the upper 8 bits
|
||||||
|
of addresses are constant, this optimization avoids storing an extra
|
||||||
|
event record by ignoring the upper 8 bit of the address */
|
||||||
addr_low = address & 0xFFFF;
|
addr_low = address & 0xFFFF;
|
||||||
addr_high = (address >> 16) & 0xFF;
|
addr_high = (address >> 16) & 0xFF;
|
||||||
#else
|
#else
|
||||||
|
/* The whole 32 bit address is stored using a second event record
|
||||||
|
for the upper 16 bit */
|
||||||
addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
|
addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
|
||||||
addr_high = 0;
|
addr_high = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ma = (MemEventAddr *) xTraceNextFreeEventBufferSlot();
|
ma = (MemEventAddr *) xTraceNextFreeEventBufferSlot();
|
||||||
|
|
||||||
if (ma != NULL)
|
if (ma != NULL)
|
||||||
{
|
{
|
||||||
ma->addr_low = addr_low;
|
ma->addr_low = addr_low;
|
||||||
ma->addr_high = addr_high;
|
ma->addr_high = addr_high;
|
||||||
ma->type = ( ( uint8_t) ecode ) + 1; /* Note this! */
|
ma->type = ( ( uint8_t) ecode ) + 1; /* Note this! */
|
||||||
|
ms->type = (uint8_t)ecode;
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
|
RecorderDataPtr->heapMemUsage = heapMemUsage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -216,8 +239,10 @@ void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, uint32_t size)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
|
void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
KernelCall * kse;
|
KernelCall * kse;
|
||||||
uint16_t dts1;
|
uint16_t dts1;
|
||||||
|
uint8_t hnd8;
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
TRACE_ASSERT(ecode < 0xFF, "vTraceStoreKernelCall: ecode >= 0xFF", );
|
TRACE_ASSERT(ecode < 0xFF, "vTraceStoreKernelCall: ecode >= 0xFF", );
|
||||||
|
@ -252,11 +277,7 @@ void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_
|
||||||
if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
|
if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
|
||||||
{
|
{
|
||||||
dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
|
hnd8 = prvTraceGet8BitHandle(objectNumber);
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
|
||||||
uint8_t hnd8 = prvTraceGet8BitHandle(objectNumber);
|
|
||||||
|
|
||||||
kse = (KernelCall*) xTraceNextFreeEventBufferSlot();
|
kse = (KernelCall*) xTraceNextFreeEventBufferSlot();
|
||||||
if (kse != NULL)
|
if (kse != NULL)
|
||||||
{
|
{
|
||||||
|
@ -268,8 +289,8 @@ void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -284,8 +305,11 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
||||||
uint32_t objectNumber,
|
uint32_t objectNumber,
|
||||||
uint32_t param)
|
uint32_t param)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
KernelCallWithParamAndHandle * kse;
|
KernelCallWithParamAndHandle * kse;
|
||||||
uint8_t dts2;
|
uint8_t dts2;
|
||||||
|
uint8_t hnd8;
|
||||||
|
uint8_t p8;
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCall: evtcode >= 0xFF", );
|
TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCall: evtcode >= 0xFF", );
|
||||||
|
@ -306,21 +330,15 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task &&
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task && (! inExcludedTask || nISRactive))
|
||||||
(! inExcludedTask || nISRactive))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Check if the referenced object or the event code is excluded */
|
/* Check if the referenced object or the event code is excluded */
|
||||||
if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) &&
|
||||||
|
!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
||||||
{
|
{
|
||||||
dts2 = (uint8_t)prvTraceGetDTS(0xFF);
|
dts2 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
|
p8 = (uint8_t) prvTraceGetParam(0xFF, param);
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
hnd8 = prvTraceGet8BitHandle((objectHandleType)objectNumber);
|
||||||
{
|
|
||||||
uint8_t p8 = (uint8_t) prvTraceGetParam(0xFF, param);
|
|
||||||
|
|
||||||
uint8_t hnd8 = prvTraceGet8BitHandle((objectHandleType)objectNumber);
|
|
||||||
|
|
||||||
kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();
|
kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();
|
||||||
if (kse != NULL)
|
if (kse != NULL)
|
||||||
{
|
{
|
||||||
|
@ -332,10 +350,12 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* prvTraceGetParam
|
* prvTraceGetParam
|
||||||
*
|
*
|
||||||
|
@ -347,7 +367,8 @@ static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
|
||||||
{
|
{
|
||||||
XPSEvent* xps;
|
XPSEvent* xps;
|
||||||
|
|
||||||
TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF, "prvTraceGetParam: Invalid value for param_max", param);
|
TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF,
|
||||||
|
"prvTraceGetParam: Invalid value for param_max", param);
|
||||||
|
|
||||||
if (param <= param_max)
|
if (param <= param_max)
|
||||||
{
|
{
|
||||||
|
@ -367,6 +388,7 @@ static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
|
||||||
return param & param_max;
|
return param & param_max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceStoreKernelCallWithNumericParamOnly
|
* vTraceStoreKernelCallWithNumericParamOnly
|
||||||
|
@ -376,6 +398,7 @@ static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
|
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
KernelCallWithParam16 * kse;
|
KernelCallWithParam16 * kse;
|
||||||
uint8_t dts6;
|
uint8_t dts6;
|
||||||
uint16_t restParam;
|
uint16_t restParam;
|
||||||
|
@ -383,7 +406,8 @@ void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
|
||||||
|
|
||||||
restParam = 0;
|
restParam = 0;
|
||||||
|
|
||||||
TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );
|
TRACE_ASSERT(evtcode < 0xFF,
|
||||||
|
"vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );
|
||||||
|
|
||||||
if (recorder_busy)
|
if (recorder_busy)
|
||||||
{
|
{
|
||||||
|
@ -406,13 +430,7 @@ void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
|
||||||
if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
||||||
{
|
{
|
||||||
dts6 = (uint8_t)prvTraceGetDTS(0xFF);
|
dts6 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
|
||||||
restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
|
restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
|
||||||
kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
|
kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
|
||||||
if (kse != NULL)
|
if (kse != NULL)
|
||||||
{
|
{
|
||||||
|
@ -423,9 +441,8 @@ void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -438,11 +455,13 @@ void vTraceStoreTaskswitch(objectHandleType task_handle)
|
||||||
uint16_t dts3;
|
uint16_t dts3;
|
||||||
TSEvent* ts;
|
TSEvent* ts;
|
||||||
int8_t skipEvent;
|
int8_t skipEvent;
|
||||||
|
uint8_t hnd8;
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
skipEvent = 0;
|
skipEvent = 0;
|
||||||
|
|
||||||
TRACE_ASSERT(task_handle <= NTask, "vTraceStoreTaskswitch: Invalid value for task_handle", );
|
TRACE_ASSERT(task_handle <= NTask,
|
||||||
|
"vTraceStoreTaskswitch: Invalid value for task_handle", );
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
This is used to detect if a high-priority ISRs is illegally using the
|
This is used to detect if a high-priority ISRs is illegally using the
|
||||||
|
@ -487,13 +506,8 @@ void vTraceStoreTaskswitch(objectHandleType task_handle)
|
||||||
if (skipEvent == 0)
|
if (skipEvent == 0)
|
||||||
{
|
{
|
||||||
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
|
||||||
uint8_t hnd8;
|
|
||||||
handle_of_last_logged_task = task_handle;
|
handle_of_last_logged_task = task_handle;
|
||||||
hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
|
hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
|
||||||
|
|
||||||
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
|
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
|
||||||
|
|
||||||
if (ts != NULL)
|
if (ts != NULL)
|
||||||
|
@ -518,7 +532,6 @@ void vTraceStoreTaskswitch(objectHandleType task_handle)
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();
|
trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();
|
||||||
}
|
}
|
||||||
|
@ -539,15 +552,15 @@ void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,
|
||||||
const char * name;
|
const char * name;
|
||||||
traceLabel idx;
|
traceLabel idx;
|
||||||
|
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", );
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceStoreObjectNameOnCloseEvent: Invalid value for handle", );
|
"vTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", );
|
||||||
|
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"vTraceStoreObjectNameOnCloseEvent: Invalid value for handle", );
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive)
|
if (RecorderDataPtr->recorderActive)
|
||||||
{
|
{
|
||||||
uint8_t hnd8 = prvTraceGet8BitHandle(handle);
|
uint8_t hnd8 = prvTraceGet8BitHandle(handle);
|
||||||
|
|
||||||
name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
|
name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
|
||||||
|
|
||||||
idx = prvTraceOpenSymbol(name, 0);
|
idx = prvTraceOpenSymbol(name, 0);
|
||||||
|
|
||||||
// Interrupt disable not necessary, already done in trcHooks.h macro
|
// Interrupt disable not necessary, already done in trcHooks.h macro
|
||||||
|
@ -567,8 +580,10 @@ void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
|
||||||
{
|
{
|
||||||
ObjClosePropEvent * pe;
|
ObjClosePropEvent * pe;
|
||||||
|
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", );
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", );
|
"vTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", );
|
||||||
|
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"vTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", );
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive)
|
if (RecorderDataPtr->recorderActive)
|
||||||
{
|
{
|
||||||
|
@ -579,9 +594,9 @@ void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
|
||||||
if (objectclass == TRACE_CLASS_TASK)
|
if (objectclass == TRACE_CLASS_TASK)
|
||||||
{
|
{
|
||||||
pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
|
pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
|
||||||
pe->arg2 = 0; // Legacy - IFE info removed.
|
}
|
||||||
pe->arg3 = 0; // Legacy - IFE info removed.
|
else
|
||||||
}else{
|
{
|
||||||
pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
|
pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
|
||||||
}
|
}
|
||||||
pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
|
pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
|
||||||
|
@ -593,39 +608,48 @@ void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
|
||||||
|
|
||||||
void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t value)
|
void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t value)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", );
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceSetPriorityProperty: Invalid value for id", );
|
"vTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", );
|
||||||
|
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"vTraceSetPriorityProperty: Invalid value for id", );
|
||||||
|
|
||||||
TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
|
TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)
|
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceGetPriorityProperty: Invalid value for id", 0);
|
"uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
|
||||||
|
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"uiTraceGetPriorityProperty: Invalid value for id", 0);
|
||||||
|
|
||||||
return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
|
return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vTraceSetObjectState(uint8_t objectclass, objectHandleType id, uint8_t value)
|
void vTraceSetObjectState(uint8_t objectclass, objectHandleType id, uint8_t value)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceSetObjectState: objectclass >= TRACE_NCLASSES", );
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceSetObjectState: Invalid value for id", );
|
"vTraceSetObjectState: objectclass >= TRACE_NCLASSES", );
|
||||||
|
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"vTraceSetObjectState: Invalid value for id", );
|
||||||
|
|
||||||
TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
|
TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t uiTraceGetObjectState(uint8_t objectclass, objectHandleType id)
|
uint8_t uiTraceGetObjectState(uint8_t objectclass, objectHandleType id)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);
|
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
|
||||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceGetObjectState: Invalid value for id", 0);
|
"uiTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);
|
||||||
|
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
|
||||||
|
"uiTraceGetObjectState: Invalid value for id", 0);
|
||||||
|
|
||||||
return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
|
return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vTraceSetTaskInstanceFinished(objectHandleType handle)
|
void vTraceSetTaskInstanceFinished(objectHandleType handle)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK], "vTraceSetTaskInstanceFinished: Invalid value for handle", );
|
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK],
|
||||||
|
"vTraceSetTaskInstanceFinished: Invalid value for handle", );
|
||||||
|
|
||||||
#if (USE_IMPLICIT_IFE_RULES == 1)
|
#if (USE_IMPLICIT_IFE_RULES == 1)
|
||||||
TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
|
TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcKernelPort.c
|
* trcKernelPort.c
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -56,13 +58,27 @@ traceObjectClass TraceObjectClassTable[5] = {
|
||||||
int uiInEventGroupSetBitsFromISR = 0;
|
int uiInEventGroupSetBitsFromISR = 0;
|
||||||
|
|
||||||
extern unsigned char ucQueueGetQueueType(void*);
|
extern unsigned char ucQueueGetQueueType(void*);
|
||||||
extern BaseType_t uxQueueGetQueueNumber(void*);
|
|
||||||
|
#if (FREERTOS_VERSION < FREERTOS_VERSION_8_0_OR_LATER)
|
||||||
|
|
||||||
|
extern portBASE_TYPE ucQueueGetQueueNumber(void*);
|
||||||
|
|
||||||
objectHandleType prvTraceGetObjectNumber(void* handle)
|
objectHandleType prvTraceGetObjectNumber(void* handle)
|
||||||
{
|
{
|
||||||
return ( objectHandleType ) uxQueueGetQueueNumber(handle);
|
return (objectHandleType) ucQueueGetQueueNumber(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern portBASE_TYPE uxQueueGetQueueNumber(void*);
|
||||||
|
|
||||||
|
objectHandleType prvTraceGetObjectNumber(void* handle)
|
||||||
|
{
|
||||||
|
return (objectHandleType) uxQueueGetQueueNumber(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char prvTraceGetObjectType(void* handle)
|
unsigned char prvTraceGetObjectType(void* handle)
|
||||||
{
|
{
|
||||||
return ucQueueGetQueueType(handle);
|
return ucQueueGetQueueType(handle);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcUser.c
|
* trcUser.c
|
||||||
|
@ -31,7 +31,9 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -56,7 +58,7 @@ extern uint32_t hwtc_count_sum_after_tick;
|
||||||
extern uint32_t hwtc_count_sum_after_tick_counter;
|
extern uint32_t hwtc_count_sum_after_tick_counter;
|
||||||
extern char* traceErrorMessage;
|
extern char* traceErrorMessage;
|
||||||
|
|
||||||
/*** private functions *******************************************************/
|
/*** Private functions *******************************************************/
|
||||||
void vTracePrintF_Helper(traceLabel eventLabel, const char* formatStr, va_list vl);
|
void vTracePrintF_Helper(traceLabel eventLabel, const char* formatStr, va_list vl);
|
||||||
|
|
||||||
#if (USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
#if (USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
||||||
|
@ -64,8 +66,8 @@ void vTraceChannelPrintF_Helper(UserEventChannel channelPair, va_list vl);
|
||||||
static void prvTraceUserEventHelper1(UserEventChannel channel, traceLabel eventLabel, traceLabel formatLabel, va_list vl);
|
static void prvTraceUserEventHelper1(UserEventChannel channel, traceLabel eventLabel, traceLabel formatLabel, va_list vl);
|
||||||
static void prvTraceUserEventHelper2(UserEventChannel channel, uint32_t* data, uint32_t noOfSlots);
|
static void prvTraceUserEventHelper2(UserEventChannel channel, uint32_t* data, uint32_t noOfSlots);
|
||||||
#endif
|
#endif
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
static void prvTraceTaskInstanceFinish(int8_t direct);
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -93,6 +95,16 @@ void vTraceSetRecorderData(void* pRecorderData)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceSetStopHook
|
||||||
|
*
|
||||||
|
* Sets a function to be called when the recorder is stopped.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction)
|
||||||
|
{
|
||||||
|
vTraceStopHookPtr = stopHookFunction;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* vTraceClear
|
* vTraceClear
|
||||||
*
|
*
|
||||||
|
@ -104,6 +116,8 @@ void vTraceClear(void)
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
|
|
||||||
|
RecorderDataPtr->absTimeLastEventSecond = 0;
|
||||||
|
|
||||||
RecorderDataPtr->absTimeLastEvent = 0;
|
RecorderDataPtr->absTimeLastEvent = 0;
|
||||||
RecorderDataPtr->nextFreeIndex = 0;
|
RecorderDataPtr->nextFreeIndex = 0;
|
||||||
RecorderDataPtr->numEvents = 0;
|
RecorderDataPtr->numEvents = 0;
|
||||||
|
@ -111,6 +125,8 @@ void vTraceClear(void)
|
||||||
traceErrorMessage = NULL;
|
traceErrorMessage = NULL;
|
||||||
RecorderDataPtr->internalErrorOccured = 0;
|
RecorderDataPtr->internalErrorOccured = 0;
|
||||||
|
|
||||||
|
memset(RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4);
|
||||||
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -140,6 +156,7 @@ uint32_t uiTraceStart(void)
|
||||||
vTraceError("RecorderDataPtr is NULL. Call vTraceInitTraceData() before starting trace.");
|
vTraceError("RecorderDataPtr is NULL. Call vTraceInitTraceData() before starting trace.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceErrorMessage == NULL)
|
if (traceErrorMessage == NULL)
|
||||||
{
|
{
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
|
@ -191,7 +208,7 @@ void vTraceStop(void)
|
||||||
|
|
||||||
if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0)
|
if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0)
|
||||||
{
|
{
|
||||||
(*vTraceStopHookPtr)(); /* Call an application level call back function. */
|
(*vTraceStopHookPtr)(); /* An application call-back function. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,19 +264,97 @@ uint32_t uiTraceGetTraceBufferSize(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* vTraceTaskInstanceIsFinished
|
* prvTraceTaskInstanceFinish.
|
||||||
|
*
|
||||||
|
* Private common function for the vTraceTaskInstanceFinishXXX functions.
|
||||||
*
|
*
|
||||||
* 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
|
|
||||||
* context-switch. This function should be called right before the API function
|
|
||||||
* call considered to be the Instance Finish Event.
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void vTraceTaskInstanceIsFinished()
|
void prvTraceTaskInstanceFinish(int8_t direct)
|
||||||
{
|
{
|
||||||
if (handle_of_last_logged_task)
|
TaskInstanceStatusEvent* tis;
|
||||||
|
uint8_t dts45;
|
||||||
|
|
||||||
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
|
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle_of_last_logged_task) = 0;
|
dts45 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
|
tis = (TaskInstanceStatusEvent*) xTraceNextFreeEventBufferSlot();
|
||||||
|
if (tis != NULL)
|
||||||
|
{
|
||||||
|
if (direct == 0)
|
||||||
|
tis->type = TASK_INSTANCE_FINISHED_NEXT_KSE;
|
||||||
|
else
|
||||||
|
tis->type = TASK_INSTANCE_FINISHED_DIRECT;
|
||||||
|
|
||||||
|
tis->dts = dts45;
|
||||||
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
trcCRITICAL_SECTION_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* vTraceTaskInstanceFinish(void)
|
||||||
|
*
|
||||||
|
* Marks the current task instance as finished on the next kernel call.
|
||||||
|
*
|
||||||
|
* If that kernel call is blocking, the instance ends after the blocking event
|
||||||
|
* and the corresponding return event is then the start of the next instance.
|
||||||
|
* If the kernel call is not blocking, the viewer instead splits the current
|
||||||
|
* fragment right before the kernel call, which makes this call the first event
|
||||||
|
* of the next instance.
|
||||||
|
*
|
||||||
|
* See also USE_IMPLICIT_IFE_RULES in trcConfig.h
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* while(1)
|
||||||
|
* {
|
||||||
|
* xQueueReceive(CommandQueue, &command, timeoutDuration);
|
||||||
|
* processCommand(command);
|
||||||
|
* vTraceInstanceFinish();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Note: This is only supported in Tracealyzer tools v2.7 or later
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
void vTraceTaskInstanceFinish(void)
|
||||||
|
{
|
||||||
|
prvTraceTaskInstanceFinish(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* vTraceTaskInstanceFinishDirect(void)
|
||||||
|
*
|
||||||
|
* Marks the current task instance as finished at this very instant.
|
||||||
|
* This makes the viewer to splits the current fragment at this point and begin
|
||||||
|
* a new actor instance.
|
||||||
|
*
|
||||||
|
* See also USE_IMPLICIT_IFE_RULES in trcConfig.h
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* This example will generate two instances for each loop iteration.
|
||||||
|
* The first instance ends at vTraceInstanceFinishDirect(), while the second
|
||||||
|
* instance ends at the next xQueueReceive call.
|
||||||
|
*
|
||||||
|
* while (1)
|
||||||
|
* {
|
||||||
|
* xQueueReceive(CommandQueue, &command, timeoutDuration);
|
||||||
|
* ProcessCommand(command);
|
||||||
|
* vTraceInstanceFinishDirect();
|
||||||
|
* DoSometingElse();
|
||||||
|
* vTraceInstanceFinish();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Note: This is only supported in Tracealyzer tools v2.7 or later
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
void vTraceTaskInstanceFinishDirect(void)
|
||||||
|
{
|
||||||
|
prvTraceTaskInstanceFinish(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -289,7 +384,7 @@ static uint8_t isrstack[MAX_ISR_NESTING];
|
||||||
* {
|
* {
|
||||||
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd();
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* NOTE: To safely record ISRs, you need to make sure that all traced
|
* NOTE: To safely record ISRs, you need to make sure that all traced
|
||||||
|
@ -302,7 +397,6 @@ void vTraceSetISRProperties(objectHandleType handle, const char* name, char prio
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceSetISRProperties: Invalid value for handle", );
|
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceSetISRProperties: Invalid value for handle", );
|
||||||
TRACE_ASSERT(name != NULL, "vTraceSetISRProperties: name == NULL", );
|
TRACE_ASSERT(name != NULL, "vTraceSetISRProperties: name == NULL", );
|
||||||
TRACE_ASSERT(priority >= 0, "vTraceSetISRProperties: Invalid value for priority", );
|
|
||||||
|
|
||||||
vTraceSetObjectName(TRACE_CLASS_ISR, handle, name);
|
vTraceSetObjectName(TRACE_CLASS_ISR, handle, name);
|
||||||
vTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority);
|
vTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority);
|
||||||
|
@ -339,6 +433,10 @@ void vTraceSetISRProperties(objectHandleType handle, const char* name, char prio
|
||||||
* If this value is set too high, you get the opposite effect - separate ISRs
|
* If this value is set too high, you get the opposite effect - separate ISRs
|
||||||
* will appear to execute tail-chained and will appear to have higher execution
|
* will appear to execute tail-chained and will appear to have higher execution
|
||||||
* time and response time (maximum ISR_TAILCHAINING_THRESHOLD cycles more).
|
* time and response time (maximum ISR_TAILCHAINING_THRESHOLD cycles more).
|
||||||
|
*
|
||||||
|
* Read the blog post explaining this on our website:
|
||||||
|
* http://percepio.com/2014/05/06/sw-based-exc-tracing-arm-cortex-m/
|
||||||
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define ISR_TAILCHAINING_THRESHOLD 66
|
#define ISR_TAILCHAINING_THRESHOLD 66
|
||||||
|
|
||||||
|
@ -350,7 +448,7 @@ uint32_t DWTCycleCountAtLastISRExit = 0;
|
||||||
*
|
*
|
||||||
* MEASURE_ISR_TAILCHAINING_THRESHOLD (For Cortex-M devices only)
|
* MEASURE_ISR_TAILCHAINING_THRESHOLD (For Cortex-M devices only)
|
||||||
*
|
*
|
||||||
* Allows for measuring the value of ISR_TAILCHAINING_THRESHOLD (see above).
|
* Allows for calibrating the value of ISR_TAILCHAINING_THRESHOLD (see above).
|
||||||
*
|
*
|
||||||
* This is intended to measure the minimum number of clock cycles from the end
|
* This is intended to measure the minimum number of clock cycles from the end
|
||||||
* of vTraceStoreISREnd to the beginning of the following vTraceStoreISRBegin.
|
* of vTraceStoreISREnd to the beginning of the following vTraceStoreISRBegin.
|
||||||
|
@ -365,13 +463,12 @@ uint32_t DWTCycleCountAtLastISRExit = 0;
|
||||||
* void xPortSysTickHandler( void )
|
* void xPortSysTickHandler( void )
|
||||||
* {
|
* {
|
||||||
* vTraceStoreISRBegin(1);
|
* vTraceStoreISRBegin(1);
|
||||||
* vTraceStoreISREnd();
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* 3. To make sure that the ISRs execute back-to-back, increase the OS tick
|
* 3. To make sure that the ISRs execute back-to-back, increase the OS tick
|
||||||
* frequency to a very high level so that the OS tick interrupt execute
|
* frequency to a very high level so that the OS tick interrupt execute
|
||||||
* continuously with no application tasks in between. A tick frequency of
|
* continuously with no application tasks in between, e.g. 10 MHz.
|
||||||
* 1 MHz (1.000.000) should be sufficient.
|
|
||||||
*
|
*
|
||||||
* 4. Put a breakpoint in the highest priority task and make sure it is not
|
* 4. Put a breakpoint in the highest priority task and make sure it is not
|
||||||
* reached. This means that the SysTick handler is executing at maximum rate
|
* reached. This means that the SysTick handler is executing at maximum rate
|
||||||
|
@ -393,9 +490,13 @@ uint32_t DWTCycleCountAtLastISRExit = 0;
|
||||||
* Cortex-M0+ (HL = 15): 72 cycles
|
* Cortex-M0+ (HL = 15): 72 cycles
|
||||||
*
|
*
|
||||||
* If the ISR_TAILCHAINING_THRESHOLD value is set too low, some tail-chained
|
* If the ISR_TAILCHAINING_THRESHOLD value is set too low, some tail-chained
|
||||||
* ISRs be shown separated, with a short fragment of the previous actor. If
|
* ISRs be shown separated, with a short fragment of the previous context
|
||||||
* the value is set too high, separate ISRs will appear to execute tail-chained
|
* in between. On the other hand, if the value is set too high, ISRs that
|
||||||
* and for too long time.
|
* actually are separated may appear to execute back-to-back (tail-chained).
|
||||||
|
*
|
||||||
|
* Read the blog post explaining this on our website:
|
||||||
|
* http://percepio.com/2014/05/06/sw-based-exc-tracing-arm-cortex-m/
|
||||||
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define MEASURE_ISR_TAILCHAINING_THRESHOLD 1
|
#define MEASURE_ISR_TAILCHAINING_THRESHOLD 1
|
||||||
|
|
||||||
|
@ -420,7 +521,7 @@ volatile uint32_t threshold_low_watermark = 2000000000;
|
||||||
* {
|
* {
|
||||||
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd();
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -428,7 +529,7 @@ void vTraceStoreISRBegin(objectHandleType handle)
|
||||||
{
|
{
|
||||||
uint16_t dts4;
|
uint16_t dts4;
|
||||||
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
||||||
uint32_t CPUCyclesSinceLastISRExit = DWT_CYCLE_COUNTER - DWTCycleCountAtLastISRExit;
|
uint32_t CPUCyclesSinceLastISRExit = REG_DWT_CYCCNT - DWTCycleCountAtLastISRExit;
|
||||||
#endif
|
#endif
|
||||||
TSEvent* ts;
|
TSEvent* ts;
|
||||||
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
TRACE_SR_ALLOC_CRITICAL_SECTION();
|
||||||
|
@ -507,7 +608,11 @@ void vTraceStoreISRBegin(objectHandleType handle)
|
||||||
*
|
*
|
||||||
* Registers the end of an Interrupt Service Routine.
|
* Registers the end of an Interrupt Service Routine.
|
||||||
*
|
*
|
||||||
|
* The parameter pendingISR indicates if the interrupt has requested a
|
||||||
|
* task-switch (= 1) or if the interrupt returns to the earlier context (= 0)
|
||||||
|
*
|
||||||
* Example:
|
* Example:
|
||||||
|
*
|
||||||
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
|
* #define ID_ISR_TIMER1 1 // lowest valid ID is 1
|
||||||
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
|
* #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt
|
||||||
* ...
|
* ...
|
||||||
|
@ -517,11 +622,11 @@ void vTraceStoreISRBegin(objectHandleType handle)
|
||||||
* {
|
* {
|
||||||
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
* vTraceStoreISRBegin(ID_OF_ISR_TIMER1);
|
||||||
* ...
|
* ...
|
||||||
* vTraceStoreISREnd();
|
* vTraceStoreISREnd(0);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceStoreISREnd(void)
|
void vTraceStoreISREnd(int pendingISR)
|
||||||
{
|
{
|
||||||
TSEvent* ts;
|
TSEvent* ts;
|
||||||
uint16_t dts5;
|
uint16_t dts5;
|
||||||
|
@ -534,13 +639,12 @@ void vTraceStoreISREnd(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
trcCRITICAL_SECTION_BEGIN();
|
trcCRITICAL_SECTION_BEGIN();
|
||||||
|
if (pendingISR == 0)
|
||||||
|
{
|
||||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
|
||||||
{
|
|
||||||
dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
{
|
||||||
uint8_t hnd8, type;
|
uint8_t hnd8, type;
|
||||||
|
dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||||
|
|
||||||
if (nISRactive > 1)
|
if (nISRactive > 1)
|
||||||
{
|
{
|
||||||
|
@ -556,24 +660,26 @@ void vTraceStoreISREnd(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
|
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
|
||||||
|
|
||||||
if (ts != NULL)
|
if (ts != NULL)
|
||||||
{
|
{
|
||||||
ts->type = type;
|
ts->type = type;
|
||||||
ts->objHandle = hnd8;
|
ts->objHandle = hnd8;
|
||||||
ts->dts = dts5;
|
ts->dts = dts5;
|
||||||
nISRactive--;
|
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
||||||
/* Remember the last ISR exit event, as the event needs to be modified in case of a following ISR entry (if tail-chained ISRs) */
|
/* Remember the last ISR exit event, as the event needs to be modified in case of a following ISR entry (if tail-chained ISRs) */
|
||||||
ptrLastISRExitEvent = (uint8_t*)ts;
|
ptrLastISRExitEvent = (uint8_t*)ts;
|
||||||
DWTCycleCountAtLastISRExit = DWT_CYCLE_COUNTER;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
nISRactive--;
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_ARM_CortexM)
|
||||||
|
DWTCycleCountAtLastISRExit = REG_DWT_CYCCNT;
|
||||||
|
#endif
|
||||||
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,9 +700,9 @@ void vTraceDecreaseISRActive(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/********************************************************************************/
|
||||||
* User Event functions
|
/* User Event functions */
|
||||||
******************************************************************************/
|
/********************************************************************************/
|
||||||
|
|
||||||
#if (INCLUDE_USER_EVENTS == 1)
|
#if (INCLUDE_USER_EVENTS == 1)
|
||||||
|
|
||||||
|
@ -707,10 +813,11 @@ static uint8_t writeFloat(void * buffer, uint8_t i, float value)
|
||||||
/*** Locally used in vTracePrintF ***/
|
/*** Locally used in vTracePrintF ***/
|
||||||
static uint8_t writeDouble(void * buffer, uint8_t i, double value)
|
static uint8_t writeDouble(void * buffer, uint8_t i, double value)
|
||||||
{
|
{
|
||||||
|
uint32_t * dest;
|
||||||
|
uint32_t * src = (uint32_t*)&value;
|
||||||
|
|
||||||
TRACE_ASSERT(buffer != NULL, "writeDouble: buffer == NULL", 0);
|
TRACE_ASSERT(buffer != NULL, "writeDouble: buffer == NULL", 0);
|
||||||
|
|
||||||
uint32_t * dest;
|
|
||||||
uint32_t * src = (void*)&value;
|
|
||||||
/* The double is written as two 32 bit values, and should begin at an even
|
/* The double is written as two 32 bit values, and should begin at an even
|
||||||
4-byte address (to avoid having to align with 8 byte) */
|
4-byte address (to avoid having to align with 8 byte) */
|
||||||
while (i % 4 != 0)
|
while (i % 4 != 0)
|
||||||
|
@ -729,7 +836,7 @@ static uint8_t writeDouble(void * buffer, uint8_t i, double value)
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest = &(((uint32_t *)buffer)[i]);
|
dest = &(((uint32_t *)buffer)[i/4]);
|
||||||
|
|
||||||
dest[0] = src[0];
|
dest[0] = src[0];
|
||||||
dest[1] = src[1];
|
dest[1] = src[1];
|
||||||
|
@ -762,28 +869,28 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* These below code writes raw data (primitive datatypes) in the event buffer,
|
* These below code writes raw data (primitive datatypes) in the event buffer,
|
||||||
* instead of the normal event structs (where byte 0 is event type).
|
* instead of the normal event structs (where byte 0 is event type).
|
||||||
* These data entries must never be interpreted as real event data, as the type
|
* These data entries must never be interpreted as real event data, as the type
|
||||||
* field would be misleading since used for payload data.
|
* field would be misleading since used for payload data.
|
||||||
*
|
*
|
||||||
* The correctness of this encoding depends on two mechanisms:
|
* The correctness of this encoding depends on two mechanisms:
|
||||||
*
|
*
|
||||||
* 1. An initial USER_EVENT, which type code tells the number of 32-bit data
|
* 1. An initial USER_EVENT, which type code tells the number of 32-bit data
|
||||||
* entires that follows. (code - USER_EVENT = number of data entries).
|
* entires that follows. (code - USER_EVENT = number of data entries).
|
||||||
* Note that a data entry corresponds to the slots that normally corresponds to
|
* Note that a data entry corresponds to the slots that normally corresponds to
|
||||||
* one (1) event, i.e., 32 bits. vTracePrintF may encode several pieces of data
|
* one (1) event, i.e., 32 bits. vTracePrintF may encode several pieces of data
|
||||||
* in one data entry, e.g., two 16-bit values or four 8-bit values, one 16-bit
|
* in one data entry, e.g., two 16-bit values or four 8-bit values, one 16-bit
|
||||||
* value followed by two 8-bit values, etc.
|
* value followed by two 8-bit values, etc.
|
||||||
*
|
*
|
||||||
* 2. A two-phase commit procedure, where the USER_EVENT and data entries are
|
* 2. A two-phase commit procedure, where the USER_EVENT and data entries are
|
||||||
* written to a local buffer at first, and when all checks are OK then copied to
|
* written to a local buffer at first, and when all checks are OK then copied to
|
||||||
* the main event buffer using a fast memcpy. The event code is finalized as the
|
* the main event buffer using a fast memcpy. The event code is finalized as the
|
||||||
* very last step. Before that step, the event code indicates an unfinished
|
* very last step. Before that step, the event code indicates an unfinished
|
||||||
* event, which causes it to be ignored and stop the loading of the file (since
|
* event, which causes it to be ignored and stop the loading of the file (since
|
||||||
* an unfinished event is the last event in the trace).
|
* an unfinished event is the last event in the trace).
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
formatStrIndex++;
|
formatStrIndex++;
|
||||||
|
|
||||||
while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.')
|
while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.')
|
||||||
|
@ -793,17 +900,17 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
{
|
{
|
||||||
switch (formatStr[formatStrIndex])
|
switch (formatStr[formatStrIndex])
|
||||||
{
|
{
|
||||||
case 'd': i = writeInt32(buffer,
|
case 'd': i = writeInt32( buffer,
|
||||||
i,
|
i,
|
||||||
(uint32_t)va_arg(vl, uint32_t));
|
(uint32_t)va_arg(vl, uint32_t));
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'u': i = writeInt32(buffer,
|
case 'u': i = writeInt32( buffer,
|
||||||
i,
|
i,
|
||||||
(uint32_t)va_arg(vl, uint32_t));
|
(uint32_t)va_arg(vl, uint32_t));
|
||||||
break;
|
break;
|
||||||
case 's': i = writeInt16(buffer,
|
case 's': i = writeInt16( buffer,
|
||||||
i,
|
i,
|
||||||
(uint16_t)xTraceOpenLabel((char*)va_arg(vl, char*)));
|
(uint16_t)xTraceOpenLabel((char*)va_arg(vl, char*)));
|
||||||
break;
|
break;
|
||||||
|
@ -812,7 +919,7 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
/* Yes, "double" as type also in the float
|
/* Yes, "double" as type also in the float
|
||||||
case. This since "float" is promoted into "double"
|
case. This since "float" is promoted into "double"
|
||||||
by the va_arg stuff. */
|
by the va_arg stuff. */
|
||||||
case 'f': i = writeFloat(buffer,
|
case 'f': i = writeFloat( buffer,
|
||||||
i,
|
i,
|
||||||
(float)va_arg(vl, double));
|
(float)va_arg(vl, double));
|
||||||
break;
|
break;
|
||||||
|
@ -822,7 +929,7 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
data on uint_32 format (will not be displayed anyway). This is just
|
data on uint_32 format (will not be displayed anyway). This is just
|
||||||
to keep va_arg and i consistent. */
|
to keep va_arg and i consistent. */
|
||||||
|
|
||||||
case 'f': i = writeInt32(buffer,
|
case 'f': i = writeInt32( buffer,
|
||||||
i,
|
i,
|
||||||
(uint32_t)va_arg(vl, double));
|
(uint32_t)va_arg(vl, double));
|
||||||
break;
|
break;
|
||||||
|
@ -841,10 +948,11 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
avoid a possible crash due to float reference. Instead store the
|
avoid a possible crash due to float reference. Instead store the
|
||||||
data on uint_32 format (will not be displayed anyway). This is just
|
data on uint_32 format (will not be displayed anyway). This is just
|
||||||
to keep va_arg and i consistent. */
|
to keep va_arg and i consistent. */
|
||||||
case 'f': i = writeInt32(buffer, /* In this case, the value will not be shown anyway */
|
case 'f': i = writeInt32( buffer, /* In this case, the value will not be shown anyway */
|
||||||
i,
|
i,
|
||||||
(uint32_t)va_arg(vl, double));
|
(uint32_t)va_arg(vl, double));
|
||||||
i = writeInt32(buffer, /* Do it twice, to write in total 8 bytes */
|
|
||||||
|
i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */
|
||||||
i,
|
i,
|
||||||
(uint32_t)va_arg(vl, double));
|
(uint32_t)va_arg(vl, double));
|
||||||
break;
|
break;
|
||||||
|
@ -856,11 +964,11 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
formatStrIndex++;
|
formatStrIndex++;
|
||||||
switch (formatStr[formatStrIndex])
|
switch (formatStr[formatStrIndex])
|
||||||
{
|
{
|
||||||
case 'd': i = writeInt16(buffer,
|
case 'd': i = writeInt16( buffer,
|
||||||
i,
|
i,
|
||||||
(uint16_t)va_arg(vl, uint32_t));
|
(uint16_t)va_arg(vl, uint32_t));
|
||||||
break;
|
break;
|
||||||
case 'u': i = writeInt16(buffer,
|
case 'u': i = writeInt16( buffer,
|
||||||
i,
|
i,
|
||||||
(uint16_t)va_arg(vl, uint32_t));
|
(uint16_t)va_arg(vl, uint32_t));
|
||||||
break;
|
break;
|
||||||
|
@ -870,11 +978,12 @@ static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_
|
||||||
formatStrIndex++;
|
formatStrIndex++;
|
||||||
switch (formatStr[formatStrIndex])
|
switch (formatStr[formatStrIndex])
|
||||||
{
|
{
|
||||||
case 'd': i = writeInt8(buffer,
|
case 'd': i = writeInt8( buffer,
|
||||||
i,
|
i,
|
||||||
(uint8_t)va_arg(vl, uint32_t));
|
(uint8_t)va_arg(vl, uint32_t));
|
||||||
break;
|
break;
|
||||||
case 'u': i = writeInt8(buffer,
|
|
||||||
|
case 'u': i = writeInt8( buffer,
|
||||||
i,
|
i,
|
||||||
(uint8_t)va_arg(vl, uint32_t));
|
(uint8_t)va_arg(vl, uint32_t));
|
||||||
break;
|
break;
|
||||||
|
@ -906,7 +1015,8 @@ static void prvTraceClearChannelBuffer(uint32_t count)
|
||||||
{
|
{
|
||||||
uint32_t slots;
|
uint32_t slots;
|
||||||
|
|
||||||
TRACE_ASSERT(USER_EVENT_BUFFER_SIZE >= count, "prvTraceClearChannelBuffer: USER_EVENT_BUFFER_SIZE is too small to handle this event.", );
|
TRACE_ASSERT(USER_EVENT_BUFFER_SIZE >= count,
|
||||||
|
"prvTraceClearChannelBuffer: USER_EVENT_BUFFER_SIZE is too small to handle this event.", );
|
||||||
|
|
||||||
/* Check if we're close to the end of the buffer */
|
/* Check if we're close to the end of the buffer */
|
||||||
if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > USER_EVENT_BUFFER_SIZE)
|
if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > USER_EVENT_BUFFER_SIZE)
|
||||||
|
@ -926,8 +1036,10 @@ static void prvTraceClearChannelBuffer(uint32_t count)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count)
|
static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count)
|
||||||
{
|
{
|
||||||
TRACE_ASSERT(data != NULL, "prvTraceCopyToDataBuffer: data == NULL.", );
|
TRACE_ASSERT(data != NULL,
|
||||||
TRACE_ASSERT(count <= USER_EVENT_BUFFER_SIZE, "prvTraceCopyToDataBuffer: USER_EVENT_BUFFER_SIZE is too small to handle this event.", );
|
"prvTraceCopyToDataBuffer: data == NULL.", );
|
||||||
|
TRACE_ASSERT(count <= USER_EVENT_BUFFER_SIZE,
|
||||||
|
"prvTraceCopyToDataBuffer: USER_EVENT_BUFFER_SIZE is too small to handle this event.", );
|
||||||
|
|
||||||
uint32_t slots;
|
uint32_t slots;
|
||||||
/* Check if we're close to the end of the buffer */
|
/* Check if we're close to the end of the buffer */
|
||||||
|
@ -946,7 +1058,8 @@ static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* prvTraceUserEventHelper1
|
* prvTraceUserEventHelper1
|
||||||
*
|
*
|
||||||
* Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on to the next helper function.
|
* Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on
|
||||||
|
* to the next helper function.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static void prvTraceUserEventHelper1(UserEventChannel channel, traceLabel eventLabel, traceLabel formatLabel, va_list vl)
|
static void prvTraceUserEventHelper1(UserEventChannel channel, traceLabel eventLabel, traceLabel formatLabel, va_list vl)
|
||||||
{
|
{
|
||||||
|
@ -984,7 +1097,10 @@ static void prvTraceUserEventHelper2(UserEventChannel channel, uint32_t* data, u
|
||||||
vTracePortGetTimeStamp(data);
|
vTracePortGetTimeStamp(data);
|
||||||
|
|
||||||
if (*data < old_timestamp)
|
if (*data < old_timestamp)
|
||||||
|
{
|
||||||
RecorderDataPtr->userEventBuffer.wraparoundCounter++;
|
RecorderDataPtr->userEventBuffer.wraparoundCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
old_timestamp = *data;
|
old_timestamp = *data;
|
||||||
|
|
||||||
/* Start by erasing any information in the channel buffer */
|
/* Start by erasing any information in the channel buffer */
|
||||||
|
@ -997,9 +1113,14 @@ static void prvTraceUserEventHelper2(UserEventChannel channel, uint32_t* data, u
|
||||||
|
|
||||||
/* Write to the channel buffer to indicate that this user event is ready to be used */
|
/* Write to the channel buffer to indicate that this user event is ready to be used */
|
||||||
if (channel != 0)
|
if (channel != 0)
|
||||||
|
{
|
||||||
RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = channel;
|
RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = channel;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = (UserEventChannel)0xFF; /* 0xFF indicates that this is not a normal channel id */
|
{
|
||||||
|
/* 0xFF indicates that this is not a normal channel id */
|
||||||
|
RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = (UserEventChannel)0xFF;
|
||||||
|
}
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1052,11 +1173,13 @@ UserEventChannel xTraceRegisterChannelFormat(traceLabel channel, traceLabel form
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceChannelPrintF(UserEventChannel channelPair, ...)
|
void vTraceChannelPrintF(UserEventChannel channelPair, ...)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
va_list vl;
|
va_list vl;
|
||||||
|
|
||||||
va_start(vl, channelPair);
|
va_start(vl, channelPair);
|
||||||
vTraceChannelPrintF_Helper(channelPair, vl);
|
vTraceChannelPrintF_Helper(channelPair, vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vTraceChannelPrintF_Helper(UserEventChannel channelPair, va_list vl)
|
void vTraceChannelPrintF_Helper(UserEventChannel channelPair, va_list vl)
|
||||||
|
@ -1080,16 +1203,18 @@ void vTraceChannelPrintF_Helper(UserEventChannel channelPair, va_list vl)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceChannelUserEvent(UserEventChannel channelPair)
|
void vTraceChannelUserEvent(UserEventChannel channelPair)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
uint32_t data[(3 + MAX_ARG_SIZE) / 4];
|
uint32_t data[(3 + MAX_ARG_SIZE) / 4];
|
||||||
|
|
||||||
TRACE_ASSERT(channelPair != 0, "vTraceChannelPrintF: channelPair == 0", );
|
TRACE_ASSERT(channelPair != 0, "vTraceChannelPrintF: channelPair == 0", );
|
||||||
TRACE_ASSERT(channelPair <= CHANNEL_FORMAT_PAIRS, "vTraceChannelPrintF: ", );
|
TRACE_ASSERT(channelPair <= CHANNEL_FORMAT_PAIRS, "vTraceChannelPrintF: ", );
|
||||||
|
|
||||||
prvTraceUserEventHelper2(channelPair, data, 1); /* Only need one slot for timestamp */
|
prvTraceUserEventHelper2(channelPair, data, 1); /* Only need one slot for timestamp */
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
#endif /* USE_SEPARATE_USER_EVENT_BUFFER == 1 */
|
#endif /* USE_SEPARATE_USER_EVENT_BUFFER == 1 */
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* vTracePrintF
|
* vTracePrintF
|
||||||
*
|
*
|
||||||
* Advanced user events (Professional Edition only)
|
* Advanced user events (Professional Edition only)
|
||||||
|
@ -1128,25 +1253,32 @@ void vTraceChannelUserEvent(UserEventChannel channelPair)
|
||||||
* %hu - 16 bit unsigned integer
|
* %hu - 16 bit unsigned integer
|
||||||
* %bd - 8 bit signed integer
|
* %bd - 8 bit signed integer
|
||||||
* %bu - 8 bit unsigned integer
|
* %bu - 8 bit unsigned integer
|
||||||
* %lf - double-precision float
|
* %lf - double-precision float (Note! See below...)
|
||||||
*
|
*
|
||||||
* Up to 15 data arguments are allowed, with a total size of maximum 32 byte.
|
* 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.
|
* 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
|
* 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.
|
* 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
|
* A string requires two bytes, as the symbol table is limited to 64K. Storing
|
||||||
* double (%lf) uses two records, so this is quite costly. Use float (%f) unless
|
* a double (%lf) uses two records, so this is quite costly. Use float (%f)
|
||||||
* the higher precision is really necessary.
|
* 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. PIC24 and PIC32.
|
||||||
|
* 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, ...)
|
void vTracePrintF(traceLabel eventLabel, const char* formatStr, ...)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
va_list vl;
|
va_list vl;
|
||||||
|
|
||||||
va_start(vl, formatStr);
|
va_start(vl, formatStr);
|
||||||
vTracePrintF_Helper(eventLabel, formatStr, vl);
|
vTracePrintF_Helper(eventLabel, formatStr, vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
void vTracePrintF_Helper(traceLabel eventLabel, const char* formatStr, va_list vl)
|
void vTracePrintF_Helper(traceLabel eventLabel, const char* formatStr, va_list vl)
|
||||||
|
@ -1248,14 +1380,6 @@ void vTracePrintF_Helper(traceLabel eventLabel, const char* formatStr, va_list v
|
||||||
vTraceStop();
|
vTraceStop();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (STOP_AFTER_N_EVENTS > -1)
|
|
||||||
/* Check if we have reached the desired number of events */
|
|
||||||
if (RecorderDataPtr->numEvents >= STOP_AFTER_N_EVENTS)
|
|
||||||
{
|
|
||||||
vTraceStop();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (TRACE_RECORDER_STORE_MODE == TRACE_STORE_MODE_RING_BUFFER)
|
#if (TRACE_RECORDER_STORE_MODE == TRACE_STORE_MODE_RING_BUFFER)
|
||||||
|
@ -1293,6 +1417,7 @@ void vTracePrintF_Helper(traceLabel eventLabel, const char* formatStr, va_list v
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void vTraceUserEvent(traceLabel eventLabel)
|
void vTraceUserEvent(traceLabel eventLabel)
|
||||||
{
|
{
|
||||||
|
#if (TRACE_SCHEDULING_ONLY == 0)
|
||||||
#if (USE_SEPARATE_USER_EVENT_BUFFER == 0)
|
#if (USE_SEPARATE_USER_EVENT_BUFFER == 0)
|
||||||
UserEvent* ue;
|
UserEvent* ue;
|
||||||
uint8_t dts1;
|
uint8_t dts1;
|
||||||
|
@ -1304,9 +1429,6 @@ void vTraceUserEvent(traceLabel eventLabel)
|
||||||
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
if (RecorderDataPtr->recorderActive && (! inExcludedTask || nISRactive) && handle_of_last_logged_task)
|
||||||
{
|
{
|
||||||
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
dts1 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||||
|
|
||||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
|
||||||
{
|
|
||||||
ue = (UserEvent*) xTraceNextFreeEventBufferSlot();
|
ue = (UserEvent*) xTraceNextFreeEventBufferSlot();
|
||||||
if (ue != NULL)
|
if (ue != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1316,7 +1438,6 @@ void vTraceUserEvent(traceLabel eventLabel)
|
||||||
prvTraceUpdateCounters();
|
prvTraceUpdateCounters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
trcCRITICAL_SECTION_END();
|
trcCRITICAL_SECTION_END();
|
||||||
|
|
||||||
#elif (USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
#elif (USE_SEPARATE_USER_EVENT_BUFFER == 1)
|
||||||
|
@ -1338,6 +1459,7 @@ void vTraceUserEvent(traceLabel eventLabel)
|
||||||
prvTraceUserEventHelper2(channel, tempDataBuffer, noOfSlots);
|
prvTraceUserEventHelper2(channel, tempDataBuffer, noOfSlots);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* TRACE_SCHEDULING_ONLY */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* See the following URL for an exaplanation of this file:
|
* See the following URL for an explanation of this file:
|
||||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* See the following URL for an exaplanation of this file:
|
* See the following URL for an explanation of this file:
|
||||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* See the following URL for an exaplanation of this file:
|
* See the following URL for an explanation of this file:
|
||||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* See the following URL for an exaplanation of this file:
|
* See the following URL for an explanation of this file:
|
||||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* See the following URL for an exaplanation of this file:
|
* See the following URL for an explanation of this file:
|
||||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* See the following URL for an exaplanation of this file:
|
* See the following URL for an explanation of this file:
|
||||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Compiler_Porting.shtml
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
|
@ -132,7 +132,7 @@ BaseType_t xStatus;
|
||||||
XUartPs_Config *pxConfig;
|
XUartPs_Config *pxConfig;
|
||||||
|
|
||||||
/* Create the queue used to hold received characters. NOTE THE COMMENTS AT
|
/* Create the queue used to hold received characters. NOTE THE COMMENTS AT
|
||||||
THE TOP OF THIS FILE REGARDING THE QUEUE OF QUEUES FOR THIS PURPSOE. */
|
THE TOP OF THIS FILE REGARDING THE USE OF QUEUES FOR THIS PURPSOE. */
|
||||||
xRxQueue = xQueueCreate( uxQueueLength, sizeof( char ) );
|
xRxQueue = xQueueCreate( uxQueueLength, sizeof( char ) );
|
||||||
configASSERT( xRxQueue );
|
configASSERT( xRxQueue );
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ extern void vRegisterSampleCLICommands( void );
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Get the next output string from the command interpreter. */
|
/* Get the next output string from the command interpreter. */
|
||||||
xReturned = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
|
xReturned = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_INPUT_SIZE );
|
||||||
lwip_send( lClientFd, cOutputString, strlen( ( const char * ) cOutputString ), 0 );
|
lwip_send( lClientFd, cOutputString, strlen( ( const char * ) cOutputString ), 0 );
|
||||||
|
|
||||||
} while( xReturned != pdFALSE );
|
} while( xReturned != pdFALSE );
|
||||||
|
|
|
@ -145,7 +145,7 @@ static void prvSetupHardware( void );
|
||||||
extern void main_lwIP( void );
|
extern void main_lwIP( void );
|
||||||
#else
|
#else
|
||||||
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
|
#error Invalid mainSELECTED_APPLICATION setting. See the comments at the top of this file and above the mainSELECTED_APPLICATION definition.
|
||||||
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Xilinx projects use a BSP that do not allow the start up code to be
|
* The Xilinx projects use a BSP that do not allow the start up code to be
|
||||||
|
|
505
FreeRTOS/Demo/Common/Minimal/TaskNotify.c
Normal file
505
FreeRTOS/Demo/Common/Minimal/TaskNotify.c
Normal file
|
@ -0,0 +1,505 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the behaviour of direct task notifications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
|
||||||
|
#define notifyTASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of the task that gets notified.
|
||||||
|
*/
|
||||||
|
static void prvNotifiedTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Performs a few initial tests that can be done prior to creating the second
|
||||||
|
* task.
|
||||||
|
*/
|
||||||
|
static void prvSingleTaskTests( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Software timer callback function from which xTaskNotify() is called.
|
||||||
|
*/
|
||||||
|
static void prvNotifyingTimer( TimerHandle_t xTimer );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility function to create pseudo random numbers.
|
||||||
|
*/
|
||||||
|
static UBaseType_t prvRand( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Used to latch errors during the test's execution. */
|
||||||
|
static BaseType_t xErrorStatus = pdPASS;
|
||||||
|
|
||||||
|
/* Used to ensure the task has not stalled. */
|
||||||
|
static volatile uint32_t ulNotifyCycleCount = 0;
|
||||||
|
|
||||||
|
/* The handle of the task that receives the notifications. */
|
||||||
|
static TaskHandle_t xTaskToNotify = NULL;
|
||||||
|
|
||||||
|
/* Used to count the notifications sent to the task from a software timer and
|
||||||
|
the number of notifications received by the task from the software timer. The
|
||||||
|
two should stay synchronised. */
|
||||||
|
static uint32_t ulTimerNotificationsReceived = 0UL, ulTimerNotificationsSent = 0UL;
|
||||||
|
|
||||||
|
/* The timer used to notify the task. */
|
||||||
|
static TimerHandle_t xTimer = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartTaskNotifyTask( void )
|
||||||
|
{
|
||||||
|
/* Create the task that performs some tests by itself, then loops around
|
||||||
|
being notified by both a software timer and an interrupt. */
|
||||||
|
xTaskCreate( prvNotifiedTask, "Notified", configMINIMAL_STACK_SIZE, NULL, notifyTASK_PRIORITY, &xTaskToNotify );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSingleTaskTests( void )
|
||||||
|
{
|
||||||
|
const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );
|
||||||
|
BaseType_t xReturned;
|
||||||
|
uint32_t ulNotifiedValue, ulLoop, ulNotifyingValue;
|
||||||
|
TickType_t xTimeOnEntering;
|
||||||
|
const uint32_t ulFirstNotifiedConst = 100001UL, ulSecondNotifiedValueConst = 5555UL, ulMaxLoops = 5UL;
|
||||||
|
const uint32_t ulBit0 = 0x01UL, ulBit1 = 0x02UL;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
Check blocking when there are no notifications. */
|
||||||
|
xTimeOnEntering = xTaskGetTickCount();
|
||||||
|
xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, xTicksToWait );
|
||||||
|
|
||||||
|
/* Should have blocked for the entire block time. */
|
||||||
|
if( ( xTaskGetTickCount() - xTimeOnEntering ) < xTicksToWait )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
configASSERT( ulNotifiedValue == 0UL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
Check no blocking when notifications are pending. First notify itself -
|
||||||
|
this would not be a normal thing to do and is done here for test purposes
|
||||||
|
only. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite );
|
||||||
|
|
||||||
|
/* Even through the 'without overwrite' action was used the update should
|
||||||
|
have been successful. */
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
|
||||||
|
/* The task should now have a notification pending, and so not time out. */
|
||||||
|
xTimeOnEntering = xTaskGetTickCount();
|
||||||
|
xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, xTicksToWait );
|
||||||
|
|
||||||
|
if( ( xTaskGetTickCount() - xTimeOnEntering ) >= xTicksToWait )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task should have been notified, and the notified value should
|
||||||
|
be equal to ulFirstNotifiedConst. */
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ulFirstNotifiedConst );
|
||||||
|
|
||||||
|
/* Incremented to show the task is still running. */
|
||||||
|
ulNotifyCycleCount++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check the non-overwriting functionality. The notification is done twice
|
||||||
|
using two different notification values. The action says don't overwrite so
|
||||||
|
only the first notification should pass and the value read back should also
|
||||||
|
be that used with the first notification. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithoutOverwrite );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
|
||||||
|
/* Waiting for the notification should now return immediately so a block
|
||||||
|
time of zero is used. */
|
||||||
|
xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ulFirstNotifiedConst );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Do the same again, only this time use the overwriting version. This time
|
||||||
|
both notifications should pass, and the value written the second time should
|
||||||
|
overwrite the value written the first time, and so be the value that is read
|
||||||
|
back. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithOverwrite );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithOverwrite );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check notifications with no action pass without updating the value. Even
|
||||||
|
though ulFirstNotifiedConst is used as the value the value read back should
|
||||||
|
remain at ulSecondNotifiedConst. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eNoAction );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check incrementing values. Send ulMaxLoop increment notifications, then
|
||||||
|
ensure the received value is as expected - which should be
|
||||||
|
ulSecondNotificationValueConst plus how ever many times to loop iterated. */
|
||||||
|
for( ulLoop = 0; ulLoop < ulMaxLoops; ulLoop++ )
|
||||||
|
{
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, 0, eIncrement );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
}
|
||||||
|
|
||||||
|
xReturned = xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ( ulSecondNotifiedValueConst + ulMaxLoops ) );
|
||||||
|
|
||||||
|
/* Should not be any notifications pending now. */
|
||||||
|
xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check all bits can be set by notifying the task with one additional bit set
|
||||||
|
on each notification, and exiting the loop when all the bits are found to be
|
||||||
|
set. As there are 32-bits the loop should execute 32 times before all the
|
||||||
|
bits are found to be set. */
|
||||||
|
ulNotifyingValue = 0x01;
|
||||||
|
ulLoop = 0;
|
||||||
|
|
||||||
|
/* Start with all bits clear. */
|
||||||
|
xTaskNotifyWait( ULONG_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Set the next bit in the task's notified value. */
|
||||||
|
xTaskNotify( xTaskToNotify, ulNotifyingValue, eSetBits );
|
||||||
|
|
||||||
|
/* Wait for the notified value - which of course will already be
|
||||||
|
available. Don't clear the bits on entry or exit as this loop is exited
|
||||||
|
when all the bits are set. */
|
||||||
|
xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
|
||||||
|
ulLoop++;
|
||||||
|
|
||||||
|
/* Use the next bit on the next iteration around this loop. */
|
||||||
|
ulNotifyingValue <<= 1UL;
|
||||||
|
|
||||||
|
} while ( ulNotifiedValue != ULONG_MAX );
|
||||||
|
|
||||||
|
/* As a 32-bit value was used the loop should have executed 32 times before
|
||||||
|
all the bits were set. */
|
||||||
|
configASSERT( ulLoop == 32 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check bits are cleared on entry but not on exit when a notification fails
|
||||||
|
to arrive before timing out - both with and without a timeout value. Wait
|
||||||
|
for the notification again - but this time it is not given by anything and
|
||||||
|
should return pdFAIL. The parameters are set to clear bit zero on entry and
|
||||||
|
bit one on exit. As no notification was received only the bit cleared on
|
||||||
|
entry should actually get cleared. */
|
||||||
|
xReturned = xTaskNotifyWait( ulBit0, ulBit1, &ulNotifiedValue, xTicksToWait );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
|
||||||
|
/* Notify the task with no action so as not to update the bits even though
|
||||||
|
ULONG_MAX is used as the notification value. */
|
||||||
|
xTaskNotify( xTaskToNotify, ULONG_MAX, eNoAction );
|
||||||
|
|
||||||
|
/* Reading back the value should should find bit 0 is clear, as this was
|
||||||
|
cleared on entry, but bit 1 is not clear as it will not have been cleared on
|
||||||
|
exit as no notification was received. */
|
||||||
|
xReturned = xTaskNotifyWait( 0x00UL, 0x00UL, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ( ULONG_MAX & ~ulBit0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Now try clearing the bit on exit. For that to happen a notification must be
|
||||||
|
received, so the task is notified first. */
|
||||||
|
xTaskNotify( xTaskToNotify, 0, eNoAction );
|
||||||
|
xTaskNotifyWait( 0x00, ulBit1, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
/* However as the bit is cleared on exit, after the returned notification
|
||||||
|
value is set, the returned notification value should not have the bit
|
||||||
|
cleared... */
|
||||||
|
configASSERT( ulNotifiedValue == ( ULONG_MAX & ~ulBit0 ) );
|
||||||
|
|
||||||
|
/* ...but reading the value back again should find that the bit was indeed
|
||||||
|
cleared internally. The returned value should be pdFAIL however as nothing
|
||||||
|
has notified the task in the mean time. */
|
||||||
|
xReturned = xTaskNotifyWait( 0x00, 0x00, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
configASSERT( ulNotifiedValue == ( ULONG_MAX & ~( ulBit0 | ulBit1 ) ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Incremented to show the task is still running. */
|
||||||
|
ulNotifyCycleCount++;
|
||||||
|
|
||||||
|
/* Leave all bits cleared. */
|
||||||
|
xTaskNotifyWait( ULONG_MAX, 0, NULL, 0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvNotifyingTimer( TimerHandle_t xTimer )
|
||||||
|
{
|
||||||
|
( void ) xTimer;
|
||||||
|
|
||||||
|
xTaskNotifyGive( xTaskToNotify );
|
||||||
|
|
||||||
|
/* This value is also incremented from an interrupt. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulTimerNotificationsSent++;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvNotifiedTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const TickType_t xMaxPeriod = pdMS_TO_TICKS( 90 ), xMinPeriod = pdMS_TO_TICKS( 10 ), xDontBlock = 0;
|
||||||
|
TickType_t xPeriod;
|
||||||
|
|
||||||
|
/* Remove compiler warnings about unused parameters. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Run a few tests that can be done from a single task before entering the
|
||||||
|
main loop. */
|
||||||
|
prvSingleTaskTests();
|
||||||
|
|
||||||
|
/* Create the software timer that is used to send notifications to this
|
||||||
|
task. Notifications are also received from an interrupt. */
|
||||||
|
xTimer = xTimerCreate( "Notifier", xMaxPeriod, pdFALSE, NULL, prvNotifyingTimer );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Start the timer again with a different period. Sometimes the period
|
||||||
|
will be higher than the tasks block time, sometimes it will be lower
|
||||||
|
than the tasks block time. */
|
||||||
|
xPeriod = prvRand() % xMaxPeriod;
|
||||||
|
if( xPeriod < xMinPeriod )
|
||||||
|
{
|
||||||
|
xPeriod = xMinPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
xTimerChangePeriod( xTimer, xPeriod, portMAX_DELAY );
|
||||||
|
xTimerStart( xTimer, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* Block waiting for the notification again with a different period.
|
||||||
|
Sometimes the period will be higher than the tasks block time, sometimes
|
||||||
|
it will be lower than the tasks block time. */
|
||||||
|
xPeriod = prvRand() % xMaxPeriod;
|
||||||
|
if( xPeriod < xMinPeriod )
|
||||||
|
{
|
||||||
|
xPeriod = xMinPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Block to wait for a notification but without clearing the
|
||||||
|
notification count, so only add one to the count of received
|
||||||
|
notifications as any other notifications will remain pending. */
|
||||||
|
if( ulTaskNotifyTake( pdFALSE, xPeriod ) != 0 )
|
||||||
|
{
|
||||||
|
ulTimerNotificationsReceived++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take a notification without clearing again, but this time without a
|
||||||
|
block time specified. */
|
||||||
|
if( ulTaskNotifyTake( pdFALSE, xDontBlock ) != 0 )
|
||||||
|
{
|
||||||
|
ulTimerNotificationsReceived++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the next notification from the timer, clearing all
|
||||||
|
notifications if one is received, so this time adding the total number
|
||||||
|
of notifications that were pending as none will be left pending after
|
||||||
|
the function call. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, xPeriod );
|
||||||
|
|
||||||
|
/* Wait for the next notification again, clearing all notifications if
|
||||||
|
one is received, but this time blocking indefinitely. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* Incremented to show the task is still running. */
|
||||||
|
ulNotifyCycleCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xNotifyTaskFromISR( void )
|
||||||
|
{
|
||||||
|
static BaseType_t xCallCount = 0;
|
||||||
|
const BaseType_t xCallInterval = pdMS_TO_TICKS( 50 );
|
||||||
|
|
||||||
|
/* The task performs some tests before starting the timer that gives the
|
||||||
|
notification from this interrupt. If the timer has not been created yet
|
||||||
|
then the initial tests have not yet completed and the notification should
|
||||||
|
not be sent. */
|
||||||
|
if( xTimer != NULL )
|
||||||
|
{
|
||||||
|
xCallCount++;
|
||||||
|
|
||||||
|
if( xCallCount >= xCallInterval )
|
||||||
|
{
|
||||||
|
/* It is time to 'give' the notification again. */
|
||||||
|
xCallCount = 0;
|
||||||
|
|
||||||
|
xTaskNotifyGiveFromISR( xTaskToNotify, NULL );
|
||||||
|
ulTimerNotificationsSent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check the created tasks are still running and have not
|
||||||
|
detected any errors. */
|
||||||
|
BaseType_t xAreTaskNotificationTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastNotifyCycleCount = 0;
|
||||||
|
const uint32_t ulMaxSendReceiveDeviation = 5UL;
|
||||||
|
|
||||||
|
/* Check the cycle count is still incrementing to ensure the task is still
|
||||||
|
actually running. */
|
||||||
|
if( ulLastNotifyCycleCount == ulNotifyCycleCount )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulLastNotifyCycleCount = ulNotifyCycleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the count of 'takes' from the software timer is keeping track with
|
||||||
|
the amount of 'gives'. */
|
||||||
|
if( ulTimerNotificationsSent > ulTimerNotificationsSent )
|
||||||
|
{
|
||||||
|
if( ( ulTimerNotificationsSent - ulTimerNotificationsReceived ) > ulMaxSendReceiveDeviation )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xErrorStatus;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static UBaseType_t prvRand( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulNextRand = ( uint32_t ) prvRand;
|
||||||
|
|
||||||
|
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
|
||||||
|
|
||||||
|
/* Utility function to generate a pseudo random number. */
|
||||||
|
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
|
||||||
|
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
|
@ -739,11 +739,16 @@ static TickType_t uxTick = ( TickType_t ) -1;
|
||||||
will expire when the kernel's tick count is (100 + xBasePeriod). For this
|
will expire when the kernel's tick count is (100 + xBasePeriod). For this
|
||||||
reason xMargin is used as an allowable margin for premature timer expiries
|
reason xMargin is used as an allowable margin for premature timer expiries
|
||||||
as well as late timer expiries. */
|
as well as late timer expiries. */
|
||||||
|
#ifdef _WINDOWS_
|
||||||
|
/* Windows is not real real time. */
|
||||||
|
const TickType_t xMargin = 20;
|
||||||
|
#else
|
||||||
const TickType_t xMargin = 6;
|
const TickType_t xMargin = 6;
|
||||||
|
#endif /* _WINDOWS_ */
|
||||||
#else
|
#else
|
||||||
#ifdef _WINDOWS_
|
#ifdef _WINDOWS_
|
||||||
/* Windows is not real real time. */
|
/* Windows is not real real time. */
|
||||||
const TickType_t xMargin = 10;
|
const TickType_t xMargin = 20;
|
||||||
#else
|
#else
|
||||||
const TickType_t xMargin = 4;
|
const TickType_t xMargin = 4;
|
||||||
#endif /* _WINDOWS_ */
|
#endif /* _WINDOWS_ */
|
||||||
|
|
76
FreeRTOS/Demo/Common/include/TaskNotify.h
Normal file
76
FreeRTOS/Demo/Common/include/TaskNotify.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TASK_NOTIFY_H
|
||||||
|
#define TASK_NOTIFY_H
|
||||||
|
|
||||||
|
void vStartTaskNotifyTask( void );
|
||||||
|
BaseType_t xAreTaskNotificationTasksStillRunning( void );
|
||||||
|
void xNotifyTaskFromISR( void );
|
||||||
|
|
||||||
|
#endif /* TASK_NOTIFY_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
#if (BCLK_PIN == 1)
|
#if (BCLK_PIN == 1)
|
||||||
#define PSTOP1_SCKCR 0x00800000L
|
#define PSTOP1_SCKCR 0x00800000L
|
||||||
#elif
|
#else
|
||||||
#define PSTOP1_SCKCR 0x00000000L
|
#define PSTOP1_SCKCR 0x00000000L
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -96,8 +96,8 @@
|
||||||
#include "rskrx64mdef.h"
|
#include "rskrx64mdef.h"
|
||||||
|
|
||||||
/* Set option bytes */
|
/* Set option bytes */
|
||||||
#pragma address OFS0_location = 0xFFFFFF8CUL
|
#pragma address OFS0_location 0xFFFFFF8CUL
|
||||||
#pragma address OFS1_location = 0xFFFFFF88UL
|
#pragma address OFS1_location 0xFFFFFF88UL
|
||||||
volatile const uint32_t OFS0_location = 0xFFFFFFFFUL;
|
volatile const uint32_t OFS0_location = 0xFFFFFFFFUL;
|
||||||
volatile const uint32_t OFS1_location = 0xFFFFFFFFUL;
|
volatile const uint32_t OFS1_location = 0xFFFFFFFFUL;
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
#define configUSE_TICK_HOOK 1
|
#define configUSE_TICK_HOOK 1
|
||||||
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
|
||||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 22 * 1024 ) )
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 23 * 1024 ) )
|
||||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||||
#define configUSE_TRACE_FACILITY 1
|
#define configUSE_TRACE_FACILITY 1
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
@ -97,6 +97,7 @@
|
||||||
#define configUSE_COUNTING_SEMAPHORES 1
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
#define configUSE_ALTERNATIVE_API 1
|
#define configUSE_ALTERNATIVE_API 1
|
||||||
#define configUSE_QUEUE_SETS 1
|
#define configUSE_QUEUE_SETS 1
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS 1
|
||||||
|
|
||||||
/* Software timer related configuration options. */
|
/* Software timer related configuration options. */
|
||||||
#define configUSE_TIMERS 1
|
#define configUSE_TIMERS 1
|
||||||
|
@ -148,6 +149,8 @@ extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
|
||||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
|
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
|
||||||
|
|
||||||
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
||||||
|
#define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL()
|
||||||
|
#define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL()
|
||||||
#include "trcKernelPort.h"
|
#include "trcKernelPort.h"
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcConfig.h
|
* trcConfig.h
|
||||||
|
@ -36,16 +36,101 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef TRCCONFIG_H
|
#ifndef TRCCONFIG_H
|
||||||
#define TRCCONFIG_H
|
#define TRCCONFIG_H
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* SELECTED_PORT
|
||||||
|
*
|
||||||
|
* Macro that specifies what hardware port that should be used.
|
||||||
|
* Available ports are:
|
||||||
|
*
|
||||||
|
* Port Name Code Official OS supported
|
||||||
|
* PORT_APPLICATION_DEFINED -2 - -
|
||||||
|
* PORT_NOT_SET -1 - -
|
||||||
|
* PORT_HWIndependent 0 Yes Any
|
||||||
|
* PORT_Win32 1 Yes FreeRTOS on Win32
|
||||||
|
* PORT_Atmel_AT91SAM7 2 No Any
|
||||||
|
* PORT_Atmel_UC3A0 3 No Any
|
||||||
|
* PORT_ARM_CortexM 4 Yes Any
|
||||||
|
* PORT_Renesas_RX600 5 Yes Any
|
||||||
|
* PORT_Microchip_dsPIC_AND_PIC24 6 Yes Any
|
||||||
|
* PORT_TEXAS_INSTRUMENTS_TMS570 7 No Any
|
||||||
|
* PORT_TEXAS_INSTRUMENTS_MSP430 8 No Any
|
||||||
|
* PORT_MICROCHIP_PIC32MX 9 Yes Any
|
||||||
|
* PORT_XILINX_PPC405 10 No FreeRTOS
|
||||||
|
* PORT_XILINX_PPC440 11 No FreeRTOS
|
||||||
|
* PORT_XILINX_MICROBLAZE 12 No Any
|
||||||
|
* PORT_NXP_LPC210X 13 No Any
|
||||||
|
* PORT_MICROCHIP_PIC32MZ 14 Yes Any
|
||||||
|
* PORT_ARM_CORTEX_A9 15 No Any
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
// Set the port setting here!
|
||||||
|
#define SELECTED_PORT PORT_NOT_SET
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_NOT_SET)
|
||||||
|
#error "You need to define SELECTED_PORT here!"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// For Win32 demo projects this is set automatically
|
||||||
|
#define SELECTED_PORT PORT_Win32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FREERTOS_VERSION
|
||||||
|
*
|
||||||
|
* Specify what version of FreeRTOS that is used. This is necessary compensate
|
||||||
|
* for renamed symbols in the FreeRTOS kernel (does not build if incorrect).
|
||||||
|
*
|
||||||
|
* FREERTOS_VERSION_7_3_OR_7_4 (= 1) If using FreeRTOS v7.3.0 - v7.4.2
|
||||||
|
* FREERTOS_VERSION_7_5_OR_7_6 (= 2) If using FreeRTOS v7.5.0 - v7.6.0
|
||||||
|
* FREERTOS_VERSION_8_0_OR_LATER (= 3) If using FreeRTOS v8.0.0 or later
|
||||||
|
*****************************************************************************/
|
||||||
|
#define FREERTOS_VERSION FREERTOS_VERSION_8_0_OR_LATER
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_RECORDER_STORE_MODE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as one of:
|
||||||
|
* - TRACE_STORE_MODE_RING_BUFFER
|
||||||
|
* - TRACE_STORE_MODE_STOP_WHEN_FULL
|
||||||
|
* Default is TRACE_STORE_MODE_RING_BUFFER.
|
||||||
|
*
|
||||||
|
* With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the
|
||||||
|
* events are stored in a ring buffer, i.e., where the oldest events are
|
||||||
|
* overwritten when the buffer becomes full. This allows you to get the last
|
||||||
|
* events leading up to an interesting state, e.g., an error, without having
|
||||||
|
* to store the whole run since startup.
|
||||||
|
*
|
||||||
|
* When TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the
|
||||||
|
* recording is stopped when the buffer becomes full. This is useful for
|
||||||
|
* recording events following a specific state, e.g., the startup sequence.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* CONFIGURATION RELATED TO CAPACITY AND ALLOCATION
|
* TRACE_SCHEDULING_ONLY
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* If this setting is enabled (= 1), only scheduling events are recorded.
|
||||||
|
* If disabled (= 0), all events are recorded.
|
||||||
|
*
|
||||||
|
* Users of FreeRTOS+Trace Free Edition only displays scheduling events, so this
|
||||||
|
* option can be used to avoid storing unsupported events.
|
||||||
|
*
|
||||||
|
* Default value is 0 (store all enabled events).
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define TRACE_SCHEDULING_ONLY 0
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* EVENT_BUFFER_SIZE
|
* EVENT_BUFFER_SIZE
|
||||||
|
@ -53,34 +138,144 @@
|
||||||
* Macro which should be defined as an integer value.
|
* Macro which should be defined as an integer value.
|
||||||
*
|
*
|
||||||
* This defines the capacity of the event buffer, i.e., the number of records
|
* 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
|
* it may store. Most events use one record (4 byte), although some events
|
||||||
* vTracePrintF may use multiple records depending on the number of data args.
|
* require multiple 4-byte records. You should adjust this to the amount of RAM
|
||||||
|
* available in the target system.
|
||||||
|
*
|
||||||
|
* Default value is 1000, which means that 4000 bytes is allocated for the
|
||||||
|
* event buffer.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define EVENT_BUFFER_SIZE 15000
|
||||||
#define EVENT_BUFFER_SIZE 10000 /* Adjust wrt. to available RAM */
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* USE_LINKER_PRAGMA
|
* NTask, NISR, NQueue, NSemaphore, NMutex
|
||||||
*
|
*
|
||||||
* Macro which should be defined as an integer value, default is 0.
|
* A group of macros which should be defined as integer values, zero or larger.
|
||||||
*
|
*
|
||||||
* If this is 1, the header file "recorderdata_linker_pragma.h" is included just
|
* These define the capacity of the Object Property Table, i.e., the maximum
|
||||||
* before the declaration of RecorderData (in trcBase.c), i.e., the trace data
|
* number of objects active at any given point, within each object class (e.g.,
|
||||||
* structure. This allows the user to specify a pragma with linker options.
|
* task, queue, semaphore, ...).
|
||||||
*
|
*
|
||||||
* Example (for IAR Embedded Workbench and NXP LPC17xx):
|
* If tasks or other other objects are deleted in your system, this
|
||||||
* #pragma location="AHB_RAM_MEMORY"
|
* setting does not limit the total amount of objects created, only the number
|
||||||
|
* of objects that have been successfully created but not yet deleted.
|
||||||
*
|
*
|
||||||
* This example instructs the IAR linker to place RecorderData in another RAM
|
* Using too small values will cause vTraceError to be called, which stores an
|
||||||
* bank, the AHB RAM. This can also be used for other compilers with a similar
|
* error message in the trace that is shown when opening the trace file.
|
||||||
* pragmas for linker options.
|
|
||||||
*
|
*
|
||||||
* Note that this only applies if using static allocation, see below.
|
* It can be wise to start with large values for these constants,
|
||||||
|
* unless you are very confident on these numbers. Then do a recording and
|
||||||
|
* check the actual usage by selecting View menu -> Trace Details ->
|
||||||
|
* Resource Usage -> Object Table.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define NTask 100
|
||||||
|
#define NISR 60
|
||||||
|
#define NQueue 60
|
||||||
|
#define NSemaphore 60
|
||||||
|
#define NMutex 60
|
||||||
|
#define NTimer 200
|
||||||
|
#define NEventGroup 60
|
||||||
|
|
||||||
#define USE_LINKER_PRAGMA 0
|
/******************************************************************************
|
||||||
|
* INCLUDE_MEMMANG_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This controls if malloc and free calls should be traced. Set this to zero to
|
||||||
|
* exclude malloc/free calls, or one (1) to include such events in the trace.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_MEMMANG_EVENTS 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_USER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (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
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note that User Events are only displayed in Professional Edition.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_USER_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_ISR_TRACING
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the code for recording Interrupt Service Routines is
|
||||||
|
* excluded to reduce code size.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note, if the kernel has no central interrupt dispatcher, recording ISRs
|
||||||
|
* require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd
|
||||||
|
* in your interrupt handlers.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_ISR_TRACING 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_READY_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If one (1), events are recorded when tasks enter scheduling state "ready".
|
||||||
|
* This uses a lot of space in the event buffer, so excluding "ready events"
|
||||||
|
* will allow for longer traces. Including ready events however allows for
|
||||||
|
* showing the initial pending time before tasks enter the execution state, and
|
||||||
|
* for presenting accurate response times.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_READY_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_NEW_TIME_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (1), events will be generated whenever the OS clock is
|
||||||
|
* increased.
|
||||||
|
*
|
||||||
|
* Default value is 0.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_NEW_TIME_EVENTS 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_FLOAT_SUPPORT
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (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) arguments.
|
||||||
|
*
|
||||||
|
* vTracePrintF can be used with integer and string arguments in either case.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_FLOAT_SUPPORT 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_OBJECT_DELETE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This must be enabled (1) if tasks, queues or other
|
||||||
|
* traced kernel objects are deleted at runtime. If no deletes are made, this
|
||||||
|
* can be set to 0 in order to exclude the delete-handling code.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_OBJECT_DELETE 1
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SYMBOL_TABLE_SIZE
|
* SYMBOL_TABLE_SIZE
|
||||||
|
@ -89,11 +284,12 @@
|
||||||
*
|
*
|
||||||
* This defines the capacity of the symbol table, in bytes. This symbol table
|
* 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
|
* 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
|
* objects. If you don't use User Events or delete any kernel
|
||||||
* Object Table. Thus, if you don't use User Events or delete any kernel
|
* objects you set this to a very low value. The minimum recommended value is 4.
|
||||||
* objects you set this to a very low value, e.g. 4, but not zero (0) since
|
* A size of zero (0) is not allowed since a zero-sized array may result in a
|
||||||
* this causes a declaration of a zero-sized array, for which the C compiler
|
* 32-bit pointer, i.e., using 4 bytes rather than 0.
|
||||||
* behavior is not standardized and may cause misaligned data.
|
*
|
||||||
|
* Default value is 800.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define SYMBOL_TABLE_SIZE 5000
|
#define SYMBOL_TABLE_SIZE 5000
|
||||||
|
|
||||||
|
@ -101,84 +297,13 @@
|
||||||
#error "SYMBOL_TABLE_SIZE may not be zero!"
|
#error "SYMBOL_TABLE_SIZE may not be zero!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/******************************************************************************
|
||||||
* USE_SEPARATE_USER_EVENT_BUFFER
|
* NameLenTask, NameLenQueue, ...
|
||||||
*
|
*
|
||||||
* Macro which should be defined as an integer value.
|
* Macros that specify the maximum lengths (number of characters) for names of
|
||||||
* Default is zero (0).
|
* kernel objects, such as tasks and queues. If longer names are used, they will
|
||||||
*
|
* be truncated when stored in the recorder.
|
||||||
* This enables and disables the use of the separate user event buffer.
|
*****************************************************************************/
|
||||||
*
|
|
||||||
* Note: When using the separate user event buffer, you may get an artificial
|
|
||||||
* task instance named "Unknown actor". This is added as a placeholder when the
|
|
||||||
* user event history is longer than the task scheduling history.
|
|
||||||
******************************************************************************/
|
|
||||||
#define USE_SEPARATE_USER_EVENT_BUFFER 0
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* USER_EVENT_BUFFER_SIZE
|
|
||||||
*
|
|
||||||
* Macro which should be defined as an integer value.
|
|
||||||
*
|
|
||||||
* This defines the capacity of the user event buffer, in number of slots.
|
|
||||||
* A single user event can use between 1 and X slots, depending on the data.
|
|
||||||
*
|
|
||||||
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
|
||||||
******************************************************************************/
|
|
||||||
#define USER_EVENT_BUFFER_SIZE 500
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* USER_EVENT_CHANNELS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as an integer value.
|
|
||||||
*
|
|
||||||
* This defines the number of allowed user event channels.
|
|
||||||
*
|
|
||||||
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
|
||||||
******************************************************************************/
|
|
||||||
#define CHANNEL_FORMAT_PAIRS 32
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* NTask, NISR, NQueue, NSemaphore, NMutex
|
|
||||||
*
|
|
||||||
* 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 Tracealyzer. If you are using the recorder status monitor task,
|
|
||||||
* any error messages are displayed in console prints, assuming that the
|
|
||||||
* print macro has been defined properly (vConsolePrintMessage).
|
|
||||||
*
|
|
||||||
* It can be wise to start with very large values for these constants,
|
|
||||||
* unless you are very confident on these numbers. Then do a recording and
|
|
||||||
* check the actual usage in Tracealyzer. This is shown by selecting
|
|
||||||
* View -> Trace Details -> Resource Usage -> Object Table
|
|
||||||
*
|
|
||||||
* NOTE 2: Remember to account for all tasks and other objects created by
|
|
||||||
* the kernel, such as the IDLE task, any timer tasks, and any tasks created
|
|
||||||
* by other 3rd party software components, such as communication stacks.
|
|
||||||
* Moreover, one task slot is used to indicate "(startup)", i.e., a fictive
|
|
||||||
* task that represent the time before the scheduler starts.
|
|
||||||
* NTask should thus be at least 2-3 slots larger than your application task count.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
#define NTask 100
|
|
||||||
#define NISR 20
|
|
||||||
#define NQueue 60
|
|
||||||
#define NSemaphore 60
|
|
||||||
#define NMutex 60
|
|
||||||
#define NTimer 200
|
|
||||||
#define NEventGroup 60
|
|
||||||
|
|
||||||
/* Maximum object name length for each class (includes zero termination) */
|
|
||||||
#define NameLenTask 15
|
#define NameLenTask 15
|
||||||
#define NameLenISR 15
|
#define NameLenISR 15
|
||||||
#define NameLenQueue 15
|
#define NameLenQueue 15
|
||||||
|
@ -187,30 +312,6 @@
|
||||||
#define NameLenTimer 15
|
#define NameLenTimer 15
|
||||||
#define NameLenEventGroup 15
|
#define NameLenEventGroup 15
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRACE_DESCRIPTION
|
|
||||||
*
|
|
||||||
* Macro which should be defined as a string.
|
|
||||||
*
|
|
||||||
* This string is stored in the trace and displayed in Tracealyzer. Can be
|
|
||||||
* used to store, e.g., system version or build date. This is also used to store
|
|
||||||
* internal error messages from the recorder, which if occurs overwrites the
|
|
||||||
* value defined here. This may be maximum 256 chars.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRACE_DESCRIPTION "Tracealyzer Recorder Test Program"
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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
|
* TRACE_DATA_ALLOCATION
|
||||||
*
|
*
|
||||||
|
@ -227,173 +328,49 @@
|
||||||
*
|
*
|
||||||
* Using dynamic allocation may give more flexibility in some cases.
|
* Using dynamic allocation may give more flexibility in some cases.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#define TRACE_DATA_ALLOCATION TRACE_DATA_ALLOCATION_STATIC
|
#define TRACE_DATA_ALLOCATION TRACE_DATA_ALLOCATION_STATIC
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* CONFIGURATION REGARDING WHAT CODE/FEATURES TO INCLUDE
|
*** ADVANCED SETTINGS ********************************************************
|
||||||
|
******************************************************************************
|
||||||
|
* The remaining settings are not necessary to modify but allows for optimizing
|
||||||
|
* the recorder setup for your specific needs, e.g., to exclude events that you
|
||||||
|
* are not interested in, in order to get longer traces.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USE_TRACE_ASSERT
|
* HEAP_SIZE_BELOW_16M
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* An integer constant that can be used to reduce the buffer usage of memory
|
||||||
* Default is 0.
|
* allocation events (malloc/free). This value should be 1 if the heap size is
|
||||||
*
|
* below 16 MB (2^24 byte), and you can live with reported addresses showing the
|
||||||
* If this is one (1), the TRACE_ASSERT macro will verify that a condition is
|
* lower 24 bits only. If 0, you get the full 32-bit addresses.
|
||||||
* true. If the condition is false, vTraceError() will be called.
|
*
|
||||||
*****************************************************************************/
|
* Default value is 0.
|
||||||
#define USE_TRACE_ASSERT 1
|
******************************************************************************/
|
||||||
|
#define HEAP_SIZE_BELOW_16M 0
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* INCLUDE_FLOAT_SUPPORT
|
* USE_LINKER_PRAGMA
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* Macro which should be defined as an integer value, default is 0.
|
||||||
* Default is 1.
|
|
||||||
*
|
*
|
||||||
* If this is zero (0), all references to floating point values are removed,
|
* If this is 1, the header file "recorderdata_linker_pragma.h" is included just
|
||||||
* in case floating point values are not supported by the platform used.
|
* before the declaration of RecorderData (in trcBase.c), i.e., the trace data
|
||||||
* Floating point values are only used in vTracePrintF and its subroutines, to
|
* structure. This allows the user to specify a pragma with linker options.
|
||||||
* store float (%f) or double (%lf) argments.
|
|
||||||
*
|
*
|
||||||
* Note: vTracePrintF can still be used with integer and string arguments in
|
* Example (for IAR Embedded Workbench and NXP LPC17xx):
|
||||||
* either case.
|
* #pragma location="AHB_RAM_MEMORY"
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_FLOAT_SUPPORT 0
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* INCLUDE_USER_EVENTS
|
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* This example instructs the IAR linker to place RecorderData in another RAM
|
||||||
* Default is 1.
|
* bank, the AHB RAM. This can also be used for other compilers with a similar
|
||||||
|
* pragmas for linker options.
|
||||||
*
|
*
|
||||||
* If this is zero (0) the code for creating User Events is excluded to
|
* Note that this only applies if using static allocation, see below.
|
||||||
* reduce code size. User Events are application-generated events, like
|
******************************************************************************/
|
||||||
* "printf" but for the trace log instead of console output. User Events are
|
#define USE_LINKER_PRAGMA 0
|
||||||
* much faster than a printf and can therefore be used in timing critical code.
|
|
||||||
* See vTraceUserEvent() and vTracePrintF() in trcUser.h
|
|
||||||
*
|
|
||||||
* Note that User Events 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_NEW_TIME_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 0.
|
|
||||||
*
|
|
||||||
* If this is zero (1), events will be generated whenever the os clock is
|
|
||||||
* increased.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_NEW_TIME_EVENTS 0
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* INCLUDE_ISR_TRACING
|
|
||||||
*
|
|
||||||
* 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, if the kernel has no central interrupt dispatcher, recording ISRs
|
|
||||||
* require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd
|
|
||||||
* in your interrupt handlers.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_ISR_TRACING 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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. If no deletes are made, this
|
|
||||||
* can be set to 0 in order to exclude the delete-handling code.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_OBJECT_DELETE 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* INCLUDE_MEMMANG_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 1.
|
|
||||||
*
|
|
||||||
* This controls if malloc and free calls should be traced. Set this to zero to
|
|
||||||
* exclude malloc/free calls from the tracing.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_MEMMANG_EVENTS 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* CONFIGURATION RELATED TO BEHAVIOR
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRACE_RECORDER_STORE_MODE
|
|
||||||
*
|
|
||||||
* Macro which should be defined as one of:
|
|
||||||
* - TRACE_STORE_MODE_RING_BUFFER
|
|
||||||
* - TRACE_STORE_MODE_STOP_WHEN_FULL
|
|
||||||
* Default is TRACE_STORE_MODE_RING_BUFFER.
|
|
||||||
*
|
|
||||||
* With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the events are
|
|
||||||
* stored in a ring buffer, i.e., where the oldest events are overwritten when
|
|
||||||
* the buffer becomes full. This allows you to get the last events leading up
|
|
||||||
* to an interesting state, e.g., an error, without having a large trace buffer
|
|
||||||
* for string the whole run since startup. In this mode, the recorder can run
|
|
||||||
* "forever" as the buffer never gets full, i.e., in the sense that it always
|
|
||||||
* has room for more events.
|
|
||||||
*
|
|
||||||
* To fetch the trace in mode TRACE_STORE_MODE_RING_BUFFER, you need to first halt the
|
|
||||||
* system using your debugger and then do a RAM dump, or to explicitly stop the
|
|
||||||
* recorder using vTraceStop() and then store/upload the trace data using a
|
|
||||||
* 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 TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the recording is
|
|
||||||
* stopped when the buffer becomes full. When the recorder stops itself this way
|
|
||||||
* vTracePortEnd() is called which allows for custom actions, such as triggering
|
|
||||||
* a task that stores the trace buffer, i.e., in case taking a RAM dump
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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
|
* USE_IMPLICIT_IFE_RULES
|
||||||
|
@ -401,56 +378,26 @@
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
* Default is 1.
|
* Default is 1.
|
||||||
*
|
*
|
||||||
* ### Instance Finish Events (IFE) ###
|
* Tracealyzer groups the events into actor instances, based on context-switches
|
||||||
|
* and a definition of "Instance Finish Events", or IFEs. These are kernel calls
|
||||||
|
* considered to be the last event in a task instance. Some kernel calls are
|
||||||
|
* considered IFEs by default (e.g., delay functions), but it is also possible
|
||||||
|
* to specify this individually for each task (see vTraceTaskInstanceFinish).
|
||||||
*
|
*
|
||||||
* For tasks with "infinite" main loops (non-terminating tasks), the concept
|
* If USE_IMPLICIT_IFE_RULES is one (1), the default IFEs will be enabled, which
|
||||||
* of a task instance has no clear definition, it is an application-specific
|
* gives a "typical" grouping of events into instances. You can combine this
|
||||||
* thing. Tracealyzer allows you to define Instance Finish Events (IFEs),
|
* with calls to vTraceTaskInstanceFinish for specific tasks.
|
||||||
* 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 kernel macros (trcKernelPort.h)
|
* If USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFEs are disabled and all
|
||||||
* will define what kernel calls are considered by default to be IFEs.
|
* events withing each task is then shown as a single instance, unless you call
|
||||||
*
|
* vTraceTaskInstanceFinish() at suitable locations to mark the IFEs.
|
||||||
* However, Implicit IFEs only applies to blocking kernel calls. If a
|
|
||||||
* service reads a message without blocking, it does not create a new
|
|
||||||
* instance since no blocking occurred.
|
|
||||||
*
|
|
||||||
* Moreover, the actual IFE might sometimes be another blocking call. 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, 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
|
#define USE_IMPLICIT_IFE_RULES 1
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USE_16BIT_OBJECT_HANDLES
|
* USE_16BIT_OBJECT_HANDLES
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
* Default is 0.
|
|
||||||
*
|
*
|
||||||
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
|
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
|
||||||
* objects such as tasks and queues. This limits the supported number of
|
* objects such as tasks and queues. This limits the supported number of
|
||||||
|
@ -462,69 +409,67 @@
|
||||||
* object property table is limited to 64 KB, the practical limit is about
|
* object property table is limited to 64 KB, the practical limit is about
|
||||||
* 3000 objects in total.
|
* 3000 objects in total.
|
||||||
*
|
*
|
||||||
* NOTE: An object with a high ID (> 255) will generate an extra event
|
* Default is 0.
|
||||||
* (= 4 byte) in the event buffer.
|
|
||||||
*
|
*
|
||||||
* NOTE: Some internal tables in the recorder gets larger when using 16-bit
|
* NOTE: An object with handle above 255 will use an extra 4-byte record in
|
||||||
* handles. The additional RAM usage is 5-10 byte plus 1 byte per kernel object
|
* the event buffer whenever referenced. Moreover, some internal tables in the
|
||||||
*, i.e., task, queue, semaphore, mutex, etc.
|
* recorder gets larger when using 16-bit handles. The additional RAM usage is
|
||||||
|
* 5-10 byte plus 1 byte per kernel object i.e., task, queue, mutex, etc.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define USE_16BIT_OBJECT_HANDLES 0
|
#define USE_16BIT_OBJECT_HANDLES 0
|
||||||
|
|
||||||
/****** Port Name ******************** Code ** Official ** OS Platform ******
|
|
||||||
* PORT_APPLICATION_DEFINED -2 - -
|
|
||||||
* PORT_NOT_SET -1 - -
|
|
||||||
* PORT_HWIndependent 0 Yes Any
|
|
||||||
* PORT_Win32 1 Yes FreeRTOS Win32
|
|
||||||
* PORT_Atmel_AT91SAM7 2 No Any
|
|
||||||
* PORT_Atmel_UC3A0 3 No Any
|
|
||||||
* PORT_ARM_CortexM 4 Yes Any
|
|
||||||
* PORT_Renesas_RX600 5 Yes Any
|
|
||||||
* PORT_Microchip_dsPIC_AND_PIC24 6 Yes Any
|
|
||||||
* PORT_TEXAS_INSTRUMENTS_TMS570 7 No Any
|
|
||||||
* PORT_TEXAS_INSTRUMENTS_MSP430 8 No Any
|
|
||||||
* PORT_MICROCHIP_PIC32 9 No Any
|
|
||||||
* PORT_XILINX_PPC405 10 No FreeRTOS
|
|
||||||
* PORT_XILINX_PPC440 11 No FreeRTOS
|
|
||||||
* PORT_XILINX_MICROBLAZE 12 No Any
|
|
||||||
* PORT_NXP_LPC210X 13 No Any
|
|
||||||
*****************************************************************************/
|
|
||||||
#define SELECTED_PORT PORT_Win32
|
|
||||||
|
|
||||||
#if (SELECTED_PORT == PORT_NOT_SET)
|
|
||||||
#error "You need to define SELECTED_PORT here!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USE_PRIMASK_CS (for Cortex M devices only)
|
* USE_TRACE_ASSERT
|
||||||
*
|
|
||||||
* An integer constant that selects between two options for the critical
|
|
||||||
* sections of the recorder library.
|
|
||||||
*
|
*
|
||||||
* 0: The default FreeRTOS critical section (BASEPRI) - default setting
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
* 1: Always disable ALL interrupts (using PRIMASK)
|
* Default is 1.
|
||||||
*
|
*
|
||||||
* Option 0 uses the standard FreeRTOS macros for critical sections.
|
* If this is one (1), the TRACE_ASSERT macro will verify that a condition is
|
||||||
* However, on Cortex-M devices they only disable interrupts with priorities
|
* true. If the condition is false, vTraceError() will be called.
|
||||||
* below a certain configurable level, while higher priority ISRs remain active.
|
* This is used on several places in the recorder code for sanity checks on
|
||||||
* Such high-priority ISRs may not use the recorder functions in this mode.
|
* parameters. Can be switched off to reduce CPU usage of the tracing.
|
||||||
*
|
*****************************************************************************/
|
||||||
* Option 1 allows you to safely call the recorder from any ISR, independent of
|
#define USE_TRACE_ASSERT 1
|
||||||
* the interrupt priority. This mode may however cause higher IRQ latencies
|
|
||||||
* (some microseconds) since ALL configurable interrupts are disabled during
|
/*******************************************************************************
|
||||||
* the recorder's critical sections in this mode, using the PRIMASK register.
|
* USE_SEPARATE_USER_EVENT_BUFFER
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
* Default is zero (0).
|
||||||
|
*
|
||||||
|
* This enables and disables the use of the separate user event buffer. Using
|
||||||
|
* this separate buffer has the benefit of not overwriting the user events with
|
||||||
|
* kernel events (usually generated at a much higher rate), i.e., when using
|
||||||
|
* ring-buffer mode.
|
||||||
|
*
|
||||||
|
* Note: When using the separate user event buffer, you may get an artificial
|
||||||
|
* task instance named "Unknown actor". This is added as a placeholder when the
|
||||||
|
* user event history is longer than the task scheduling history.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define USE_PRIMASK_CS 0
|
#define USE_SEPARATE_USER_EVENT_BUFFER 0
|
||||||
|
|
||||||
/******************************************************************************
|
/*******************************************************************************
|
||||||
* HEAP_SIZE_BELOW_16M
|
* USER_EVENT_BUFFER_SIZE
|
||||||
*
|
*
|
||||||
* An integer constant that can be used to reduce the buffer usage of memory
|
* Macro which should be defined as an integer value.
|
||||||
* allocation events (malloc/free). This value should be 1 if the heap size is
|
*
|
||||||
* below 16 MB (2^24 byte), and you can live with addresses truncated to the
|
* This defines the capacity of the user event buffer, in number of slots.
|
||||||
* lower 24 bit. Otherwise set it to 0 to get the full 32-bit addresses.
|
* A single user event can use between 1 and X slots, depending on the data.
|
||||||
******************************************************************************/
|
*
|
||||||
#define HEAP_SIZE_BELOW_16M 0
|
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
||||||
|
******************************************************************************/
|
||||||
|
#define USER_EVENT_BUFFER_SIZE 10
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* USER_EVENT_CHANNELS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* This defines the number of allowed user event channels.
|
||||||
|
*
|
||||||
|
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
||||||
|
******************************************************************************/
|
||||||
|
#define CHANNEL_FORMAT_PAIRS 32
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,7 @@
|
||||||
<ClCompile Include="..\Common\Minimal\QueueOverwrite.c" />
|
<ClCompile Include="..\Common\Minimal\QueueOverwrite.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\QueueSet.c" />
|
<ClCompile Include="..\Common\Minimal\QueueSet.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\semtest.c" />
|
<ClCompile Include="..\Common\Minimal\semtest.c" />
|
||||||
|
<ClCompile Include="..\Common\Minimal\TaskNotify.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\timerdemo.c" />
|
<ClCompile Include="..\Common\Minimal\timerdemo.c" />
|
||||||
<ClCompile Include="DemosModifiedForLowTickRate\recmutex.c" />
|
<ClCompile Include="DemosModifiedForLowTickRate\recmutex.c" />
|
||||||
<ClCompile Include="main.c">
|
<ClCompile Include="main.c">
|
||||||
|
|
|
@ -139,6 +139,9 @@
|
||||||
<ClCompile Include="..\Common\Minimal\IntSemTest.c">
|
<ClCompile Include="..\Common\Minimal\IntSemTest.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Common\Minimal\TaskNotify.c">
|
||||||
|
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="FreeRTOSConfig.h">
|
<ClInclude Include="FreeRTOSConfig.h">
|
||||||
|
|
|
@ -113,8 +113,8 @@ being used as this demo could easily create one large heap region instead of
|
||||||
multiple smaller heap regions - in which case heap_4.c would be the more
|
multiple smaller heap regions - in which case heap_4.c would be the more
|
||||||
appropriate choice. */
|
appropriate choice. */
|
||||||
#define mainREGION_1_SIZE 3001
|
#define mainREGION_1_SIZE 3001
|
||||||
#define mainREGION_2_SIZE 18005
|
#define mainREGION_2_SIZE 18105
|
||||||
#define mainREGION_3_SIZE 1007
|
#define mainREGION_3_SIZE 1407
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||||
|
@ -369,4 +369,5 @@ const HeapRegion_t xHeapRegions[] =
|
||||||
|
|
||||||
vPortDefineHeapRegions( xHeapRegions );
|
vPortDefineHeapRegions( xHeapRegions );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@
|
||||||
|
|
||||||
/* The rate at which data is sent to the queue. The 200ms value is converted
|
/* The rate at which data is sent to the queue. The 200ms value is converted
|
||||||
to ticks using the portTICK_PERIOD_MS constant. */
|
to ticks using the portTICK_PERIOD_MS constant. */
|
||||||
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 )
|
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
|
||||||
|
|
||||||
/* The number of items the queue can hold. This is 1 as the receive task
|
/* The number of items the queue can hold. This is 1 as the receive task
|
||||||
will remove items as they are added, meaning the send task should always find
|
will remove items as they are added, meaning the send task should always find
|
||||||
|
|
|
@ -112,10 +112,10 @@
|
||||||
|
|
||||||
/* Kernel includes. */
|
/* Kernel includes. */
|
||||||
#include <FreeRTOS.h>
|
#include <FreeRTOS.h>
|
||||||
#include "task.h"
|
#include <task.h>
|
||||||
#include "queue.h"
|
#include <queue.h>
|
||||||
#include "timers.h"
|
#include <timers.h>
|
||||||
#include "semphr.h"
|
#include <semphr.h>
|
||||||
|
|
||||||
/* Standard demo includes. */
|
/* Standard demo includes. */
|
||||||
#include "BlockQ.h"
|
#include "BlockQ.h"
|
||||||
|
@ -134,6 +134,7 @@
|
||||||
#include "QueueOverwrite.h"
|
#include "QueueOverwrite.h"
|
||||||
#include "EventGroupsDemo.h"
|
#include "EventGroupsDemo.h"
|
||||||
#include "IntSemTest.h"
|
#include "IntSemTest.h"
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
|
||||||
/* Priorities at which the tasks are created. */
|
/* Priorities at which the tasks are created. */
|
||||||
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||||
|
@ -196,6 +197,7 @@ int main_full( void )
|
||||||
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
|
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
|
||||||
|
|
||||||
/* Create the standard demo tasks. */
|
/* Create the standard demo tasks. */
|
||||||
|
vStartTaskNotifyTask();
|
||||||
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
||||||
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||||
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
||||||
|
@ -265,6 +267,11 @@ const TickType_t xCycleFrequency = 2500 / portTICK_PERIOD_MS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "Error: Notification";
|
||||||
|
}
|
||||||
|
|
||||||
if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
|
if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
|
||||||
{
|
{
|
||||||
pcStatusMessage = "Error: IntSem";
|
pcStatusMessage = "Error: IntSem";
|
||||||
|
@ -379,7 +386,7 @@ void *pvAllocated;
|
||||||
xMutexToDelete = NULL;
|
xMutexToDelete = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exercise heap_4 a bit. The malloc failed hook will trap failed
|
/* Exercise heap_5 a bit. The malloc failed hook will trap failed
|
||||||
allocations so there is no need to test here. */
|
allocations so there is no need to test here. */
|
||||||
pvAllocated = pvPortMalloc( ( rand() % 100 ) + 1 );
|
pvAllocated = pvPortMalloc( ( rand() % 100 ) + 1 );
|
||||||
vPortFree( pvAllocated );
|
vPortFree( pvAllocated );
|
||||||
|
@ -410,6 +417,9 @@ void vFullDemoTickHookFunction( void )
|
||||||
|
|
||||||
/* Exercise giving mutexes from an interrupt. */
|
/* Exercise giving mutexes from an interrupt. */
|
||||||
vInterruptSemaphorePeriodicTest();
|
vInterruptSemaphorePeriodicTest();
|
||||||
|
|
||||||
|
/* Exercise using task notifications from an interrupt. */
|
||||||
|
xNotifyTaskFromISR();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193247</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193247</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193257</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193257</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193267</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193277</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193277</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193287</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193297</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -137,7 +137,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193297</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193308</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193313</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -164,7 +164,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193319</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -173,7 +173,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193325</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321193349</id>
|
||||||
<name>Standard_Demo_Tasks</name>
|
<name>Standard_Demo_Tasks</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
|
@ -190,6 +190,24 @@
|
||||||
<arguments>1.0-name-matches-false-false-timerdemo.c</arguments>
|
<arguments>1.0-name-matches-false-false-timerdemo.c</arguments>
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1418321193369</id>
|
||||||
|
<name>Standard_Demo_Tasks</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-IntSemTest.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1418321193379</id>
|
||||||
|
<name>Standard_Demo_Tasks</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-TaskNotify.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>0</id>
|
||||||
<name>FreeRTOS_Source/portable</name>
|
<name>FreeRTOS_Source/portable</name>
|
||||||
|
@ -209,12 +227,12 @@
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>0</id>
|
<id>1418321226214</id>
|
||||||
<name>FreeRTOS_Source/portable/MemMang</name>
|
<name>FreeRTOS_Source/portable/MemMang</name>
|
||||||
<type>5</type>
|
<type>5</type>
|
||||||
<matcher>
|
<matcher>
|
||||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
|
<arguments>1.0-name-matches-false-false-heap_5.c</arguments>
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
</filteredResources>
|
</filteredResources>
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
#define configUSE_TICK_HOOK 1
|
#define configUSE_TICK_HOOK 1
|
||||||
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 50 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
|
||||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) )
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 23 * 1024 ) )
|
||||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||||
#define configUSE_TRACE_FACILITY 1
|
#define configUSE_TRACE_FACILITY 1
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
@ -97,6 +97,7 @@
|
||||||
#define configUSE_COUNTING_SEMAPHORES 1
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
#define configUSE_ALTERNATIVE_API 1
|
#define configUSE_ALTERNATIVE_API 1
|
||||||
#define configUSE_QUEUE_SETS 1
|
#define configUSE_QUEUE_SETS 1
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS 1
|
||||||
|
|
||||||
/* Software timer related configuration options. */
|
/* Software timer related configuration options. */
|
||||||
#define configUSE_TIMERS 1
|
#define configUSE_TIMERS 1
|
||||||
|
@ -104,7 +105,7 @@
|
||||||
#define configTIMER_QUEUE_LENGTH 20
|
#define configTIMER_QUEUE_LENGTH 20
|
||||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||||
|
|
||||||
#define configMAX_PRIORITIES ( 8 )
|
#define configMAX_PRIORITIES ( 7 )
|
||||||
|
|
||||||
/* Run time stats gathering configuration options. */
|
/* Run time stats gathering configuration options. */
|
||||||
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
|
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
|
||||||
|
@ -147,7 +148,9 @@ uses the same semantics as the standard C assert() macro. */
|
||||||
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
|
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
|
||||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
|
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
|
||||||
|
|
||||||
|
|
||||||
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
||||||
|
#define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL()
|
||||||
|
#define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL()
|
||||||
#include "trcKernelPort.h"
|
#include "trcKernelPort.h"
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Tracealyzer v2.6.0 Recorder Library
|
* Tracealyzer v2.7.0 Recorder Library
|
||||||
* Percepio AB, www.percepio.com
|
* Percepio AB, www.percepio.com
|
||||||
*
|
*
|
||||||
* trcConfig.h
|
* trcConfig.h
|
||||||
|
@ -36,16 +36,101 @@
|
||||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
* 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.
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
*
|
*
|
||||||
* Copyright Percepio AB, 2013.
|
* Tabs are used for indent in this file (1 tab = 4 spaces)
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2014.
|
||||||
* www.percepio.com
|
* www.percepio.com
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef TRCCONFIG_H
|
#ifndef TRCCONFIG_H
|
||||||
#define TRCCONFIG_H
|
#define TRCCONFIG_H
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* SELECTED_PORT
|
||||||
|
*
|
||||||
|
* Macro that specifies what hardware port that should be used.
|
||||||
|
* Available ports are:
|
||||||
|
*
|
||||||
|
* Port Name Code Official OS supported
|
||||||
|
* PORT_APPLICATION_DEFINED -2 - -
|
||||||
|
* PORT_NOT_SET -1 - -
|
||||||
|
* PORT_HWIndependent 0 Yes Any
|
||||||
|
* PORT_Win32 1 Yes FreeRTOS on Win32
|
||||||
|
* PORT_Atmel_AT91SAM7 2 No Any
|
||||||
|
* PORT_Atmel_UC3A0 3 No Any
|
||||||
|
* PORT_ARM_CortexM 4 Yes Any
|
||||||
|
* PORT_Renesas_RX600 5 Yes Any
|
||||||
|
* PORT_Microchip_dsPIC_AND_PIC24 6 Yes Any
|
||||||
|
* PORT_TEXAS_INSTRUMENTS_TMS570 7 No Any
|
||||||
|
* PORT_TEXAS_INSTRUMENTS_MSP430 8 No Any
|
||||||
|
* PORT_MICROCHIP_PIC32MX 9 Yes Any
|
||||||
|
* PORT_XILINX_PPC405 10 No FreeRTOS
|
||||||
|
* PORT_XILINX_PPC440 11 No FreeRTOS
|
||||||
|
* PORT_XILINX_MICROBLAZE 12 No Any
|
||||||
|
* PORT_NXP_LPC210X 13 No Any
|
||||||
|
* PORT_MICROCHIP_PIC32MZ 14 Yes Any
|
||||||
|
* PORT_ARM_CORTEX_A9 15 No Any
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
// Set the port setting here!
|
||||||
|
#define SELECTED_PORT PORT_NOT_SET
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_NOT_SET)
|
||||||
|
#error "You need to define SELECTED_PORT here!"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// For Win32 demo projects this is set automatically
|
||||||
|
#define SELECTED_PORT PORT_Win32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* FREERTOS_VERSION
|
||||||
|
*
|
||||||
|
* Specify what version of FreeRTOS that is used. This is necessary compensate
|
||||||
|
* for renamed symbols in the FreeRTOS kernel (does not build if incorrect).
|
||||||
|
*
|
||||||
|
* FREERTOS_VERSION_7_3_OR_7_4 (= 1) If using FreeRTOS v7.3.0 - v7.4.2
|
||||||
|
* FREERTOS_VERSION_7_5_OR_7_6 (= 2) If using FreeRTOS v7.5.0 - v7.6.0
|
||||||
|
* FREERTOS_VERSION_8_0_OR_LATER (= 3) If using FreeRTOS v8.0.0 or later
|
||||||
|
*****************************************************************************/
|
||||||
|
#define FREERTOS_VERSION FREERTOS_VERSION_8_0_OR_LATER
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_RECORDER_STORE_MODE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as one of:
|
||||||
|
* - TRACE_STORE_MODE_RING_BUFFER
|
||||||
|
* - TRACE_STORE_MODE_STOP_WHEN_FULL
|
||||||
|
* Default is TRACE_STORE_MODE_RING_BUFFER.
|
||||||
|
*
|
||||||
|
* With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the
|
||||||
|
* events are stored in a ring buffer, i.e., where the oldest events are
|
||||||
|
* overwritten when the buffer becomes full. This allows you to get the last
|
||||||
|
* events leading up to an interesting state, e.g., an error, without having
|
||||||
|
* to store the whole run since startup.
|
||||||
|
*
|
||||||
|
* When TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the
|
||||||
|
* recording is stopped when the buffer becomes full. This is useful for
|
||||||
|
* recording events following a specific state, e.g., the startup sequence.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* CONFIGURATION RELATED TO CAPACITY AND ALLOCATION
|
* TRACE_SCHEDULING_ONLY
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* If this setting is enabled (= 1), only scheduling events are recorded.
|
||||||
|
* If disabled (= 0), all events are recorded.
|
||||||
|
*
|
||||||
|
* Users of FreeRTOS+Trace Free Edition only displays scheduling events, so this
|
||||||
|
* option can be used to avoid storing unsupported events.
|
||||||
|
*
|
||||||
|
* Default value is 0 (store all enabled events).
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define TRACE_SCHEDULING_ONLY 0
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* EVENT_BUFFER_SIZE
|
* EVENT_BUFFER_SIZE
|
||||||
|
@ -53,34 +138,144 @@
|
||||||
* Macro which should be defined as an integer value.
|
* Macro which should be defined as an integer value.
|
||||||
*
|
*
|
||||||
* This defines the capacity of the event buffer, i.e., the number of records
|
* 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
|
* it may store. Most events use one record (4 byte), although some events
|
||||||
* vTracePrintF may use multiple records depending on the number of data args.
|
* require multiple 4-byte records. You should adjust this to the amount of RAM
|
||||||
|
* available in the target system.
|
||||||
|
*
|
||||||
|
* Default value is 1000, which means that 4000 bytes is allocated for the
|
||||||
|
* event buffer.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define EVENT_BUFFER_SIZE 15000
|
||||||
#define EVENT_BUFFER_SIZE 10000 /* Adjust wrt. to available RAM */
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* USE_LINKER_PRAGMA
|
* NTask, NISR, NQueue, NSemaphore, NMutex
|
||||||
*
|
*
|
||||||
* Macro which should be defined as an integer value, default is 0.
|
* A group of macros which should be defined as integer values, zero or larger.
|
||||||
*
|
*
|
||||||
* If this is 1, the header file "recorderdata_linker_pragma.h" is included just
|
* These define the capacity of the Object Property Table, i.e., the maximum
|
||||||
* before the declaration of RecorderData (in trcBase.c), i.e., the trace data
|
* number of objects active at any given point, within each object class (e.g.,
|
||||||
* structure. This allows the user to specify a pragma with linker options.
|
* task, queue, semaphore, ...).
|
||||||
*
|
*
|
||||||
* Example (for IAR Embedded Workbench and NXP LPC17xx):
|
* If tasks or other other objects are deleted in your system, this
|
||||||
* #pragma location="AHB_RAM_MEMORY"
|
* setting does not limit the total amount of objects created, only the number
|
||||||
|
* of objects that have been successfully created but not yet deleted.
|
||||||
*
|
*
|
||||||
* This example instructs the IAR linker to place RecorderData in another RAM
|
* Using too small values will cause vTraceError to be called, which stores an
|
||||||
* bank, the AHB RAM. This can also be used for other compilers with a similar
|
* error message in the trace that is shown when opening the trace file.
|
||||||
* pragmas for linker options.
|
|
||||||
*
|
*
|
||||||
* Note that this only applies if using static allocation, see below.
|
* It can be wise to start with large values for these constants,
|
||||||
|
* unless you are very confident on these numbers. Then do a recording and
|
||||||
|
* check the actual usage by selecting View menu -> Trace Details ->
|
||||||
|
* Resource Usage -> Object Table.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#define NTask 100
|
||||||
|
#define NISR 60
|
||||||
|
#define NQueue 60
|
||||||
|
#define NSemaphore 60
|
||||||
|
#define NMutex 60
|
||||||
|
#define NTimer 200
|
||||||
|
#define NEventGroup 60
|
||||||
|
|
||||||
#define USE_LINKER_PRAGMA 0
|
/******************************************************************************
|
||||||
|
* INCLUDE_MEMMANG_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This controls if malloc and free calls should be traced. Set this to zero to
|
||||||
|
* exclude malloc/free calls, or one (1) to include such events in the trace.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_MEMMANG_EVENTS 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_USER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (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
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note that User Events are only displayed in Professional Edition.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_USER_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_ISR_TRACING
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (0), the code for recording Interrupt Service Routines is
|
||||||
|
* excluded to reduce code size.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*
|
||||||
|
* Note, if the kernel has no central interrupt dispatcher, recording ISRs
|
||||||
|
* require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd
|
||||||
|
* in your interrupt handlers.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_ISR_TRACING 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_READY_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If one (1), events are recorded when tasks enter scheduling state "ready".
|
||||||
|
* This uses a lot of space in the event buffer, so excluding "ready events"
|
||||||
|
* will allow for longer traces. Including ready events however allows for
|
||||||
|
* showing the initial pending time before tasks enter the execution state, and
|
||||||
|
* for presenting accurate response times.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_READY_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_NEW_TIME_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* If this is zero (1), events will be generated whenever the OS clock is
|
||||||
|
* increased.
|
||||||
|
*
|
||||||
|
* Default value is 0.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_NEW_TIME_EVENTS 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_FLOAT_SUPPORT
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (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) arguments.
|
||||||
|
*
|
||||||
|
* vTracePrintF can be used with integer and string arguments in either case.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_FLOAT_SUPPORT 0
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_OBJECT_DELETE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
*
|
||||||
|
* This must be enabled (1) if tasks, queues or other
|
||||||
|
* traced kernel objects are deleted at runtime. If no deletes are made, this
|
||||||
|
* can be set to 0 in order to exclude the delete-handling code.
|
||||||
|
*
|
||||||
|
* Default value is 1.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_OBJECT_DELETE 1
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* SYMBOL_TABLE_SIZE
|
* SYMBOL_TABLE_SIZE
|
||||||
|
@ -89,11 +284,12 @@
|
||||||
*
|
*
|
||||||
* This defines the capacity of the symbol table, in bytes. This symbol table
|
* 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
|
* 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
|
* objects. If you don't use User Events or delete any kernel
|
||||||
* Object Table. Thus, if you don't use User Events or delete any kernel
|
* objects you set this to a very low value. The minimum recommended value is 4.
|
||||||
* objects you set this to a very low value, e.g. 4, but not zero (0) since
|
* A size of zero (0) is not allowed since a zero-sized array may result in a
|
||||||
* this causes a declaration of a zero-sized array, for which the C compiler
|
* 32-bit pointer, i.e., using 4 bytes rather than 0.
|
||||||
* behavior is not standardized and may cause misaligned data.
|
*
|
||||||
|
* Default value is 800.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define SYMBOL_TABLE_SIZE 5000
|
#define SYMBOL_TABLE_SIZE 5000
|
||||||
|
|
||||||
|
@ -101,84 +297,13 @@
|
||||||
#error "SYMBOL_TABLE_SIZE may not be zero!"
|
#error "SYMBOL_TABLE_SIZE may not be zero!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************
|
/******************************************************************************
|
||||||
* USE_SEPARATE_USER_EVENT_BUFFER
|
* NameLenTask, NameLenQueue, ...
|
||||||
*
|
*
|
||||||
* Macro which should be defined as an integer value.
|
* Macros that specify the maximum lengths (number of characters) for names of
|
||||||
* Default is zero (0).
|
* kernel objects, such as tasks and queues. If longer names are used, they will
|
||||||
*
|
* be truncated when stored in the recorder.
|
||||||
* This enables and disables the use of the separate user event buffer.
|
*****************************************************************************/
|
||||||
*
|
|
||||||
* Note: When using the separate user event buffer, you may get an artificial
|
|
||||||
* task instance named "Unknown actor". This is added as a placeholder when the
|
|
||||||
* user event history is longer than the task scheduling history.
|
|
||||||
******************************************************************************/
|
|
||||||
#define USE_SEPARATE_USER_EVENT_BUFFER 0
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* USER_EVENT_BUFFER_SIZE
|
|
||||||
*
|
|
||||||
* Macro which should be defined as an integer value.
|
|
||||||
*
|
|
||||||
* This defines the capacity of the user event buffer, in number of slots.
|
|
||||||
* A single user event can use between 1 and X slots, depending on the data.
|
|
||||||
*
|
|
||||||
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
|
||||||
******************************************************************************/
|
|
||||||
#define USER_EVENT_BUFFER_SIZE 500
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* USER_EVENT_CHANNELS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as an integer value.
|
|
||||||
*
|
|
||||||
* This defines the number of allowed user event channels.
|
|
||||||
*
|
|
||||||
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
|
||||||
******************************************************************************/
|
|
||||||
#define CHANNEL_FORMAT_PAIRS 32
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* NTask, NISR, NQueue, NSemaphore, NMutex
|
|
||||||
*
|
|
||||||
* 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 Tracealyzer. If you are using the recorder status monitor task,
|
|
||||||
* any error messages are displayed in console prints, assuming that the
|
|
||||||
* print macro has been defined properly (vConsolePrintMessage).
|
|
||||||
*
|
|
||||||
* It can be wise to start with very large values for these constants,
|
|
||||||
* unless you are very confident on these numbers. Then do a recording and
|
|
||||||
* check the actual usage in Tracealyzer. This is shown by selecting
|
|
||||||
* View -> Trace Details -> Resource Usage -> Object Table
|
|
||||||
*
|
|
||||||
* NOTE 2: Remember to account for all tasks and other objects created by
|
|
||||||
* the kernel, such as the IDLE task, any timer tasks, and any tasks created
|
|
||||||
* by other 3rd party software components, such as communication stacks.
|
|
||||||
* Moreover, one task slot is used to indicate "(startup)", i.e., a fictive
|
|
||||||
* task that represent the time before the scheduler starts.
|
|
||||||
* NTask should thus be at least 2-3 slots larger than your application task count.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
#define NTask 100
|
|
||||||
#define NISR 20
|
|
||||||
#define NQueue 60
|
|
||||||
#define NSemaphore 60
|
|
||||||
#define NMutex 60
|
|
||||||
#define NTimer 200
|
|
||||||
#define NEventGroup 60
|
|
||||||
|
|
||||||
/* Maximum object name length for each class (includes zero termination) */
|
|
||||||
#define NameLenTask 15
|
#define NameLenTask 15
|
||||||
#define NameLenISR 15
|
#define NameLenISR 15
|
||||||
#define NameLenQueue 15
|
#define NameLenQueue 15
|
||||||
|
@ -187,30 +312,6 @@
|
||||||
#define NameLenTimer 15
|
#define NameLenTimer 15
|
||||||
#define NameLenEventGroup 15
|
#define NameLenEventGroup 15
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRACE_DESCRIPTION
|
|
||||||
*
|
|
||||||
* Macro which should be defined as a string.
|
|
||||||
*
|
|
||||||
* This string is stored in the trace and displayed in Tracealyzer. Can be
|
|
||||||
* used to store, e.g., system version or build date. This is also used to store
|
|
||||||
* internal error messages from the recorder, which if occurs overwrites the
|
|
||||||
* value defined here. This may be maximum 256 chars.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define TRACE_DESCRIPTION "Tracealyzer Recorder Test Program"
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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
|
* TRACE_DATA_ALLOCATION
|
||||||
*
|
*
|
||||||
|
@ -227,173 +328,49 @@
|
||||||
*
|
*
|
||||||
* Using dynamic allocation may give more flexibility in some cases.
|
* Using dynamic allocation may give more flexibility in some cases.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#define TRACE_DATA_ALLOCATION TRACE_DATA_ALLOCATION_STATIC
|
#define TRACE_DATA_ALLOCATION TRACE_DATA_ALLOCATION_STATIC
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* CONFIGURATION REGARDING WHAT CODE/FEATURES TO INCLUDE
|
*** ADVANCED SETTINGS ********************************************************
|
||||||
|
******************************************************************************
|
||||||
|
* The remaining settings are not necessary to modify but allows for optimizing
|
||||||
|
* the recorder setup for your specific needs, e.g., to exclude events that you
|
||||||
|
* are not interested in, in order to get longer traces.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USE_TRACE_ASSERT
|
* HEAP_SIZE_BELOW_16M
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* An integer constant that can be used to reduce the buffer usage of memory
|
||||||
* Default is 0.
|
* allocation events (malloc/free). This value should be 1 if the heap size is
|
||||||
*
|
* below 16 MB (2^24 byte), and you can live with reported addresses showing the
|
||||||
* If this is one (1), the TRACE_ASSERT macro will verify that a condition is
|
* lower 24 bits only. If 0, you get the full 32-bit addresses.
|
||||||
* true. If the condition is false, vTraceError() will be called.
|
*
|
||||||
*****************************************************************************/
|
* Default value is 0.
|
||||||
#define USE_TRACE_ASSERT 1
|
******************************************************************************/
|
||||||
|
#define HEAP_SIZE_BELOW_16M 0
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* INCLUDE_FLOAT_SUPPORT
|
* USE_LINKER_PRAGMA
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* Macro which should be defined as an integer value, default is 0.
|
||||||
* Default is 1.
|
|
||||||
*
|
*
|
||||||
* If this is zero (0), all references to floating point values are removed,
|
* If this is 1, the header file "recorderdata_linker_pragma.h" is included just
|
||||||
* in case floating point values are not supported by the platform used.
|
* before the declaration of RecorderData (in trcBase.c), i.e., the trace data
|
||||||
* Floating point values are only used in vTracePrintF and its subroutines, to
|
* structure. This allows the user to specify a pragma with linker options.
|
||||||
* store float (%f) or double (%lf) argments.
|
|
||||||
*
|
*
|
||||||
* Note: vTracePrintF can still be used with integer and string arguments in
|
* Example (for IAR Embedded Workbench and NXP LPC17xx):
|
||||||
* either case.
|
* #pragma location="AHB_RAM_MEMORY"
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_FLOAT_SUPPORT 0
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* INCLUDE_USER_EVENTS
|
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* This example instructs the IAR linker to place RecorderData in another RAM
|
||||||
* Default is 1.
|
* bank, the AHB RAM. This can also be used for other compilers with a similar
|
||||||
|
* pragmas for linker options.
|
||||||
*
|
*
|
||||||
* If this is zero (0) the code for creating User Events is excluded to
|
* Note that this only applies if using static allocation, see below.
|
||||||
* reduce code size. User Events are application-generated events, like
|
******************************************************************************/
|
||||||
* "printf" but for the trace log instead of console output. User Events are
|
#define USE_LINKER_PRAGMA 0
|
||||||
* much faster than a printf and can therefore be used in timing critical code.
|
|
||||||
* See vTraceUserEvent() and vTracePrintF() in trcUser.h
|
|
||||||
*
|
|
||||||
* Note that User Events 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_NEW_TIME_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 0.
|
|
||||||
*
|
|
||||||
* If this is zero (1), events will be generated whenever the os clock is
|
|
||||||
* increased.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_NEW_TIME_EVENTS 0
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* INCLUDE_ISR_TRACING
|
|
||||||
*
|
|
||||||
* 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, if the kernel has no central interrupt dispatcher, recording ISRs
|
|
||||||
* require that you insert calls to vTraceStoreISRBegin and vTraceStoreISREnd
|
|
||||||
* in your interrupt handlers.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_ISR_TRACING 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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. If no deletes are made, this
|
|
||||||
* can be set to 0 in order to exclude the delete-handling code.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_OBJECT_DELETE 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* INCLUDE_MEMMANG_EVENTS
|
|
||||||
*
|
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
|
||||||
* Default is 1.
|
|
||||||
*
|
|
||||||
* This controls if malloc and free calls should be traced. Set this to zero to
|
|
||||||
* exclude malloc/free calls from the tracing.
|
|
||||||
*****************************************************************************/
|
|
||||||
#define INCLUDE_MEMMANG_EVENTS 1
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* CONFIGURATION RELATED TO BEHAVIOR
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TRACE_RECORDER_STORE_MODE
|
|
||||||
*
|
|
||||||
* Macro which should be defined as one of:
|
|
||||||
* - TRACE_STORE_MODE_RING_BUFFER
|
|
||||||
* - TRACE_STORE_MODE_STOP_WHEN_FULL
|
|
||||||
* Default is TRACE_STORE_MODE_RING_BUFFER.
|
|
||||||
*
|
|
||||||
* With TRACE_RECORDER_STORE_MODE set to TRACE_STORE_MODE_RING_BUFFER, the events are
|
|
||||||
* stored in a ring buffer, i.e., where the oldest events are overwritten when
|
|
||||||
* the buffer becomes full. This allows you to get the last events leading up
|
|
||||||
* to an interesting state, e.g., an error, without having a large trace buffer
|
|
||||||
* for string the whole run since startup. In this mode, the recorder can run
|
|
||||||
* "forever" as the buffer never gets full, i.e., in the sense that it always
|
|
||||||
* has room for more events.
|
|
||||||
*
|
|
||||||
* To fetch the trace in mode TRACE_STORE_MODE_RING_BUFFER, you need to first halt the
|
|
||||||
* system using your debugger and then do a RAM dump, or to explicitly stop the
|
|
||||||
* recorder using vTraceStop() and then store/upload the trace data using a
|
|
||||||
* 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 TRACE_RECORDER_STORE_MODE is TRACE_STORE_MODE_STOP_WHEN_FULL, the recording is
|
|
||||||
* stopped when the buffer becomes full. When the recorder stops itself this way
|
|
||||||
* vTracePortEnd() is called which allows for custom actions, such as triggering
|
|
||||||
* a task that stores the trace buffer, i.e., in case taking a RAM dump
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#define TRACE_RECORDER_STORE_MODE TRACE_STORE_MODE_RING_BUFFER
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* 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
|
* USE_IMPLICIT_IFE_RULES
|
||||||
|
@ -401,56 +378,26 @@
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
* Default is 1.
|
* Default is 1.
|
||||||
*
|
*
|
||||||
* ### Instance Finish Events (IFE) ###
|
* Tracealyzer groups the events into actor instances, based on context-switches
|
||||||
|
* and a definition of "Instance Finish Events", or IFEs. These are kernel calls
|
||||||
|
* considered to be the last event in a task instance. Some kernel calls are
|
||||||
|
* considered IFEs by default (e.g., delay functions), but it is also possible
|
||||||
|
* to specify this individually for each task (see vTraceTaskInstanceFinish).
|
||||||
*
|
*
|
||||||
* For tasks with "infinite" main loops (non-terminating tasks), the concept
|
* If USE_IMPLICIT_IFE_RULES is one (1), the default IFEs will be enabled, which
|
||||||
* of a task instance has no clear definition, it is an application-specific
|
* gives a "typical" grouping of events into instances. You can combine this
|
||||||
* thing. Tracealyzer allows you to define Instance Finish Events (IFEs),
|
* with calls to vTraceTaskInstanceFinish for specific tasks.
|
||||||
* 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 kernel macros (trcKernelPort.h)
|
* If USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFEs are disabled and all
|
||||||
* will define what kernel calls are considered by default to be IFEs.
|
* events withing each task is then shown as a single instance, unless you call
|
||||||
*
|
* vTraceTaskInstanceFinish() at suitable locations to mark the IFEs.
|
||||||
* However, Implicit IFEs only applies to blocking kernel calls. If a
|
|
||||||
* service reads a message without blocking, it does not create a new
|
|
||||||
* instance since no blocking occurred.
|
|
||||||
*
|
|
||||||
* Moreover, the actual IFE might sometimes be another blocking call. 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, 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
|
#define USE_IMPLICIT_IFE_RULES 1
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USE_16BIT_OBJECT_HANDLES
|
* USE_16BIT_OBJECT_HANDLES
|
||||||
*
|
*
|
||||||
* Macro which should be defined as either zero (0) or one (1).
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
* Default is 0.
|
|
||||||
*
|
*
|
||||||
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
|
* If set to 0 (zero), the recorder uses 8-bit handles to identify kernel
|
||||||
* objects such as tasks and queues. This limits the supported number of
|
* objects such as tasks and queues. This limits the supported number of
|
||||||
|
@ -462,69 +409,67 @@
|
||||||
* object property table is limited to 64 KB, the practical limit is about
|
* object property table is limited to 64 KB, the practical limit is about
|
||||||
* 3000 objects in total.
|
* 3000 objects in total.
|
||||||
*
|
*
|
||||||
* NOTE: An object with a high ID (> 255) will generate an extra event
|
* Default is 0.
|
||||||
* (= 4 byte) in the event buffer.
|
|
||||||
*
|
*
|
||||||
* NOTE: Some internal tables in the recorder gets larger when using 16-bit
|
* NOTE: An object with handle above 255 will use an extra 4-byte record in
|
||||||
* handles. The additional RAM usage is 5-10 byte plus 1 byte per kernel object
|
* the event buffer whenever referenced. Moreover, some internal tables in the
|
||||||
*, i.e., task, queue, semaphore, mutex, etc.
|
* recorder gets larger when using 16-bit handles. The additional RAM usage is
|
||||||
|
* 5-10 byte plus 1 byte per kernel object i.e., task, queue, mutex, etc.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#define USE_16BIT_OBJECT_HANDLES 0
|
#define USE_16BIT_OBJECT_HANDLES 0
|
||||||
|
|
||||||
/****** Port Name ******************** Code ** Official ** OS Platform ******
|
|
||||||
* PORT_APPLICATION_DEFINED -2 - -
|
|
||||||
* PORT_NOT_SET -1 - -
|
|
||||||
* PORT_HWIndependent 0 Yes Any
|
|
||||||
* PORT_Win32 1 Yes FreeRTOS Win32
|
|
||||||
* PORT_Atmel_AT91SAM7 2 No Any
|
|
||||||
* PORT_Atmel_UC3A0 3 No Any
|
|
||||||
* PORT_ARM_CortexM 4 Yes Any
|
|
||||||
* PORT_Renesas_RX600 5 Yes Any
|
|
||||||
* PORT_Microchip_dsPIC_AND_PIC24 6 Yes Any
|
|
||||||
* PORT_TEXAS_INSTRUMENTS_TMS570 7 No Any
|
|
||||||
* PORT_TEXAS_INSTRUMENTS_MSP430 8 No Any
|
|
||||||
* PORT_MICROCHIP_PIC32 9 No Any
|
|
||||||
* PORT_XILINX_PPC405 10 No FreeRTOS
|
|
||||||
* PORT_XILINX_PPC440 11 No FreeRTOS
|
|
||||||
* PORT_XILINX_MICROBLAZE 12 No Any
|
|
||||||
* PORT_NXP_LPC210X 13 No Any
|
|
||||||
*****************************************************************************/
|
|
||||||
#define SELECTED_PORT PORT_Win32
|
|
||||||
|
|
||||||
#if (SELECTED_PORT == PORT_NOT_SET)
|
|
||||||
#error "You need to define SELECTED_PORT here!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* USE_PRIMASK_CS (for Cortex M devices only)
|
* USE_TRACE_ASSERT
|
||||||
*
|
|
||||||
* An integer constant that selects between two options for the critical
|
|
||||||
* sections of the recorder library.
|
|
||||||
*
|
*
|
||||||
* 0: The default FreeRTOS critical section (BASEPRI) - default setting
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
* 1: Always disable ALL interrupts (using PRIMASK)
|
* Default is 1.
|
||||||
*
|
*
|
||||||
* Option 0 uses the standard FreeRTOS macros for critical sections.
|
* If this is one (1), the TRACE_ASSERT macro will verify that a condition is
|
||||||
* However, on Cortex-M devices they only disable interrupts with priorities
|
* true. If the condition is false, vTraceError() will be called.
|
||||||
* below a certain configurable level, while higher priority ISRs remain active.
|
* This is used on several places in the recorder code for sanity checks on
|
||||||
* Such high-priority ISRs may not use the recorder functions in this mode.
|
* parameters. Can be switched off to reduce CPU usage of the tracing.
|
||||||
*
|
*****************************************************************************/
|
||||||
* Option 1 allows you to safely call the recorder from any ISR, independent of
|
#define USE_TRACE_ASSERT 1
|
||||||
* the interrupt priority. This mode may however cause higher IRQ latencies
|
|
||||||
* (some microseconds) since ALL configurable interrupts are disabled during
|
/*******************************************************************************
|
||||||
* the recorder's critical sections in this mode, using the PRIMASK register.
|
* USE_SEPARATE_USER_EVENT_BUFFER
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
* Default is zero (0).
|
||||||
|
*
|
||||||
|
* This enables and disables the use of the separate user event buffer. Using
|
||||||
|
* this separate buffer has the benefit of not overwriting the user events with
|
||||||
|
* kernel events (usually generated at a much higher rate), i.e., when using
|
||||||
|
* ring-buffer mode.
|
||||||
|
*
|
||||||
|
* Note: When using the separate user event buffer, you may get an artificial
|
||||||
|
* task instance named "Unknown actor". This is added as a placeholder when the
|
||||||
|
* user event history is longer than the task scheduling history.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define USE_PRIMASK_CS 0
|
#define USE_SEPARATE_USER_EVENT_BUFFER 0
|
||||||
|
|
||||||
/******************************************************************************
|
/*******************************************************************************
|
||||||
* HEAP_SIZE_BELOW_16M
|
* USER_EVENT_BUFFER_SIZE
|
||||||
*
|
*
|
||||||
* An integer constant that can be used to reduce the buffer usage of memory
|
* Macro which should be defined as an integer value.
|
||||||
* allocation events (malloc/free). This value should be 1 if the heap size is
|
*
|
||||||
* below 16 MB (2^24 byte), and you can live with addresses truncated to the
|
* This defines the capacity of the user event buffer, in number of slots.
|
||||||
* lower 24 bit. Otherwise set it to 0 to get the full 32-bit addresses.
|
* A single user event can use between 1 and X slots, depending on the data.
|
||||||
******************************************************************************/
|
*
|
||||||
#define HEAP_SIZE_BELOW_16M 0
|
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
||||||
|
******************************************************************************/
|
||||||
|
#define USER_EVENT_BUFFER_SIZE 10
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* USER_EVENT_CHANNELS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* This defines the number of allowed user event channels.
|
||||||
|
*
|
||||||
|
* Only in use if USE_SEPARATE_USER_EVENT_BUFFER is set to 1.
|
||||||
|
******************************************************************************/
|
||||||
|
#define CHANNEL_FORMAT_PAIRS 32
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,16 @@ mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.
|
||||||
The simply blinky demo is implemented and described in main_blinky.c. The more
|
The simply blinky demo is implemented and described in main_blinky.c. The more
|
||||||
comprehensive test and demo application is implemented and described in
|
comprehensive test and demo application is implemented and described in
|
||||||
main_full.c. */
|
main_full.c. */
|
||||||
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
|
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
|
||||||
|
|
||||||
|
/* This demo uses heap_5.c, and these constants define the sizes of the regions
|
||||||
|
that make up the total heap. This is only done to provide an example of heap_5
|
||||||
|
being used as this demo could easily create one large heap region instead of
|
||||||
|
multiple smaller heap regions - in which case heap_4.c would be the more
|
||||||
|
appropriate choice. */
|
||||||
|
#define mainREGION_1_SIZE 3001
|
||||||
|
#define mainREGION_2_SIZE 18105
|
||||||
|
#define mainREGION_3_SIZE 1107
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||||
|
@ -114,15 +123,28 @@ main_full.c. */
|
||||||
extern void main_blinky( void );
|
extern void main_blinky( void );
|
||||||
extern void main_full( void );
|
extern void main_full( void );
|
||||||
|
|
||||||
/* Some of the RTOS hook (callback) functions only need special processing when
|
/*
|
||||||
the full demo is being used. The simply blinky demo has no special requirements,
|
* Some of the RTOS hook (callback) functions only need special processing when
|
||||||
so these functions are called from the hook functions defined in this file, but
|
* the full demo is being used. The simply blinky demo has no special
|
||||||
are defined in main_full.c. */
|
* requirements, so these functions are called from the hook functions defined
|
||||||
|
* in this file, but are defined in main_full.c.
|
||||||
|
*/
|
||||||
void vFullDemoTickHookFunction( void );
|
void vFullDemoTickHookFunction( void );
|
||||||
void vFullDemoIdleFunction( void );
|
void vFullDemoIdleFunction( void );
|
||||||
|
|
||||||
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
|
/*
|
||||||
within this file. */
|
* This demo uses heap_5.c, so start by defining some heap regions. This is
|
||||||
|
* only done to provide an example as this demo could easily create one large
|
||||||
|
* heap region instead of multiple smaller heap regions - in which case heap_4.c
|
||||||
|
* would be the more appropriate choice. No initialisation is required when
|
||||||
|
* heap_4.c is used.
|
||||||
|
*/
|
||||||
|
static void prvInitialiseHeap( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes for the standard FreeRTOS callback/hook functions implemented
|
||||||
|
* within this file.
|
||||||
|
*/
|
||||||
void vApplicationMallocFailedHook( void );
|
void vApplicationMallocFailedHook( void );
|
||||||
void vApplicationIdleHook( void );
|
void vApplicationIdleHook( void );
|
||||||
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
|
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
|
||||||
|
@ -145,6 +167,13 @@ static portBASE_TYPE xTraceRunning = pdTRUE;
|
||||||
|
|
||||||
int main( void )
|
int main( void )
|
||||||
{
|
{
|
||||||
|
/* This demo uses heap_5.c, so start by defining some heap regions. This
|
||||||
|
is only done to provide an example as this demo could easily create one
|
||||||
|
large heap region instead of multiple smaller heap regions - in which case
|
||||||
|
heap_4.c would be the more appropriate choice. No initialisation is
|
||||||
|
required when heap_4.c is used. */
|
||||||
|
prvInitialiseHeap();
|
||||||
|
|
||||||
/* Initialise the trace recorder and create the label used to post user
|
/* Initialise the trace recorder and create the label used to post user
|
||||||
events to the trace recording on each tick interrupt. */
|
events to the trace recording on each tick interrupt. */
|
||||||
vTraceInitTraceData();
|
vTraceInitTraceData();
|
||||||
|
@ -263,14 +292,14 @@ void vApplicationTickHook( void )
|
||||||
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
|
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
|
||||||
{
|
{
|
||||||
static portBASE_TYPE xPrinted = pdFALSE;
|
static portBASE_TYPE xPrinted = pdFALSE;
|
||||||
|
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
|
||||||
|
|
||||||
/* Parameters are not used. */
|
/* Parameters are not used. */
|
||||||
( void ) ulLine;
|
( void ) ulLine;
|
||||||
( void ) pcFileName;
|
( void ) pcFileName;
|
||||||
|
|
||||||
taskDISABLE_INTERRUPTS();
|
taskENTER_CRITICAL();
|
||||||
__asm volatile( "int $3" );
|
{
|
||||||
|
|
||||||
/* Stop the trace recording. */
|
/* Stop the trace recording. */
|
||||||
if( xPrinted == pdFALSE )
|
if( xPrinted == pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -282,7 +311,16 @@ static portBASE_TYPE xPrinted = pdFALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taskENABLE_INTERRUPTS();
|
/* You can step out of this function to debug the assertion by using
|
||||||
|
the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
|
||||||
|
value. */
|
||||||
|
while( ulSetToNonZeroInDebuggerToContinue == 0 )
|
||||||
|
{
|
||||||
|
__asm volatile( "NOP" );
|
||||||
|
__asm volatile( "NOP" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -303,3 +341,34 @@ FILE* pxOutputFile;
|
||||||
printf( "\r\nFailed to create trace dump file\r\n" );
|
printf( "\r\nFailed to create trace dump file\r\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInitialiseHeap( void )
|
||||||
|
{
|
||||||
|
/* This demo uses heap_5.c, so start by defining some heap regions. This is
|
||||||
|
only done to provide an example as this demo could easily create one large heap
|
||||||
|
region instead of multiple smaller heap regions - in which case heap_4.c would
|
||||||
|
be the more appropriate choice. No initialisation is required when heap_4.c is
|
||||||
|
used. The xHeapRegions structure requires the regions to be defined in order,
|
||||||
|
so this just creates one big array, then populates the structure with offsets
|
||||||
|
into the array - with gaps in between and messy alignment just for test
|
||||||
|
purposes. */
|
||||||
|
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
|
||||||
|
volatile uint32_t ulAdditionalOffset = 19; /* Just to prevent 'condition is always true' warnings in configASSERT(). */
|
||||||
|
const HeapRegion_t xHeapRegions[] =
|
||||||
|
{
|
||||||
|
/* Start address with dummy offsets Size */
|
||||||
|
{ ucHeap + 1, mainREGION_1_SIZE },
|
||||||
|
{ ucHeap + 15 + mainREGION_1_SIZE, mainREGION_2_SIZE },
|
||||||
|
{ ucHeap + 19 + mainREGION_1_SIZE + mainREGION_2_SIZE, mainREGION_3_SIZE },
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Sanity check that the sizes and offsets defined actually fit into the
|
||||||
|
array. */
|
||||||
|
configASSERT( ( ulAdditionalOffset + mainREGION_1_SIZE + mainREGION_2_SIZE + mainREGION_3_SIZE ) < configTOTAL_HEAP_SIZE );
|
||||||
|
|
||||||
|
vPortDefineHeapRegions( xHeapRegions );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,7 @@ static void prvQueueSendTask( void *pvParameters )
|
||||||
{
|
{
|
||||||
TickType_t xNextWakeTime;
|
TickType_t xNextWakeTime;
|
||||||
const unsigned long ulValueToSend = 100UL;
|
const unsigned long ulValueToSend = 100UL;
|
||||||
|
const TickType_t xBlockTime = pdMS_TO_TICKS( mainQUEUE_SEND_FREQUENCY_MS );
|
||||||
|
|
||||||
/* Remove compiler warning in the case that configASSERT() is not
|
/* Remove compiler warning in the case that configASSERT() is not
|
||||||
defined. */
|
defined. */
|
||||||
|
@ -207,7 +208,7 @@ const unsigned long ulValueToSend = 100UL;
|
||||||
The block time is specified in ticks, the constant used converts ticks
|
The block time is specified in ticks, the constant used converts ticks
|
||||||
to ms. While in the Blocked state this task will not consume any CPU
|
to ms. While in the Blocked state this task will not consume any CPU
|
||||||
time. */
|
time. */
|
||||||
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
|
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
|
||||||
|
|
||||||
/* Send to the queue - causing the queue receive task to unblock and
|
/* Send to the queue - causing the queue receive task to unblock and
|
||||||
toggle the LED. 0 is used as the block time so the sending operation
|
toggle the LED. 0 is used as the block time so the sending operation
|
||||||
|
|
|
@ -133,6 +133,8 @@
|
||||||
#include "QueueSet.h"
|
#include "QueueSet.h"
|
||||||
#include "QueueOverwrite.h"
|
#include "QueueOverwrite.h"
|
||||||
#include "EventGroupsDemo.h"
|
#include "EventGroupsDemo.h"
|
||||||
|
#include "IntSemTest.h"
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
|
||||||
/* Priorities at which the tasks are created. */
|
/* Priorities at which the tasks are created. */
|
||||||
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||||
|
@ -195,6 +197,7 @@ int main_full( void )
|
||||||
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
|
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
|
||||||
|
|
||||||
/* Create the standard demo tasks. */
|
/* Create the standard demo tasks. */
|
||||||
|
vStartTaskNotifyTask();
|
||||||
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
||||||
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||||
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
||||||
|
@ -209,6 +212,7 @@ int main_full( void )
|
||||||
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
|
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
|
||||||
xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
vStartEventGroupTasks();
|
vStartEventGroupTasks();
|
||||||
|
vStartInterruptSemaphoreTasks();
|
||||||
|
|
||||||
#if( configUSE_PREEMPTION != 0 )
|
#if( configUSE_PREEMPTION != 0 )
|
||||||
{
|
{
|
||||||
|
@ -263,7 +267,16 @@ const TickType_t xCycleFrequency = 2500 / portTICK_PERIOD_MS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( xAreEventGroupTasksStillRunning() != pdTRUE )
|
if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "Error: Notification";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "Error: IntSem";
|
||||||
|
}
|
||||||
|
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
|
||||||
{
|
{
|
||||||
pcStatusMessage = "Error: EventGroup";
|
pcStatusMessage = "Error: EventGroup";
|
||||||
}
|
}
|
||||||
|
@ -374,7 +387,7 @@ void *pvAllocated;
|
||||||
xMutexToDelete = NULL;
|
xMutexToDelete = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exercise heap_4 a bit. The malloc failed hook will trap failed
|
/* Exercise heap_5 a bit. The malloc failed hook will trap failed
|
||||||
allocations so there is no need to test here. */
|
allocations so there is no need to test here. */
|
||||||
pvAllocated = pvPortMalloc( ( rand() % 100 ) + 1 );
|
pvAllocated = pvPortMalloc( ( rand() % 100 ) + 1 );
|
||||||
vPortFree( pvAllocated );
|
vPortFree( pvAllocated );
|
||||||
|
@ -402,6 +415,12 @@ void vFullDemoTickHookFunction( void )
|
||||||
|
|
||||||
/* Exercise event groups from interrupts. */
|
/* Exercise event groups from interrupts. */
|
||||||
vPeriodicEventGroupsProcessing();
|
vPeriodicEventGroupsProcessing();
|
||||||
|
|
||||||
|
/* Exercise giving mutexes from an interrupt. */
|
||||||
|
vInterruptSemaphorePeriodicTest();
|
||||||
|
|
||||||
|
/* Exercise using task notifications from an interrupt. */
|
||||||
|
xNotifyTaskFromISR();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
5
FreeRTOS/Demo/links_to_doc_pages_for_these_demos.url
Normal file
5
FreeRTOS/Demo/links_to_doc_pages_for_these_demos.url
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,2
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=http://www.freertos.org/a00090.html
|
||||||
|
IDList=
|
|
@ -1,3 +1,6 @@
|
||||||
|
Links to a documentation page for each demo are provided on the following
|
||||||
|
URL: http://www.freertos.org/a00090.html
|
||||||
|
|
||||||
Each RTOS port has a demo application to demonstrate it's use.
|
Each RTOS port has a demo application to demonstrate it's use.
|
||||||
|
|
||||||
+ The Demo/Common directory contains the demo application files as described on
|
+ The Demo/Common directory contains the demo application files as described on
|
||||||
|
|
|
@ -35,8 +35,10 @@ work under terms of your choice, provided that
|
||||||
|
|
||||||
+ The combined work is not itself an RTOS, scheduler, kernel or related product.
|
+ The combined work is not itself an RTOS, scheduler, kernel or related product.
|
||||||
|
|
||||||
+ The independent modules add significant and primary functionality to FreeRTOS
|
+ The independent modules add significant and primary functionality that is
|
||||||
and do not merely extend the existing functionality already present in FreeRTOS.
|
unrelated to multitasking, intertask communication or intertask signalling -
|
||||||
|
and therefore do not merely extend the functionality already present in
|
||||||
|
FreeRTOS.
|
||||||
|
|
||||||
Clause 2:
|
Clause 2:
|
||||||
|
|
||||||
|
|
|
@ -276,6 +276,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
/* Check the user is not attempting to wait on the bits used by the kernel
|
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||||
itself, and that at least one bit is being requested. */
|
itself, and that at least one bit is being requested. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
configASSERT( uxBitsToWaitFor != 0 );
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
@ -421,6 +422,7 @@ EventBits_t uxReturn;
|
||||||
|
|
||||||
/* Check the user is not attempting to clear the bits used by the kernel
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
itself. */
|
itself. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
|
@ -482,6 +484,7 @@ BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
/* Check the user is not attempting to set the bits used by the kernel
|
/* Check the user is not attempting to set the bits used by the kernel
|
||||||
itself. */
|
itself. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
|
@ -723,6 +723,10 @@ extern "C" {
|
||||||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TASK_NOTIFICATIONS
|
||||||
|
#define configUSE_TASK_NOTIFICATIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Definitions to allow backward compatibility with FreeRTOS versions prior to
|
/* Definitions to allow backward compatibility with FreeRTOS versions prior to
|
||||||
V8 if desired. */
|
V8 if desired. */
|
||||||
#ifndef configENABLE_BACKWARD_COMPATIBILITY
|
#ifndef configENABLE_BACKWARD_COMPATIBILITY
|
||||||
|
|
317
FreeRTOS/Source/include/deprecated_definitions.h
Normal file
317
FreeRTOS/Source/include/deprecated_definitions.h
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DEPRECATED_DEFINITIONS_H
|
||||||
|
#define DEPRECATED_DEFINITIONS_H
|
||||||
|
|
||||||
|
|
||||||
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
|
pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
|
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
|
of setting the compiler's include path such that it found the correct
|
||||||
|
portmacro.h file - removing the need for the constant and allowing the
|
||||||
|
portmacro.h file to be located anywhere in relation to the port being used. The
|
||||||
|
definitions below remain in the code for backward compatibility only. New
|
||||||
|
projects should not use them. */
|
||||||
|
|
||||||
|
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||||
|
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||||
|
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MEGA_AVR
|
||||||
|
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_MEGA_AVR
|
||||||
|
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC24_PORT
|
||||||
|
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_DSPIC_PORT
|
||||||
|
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC18F_PORT
|
||||||
|
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC32MX_PORT
|
||||||
|
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _FEDPICC
|
||||||
|
#include "libFreeRTOS/Include/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDCC_CYGNAL
|
||||||
|
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARM7
|
||||||
|
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARM7_ECLIPSE
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROWLEY_LPC23xx
|
||||||
|
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_MSP430
|
||||||
|
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MSP430
|
||||||
|
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROWLEY_MSP430
|
||||||
|
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||||
|
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM7_GCC
|
||||||
|
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM7_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM9XE_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LPC2000_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR71X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR75X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR75X_GCC
|
||||||
|
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR91X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_H8S
|
||||||
|
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_AT91FR40008
|
||||||
|
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RVDS_ARMCM3_LM3S102
|
||||||
|
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARMCM3_LM3S102
|
||||||
|
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARMCM3
|
||||||
|
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_ARM_CM3
|
||||||
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_ARMCM3_LM
|
||||||
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HCS12_CODE_WARRIOR
|
||||||
|
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROBLAZE_GCC
|
||||||
|
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TERN_EE
|
||||||
|
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_HCS12
|
||||||
|
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MCF5235
|
||||||
|
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLDFIRE_V2_GCC
|
||||||
|
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||||
|
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_PPC405
|
||||||
|
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_PPC440
|
||||||
|
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _16FX_SOFTUNE
|
||||||
|
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||||
|
/* A short file name has to be used in place of the normal
|
||||||
|
FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
|
#include "frconfig.h"
|
||||||
|
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BCC_FLASH_LITE_186_PORT
|
||||||
|
/* A short file name has to be used in place of the normal
|
||||||
|
FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
|
#include "frconfig.h"
|
||||||
|
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifdef __AVR32_AVR32A__
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ICCAVR32__
|
||||||
|
#ifdef __CORE__
|
||||||
|
#if __CORE__ == __AVR32A__
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __91467D
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __96340
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Fx3__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx3__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx3_L__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx2__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Hx2__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_78K0R_Kx3__
|
||||||
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_78K0R_Kx3L__
|
||||||
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||||
|
|
|
@ -70,253 +70,22 @@
|
||||||
#ifndef PORTABLE_H
|
#ifndef PORTABLE_H
|
||||||
#define PORTABLE_H
|
#define PORTABLE_H
|
||||||
|
|
||||||
/* Include the macro file relevant to the port being used.
|
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||||
NOTE: The following definitions are *DEPRECATED* as it is preferred to instead
|
pre-processor definition was used to ensure the pre-processor found the correct
|
||||||
just add the path to the correct portmacro.h header file to the compiler's
|
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||||
include path. */
|
of setting the compiler's include path such that it found the correct
|
||||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
portmacro.h file - removing the need for the constant and allowing the
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
portmacro.h file to be located anywhere in relation to the port being used.
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
Purely for reasons of backward compatibility the old method is still valid, but
|
||||||
#endif
|
to make it clear that new projects should not use it, support for the port
|
||||||
|
specific constants has been moved into the deprecated_definitions.h header
|
||||||
|
file. */
|
||||||
|
#include "deprecated_definitions.h"
|
||||||
|
|
||||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
did not result in a portmacro.h header file being included - and it should be
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
included here. In this case the path to the correct portmacro.h header file
|
||||||
#endif
|
must be set in the compiler's include path. */
|
||||||
|
|
||||||
#ifdef GCC_MEGA_AVR
|
|
||||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IAR_MEGA_AVR
|
|
||||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MPLAB_PIC24_PORT
|
|
||||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MPLAB_DSPIC_PORT
|
|
||||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MPLAB_PIC18F_PORT
|
|
||||||
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MPLAB_PIC32MX_PORT
|
|
||||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _FEDPICC
|
|
||||||
#include "libFreeRTOS/Include/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SDCC_CYGNAL
|
|
||||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_ARM7
|
|
||||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_ARM7_ECLIPSE
|
|
||||||
#include "portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ROWLEY_LPC23xx
|
|
||||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IAR_MSP430
|
|
||||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_MSP430
|
|
||||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ROWLEY_MSP430
|
|
||||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
|
||||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SAM7_GCC
|
|
||||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SAM7_IAR
|
|
||||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SAM9XE_IAR
|
|
||||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LPC2000_IAR
|
|
||||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STR71X_IAR
|
|
||||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STR75X_IAR
|
|
||||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STR75X_GCC
|
|
||||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STR91X_IAR
|
|
||||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_H8S
|
|
||||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_AT91FR40008
|
|
||||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RVDS_ARMCM3_LM3S102
|
|
||||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_ARMCM3_LM3S102
|
|
||||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_ARMCM3
|
|
||||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IAR_ARM_CM3
|
|
||||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IAR_ARMCM3_LM
|
|
||||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HCS12_CODE_WARRIOR
|
|
||||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MICROBLAZE_GCC
|
|
||||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TERN_EE
|
|
||||||
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_HCS12
|
|
||||||
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_MCF5235
|
|
||||||
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COLDFIRE_V2_GCC
|
|
||||||
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef COLDFIRE_V2_CODEWARRIOR
|
|
||||||
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_PPC405
|
|
||||||
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_PPC440
|
|
||||||
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _16FX_SOFTUNE
|
|
||||||
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
|
||||||
/* A short file name has to be used in place of the normal
|
|
||||||
FreeRTOSConfig.h when using the Borland compiler. */
|
|
||||||
#include "frconfig.h"
|
|
||||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BCC_FLASH_LITE_186_PORT
|
|
||||||
/* A short file name has to be used in place of the normal
|
|
||||||
FreeRTOSConfig.h when using the Borland compiler. */
|
|
||||||
#include "frconfig.h"
|
|
||||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#ifdef __AVR32_AVR32A__
|
|
||||||
#include "portmacro.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __ICCAVR32__
|
|
||||||
#ifdef __CORE__
|
|
||||||
#if __CORE__ == __AVR32A__
|
|
||||||
#include "portmacro.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __91467D
|
|
||||||
#include "portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __96340
|
|
||||||
#include "portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __IAR_V850ES_Fx3__
|
|
||||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __IAR_V850ES_Jx3__
|
|
||||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __IAR_V850ES_Jx3_L__
|
|
||||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __IAR_V850ES_Jx2__
|
|
||||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __IAR_V850ES_Hx2__
|
|
||||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __IAR_78K0R_Kx3__
|
|
||||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __IAR_78K0R_Kx3L__
|
|
||||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Catch all to ensure portmacro.h is included in the build. Newer demos
|
|
||||||
have the path as part of the project options, rather than as relative from
|
|
||||||
the project location. If portENTER_CRITICAL() has not been defined then
|
|
||||||
portmacro.h has not yet been included - as every portmacro.h provides a
|
|
||||||
portENTER_CRITICAL() definition. Check the demo application for your demo
|
|
||||||
to find the path to the correct portmacro.h file. */
|
|
||||||
#ifndef portENTER_CRITICAL
|
#ifndef portENTER_CRITICAL
|
||||||
#include "portmacro.h"
|
#include "portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -114,6 +114,16 @@ typedef enum
|
||||||
eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */
|
eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */
|
||||||
} eTaskState;
|
} eTaskState;
|
||||||
|
|
||||||
|
/* Actions that can be performed when vTaskNotify() is called. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eNoAction, /* Notify the task without updating its notify value. */
|
||||||
|
eSetBits, /* Set bits in the task's notification value. */
|
||||||
|
eIncrement, /* Increment the task's notification value. */
|
||||||
|
eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */
|
||||||
|
eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
|
||||||
|
} eNotifyAction;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used internally only.
|
* Used internally only.
|
||||||
*/
|
*/
|
||||||
|
@ -1358,6 +1368,432 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
|
||||||
*/
|
*/
|
||||||
void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
* <PRE>BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE>
|
||||||
|
*
|
||||||
|
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||||
|
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||||
|
*
|
||||||
|
* Events can be sent to a task using an intermediary object. Examples of such
|
||||||
|
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||||
|
* are a method of sending an event directly to a task without the need for such
|
||||||
|
* an intermediary object.
|
||||||
|
*
|
||||||
|
* A notification sent to a task can optionally perform an action, such as
|
||||||
|
* update, overwrite or increment the task's notification value. In that way
|
||||||
|
* task notifications can be used to send data to a task, or be used as light
|
||||||
|
* weight and fast binary or counting semaphores.
|
||||||
|
*
|
||||||
|
* A notification sent to a task will remain pending until it is cleared by the
|
||||||
|
* task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
|
||||||
|
* already in the Blocked state to wait for a notification when the notification
|
||||||
|
* arrives then the task will automatically be removed from the Blocked state
|
||||||
|
* (unblocked) and the notification cleared.
|
||||||
|
*
|
||||||
|
* A task can use xTaskNotifyWait() to [optionally] block to wait for a
|
||||||
|
* notification to be pending, or xTaskNotifyTake() to [optionally] block
|
||||||
|
* to wait for its notification value to have a non-zero value. The task does
|
||||||
|
* not consume any CPU time while it is in the Blocked state.
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||||
|
* it is best to use a task notification to send an event to a task compared to
|
||||||
|
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||||
|
* mutex or event group) to send an event to a task.
|
||||||
|
*
|
||||||
|
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||||
|
* task can be returned from the xTaskCreate() API function used to create the
|
||||||
|
* task, and the handle of the currently running task can be obtained by calling
|
||||||
|
* xTaskGetCurrentTaskHandle().
|
||||||
|
*
|
||||||
|
* @param ulValue Data that can be sent with the notification. How the data is
|
||||||
|
* used depends on the value of the eAction parameter.
|
||||||
|
*
|
||||||
|
* @param eAction Specifies how the notification updates the task's notification
|
||||||
|
* value, if at all. Valid values for eAction are as follows:
|
||||||
|
*
|
||||||
|
* eSetBits -
|
||||||
|
* The task's notification value is bitwise ORed with ulValue. xTaskNofify()
|
||||||
|
* always returns pdPASS in this case.
|
||||||
|
*
|
||||||
|
* eIncrement -
|
||||||
|
* The task's notification value is incremented. ulValue is not used and
|
||||||
|
* xTaskNotify() always returns pdPASS in this case.
|
||||||
|
*
|
||||||
|
* eSetValueWithOverwrite -
|
||||||
|
* The task's notification value is set to the value of ulValue, even if the
|
||||||
|
* task being notified had not yet processed the previous notification (the
|
||||||
|
* task already had a notification pending). xTaskNotify() always returns
|
||||||
|
* pdPASS in this case.
|
||||||
|
*
|
||||||
|
* eSetValueWithoutOverwrite -
|
||||||
|
* If the task being notified did not already have a notification pending then
|
||||||
|
* the task's notification value is set to ulValue and xTaskNotify() will
|
||||||
|
* return pdPASS. If the task being notified already had a notification
|
||||||
|
* pending then no action is performed and pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* eNoAction -
|
||||||
|
* The task receives a notification without its notification value being
|
||||||
|
* updated. ulValue is not used and xTaskNotify() always returns pdPASS in
|
||||||
|
* this case.
|
||||||
|
*
|
||||||
|
* @return Dependent on the value of eAction. See the description of the
|
||||||
|
* eAction parameter.
|
||||||
|
*
|
||||||
|
* \defgroup xTaskNotify xTaskNotify
|
||||||
|
* \ingroup TaskNotifications
|
||||||
|
*/
|
||||||
|
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
* <PRE>BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );</PRE>
|
||||||
|
*
|
||||||
|
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||||
|
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||||
|
*
|
||||||
|
* A version of xTaskNotify() that can be used from an interrupt service routine
|
||||||
|
* (ISR).
|
||||||
|
*
|
||||||
|
* Events can be sent to a task using an intermediary object. Examples of such
|
||||||
|
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||||
|
* are a method of sending an event directly to a task without the need for such
|
||||||
|
* an intermediary object.
|
||||||
|
*
|
||||||
|
* A notification sent to a task can optionally perform an action, such as
|
||||||
|
* update, overwrite or increment the task's notification value. In that way
|
||||||
|
* task notifications can be used to send data to a task, or be used as light
|
||||||
|
* weight and fast binary or counting semaphores.
|
||||||
|
*
|
||||||
|
* A notification sent to a task will remain pending until it is cleared by the
|
||||||
|
* task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
|
||||||
|
* already in the Blocked state to wait for a notification when the notification
|
||||||
|
* arrives then the task will automatically be removed from the Blocked state
|
||||||
|
* (unblocked) and the notification cleared.
|
||||||
|
*
|
||||||
|
* A task can use xTaskNotifyWait() to [optionally] block to wait for a
|
||||||
|
* notification to be pending, or xTaskNotifyTake() to [optionally] block
|
||||||
|
* to wait for its notification value to have a non-zero value. The task does
|
||||||
|
* not consume any CPU time while it is in the Blocked state.
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||||
|
* it is best to use a task notification to send an event to a task compared to
|
||||||
|
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||||
|
* mutex or event group) to send an event to a task.
|
||||||
|
*
|
||||||
|
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||||
|
* task can be returned from the xTaskCreate() API function used to create the
|
||||||
|
* task, and the handle of the currently running task can be obtained by calling
|
||||||
|
* xTaskGetCurrentTaskHandle().
|
||||||
|
*
|
||||||
|
* @param ulValue Data that can be sent with the notification. How the data is
|
||||||
|
* used depends on the value of the eAction parameter.
|
||||||
|
*
|
||||||
|
* @param eAction Specifies how the notification updates the task's notification
|
||||||
|
* value, if at all. Valid values for eAction are as follows:
|
||||||
|
*
|
||||||
|
* eSetBits -
|
||||||
|
* The task's notification value is bitwise ORed with ulValue. xTaskNofify()
|
||||||
|
* always returns pdPASS in this case.
|
||||||
|
*
|
||||||
|
* eIncrement -
|
||||||
|
* The task's notification value is incremented. ulValue is not used and
|
||||||
|
* xTaskNotify() always returns pdPASS in this case.
|
||||||
|
*
|
||||||
|
* eSetValueWithOverwrite -
|
||||||
|
* The task's notification value is set to the value of ulValue, even if the
|
||||||
|
* task being notified had not yet processed the previous notification (the
|
||||||
|
* task already had a notification pending). xTaskNotify() always returns
|
||||||
|
* pdPASS in this case.
|
||||||
|
*
|
||||||
|
* eSetValueWithoutOverwrite -
|
||||||
|
* If the task being notified did not already have a notification pending then
|
||||||
|
* the task's notification value is set to ulValue and xTaskNotify() will
|
||||||
|
* return pdPASS. If the task being notified already had a notification
|
||||||
|
* pending then no action is performed and pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* eNoAction -
|
||||||
|
* The task receives a notification without its notification value being
|
||||||
|
* updated. ulValue is not used and xTaskNotify() always returns pdPASS in
|
||||||
|
* this case.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set
|
||||||
|
* *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
|
||||||
|
* task to which the notification was sent to leave the Blocked state, and the
|
||||||
|
* unblocked task has a priority higher than the currently running task. If
|
||||||
|
* xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be requested before the interrupt is exited. How a context switch is
|
||||||
|
* requested from an ISR is dependent on the port - see the documentation page
|
||||||
|
* for the port in use.
|
||||||
|
*
|
||||||
|
* @return Dependent on the value of eAction. See the description of the
|
||||||
|
* eAction parameter.
|
||||||
|
*
|
||||||
|
* \defgroup xTaskNotify xTaskNotify
|
||||||
|
* \ingroup TaskNotifications
|
||||||
|
*/
|
||||||
|
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
* <PRE>BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );</pre>
|
||||||
|
*
|
||||||
|
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||||
|
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||||
|
*
|
||||||
|
* Events can be sent to a task using an intermediary object. Examples of such
|
||||||
|
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||||
|
* are a method of sending an event directly to a task without the need for such
|
||||||
|
* an intermediary object.
|
||||||
|
*
|
||||||
|
* A notification sent to a task can optionally perform an action, such as
|
||||||
|
* update, overwrite or increment the task's notification value. In that way
|
||||||
|
* task notifications can be used to send data to a task, or be used as light
|
||||||
|
* weight and fast binary or counting semaphores.
|
||||||
|
*
|
||||||
|
* A notification sent to a task will remain pending until it is cleared by the
|
||||||
|
* task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
|
||||||
|
* already in the Blocked state to wait for a notification when the notification
|
||||||
|
* arrives then the task will automatically be removed from the Blocked state
|
||||||
|
* (unblocked) and the notification cleared.
|
||||||
|
*
|
||||||
|
* A task can use xTaskNotifyWait() to [optionally] block to wait for a
|
||||||
|
* notification to be pending, or xTaskNotifyTake() to [optionally] block
|
||||||
|
* to wait for its notification value to have a non-zero value. The task does
|
||||||
|
* not consume any CPU time while it is in the Blocked state.
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||||
|
* it is best to use a task notification to send an event to a task compared to
|
||||||
|
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||||
|
* mutex or event group) to send an event to a task.
|
||||||
|
*
|
||||||
|
* @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value
|
||||||
|
* will be cleared in the calling task's notification value before the task
|
||||||
|
* checks to see if any notifications are pending, and optionally blocks if no
|
||||||
|
* notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if
|
||||||
|
* limits.h is included) or 0xffffffffUL (if limits.h is not included) will have
|
||||||
|
* the effect of resetting the task's notification value to 0. Setting
|
||||||
|
* ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged.
|
||||||
|
*
|
||||||
|
* @param ulBitsToClearOnExit If a notification is pending or received before
|
||||||
|
* the calling task exits the xTaskNotifyWait() function then the task's
|
||||||
|
* notification value (see the xTaskNotify() API function) is passed out using
|
||||||
|
* the pulNotificationValue parameter. Then any bits that are set in
|
||||||
|
* ulBitsToClearOnExit will be cleared in the task's notification value (note
|
||||||
|
* *pulNotificationValue is set before any bits are cleared). Setting
|
||||||
|
* ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL
|
||||||
|
* (if limits.h is not included) will have the effect of resetting the task's
|
||||||
|
* notification value to 0 before the function exits. Setting
|
||||||
|
* ulBitsToClearOnExit to 0 will leave the task's notification value unchanged
|
||||||
|
* when the function exits (in which case the value passed out in
|
||||||
|
* pulNotificationValue will match the task's notification value).
|
||||||
|
*
|
||||||
|
* @param pulNotificationValue Used to pass the task's notification value out
|
||||||
|
* of the function. Note the value passed out will not be effected by the
|
||||||
|
* clearing of any bits caused by ulBitsToClearOnExit being non-zero.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time that the task should wait in
|
||||||
|
* the Blocked state for a notification to be received, should a notification
|
||||||
|
* not already be pending when xTaskNotifyWait() was called. The task
|
||||||
|
* will not consume any processing time while it is in the Blocked state. This
|
||||||
|
* is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be
|
||||||
|
* used to convert a time specified in milliseconds to a time specified in
|
||||||
|
* ticks.
|
||||||
|
*
|
||||||
|
* @return If a notification was received (including notifications that were
|
||||||
|
* already pending when xTaskNotifyWait was called) then pdPASS is
|
||||||
|
* returned. Otherwise pdFAIL is returned.
|
||||||
|
*
|
||||||
|
* \defgroup xTaskNotifyWait xTaskNotifyWait
|
||||||
|
* \ingroup TaskNotifications
|
||||||
|
*/
|
||||||
|
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
* <PRE>BaseType_t xTaskNotifyGive( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this macro to be
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||||
|
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||||
|
*
|
||||||
|
* Events can be sent to a task using an intermediary object. Examples of such
|
||||||
|
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||||
|
* are a method of sending an event directly to a task without the need for such
|
||||||
|
* an intermediary object.
|
||||||
|
*
|
||||||
|
* A notification sent to a task can optionally perform an action, such as
|
||||||
|
* update, overwrite or increment the task's notification value. In that way
|
||||||
|
* task notifications can be used to send data to a task, or be used as light
|
||||||
|
* weight and fast binary or counting semaphores.
|
||||||
|
*
|
||||||
|
* xTaskNotifyGive() is a helper macro intended for use when task notifications
|
||||||
|
* are used as light weight and faster binary or counting semaphore equivalents.
|
||||||
|
* Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function,
|
||||||
|
* the equivalent action that instead uses a task notification is
|
||||||
|
* xTaskNotifyGive().
|
||||||
|
*
|
||||||
|
* When task notifications are being used as a binary or counting semaphore
|
||||||
|
* equivalent then the task being notified should wait for the notification
|
||||||
|
* using the ulTaskNotificationTake() API function rather than the
|
||||||
|
* xTaskNotifyWait() API function.
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for more details.
|
||||||
|
*
|
||||||
|
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||||
|
* task can be returned from the xTaskCreate() API function used to create the
|
||||||
|
* task, and the handle of the currently running task can be obtained by calling
|
||||||
|
* xTaskGetCurrentTaskHandle().
|
||||||
|
*
|
||||||
|
* @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the
|
||||||
|
* eAction parameter set to eIncrement - so pdPASS is always returned.
|
||||||
|
*
|
||||||
|
* \defgroup xTaskNotifyGive xTaskNotifyGive
|
||||||
|
* \ingroup TaskNotifications
|
||||||
|
*/
|
||||||
|
#define xTaskNotifyGive( xTaskToNotify ) xTaskNotify( ( xTaskToNotify ), 0, eIncrement );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
* <PRE>BaseType_t xTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this macro to be
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||||
|
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||||
|
*
|
||||||
|
* A version of xTaskNotifyGive() that can be called from an interrupt service
|
||||||
|
* routine (ISR).
|
||||||
|
*
|
||||||
|
* Events can be sent to a task using an intermediary object. Examples of such
|
||||||
|
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||||
|
* are a method of sending an event directly to a task without the need for such
|
||||||
|
* an intermediary object.
|
||||||
|
*
|
||||||
|
* A notification sent to a task can optionally perform an action, such as
|
||||||
|
* update, overwrite or increment the task's notification value. In that way
|
||||||
|
* task notifications can be used to send data to a task, or be used as light
|
||||||
|
* weight and fast binary or counting semaphores.
|
||||||
|
*
|
||||||
|
* xTaskNotifyGiveFromISR() is a helper macro intended for use when task
|
||||||
|
* notifications are used as light weight and faster binary or counting
|
||||||
|
* semaphore equivalents. Actual FreeRTOS semaphores are given from an ISR
|
||||||
|
* using the xSemaphoreGiveFromISR() API function, the equivalent action that
|
||||||
|
* instead uses a task notification is xTaskNotifyGiveFromISR().
|
||||||
|
*
|
||||||
|
* When task notifications are being used as a binary or counting semaphore
|
||||||
|
* equivalent then the task being notified should wait for the notification
|
||||||
|
* using the ulTaskNotificationTake() API function rather than the
|
||||||
|
* xTaskNotifyWait() API function.
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for more details.
|
||||||
|
*
|
||||||
|
* @param xTaskToNotify The handle of the task being notified. The handle to a
|
||||||
|
* task can be returned from the xTaskCreate() API function used to create the
|
||||||
|
* task, and the handle of the currently running task can be obtained by calling
|
||||||
|
* xTaskGetCurrentTaskHandle().
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken xTaskNotifyGiveFromISR() will set
|
||||||
|
* *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
|
||||||
|
* task to which the notification was sent to leave the Blocked state, and the
|
||||||
|
* unblocked task has a priority higher than the currently running task. If
|
||||||
|
* xTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
|
||||||
|
* should be requested before the interrupt is exited. How a context switch is
|
||||||
|
* requested from an ISR is dependent on the port - see the documentation page
|
||||||
|
* for the port in use.
|
||||||
|
*
|
||||||
|
* @return xTaskNotifyGiveFromISR() is a macro that calls xTaskNotifyFromISR()
|
||||||
|
* with the eAction parameter set to eIncrement - so pdPASS is always returned.
|
||||||
|
*
|
||||||
|
* \defgroup xTaskNotifyWait xTaskNotifyWait
|
||||||
|
* \ingroup TaskNotifications
|
||||||
|
*/
|
||||||
|
#define xTaskNotifyGiveFromISR( xTaskToNotify, pxHigherPriorityTaskWoken ) xTaskNotifyFromISR( ( xTaskToNotify ), 0, eIncrement, ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* task. h
|
||||||
|
* <PRE>uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );</pre>
|
||||||
|
*
|
||||||
|
* configUSE_TASK_NOTIFICATIONS must be defined as 1 for this function to be
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
|
||||||
|
* "notification value", which is a 32-bit unsigned integer (uint32_t).
|
||||||
|
*
|
||||||
|
* Events can be sent to a task using an intermediary object. Examples of such
|
||||||
|
* objects are queues, semaphores, mutexes and event groups. Task notifications
|
||||||
|
* are a method of sending an event directly to a task without the need for such
|
||||||
|
* an intermediary object.
|
||||||
|
*
|
||||||
|
* A notification sent to a task can optionally perform an action, such as
|
||||||
|
* update, overwrite or increment the task's notification value. In that way
|
||||||
|
* task notifications can be used to send data to a task, or be used as light
|
||||||
|
* weight and fast binary or counting semaphores.
|
||||||
|
*
|
||||||
|
* ulTaskNotifyTake() is intended for use when a task notification is used as a
|
||||||
|
* faster and lighter weight binary or counting semaphore alternative. Actual
|
||||||
|
* FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the
|
||||||
|
* equivalent action that instead uses a task notification is
|
||||||
|
* xTaskNotifyTake().
|
||||||
|
*
|
||||||
|
* When a task is using its notification value as a binary or counting semaphore
|
||||||
|
* other tasks should send notifications to it using the xTaskNotifyGive()
|
||||||
|
* macro, or xTaskNotify() function with the eAction parameter set to
|
||||||
|
* eIncrement.
|
||||||
|
*
|
||||||
|
* xTaskNotifyTake() can either clear the task's notification value to
|
||||||
|
* zero on exit, in which case the notification value acts like a binary
|
||||||
|
* semaphore, or decrement the task's notification value on exit, in which case
|
||||||
|
* the notification value acts like a counting semaphore.
|
||||||
|
*
|
||||||
|
* A task can use xTaskNotifyTake() to [optionally] block to wait for a
|
||||||
|
* the tasks notification value to be non-zero. The task does not consume any
|
||||||
|
* CPU time while it is in the Blocked state.
|
||||||
|
*
|
||||||
|
* Where as xTaskNotifyWait() will return when a notification is pending,
|
||||||
|
* xTaskNotifyTake() will return when the task's notification value is
|
||||||
|
* not zero.
|
||||||
|
*
|
||||||
|
* See http://www.FreeRTOS.org/RTOS_task_notifications.html for details of when
|
||||||
|
* it is best to use a task notification to send an event to a task compared to
|
||||||
|
* when it is best to use an intermediary object (such as a queue, semaphore,
|
||||||
|
* mutex or event group) to send an event to a task.
|
||||||
|
*
|
||||||
|
* @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's
|
||||||
|
* notification value is decremented when the function exits. In this way the
|
||||||
|
* notification value acts like a counting semaphore. If xClearCountOnExit is
|
||||||
|
* not pdFALSE then the task's notification value is cleared to zero when the
|
||||||
|
* function exits. In this way the notification value acts like a binary
|
||||||
|
* semaphore.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time that the task should wait in
|
||||||
|
* the Blocked state for the task's notification value to be greater than zero,
|
||||||
|
* should the count not already be greater than zero when
|
||||||
|
* xTaskNotifyTake() was called. The task will not consume any processing
|
||||||
|
* time while it is in the Blocked state. This is specified in kernel ticks,
|
||||||
|
* the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time
|
||||||
|
* specified in milliseconds to a time specified in ticks.
|
||||||
|
*
|
||||||
|
* @return The task's notification count before it is either cleared to zero or
|
||||||
|
* decremented (see the xClearCountOnExit parameter).
|
||||||
|
*
|
||||||
|
* \defgroup ulTaskNotifyTake ulTaskNotifyTake
|
||||||
|
* \ingroup TaskNotifications
|
||||||
|
*/
|
||||||
|
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
|
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
|
@ -125,13 +125,12 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
|
|
||||||
If the list already contains a list item with the same item value then
|
If the list already contains a list item with the same item value then the
|
||||||
the new list item should be placed after it. This ensures that TCB's which
|
new list item should be placed after it. This ensures that TCB's which are
|
||||||
are stored in ready lists (all of which have the same xItemValue value)
|
stored in ready lists (all of which have the same xItemValue value) get a
|
||||||
get an equal share of the CPU. However, if the xItemValue is the same as
|
share of the CPU. However, if the xItemValue is the same as the back marker
|
||||||
the back marker the iteration loop below will not end. This means we need
|
the iteration loop below will not end. Therefore the value is checked
|
||||||
to guard against this by checking the value first and modifying the
|
first, and the algorithm slightly modified if necessary. */
|
||||||
algorithm slightly if necessary. */
|
|
||||||
if( xValueOfInsertion == portMAX_DELAY )
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
{
|
{
|
||||||
pxIterator = pxList->xListEnd.pxPrevious;
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
|
@ -139,27 +138,31 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* *** NOTE ***********************************************************
|
/* *** NOTE ***********************************************************
|
||||||
If you find your application is crashing here then likely causes are:
|
If you find your application is crashing here then likely causes are
|
||||||
|
listed below. In addition see http://www.freertos.org/FAQHelp.html for
|
||||||
|
more tips, and ensure configASSERT() is defined!
|
||||||
|
http://www.freertos.org/a00110.html#configASSERT
|
||||||
|
|
||||||
1) Stack overflow -
|
1) Stack overflow -
|
||||||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||||
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||||
parts where numerically high priority values denote low actual
|
parts where numerically high priority values denote low actual
|
||||||
interrupt priorities, which can seem counter intuitive. See
|
interrupt priorities, which can seem counter intuitive. See
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
|
||||||
|
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||||
|
http://www.freertos.org/a00110.html
|
||||||
3) Calling an API function from within a critical section or when
|
3) Calling an API function from within a critical section or when
|
||||||
the scheduler is suspended, or calling an API function that does
|
the scheduler is suspended, or calling an API function that does
|
||||||
not end in "FromISR" from an interrupt.
|
not end in "FromISR" from an interrupt.
|
||||||
4) Using a queue or semaphore before it has been initialised or
|
4) Using a queue or semaphore before it has been initialised or
|
||||||
before the scheduler has been started (are interrupts firing
|
before the scheduler has been started (are interrupts firing
|
||||||
before vTaskStartScheduler() has been called?).
|
before vTaskStartScheduler() has been called?).
|
||||||
See http://www.freertos.org/FAQHelp.html for more tips, and ensure
|
|
||||||
configASSERT() is defined! http://www.freertos.org/a00110.html#configASSERT
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
{
|
{
|
||||||
/* There is nothing to do here, we are just iterating to the
|
/* There is nothing to do here, just iterating to the wanted
|
||||||
wanted insertion position. */
|
insertion position. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ the CPU itself before modifying certain hardware registers. */
|
||||||
{ \
|
{ \
|
||||||
portCPU_IRQ_DISABLE(); \
|
portCPU_IRQ_DISABLE(); \
|
||||||
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
|
||||||
__asm( "DSB \n" \
|
__asm volatile ( "DSB \n" \
|
||||||
"ISB \n" ); \
|
"ISB \n" ); \
|
||||||
portCPU_IRQ_ENABLE(); \
|
portCPU_IRQ_ENABLE(); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000UL )
|
#define portINITIAL_XPSR ( 0x01000000UL )
|
||||||
|
|
|
@ -111,7 +111,7 @@
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
@ -384,24 +384,10 @@ void vPortEndScheduler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__asm volatile( "dsb" );
|
|
||||||
__asm volatile( "isb" );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__asm volatile( "dsb" );
|
|
||||||
__asm volatile( "isb" );
|
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
|
@ -426,37 +412,6 @@ void vPortExitCritical( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__attribute__(( naked )) uint32_t ulPortSetInterruptMask( void )
|
|
||||||
{
|
|
||||||
__asm volatile \
|
|
||||||
( \
|
|
||||||
" mrs r0, basepri \n" \
|
|
||||||
" mov r1, %0 \n" \
|
|
||||||
" msr basepri, r1 \n" \
|
|
||||||
" bx lr \n" \
|
|
||||||
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \
|
|
||||||
);
|
|
||||||
|
|
||||||
/* This return will not be reached but is necessary to prevent compiler
|
|
||||||
warnings. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__attribute__(( naked )) void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
|
||||||
{
|
|
||||||
__asm volatile \
|
|
||||||
( \
|
|
||||||
" msr basepri, r0 \n" \
|
|
||||||
" bx lr \n" \
|
|
||||||
:::"r0" \
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Just to avoid compiler warnings. */
|
|
||||||
( void ) ulNewMaskValue;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void xPortPendSVHandler( void )
|
void xPortPendSVHandler( void )
|
||||||
{
|
{
|
||||||
/* This is a naked function. */
|
/* This is a naked function. */
|
||||||
|
@ -480,6 +435,8 @@ void xPortPendSVHandler( void )
|
||||||
" stmdb sp!, {r3} \n"
|
" stmdb sp!, {r3} \n"
|
||||||
" mov r0, %0 \n"
|
" mov r0, %0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
" bl vTaskSwitchContext \n"
|
" bl vTaskSwitchContext \n"
|
||||||
" mov r0, #0 \n"
|
" mov r0, #0 \n"
|
||||||
" msr basepri, r0 \n"
|
" msr basepri, r0 \n"
|
||||||
|
|
|
@ -109,25 +109,21 @@ typedef unsigned long UBaseType_t;
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
|
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
@ -188,6 +184,53 @@ not necessary for to use this port. They are defined so the common demo files
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs %0, basepri \n" \
|
||||||
|
" mov %1, %2 \n" \
|
||||||
|
" msr basepri, %1 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return ulOriginalBASEPRI;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" msr basepri, %0 " :: "r" ( ulNewMaskValue )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortYield( void )
|
||||||
|
{
|
||||||
|
/* Set a PendSV to request a context switch. */
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
|
||||||
|
/* Barriers are normally not required but do ensure the code is completely
|
||||||
|
within the specified behaviour for the architecture. */
|
||||||
|
__asm volatile( "dsb" );
|
||||||
|
__asm volatile( "isb" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -217,7 +217,7 @@ typedef struct PORT_REGISTER_DUMP
|
||||||
/* The human readable name of the task that was running at the time the
|
/* The human readable name of the task that was running at the time the
|
||||||
exception occurred. This is the name that was given to the task when the
|
exception occurred. This is the name that was given to the task when the
|
||||||
task was created using the FreeRTOS xTaskCreate() API function. */
|
task was created using the FreeRTOS xTaskCreate() API function. */
|
||||||
int8_t *pcCurrentTaskName;
|
char *pcCurrentTaskName;
|
||||||
|
|
||||||
/* The handle of the task that was running a the time the exception
|
/* The handle of the task that was running a the time the exception
|
||||||
occurred. */
|
occurred. */
|
||||||
|
|
|
@ -114,7 +114,7 @@
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to set up the initial stack. */
|
/* Constants required to set up the initial stack. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
|
|
|
@ -118,7 +118,7 @@
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
@ -335,24 +335,10 @@ void vPortEndScheduler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
|
|
|
@ -72,8 +72,6 @@
|
||||||
EXTERN vTaskSwitchContext
|
EXTERN vTaskSwitchContext
|
||||||
|
|
||||||
PUBLIC xPortPendSVHandler
|
PUBLIC xPortPendSVHandler
|
||||||
PUBLIC ulPortSetInterruptMask
|
|
||||||
PUBLIC vPortClearInterruptMask
|
|
||||||
PUBLIC vPortSVCHandler
|
PUBLIC vPortSVCHandler
|
||||||
PUBLIC vPortStartFirstTask
|
PUBLIC vPortStartFirstTask
|
||||||
PUBLIC vPortEnableVFP
|
PUBLIC vPortEnableVFP
|
||||||
|
@ -102,6 +100,8 @@ xPortPendSVHandler:
|
||||||
stmdb sp!, {r3}
|
stmdb sp!, {r3}
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
bl vTaskSwitchContext
|
bl vTaskSwitchContext
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
|
@ -134,20 +134,6 @@ xPortPendSVHandler:
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
ulPortSetInterruptMask:
|
|
||||||
mrs r0, basepri
|
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r1
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortClearInterruptMask:
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
vPortSVCHandler:
|
vPortSVCHandler:
|
||||||
/* Get the location of the current TCB. */
|
/* Get the location of the current TCB. */
|
||||||
ldr r3, =pxCurrentTCB
|
ldr r3, =pxCurrentTCB
|
||||||
|
|
|
@ -110,11 +110,10 @@ typedef unsigned long UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -145,15 +144,13 @@ extern void vPortYield( void );
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMask );
|
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Tickless idle/low power functionality. */
|
/* Tickless idle/low power functionality. */
|
||||||
|
@ -179,6 +176,51 @@ not necessary for to use this port. They are defined so the common demo files
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE _Pragma("inline=forced")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortYield( void )
|
||||||
|
{
|
||||||
|
/* Set a PendSV to request a context switch. */
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
|
||||||
|
/* Barriers are normally not required but do ensure the code is completely
|
||||||
|
within the specified behaviour for the architecture. */
|
||||||
|
__DSB();
|
||||||
|
__ISB();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulOriginalBASEPRI;
|
||||||
|
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" mrs %0, basepri \n" \
|
||||||
|
" mov r1, %1 \n" \
|
||||||
|
" msr basepri, r1 \n" \
|
||||||
|
" isb \n" \
|
||||||
|
" dsb \n" \
|
||||||
|
:"=r" (ulOriginalBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r1"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* This return will not be reached but is necessary to prevent compiler
|
||||||
|
warnings. */
|
||||||
|
return ulOriginalBASEPRI;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" msr basepri, %0 " :: "r" ( ulNewMaskValue )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
the source code because to do so would cause other compilers to generate
|
the source code because to do so would cause other compilers to generate
|
||||||
warnings. */
|
warnings. */
|
||||||
|
|
|
@ -111,7 +111,7 @@ is defined. */
|
||||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
|
||||||
|
|
|
@ -124,7 +124,7 @@ is defined. */
|
||||||
#define portPRIGROUP_SHIFT ( 8UL )
|
#define portPRIGROUP_SHIFT ( 8UL )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
@ -134,9 +134,6 @@ is defined. */
|
||||||
#define portINITIAL_XPSR ( 0x01000000 )
|
#define portINITIAL_XPSR ( 0x01000000 )
|
||||||
#define portINITIAL_EXEC_RETURN ( 0xfffffffd )
|
#define portINITIAL_EXEC_RETURN ( 0xfffffffd )
|
||||||
|
|
||||||
/* Constants used with memory barrier intrinsics. */
|
|
||||||
#define portSY_FULL_READ_WRITE ( 15 )
|
|
||||||
|
|
||||||
/* The systick is a 24-bit counter. */
|
/* The systick is a 24-bit counter. */
|
||||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||||
|
|
||||||
|
@ -401,24 +398,10 @@ void vPortEndScheduler( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vPortYield( void )
|
|
||||||
{
|
|
||||||
/* Set a PendSV to request a context switch. */
|
|
||||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
|
||||||
|
|
||||||
/* Barriers are normally not required but do ensure the code is completely
|
|
||||||
within the specified behaviour for the architecture. */
|
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
void vPortEnterCritical( void )
|
void vPortEnterCritical( void )
|
||||||
{
|
{
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
uxCriticalNesting++;
|
uxCriticalNesting++;
|
||||||
__dsb( portSY_FULL_READ_WRITE );
|
|
||||||
__isb( portSY_FULL_READ_WRITE );
|
|
||||||
|
|
||||||
/* This is not the interrupt safe version of the enter critical function so
|
/* This is not the interrupt safe version of the enter critical function so
|
||||||
assert() if it is being called from an interrupt context. Only API
|
assert() if it is being called from an interrupt context. Only API
|
||||||
|
@ -471,6 +454,8 @@ __asm void xPortPendSVHandler( void )
|
||||||
stmdb sp!, {r3}
|
stmdb sp!, {r3}
|
||||||
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
bl vTaskSwitchContext
|
bl vTaskSwitchContext
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
msr basepri, r0
|
msr basepri, r0
|
||||||
|
@ -702,26 +687,6 @@ void xPortSysTickHandler( void )
|
||||||
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__asm uint32_t ulPortSetInterruptMask( void )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
mrs r0, basepri
|
|
||||||
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
|
||||||
msr basepri, r1
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm void vPortClearInterruptMask( uint32_t ulNewMask )
|
|
||||||
{
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
msr basepri, r0
|
|
||||||
bx r14
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
__asm uint32_t vPortGetIPSR( void )
|
__asm uint32_t vPortGetIPSR( void )
|
||||||
{
|
{
|
||||||
PRESERVE8
|
PRESERVE8
|
||||||
|
|
|
@ -107,29 +107,30 @@ typedef unsigned long UBaseType_t;
|
||||||
#define portSTACK_GROWTH ( -1 )
|
#define portSTACK_GROWTH ( -1 )
|
||||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
#define portBYTE_ALIGNMENT 8
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
|
||||||
|
/* Constants used with memory barrier intrinsics. */
|
||||||
|
#define portSY_FULL_READ_WRITE ( 15 )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Scheduler utilities. */
|
/* Scheduler utilities. */
|
||||||
extern void vPortYield( void );
|
|
||||||
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) vPortYield()
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern uint32_t ulPortSetInterruptMask( void );
|
|
||||||
extern void vPortClearInterruptMask( uint32_t ulNewMask );
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
#define portDISABLE_INTERRUPTS() ulPortRaiseBASEPRI()
|
||||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x)
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -178,6 +179,53 @@ not necessary for to use this port. They are defined so the common demo files
|
||||||
/* portNOP() is not required by this port. */
|
/* portNOP() is not required by this port. */
|
||||||
#define portNOP()
|
#define portNOP()
|
||||||
|
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE __forceinline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
/* Barrier instructions are not used as this function is only used to
|
||||||
|
lower the BASEPRI value. */
|
||||||
|
msr basepri, ulBASEPRI
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
/* Set BASEPRI to the max syscall priority to effect a critical
|
||||||
|
section. */
|
||||||
|
mrs ulReturn, basepri
|
||||||
|
msr basepri, ulNewBASEPRI
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portFORCE_INLINE void vPortYield( void )
|
||||||
|
{
|
||||||
|
/* Set a PendSV to request a context switch. */
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||||
|
|
||||||
|
/* Barriers are normally not required but do ensure the code is completely
|
||||||
|
within the specified behaviour for the architecture. */
|
||||||
|
__dsb( portSY_FULL_READ_WRITE );
|
||||||
|
__isb( portSY_FULL_READ_WRITE );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
|
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
|
||||||
|
|
||||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
|
||||||
#define portVECTACTIVE_MASK ( 0x1FUL )
|
#define portVECTACTIVE_MASK ( 0xFFUL )
|
||||||
|
|
||||||
/* Constants required to manipulate the VFP. */
|
/* Constants required to manipulate the VFP. */
|
||||||
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */
|
||||||
|
|
|
@ -1377,8 +1377,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* Is there data in the queue now? To be running we must be
|
/* Is there data in the queue now? To be running the calling task
|
||||||
the highest priority task wanting to access the queue. */
|
must be the highest priority task wanting to access the queue. */
|
||||||
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 )
|
||||||
{
|
{
|
||||||
/* Remember the read position in case the queue is only being
|
/* Remember the read position in case the queue is only being
|
||||||
|
|
|
@ -114,6 +114,14 @@ functions but without including stdio.h here. */
|
||||||
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Value that can be assigned to the eNotifyState member of the TCB. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eNotWaitingNotification,
|
||||||
|
eWaitingNotification,
|
||||||
|
eNotified
|
||||||
|
} eNotifyValue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Task control block. A task control block (TCB) is allocated for each task,
|
* Task control block. A task control block (TCB) is allocated for each task,
|
||||||
* and stores task state information, including a pointer to the task's context
|
* and stores task state information, including a pointer to the task's context
|
||||||
|
@ -170,6 +178,11 @@ typedef struct tskTaskControlBlock
|
||||||
struct _reent xNewLib_reent;
|
struct _reent xNewLib_reent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
uint32_t ulNotifiedValue;
|
||||||
|
eNotifyValue eNotifyState;
|
||||||
|
#endif
|
||||||
|
|
||||||
} tskTCB;
|
} tskTCB;
|
||||||
|
|
||||||
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
||||||
|
@ -228,8 +241,8 @@ PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;
|
||||||
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = portMAX_DELAY;
|
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = portMAX_DELAY;
|
||||||
|
|
||||||
/* Context switches are held pending while the scheduler is suspended. Also,
|
/* Context switches are held pending while the scheduler is suspended. Also,
|
||||||
interrupts must not manipulate the xStateListItem of a TCB, or any of the
|
interrupts must not manipulate the xGenericListItem of a TCB, or any of the
|
||||||
lists the xStateListItem can be referenced from, if the scheduler is suspended.
|
lists the xGenericListItem can be referenced from, if the scheduler is suspended.
|
||||||
If an interrupt needs to unblock a task while the scheduler is suspended then it
|
If an interrupt needs to unblock a task while the scheduler is suspended then it
|
||||||
moves the task's event list item into the xPendingReadyList, ready for the
|
moves the task's event list item into the xPendingReadyList, ready for the
|
||||||
kernel to move the task from the pending ready list into the real ready list
|
kernel to move the task from the pending ready list into the real ready list
|
||||||
|
@ -515,6 +528,15 @@ static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t *
|
||||||
*/
|
*/
|
||||||
static void prvResetNextTaskUnblockTime( void );
|
static void prvResetNextTaskUnblockTime( void );
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function used to pad task names with spaces when printing out
|
||||||
|
* human readable tables of task information.
|
||||||
|
*/
|
||||||
|
static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName );
|
||||||
|
|
||||||
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
@ -995,7 +1017,7 @@ TCB_t * pxNewTCB;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else
|
else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */
|
||||||
{
|
{
|
||||||
/* If the task is not in any other state, it must be in the
|
/* If the task is not in any other state, it must be in the
|
||||||
Ready (including pending ready) state. */
|
Ready (including pending ready) state. */
|
||||||
|
@ -1031,6 +1053,46 @@ TCB_t * pxNewTCB;
|
||||||
#endif /* INCLUDE_uxTaskPriorityGet */
|
#endif /* INCLUDE_uxTaskPriorityGet */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( INCLUDE_uxTaskPriorityGet == 1 )
|
||||||
|
|
||||||
|
UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask )
|
||||||
|
{
|
||||||
|
TCB_t *pxTCB;
|
||||||
|
UBaseType_t uxReturn, uxSavedInterruptState;
|
||||||
|
|
||||||
|
/* RTOS ports that support interrupt nesting have the concept of a
|
||||||
|
maximum system call (or maximum API call) interrupt priority.
|
||||||
|
Interrupts that are above the maximum system call priority are keep
|
||||||
|
permanently enabled, even when the RTOS kernel is in a critical section,
|
||||||
|
but cannot make any calls to FreeRTOS API functions. If configASSERT()
|
||||||
|
is defined in FreeRTOSConfig.h then
|
||||||
|
portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
|
||||||
|
failure if a FreeRTOS API function is called from an interrupt that has
|
||||||
|
been assigned a priority above the configured maximum system call
|
||||||
|
priority. Only FreeRTOS functions that end in FromISR can be called
|
||||||
|
from interrupts that have been assigned a priority at or (logically)
|
||||||
|
below the maximum system call interrupt priority. FreeRTOS maintains a
|
||||||
|
separate interrupt safe API to ensure interrupt entry is as fast and as
|
||||||
|
simple as possible. More information (albeit Cortex-M specific) is
|
||||||
|
provided on the following link:
|
||||||
|
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
|
||||||
|
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
|
||||||
|
|
||||||
|
uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
/* If null is passed in here then we are changing the
|
||||||
|
priority of the calling function. */
|
||||||
|
pxTCB = prvGetTCBFromHandle( xTask );
|
||||||
|
uxReturn = pxTCB->uxPriority;
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_uxTaskPriorityGet */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( INCLUDE_vTaskPrioritySet == 1 )
|
#if ( INCLUDE_vTaskPrioritySet == 1 )
|
||||||
|
|
||||||
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
|
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
|
||||||
|
@ -1614,8 +1676,8 @@ BaseType_t xAlreadyYielded = pdFALSE;
|
||||||
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
prvAddTaskToReadyList( pxTCB );
|
prvAddTaskToReadyList( pxTCB );
|
||||||
|
|
||||||
/* If we have moved a task that has a priority higher than
|
/* If the moved task has a priority higher than the current
|
||||||
the current task then we should yield. */
|
task then a yield must be performed. */
|
||||||
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
|
||||||
{
|
{
|
||||||
xYieldPending = pdTRUE;
|
xYieldPending = pdTRUE;
|
||||||
|
@ -2395,6 +2457,20 @@ BaseType_t xReturn;
|
||||||
xReturn = pdFALSE;
|
xReturn = pdFALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||||
|
{
|
||||||
|
/* If a task is blocked on a kernel object then xNextTaskUnblockTime
|
||||||
|
might be set to the blocked task's time out time. If the task is
|
||||||
|
unblocked for a reason other than a timeout xNextTaskUnblockTime is
|
||||||
|
normally left unchanged, because it is automatically get reset to a new
|
||||||
|
value when the tick count equals xNextTaskUnblockTime. However if
|
||||||
|
tickless idling is used it might be more important to enter sleep mode
|
||||||
|
at the earliest possible time - so reset xNextTaskUnblockTime here to
|
||||||
|
ensure it is updated at the earliest possible time. */
|
||||||
|
prvResetNextTaskUnblockTime();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -2788,6 +2864,13 @@ UBaseType_t x;
|
||||||
}
|
}
|
||||||
#endif /* portUSING_MPU_WRAPPERS */
|
#endif /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
|
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
{
|
||||||
|
pxTCB->ulNotifiedValue = 0;
|
||||||
|
pxTCB->eNotifyState = eNotWaitingNotification;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
#if ( configUSE_NEWLIB_REENTRANT == 1 )
|
||||||
{
|
{
|
||||||
/* Initialise this task's Newlib reent structure. */
|
/* Initialise this task's Newlib reent structure. */
|
||||||
|
@ -3416,6 +3499,32 @@ TCB_t *pxTCB;
|
||||||
#endif /* portCRITICAL_NESTING_IN_TCB */
|
#endif /* portCRITICAL_NESTING_IN_TCB */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||||
|
|
||||||
|
static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName )
|
||||||
|
{
|
||||||
|
BaseType_t x;
|
||||||
|
|
||||||
|
/* Start by copying the entire string. */
|
||||||
|
strcpy( pcBuffer, pcTaskName );
|
||||||
|
|
||||||
|
/* Pad the end of the string with spaces to ensure columns line up when
|
||||||
|
printed out. */
|
||||||
|
for( x = strlen( pcBuffer ); x < configMAX_TASK_NAME_LEN; x++ )
|
||||||
|
{
|
||||||
|
pcBuffer[ x ] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate. */
|
||||||
|
pcBuffer[ x ] = 0x00;
|
||||||
|
|
||||||
|
/* Return the new end of string. */
|
||||||
|
return &( pcBuffer[ x ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
|
||||||
|
|
||||||
void vTaskList( char * pcWriteBuffer )
|
void vTaskList( char * pcWriteBuffer )
|
||||||
|
@ -3487,7 +3596,12 @@ TCB_t *pxTCB;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf( pcWriteBuffer, "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
|
/* Write the task name to the string, padding with spaces so it
|
||||||
|
can be printed in tabular form more easily. */
|
||||||
|
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
|
||||||
|
|
||||||
|
/* Write the rest of the string. */
|
||||||
|
sprintf( pcWriteBuffer, "\t\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
|
||||||
pcWriteBuffer += strlen( pcWriteBuffer );
|
pcWriteBuffer += strlen( pcWriteBuffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3573,15 +3687,20 @@ TCB_t *pxTCB;
|
||||||
|
|
||||||
if( ulStatsAsPercentage > 0UL )
|
if( ulStatsAsPercentage > 0UL )
|
||||||
{
|
{
|
||||||
|
/* Write the task name to the string, padding with
|
||||||
|
spaces so it can be printed in tabular form more
|
||||||
|
easily. */
|
||||||
|
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
|
||||||
|
|
||||||
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
|
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
|
||||||
{
|
{
|
||||||
sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
|
sprintf( pcWriteBuffer, "\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
/* sizeof( int ) == sizeof( long ) so a smaller
|
/* sizeof( int ) == sizeof( long ) so a smaller
|
||||||
printf() library can be used. */
|
printf() library can be used. */
|
||||||
sprintf( pcWriteBuffer, "%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
|
sprintf( pcWriteBuffer, "\t\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3651,7 +3770,433 @@ TickType_t uxReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_MUTEXES */
|
#endif /* configUSE_MUTEXES */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
|
||||||
|
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
TickType_t xTimeToWake;
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* Only block if the notification count is not already non-zero. */
|
||||||
|
if( pxCurrentTCB->ulNotifiedValue == 0UL )
|
||||||
|
{
|
||||||
|
/* Mark this task as waiting for a notification. */
|
||||||
|
pxCurrentTCB->eNotifyState = eWaitingNotification;
|
||||||
|
|
||||||
|
if( xTicksToWait > 0 )
|
||||||
|
{
|
||||||
|
/* The task is going to block. First it must be removed
|
||||||
|
from the ready list. */
|
||||||
|
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The current task must be in a ready list, so there is
|
||||||
|
no need to check, and the port reset macro can be called
|
||||||
|
directly. */
|
||||||
|
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||||
|
{
|
||||||
|
if( xTicksToWait == portMAX_DELAY )
|
||||||
|
{
|
||||||
|
/* Add the task to the suspended task list instead
|
||||||
|
of a delayed task list to ensure the task is not
|
||||||
|
woken by a timing event. It will block
|
||||||
|
indefinitely. */
|
||||||
|
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Calculate the time at which the task should be
|
||||||
|
woken if no notification events occur. This may
|
||||||
|
overflow but this doesn't matter, the scheduler will
|
||||||
|
handle it. */
|
||||||
|
xTimeToWake = xTickCount + xTicksToWait;
|
||||||
|
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* INCLUDE_vTaskSuspend */
|
||||||
|
{
|
||||||
|
/* Calculate the time at which the task should be
|
||||||
|
woken if the event does not occur. This may
|
||||||
|
overflow but this doesn't matter, the scheduler will
|
||||||
|
handle it. */
|
||||||
|
xTimeToWake = xTickCount + xTicksToWait;
|
||||||
|
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_vTaskSuspend */
|
||||||
|
|
||||||
|
/* All ports are written to allow a yield in a critical
|
||||||
|
section (some will yield immediately, others wait until the
|
||||||
|
critical section exits) - but it is not something that
|
||||||
|
application code should ever do. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulReturn = pxCurrentTCB->ulNotifiedValue;
|
||||||
|
|
||||||
|
if( ulReturn != 0 )
|
||||||
|
{
|
||||||
|
if( xClearCountOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxCurrentTCB->ulNotifiedValue = 0UL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
( pxCurrentTCB->ulNotifiedValue )--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
pxCurrentTCB->eNotifyState = eNotWaitingNotification;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
|
||||||
|
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, BaseType_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
TickType_t xTimeToWake;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* Only block if a notification is not already pending. */
|
||||||
|
if( pxCurrentTCB->eNotifyState != eNotified )
|
||||||
|
{
|
||||||
|
/* Clear bits in the task's notification value as bits may get
|
||||||
|
set by the notifying task or interrupt. This can be used to
|
||||||
|
clear the value to zero. */
|
||||||
|
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;
|
||||||
|
|
||||||
|
/* Mark this task as waiting for a notification. */
|
||||||
|
pxCurrentTCB->eNotifyState = eWaitingNotification;
|
||||||
|
|
||||||
|
if( xTicksToWait > 0 )
|
||||||
|
{
|
||||||
|
/* The task is going to block. First it must be removed
|
||||||
|
from the ready list. */
|
||||||
|
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The current task must be in a ready list, so there is
|
||||||
|
no need to check, and the port reset macro can be called
|
||||||
|
directly. */
|
||||||
|
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||||
|
{
|
||||||
|
if( xTicksToWait == portMAX_DELAY )
|
||||||
|
{
|
||||||
|
/* Add the task to the suspended task list instead
|
||||||
|
of a delayed task list to ensure the task is not
|
||||||
|
woken by a timing event. It will block
|
||||||
|
indefinitely. */
|
||||||
|
vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Calculate the time at which the task should be
|
||||||
|
woken if no notification events occur. This may
|
||||||
|
overflow but this doesn't matter, the scheduler will
|
||||||
|
handle it. */
|
||||||
|
xTimeToWake = xTickCount + xTicksToWait;
|
||||||
|
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* INCLUDE_vTaskSuspend */
|
||||||
|
{
|
||||||
|
/* Calculate the time at which the task should be
|
||||||
|
woken if the event does not occur. This may
|
||||||
|
overflow but this doesn't matter, the scheduler will
|
||||||
|
handle it. */
|
||||||
|
xTimeToWake = xTickCount + xTicksToWait;
|
||||||
|
prvAddCurrentTaskToDelayedList( xTimeToWake );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_vTaskSuspend */
|
||||||
|
|
||||||
|
/* All ports are written to allow a yield in a critical
|
||||||
|
section (some will yield immediately, others wait until the
|
||||||
|
critical section exits) - but it is not something that
|
||||||
|
application code should ever do. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( pulNotificationValue != NULL )
|
||||||
|
{
|
||||||
|
/* Output the current notification value, which may or may not
|
||||||
|
have changed. */
|
||||||
|
*pulNotificationValue = pxCurrentTCB->ulNotifiedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If eNotifyValue is set then either the task never entered the
|
||||||
|
blocked state (because a notification was already pending) or the
|
||||||
|
task unblocked because of a notification. Otherwise the task
|
||||||
|
unblocked because of a timeout. */
|
||||||
|
if( pxCurrentTCB->eNotifyState == eWaitingNotification )
|
||||||
|
{
|
||||||
|
/* A notification was not received. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* A notification was already pending or a notification was
|
||||||
|
received while the task was waiting. */
|
||||||
|
pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxCurrentTCB->eNotifyState = eNotWaitingNotification;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
|
||||||
|
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction )
|
||||||
|
{
|
||||||
|
TCB_t * pxTCB;
|
||||||
|
eNotifyValue eOriginalNotifyState;
|
||||||
|
BaseType_t xReturn = pdPASS;
|
||||||
|
|
||||||
|
configASSERT( xTaskToNotify );
|
||||||
|
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||||
|
|
||||||
|
pxTCB->eNotifyState = eNotified;
|
||||||
|
|
||||||
|
switch( eAction )
|
||||||
|
{
|
||||||
|
case eSetBits :
|
||||||
|
pxTCB->ulNotifiedValue |= ulValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eIncrement :
|
||||||
|
( pxTCB->ulNotifiedValue )++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eSetValueWithOverwrite :
|
||||||
|
pxTCB->ulNotifiedValue = ulValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eSetValueWithoutOverwrite :
|
||||||
|
if( eOriginalNotifyState != eNotified )
|
||||||
|
{
|
||||||
|
pxTCB->ulNotifiedValue = ulValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The value could not be written to the task. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
/* The task is being notified without its notify value being
|
||||||
|
updated. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If the task is in the blocked state specifically to wait for a
|
||||||
|
notification then unblock it now. */
|
||||||
|
if( eOriginalNotifyState == eWaitingNotification )
|
||||||
|
{
|
||||||
|
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
prvAddTaskToReadyList( pxTCB );
|
||||||
|
|
||||||
|
/* The task should not have been on an event list. */
|
||||||
|
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
|
||||||
|
|
||||||
|
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||||
|
{
|
||||||
|
/* The notified task has a priority above the currently
|
||||||
|
executing task so a yield is required. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
|
||||||
|
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken )
|
||||||
|
{
|
||||||
|
TCB_t * pxTCB;
|
||||||
|
eNotifyValue eOriginalNotifyState;
|
||||||
|
BaseType_t xReturn = pdPASS;
|
||||||
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
|
|
||||||
|
configASSERT( xTaskToNotify );
|
||||||
|
|
||||||
|
/* RTOS ports that support interrupt nesting have the concept of a
|
||||||
|
maximum system call (or maximum API call) interrupt priority.
|
||||||
|
Interrupts that are above the maximum system call priority are keep
|
||||||
|
permanently enabled, even when the RTOS kernel is in a critical section,
|
||||||
|
but cannot make any calls to FreeRTOS API functions. If configASSERT()
|
||||||
|
is defined in FreeRTOSConfig.h then
|
||||||
|
portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
|
||||||
|
failure if a FreeRTOS API function is called from an interrupt that has
|
||||||
|
been assigned a priority above the configured maximum system call
|
||||||
|
priority. Only FreeRTOS functions that end in FromISR can be called
|
||||||
|
from interrupts that have been assigned a priority at or (logically)
|
||||||
|
below the maximum system call interrupt priority. FreeRTOS maintains a
|
||||||
|
separate interrupt safe API to ensure interrupt entry is as fast and as
|
||||||
|
simple as possible. More information (albeit Cortex-M specific) is
|
||||||
|
provided on the following link:
|
||||||
|
http://www.freertos.org/RTOS-Cortex-M3-M4.html */
|
||||||
|
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
|
||||||
|
|
||||||
|
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||||
|
|
||||||
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
eOriginalNotifyState = pxTCB->eNotifyState;
|
||||||
|
|
||||||
|
pxTCB->eNotifyState = eNotified;
|
||||||
|
|
||||||
|
switch( eAction )
|
||||||
|
{
|
||||||
|
case eSetBits :
|
||||||
|
pxTCB->ulNotifiedValue |= ulValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eIncrement :
|
||||||
|
( pxTCB->ulNotifiedValue )++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eSetValueWithOverwrite :
|
||||||
|
pxTCB->ulNotifiedValue = ulValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eSetValueWithoutOverwrite :
|
||||||
|
if( eOriginalNotifyState != eNotified )
|
||||||
|
{
|
||||||
|
pxTCB->ulNotifiedValue = ulValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The value could not be written to the task. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
/* The task is being notified without its notify value being
|
||||||
|
updated. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If the task is in the blocked state specifically to wait for a
|
||||||
|
notification then unblock it now. */
|
||||||
|
if( eOriginalNotifyState == eWaitingNotification )
|
||||||
|
{
|
||||||
|
/* The task should not have been on an event list. */
|
||||||
|
configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
|
||||||
|
|
||||||
|
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
|
||||||
|
{
|
||||||
|
( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
|
||||||
|
prvAddTaskToReadyList( pxTCB );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The delayed and ready lists cannot be accessed, so hold
|
||||||
|
this task pending until the scheduler is resumed. */
|
||||||
|
vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
|
||||||
|
{
|
||||||
|
/* The notified task has a priority above the currently
|
||||||
|
executing task so a yield is required. */
|
||||||
|
if( pxHigherPriorityTaskWoken != NULL )
|
||||||
|
{
|
||||||
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_TASK_NOTIFICATIONS */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef FREERTOS_MODULE_TEST
|
#ifdef FREERTOS_MODULE_TEST
|
||||||
|
|
Loading…
Reference in a new issue