Demo/Posix_GCC: add demo application for Posix port using GCC

This is largely a copy of the Windows demo application with a few key
changes:

- heap_3 (use malloc()/free()) so tools like valgrind "just work".

- printf() wrapped in a mutex to prevent deadlocks on the internal
  pthread mutexes inside printf().

SCons (https://scons.org/) is used as the build system.

This will be built as a 64-bit application, but note that the memory
allocation trace points only record the lower 32-bits of the address.
This commit is contained in:
David Vrabel
2020-03-16 11:21:46 +00:00
committed by Yuhui Zheng
parent f78f919b3e
commit 9f316c246b
13 changed files with 3318 additions and 0 deletions

4
FreeRTOS/Demo/Posix_GCC/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.sconsign.dblite
build/
src/FreeRTOS
src/FreeRTOS-Plus

View File

@ -0,0 +1,52 @@
# FreeRTOS Kernel V10.3.0
# Copyright (C) 2020 Cambridge Consultants Ltd.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# http://www.FreeRTOS.org
# http://aws.amazon.com/freertos
#
# This is the main SCons (https://scons.org/) build file for the
# Posix/GCC demo application.
import os
# Create a symlink to the FreeRTOS sources.
if not os.path.exists("src/FreeRTOS"):
os.symlink("../../..", "src/FreeRTOS")
if not os.path.exists("src/FreeRTOS-Plus"):
os.symlink("../../../../FreeRTOS-Plus", "src/FreeRTOS-Plus")
AddOption("--simple",
action='store_true',
help="build the simple 'blinky' demo application")
AddOption("--coverage",
action='store_true',
help="enable code coverage")
env = Environment()
Export("env")
env.Append(CFLAGS = [
"-g",
"-Wall",
"-O2",
])
SConscript("src/SConscript", variant_dir="build", duplicate=0)

View File

@ -0,0 +1,158 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See
* http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_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 configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* 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 ) ( 65 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 20
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configSUPPORT_STATIC_ALLOCATION 1
/* Software timer related configuration options. The maximum possible task
priority is configMAX_PRIORITIES - 1. The priority of the timer task is
deliberately set higher to ensure it is correctly capped back to
configMAX_PRIORITIES - 1. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 20
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define configMAX_PRIORITIES ( 7 )
/* Run time stats gathering configuration options. */
unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */
void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */
#define configGENERATE_RUN_TIME_STATS 1
/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* This demo can use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
readable ASCII form. See the notes in the implementation of vTaskList() within
FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Enables the test whereby a stack larger than the total heap size is
requested. */
#define configSTACK_DEPTH_TYPE uint32_t
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. In most cases the linker will remove unused
functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_uxTaskGetStackHighWaterMark2 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0
#if ( configINCLUDE_MESSAGE_BUFFER_AMP_DEMO == 1 )
extern void vGenerateCoreBInterrupt( void * xUpdatedMessageBuffer );
#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreBInterrupt( pxStreamBuffer )
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
/* projCOVERAGE_TEST should be defined on the command line so this file can be
used with multiple project configurations. If it is
*/
#ifndef projCOVERAGE_TEST
#error projCOVERAGE_TEST should be defined to 1 or 0 on the command line.
#endif
#if( projCOVERAGE_TEST == 1 )
/* Insert NOPs in empty decision paths to ensure both true and false paths
are being tested. */
#define mtCOVERAGE_TEST_MARKER() __asm volatile( "NOP" )
/* Ensure the tick count overflows during the coverage test. */
#define configINITIAL_TICK_COUNT 0xffffd800UL
/* Allows tests of trying to allocate more than the heap has free. */
#define configUSE_MALLOC_FAILED_HOOK 0
/* To test builds that remove the static qualifier for debug builds. */
#define portREMOVE_STATIC_QUALIFIER
#else
/* It is a good idea to define configASSERT() while developing. configASSERT()
uses the same semantics as the standard C assert() macro. Don't define
configASSERT() when performing code coverage tests though, as it is not
intended to asserts() to fail, some some code is intended not to run if no
errors are present. */
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )
#define configUSE_MALLOC_FAILED_HOOK 1
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
#include "trcRecorder.h"
#endif
#endif /* FREERTOS_CONFIG_H */

View File

@ -0,0 +1,124 @@
# FreeRTOS Kernel V10.3.0
# Copyright (C) 2020 Cambridge Consultants Ltd.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# http://www.FreeRTOS.org
# http://aws.amazon.com/freertos
Import("env")
env.Append(CPPPATH = [
".",
"FreeRTOS/Source/include",
"FreeRTOS/Source/portable/ThirdParty/GCC/Posix",
"FreeRTOS/Demo/Common/include",
"FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include",
])
env.Append(LIBS = [
"pthread",
])
src = [
"console.c",
"main.c",
"main_blinky.c",
"main_full.c",
"run-time-stats-utils.c",
# FreeRTOS kernel
"FreeRTOS/Source/event_groups.c",
"FreeRTOS/Source/list.c",
"FreeRTOS/Source/queue.c",
"FreeRTOS/Source/stream_buffer.c",
"FreeRTOS/Source/tasks.c",
"FreeRTOS/Source/timers.c",
# Memory manager (use malloc()/free()).
"FreeRTOS/Source/portable/MemMang/heap_3.c",
# Posix port.
"FreeRTOS/Source/portable/ThirdParty/GCC/Posix/port.c",
# Demo library.
"FreeRTOS/Demo/Common/Minimal/AbortDelay.c",
"FreeRTOS/Demo/Common/Minimal/BlockQ.c",
"FreeRTOS/Demo/Common/Minimal/blocktim.c",
"FreeRTOS/Demo/Common/Minimal/countsem.c",
"FreeRTOS/Demo/Common/Minimal/death.c",
"FreeRTOS/Demo/Common/Minimal/dynamic.c",
"FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c",
"FreeRTOS/Demo/Common/Minimal/flop.c",
"FreeRTOS/Demo/Common/Minimal/GenQTest.c",
"FreeRTOS/Demo/Common/Minimal/integer.c",
"FreeRTOS/Demo/Common/Minimal/IntSemTest.c",
"FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c",
"FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c",
"FreeRTOS/Demo/Common/Minimal/PollQ.c",
"FreeRTOS/Demo/Common/Minimal/QPeek.c",
"FreeRTOS/Demo/Common/Minimal/QueueOverwrite.c",
"FreeRTOS/Demo/Common/Minimal/QueueSet.c",
"FreeRTOS/Demo/Common/Minimal/QueueSetPolling.c",
"FreeRTOS/Demo/Common/Minimal/recmutex.c",
"FreeRTOS/Demo/Common/Minimal/semtest.c",
"FreeRTOS/Demo/Common/Minimal/StaticAllocation.c",
"FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c",
"FreeRTOS/Demo/Common/Minimal/StreamBufferInterrupt.c",
"FreeRTOS/Demo/Common/Minimal/TaskNotify.c",
"FreeRTOS/Demo/Common/Minimal/TimerDemo.c",
]
if GetOption("coverage"):
env.Append(CPPDEFINES = [
"projCOVERAGE_TEST=1",
])
env.Append(CFLAGS = [
"-fprofile-arcs",
"-ftest-coverage",
])
env.Append(LINKFLAGS = [
"-fprofile-arcs",
"-ftest-coverage",
])
src += [
"code_coverage_additions.c",
]
else:
env.Append(CPPDEFINES = [
"projCOVERAGE_TEST=0",
])
src += [
# Trace library.
"FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c",
"FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c",
"FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcStreamingRecorder.c",
"FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/streamports/File/trcStreamingPort.c",
]
# Build the simple "blinky" demo application, or the full test
# applicaton?
if GetOption("simple"):
env.Append(CPPDEFINES = [
"mainCREATE_SIMPLE_BLINKY_DEMO_ONLY=1",
])
env.Program("posix_demo", src)

View File

@ -0,0 +1,615 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* Contains sundry tests to exercise code that is not touched by the standard
* demo tasks (which are predominantly test tasks). Some tests are incldued
* here because they can only be executed when configASSERT() is not defined.
*/
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "event_groups.h"
#include "semphr.h"
#include "stream_buffer.h"
#include "message_buffer.h"
/*-----------------------------------------------------------*/
/*
* Try creating static objects with one of the mandatory parameters set to NULL.
* This can't be done in the standard demos as asserts() will get hit.
*/
static BaseType_t prvStaticAllocationsWithNullBuffers( void );
/*
* Code coverage analysis is performed with tracing turned off, so this
* function executes the trace specific utility functions that would not
* otherwise be executed..
*/
static BaseType_t prvTraceUtils( void );
/*
* The queue peek standard demo does not cover the case where an attempt to peek
* times out, so test that case.
*/
static BaseType_t prvPeekTimeout( void );
/*
* Calls various interrupt safe functions designed to query the state of a
* queue.
*/
static BaseType_t prvQueueQueryFromISR( void );
/*
* Hits a few paths in tasks state and status query functions not otherwise hit
* by standard demo and test files.
*/
static BaseType_t prvTaskQueryFunctions( void );
/*
* None of the standard demo tasks use the task tags - exercise them here.
*/
static BaseType_t prvTaskTags( void );
/*
* Exercises a few of the query functions that are not otherwise exercised in
* the standard demo and test functions.
*/
static BaseType_t prvTimerQuery( void );
/*-----------------------------------------------------------*/
static BaseType_t prvStaticAllocationsWithNullBuffers( void )
{
uintptr_t ulReturned = 0;
BaseType_t xReturn = pdPASS;
UBaseType_t uxDummy = 10;
/* Don't expect to create any of the objects as a NULL parameter is always
passed in place of a required buffer. Hence if all passes then none of the
|= will be against 0, and ulReturned will still be zero at the end of this
function. */
ulReturned |= ( uintptr_t ) xEventGroupCreateStatic( NULL );
/* Try creating a task twice, once with puxStackBuffer NULL, and once with
pxTaskBuffer NULL. */
ulReturned |= ( uintptr_t ) xTaskCreateStatic( NULL, /* Task to run, not needed as the task is not created. */
"Dummy", /* Task name. */
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY,
NULL,
( StaticTask_t * ) &xReturn ); /* Dummy value just to pass a non NULL value in - won't get used. */
ulReturned |= ( uintptr_t ) xTaskCreateStatic( NULL, /* Task to run, not needed as the task is not created. */
"Dummy", /* Task name. */
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY,
( StackType_t * ) &xReturn, /* Dummy value just to pass a non NULL value in - won't get used. */
NULL );
ulReturned |= ( uintptr_t ) xQueueCreateStatic( uxDummy,
uxDummy,
( uint8_t * ) &xReturn, /* Dummy value just to pass a non NULL value in - won't get used. */
NULL );
/* Try creating a stream buffer twice, once with pucStreamBufferStorageArea
set to NULL, and once with pxStaticStreamBuffer set to NULL. */
ulReturned |= ( uintptr_t ) xStreamBufferCreateStatic( uxDummy,
uxDummy,
NULL,
( StaticStreamBuffer_t * ) &xReturn ); /* Dummy value just to pass a non NULL value in - won't get used. */
ulReturned |= ( uintptr_t ) xStreamBufferCreateStatic( uxDummy,
uxDummy,
( uint8_t * ) &xReturn, /* Dummy value just to pass a non NULL value in - won't get used. */
NULL );
if( ulReturned != 0 )
{
/* Something returned a non-NULL value. */
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvTraceUtils( void )
{
EventGroupHandle_t xEventGroup;
QueueHandle_t xQueue;
BaseType_t xReturn = pdPASS;
const UBaseType_t xNumber = ( UBaseType_t ) 100, xQueueLength = ( UBaseType_t ) 1;
UBaseType_t uxValue;
TaskHandle_t xTaskHandle;
StreamBufferHandle_t xStreamBuffer;
MessageBufferHandle_t xMessageBuffer;
/* Exercise the event group trace utilities. */
xEventGroup = xEventGroupCreate();
if( xEventGroup != NULL )
{
vEventGroupSetNumber( xEventGroup, xNumber );
if( uxEventGroupGetNumber( NULL ) != 0 )
{
xReturn = pdFAIL;
}
if( uxEventGroupGetNumber( xEventGroup ) != xNumber )
{
xReturn = pdFAIL;
}
vEventGroupDelete( xEventGroup );
}
else
{
xReturn = pdFAIL;
}
/* Exercise the queue trace utilities. */
xQueue = xQueueCreate( xQueueLength, ( UBaseType_t ) sizeof( uxValue ) );
if( xQueue != NULL )
{
vQueueSetQueueNumber( xQueue, xNumber );
if( uxQueueGetQueueNumber( xQueue ) != xNumber )
{
xReturn = pdFAIL;
}
if( ucQueueGetQueueType( xQueue ) != queueQUEUE_TYPE_BASE )
{
xReturn = pdFAIL;
}
vQueueDelete( xQueue );
}
else
{
xReturn = pdFAIL;
}
/* Exercise the task trace utilities. Value of 100 is arbitrary, just want
to check the value that is set is also read back. */
uxValue = 100;
xTaskHandle = xTaskGetCurrentTaskHandle();
vTaskSetTaskNumber( xTaskHandle, uxValue );
if( uxTaskGetTaskNumber( xTaskHandle ) != uxValue )
{
xReturn = pdFAIL;
}
if( uxTaskGetTaskNumber( NULL ) != 0 )
{
xReturn = pdFAIL;
}
/* Timer trace util functions are exercised in prvTimerQuery(). */
/* Exercise the stream buffer utilities. Try creating with a trigger level
of 0, it should then get capped to 1. */
xStreamBuffer = xStreamBufferCreate( sizeof( uint32_t ), 0 );
if( xStreamBuffer != NULL )
{
vStreamBufferSetStreamBufferNumber( xStreamBuffer, uxValue );
if( uxStreamBufferGetStreamBufferNumber( xStreamBuffer ) != uxValue )
{
xReturn = pdFALSE;
}
if( ucStreamBufferGetStreamBufferType( xStreamBuffer ) != 0 )
{
/* "Is Message Buffer" flag should have been 0. */
xReturn = pdFALSE;
}
vStreamBufferDelete( xStreamBuffer );
}
else
{
xReturn = pdFALSE;
}
xMessageBuffer = xMessageBufferCreate( sizeof( uint32_t ) );
if( xMessageBuffer != NULL )
{
if( ucStreamBufferGetStreamBufferType( xMessageBuffer ) == 0 )
{
/* "Is Message Buffer" flag should have been 1. */
xReturn = pdFALSE;
}
vMessageBufferDelete( xMessageBuffer );
}
else
{
xReturn = pdFALSE;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvPeekTimeout( void )
{
QueueHandle_t xHandle;
const UBaseType_t xQueueLength = 1;
BaseType_t xReturn = pdPASS;
TickType_t xBlockTime = ( TickType_t ) 2;
UBaseType_t uxReceived;
/* Create the queue just to try peeking it while it is empty. */
xHandle = xQueueCreate( xQueueLength, ( UBaseType_t ) sizeof( xQueueLength ) );
if( xHandle != NULL )
{
if( uxQueueMessagesWaiting( xHandle ) != 0 )
{
xReturn = pdFAIL;
}
/* Ensure peeking from the queue times out as the queue is empty. */
if( xQueuePeek( xHandle, &uxReceived, xBlockTime ) != pdFALSE )
{
xReturn = pdFAIL;
}
vQueueDelete( xHandle );
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvQueueQueryFromISR( void )
{
BaseType_t xReturn = pdPASS, xValue = 1;
const UBaseType_t xISRQueueLength = ( UBaseType_t ) 1;
const char *pcISRQueueName = "ISRQueue";
QueueHandle_t xISRQueue = NULL;
xISRQueue = xQueueCreate( xISRQueueLength, ( UBaseType_t ) sizeof( BaseType_t ) );
if( xISRQueue != NULL )
{
vQueueAddToRegistry( xISRQueue, pcISRQueueName );
if( strcmp( pcQueueGetName( xISRQueue ), pcISRQueueName ) )
{
xReturn = pdFAIL;
}
/* Expect the queue to be empty here. */
if( uxQueueMessagesWaitingFromISR( xISRQueue ) != 0 )
{
xReturn = pdFAIL;
}
if( xQueueIsQueueEmptyFromISR( xISRQueue ) != pdTRUE )
{
xReturn = pdFAIL;
}
if( xQueueIsQueueFullFromISR( xISRQueue ) != pdFALSE )
{
xReturn = pdFAIL;
}
/* Now fill the queue - it only has one space. */
if( xQueueSendFromISR( xISRQueue, &xValue, NULL ) != pdPASS )
{
xReturn = pdFAIL;
}
/* Check it now reports as full. */
if( uxQueueMessagesWaitingFromISR( xISRQueue ) != 1 )
{
xReturn = pdFAIL;
}
if( xQueueIsQueueEmptyFromISR( xISRQueue ) != pdFALSE )
{
xReturn = pdFAIL;
}
if( xQueueIsQueueFullFromISR( xISRQueue ) != pdTRUE )
{
xReturn = pdFAIL;
}
vQueueDelete( xISRQueue );
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvTaskQueryFunctions( void )
{
static TaskStatus_t xStatus, *pxStatusArray;
TaskHandle_t xTimerTask, xIdleTask;
BaseType_t xReturn = pdPASS;
UBaseType_t uxNumberOfTasks, uxReturned, ux;
uint32_t ulTotalRunTime1, ulTotalRunTime2;
const uint32_t ulRunTimeTollerance = ( uint32_t ) 0xfff;
/* Obtain task status with the stack high water mark and without the
state. */
vTaskGetInfo( NULL, &xStatus, pdTRUE, eRunning );
if( uxTaskGetStackHighWaterMark( NULL ) != xStatus.usStackHighWaterMark )
{
xReturn = pdFAIL;
}
if( uxTaskGetStackHighWaterMark2( NULL ) != ( configSTACK_DEPTH_TYPE ) xStatus.usStackHighWaterMark )
{
xReturn = pdFAIL;
}
/* Now obtain a task status without the high water mark but with the state,
which in the case of the idle task should be Read. */
xTimerTask = xTimerGetTimerDaemonTaskHandle();
vTaskSuspend( xTimerTask ); /* Should never suspend Timer task normally!. */
vTaskGetInfo( xTimerTask, &xStatus, pdFALSE, eInvalid );
if( xStatus.eCurrentState != eSuspended )
{
xReturn = pdFAIL;
}
if( xStatus.uxBasePriority != uxTaskPriorityGetFromISR( xTimerTask ) )
{
xReturn = pdFAIL;
}
if( xStatus.uxBasePriority != ( configMAX_PRIORITIES - 1 ) )
{
xReturn = pdFAIL;
}
xTaskResumeFromISR( xTimerTask );
vTaskGetInfo( xTimerTask, &xStatus, pdTRUE, eInvalid );
if( ( xStatus.eCurrentState != eReady ) && ( xStatus.eCurrentState != eBlocked ) )
{
xReturn = pdFAIL;
}
if( uxTaskGetStackHighWaterMark( xTimerTask ) != xStatus.usStackHighWaterMark )
{
xReturn = pdFAIL;
}
if( uxTaskGetStackHighWaterMark2( xTimerTask ) != ( configSTACK_DEPTH_TYPE ) xStatus.usStackHighWaterMark )
{
xReturn = pdFAIL;
}
/* Attempting to abort a delay in the idle task should be guaranteed to
fail as the idle task should never block. */
xIdleTask = xTaskGetIdleTaskHandle();
if( xTaskAbortDelay( xIdleTask ) != pdFAIL )
{
xReturn = pdFAIL;
}
/* Create an array of task status objects large enough to hold information
on the number of tasks at this time - note this may change at any time if
higher priority tasks are executing and creating tasks. */
uxNumberOfTasks = uxTaskGetNumberOfTasks();
pxStatusArray = ( TaskStatus_t * ) pvPortMalloc( uxNumberOfTasks * sizeof( TaskStatus_t ) );
if( pxStatusArray != NULL )
{
/* Pass part of the array into uxTaskGetSystemState() to ensure it doesn't
try using more space than there is available. */
uxReturned = uxTaskGetSystemState( pxStatusArray, uxNumberOfTasks / ( UBaseType_t ) 2, NULL );
if( uxReturned != ( UBaseType_t ) 0 )
{
xReturn = pdFAIL;
}
/* Now do the same but passing in the complete array size, this is done
twice to check for a difference in the total run time. */
uxTaskGetSystemState( pxStatusArray, uxNumberOfTasks, &ulTotalRunTime1 );
memset( ( void * ) pxStatusArray, 0xaa, uxNumberOfTasks * sizeof( TaskStatus_t ) );
uxReturned = uxTaskGetSystemState( pxStatusArray, uxNumberOfTasks, &ulTotalRunTime2 );
if( ( ulTotalRunTime2 - ulTotalRunTime1 ) > ulRunTimeTollerance )
{
xReturn = pdFAIL;
}
/* Basic santity check of array contents. */
for( ux = 0; ux < uxReturned; ux++ )
{
if( pxStatusArray[ ux ].eCurrentState >= ( UBaseType_t ) eInvalid )
{
xReturn = pdFAIL;
}
if( pxStatusArray[ ux ].uxCurrentPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
{
xReturn = pdFAIL;
}
}
vPortFree( pxStatusArray );
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvDummyTagFunction( void *pvParameter )
{
return ( BaseType_t ) pvParameter;
}
/*-----------------------------------------------------------*/
static BaseType_t prvTaskTags( void )
{
BaseType_t xReturn = pdPASS, xParameter = ( BaseType_t ) 0xDEADBEEF;
TaskHandle_t xTask;
/* First try with the handle of a different task. Use the timer task for
convenience. */
xTask = xTimerGetTimerDaemonTaskHandle();
vTaskSetApplicationTaskTag( xTask, prvDummyTagFunction );
if( xTaskGetApplicationTaskTag( xTask ) != prvDummyTagFunction )
{
xReturn = pdFAIL;
}
else
{
if( xTaskCallApplicationTaskHook( xTask, ( void * ) xParameter ) != xParameter )
{
xReturn = pdFAIL;
}
if( xTaskCallApplicationTaskHook( xTask, ( void * ) NULL ) != pdFAIL )
{
xReturn = pdFAIL;
}
}
/* Try FromISR version too. */
if( xTaskGetApplicationTaskTagFromISR( xTask ) != prvDummyTagFunction )
{
xReturn = pdFAIL;
}
/* Now try with a NULL handle, so using this task. */
vTaskSetApplicationTaskTag( NULL, NULL );
if( xTaskGetApplicationTaskTag( NULL ) != NULL )
{
xReturn = pdFAIL;
}
if( xTaskGetApplicationTaskTagFromISR( NULL ) != NULL )
{
xReturn = pdFAIL;
}
vTaskSetApplicationTaskTag( NULL, prvDummyTagFunction );
if( xTaskGetApplicationTaskTag( NULL ) != prvDummyTagFunction )
{
xReturn = pdFAIL;
}
else
{
if( xTaskCallApplicationTaskHook( NULL, ( void * ) xParameter ) != xParameter )
{
xReturn = pdFAIL;
}
if( xTaskCallApplicationTaskHook( NULL, ( void * ) NULL ) != pdFAIL )
{
xReturn = pdFAIL;
}
}
/* Try FromISR version too. */
if( xTaskGetApplicationTaskTagFromISR( NULL ) != prvDummyTagFunction )
{
xReturn = pdFAIL;
}
vTaskSetApplicationTaskTag( NULL, NULL );
if( xTaskGetApplicationTaskTag( NULL ) != NULL )
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvTimerQuery( void )
{
TimerHandle_t xTimer;
BaseType_t xReturn = pdPASS;
const char *pcTimerName = "TestTimer";
const TickType_t xTimerPeriod = ( TickType_t ) 100;
const UBaseType_t uxTimerNumber = ( UBaseType_t ) 55;
xTimer = xTimerCreate( pcTimerName,
xTimerPeriod,
pdFALSE,
( void * ) xTimerPeriod,
NULL ); /* Not actually going to start timer so NULL callback is ok. */
if( xTimer != NULL )
{
if( xTimerGetPeriod( xTimer ) != xTimerPeriod )
{
xReturn = pdFAIL;
}
if( strcmp( pcTimerGetName( xTimer ), pcTimerName ) != 0 )
{
xReturn = pdFAIL;
}
vTimerSetTimerNumber( xTimer, uxTimerNumber );
if( uxTimerGetTimerNumber( xTimer ) != uxTimerNumber )
{
xReturn = pdFAIL;
}
xTimerDelete( xTimer, portMAX_DELAY );
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
BaseType_t xRunCodeCoverageTestAdditions( void )
{
BaseType_t xReturn = pdPASS;
xReturn &= prvStaticAllocationsWithNullBuffers();
xReturn &= prvTraceUtils();
xReturn &= prvPeekTimeout();
xReturn &= prvQueueQueryFromISR();
xReturn &= prvTaskQueryFunctions();
xReturn &= prvTaskTags();
xReturn &= prvTimerQuery();
return xReturn;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,59 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Cambridge Consultants Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*-----------------------------------------------------------
* Example console I/O wrappers.
*----------------------------------------------------------*/
#include <stdarg.h>
#include <stdio.h>
#include <FreeRTOS.h>
#include <semphr.h>
SemaphoreHandle_t xStdioMutex;
StaticSemaphore_t xStdioMutexBuffer;
void console_init(void)
{
xStdioMutex = xSemaphoreCreateMutexStatic(&xStdioMutexBuffer);
}
void console_print(const char *fmt, ...)
{
va_list vargs;
va_start(vargs, fmt);
xSemaphoreTake(xStdioMutex, portMAX_DELAY);
vprintf(fmt, vargs);
xSemaphoreGive(xStdioMutex);
va_end(vargs);
}

View File

@ -0,0 +1,45 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Cambridge Consultants Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef CONSOLE_H
#define CONSOLE_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------
* Example console I/O wrappers.
*----------------------------------------------------------*/
void console_init(void);
void console_print(const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif /* CONSOLE_H */

View File

@ -0,0 +1,354 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/******************************************************************************
* This project provides two demo applications. A simple blinky style project,
* and a more comprehensive test and demo application. The
* 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 comprehensive test and demo application is implemented and described in
* main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and FreeRTOS hook functions.
*
*******************************************************************************
* NOTE: Windows will not be running the FreeRTOS demo threads continuously, so
* do not expect to get real time behaviour from the FreeRTOS Windows port, or
* this demo application. Also, the timing information in the FreeRTOS+Trace
* logs have no meaningful units. See the documentation page for the Windows
* port for further information:
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
*
*
*******************************************************************************
*/
/* Standard includes. */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Local includes. */
#include "console.h"
/* This project provides two demo applications. A simple blinky style demo
application, and a more comprehensive test and demo application. The
mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is 1 then the blinky demo will be built.
The blinky demo is implemented and described in main_blinky.c.
If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and
demo application will be built. The comprehensive test and demo application is
implemented and described in main_full.c. */
#ifndef mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
#endif
/* This demo uses heap_3.c (the libc provided malloc() and free()). */
/*-----------------------------------------------------------*/
/*
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/
extern void main_blinky( void );
extern void main_full( void );
/*
* Only the comprehensive demo uses application hook (callback) functions. See
* http://www.freertos.org/a00016.html for more information.
*/
void vFullDemoTickHookFunction( void );
void vFullDemoIdleFunction( void );
/*
* Prototypes for the standard FreeRTOS application hook (callback) functions
* implemented within this file. See http://www.freertos.org/a00016.html .
*/
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationTickHook( void );
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
/*
* Writes trace data to a disk file when the trace recording is stopped.
* This function will simply overwrite any trace files that already exist.
*/
static void prvSaveTraceFile( void );
/*-----------------------------------------------------------*/
/* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
use a callback function to optionally provide the memory required by the idle
and timer tasks. This is the stack that will be used by the timer task. It is
declared here, as a global, so it can be checked by a test that is implemented
in a different file. */
StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
/* Notes if the trace is running or not. */
static BaseType_t xTraceRunning = pdTRUE;
/*-----------------------------------------------------------*/
int main( void )
{
/* Do not include trace code when performing a code coverage analysis. */
#if( projCOVERAGE_TEST != 1 )
{
/* Initialise the trace recorder. Use of the trace recorder is optional.
See http://www.FreeRTOS.org/trace for more information. */
vTraceEnable( TRC_START );
/* Start the trace recording - the recording is written to a file if
configASSERT() is called. */
printf( "\r\nTrace started.\r\nThe trace will be dumped to disk if a call to configASSERT() fails.\r\n" );
printf( "Uncomment the call to kbhit() in this file to also dump trace with a key press.\r\n" );
uiTraceStart();
}
#endif
console_init();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
#else
{
main_full();
}
#endif
return 0;
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c, heap_2.c or heap_4.c is being used, then the
size of the heap available to pvPortMalloc() is defined by
configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
API function can be used to query the size of free heap space that remains
(although it does not provide information on how the remaining heap might be
fragmented). See http://www.freertos.org/a00111.html for more
information. */
vAssertCalled( __LINE__, __FILE__ );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If application tasks make use of the
vTaskDelete() API function to delete themselves then it is also important
that vApplicationIdleHook() is permitted to return to its calling function,
because it is the responsibility of the idle task to clean up memory
allocated by the kernel to any task that has since deleted itself. */
sleep(1);
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
{
/* Call the idle task processing used by the full demo. The simple
blinky demo does not use the idle task hook. */
vFullDemoIdleFunction();
}
#endif
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. This function is
provided as an example only as stack overflow checking does not function
when running the FreeRTOS Windows port. */
vAssertCalled( __LINE__, __FILE__ );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
{
vFullDemoTickHookFunction();
}
#endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */
}
/*-----------------------------------------------------------*/
void vApplicationDaemonTaskStartupHook( void )
{
/* This function will be called once only, when the daemon task starts to
execute (sometimes called the timer task). This is useful if the
application includes initialisation code that would benefit from executing
after the scheduler has been started. */
}
/*-----------------------------------------------------------*/
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
{
static BaseType_t xPrinted = pdFALSE;
volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
/* Called if an assertion passed to configASSERT() fails. See
http://www.freertos.org/a00110.html#configASSERT for more information. */
/* Parameters are not used. */
( void ) ulLine;
( void ) pcFileName;
taskENTER_CRITICAL();
{
/* Stop the trace recording. */
if( xPrinted == pdFALSE )
{
xPrinted = pdTRUE;
if( xTraceRunning == pdTRUE )
{
prvSaveTraceFile();
}
}
/* 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();
}
/*-----------------------------------------------------------*/
static void prvSaveTraceFile( void )
{
/* Tracing is not used when code coverage analysis is being performed. */
#if( projCOVERAGE_TEST != 1 )
{
FILE* pxOutputFile;
vTraceStop();
pxOutputFile = fopen( "Trace.dump", "wb");
if( pxOutputFile != NULL )
{
fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );
fclose( pxOutputFile );
printf( "\r\nTrace output saved to Trace.dump\r\n" );
}
else
{
printf( "\r\nFailed to create trace dump file\r\n" );
}
}
#endif
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
/* If the buffers to be provided to the Idle task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
/* If the buffers to be provided to the Timer task are declared inside this
function then they must be declared static - otherwise they will be allocated on
the stack and so not exists after this function exits. */
static StaticTask_t xTimerTaskTCB;
/* Pass out a pointer to the StaticTask_t structure in which the Timer
task's state will be stored. */
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
/* Pass out the array that will be used as the Timer task's stack. */
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

View File

@ -0,0 +1,265 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: Windows will not be running the FreeRTOS demo threads continuously, so
* do not expect to get real time behaviour from the FreeRTOS Windows port, or
* this demo application. Also, the timing information in the FreeRTOS+Trace
* logs have no meaningful units. See the documentation page for the Windows
* port for further information:
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
*
* NOTE 2: This project provides two demo applications. A simple blinky style
* project, and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
* in main.c. This file implements the simply blinky version. Console output
* is used in place of the normal LED toggling.
*
* NOTE 3: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, are defined
* in main.c.
******************************************************************************
*
* main_blinky() creates one queue, one software timer, and two tasks. It then
* starts the scheduler.
*
* The Queue Send Task:
* The queue send task is implemented by the prvQueueSendTask() function in
* this file. It uses vTaskDelayUntil() to create a periodic task that sends
* the value 100 to the queue every 200 milliseconds (please read the notes
* above regarding the accuracy of timing under Windows).
*
* The Queue Send Software Timer:
* The timer is an auto-reload timer with a period of two seconds. The timer's
* callback function writes the value 200 to the queue. The callback function
* is implemented by prvQueueSendTimerCallback() within this file.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() waits for data to arrive on the queue.
* When data is received, the task checks the value of the data, then outputs a
* message to indicate if the data came from the queue send task or the queue
* send software timer.
*
* Expected Behaviour:
* - The queue send task writes to the queue every 200ms, so every 200ms the
* queue receive task will output a message indicating that data was received
* on the queue from the queue send task.
* - The queue send software timer has a period of two seconds, and is reset
* each time a key is pressed. So if two seconds expire without a key being
* pressed then the queue receive task will output a message indicating that
* data was received on the queue from the queue send software timer.
*
* NOTE: Console input and output relies on Windows system calls, which can
* interfere with the execution of the FreeRTOS Windows port. This demo only
* uses Windows system call occasionally. Heavier use of Windows system calls
* can crash the port.
*/
#include <stdio.h>
#include <pthread.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
/* Local includes. */
#include "console.h"
/* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The times are converted from
milliseconds to ticks using the pdMS_TO_TICKS() macro. */
#define mainTASK_SEND_FREQUENCY_MS pdMS_TO_TICKS( 200UL )
#define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL )
/* The number of items the queue can hold at once. */
#define mainQUEUE_LENGTH ( 2 )
/* The values sent to the queue receive task from the queue send task and the
queue send software timer respectively. */
#define mainVALUE_SENT_FROM_TASK ( 100UL )
#define mainVALUE_SENT_FROM_TIMER ( 200UL )
/*-----------------------------------------------------------*/
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*
* The callback function executed when the software timer expires.
*/
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */
static QueueHandle_t xQueue = NULL;
/* A software timer that is started from the tick hook. */
static TimerHandle_t xTimer = NULL;
/*-----------------------------------------------------------*/
/*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/
void main_blinky( void )
{
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this simple case. */
mainQUEUE_RECEIVE_TASK_PRIORITY,/* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer, but don't start it yet. */
xTimer = xTimerCreate( "Timer", /* The text name assigned to the software timer - for debug only as it is not used by the kernel. */
xTimerPeriod, /* The period of the software timer in ticks. */
pdTRUE, /* xAutoReload is set to pdTRUE. */
NULL, /* The timer's ID is not used. */
prvQueueSendTimerCallback );/* The function executed when the timer expires. */
if( xTimer != NULL )
{
xTimerStart( xTimer, 0 );
}
/* Start the tasks and timer running. */
vTaskStartScheduler();
}
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details. */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Prevent the compiler warning about the unused parameter. */
( void ) pvParameters;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
{
/* Place this task in the blocked state until it is time to run again.
The block time is specified in ticks, pdMS_TO_TICKS() was used to
convert a time specified in milliseconds into a time specified in ticks.
While in the Blocked state this task will not consume any CPU time. */
vTaskDelayUntil( &xNextWakeTime, xBlockTime );
/* Send to the queue - causing the queue receive task to unblock and
write to the console. 0 is used as the block time so the send operation
will not block - it shouldn't need to block as the queue should always
have at least one space at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )
{
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;
/* This is the software timer callback function. The software timer has a
period of two seconds and is reset each time a key is pressed. This
callback function will execute if the timer expires, which will only happen
if a key is not pressed for two seconds. */
/* Avoid compiler warnings resulting from the unused parameter. */
( void ) xTimerHandle;
/* Send to the queue - causing the queue receive task to unblock and
write out a message. This function is called from the timer/daemon task, so
must not block. Hence the block time is set to 0. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
{
uint32_t ulReceivedValue;
/* Prevent the compiler warning about the unused parameter. */
( void ) pvParameters;
for( ;; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. It will not use any CPU time while it is in the
Blocked state. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but
is it an expected value? Normally calling printf() from a task is not
a good idea. Here there is lots of stack space and only one task is
using console IO so it is ok. However, note the comments at the top of
this file about the risks of making Windows system calls (such as
console output) from a FreeRTOS task. */
if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )
{
console_print( "Message received from task\n" );
}
else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
{
console_print( "Message received from software timer\n" );
}
else
{
console_print( "Unexpected message\n" );
}
}
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,896 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
*******************************************************************************
* NOTE 1: The Win32 port is a simulation (or is that emulation?) only! Do not
* expect to get real time behaviour from the Win32 port or this demo
* application. It is provided as a convenient development and demonstration
* test bed only.
*
* Windows will not be running the FreeRTOS simulator threads continuously, so
* the timing information in the FreeRTOS+Trace logs have no meaningful units.
* See the documentation page for the Windows simulator for an explanation of
* the slow timing:
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
* - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -
*
* NOTE 2: This project provides two demo applications. A simple blinky style
* project, and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
* in main.c. This file implements the comprehensive test and demo version.
*
* NOTE 3: This file only contains the source code that is specific to the
* full demo. Generic functions, such FreeRTOS hook functions, are defined in
* main.c.
*******************************************************************************
*
* main() creates all the demo application tasks, then starts the scheduler.
* The web documentation provides more details of the standard demo application
* tasks, which provide no particular functionality but do provide a good
* example of how to use the FreeRTOS API.
*
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
* "Check" task - This only executes every five seconds but has a high priority
* to ensure it gets processor time. Its main function is to check that all the
* standard demo tasks are still operational. While no errors have been
* discovered the check task will print out "OK" and the current simulated tick
* time. If an error is discovered in the execution of a task then the check
* task will print out an appropriate error message.
*
*/
/* Standard includes. */
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* Kernel includes. */
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <timers.h>
#include <semphr.h>
/* Standard demo includes. */
#include "BlockQ.h"
#include "integer.h"
#include "semtest.h"
#include "PollQ.h"
#include "GenQTest.h"
#include "QPeek.h"
#include "recmutex.h"
#include "flop.h"
#include "TimerDemo.h"
#include "countsem.h"
#include "death.h"
#include "dynamic.h"
#include "QueueSet.h"
#include "QueueOverwrite.h"
#include "EventGroupsDemo.h"
#include "IntSemTest.h"
#include "TaskNotify.h"
#include "QueueSetPolling.h"
#include "StaticAllocation.h"
#include "blocktim.h"
#include "AbortDelay.h"
#include "MessageBufferDemo.h"
#include "StreamBufferDemo.h"
#include "StreamBufferInterrupt.h"
#include "MessageBufferAMP.h"
/* Priorities at which the tasks are created. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainQUEUE_OVERWRITE_PRIORITY ( tskIDLE_PRIORITY )
#define mainTIMER_TEST_PERIOD ( 50 )
/*
* Exercises code that is not otherwise covered by the standard demo/test
* tasks.
*/
extern BaseType_t xRunCodeCoverageTestAdditions( void );
/* Task function prototypes. */
static void prvCheckTask( void *pvParameters );
/* A task that is created from the idle task to test the functionality of
eTaskStateGet(). */
static void prvTestTask( void *pvParameters );
/*
* Called from the idle task hook function to demonstrate a few utility
* functions that are not demonstrated by any of the standard demo tasks.
*/
static void prvDemonstrateTaskStateAndHandleGetFunctions( void );
/*
* Called from the idle task hook function to demonstrate the use of
* xTimerPendFunctionCall() as xTimerPendFunctionCall() is not demonstrated by
* any of the standard demo tasks.
*/
static void prvDemonstratePendingFunctionCall( void );
/*
* The function that is pended by prvDemonstratePendingFunctionCall().
*/
static void prvPendedFunction( void *pvParameter1, uint32_t ulParameter2 );
/*
* prvDemonstrateTimerQueryFunctions() is called from the idle task hook
* function to demonstrate the use of functions that query information about a
* software timer. prvTestTimerCallback() is the callback function for the
* timer being queried.
*/
static void prvDemonstrateTimerQueryFunctions( void );
static void prvTestTimerCallback( TimerHandle_t xTimer );
/*
* A task to demonstrate the use of the xQueueSpacesAvailable() function.
*/
static void prvDemoQueueSpaceFunctions( void *pvParameters );
/*
* Tasks that ensure indefinite delays are truly indefinite.
*/
static void prvPermanentlyBlockingSemaphoreTask( void *pvParameters );
static void prvPermanentlyBlockingNotificationTask( void *pvParameters );
/*
* The test function and callback function used when exercising the timer AP
* function that changes the timer's auto-reload mode.
*/
static void prvDemonstrateChangingTimerReloadMode( void *pvParameters );
static void prvReloadModeTestTimerCallback( TimerHandle_t xTimer );
/*-----------------------------------------------------------*/
/* The variable into which error messages are latched. */
static char *pcStatusMessage = "No errors";
/* This semaphore is created purely to test using the vSemaphoreDelete() and
semaphore tracing API functions. It has no other purpose. */
static SemaphoreHandle_t xMutexToDelete = NULL;
/*-----------------------------------------------------------*/
int main_full( void )
{
/* Start the check task as described at the top of this file. */
xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Create the standard demo tasks. */
vStartTaskNotifyTask();
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
vStartQueuePeekTasks();
vStartMathTasks( mainFLOP_TASK_PRIORITY );
vStartRecursiveMutexTasks();
vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks();
vStartQueueSetTasks();
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );
xTaskCreate( prvDemoQueueSpaceFunctions, NULL, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); /* Name is null for code coverage. */
vStartEventGroupTasks();
vStartInterruptSemaphoreTasks();
vStartQueueSetPollingTask();
vCreateBlockTimeTasks();
vCreateAbortDelayTasks();
xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvPermanentlyBlockingSemaphoreTask, "BlockSem", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvPermanentlyBlockingNotificationTask, "BlockNoti", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvDemonstrateChangingTimerReloadMode, "TimerMode", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
vStartMessageBufferTasks( configMINIMAL_STACK_SIZE );
/* vStartStreamBufferTasks(); */
/* vStartStreamBufferInterruptDemo(); */
vStartMessageBufferAMPTasks( configMINIMAL_STACK_SIZE );
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
{
vStartStaticallyAllocatedTasks();
}
#endif
#if( configUSE_PREEMPTION != 0 )
{
/* Don't expect these tasks to pass when preemption is not used. */
//vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
}
#endif
/* The suicide tasks must be created last as they need to know how many
tasks were running prior to their creation. This then allows them to
ascertain whether or not the correct/expected number of tasks are running at
any given time. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Create the semaphore that will be deleted in the idle task hook. This
is done purely to test the use of vSemaphoreDelete(). */
xMutexToDelete = xSemaphoreCreateMutex();
/* Start the scheduler itself. */
vTaskStartScheduler();
/* Should never get here unless there was not enough heap space to create
the idle and other system tasks. */
return 0;
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
/* Just to remove compiler warning. */
( void ) pvParameters;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, xCycleFrequency );
/* Check the standard demo tasks are running without error. */
/* #if( configUSE_PREEMPTION != 0 ) */
/* { */
/* /\* These tasks are only created when preemption is used. *\/ */
/* if( xAreTimerDemoTasksStillRunning( xCycleFrequency ) != pdTRUE ) */
/* { */
/* pcStatusMessage = "Error: TimerDemo"; */
/* } */
/* } */
/* #endif */
/* if( xAreStreamBufferTasksStillRunning() != pdTRUE ) */
/* { */
/* pcStatusMessage = "Error: StreamBuffer"; */
/* } */
/* else */if( xAreMessageBufferTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: MessageBuffer";
}
else if( xAreTaskNotificationTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: Notification";
}
else if( xAreInterruptSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: IntSem";
}
else if( xAreEventGroupTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: EventGroup";
}
else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: IntMath";
}
else if( xAreGenericQueueTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: GenQueue";
}
else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: QueuePeek";
}
else if( xAreBlockingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: BlockQueue";
}
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: SemTest";
}
else if( xArePollingQueuesStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: PollQueue";
}
else if( xAreMathsTaskStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Flop";
}
else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: RecMutex";
}
else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: CountSem";
}
else if( xIsCreateTaskStillRunning() != pdTRUE )
{
pcStatusMessage = "Error: Death";
}
else if( xAreDynamicPriorityTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Dynamic";
}
else if( xAreQueueSetTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue set";
}
else if( xIsQueueOverwriteTaskStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue overwrite";
}
else if( xAreQueueSetPollTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Queue set polling";
}
else if( xAreBlockTimeTestTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Block time";
}
else if( xAreAbortDelayTestTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Abort delay";
}
/* else if( xIsInterruptStreamBufferDemoStillRunning() != pdPASS ) */
/* { */
/* pcStatusMessage = "Error: Stream buffer interrupt"; */
/* } */
else if( xAreMessageBufferAMPTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Message buffer AMP";
}
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
else if( xAreStaticAllocationTasksStillRunning() != pdPASS )
{
pcStatusMessage = "Error: Static allocation";
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
}
}
/*-----------------------------------------------------------*/
static void prvTestTask( void *pvParameters )
{
const unsigned long ulMSToSleep = 5;
/* Just to remove compiler warnings. */
( void ) pvParameters;
/* This task is just used to test the eTaskStateGet() function. It
does not have anything to do. */
for( ;; )
{
/* Sleep to reduce CPU load, but don't sleep indefinitely in case there are
tasks waiting to be terminated by the idle task. */
struct timespec ts;
ts.tv_sec = ulMSToSleep / 1000;
ts.tv_nsec = ulMSToSleep % 1000l * 1000000l;
nanosleep( &ts, NULL );
}
}
/*-----------------------------------------------------------*/
/* Called from vApplicationIdleHook(), which is defined in main.c. */
void vFullDemoIdleFunction( void )
{
const unsigned long ulMSToSleep = 15;
void *pvAllocated;
/* Sleep to reduce CPU load, but don't sleep indefinitely in case there are
tasks waiting to be terminated by the idle task. */
struct timespec ts;
ts.tv_sec = ulMSToSleep / 1000;
ts.tv_nsec = ulMSToSleep % 1000l * 1000000l;
nanosleep( &ts, NULL );
/* Demonstrate a few utility functions that are not demonstrated by any of
the standard demo tasks. */
prvDemonstrateTaskStateAndHandleGetFunctions();
/* Demonstrate the use of xTimerPendFunctionCall(), which is not
demonstrated by any of the standard demo tasks. */
prvDemonstratePendingFunctionCall();
/* Demonstrate the use of functions that query information about a software
timer. */
prvDemonstrateTimerQueryFunctions();
/* If xMutexToDelete has not already been deleted, then delete it now.
This is done purely to demonstrate the use of, and test, the
vSemaphoreDelete() macro. Care must be taken not to delete a semaphore
that has tasks blocked on it. */
if( xMutexToDelete != NULL )
{
/* For test purposes, add the mutex to the registry, then remove it
again, before it is deleted - checking its name is as expected before
and after the assertion into the registry and its removal from the
registry. */
configASSERT( pcQueueGetName( xMutexToDelete ) == NULL );
vQueueAddToRegistry( xMutexToDelete, "Test_Mutex" );
configASSERT( strcmp( pcQueueGetName( xMutexToDelete ), "Test_Mutex" ) == 0 );
vQueueUnregisterQueue( xMutexToDelete );
configASSERT( pcQueueGetName( xMutexToDelete ) == NULL );
vSemaphoreDelete( xMutexToDelete );
xMutexToDelete = NULL;
}
/* Exercise heap_5 a bit. The malloc failed hook will trap failed
allocations so there is no need to test here. */
pvAllocated = pvPortMalloc( ( rand() % 500 ) + 1 );
vPortFree( pvAllocated );
/* Exit after a fixed time so code coverage results are written to the
disk. */
#if( projCOVERAGE_TEST == 1 )
{
const TickType_t xMaxRunTime = pdMS_TO_TICKS( 30000UL );
/* Exercise code not otherwise executed by standard demo/test tasks. */
if( xRunCodeCoverageTestAdditions() != pdPASS )
{
pcStatusMessage = "Code coverage additions failed.\r\n";
}
if( ( xTaskGetTickCount() - configINITIAL_TICK_COUNT ) >= xMaxRunTime )
{
vTaskEndScheduler();
}
}
#endif
}
/*-----------------------------------------------------------*/
/* Called by vApplicationTickHook(), which is defined in main.c. */
void vFullDemoTickHookFunction( void )
{
TaskHandle_t xTimerTask;
/* Call the periodic timer test, which tests the timer API functions that
can be called from an ISR. */
/* #if( configUSE_PREEMPTION != 0 ) */
/* { */
/* /\* Only created when preemption is used. *\/ */
/* vTimerPeriodicISRTests(); */
/* } */
/* #endif */
/* Call the periodic queue overwrite from ISR demo. */
vQueueOverwritePeriodicISRDemo();
/* Write to a queue that is in use as part of the queue set demo to
demonstrate using queue sets from an ISR. */
vQueueSetAccessQueueSetFromISR();
vQueueSetPollingInterruptAccess();
/* Exercise event groups from interrupts. */
vPeriodicEventGroupsProcessing();
/* Exercise giving mutexes from an interrupt. */
vInterruptSemaphorePeriodicTest();
/* Exercise using task notifications from an interrupt. */
xNotifyTaskFromISR();
/* Writes to stream buffer byte by byte to test the stream buffer trigger
level functionality. */
/* vPeriodicStreamBufferProcessing(); */
/* Writes a string to a string buffer four bytes at a time to demonstrate
a stream being sent from an interrupt to a task. */
/* vBasicStreamBufferSendFromISR(); */
/* For code coverage purposes. */
xTimerTask = xTimerGetTimerDaemonTaskHandle();
configASSERT( uxTaskPriorityGetFromISR( xTimerTask ) == configTIMER_TASK_PRIORITY );
( void ) xTimerTask; /* In case configASSERT() is not defined. */
}
/*-----------------------------------------------------------*/
static void prvPendedFunction( void *pvParameter1, uint32_t ulParameter2 )
{
static intptr_t ulLastParameter1 = 1000UL, ulLastParameter2 = 0UL;
intptr_t ulParameter1;
ulParameter1 = ( intptr_t ) pvParameter1;
/* Ensure the parameters are as expected. */
configASSERT( ulParameter1 == ( ulLastParameter1 + 1 ) );
configASSERT( ulParameter2 == ( ulLastParameter2 + 1 ) );
/* Remember the parameters for the next time the function is called. */
ulLastParameter1 = ulParameter1;
ulLastParameter2 = ulParameter2;
/* Remove compiler warnings in case configASSERT() is not defined. */
( void ) ulLastParameter1;
( void ) ulLastParameter2;
}
/*-----------------------------------------------------------*/
static void prvTestTimerCallback( TimerHandle_t xTimer )
{
/* This is the callback function for the timer accessed by
prvDemonstrateTimerQueryFunctions(). The callback does not do anything. */
( void ) xTimer;
}
/*-----------------------------------------------------------*/
static void prvDemonstrateTimerQueryFunctions( void )
{
static TimerHandle_t xTimer = NULL;
const char *pcTimerName = "TestTimer";
volatile TickType_t xExpiryTime;
const TickType_t xDontBlock = 0;
if( xTimer == NULL )
{
xTimer = xTimerCreate( pcTimerName, portMAX_DELAY, pdTRUE, NULL, prvTestTimerCallback );
if( xTimer != NULL )
{
/* Called from the idle task so a block time must not be
specified. */
xTimerStart( xTimer, xDontBlock );
}
}
if( xTimer != NULL )
{
/* Demonstrate querying a timer's name. */
configASSERT( strcmp( pcTimerGetName( xTimer ), pcTimerName ) == 0 );
/* Demonstrate querying a timer's period. */
configASSERT( xTimerGetPeriod( xTimer ) == portMAX_DELAY );
/* Demonstrate querying a timer's next expiry time, although nothing is
done with the returned value. Note if the expiry time is less than the
maximum tick count then the expiry time has overflowed from the current
time. In this case the expiry time was set to portMAX_DELAY, so it is
expected to be less than the current time until the current time has
itself overflowed. */
xExpiryTime = xTimerGetExpiryTime( xTimer );
( void ) xExpiryTime;
}
}
/*-----------------------------------------------------------*/
static void prvDemonstratePendingFunctionCall( void )
{
static intptr_t ulParameter1 = 1000UL, ulParameter2 = 0UL;
const TickType_t xDontBlock = 0; /* This is called from the idle task so must *not* attempt to block. */
/* prvPendedFunction() just expects the parameters to be incremented by one
each time it is called. */
ulParameter1++;
ulParameter2++;
/* Pend the function call, sending the parameters. */
xTimerPendFunctionCall( prvPendedFunction, ( void * ) ulParameter1, ulParameter2, xDontBlock );
}
/*-----------------------------------------------------------*/
static void prvDemonstrateTaskStateAndHandleGetFunctions( void )
{
TaskHandle_t xIdleTaskHandle, xTimerTaskHandle;
char *pcTaskName;
static portBASE_TYPE xPerformedOneShotTests = pdFALSE;
TaskHandle_t xTestTask;
TaskStatus_t xTaskInfo;
extern StackType_t uxTimerTaskStack[];
static uint32_t ulLastIdleExecutionTime = 0;
uint32_t ulIdleExecutionTime;
/* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and
xTaskGetIdleTaskHandle() functions. Also try using the function that sets
the task number. */
xIdleTaskHandle = xTaskGetIdleTaskHandle();
xTimerTaskHandle = xTimerGetTimerDaemonTaskHandle();
/* This is the idle hook, so the current task handle should equal the
returned idle task handle. */
if( xTaskGetCurrentTaskHandle() != xIdleTaskHandle )
{
pcStatusMessage = "Error: Returned idle task handle was incorrect";
}
/* Check the same handle is obtained using the idle task's name. First try
with the wrong name, then the right name. */
if( xTaskGetHandle( "Idle" ) == xIdleTaskHandle )
{
pcStatusMessage = "Error: Returned handle for name Idle was incorrect";
}
if( xTaskGetHandle( "IDLE" ) != xIdleTaskHandle )
{
pcStatusMessage = "Error: Returned handle for name Idle was incorrect";
}
/* Check the timer task handle was returned correctly. */
pcTaskName = pcTaskGetName( xTimerTaskHandle );
if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )
{
pcStatusMessage = "Error: Returned timer task handle was incorrect";
}
if( xTaskGetHandle( "Tmr Svc" ) != xTimerTaskHandle )
{
pcStatusMessage = "Error: Returned handle for name Tmr Svc was incorrect";
}
/* This task is running, make sure it's state is returned as running. */
if( eTaskStateGet( xIdleTaskHandle ) != eRunning )
{
pcStatusMessage = "Error: Returned idle task state was incorrect";
}
/* If this task is running, then the timer task must be blocked. */
if( eTaskStateGet( xTimerTaskHandle ) != eBlocked )
{
pcStatusMessage = "Error: Returned timer task state was incorrect";
}
/* Also with the vTaskGetInfo() function. */
vTaskGetInfo( xTimerTaskHandle, /* The task being queried. */
&xTaskInfo, /* The structure into which information on the task will be written. */
pdTRUE, /* Include the task's high watermark in the structure. */
eInvalid ); /* Include the task state in the structure. */
/* Check the information returned by vTaskGetInfo() is as expected. */
if( ( xTaskInfo.eCurrentState != eBlocked ) ||
( strcmp( xTaskInfo.pcTaskName, "Tmr Svc" ) != 0 ) ||
( xTaskInfo.uxCurrentPriority != configTIMER_TASK_PRIORITY ) ||
( xTaskInfo.pxStackBase != uxTimerTaskStack ) ||
( xTaskInfo.xHandle != xTimerTaskHandle ) )
{
pcStatusMessage = "Error: vTaskGetInfo() returned incorrect information about the timer task";
}
/* Other tests that should only be performed once follow. The test task
is not created on each iteration because to do so would cause the death
task to report an error (too many tasks running). */
if( xPerformedOneShotTests == pdFALSE )
{
/* Don't run this part of the test again. */
xPerformedOneShotTests = pdTRUE;
/* Create a test task to use to test other eTaskStateGet() return values. */
if( xTaskCreate( prvTestTask, "Test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xTestTask ) == pdPASS )
{
/* If this task is running, the test task must be in the ready state. */
if( eTaskStateGet( xTestTask ) != eReady )
{
pcStatusMessage = "Error: Returned test task state was incorrect 1";
}
/* Now suspend the test task and check its state is reported correctly. */
vTaskSuspend( xTestTask );
if( eTaskStateGet( xTestTask ) != eSuspended )
{
pcStatusMessage = "Error: Returned test task state was incorrect 2";
}
/* Now delete the task and check its state is reported correctly. */
vTaskDelete( xTestTask );
if( eTaskStateGet( xTestTask ) != eDeleted )
{
pcStatusMessage = "Error: Returned test task state was incorrect 3";
}
}
}
ulIdleExecutionTime = ulTaskGetIdleRunTimeCounter();
if( ulIdleExecutionTime == ulLastIdleExecutionTime )
{
pcStatusMessage = "Error: Total amount of Idle task execution time did not change";
}
ulLastIdleExecutionTime = ulIdleExecutionTime;
}
/*-----------------------------------------------------------*/
static void prvDemoQueueSpaceFunctions( void *pvParameters )
{
QueueHandle_t xQueue = NULL;
const unsigned portBASE_TYPE uxQueueLength = 10;
unsigned portBASE_TYPE uxReturn, x;
/* Remove compiler warnings. */
( void ) pvParameters;
/* Create the queue that will be used. Nothing is actually going to be
sent or received so the queue item size is set to 0. */
xQueue = xQueueCreate( uxQueueLength, 0 );
configASSERT( xQueue );
for( ;; )
{
for( x = 0; x < uxQueueLength; x++ )
{
/* Ask how many messages are available... */
uxReturn = uxQueueMessagesWaiting( xQueue );
/* Check the number of messages being reported as being available
is as expected, and force an assert if not. */
if( uxReturn != x )
{
/* xQueue cannot be NULL so this is deliberately causing an
assert to be triggered as there is an error. */
configASSERT( xQueue == NULL );
}
/* Ask how many spaces remain in the queue... */
uxReturn = uxQueueSpacesAvailable( xQueue );
/* Check the number of spaces being reported as being available
is as expected, and force an assert if not. */
if( uxReturn != ( uxQueueLength - x ) )
{
/* xQueue cannot be NULL so this is deliberately causing an
assert to be triggered as there is an error. */
configASSERT( xQueue == NULL );
}
/* Fill one more space in the queue. */
xQueueSendToBack( xQueue, NULL, 0 );
}
/* Perform the same check while the queue is full. */
uxReturn = uxQueueMessagesWaiting( xQueue );
if( uxReturn != uxQueueLength )
{
configASSERT( xQueue == NULL );
}
uxReturn = uxQueueSpacesAvailable( xQueue );
if( uxReturn != 0 )
{
configASSERT( xQueue == NULL );
}
/* The queue is full, start again. */
xQueueReset( xQueue );
#if( configUSE_PREEMPTION == 0 )
taskYIELD();
#endif
}
}
/*-----------------------------------------------------------*/
static void prvPermanentlyBlockingSemaphoreTask( void *pvParameters )
{
SemaphoreHandle_t xSemaphore;
/* Prevent compiler warning about unused parameter in the case that
configASSERT() is not defined. */
( void ) pvParameters;
/* This task should block on a semaphore, and never return. */
xSemaphore = xSemaphoreCreateBinary();
configASSERT( xSemaphore );
xSemaphoreTake( xSemaphore, portMAX_DELAY );
/* The above xSemaphoreTake() call should never return, force an assert if
it does. */
configASSERT( pvParameters != NULL );
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvPermanentlyBlockingNotificationTask( void *pvParameters )
{
/* Prevent compiler warning about unused parameter in the case that
configASSERT() is not defined. */
( void ) pvParameters;
/* This task should block on a task notification, and never return. */
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
/* The above ulTaskNotifyTake() call should never return, force an assert
if it does. */
configASSERT( pvParameters != NULL );
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvReloadModeTestTimerCallback( TimerHandle_t xTimer )
{
intptr_t ulTimerID;
/* Increment the timer's ID to show the callback has executed. */
ulTimerID = ( intptr_t ) pvTimerGetTimerID( xTimer );
ulTimerID++;
vTimerSetTimerID( xTimer, ( void * ) ulTimerID );
}
/*-----------------------------------------------------------*/
static void prvDemonstrateChangingTimerReloadMode( void *pvParameters )
{
TimerHandle_t xTimer;
const char * const pcTimerName = "TestTimer";
const TickType_t x100ms = pdMS_TO_TICKS( 100UL );
/* Avoid compiler warnings about unused parameter. */
( void ) pvParameters;
xTimer = xTimerCreate( pcTimerName,
x100ms,
pdFALSE, /* Created as a one-shot timer. */
0,
prvReloadModeTestTimerCallback );
configASSERT( xTimer );
configASSERT( xTimerIsTimerActive( xTimer ) == pdFALSE );
configASSERT( xTimerGetTimerDaemonTaskHandle() != NULL );
configASSERT( strcmp( pcTimerName, pcTimerGetName( xTimer ) ) == 0 );
configASSERT( xTimerGetPeriod( xTimer ) == x100ms );
/* Timer was created as a one-shot timer. Its callback just increments the
timer's ID - so set the ID to 0, let the timer run for a number of timeout
periods, then check the timer has only executed once. */
vTimerSetTimerID( xTimer, ( void * ) 0 );
xTimerStart( xTimer, portMAX_DELAY );
vTaskDelay( 3UL * x100ms );
configASSERT( ( ( uintptr_t ) ( pvTimerGetTimerID( xTimer ) ) ) == 1UL );
/* Now change the timer to be an auto-reload timer and check it executes
the expected number of times. */
vTimerSetReloadMode( xTimer, pdTRUE );
vTimerSetTimerID( xTimer, ( void * ) 0 );
xTimerStart( xTimer, 0 );
vTaskDelay( ( 3UL * x100ms ) + ( x100ms / 2UL ) ); /* Three full periods. */
configASSERT( ( uintptr_t ) ( pvTimerGetTimerID( xTimer ) ) == 3UL );
configASSERT( xTimerStop( xTimer, 0 ) != pdFAIL );
/* Now change the timer back to be a one-shot timer and check it only
executes once. */
vTimerSetReloadMode( xTimer, pdFALSE );
vTimerSetTimerID( xTimer, ( void * ) 0 );
xTimerStart( xTimer, 0 );
vTaskDelay( 3UL * x100ms );
configASSERT( xTimerStop( xTimer, 0 ) != pdFAIL );
configASSERT( ( uintptr_t ) ( pvTimerGetTimerID( xTimer ) ) == 1UL );
/* Clean up at the end. */
xTimerDelete( xTimer, portMAX_DELAY );
vTaskDelete( NULL );
}

View File

@ -0,0 +1,68 @@
/*
* FreeRTOS Kernel V10.3.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/*
* Utility functions required to gather run time statistics. See:
* http://www.freertos.org/rtos-run-time-stats.html
*
* Note that this is a simulated port, where simulated time is a lot slower than
* real time, therefore the run time counter values have no real meaningful
* units.
*
* Also note that it is assumed this demo is going to be used for short periods
* of time only, and therefore timer overflows are not handled.
*/
#include <time.h>
/* FreeRTOS includes. */
#include <FreeRTOS.h>
/* Time at start of day (in ns). */
static unsigned long ulStartTimeNs;
/*-----------------------------------------------------------*/
void vConfigureTimerForRunTimeStats( void )
{
struct timespec xNow;
clock_gettime(CLOCK_MONOTONIC, &xNow);
ulStartTimeNs = xNow.tv_sec * 1000000000ul + xNow.tv_nsec;
}
/*-----------------------------------------------------------*/
unsigned long ulGetRunTimeCounterValue( void )
{
struct timespec xNow;
/* Time at start. */
clock_gettime(CLOCK_MONOTONIC, &xNow);
return xNow.tv_sec * 1000000000ul + xNow.tv_nsec - ulStartTimeNs;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,300 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.1.2
* Percepio AB, www.percepio.com
*
* trcConfig.h
*
* Main configuration parameters for the trace recorder library.
* More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h.
*
* Read more at http://percepio.com/2016/10/05/rtos-tracing/
*
* Terms of Use
* This file is part of the trace recorder library (RECORDER), which is the
* intellectual property of Percepio AB (PERCEPIO) and provided under a
* license as follows.
* The RECORDER may be used free of charge for the purpose of recording data
* intended for analysis in PERCEPIO products. It may not be used or modified
* for other purposes without explicit permission from PERCEPIO.
* You may distribute the RECORDER in its original source code form, assuming
* this text (terms of use, disclaimer, copyright notice) is unchanged. You are
* allowed to distribute the RECORDER with minor modifications intended for
* configuration or porting of the RECORDER, e.g., to allow using it on a
* specific processor, processor family or with a specific communication
* interface. Any such modifications should be documented directly below
* this comment block.
*
* Disclaimer
* The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty
* as to its use or performance. PERCEPIO does not and cannot warrant the
* performance or results you may obtain by using the RECORDER or documentation.
* PERCEPIO make no warranties, express or implied, as to noninfringement of
* third party rights, merchantability, or fitness for any particular purpose.
* In no event will PERCEPIO, its technology partners, or distributors be liable
* to you for any consequential, incidental or special damages, including any
* lost profits or lost savings, even if a representative of PERCEPIO has been
* advised of the possibility of such damages, or for any claim by any third
* party. Some jurisdictions do not allow the exclusion or limitation of
* incidental, consequential or special damages, or the exclusion of implied
* warranties or limitations on how long an implied warranty may last, so the
* above limitations may not apply to you.
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2016.
* www.percepio.com
******************************************************************************/
#ifndef TRC_CONFIG_H
#define TRC_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "trcPortDefines.h"
/******************************************************************************
* Include of processor header file
*
* Here you may need to include the header file for your processor. This is
* required at least for the ARM Cortex-M port, that uses the ARM CMSIS API.
* Try that in case of build problems. Otherwise, remove the #error line below.
*****************************************************************************/
//#error "Trace Recorder: Please include your processor's header file here and remove this line."
/*******************************************************************************
* Configuration Macro: TRC_CFG_HARDWARE_PORT
*
* Specify what hardware port to use (i.e., the "timestamping driver").
*
* All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M".
* This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is
* available on most such devices. In case your device don't have DWT support,
* you will get an error message opening the trace. In that case, you may
* force the recorder to use SysTick timestamping instead, using this define:
*
* #define TRC_CFG_ARM_CM_USE_SYSTICK
*
* For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically.
*
* See trcHardwarePort.h for available ports and information on how to
* define your own port, if not already present.
******************************************************************************/
#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_Win32
/*******************************************************************************
* Configuration Macro: TRC_CFG_RECORDER_MODE
*
* Specify what recording mode to use. Snapshot means that the data is saved in
* an internal RAM buffer, for later upload. Streaming means that the data is
* transferred continuously to the host PC.
*
* For more information, see http://percepio.com/2016/10/05/rtos-tracing/
* and the Tracealyzer User Manual.
*
* Values:
* TRC_RECORDER_MODE_SNAPSHOT
* TRC_RECORDER_MODE_STREAMING
******************************************************************************/
#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT
/******************************************************************************
* TRC_CFG_FREERTOS_VERSION
*
* Specify what version of FreeRTOS that is used (don't change unless using the
* trace recorder library with an older version of FreeRTOS).
*
* TRC_FREERTOS_VERSION_7_3 If using FreeRTOS v7.3.x
* TRC_FREERTOS_VERSION_7_4 If using FreeRTOS v7.4.x
* TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0
* TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X
* TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0
* TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1
* TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2
* TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later
*****************************************************************************/
#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0
/*******************************************************************************
* TRC_CFG_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 (unless filtered in other ways).
*
* Default value is 0 (= include additional events).
******************************************************************************/
#define TRC_CFG_SCHEDULING_ONLY 0
/******************************************************************************
* TRC_CFG_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 (0)
* to exclude malloc/free calls, or one (1) to include such events in the trace.
*
* Default value is 1.
*****************************************************************************/
#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1
/******************************************************************************
* TRC_CFG_INCLUDE_USER_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), all code related to User Events is excluded in order
* to reduce code size. Any attempts of storing User Events are then silently
* ignored.
*
* User Events are application-generated events, like "printf" but for the
* trace log, generated using vTracePrint and vTracePrintF.
* The formatting is done on host-side, by Tracealyzer. User Events are
* therefore much faster than a console printf and can often be used
* in timing critical code without problems.
*
* Note: In streaming mode, User Events are used to provide error messages
* and warnings from the recorder (in case of incorrect configuration) for
* display in Tracealyzer. Disabling user events will also disable these
* warnings. You can however still catch them by calling xTraceGetLastError
* or by putting breakpoints in prvTraceError and prvTraceWarning.
*
* Default value is 1.
*****************************************************************************/
#define TRC_CFG_INCLUDE_USER_EVENTS 1
/*****************************************************************************
* TRC_CFG_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, in order to reduce code size.
*
* Default value is 1.
*
* Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin
* and vTraceStoreISREnd in your interrupt handlers.
*****************************************************************************/
#define TRC_CFG_INCLUDE_ISR_TRACING 1
/*****************************************************************************
* TRC_CFG_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 allows Tracealyzer to show the initial pending time before tasks enter
* the execution state, and present accurate response times.
* If zero (0), "ready events" are not created, which allows for recording
* longer traces in the same amount of RAM.
*
* Default value is 1.
*****************************************************************************/
#define TRC_CFG_INCLUDE_READY_EVENTS 1
/*****************************************************************************
* TRC_CFG_INCLUDE_OSTICK_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is one (1), events will be generated whenever the OS clock is
* increased. If zero (0), OS tick events are not generated, which allows for
* recording longer traces in the same amount of RAM.
*
* Default value is 1.
*****************************************************************************/
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1
/*****************************************************************************
* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any "event group" events.
*
* Default value is 0 (excluded) since dependent on event_groups.c
*****************************************************************************/
#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1
/*****************************************************************************
* TRC_CFG_INCLUDE_TIMER_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any Timer events.
*
* Default value is 0 since dependent on timers.c
*****************************************************************************/
#define TRC_CFG_INCLUDE_TIMER_EVENTS 1
/*****************************************************************************
* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any "pending function call"
* events, such as xTimerPendFunctionCall().
*
* Default value is 0 since dependent on timers.c
*****************************************************************************/
#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1
/*******************************************************************************
* Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the trace will exclude any stream buffer or message
* buffer events.
*
* Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10)
******************************************************************************/
#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 1
/*******************************************************************************
* Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION
*
* Specifies how the recorder buffer is allocated (also in case of streaming, in
* port using the recorder's internal temporary buffer)
*
* Values:
* TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal)
* TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable
* TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer
*
* Static and dynamic mode does the allocation for you, either in compile time
* (static) or in runtime (malloc).
* The custom mode allows you to control how and where the allocation is made,
* for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer().
******************************************************************************/
#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC
/******************************************************************************
* TRC_CFG_MAX_ISR_NESTING
*
* Defines how many levels of interrupt nesting the recorder can handle, in
* case multiple ISRs are traced and ISR nesting is possible. If this
* is exceeded, the particular ISR will not be traced and the recorder then
* logs an error message. This setting is used to allocate an internal stack
* for keeping track of the previous execution context (4 byte per entry).
*
* This value must be a non-zero positive constant, at least 1.
*
* Default value: 8
*****************************************************************************/
#define TRC_CFG_MAX_ISR_NESTING 8
/* Specific configuration, depending on Streaming/Snapshot mode */
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)
#include "trcSnapshotConfig.h"
#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#include "trcStreamingConfig.h"
#endif
#ifdef __cplusplus
}
#endif
#endif /* _TRC_CONFIG_H */

View File

@ -0,0 +1,378 @@
/*******************************************************************************
* Trace Recorder Library for Tracealyzer v3.1.2
* Percepio AB, www.percepio.com
*
* trcSnapshotConfig.h
*
* Configuration parameters for trace recorder library in snapshot mode.
* Read more at http://percepio.com/2016/10/05/rtos-tracing/
*
* Terms of Use
* This file is part of the trace recorder library (RECORDER), which is the
* intellectual property of Percepio AB (PERCEPIO) and provided under a
* license as follows.
* The RECORDER may be used free of charge for the purpose of recording data
* intended for analysis in PERCEPIO products. It may not be used or modified
* for other purposes without explicit permission from PERCEPIO.
* You may distribute the RECORDER in its original source code form, assuming
* this text (terms of use, disclaimer, copyright notice) is unchanged. You are
* allowed to distribute the RECORDER with minor modifications intended for
* configuration or porting of the RECORDER, e.g., to allow using it on a
* specific processor, processor family or with a specific communication
* interface. Any such modifications should be documented directly below
* this comment block.
*
* Disclaimer
* The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty
* as to its use or performance. PERCEPIO does not and cannot warrant the
* performance or results you may obtain by using the RECORDER or documentation.
* PERCEPIO make no warranties, express or implied, as to noninfringement of
* third party rights, merchantability, or fitness for any particular purpose.
* In no event will PERCEPIO, its technology partners, or distributors be liable
* to you for any consequential, incidental or special damages, including any
* lost profits or lost savings, even if a representative of PERCEPIO has been
* advised of the possibility of such damages, or for any claim by any third
* party. Some jurisdictions do not allow the exclusion or limitation of
* incidental, consequential or special damages, or the exclusion of implied
* warranties or limitations on how long an implied warranty may last, so the
* above limitations may not apply to you.
*
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2017.
* www.percepio.com
******************************************************************************/
#ifndef TRC_SNAPSHOT_CONFIG_H
#define TRC_SNAPSHOT_CONFIG_H
#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01)
#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02)
/******************************************************************************
* TRC_CFG_SNAPSHOT_MODE
*
* Macro which should be defined as one of:
* - TRC_SNAPSHOT_MODE_RING_BUFFER
* - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL
* Default is TRC_SNAPSHOT_MODE_RING_BUFFER.
*
* With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_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 TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_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 TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER
/*******************************************************************************
* TRC_CFG_EVENT_BUFFER_SIZE
*
* Macro which should be defined as an integer value.
*
* This defines the capacity of the event buffer, i.e., the number of records
* it may store. Most events use one record (4 byte), although some events
* 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 TRC_CFG_EVENT_BUFFER_SIZE 15000
/*******************************************************************************
* TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE...
*
* 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 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. The
* error message can also be retrieved using xTraceGetLastError.
*
* 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 TRC_CFG_NTASK 150
#define TRC_CFG_NISR 90
#define TRC_CFG_NQUEUE 90
#define TRC_CFG_NSEMAPHORE 90
#define TRC_CFG_NMUTEX 90
#define TRC_CFG_NTIMER 250
#define TRC_CFG_NEVENTGROUP 90
#define TRC_CFG_NSTREAMBUFFER 5
#define TRC_CFG_NMESSAGEBUFFER 5
/******************************************************************************
* TRC_CFG_INCLUDE_FLOAT_SUPPORT
*
* Macro which should be defined as either zero (0) or one (1).
*
* If this is zero (0), the support for logging floating point values in
* vTracePrintF is stripped out, in case floating point values are not used or
* supported by the platform used.
*
* Floating point values are only used in vTracePrintF and its subroutines, to
* allow for storing float (%f) or double (%lf) arguments.
*
* vTracePrintF can be used with integer and string arguments in either case.
*
* Default value is 0.
*****************************************************************************/
#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0
/*******************************************************************************
* TRC_CFG_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 TRC_CFG_SYMBOL_TABLE_SIZE 5000
#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0)
#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!"
#endif
/******************************************************************************
* TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ...
*
* 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 TRC_CFG_NAME_LEN_TASK 15
#define TRC_CFG_NAME_LEN_ISR 15
#define TRC_CFG_NAME_LEN_QUEUE 15
#define TRC_CFG_NAME_LEN_SEMAPHORE 15
#define TRC_CFG_NAME_LEN_MUTEX 15
#define TRC_CFG_NAME_LEN_TIMER 15
#define TRC_CFG_NAME_LEN_EVENTGROUP 15
#define TRC_CFG_NAME_LEN_STREAMBUFFER 15
#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15
/******************************************************************************
*** 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.
*****************************************************************************/
/******************************************************************************
* TRC_CFG_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 TRC_CFG_HEAP_SIZE_BELOW_16M 0
/******************************************************************************
* TRC_CFG_USE_IMPLICIT_IFE_RULES
*
* Macro which should be defined as either zero (0) or one (1).
* Default is 1.
*
* Tracealyzer groups the events into "instances" based on Instance Finish
* Events (IFEs), produced either by default rules or calls to the recorder
* functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext.
*
* If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is
* used, resulting in a "typical" grouping of events into instances.
* If these rules don't give appropriate instances in your case, you can
* override the default rules using vTraceInstanceFinishedNow/Next for one
* or several tasks. The default IFE rules are then disabled for those tasks.
*
* If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are
* disabled globally. You must then call vTraceInstanceFinishedNow or
* vTraceInstanceFinishedNext to manually group the events into instances,
* otherwise the tasks will appear a single long instance.
*
* The default IFE rules count the following events as "instance finished":
* - Task delay, delay until
* - Task suspend
* - Blocking on "input" operations, i.e., when the task is waiting for the
* next a message/signal/event. But only if this event is blocking.
*
* For details, see trcSnapshotKernelPort.h and look for references to the
* macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED.
*****************************************************************************/
#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1
/******************************************************************************
* TRC_CFG_USE_16BIT_OBJECT_HANDLES
*
* 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 (tasks, queues, mutexes,
* etc.) Note: 255, not 256, since handle 0 is reserved.
*
* 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 (8-bit handles)
*
* NOTE: An object with handle above 255 will use an extra 4-byte record in
* the event buffer whenever the object is referenced. Moreover, some internal
* tables in the recorder gets slightly larger when using 16-bit handles.
*****************************************************************************/
#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0
/******************************************************************************
* TRC_CFG_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 (used at various locations in the
* trace recorder) will verify that a relevant condition is true.
* If the condition is false, prvTraceError() will be called, which stops the
* recording and stores an error message that is displayed when opening the
* trace in Tracealyzer.
*
* This is used on several places in the recorder code for sanity checks on
* parameters. Can be switched off to reduce the footprint of the tracing, but
* we recommend to have it enabled initially.
*****************************************************************************/
#define TRC_CFG_USE_TRACE_ASSERT 1
/*******************************************************************************
* TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER
*
* Macro which should be defined as an integer value.
*
* Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the
* separate user event buffer (UB).
* In this mode, user events are stored separately from other events,
* e.g., RTOS events. Thereby you can get a much longer history of
* user events as they don't need to share the buffer space with more
* frequent events.
*
* The UB is typically used with the snapshot ring-buffer mode, so the
* recording can continue when the main buffer gets full. And since the
* main buffer then overwrites the earliest events, Tracealyzer displays
* "Unknown Actor" instead of task scheduling for periods with UB data only.
*
* In UB mode, user events are structured as UB channels, which contains
* a channel name and a default format string. Register a UB channel using
* xTraceRegisterUBChannel.
*
* Events and data arguments are written using vTraceUBEvent and
* vTraceUBData. They are designed to provide efficient logging of
* repeating events, using the same format string within each channel.
*
* Examples:
*
* traceString chn1 = xTraceRegisterString("Channel 1");
* traceString fmt1 = xTraceRegisterString("Event!");
* traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1);
*
* traceString chn2 = xTraceRegisterString("Channel 2");
* traceString fmt2 = xTraceRegisterString("X: %d, Y: %d");
* traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2);
*
* // Result in "[Channel 1] Event!"
* vTraceUBEvent(UBCh1);
*
* // Result in "[Channel 2] X: 23, Y: 19"
* vTraceUBData(UBCh2, 23, 19);
*
* You can also use the other user event functions, like vTracePrintF.
* as they are then rerouted to the UB instead of the main event buffer.
* vTracePrintF then looks up the correct UB channel based on the
* provided channel name and format string, or creates a new UB channel
* if no match is found. The format string should therefore not contain
* "random" messages but mainly format specifiers. Random strings should
* be stored using %s and with the string as an argument.
*
* // Creates a new UB channel ("Channel 2", "%Z: %d")
* vTracePrintF(chn2, "%Z: %d", value1);
*
* // Finds the existing UB channel
* vTracePrintF(chn2, "%Z: %d", value2);
******************************************************************************/
#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0
/*******************************************************************************
* TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE
*
* Macro which should be defined as an integer value.
*
* This defines the capacity of the user event buffer (UB), in number of slots.
* A single user event can use multiple slots, depending on the arguments.
*
* Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
******************************************************************************/
#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200
/*******************************************************************************
* TRC_CFG_UB_CHANNELS
*
* Macro which should be defined as an integer value.
*
* This defines the number of User Event Buffer Channels (UB channels).
* These are used to structure the events when using the separate user
* event buffer, and contains both a User Event Channel (the name) and
* a default format string for the channel.
*
* Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1.
******************************************************************************/
#define TRC_CFG_UB_CHANNELS 32
/*******************************************************************************
* TRC_CFG_ISR_TAILCHAINING_THRESHOLD
*
* Macro which should be defined as an integer value.
*
* If tracing multiple ISRs, this setting allows for accurate display of the
* context-switching also in cases when the ISRs execute in direct sequence.
*
* vTraceStoreISREnd normally assumes that the ISR returns to the previous
* context, i.e., a task or a preempted ISR. But if another traced ISR
* executes in direct sequence, Tracealyzer may incorrectly display a minimal
* fragment of the previous context in between the ISRs.
*
* By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is
* however a threshold value that must be measured for your specific setup.
* See http://percepio.com/2014/03/21/isr_tailchaining_threshold/
*
* The default setting is 0, meaning "disabled" and that you may get an
* extra fragments of the previous context in between tail-chained ISRs.
*
* Note: This setting has separate definitions in trcSnapshotConfig.h and
* trcStreamingConfig.h, since it is affected by the recorder mode.
******************************************************************************/
#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0
#endif /*TRC_SNAPSHOT_CONFIG_H*/