Final preparation for new release:

FreeRTOS+Trace:
 - Add trace macros for task notifications.
 - Update to the latest trace recorder library.

Demo projects:
 - Only include the CLI command to show run time states if configGENERATE_RUN_TIME_STATS is set to 1.
This commit is contained in:
Richard Barry 2015-08-12 10:34:30 +00:00
parent 99d4f2c454
commit 3291f5a08d
23 changed files with 5473 additions and 1268 deletions

View file

@ -110,7 +110,9 @@ static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferL
/*
* Implements the run-time-stats command.
*/
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
#if( configGENERATE_RUN_TIME_STATS == 1 )
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
#endif /* configGENERATE_RUN_TIME_STATS */
/*
* Implements the echo-three-parameters command.
@ -136,16 +138,6 @@ static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBuf
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
#endif
/* Structure that defines the "run-time-stats" command line command. This
generates a table that shows how much run time each task has */
static const CLI_Command_Definition_t xRunTimeStats =
{
"run-time-stats", /* The command string to type. */
"\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",
prvRunTimeStatsCommand, /* The function to run. */
0 /* No parameters are expected. */
};
/* Structure that defines the "task-stats" command line command. This generates
a table that gives information on each task in the system. */
static const CLI_Command_Definition_t xTaskStats =
@ -178,6 +170,18 @@ static const CLI_Command_Definition_t xParameterEcho =
-1 /* The user can enter any number of commands. */
};
#if( configGENERATE_RUN_TIME_STATS == 1 )
/* Structure that defines the "run-time-stats" command line command. This
generates a table that shows how much run time each task has */
static const CLI_Command_Definition_t xRunTimeStats =
{
"run-time-stats", /* The command string to type. */
"\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",
prvRunTimeStatsCommand, /* The function to run. */
0 /* No parameters are expected. */
};
#endif /* configGENERATE_RUN_TIME_STATS */
#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )
/* Structure that defines the "query_heap" command line command. */
static const CLI_Command_Definition_t xQueryHeap =
@ -206,11 +210,16 @@ static const CLI_Command_Definition_t xParameterEcho =
void vRegisterSampleCLICommands( void )
{
/* Register all the command line commands defined immediately above. */
FreeRTOS_CLIRegisterCommand( &xTaskStats );
FreeRTOS_CLIRegisterCommand( &xRunTimeStats );
FreeRTOS_CLIRegisterCommand( &xTaskStats );
FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );
FreeRTOS_CLIRegisterCommand( &xParameterEcho );
#if( configGENERATE_RUN_TIME_STATS == 1 )
{
FreeRTOS_CLIRegisterCommand( &xRunTimeStats );
}
#endif
#if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )
{
FreeRTOS_CLIRegisterCommand( &xQueryHeap );
@ -283,43 +292,47 @@ BaseType_t xSpacePadding;
#endif /* configINCLUDE_QUERY_HEAP */
/*-----------------------------------------------------------*/
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n";
BaseType_t xSpacePadding;
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
/* Generate a table of task stats. */
strcpy( pcWriteBuffer, "Task" );
pcWriteBuffer += strlen( pcWriteBuffer );
/* Pad the string "task" with however many bytes necessary to make it the
length of a task name. Minus three for the null terminator and half the
number of characters in "Task" so the column lines up with the centre of
the heading. */
for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
#if( configGENERATE_RUN_TIME_STATS == 1 )
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
/* Add a space to align columns after the task's name. */
*pcWriteBuffer = ' ';
pcWriteBuffer++;
const char * const pcHeader = " Abs Time % Time\r\n****************************************\r\n";
BaseType_t xSpacePadding;
/* Ensure always terminated. */
*pcWriteBuffer = 0x00;
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
/* Generate a table of task stats. */
strcpy( pcWriteBuffer, "Task" );
pcWriteBuffer += strlen( pcWriteBuffer );
/* Pad the string "task" with however many bytes necessary to make it the
length of a task name. Minus three for the null terminator and half the
number of characters in "Task" so the column lines up with the centre of
the heading. */
for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
{
/* Add a space to align columns after the task's name. */
*pcWriteBuffer = ' ';
pcWriteBuffer++;
/* Ensure always terminated. */
*pcWriteBuffer = 0x00;
}
strcpy( pcWriteBuffer, pcHeader );
vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );
/* There is no more data to return after this single string, so return
pdFALSE. */
return pdFALSE;
}
strcpy( pcWriteBuffer, pcHeader );
vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );
/* There is no more data to return after this single string, so return
pdFALSE. */
return pdFALSE;
}
#endif /* configGENERATE_RUN_TIME_STATS */
/*-----------------------------------------------------------*/
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )

View file

@ -1,5 +1,6 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
URL=http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Reliance_Edge_Fail_Safe_File_System.shtml
URL=http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml
IDList=
HotKey=0

View file

@ -71,7 +71,7 @@
*
* This demo is described on the following web page:
* TODO: This link describes the FAT version of this demo.
* http://FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml
* http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml
*
******************************************************************************/
@ -112,7 +112,10 @@ extern void vUDPCommandInterpreterTask( void *pvParameters );
extern void vCreateAndVerifySampleFiles( void );
/*-----------------------------------------------------------*/
#pragma warning - add link to documentation page
/* See http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml
for instructions. */
int main( void )
{
const uint32_t ulLongTime_ms = 250UL;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.0 Recorder Library
* Tracealyzer v2.7.7 Recorder Library
* Percepio AB, www.percepio.com
*
* trcConfig.h
@ -38,7 +38,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2014.
* Copyright Percepio AB, 2012-2015.
* www.percepio.com
******************************************************************************/
@ -70,18 +70,20 @@
* PORT_NXP_LPC210X 13 No Any
* PORT_MICROCHIP_PIC32MZ 14 Yes Any
* PORT_ARM_CORTEX_A9 15 No Any
* PORT_ARM_CORTEX_M0 16 Yes Any
*****************************************************************************/
#ifndef WIN32
// Set the port setting here!
#define SELECTED_PORT PORT_NOT_SET
// 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
#if (SELECTED_PORT == PORT_ARM_CortexM)
/* For ARM Cortex-M: make sure ARM's CMSIS library is included here, which
is used for accessing the PRIMASK register. e.g. #include "board.h" */
#endif
#if (SELECTED_PORT == PORT_NOT_SET)
#error "You need to define SELECTED_PORT here!"
#endif
/******************************************************************************

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.0 Recorder Library
* Tracealyzer v2.7.7 Recorder Library
* Percepio AB, www.percepio.com
*
* trcHardwarePort.h
@ -34,7 +34,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2014.
* Copyright Percepio AB, 2012-2015.
* www.percepio.com
******************************************************************************/
@ -112,6 +112,7 @@
#define PORT_NXP_LPC210X 13 /* No Any */
#define PORT_MICROCHIP_PIC32MZ 14 /* Yes Any */
#define PORT_ARM_CORTEX_A9 15 /* No Any */
#define PORT_ARM_CORTEX_M0 16 /* Yes Any */
#include "trcConfig.h"
@ -199,12 +200,12 @@
#elif (SELECTED_PORT == PORT_ARM_CortexM)
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)
@ -223,7 +224,7 @@
#define PORT_SPECIFIC_INIT() prvTraceInitCortexM()
extern uint32_t DWT_CYCLES_ADDED;
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (REG_DWT_CYCCNT + DWT_CYCLES_ADDED)
#define HWTC_PERIOD 0
@ -231,6 +232,14 @@
#define IRQ_PRIORITY_ORDER 0 // lower IRQ priority values are more significant
#elif (SELECTED_PORT == PORT_ARM_CORTEX_M0)
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
#define HWTC_COUNT (*((uint32_t*)0xE000E018))
#define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)
#define HWTC_DIVISOR 2
#define IRQ_PRIORITY_ORDER 0 // lower IRQ priority values are more significant
#elif (SELECTED_PORT == PORT_Renesas_RX600)
#include "iodefine.h"
@ -241,8 +250,8 @@
#define HWTC_DIVISOR 1
#define IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant
#elif (SELECTED_PORT == PORT_MICROCHIP_PIC32MX || SELECTED_PORT == PORT_MICROCHIP_PIC32MZ)
#elif ((SELECTED_PORT == PORT_MICROCHIP_PIC32MX) || (SELECTED_PORT == PORT_MICROCHIP_PIC32MZ))
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (TMR1)
#define HWTC_PERIOD (PR1 + 1)
@ -299,11 +308,11 @@
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
#define RTIFRC0 *((uint32_t *)0xFFFFFC10)
#define RTICOMP0 *((uint32_t *)0xFFFFFC50)
#define RTIUDCP0 *((uint32_t *)0xFFFFFC54)
#define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10)
#define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50)
#define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54)
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
#define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))
#define HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0))
#define HWTC_PERIOD (RTIUDCP0)
#define HWTC_DIVISOR 1

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.0 Recorder Library
* Tracealyzer v2.7.7 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.h
@ -31,7 +31,7 @@
* 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.
*
* Copyright Percepio AB, 2013.
* Copyright Percepio AB, 2012-2015.
* www.percepio.com
******************************************************************************/
@ -45,7 +45,10 @@
/* Internal functions */
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
void vTraceStoreTaskReady(objectHandleType handle);
void vTraceSetReadyEventsEnabled(int status);
void vTraceStoreTaskReady(objectHandleType handle);
#else
#define vTraceSetReadyEventsEnabled(status)
#endif
void vTraceStoreLowPower(uint32_t flag);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.0 Recorder Library
* Tracealyzer v2.7.7 Recorder Library
* Percepio AB, www.percepio.com
*
* trcUser.h
@ -32,7 +32,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2014.
* Copyright Percepio AB, 2012-2015.
* www.percepio.com
******************************************************************************/
@ -448,7 +448,7 @@ void vTraceChannelUserEvent(UserEventChannel channel);
#define vTraceSetISRProperties(handle, name, priority)
#define vTraceStoreISRBegin(id)
#define vTraceStoreISREnd()
#define vTraceStoreISREnd(flag)
#define vTraceExcludeTaskFromTrace(handle)
#define vTraceSetQueueName(a, b)
#define vTraceSetMutexName(a, b)

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.0 Recorder Library
* Tracealyzer v2.7.7 Recorder Library
* Percepio AB, www.percepio.com
*
* trcKernel.c
@ -33,7 +33,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2014.
* Copyright Percepio AB, 2012-2015.
* www.percepio.com
******************************************************************************/
@ -44,18 +44,28 @@
#include <stdint.h>
/* Internal variables */
uint8_t nISRactive = 0;
int8_t nISRactive = 0;
objectHandleType handle_of_last_logged_task = 0;
uint8_t inExcludedTask = 0;
#if (INCLUDE_MEMMANG_EVENTS == 1)
/* Current heap usage. Always updated. */
static uint32_t heapMemUsage = 0;
#endif
#if (TRACE_SCHEDULING_ONLY == 0)
static uint32_t prvTraceGetParam(uint32_t, uint32_t);
#endif
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
static int readyEventsEnabled = 1;
void vTraceSetReadyEventsEnabled(int status)
{
readyEventsEnabled = status;
}
/*******************************************************************************
* vTraceStoreTaskReady
*
@ -75,6 +85,14 @@ void vTraceStoreTaskReady(objectHandleType handle)
placement of the trace macro. In that case, the events are ignored. */
return;
}
if (! readyEventsEnabled)
{
/* When creating tasks, ready events are also created. If creating
a "hidden" (not traced) task, we must therefore disable recording
of ready events to avoid an undesired ready event... */
return;
}
TRACE_ASSERT(handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );
@ -171,13 +189,15 @@ void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_si
uint16_t addr_low;
uint8_t addr_high;
uint32_t size;
TRACE_SR_ALLOC_CRITICAL_SECTION();
if (RecorderDataPtr == NULL) // This happens in vTraceInitTraceData, if using dynamic allocation...
return;
if (signed_size < 0)
size = (uint32_t)(- signed_size);
else
size = (uint32_t)(signed_size);
TRACE_SR_ALLOC_CRITICAL_SECTION();
trcCRITICAL_SECTION_BEGIN();
@ -619,9 +639,9 @@ void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)
{
TRACE_ASSERT(objectclass < TRACE_NCLASSES,
"uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
"uiTraceGetPriorityProperty: Invalid objectclass number (>= TRACE_NCLASSES)", 0);
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
"uiTraceGetPriorityProperty: Invalid value for id", 0);
"uiTraceGetPriorityProperty: Task handle exceeds NTask. You may need to increase this constant in trcConfig.h.", 0);
return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.7.0 Recorder Library
* Tracealyzer v2.7.7 Recorder Library
* Percepio AB, www.percepio.com
*
* trcUser.c
@ -33,7 +33,7 @@
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2014.
* Copyright Percepio AB, 2012-2015.
* www.percepio.com
******************************************************************************/
#include "FreeRTOS.h"
@ -50,7 +50,7 @@
TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0;
extern uint8_t inExcludedTask;
extern uint8_t nISRactive;
extern int8_t nISRactive;
extern objectHandleType handle_of_last_logged_task;
extern uint32_t dts_min;
extern uint32_t hwtc_count_max_after_tick;
@ -127,6 +127,8 @@ void vTraceClear(void)
memset(RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4);
handle_of_last_logged_task = 0;
trcCRITICAL_SECTION_END();
}
@ -632,47 +634,55 @@ void vTraceStoreISREnd(int pendingISR)
uint16_t dts5;
TRACE_SR_ALLOC_CRITICAL_SECTION();
if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task)
{
return;
}
if (recorder_busy)
{
vTraceError("Illegal call to vTraceStoreISREnd, recorder busy!");
return;
}
if (nISRactive == 0)
{
vTraceError("Unmatched call to vTraceStoreISREnd (nISRactive == 0, expected > 0)");
return;
}
trcCRITICAL_SECTION_BEGIN();
if (pendingISR == 0)
{
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
uint8_t hnd8, type;
dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (nISRactive > 1)
{
uint8_t hnd8, type;
dts5 = (uint16_t)prvTraceGetDTS(0xFFFF);
if (nISRactive > 1)
{
/* return to another isr */
type = TS_ISR_RESUME;
hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive]);
}
else
{
/* return to task */
type = TS_TASK_RESUME;
hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
}
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
if (ts != NULL)
{
ts->type = type;
ts->objHandle = hnd8;
ts->dts = dts5;
prvTraceUpdateCounters();
}
#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) */
ptrLastISRExitEvent = (uint8_t*)ts;
#endif
/* return to another isr */
type = TS_ISR_RESUME;
hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive]);
}
else
{
/* return to task */
type = TS_TASK_RESUME;
hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
}
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
if (ts != NULL)
{
ts->type = type;
ts->objHandle = hnd8;
ts->dts = dts5;
prvTraceUpdateCounters();
}
#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) */
ptrLastISRExitEvent = (uint8_t*)ts;
#endif
}
nISRactive--;