Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions FreeRTOS/Test/CMock/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ export CC ?= /usr/local/bin/gcc
export LD ?= /usr/local/bin/ld

# Add units here when adding a new unit test directory with the same name
UNITS := timers
Comment thread
rohitmadan07 marked this conversation as resolved.
UNITS := smp
UNITS += timers
UNITS += tasks
UNITS += list
UNITS += queue
UNITS += stream_buffer
UNITS += message_buffer
UNITS += event_groups
UNITS += smp

.PHONY: makefile.in

Expand Down
98 changes: 70 additions & 28 deletions FreeRTOS/Test/CMock/coverage.mk
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
COVINFO := $(abspath $(SCRATCH_DIR)/..)/$(EXEC_PREFIX).info
COVINFO_INITIAL := $(SCRATCH_DIR)/$(EXEC_PREFIX)_initial.info
LCOV_LIST := $(addsuffix .info,$(addprefix $(SCRATCH_DIR)/,$(SUITE_UT_SRC:.c=)))
PROJ_GCDA_LIST := $(PROJ_SRC_LIST:.c=.gcda)
COV_REPORT_DIR := $(SCRATCH_DIR)/coverage
COVINFO_COMBINE := $(SCRATCH_DIR)/$(EXEC_PREFIX)_combined.info


GCOV_OPTS := --unconditional-branches --branch-probabilities
# Determine if we're in a nested test structure by checking for DISCRIMINATOR
ifdef DISCRIMINATOR
# Nested test structure (e.g., smp/granular_lock)
LCOV_LIST := $(addsuffix .info,$(addprefix $(SCRATCH_DIR)/$(EXEC_PREFIX)_,$(DISCRIMINATOR)))
INFO_PATTERN := $(SCRATCH_DIR)/$(EXEC_PREFIX)_%.info
TEST_PATTERN := $(BIN_DIR)/smp_$(PROJECT)_%_utest
else
# Flat test structure
LCOV_LIST := $(addsuffix .info,$(addprefix $(SCRATCH_DIR)/,$(SUITE_UT_SRC:.c=)))
INFO_PATTERN := $(SCRATCH_DIR)/%_utest.info
TEST_PATTERN := $(BIN_DIR)/$(EXEC_PREFIX)_%_utest
endif

# Debug information for coverage
$(info === Coverage Configuration ===)
$(info DISCRIMINATOR: $(DISCRIMINATOR))
$(info LCOV_LIST: $(LCOV_LIST))
$(info INFO_PATTERN: $(INFO_PATTERN))
$(info TEST_PATTERN: $(TEST_PATTERN))

# Common variables
COVINFO := $(abspath $(SCRATCH_DIR)/..)/$(EXEC_PREFIX).info
COVINFO_INITIAL := $(SCRATCH_DIR)/$(EXEC_PREFIX)_initial.info
PROJ_GCDA_LIST := $(PROJ_SRC_LIST:.c=.gcda)
COV_REPORT_DIR := $(SCRATCH_DIR)/coverage
COVINFO_COMBINE := $(SCRATCH_DIR)/$(EXEC_PREFIX)_combined.info

GCOV_OPTS := --unconditional-branches --branch-probabilities

# Cases that run test binaries cannot be run in parallel.
.NOTPARALLEL : $(COVINFO) $(LCOV_LIST) $(PROJ_GCDA_LIST)
Expand All @@ -18,15 +37,14 @@ NO_DELETE : $(MOCK_HDR_LIST) $(MOCK_SRC_LIST) $(MOCK_OBJ_LIST) \
$(SUITE_OBJ_LIST) $(RUNNER_SRC_LIST) $(RUNNER_OBJ_LIST) \
$(COVINFO) $(LCOV_LIST)


# Generate gcov files by default
run : gcov

gcov : $(PROJ_GCDA_LIST)

clean :
rm -rf $(SCRATCH_DIR)
rm -f $(BIN_DIR)/$(PROJECT)_utest_*
rm -f $(BIN_DIR)/*$(PROJECT)*
rm -f $(COVINFO)

libs :
Expand All @@ -37,6 +55,8 @@ $(1)
endef

$(PROJ_GCDA_LIST) : $(EXEC_LIST)
@echo "=== Generating GCDA files ==="
@echo "Executables: $(EXEC_LIST)"
rm -f $(PROJ_DIR)/*.gcda
mkdir -p $(BIN_DIR)
# run each test case
Expand All @@ -46,43 +66,46 @@ $(PROJ_GCDA_LIST) : $(EXEC_LIST)
lcov : $(COVINFO)

lcovhtml : $(COVINFO)
@echo "=== Generating HTML coverage report ==="
@echo "Output directory: $(COV_REPORT_DIR)"
mkdir -p $(COV_REPORT_DIR)
genhtml $(COVINFO) $(LCOV_OPTS) --output-directory $(COV_REPORT_DIR)

bin: $(EXEC_LIST)

# Run and append to gcov data files

# Generate callgraph for coverage filtering
$(PROJ_DIR)/callgraph.json : $(PROJ_SRC_LIST)
@echo "=== Generating callgraph ==="
mkdir -p $(PROJ_DIR)
#python3 $(UT_ROOT_DIR)/tools/callgraph.py --out $@ $^

# Generate baseline inital coverage data from .gcno file
# Generate baseline initial coverage data from .gcno file
$(COVINFO_INITIAL) : $(EXEC_LIST)
@echo "=== Generating initial coverage data ==="
@echo "Output file: $@"
lcov $(LCOV_OPTS) --capture --initial --directory $(SCRATCH_DIR) -o $@

# Run the test runner and genrate a filtered gcov.json.gz file
$(SCRATCH_DIR)/%_utest.info : $(BIN_DIR)/$(EXEC_PREFIX)_%_utest \
$(PROJ_DIR)/callgraph.json
# Add debug information before pattern rules
$(info === Coverage Pattern Debug ===)
$(info Looking for info files: $(LCOV_LIST))
$(info Info pattern: $(INFO_PATTERN))
$(info Test pattern: $(TEST_PATTERN))
$(info Executables: $(EXEC_LIST))

# Run the test runner and generate coverage info file
$(INFO_PATTERN) : $(TEST_PATTERN) $(PROJ_DIR)/callgraph.json
@echo "=== Generating coverage info for $@ ==="
@echo "Using test executable: $<"
# Remove any existing coverage data
rm -f $(PROJ_DIR)/*.gcda

# run the testrunner
$<

@echo "Capturing coverage data..."
lcov $(LCOV_OPTS) --directory $(SCRATCH_DIR) --capture -o $@
# Gather coverage into a json.gz file

#gcov $(GCOV_OPTS) $(SCRATCH_DIR)/$*/$(PROJECT).gcda \
# --json-format --stdout | gzip > $(subst .info,.json.gz,$@)

# Filter coverage based on tags in unit test file
# $(TOOLS_DIR)/filtercov.py --in $(subst .info,.json.gz,$@) \
# --map $(PROJ_DIR)/callgraph.json \
# --test $(PROJ_DIR)/$(PROJECT)_utest_$*.c \
# --format lcov \
# --out $@

@echo "Coverage summary:"
lcov $(LCOV_OPTS) --summary $@

# Remove temporary files
Expand All @@ -91,9 +114,28 @@ $(SCRATCH_DIR)/%_utest.info : $(BIN_DIR)/$(EXEC_PREFIX)_%_utest \

# Combine lcov from each test bin into one lcov info file for the suite
$(COVINFO_COMBINE) : $(LCOV_LIST)
@echo "=== Combining coverage data ==="
@echo "Input files: $(LCOV_LIST)"
@echo "Output file: $@"
lcov $(LCOV_OPTS) -o $@ $(foreach cov,$(LCOV_LIST),--add-tracefile $(cov) )

# Add baseline / initial coverage generated by gcc to point out untagged functions
$(COVINFO) : $(COVINFO_COMBINE) $(COVINFO_INITIAL)
@echo "=== Generating final coverage report ==="
@echo "Initial coverage: $(COVINFO_INITIAL)"
@echo "Combined coverage: $(COVINFO_COMBINE)"
@echo "Output file: $@"
lcov $(LCOV_OPTS) -o $@ --add-tracefile $(COVINFO_INITIAL) --add-tracefile $(COVINFO_COMBINE)
Comment thread
rohitmadan07 marked this conversation as resolved.

# Debug target for coverage configuration
coverage-debug:
@echo "=== Coverage Debug Information ==="
@echo "DISCRIMINATOR: $(DISCRIMINATOR)"
@echo "LCOV_LIST: $(LCOV_LIST)"
@echo "INFO_PATTERN: $(INFO_PATTERN)"
@echo "TEST_PATTERN: $(TEST_PATTERN)"
@echo "COVINFO: $(COVINFO)"
@echo "COVINFO_INITIAL: $(COVINFO_INITIAL)"
@echo "COVINFO_COMBINE: $(COVINFO_COMBINE)"
@echo "EXEC_LIST: $(EXEC_LIST)"
@echo "PROJ_GCDA_LIST: $(PROJ_GCDA_LIST)"
1 change: 1 addition & 0 deletions FreeRTOS/Test/CMock/smp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SUITES += single_priority_no_timeslice
SUITES += single_priority_timeslice
SUITES += multiple_priorities_no_timeslice
SUITES += multiple_priorities_timeslice
SUITES += granular_lock

# SUITS mock dependency source for coverage test
SUITES += multiple_priorities_no_timeslice_mock
Expand Down
175 changes: 175 additions & 0 deletions FreeRTOS/Test/CMock/smp/granular_lock/FreeRTOSConfig_1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* FreeRTOS V202212.00
* 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.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/


#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "fake_assert.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
* https://www.FreeRTOS.org/a00110.html
*----------------------------------------------------------*/

/* SMP test specific configuration */
#define configRUN_MULTIPLE_PRIORITIES 1
#define configNUMBER_OF_CORES 16
#define configUSE_CORE_AFFINITY 0
#define configUSE_TIME_SLICING 0
#define configUSE_TASK_PREEMPTION_DISABLE 1
#define configTICK_CORE 0

/* OS Configuration */
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
#define configTICK_RATE_HZ ( 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 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_MALLOC_FAILED_HOOK 1
#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 configTASK_NOTIFICATION_ARRAY_ENTRIES 5
#define configSUPPORT_STATIC_ALLOCATION 0
#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 )
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1
#define portREMOVE_STATIC_QUALIFIER 1
#define portCRITICAL_NESTING_IN_TCB 0
#define portSTACK_GROWTH ( 1 )
#define configUSE_PASSIVE_IDLE_HOOK 0
#define configUSE_TICKLESS_IDLE 1
#define configSTACK_DEPTH_TYPE uint32_t

/* Software timer related configuration options. */
#define configUSE_TIMERS 0
#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 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
#define portUSING_MPU_WRAPPERS 0
#define portHAS_STACK_OVERFLOW_CHECKING 0
#define configENABLE_MPU 0

/* Co-routine related configuration options. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* This demo makes 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

/* 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_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1

/* It is a good idea to define configASSERT() while developing. configASSERT()
* uses the same semantics as the standard C assert() macro. */
#define configASSERT( x ) \
do \
{ \
if( x ) \
{ \
vFakeAssert( true, __FILE__, __LINE__ ); \
} \
else \
{ \
vFakeAssert( false, __FILE__, __LINE__ ); \
} \
} while( 0 )

#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 */

/* =========================== INSTRUMENT THROUGH TRACE MACRO =========================== */
int xTraceBlockingOnQueueReceive( void * pxQueue );
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) do{ if( xTraceBlockingOnQueueReceive( pxQueue ) != 0 ) { return errQUEUE_EMPTY; } } while( 0 )

int xTraceUnblockingOnQueueReceive( void * pxQueue );
#define traceUNBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) do{ if( xTraceUnblockingOnQueueReceive( pxQueue ) != 0 ) { return errQUEUE_EMPTY; } } while( 0 )

int xTraceBlockingOnQueueSend( void * pxQueue );
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) do{ if( xTraceBlockingOnQueueSend( pxQueue ) != 0 ) { return errQUEUE_FULL; } } while( 0 )

int xTraceUnblockingOnQueueSend( void * pxQueue );
#define traceUNBLOCKING_ON_QUEUE_SEND( pxQueue ) do{ if( xTraceUnblockingOnQueueSend( pxQueue ) != 0 ) { return errQUEUE_FULL; } } while( 0 )

int xTraceEventGroupTaskBlocked( void * pxEventGroup );
#define traceEVENT_GROUP_BLOCK_ON_BITS_WAITING( pxEventGroup, uxBitsToWaitFor ) do{ if( xTraceEventGroupTaskBlocked( pxEventGroup ) != 0 ) { return 0; } } while( 0 )

int xTraceEventGroupTaskUnblocked( void * pxEventGroup );
#define traceEVENT_GROUP_UNBLOCK_ON_BITS_WAITING( pxEventGroup, uxBitsToWaitFor, xMatchFound ) do{ if( xTraceEventGroupTaskUnblocked( pxEventGroup ) != 0 ) { return 0; } } while( 0 )

#endif /* FREERTOS_CONFIG_H */
Loading
Loading