diff --git a/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.cdt.codan.core.prefs b/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.cdt.codan.core.prefs deleted file mode 100644 index 3d999f3568..0000000000 --- a/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.cdt.codan.core.prefs +++ /dev/null @@ -1,72 +0,0 @@ -eclipse.preferences.version=1 -inEditor=false -org.eclipse.cdt.codan.checkers.errnoreturn=-Warning -org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} -org.eclipse.cdt.codan.checkers.errreturnvalue=-Error -org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.nocommentinside=-Error -org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.nolinecomment=-Error -org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.noreturn=-Error -org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=-Error -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false} -org.eclipse.cdt.codan.internal.checkers.CatchByReference=-Warning -org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=-Warning -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true} -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error -org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error -org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false} -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false} -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")} -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} diff --git a/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.cdt.managedbuilder.core.prefs deleted file mode 100644 index 3bed239d5f..0000000000 --- a/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.cdt.managedbuilder.core.prefs +++ /dev/null @@ -1,31 +0,0 @@ -eclipse.preferences.version=1 -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/CPATH/delimiter=; -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/CPATH/operation=remove -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/C_INCLUDE_PATH/delimiter=; -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/C_INCLUDE_PATH/operation=remove -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/append=true -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/appendContributed=true -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/CPATH/delimiter=; -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/CPATH/operation=remove -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/C_INCLUDE_PATH/delimiter=; -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/C_INCLUDE_PATH/operation=remove -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/append=true -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/appendContributed=true -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/CPATH/delimiter=; -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/CPATH/operation=remove -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/C_INCLUDE_PATH/delimiter=; -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/C_INCLUDE_PATH/operation=remove -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/append=true -environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/appendContributed=true -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/LIBRARY_PATH/delimiter=; -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/LIBRARY_PATH/operation=remove -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/append=true -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.1332190083/appendContributed=true -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/LIBRARY_PATH/delimiter=; -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/LIBRARY_PATH/operation=remove -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/append=true -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239.539393069/appendContributed=true -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/LIBRARY_PATH/delimiter=; -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/LIBRARY_PATH/operation=remove -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/append=true -environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.mingw.exe.debug.396692239/appendContributed=true diff --git a/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.ltk.core.refactoring.prefs b/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.ltk.core.refactoring.prefs deleted file mode 100644 index cfcd1d3c22..0000000000 --- a/FreeRTOS/Demo/WIN32-MingW/.settings/org.eclipse.ltk.core.refactoring.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h b/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h index b94a693464..367e0e8a2d 100644 --- a/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h @@ -23,6 +23,7 @@ * https://github.com/FreeRTOS * */ + #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H @@ -44,7 +45,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 ) ( 65 * 1024 ) ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 100 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 12 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 diff --git a/FreeRTOS/Demo/WIN32-MingW/Makefile b/FreeRTOS/Demo/WIN32-MingW/Makefile new file mode 100644 index 0000000000..45cbe0db5e --- /dev/null +++ b/FreeRTOS/Demo/WIN32-MingW/Makefile @@ -0,0 +1,148 @@ +# Build directory +BUILD_DIR := ./build + +# Compiler - Note this expects you are using MinGW version of GCC +CC := gcc +CFLAGS := -O0 -g3 -Wall -Wextra -c -fmessage-length=0 -Wcast-qual -D_WIN32_WINNT=0x0601 + +ifeq ($(COVERAGE_TEST),1) + CFLAGS += -DprojCOVERAGE_TEST=1 +else + CFLAGS += -DprojCOVERAGE_TEST=0 +endif + +# Linker - Note this expects you are using MinGW version of GCC +LD := gcc +LDFLAGS := -Xlinker -Map=$(BUILD_DIR)/rtosdemo.map + +# Executable Targets +EXE := $(BUILD_DIR)/RTOSDemo.exe + +# FreeRTOS Kernel +FREERTOS_KERNEL_DIR := $(abspath ../../Source) +FREERTOS_KERNEL_INCLUDES := +FREERTOS_KERNEL_SOURCES := +FREERTOS_KERNEL_INCLUDE_DIRS := +FREERTOS_KERNEL_OBJS := +FREERTOS_KERNEL_BUILD_DIR := $(BUILD_DIR)/FreeRTOS-Kernel + +## FreeRTOS Kernel includes +FREERTOS_KERNEL_INCLUDES += $(wildcard $(FREERTOS_KERNEL_DIR)/include/*.h) +FREERTOS_KERNEL_INCLUDE_DIRS += -I $(FREERTOS_KERNEL_DIR)/include + +## FreeRTOS Kernel sources +FREERTOS_KERNEL_SOURCES += $(wildcard $(FREERTOS_KERNEL_DIR)/*.c) +FREERTOS_KERNEL_SOURCES += $(FREERTOS_KERNEL_DIR)/portable/MemMang/heap_5.c + +## FreeRTOS Kernel Windows port includes +FREERTOS_KERNEL_INCLUDES += $(FREERTOS_KERNEL_DIR)/portable/MSVC-MingW/portmacro.h +FREERTOS_KERNEL_INCLUDE_DIRS += -I $(FREERTOS_KERNEL_DIR)/portable/MSVC-MingW + +## FreeRTOS Kernel Windows port sources +FREERTOS_KERNEL_SOURCES += $(FREERTOS_KERNEL_DIR)/portable/MSVC-MingW/port.c + +## FreeRTOS Kernel configuration includes +FREERTOS_KERNEL_INCLUDES += ./FreeRTOSConfig.h +FREERTOS_KERNEL_INCLUDE_DIRS += -I . + +# FreeRTOS Kernel objects +FREERTOS_KERNEL_SOURCES_NAMES :=$(notdir $(FREERTOS_KERNEL_SOURCES)) +FREERTOS_KERNEL_OBJS := $(FREERTOS_KERNEL_SOURCES_NAMES:%.c=$(FREERTOS_KERNEL_BUILD_DIR)/%.o) + +# Trace Recorder +FREERTOS_PLUS_TRACE_DIR := $(abspath ../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace) +FREERTOS_PLUS_TRACE_INCLUDES := +FREERTOS_PLUS_TRACE_SOURCES := +FREERTOS_PLUS_TRACE_INCLUDE_DIRS := +FREERTOS_PLUS_TRACE_OBJS := +FREERTOS_PLUS_TRACE_BUILD_DIR := $(BUILD_DIR)/FreeRTOS-Plus-Trace + +## Trace Recorder includes +FREERTOS_PLUS_TRACE_INCLUDES += $(wildcard $(FREERTOS_PLUS_TRACE_DIR)/Include/*.h) +FREERTOS_PLUS_TRACE_INCLUDE_DIRS += -I $(FREERTOS_PLUS_TRACE_DIR)/Include + +## Trace Recorder sources +FREERTOS_PLUS_TRACE_SOURCES += $(wildcard $(FREERTOS_PLUS_TRACE_DIR)/*.c) + +## Trace Recorder configuration includes +FREERTOS_PLUS_TRACE_INCLUDES += $(wildcard ./Trace_Recorder_Configuration/*.h) +FREERTOS_PLUS_TRACE_INCLUDE_DIRS += -I ./Trace_Recorder_Configuration + +# Trace Recoder objects +FREERTOS_PLUS_TRACE_SOURCES_NAMES :=$(notdir $(FREERTOS_PLUS_TRACE_SOURCES)) +FREERTOS_PLUS_TRACE_OBJS := $(FREERTOS_PLUS_TRACE_SOURCES_NAMES:%.c=$(FREERTOS_PLUS_TRACE_BUILD_DIR)/%.o) + +# Demos +FREERTOS_DEMOS_DIR := $(abspath ../Common/Minimal) +FREERTOS_DEMOS_INCLUDES := +FREERTOS_DEMOS_SOURCES := +FREERTOS_DEMOS_INCLUDE_DIRS := +FREERTOS_DEMOS_OBJS := +FREERTOS_DEMOS_BUILD_DIR := $(BUILD_DIR)/FreeRTOS-Demos + +## Demos includes +FREERTOS_DEMOS_INCLUDES := $(wildcard $(FREERTOS_DEMOS_DIR)/../include/*.h) +FREERTOS_DEMOS_INCLUDE_DIRS := -I $(FREERTOS_DEMOS_DIR)/../include + +## Demos sources +FREERTOS_DEMOS_SOURCES += $(wildcard $(FREERTOS_DEMOS_DIR)/*.c) + +### Filter out unsupported demos +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/comtest_strings.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/comtest.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/flash_timer.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/flash.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/IntQueue.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/recmutex.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES += ./DemosModifiedForLowTickRate/recmutex.c +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/sp_flop.c, $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_SOURCES := $(filter-out $(FREERTOS_DEMOS_DIR)/TaskNotifyArray.c, $(FREERTOS_DEMOS_SOURCES)) + +## Demos objects +FREERTOS_DEMOS_SOURCES_NAMES :=$(notdir $(FREERTOS_DEMOS_SOURCES)) +FREERTOS_DEMOS_OBJS := $(FREERTOS_DEMOS_SOURCES_NAMES:%.c=$(FREERTOS_DEMOS_BUILD_DIR)/%.o) + +# Main +MAIN_DIR := . +MAIN_INCLUDES := +MAIN_SOURCES := +MAIN_INCLUDE_DIRS := +MAIN_BUILD_DIR := $(BUILD_DIR)/main + +## Main includes + +## Main sources +MAIN_SOURCES += $(wildcard $(MAIN_DIR)/*.c) + +## Main objects +MAIN_SOURCES_NAMES :=$(notdir $(MAIN_SOURCES)) +MAIN_OBJS := $(MAIN_SOURCES_NAMES:%.c=$(MAIN_BUILD_DIR)/%.o) + +$(EXE) : $(MAIN_OBJS) $(FREERTOS_KERNEL_OBJS) $(FREERTOS_DEMOS_OBJS) $(FREERTOS_PLUS_TRACE_OBJS) + $(LD) $(LDFLAGS) -o $@ $^ -lwinmm + +# Main objects rules +$(MAIN_OBJS): %.o: $(MAIN_SOURCES) $(MAIN_INCLUDES) $(FREERTOS_KERNEL_INCLUDES) $(FREERTOS_PLUS_TRACE_INCLUDES) $(FREERTOS_DEMOS_INCLUDES) + mkdir -p $(@D) + $(CC) $(CFLAGS) $(FREERTOS_KERNEL_INCLUDE_DIRS) $(FREERTOS_PLUS_TRACE_INCLUDE_DIRS) $(FREERTOS_DEMOS_INCLUDE_DIRS) -o $@ $(filter %$(notdir $(patsubst %.o, %.c, $@)), $^) + +# FreeRTOS Kernel objects rules +$(FREERTOS_KERNEL_OBJS): %.o: $(FREERTOS_KERNEL_SOURCES) $(FREERTOS_KERNEL_INCLUDES) $(FREERTOS_PLUS_TRACE_INCLUDES) + mkdir -p $(@D) + $(CC) $(CFLAGS) $(FREERTOS_KERNEL_INCLUDE_DIRS) $(FREERTOS_PLUS_TRACE_INCLUDE_DIRS) -o $@ $(filter %$(notdir $(patsubst %.o, %.c, $@)), $^) + +# FreeRTOS Demos objects rules +$(FREERTOS_DEMOS_OBJS): %.o: $(FREERTOS_DEMOS_SOURCES) $(FREERTOS_DEMOS_INCLUDES) $(FREERTOS_KERNEL_INCLUDES) $(FREERTOS_PLUS_TRACE_INCLUDES) + mkdir -p $(@D) + $(CC) $(CFLAGS) $(FREERTOS_DEMOS_INCLUDE_DIRS) $(FREERTOS_KERNEL_INCLUDE_DIRS) $(FREERTOS_PLUS_TRACE_INCLUDE_DIRS) -o $@ $(filter %$(notdir $(patsubst %.o, %.c, $@)), $^) + +# Trace Recorder object filess +$(FREERTOS_PLUS_TRACE_OBJS): %.o: $(FREERTOS_PLUS_TRACE_SOURCES) $(FREERTOS_PLUS_TRACE_INCLUDES) $(FREERTOS_KERNEL_INCLUDES) + mkdir -p $(@D) + $(CC) $(CFLAGS) $(FREERTOS_PLUS_TRACE_INCLUDE_DIRS) $(FREERTOS_KERNEL_INCLUDE_DIRS) -o $@ $(filter %$(notdir $(patsubst %.o, %.c, $@)), $^) + +# Clean rule +clean: + rm -rf $(BUILD_DIR) + + diff --git a/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcConfig.h b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcConfig.h index 5acd22bc86..34f5adc4cb 100644 --- a/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcConfig.h +++ b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcConfig.h @@ -1,49 +1,13 @@ -/******************************************************************************* - * Trace Recorder Library for Tracealyzer v3.1.2 - * Percepio AB, www.percepio.com +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com * - * trcConfig.h + * SPDX-License-Identifier: Apache-2.0 * * 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 @@ -59,12 +23,10 @@ extern "C" { * 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"). +/** + * @def TRC_CFG_HARDWARE_PORT + * @brief 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 @@ -78,118 +40,79 @@ extern "C" { * * 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_X If using FreeRTOS v7.3.X - * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X - * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X - * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X - * TRC_FREERTOS_VERSION_8_X_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 - * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1 - * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0 - * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1 - * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0 - * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1 - * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0 - * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1 - * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 or later - *****************************************************************************/ -#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_0 + */ +#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_Win32 -/******************************************************************************* - * TRC_CFG_SCHEDULING_ONLY - * - * Macro which should be defined as an integer value. +/** + * @def TRC_CFG_SCHEDULING_ONLY + * @brief 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 + */ +#define TRC_CFG_SCHEDULING_ONLY 0 - /****************************************************************************** - * TRC_CFG_INCLUDE_MEMMANG_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). +/** + * @def TRC_CFG_INCLUDE_MEMMANG_EVENTS + * @brief 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 + */ +#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 - /****************************************************************************** - * TRC_CFG_INCLUDE_USER_EVENTS +/** + * @def TRC_CFG_INCLUDE_USER_EVENTS + * @brief Macro which should be defined as either zero (0) or one (1). * - * 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 + * 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 + * 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. + * warnings. You can however still catch them by calling xTraceErrorGetLast + * or by putting breakpoints in xTraceError and xTraceWarning. * * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_USER_EVENTS 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). +/** + * @def TRC_CFG_INCLUDE_ISR_TRACING + * @brief 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. + * excluded, in order to reduce code size. This means that any calls to + * vTraceStoreISRBegin/vTraceStoreISREnd will be ignored. + * This does not completely disable ISR tracing, in cases where an ISR is + * calling a traced kernel service. These events will still be recorded and + * show up in anonymous ISR instances in Tracealyzer, with names such as + * "ISR sending to ". + * To disable such tracing, please refer to vTraceSetFilterGroup and + * vTraceSetFilterMask. * * 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 + */ +#define TRC_CFG_INCLUDE_ISR_TRACING 1 - /***************************************************************************** - * TRC_CFG_INCLUDE_READY_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). +/** + * @def TRC_CFG_INCLUDE_READY_EVENTS + * @brief 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 @@ -198,72 +121,102 @@ extern "C" { * longer traces in the same amount of RAM. * * Default value is 1. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_READY_EVENTS 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). +/** + * @def TRC_CFG_INCLUDE_OSTICK_EVENTS + * @brief 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 + */ +#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 +/** + * @def TRC_CFG_ENABLE_STACK_MONITOR + * @brief If enabled (1), the recorder periodically reports the unused stack space of + * all active tasks. + * The stack monitoring runs in the Tracealyzer Control task, TzCtrl. This task + * is always created by the recorder when in streaming mode. + * In snapshot mode, the TzCtrl task is only used for stack monitoring and is + * not created unless this is enabled. + */ +#define TRC_CFG_ENABLE_STACK_MONITOR 1 - /***************************************************************************** - * TRC_CFG_INCLUDE_TIMER_EVENTS - * - * Macro which should be defined as either zero (0) or one (1). +/** + * @def TRC_CFG_STACK_MONITOR_MAX_TASKS + * @brief Macro which should be defined as a non-zero integer value. * - * If this is zero (0), the trace will exclude any Timer events. + * This controls how many tasks that can be monitored by the stack monitor. + * If this is too small, some tasks will be excluded and a warning is shown. * - * Default value is 0 since dependent on timers.c - *****************************************************************************/ -#define TRC_CFG_INCLUDE_TIMER_EVENTS 1 + * Default value is 10. + */ +#define TRC_CFG_STACK_MONITOR_MAX_TASKS 50 - /***************************************************************************** - * TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS +/** + * @def TRC_CFG_STACK_MONITOR_MAX_REPORTS + * @brief Macro which should be defined as a non-zero integer value. + * + * This defines how many tasks that will be subject to stack usage analysis for + * each execution of the Tracealyzer Control task (TzCtrl). Note that the stack + * monitoring cycles between the tasks, so this does not affect WHICH tasks that + * are monitored, but HOW OFTEN each task stack is analyzed. + * + * This setting can be combined with TRC_CFG_CTRL_TASK_DELAY to tune the + * frequency of the stack monitoring. This is motivated since the stack analysis + * can take some time to execute. + * However, note that the stack analysis runs in a separate task (TzCtrl) that + * can be executed on low priority. This way, you can avoid that the stack + * analysis disturbs any time-sensitive tasks. * - * 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 + * Default value is 1. + */ +#define TRC_CFG_STACK_MONITOR_MAX_REPORTS 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 +/** + * @def TRC_CFG_CTRL_TASK_PRIORITY + * @brief The scheduling priority of the Tracealyzer Control (TzCtrl) task. + * + * In streaming mode, TzCtrl is used to receive start/stop commands from + * Tracealyzer and in some cases also to transmit the trace data (for stream + * ports that uses the internal buffer, like TCP/IP). For such stream ports, + * make sure the TzCtrl priority is high enough to ensure reliable periodic + * execution and transfer of the data, but low enough to avoid disturbing any + * time-sensitive functions. + * + * In Snapshot mode, TzCtrl is only used for the stack usage monitoring and is + * not created if stack monitoring is disabled. TRC_CFG_CTRL_TASK_PRIORITY should + * be low, to avoid disturbing any time-sensitive tasks. + */ +#define TRC_CFG_CTRL_TASK_PRIORITY 1 -/******************************************************************************* - * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION - * - * Specifies how the recorder buffer is allocated (also in case of streaming, in +/** + * @def TRC_CFG_CTRL_TASK_DELAY + * @brief The delay between loops of the TzCtrl task (see TRC_CFG_CTRL_TASK_PRIORITY), + * which affects the frequency of the stack monitoring. + * + * In streaming mode, this also affects the trace data transfer if you are using + * a stream port leveraging the internal buffer (like TCP/IP). A shorter delay + * increases the CPU load of TzCtrl somewhat, but may improve the performance of + * of the trace streaming, especially if the trace buffer is small. + */ +#define TRC_CFG_CTRL_TASK_DELAY 2 + +/** + * @def TRC_CFG_CTRL_TASK_STACK_SIZE + * @brief The stack size of the Tracealyzer Control (TzCtrl) task. + * See TRC_CFG_CTRL_TASK_PRIORITY for further information about TzCtrl. + */ +#define TRC_CFG_CTRL_TASK_STACK_SIZE 1024 + +/** + * @def TRC_CFG_RECORDER_BUFFER_ALLOCATION + * @brief Specifies how the recorder buffer is allocated (also in case of streaming, in * port using the recorder's internal temporary buffer) * * Values: @@ -275,13 +228,12 @@ extern "C" { * (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 + */ +#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 +/** + * @def TRC_CFG_MAX_ISR_NESTING + * @brief 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 @@ -290,15 +242,75 @@ extern "C" { * This value must be a non-zero positive constant, at least 1. * * Default value: 8 - *****************************************************************************/ -#define TRC_CFG_MAX_ISR_NESTING 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 +/** + * @def TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * @brief 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 + +/** + * @def TRC_CFG_RECORDER_DATA_INIT + * @brief Macro which states wether the recorder data should have an initial value. + * + * In very specific cases where traced objects are created before main(), + * the recorder will need to be started even before that. In these cases, + * the recorder data would be initialized by vTraceEnable(TRC_INIT) but could + * then later be overwritten by the initialization value. + * If this is an issue for you, set TRC_CFG_RECORDER_DATA_INIT to 0. + * The following code can then be used before any traced objects are created: + * + * extern uint32_t RecorderEnabled; + * RecorderEnabled = 0; + * xTraceInitialize(); + * + * After the clocks are properly initialized, use vTraceEnable(...) to start + * the tracing. + * + * Default value is 1. + */ +#define TRC_CFG_RECORDER_DATA_INIT 1 + +/** + * @def TRC_CFG_RECORDER_DATA_ATTRIBUTE + * @brief When setting TRC_CFG_RECORDER_DATA_INIT to 0, you might also need to make + * sure certain recorder data is placed in a specific RAM section to avoid being + * zeroed out after initialization. Define TRC_CFG_RECORDER_DATA_ATTRIBUTE as + * that attribute. + * + * Example: + * #define TRC_CFG_RECORDER_DATA_ATTRIBUTE __attribute__((section(".bss.trace_recorder_data"))) + * + * Default value is empty. + */ +#define TRC_CFG_RECORDER_DATA_ATTRIBUTE + +/** + * @def TRC_CFG_USE_TRACE_ASSERT + * @brief Enable or disable debug asserts. Information regarding any assert that is + * triggered will be in trcAssert.c. + */ +#define TRC_CFG_USE_TRACE_ASSERT 0 #ifdef __cplusplus } diff --git a/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcKernelPortConfig.h b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcKernelPortConfig.h new file mode 100644 index 0000000000..387df1ab66 --- /dev/null +++ b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcKernelPortConfig.h @@ -0,0 +1,116 @@ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Configuration parameters for the kernel port. + * More settings can be found in trcKernelPortStreamingConfig.h and + * trcKernelPortSnapshotConfig.h. + */ + +#ifndef TRC_KERNEL_PORT_CONFIG_H +#define TRC_KERNEL_PORT_CONFIG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @def TRC_CFG_RECORDER_MODE + * @brief 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 + +/** + * @def TRC_CFG_FREERTOS_VERSION + * @brief 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_X If using FreeRTOS v7.3.X + * TRC_FREERTOS_VERSION_7_4_X If using FreeRTOS v7.4.X + * TRC_FREERTOS_VERSION_7_5_X If using FreeRTOS v7.5.X + * TRC_FREERTOS_VERSION_7_6_X If using FreeRTOS v7.6.X + * TRC_FREERTOS_VERSION_8_X_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 + * TRC_FREERTOS_VERSION_10_0_1 If using FreeRTOS v10.0.1 + * TRC_FREERTOS_VERSION_10_1_0 If using FreeRTOS v10.1.0 + * TRC_FREERTOS_VERSION_10_1_1 If using FreeRTOS v10.1.1 + * TRC_FREERTOS_VERSION_10_2_0 If using FreeRTOS v10.2.0 + * TRC_FREERTOS_VERSION_10_2_1 If using FreeRTOS v10.2.1 + * TRC_FREERTOS_VERSION_10_3_0 If using FreeRTOS v10.3.0 + * TRC_FREERTOS_VERSION_10_3_1 If using FreeRTOS v10.3.1 + * TRC_FREERTOS_VERSION_10_4_0 If using FreeRTOS v10.4.0 + * TRC_FREERTOS_VERSION_10_4_1 If using FreeRTOS v10.4.1 or later + */ +#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_1 + +/** + * @def TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + * @brief 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 + +/** + * @def TRC_CFG_INCLUDE_TIMER_EVENTS + * @brief 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 + +/** + * @def TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS + * @brief 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 + +/** + * @def TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + * @brief 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 + +/** + * @def TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND + * @brief When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace + * point in prvNotifyQueueSetContainer() in queue.c is renamed from + * traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from + * other traceQUEUE_SEND trace points. Then set this to TRC_ACKNOWLEDGED. + */ +#define TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND 0 /* TRC_ACKNOWLEDGED */ + +#ifdef __cplusplus +} +#endif + +#endif /* TRC_KERNEL_PORT_CONFIG_H */ diff --git a/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h new file mode 100644 index 0000000000..023a803164 --- /dev/null +++ b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcKernelPortSnapshotConfig.h @@ -0,0 +1,69 @@ +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com + * + * SPDX-License-Identifier: Apache-2.0 + * + * Kernel port configuration parameters for snapshot mode. + */ + +#ifndef TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H +#define TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @def TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... + * @brief 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 50 +#define TRC_CFG_NMESSAGEBUFFER 50 + +/** + * @def TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... + * @brief 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 + +#ifdef __cplusplus +} +#endif + +#endif /* TRC_KERNEL_PORT_SNAPSHOT_CONFIG_H */ diff --git a/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcSnapshotConfig.h b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcSnapshotConfig.h index 8bb9221d79..8d7449a4cd 100644 --- a/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcSnapshotConfig.h +++ b/FreeRTOS/Demo/WIN32-MingW/Trace_Recorder_Configuration/trcSnapshotConfig.h @@ -1,58 +1,24 @@ -/******************************************************************************* - * Trace Recorder Library for Tracealyzer v3.1.2 - * Percepio AB, www.percepio.com +/* + * Trace Recorder for Tracealyzer v4.6.0 + * Copyright 2021 Percepio AB + * www.percepio.com * - * trcSnapshotConfig.h + * SPDX-License-Identifier: Apache-2.0 * * 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) +#ifdef __cplusplus + extern "C" { +#endif -/****************************************************************************** - * TRC_CFG_SNAPSHOT_MODE - * - * Macro which should be defined as one of: +/** + * @def TRC_CFG_SNAPSHOT_MODE + * @brief 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. @@ -66,13 +32,12 @@ * 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 + */ +#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER -/******************************************************************************* - * TRC_CFG_EVENT_BUFFER_SIZE - * - * Macro which should be defined as an integer value. +/** + * @def TRC_CFG_EVENT_BUFFER_SIZE + * @brief 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 @@ -81,46 +46,12 @@ * * 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 + */ +#define TRC_CFG_EVENT_BUFFER_SIZE 250000 - -/****************************************************************************** - * TRC_CFG_INCLUDE_FLOAT_SUPPORT - * - * Macro which should be defined as either zero (0) or one (1). +/** + * @def TRC_CFG_INCLUDE_FLOAT_SUPPORT + * @brief 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 @@ -132,13 +63,12 @@ * vTracePrintF can be used with integer and string arguments in either case. * * Default value is 0. - *****************************************************************************/ -#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 + */ +#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 -/******************************************************************************* - * TRC_CFG_SYMBOL_TABLE_SIZE - * - * Macro which should be defined as an integer value. +/** + * @def TRC_CFG_SYMBOL_TABLE_SIZE + * @brief 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 @@ -148,30 +78,13 @@ * 32-bit pointer, i.e., using 4 bytes rather than 0. * * Default value is 800. - ******************************************************************************/ -#define TRC_CFG_SYMBOL_TABLE_SIZE 5000 + */ +#define TRC_CFG_SYMBOL_TABLE_SIZE 8000 -#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0) -#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" +#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 ******************************************************** ****************************************************************************** @@ -180,37 +93,35 @@ * 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 +/** + * @def TRC_CFG_HEAP_SIZE_BELOW_16M + * @brief 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. * - * Macro which should be defined as either zero (0) or one (1). + * Default value is 0. + */ +#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 + +/** + * @def TRC_CFG_USE_IMPLICIT_IFE_RULES + * @brief 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. + * functions xTraceTaskInstanceFinishedNow and xTraceTaskInstanceFinishedNext. * * 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 + * override the default rules using xTraceTaskInstanceFinishedNow/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, + * disabled globally. You must then call xTraceTaskInstanceFinishedNow or + * xTraceTaskInstanceFinishedNext 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": @@ -218,16 +129,12 @@ * - 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 + */ +#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). +/** + * @def TRC_CFG_USE_16BIT_OBJECT_HANDLES + * @brief 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 @@ -245,31 +152,12 @@ * 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 + */ +#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 -/******************************************************************************* - * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER - * - * Macro which should be defined as an integer value. +/** + * @def TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + * @brief 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). @@ -292,14 +180,17 @@ * repeating events, using the same format string within each channel. * * Examples: - * - * traceString chn1 = xTraceRegisterString("Channel 1"); - * traceString fmt1 = xTraceRegisterString("Event!"); + * TraceStringHandle_t chn1; + * TraceStringHandle_t fmt1; + * xTraceStringRegister("Channel 1", &chn1); + * xTraceStringRegister("Event!", &fmt1); * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); * - * traceString chn2 = xTraceRegisterString("Channel 2"); - * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d"); - * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); + * TraceStringHandle_t chn2; + * TraceStringHandle_t fmt2; + * xTraceStringRegister("Channel 2", &chn2); + * xTraceStringRegister("X: %d, Y: %d", &fmt2); + * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); * * // Result in "[Channel 1] Event!" * vTraceUBEvent(UBCh1); @@ -307,7 +198,7 @@ * // Result in "[Channel 2] X: 23, Y: 19" * vTraceUBData(UBCh2, 23, 19); * - * You can also use the other user event functions, like vTracePrintF. + * You can also use the other user event functions, like xTracePrintF. * 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 @@ -316,30 +207,27 @@ * 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); + * xTracePrintF(chn2, "%Z: %d", value1); * * // Finds the existing UB channel - * vTracePrintF(chn2, "%Z: %d", value2); - - ******************************************************************************/ -#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 + * xTracePrintF(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. +/** + * @def TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + * @brief 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 + */ +#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 -/******************************************************************************* - * TRC_CFG_UB_CHANNELS - * - * Macro which should be defined as an integer value. +/** + * @def TRC_CFG_UB_CHANNELS + * @brief 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 @@ -347,32 +235,11 @@ * 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 + */ +#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 +#ifdef __cplusplus +} +#endif #endif /*TRC_SNAPSHOT_CONFIG_H*/ diff --git a/FreeRTOS/Demo/WIN32-MingW/main.c b/FreeRTOS/Demo/WIN32-MingW/main.c index cb6b7efa53..40ea884525 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main.c +++ b/FreeRTOS/Demo/WIN32-MingW/main.c @@ -67,16 +67,24 @@ 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. */ -#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 /* This demo uses heap_5.c, and these constants define the sizes of the regions that make up the total heap. 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 10801 -#define mainREGION_2_SIZE 29905 -#define mainREGION_3_SIZE 6007 +#define mainREGION_1_SIZE 8201 +#define mainREGION_2_SIZE 40905 +#define mainREGION_3_SIZE 50007 + +/* This demo allows for users to perform actions with the keyboard. */ +#define mainNO_KEY_PRESS_VALUE -1 +#define mainOUTPUT_TRACE_KEY 't' +#define mainINTERRUPT_NUMBER_KEYBOARD 3 + +/* This demo allows to save a trace file. */ +#define mainTRACE_FILE_NAME "Trace.dump" /*-----------------------------------------------------------*/ @@ -125,6 +133,23 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack */ static void prvSaveTraceFile( void ); +/* + * Windows thread function to capture keyboard input from outside of the + * FreeRTOS simulator. This thread passes data safely into the FreeRTOS + * simulator using a stream buffer. + */ +static DWORD WINAPI prvWindowsKeyboardInputThread( void * pvParam ); + +/* + * Interrupt handler for when keyboard input is received. + */ +static uint32_t prvKeyboardInterruptHandler( void ); + +/* + * Keyboard interrupt handler for the blinky demo. + */ +extern void vBlinkyKeyboardInterruptHandler( int xKeyPressed ); + /*-----------------------------------------------------------*/ /* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can @@ -134,204 +159,227 @@ 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; +/* Thread handle for the keyboard input Windows thread. */ +static HANDLE xWindowsKeyboardInputThreadHandle = NULL; + +/* This stores the last key pressed that has not been handled. + * Keyboard input is retrieved by the prvWindowsKeyboardInputThread + * Windows thread and stored here. This is then read by the idle + * task and handled appropriately. */ +static int xKeyPressed = mainNO_KEY_PRESS_VALUE; /*-----------------------------------------------------------*/ int main( void ) { - /* This demo uses heap_5.c, so start by defining some heap regions. heap_5 - is only used for test and example reasons. Heap_4 is more appropriate. See - http://www.freertos.org/a00111.html for an explanation. */ - prvInitialiseHeap(); - - /* 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 - - /* 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; + /* Set interrupt handler for keyboard input. */ + vPortSetInterruptHandler( mainINTERRUPT_NUMBER_KEYBOARD, prvKeyboardInterruptHandler ); + + /* Start keyboard input handling thread. */ + xWindowsKeyboardInputThreadHandle = CreateThread( + NULL, /* Pointer to thread security attributes. */ + 0, /* Initial thread stack size, in bytes. */ + prvWindowsKeyboardInputThread, /* Pointer to thread function. */ + NULL, /* Argument for new thread. */ + 0, /* Creation flags. */ + NULL); + + fflush( stdout ); + + /* Use the cores that are not used by the FreeRTOS tasks. */ + SetThreadAffinityMask( xWindowsKeyboardInputThreadHandle, ~0x01u ); + + /* This demo uses heap_5.c, so start by defining some heap regions. heap_5 + is only used for test and example reasons. Heap_4 is more appropriate. See + http://www.freertos.org/a00111.html for an explanation. */ + prvInitialiseHeap(); + + /* 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. */ + configASSERT( xTraceInitialize() == TRC_SUCCESS ); + + /* Start the trace recording - the recording is written to a file if + configASSERT() is called. */ + printf( + "Trace started.\r\n" + "Note that the trace output uses the ring buffer mode, meaning that the output trace\r\n" + "will only be the most recent data able to fit within the trace recorder buffer.\r\n\r\n" + "The trace will be dumped to the file \"%s\" whenever a call to configASSERT()\r\n" + "fails or the \'%c\' key is pressed.\r\n" + "Note that key presses cannot be captured in the Eclipse console, so for key presses to work\r\n" + "you will have to run this demo in a Windows console.\r\n\r\n", + mainTRACE_FILE_NAME, mainOUTPUT_TRACE_KEY ); + fflush( stdout ); + configASSERT( xTraceEnable( TRC_START ) == TRC_SUCCESS ); + } + #endif + + /* 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__ ); + /* 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. */ - - /* Uncomment the following code to allow the trace to be stopped with any - key press. The code is commented out by default as the kbhit() function - interferes with the run time behaviour. */ - /* - if( _kbhit() != pdFALSE ) - { - if( xTraceRunning == pdTRUE ) - { - vTraceStop(); - prvSaveTraceFile(); - xTraceRunning = pdFALSE; - } - } - */ - - #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 + /* 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. */ + + #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 ) 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 */ + /* 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. */ + /* 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(); + /* 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(); + { + printf("ASSERT! Line %ld, file %s, GetLastError() %ld\r\n", ulLine, pcFileName, GetLastError()); + fflush( stdout ); + + #if( projCOVERAGE_TEST != 1 ) + { + /* Stop the trace recording. */ + ( void ) xTraceDisable(); + prvSaveTraceFile(); + } + #endif + + /* 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" ); + } + + #if( projCOVERAGE_TEST != 1 ) + { + /* Re-enable recording */ + ( void ) xTraceEnable( TRC_START ); + } + #endif + } + 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 + /* Tracing is not used when code coverage analysis is being performed. */ + #if( projCOVERAGE_TEST != 1 ) + { + FILE* pxOutputFile; + + pxOutputFile = fopen( mainTRACE_FILE_NAME, "wb"); + + if( pxOutputFile != NULL ) + { + fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile ); + fclose( pxOutputFile ); + printf( "\r\nTrace output saved to %s\r\n", mainTRACE_FILE_NAME ); + fflush( stdout ); + } + else + { + printf( "\r\nFailed to create trace dump file\r\n" ); + fflush( stdout ); + } + } + #endif } /*-----------------------------------------------------------*/ @@ -352,27 +400,27 @@ volatile uint32_t ulAdditionalOffset = 19; /* Just to prevent 'condition is alwa HeapStats_t xHeapStats; const HeapRegion_t xHeapRegions[] = { - /* Start address with dummy offsets Size */ - { ucHeap + 1, mainREGION_1_SIZE }, - { ucHeap + 15 + mainREGION_1_SIZE, mainREGION_2_SIZE }, - { ucHeap + 19 + mainREGION_1_SIZE + mainREGION_2_SIZE, mainREGION_3_SIZE }, - { NULL, 0 } + /* Start address with dummy offsets Size */ + { ucHeap + 1, mainREGION_1_SIZE }, + { ucHeap + 15 + mainREGION_1_SIZE, mainREGION_2_SIZE }, + { ucHeap + 19 + mainREGION_1_SIZE + mainREGION_2_SIZE, mainREGION_3_SIZE }, + { NULL, 0 } }; - /* Sanity check that the sizes and offsets defined actually fit into the - array. */ - configASSERT( ( ulAdditionalOffset + mainREGION_1_SIZE + mainREGION_2_SIZE + mainREGION_3_SIZE ) < configTOTAL_HEAP_SIZE ); + /* Sanity check that the sizes and offsets defined actually fit into the + array. */ + configASSERT( ( ulAdditionalOffset + mainREGION_1_SIZE + mainREGION_2_SIZE + mainREGION_3_SIZE ) < configTOTAL_HEAP_SIZE ); - /* Prevent compiler warnings when configASSERT() is not defined. */ - ( void ) ulAdditionalOffset; + /* Prevent compiler warnings when configASSERT() is not defined. */ + ( void ) ulAdditionalOffset; - /* The heap has not been initialised yet so expect stats to all be zero. */ - vPortGetHeapStats( &xHeapStats ); + /* The heap has not been initialised yet so expect stats to all be zero. */ + vPortGetHeapStats( &xHeapStats ); - vPortDefineHeapRegions( xHeapRegions ); + vPortDefineHeapRegions( xHeapRegions ); - /* Sanity check vTaskGetHeapStats(). */ - prvExerciseHeapStats(); + /* Sanity check vTaskGetHeapStats(). */ + prvExerciseHeapStats(); } /*-----------------------------------------------------------*/ @@ -385,60 +433,60 @@ void *pvAllocatedBlock; const size_t xArraySize = 5, xBlockSize = 1000UL; void *pvAllocatedBlocks[ xArraySize ]; - /* Check heap stats are as expected after initialisation but before any - allocations. */ - vPortGetHeapStats( &xHeapStats ); - - /* Minimum ever free bytes remaining should be the same as the total number - of bytes as nothing has been allocated yet. */ - configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes ); - configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xInitialFreeSpace ); - - /* Nothing has been allocated or freed yet. */ - configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 0 ); - configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 0 ); - - /* Allocate a 1000 byte block then measure what the overhead of the - allocation in regards to how many bytes more than 1000 were actually - removed from the heap in order to store metadata about the allocation. */ - pvAllocatedBlock = pvPortMalloc( xBlockSize ); - configASSERT( pvAllocatedBlock ); - xMetaDataOverhead = ( xInitialFreeSpace - xPortGetFreeHeapSize() ) - xBlockSize; - - /* Free the block again to get back to where we started. */ - vPortFree( pvAllocatedBlock ); - vPortGetHeapStats( &xHeapStats ); - configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xInitialFreeSpace ); - configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 1 ); - configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); - - /* Allocate blocks checking some stats value on each allocation. */ - for( i = 0; i < xArraySize; i++ ) - { - pvAllocatedBlocks[ i ] = pvPortMalloc( xBlockSize ); - configASSERT( pvAllocatedBlocks[ i ] ); - vPortGetHeapStats( &xHeapStats ); - configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == ( xInitialFreeSpace - ( ( i + 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ); - configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes ); - configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( 2Ul + i ) ); - configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); /* Does not increase during allocations. */ - } - - configASSERT( xPortGetFreeHeapSize() == xPortGetMinimumEverFreeHeapSize() ); - xMinimumFreeBytes = xPortGetFreeHeapSize(); - - /* Free the blocks again. */ - for( i = 0; i < xArraySize; i++ ) - { - vPortFree( pvAllocatedBlocks[ i ] ); - vPortGetHeapStats( &xHeapStats ); - configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == ( xInitialFreeSpace - ( ( ( xArraySize - i - 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ) ); - configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( xArraySize + 1 ) ); /* Does not increase during frees. */ - configASSERT( xHeapStats.xNumberOfSuccessfulFrees == ( 2UL + i ) ); - } - - /* The minimum ever free heap size should not change as blocks are freed. */ - configASSERT( xMinimumFreeBytes == xPortGetMinimumEverFreeHeapSize() ); + /* Check heap stats are as expected after initialisation but before any + allocations. */ + vPortGetHeapStats( &xHeapStats ); + + /* Minimum ever free bytes remaining should be the same as the total number + of bytes as nothing has been allocated yet. */ + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xInitialFreeSpace ); + + /* Nothing has been allocated or freed yet. */ + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 0 ); + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 0 ); + + /* Allocate a 1000 byte block then measure what the overhead of the + allocation in regards to how many bytes more than 1000 were actually + removed from the heap in order to store metadata about the allocation. */ + pvAllocatedBlock = pvPortMalloc( xBlockSize ); + configASSERT( pvAllocatedBlock ); + xMetaDataOverhead = ( xInitialFreeSpace - xPortGetFreeHeapSize() ) - xBlockSize; + + /* Free the block again to get back to where we started. */ + vPortFree( pvAllocatedBlock ); + vPortGetHeapStats( &xHeapStats ); + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xInitialFreeSpace ); + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 1 ); + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); + + /* Allocate blocks checking some stats value on each allocation. */ + for( i = 0; i < xArraySize; i++ ) + { + pvAllocatedBlocks[ i ] = pvPortMalloc( xBlockSize ); + configASSERT( pvAllocatedBlocks[ i ] ); + vPortGetHeapStats( &xHeapStats ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == ( xInitialFreeSpace - ( ( i + 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes ); + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( 2Ul + i ) ); + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); /* Does not increase during allocations. */ + } + + configASSERT( xPortGetFreeHeapSize() == xPortGetMinimumEverFreeHeapSize() ); + xMinimumFreeBytes = xPortGetFreeHeapSize(); + + /* Free the blocks again. */ + for( i = 0; i < xArraySize; i++ ) + { + vPortFree( pvAllocatedBlocks[ i ] ); + vPortGetHeapStats( &xHeapStats ); + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == ( xInitialFreeSpace - ( ( ( xArraySize - i - 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ) ); + configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( xArraySize + 1 ) ); /* Does not increase during frees. */ + configASSERT( xHeapStats.xNumberOfSuccessfulFrees == ( 2UL + i ) ); + } + + /* The minimum ever free heap size should not change as blocks are freed. */ + configASSERT( xMinimumFreeBytes == xPortGetMinimumEverFreeHeapSize() ); } /*-----------------------------------------------------------*/ @@ -453,18 +501,19 @@ 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 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 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; + /* 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 @@ -477,16 +526,103 @@ 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 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; +} - /* 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; +/* + * Interrupt handler for when keyboard input is received. + */ +static uint32_t prvKeyboardInterruptHandler( void ) +{ + /* Handle keyboard input. */ + switch ( xKeyPressed ) + { + case mainNO_KEY_PRESS_VALUE: + break; + case mainOUTPUT_TRACE_KEY: + #if( projCOVERAGE_TEST != 1 ) + { + /* Saving the trace file requires Windows system calls, so enter a critical + * section to prevent deadlock or errors resulting from calling a Windows + * system call from within the FreeRTOS simulator. */ + portENTER_CRITICAL(); + { + ( void ) xTraceDisable(); + prvSaveTraceFile(); + ( void ) xTraceEnable( TRC_START ); + } + portEXIT_CRITICAL(); + } + #endif + break; + default: + #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) + { + /* Call the keyboard interrupt handler for the blinky demo. */ + vBlinkyKeyboardInterruptHandler( xKeyPressed ); + } + #endif + break; + } + + /* This interrupt does not require a context switch so return pdFALSE */ + return pdFALSE; } +/*-----------------------------------------------------------*/ + +/* + * Windows thread function to capture keyboard input from outside of the + * FreeRTOS simulator. This thread passes data into the simulator using + * an integer. + */ +static DWORD WINAPI prvWindowsKeyboardInputThread( void * pvParam ) +{ + ( void ) pvParam; + + for ( ; ; ) + { + /* Block on acquiring a key press */ + xKeyPressed = _getch(); + + /* Notify FreeRTOS simulator that there is a keyboard interrupt. + * This will trigger prvKeyboardInterruptHandler. + */ + vPortGenerateSimulatedInterrupt( mainINTERRUPT_NUMBER_KEYBOARD ); + } + + /* Should not get here, report negative exit status. */ + return -1; +} + +/*-----------------------------------------------------------*/ + +/* The below code is used by the trace recorder for timing. */ +static uint32_t ulEntryTime = 0; + +void vTraceTimerReset( void ) +{ + ulEntryTime = xTaskGetTickCount(); +} + +uint32_t uiTraceTimerGetFrequency( void ) +{ + return configTICK_RATE_HZ; +} + +uint32_t uiTraceTimerGetValue( void ) +{ + return( xTaskGetTickCount() - ulEntryTime ); +} diff --git a/FreeRTOS/Demo/WIN32-MingW/main_blinky.c b/FreeRTOS/Demo/WIN32-MingW/main_blinky.c index 6cbe24fe63..85f8c92674 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main_blinky.c +++ b/FreeRTOS/Demo/WIN32-MingW/main_blinky.c @@ -91,21 +91,24 @@ #include "semphr.h" /* Priorities at which the tasks are created. */ -#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#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 ) +#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 ) +#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 ) +#define mainVALUE_SENT_FROM_TASK ( 100UL ) +#define mainVALUE_SENT_FROM_TIMER ( 200UL ) + +/* This demo allows for users to perform actions with the keyboard. */ +#define mainRESET_TIMER_KEY ( 'r' ) /*-----------------------------------------------------------*/ @@ -135,44 +138,45 @@ 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( ;; ); + printf( "\r\nStarting the blinky demo. Press \'%c\' to reset the software timer used in this demo.\r\n\r\n", mainRESET_TIMER_KEY ); + /* 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( ;; ); } /*-----------------------------------------------------------*/ @@ -182,26 +186,26 @@ 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 ); - } + /* 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 ); + } } /*-----------------------------------------------------------*/ @@ -209,18 +213,18 @@ 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. */ + /* 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; + /* 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 ); + /* 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 ); } /*-----------------------------------------------------------*/ @@ -228,38 +232,78 @@ 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 ) - { - printf( "Message received from task\r\n" ); - } - else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER ) - { - printf( "Message received from software timer\r\n" ); - } - else - { - printf( "Unexpected message\r\n" ); - } - - fflush( stdout ); - } + /* 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 ); + + /* Enter critical section to use printf. Not doing this could potentially cause + a deadlock if the FreeRTOS simulator switches contexts and another task + tries to call printf - it should be noted that use of printf within + the FreeRTOS simulator is unsafe, but used here for simplicity. */ + taskENTER_CRITICAL(); + { + /* 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 ) + { + printf( "Message received from task\r\n" ); + } + else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER ) + { + printf( "Message received from software timer\r\n" ); + } + else + { + printf( "Unexpected message\r\n" ); + } + + fflush( stdout ); + } + taskEXIT_CRITICAL(); + } } + /*-----------------------------------------------------------*/ +/* Called from prvKeyboardInterruptHandler(), which is defined in main.c. */ +void vBlinkyKeyboardInterruptHandler( int xKeyPressed ) +{ + /* Handle keyboard input. */ + switch ( xKeyPressed ) + { + + case mainRESET_TIMER_KEY: + + if ( xTimer != NULL ) + { + /* Critical section around printf to prevent a deadlock + on context switch. */ + portENTER_CRITICAL(); + { + printf("\r\nResetting software timer.\r\n\r\n"); + } + portEXIT_CRITICAL(); + + /* Reset the software timer. */ + xTimerReset( xTimer, portMAX_DELAY ); + } + + break; + + default: + + break; + } +} + diff --git a/FreeRTOS/Demo/WIN32-MingW/main_full.c b/FreeRTOS/Demo/WIN32-MingW/main_full.c index 65c831c3ef..e1f3f2881e 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main_full.c +++ b/FreeRTOS/Demo/WIN32-MingW/main_full.c @@ -24,6 +24,7 @@ * */ + /* ******************************************************************************* * NOTE 1: The Win32 port is a simulation (or is that emulation?) only! Do not @@ -106,18 +107,18 @@ #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 ) +#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 @@ -190,216 +191,216 @@ 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; + /* 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 ); +const TickType_t xCyclePeriod = pdMS_TO_TICKS( 5000UL ); HeapStats_t xHeapStats; - /* 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 */ - - /* This is the only task that uses stdout so its ok to call printf() - directly. */ - vPortGetHeapStats( &xHeapStats ); - - configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() ); - configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() ); - - printf( "%s - tick count %u - free heap %u - min free heap %u - largest free block %u - number of free blocks %u\r\n", - pcStatusMessage, - xTaskGetTickCount(), - xHeapStats.xAvailableHeapSpaceInBytes, - xHeapStats.xMinimumEverFreeBytesRemaining, - xHeapStats.xSizeOfLargestFreeBlockInBytes, - xHeapStats.xNumberOfFreeBlocks ); - - fflush( stdout ); - } + /* 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, xCyclePeriod ); + + /* Check the standard demo tasks are running without error. */ + #if( configUSE_PREEMPTION != 0 ) + { + /* These tasks are only created when preemption is used. */ + if( xAreTimerDemoTasksStillRunning( xCyclePeriod ) != 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 */ + + /* This is the only task that uses stdout so its ok to call printf() + directly. */ + vPortGetHeapStats( &xHeapStats ); + + configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() ); + configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() ); + + printf( "%s - tick count %u - free heap %u - min free heap %u - largest free block %u - number of free blocks %u\r\n", + pcStatusMessage, + xTaskGetTickCount(), + xHeapStats.xAvailableHeapSpaceInBytes, + xHeapStats.xMinimumEverFreeBytesRemaining, + xHeapStats.xSizeOfLargestFreeBlockInBytes, + xHeapStats.xNumberOfFreeBlocks ); + + fflush( stdout ); + } } /*-----------------------------------------------------------*/ @@ -407,17 +408,17 @@ 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. */ - Sleep( ulMSToSleep ); - } + /* 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. */ + Sleep( ulMSToSleep ); + } } /*-----------------------------------------------------------*/ @@ -427,65 +428,65 @@ 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. */ - Sleep( ulMSToSleep ); - - /* 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 + /* Sleep to reduce CPU load, but don't sleep indefinitely in case there are + tasks waiting to be terminated by the idle task. */ + Sleep( ulMSToSleep ); + + /* 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 } /*-----------------------------------------------------------*/ @@ -494,44 +495,44 @@ 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 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(); + /* 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(); + /* 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 event groups from interrupts. */ + vPeriodicEventGroupsProcessing(); - /* Exercise giving mutexes from an interrupt. */ - vInterruptSemaphorePeriodicTest(); + /* Exercise giving mutexes from an interrupt. */ + vInterruptSemaphorePeriodicTest(); - /* Exercise using task notifications from an interrupt. */ - xNotifyTaskFromISR(); + /* 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 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(); + /* 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. */ + /* For code coverage purposes. */ + xTimerTask = xTimerGetTimerDaemonTaskHandle(); + configASSERT( uxTaskPriorityGetFromISR( xTimerTask ) == configTIMER_TASK_PRIORITY ); + ( void ) xTimerTask; /* In case configASSERT() is not defined. */ } /*-----------------------------------------------------------*/ @@ -540,27 +541,27 @@ static void prvPendedFunction( void *pvParameter1, uint32_t ulParameter2 ) static uint32_t ulLastParameter1 = 1000UL, ulLastParameter2 = 0UL; uint32_t ulParameter1; - ulParameter1 = ( uint32_t ) pvParameter1; + ulParameter1 = ( uint32_t ) pvParameter1; - /* Ensure the parameters are as expected. */ - configASSERT( ulParameter1 == ( ulLastParameter1 + 1 ) ); - configASSERT( ulParameter2 == ( ulLastParameter2 + 1 ) ); + /* 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; + /* 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; + /* 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; + /* This is the callback function for the timer accessed by + prvDemonstrateTimerQueryFunctions(). The callback does not do anything. */ + ( void ) xTimer; } /*-----------------------------------------------------------*/ @@ -571,35 +572,35 @@ 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; - } + 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; + } } /*-----------------------------------------------------------*/ @@ -608,13 +609,13 @@ static void prvDemonstratePendingFunctionCall( void ) static uint32_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++; + /* 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 ); + /* Pend the function call, sending the parameters. */ + xTimerPendFunctionCall( prvPendedFunction, ( void * ) ulParameter1, ulParameter2, xDontBlock ); } /*-----------------------------------------------------------*/ @@ -629,110 +630,110 @@ 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; + /* 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; } /*-----------------------------------------------------------*/ @@ -742,67 +743,67 @@ 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 - } + /* 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 + } } /*-----------------------------------------------------------*/ @@ -810,36 +811,36 @@ static void prvPermanentlyBlockingSemaphoreTask( void *pvParameters ) { SemaphoreHandle_t xSemaphore; - /* Prevent compiler warning about unused parameter in the case that - configASSERT() is not defined. */ - ( void ) pvParameters; + /* 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 ); + /* This task should block on a semaphore, and never return. */ + xSemaphore = xSemaphoreCreateBinary(); + configASSERT( xSemaphore ); - xSemaphoreTake( xSemaphore, portMAX_DELAY ); + xSemaphoreTake( xSemaphore, portMAX_DELAY ); - /* The above xSemaphoreTake() call should never return, force an assert if - it does. */ - configASSERT( pvParameters != NULL ); - vTaskDelete( NULL ); + /* 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; + /* 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 ); + /* 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 ); + /* The above ulTaskNotifyTake() call should never return, force an assert + if it does. */ + configASSERT( pvParameters != NULL ); + vTaskDelete( NULL ); } /*-----------------------------------------------------------*/ @@ -847,10 +848,10 @@ static void prvReloadModeTestTimerCallback( TimerHandle_t xTimer ) { uint32_t ulTimerID; - /* Increment the timer's ID to show the callback has executed. */ - ulTimerID = ( uint32_t ) pvTimerGetTimerID( xTimer ); - ulTimerID++; - vTimerSetTimerID( xTimer, ( void * ) ulTimerID ); + /* Increment the timer's ID to show the callback has executed. */ + ulTimerID = ( uint32_t ) pvTimerGetTimerID( xTimer ); + ulTimerID++; + vTimerSetTimerID( xTimer, ( void * ) ulTimerID ); } /*-----------------------------------------------------------*/ @@ -860,47 +861,49 @@ 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( ( ( uint32_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( ( uint32_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( ( uint32_t ) ( pvTimerGetTimerID( xTimer ) ) == 1UL ); - - /* Clean up at the end. */ - xTimerDelete( xTimer, portMAX_DELAY ); - vTaskDelete( NULL ); + /* 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( ( ( uint32_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( ( uint32_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( ( uint32_t ) ( pvTimerGetTimerID( xTimer ) ) == 1UL ); + + /* Clean up at the end. */ + xTimerDelete( xTimer, portMAX_DELAY ); + vTaskDelete( NULL ); }