mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-01 20:03:50 -04:00
Import the code coverage test additions from the (unpublished) Visual Studio project to the (published) MingW/Eclipse project.
Update the MingW/Eclipse project to add a code coverage build configuration in addition to the existing Debug build configuration. Update StreamBufferDemo.c so functions are called directly, rather than via configASSERT(), so their code coverage can be measured when configASSERT() is not defined. In the Win32 port, replace the call to TerminateProcess() in vPortEndScheduler() with exit( 0 ) - which triggers the writing of the code coverage data to the disk. Fix bug in ucStreamBufferGetStreamBufferType() - which is only used by the Percepio trace tool. Update the line within vTaskStartScheduler() that was setting xTickCount to 0 to instead set it to configINITIAL_TICK_COUNT.
This commit is contained in:
parent
bf8d9f4726
commit
aec45f2479
14 changed files with 818 additions and 125 deletions
|
@ -42,6 +42,7 @@
|
|||
<option id="gnu.c.compiler.option.debugging.gprof.444112294" name="Generate gprof information (-pg)" superClass="gnu.c.compiler.option.debugging.gprof" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.preprocessor.def.symbols.1757027831" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="_WIN32_WINNT=0x0601"/>
|
||||
<listOptionValue builtIn="false" value="projCOVERAGE_TEST=0"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.974248912" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
|
@ -112,6 +113,7 @@
|
|||
<option id="gnu.c.compiler.option.debugging.gprof.1677007018" name="Generate gprof information (-pg)" superClass="gnu.c.compiler.option.debugging.gprof" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.preprocessor.def.symbols.175065197" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="_WIN32_WINNT=0x0601"/>
|
||||
<listOptionValue builtIn="false" value="projCOVERAGE_TEST=1"/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.debugging.codecov.1668225592" name="Generate gcov information (-ftest-coverage -fprofile-arcs)" superClass="gnu.c.compiler.option.debugging.codecov" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.132282928" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
|
@ -137,7 +139,7 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="FreeRTOS+Trace Recorder/streamports" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry excluding="FreeRTOS+Trace Recorder|FreeRTOS+Trace Recorder/streamports" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#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 ) ( 45 * 1024 ) )
|
||||
#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
|
||||
|
@ -56,7 +56,6 @@
|
|||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 20
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_APPLICATION_TASK_TAG 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
|
@ -64,7 +63,10 @@
|
|||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
|
||||
/* Software timer related configuration options. */
|
||||
/* 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
|
||||
|
@ -80,14 +82,18 @@ void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initi
|
|||
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
|
||||
|
||||
/* Co-routine related configuration options. */
|
||||
#define configUSE_CO_ROUTINES 1
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* This demo makes use of one or more example stats formatting functions. These
|
||||
/* 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 1
|
||||
#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
|
||||
|
@ -116,11 +122,24 @@ functions anyway. */
|
|||
#endif /* configINCLUDE_MESSAGE_BUFFER_AMP_DEMO */
|
||||
|
||||
extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName );
|
||||
#define configCOVERAGE_TEST 1
|
||||
#if( configCOVERAGE_TEST == 1 )
|
||||
|
||||
/* 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
|
||||
#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
|
||||
|
@ -128,9 +147,12 @@ extern void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
|
|||
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
|
||||
|
||||
/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. */
|
||||
#include "trcRecorder.h"
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
|
594
FreeRTOS/Demo/WIN32-MingW/code_coverage_additions.c
Normal file
594
FreeRTOS/Demo/WIN32-MingW/code_coverage_additions.c
Normal file
|
@ -0,0 +1,594 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 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 "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 )
|
||||
{
|
||||
uint32_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 |= ( uint32_t ) xEventGroupCreateStatic( NULL );
|
||||
|
||||
/* Try creating a task twice, once with puxStackBuffer NULL, and once with
|
||||
pxTaskBuffer NULL. */
|
||||
ulReturned |= ( uint32_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 |= ( uint32_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 |= ( uint32_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 |= ( uint32_t ) xStreamBufferCreateStatic( uxDummy,
|
||||
uxDummy,
|
||||
NULL,
|
||||
( StaticStreamBuffer_t * ) &xReturn ); /* Dummy value just to pass a non NULL value in - won't get used. */
|
||||
|
||||
ulReturned |= ( uint32_t ) xStreamBufferCreateStatic( uxDummy,
|
||||
uxDummy,
|
||||
( uint8_t * ) &xReturn, /* Dummy value just to pass a non NULL value in - won't get used. */
|
||||
NULL );
|
||||
|
||||
/* Try to create a task with a stack that is too large to be allocated. */
|
||||
if( xTaskCreate( NULL, "TooLarge", configTOTAL_HEAP_SIZE, NULL, tskIDLE_PRIORITY, NULL ) != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY )
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now try with a NULL handle, so using this task. */
|
||||
vTaskSetApplicationTaskTag( NULL, NULL );
|
||||
if( xTaskGetApplicationTaskTag( 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -75,7 +75,7 @@ that make up the total heap. heap_5 is only used for test and example purposes
|
|||
as this demo could easily create one large heap region instead of multiple
|
||||
smaller heap regions - in which case heap_4.c would be the more appropriate
|
||||
choice. See http://www.freertos.org/a00111.html for an explanation. */
|
||||
#define mainREGION_1_SIZE 8201
|
||||
#define mainREGION_1_SIZE 10801
|
||||
#define mainREGION_2_SIZE 29905
|
||||
#define mainREGION_3_SIZE 6007
|
||||
|
||||
|
@ -141,10 +141,6 @@ int main( void )
|
|||
http://www.freertos.org/a00111.html for an explanation. */
|
||||
prvInitialiseHeap();
|
||||
|
||||
/* Initialise the trace recorder. Use of the trace recorder is optional.
|
||||
See http://www.FreeRTOS.org/trace for more information. */
|
||||
vTraceEnable( TRC_START );
|
||||
|
||||
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
|
||||
of this file. */
|
||||
#if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
|
||||
|
@ -153,11 +149,20 @@ int main( void )
|
|||
}
|
||||
#else
|
||||
{
|
||||
/* 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();
|
||||
/* 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
|
||||
|
||||
main_full();
|
||||
}
|
||||
|
@ -282,7 +287,6 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
|
|||
xPrinted = pdTRUE;
|
||||
if( xTraceRunning == pdTRUE )
|
||||
{
|
||||
vTraceStop();
|
||||
prvSaveTraceFile();
|
||||
}
|
||||
}
|
||||
|
@ -302,20 +306,27 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
|
|||
|
||||
static void prvSaveTraceFile( void )
|
||||
{
|
||||
FILE* pxOutputFile;
|
||||
|
||||
pxOutputFile = fopen( "Trace.dump", "wb");
|
||||
|
||||
if( pxOutputFile != NULL )
|
||||
/* Tracing is not used when code coverage analysis is being performed. */
|
||||
#if( projCOVERAGE_TEST != 1 )
|
||||
{
|
||||
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" );
|
||||
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
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -120,6 +120,12 @@
|
|||
|
||||
#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 );
|
||||
|
||||
|
@ -420,7 +426,6 @@ void *pvAllocated;
|
|||
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
|
||||
|
@ -448,13 +453,19 @@ void *pvAllocated;
|
|||
|
||||
/* Exit after a fixed time so code coverage results are written to the
|
||||
disk. */
|
||||
#if( configCOVERAGE_TEST == 1 )
|
||||
#if( projCOVERAGE_TEST == 1 )
|
||||
{
|
||||
const TickType_t xMaxRunTime = pdMS_TO_TICKS( 60000UL );
|
||||
const TickType_t xMaxRunTime = pdMS_TO_TICKS( 30000UL );
|
||||
|
||||
if( xTaskGetTickCount() >= xMaxRunTime )
|
||||
/* Exercise code not otherwise executed by standard demo/test tasks. */
|
||||
if( xRunCodeCoverageTestAdditions() != pdPASS )
|
||||
{
|
||||
exit( 0 );
|
||||
pcStatusMessage = "Code coverage additions failed.\r\n";
|
||||
}
|
||||
|
||||
if( ( xTaskGetTickCount() - configINITIAL_TICK_COUNT ) >= xMaxRunTime )
|
||||
{
|
||||
vTaskEndScheduler();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue