--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<?ccsproject version="1.0"?>\r
+\r
+<projectOptions>\r
+<deviceVariant value="Cortex R.RM48L952"/>\r
+<deviceFamily value="TMS470"/>\r
+<deviceEndianness value="little"/>\r
+<codegenToolVersion value="4.9.5"/>\r
+<isElfFormat value="true"/>\r
+<connection value="common/targetdb/connections/TIXDS100v2_Connection.xml"/>\r
+<rts value="rtsv7R4_T_le_v3D16_eabi.lib"/>\r
+<templateProperties value="id=com.ti.common.project.core.emptyProjectWithMainTemplate,"/>\r
+</projectOptions>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<?fileVersion 4.0.0?>\r
+\r
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">\r
+ <storageModule configRelations="2" moduleId="org.eclipse.cdt.core.settings">\r
+ <cconfiguration id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.580416121">\r
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.580416121" moduleId="org.eclipse.cdt.core.settings" name="Debug">\r
+ <externalSettings/>\r
+ <extensions>\r
+ <extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>\r
+ <extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+ <extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+ <extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+ </extensions>\r
+ </storageModule>\r
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+ <configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.580416121" name="Debug" parent="com.ti.ccstudio.buildDefinitions.TMS470.Debug">\r
+ <folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.580416121." name="/" resourcePath="">\r
+ <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.DebugToolchain.1023182662" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.DebugToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerDebug.1702479053">\r
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.1465456143" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">\r
+ <listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=Cortex R.RM48L950"/>\r
+ <listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>\r
+ <listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>\r
+ <listOptionValue builtIn="false" value="CCS_MBS_VERSION=5.1.0.01"/>\r
+ <listOptionValue builtIn="false" value="LINKER_COMMAND_FILE=sys_link.cmd"/>\r
+ <listOptionValue builtIn="false" value="RUNTIME_SUPPORT_LIBRARY=libc.a"/>\r
+ <listOptionValue builtIn="false" value="OUTPUT_TYPE=executable"/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1528434639" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="4.9.5" valueType="string"/>\r
+ <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.targetPlatformDebug.580671531" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.targetPlatformDebug"/>\r
+ <builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.builderDebug.1190105434" keepEnvironmentInBuildfile="false" name="GNU Make" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.builderDebug"/>\r
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.compilerDebug.1935264313" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.compilerDebug">\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.CODE_STATE.619839677" name="Designate code state, 16-bit (thumb) or 32-bit (--code_state)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.CODE_STATE" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.CODE_STATE.32" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.SILICON_VERSION.942876674" name="Target processor version (--silicon_version, -mv)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.SILICON_VERSION.7R4" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.FLOAT_SUPPORT.748273201" name="Specify floating point support (--float_support)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.FLOAT_SUPPORT" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.FLOAT_SUPPORT._none" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ABI.901458990" name="Application binary interface (tiabi, ti_arm9_abi, eabi) (--abi)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ABI.eabi" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ENUM_TYPE.1247828011" name="Designate enum type (Default is packed for EABI) (--enum_type)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ENUM_TYPE" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ENUM_TYPE.packed" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.LITTLE_ENDIAN.1062648374" name="Little endian code (--little_endian, -me)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.LITTLE_ENDIAN" value="true" valueType="boolean"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.OPT_LEVEL.704079957" name="Optimization level (--opt_level, -O)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.OPT_LEVEL" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.OPT_LEVEL.3" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DEBUGGING_MODEL.1844493246" name="Debugging model" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.INCLUDE_PATH.103913639" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.INCLUDE_PATH" valueType="includePath">\r
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/demo}""/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/os}""/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/startup}""/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DIAG_WARNING.269144842" name="Treat diagnostic <id> as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DIAG_WARNING" valueType="stringList">\r
+ <listOptionValue builtIn="false" value="225"/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DISPLAY_ERROR_NUMBER.135924003" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__C_SRCS.147863472" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__C_SRCS"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__CPP_SRCS.44313954" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__CPP_SRCS"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM_SRCS.1138240635" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM_SRCS"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM2_SRCS.472900198" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM2_SRCS"/>\r
+ </tool>\r
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerDebug.1702479053" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerDebug">\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.OUTPUT_FILE.388311302" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.OUTPUT_FILE" value=""${ProjName}.out"" valueType="string"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.STACK_SIZE.281008610" name="Set C system stack size (--stack_size, -stack)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.STACK_SIZE" value="0" valueType="string"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.MAP_FILE.621729312" name="Input and output sections listed into <file> (--map_file, -m)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.MAP_FILE" value=""${ProjName}.map"" valueType="string"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.HEAP_SIZE.1208137669" name="Heap size for C/C++ dynamic memory allocation (--heap_size, -heap)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.HEAP_SIZE" value="4096" valueType="string"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.SEARCH_PATH.1264252191" name="Add <dir> to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.SEARCH_PATH" valueType="stringList">\r
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/lib""/>\r
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.DISPLAY_ERROR_NUMBER.1175489283" name="Emit diagnostic identifier numbers (--display_error_number)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.LIBRARY.1560618069" name="Include library file or command file as input (--library, -l)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.LIBRARY" valueType="libs">\r
+ <listOptionValue builtIn="false" value=""libc.a""/>\r
+ </option>\r
+ </tool>\r
+ </toolChain>\r
+ </folderInfo>\r
+ <fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Debug.580416121.sys_link.cmd" name="sys_link.cmd" rcbsApplicability="disable" resourcePath="sys_link.cmd" toolsToInvoke="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerDebug.1702479053.560971072">\r
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerDebug.1702479053.560971072" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerDebug.1702479053"/>\r
+ </fileInfo>\r
+ <sourceEntries>\r
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>\r
+ </sourceEntries>\r
+ </configuration>\r
+ </storageModule>\r
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>\r
+ </cconfiguration>\r
+ <cconfiguration id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1557389116">\r
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1557389116" moduleId="org.eclipse.cdt.core.settings" name="Release">\r
+ <externalSettings/>\r
+ <extensions>\r
+ <extension id="com.ti.ccstudio.binaryparser.CoffParser" point="org.eclipse.cdt.core.BinaryParser"/>\r
+ <extension id="com.ti.ccstudio.errorparser.CoffErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+ <extension id="com.ti.ccstudio.errorparser.LinkErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+ <extension id="com.ti.ccstudio.errorparser.AsmErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+ </extensions>\r
+ </storageModule>\r
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+ <configuration artifactExtension="out" artifactName="${ProjName}" buildProperties="" cleanCommand="${CG_CLEAN_CMD}" description="" id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1557389116" name="Release" parent="com.ti.ccstudio.buildDefinitions.TMS470.Release">\r
+ <folderInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1557389116." name="/" resourcePath="">\r
+ <toolChain id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.ReleaseToolchain.1510001903" name="TI Build Tools" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.ReleaseToolchain" targetTool="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerRelease.1567342118">\r
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS.266621205" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_TAGS" valueType="stringList">\r
+ <listOptionValue builtIn="false" value="DEVICE_CONFIGURATION_ID=Cortex R.RM48L952"/>\r
+ <listOptionValue builtIn="false" value="DEVICE_ENDIANNESS=little"/>\r
+ <listOptionValue builtIn="false" value="OUTPUT_FORMAT=ELF"/>\r
+ <listOptionValue builtIn="false" value="CCS_MBS_VERSION=5.1.0.01"/>\r
+ <listOptionValue builtIn="false" value="RUNTIME_SUPPORT_LIBRARY=rtsv7R4_T_le_v3D16_eabi.lib"/>\r
+ <listOptionValue builtIn="false" value="OUTPUT_TYPE=executable"/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1859769006" name="Compiler version" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="4.9.5" valueType="string"/>\r
+ <targetPlatform id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.targetPlatformRelease.1886854345" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.targetPlatformRelease"/>\r
+ <builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.builderRelease.2092310904" keepEnvironmentInBuildfile="false" name="GNU Make" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.builderRelease"/>\r
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.compilerRelease.709121230" name="ARM Compiler" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.compilerRelease">\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.CODE_STATE.856988966" name="Designate code state, 16-bit (thumb) or 32-bit (--code_state)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.CODE_STATE" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.CODE_STATE.32" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.SILICON_VERSION.1200799451" name="Target processor version (--silicon_version, -mv)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.SILICON_VERSION.7R4" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.FLOAT_SUPPORT.563519534" name="Specify floating point support (--float_support)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.FLOAT_SUPPORT" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.FLOAT_SUPPORT.VFPv3D16" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ABI.984902156" name="Application binary interface (tiabi, ti_arm9_abi, eabi) (--abi)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ABI" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ABI.eabi" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ENUM_TYPE.1806392852" name="Designate enum type (Default is packed for EABI) (--enum_type)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ENUM_TYPE" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.ENUM_TYPE.packed" valueType="enumerated"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DIAG_WARNING.292806785" name="Treat diagnostic <id> as warning (--diag_warning, -pdsw)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DIAG_WARNING" valueType="stringList">\r
+ <listOptionValue builtIn="false" value="225"/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DISPLAY_ERROR_NUMBER.560946167" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.INCLUDE_PATH.1735407543" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.INCLUDE_PATH" valueType="includePath">\r
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.LITTLE_ENDIAN.411357638" name="Little endian code (--little_endian, -me)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.LITTLE_ENDIAN" value="true" valueType="boolean"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__C_SRCS.1274560082" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__C_SRCS"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__CPP_SRCS.1267997378" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__CPP_SRCS"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM_SRCS.305910033" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM_SRCS"/>\r
+ <inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM2_SRCS.1606352786" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM2_SRCS"/>\r
+ </tool>\r
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerRelease.1567342118" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerRelease">\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.OUTPUT_FILE.1993234820" name="Specify output file name (--output_file, -o)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.OUTPUT_FILE" value=""${ProjName}.out"" valueType="string"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.MAP_FILE.2106964463" name="Input and output sections listed into <file> (--map_file, -m)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.MAP_FILE" value=""${ProjName}.map"" valueType="string"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.DISPLAY_ERROR_NUMBER.1672298509" name="Emit diagnostic identifier numbers (--display_error_number)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.SEARCH_PATH.815216306" name="Add <dir> to library search path (--search_path, -i)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.SEARCH_PATH" valueType="stringList">\r
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/lib""/>\r
+ <listOptionValue builtIn="false" value=""${CG_TOOL_ROOT}/include""/>\r
+ </option>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.LIBRARY.255790447" name="Include library file or command file as input (--library, -l)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.linkerID.LIBRARY" valueType="libs">\r
+ <listOptionValue builtIn="false" value=""rtsv7R4_T_le_v3D16_eabi.lib""/>\r
+ </option>\r
+ </tool>\r
+ </toolChain>\r
+ </folderInfo>\r
+ <fileInfo id="com.ti.ccstudio.buildDefinitions.TMS470.Release.1557389116.sys_link.cmd" name="sys_link.cmd" rcbsApplicability="disable" resourcePath="sys_link.cmd" toolsToInvoke="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerRelease.1567342118.725136841">\r
+ <tool id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerRelease.1567342118.725136841" name="ARM Linker" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.exe.linkerRelease.1567342118"/>\r
+ <tool customBuildStep="true" id="org.eclipse.cdt.managedbuilder.ui.rcbs.1742732949" name="Resource Custom Build Step">\r
+ <inputType id="org.eclipse.cdt.managedbuilder.ui.rcbs.inputtype.113483468" name="Resource Custom Build Step Input Type">\r
+ <additionalInput kind="additionalinputdependency" paths=""/>\r
+ </inputType>\r
+ <outputType id="org.eclipse.cdt.managedbuilder.ui.rcbs.outputtype.223114845" name="Resource Custom Build Step Output Type"/>\r
+ </tool>\r
+ </fileInfo>\r
+ <sourceEntries>\r
+ <entry excluding="sys_link.cmd" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>\r
+ </sourceEntries>\r
+ </configuration>\r
+ </storageModule>\r
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>\r
+ </cconfiguration>\r
+ </storageModule>\r
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+ <project id="FreeRTOS-RM48.com.ti.ccstudio.buildDefinitions.TMS470.ProjectType.470036695" name="ARM" projectType="com.ti.ccstudio.buildDefinitions.TMS470.ProjectType"/>\r
+ </storageModule>\r
+ <storageModule moduleId="scannerConfiguration"/>\r
+ <storageModule moduleId="org.eclipse.cdt.core.language.mapping">\r
+ <project-mappings>\r
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.asmSource" language="com.ti.ccstudio.core.TIASMLanguage"/>\r
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cHeader" language="com.ti.ccstudio.core.TIGCCLanguage"/>\r
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cSource" language="com.ti.ccstudio.core.TIGCCLanguage"/>\r
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxHeader" language="com.ti.ccstudio.core.TIGPPLanguage"/>\r
+ <content-type-mapping configuration="" content-type="org.eclipse.cdt.core.cxxSource" language="com.ti.ccstudio.core.TIGPPLanguage"/>\r
+ </project-mappings>\r
+ </storageModule>\r
+ <storageModule moduleId="refreshScope"/>\r
+</cproject>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>FreeRTOS-RM48</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>\r
+ <arguments>\r
+ <dictionary>\r
+ <key>?name?</key>\r
+ <value></value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.append_environment</key>\r
+ <value>true</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.autoBuildTarget</key>\r
+ <value>all</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.buildArguments</key>\r
+ <value>-k</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.buildCommand</key>\r
+ <value>${CCS_UTILS_DIR}/bin/gmake</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.buildLocation</key>\r
+ <value>${BuildDirectory}</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>\r
+ <value>clean</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.contents</key>\r
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>\r
+ <value>true</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>\r
+ <value>true</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>\r
+ <value>true</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.fullBuildTarget</key>\r
+ <value>all</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.stopOnError</key>\r
+ <value>false</value>\r
+ </dictionary>\r
+ <dictionary>\r
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>\r
+ <value>true</value>\r
+ </dictionary>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>\r
+ <triggers>full,incremental,</triggers>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>com.ti.ccstudio.core.ccsNature</nature>\r
+ <nature>org.eclipse.cdt.core.cnature</nature>\r
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>\r
+ <nature>org.eclipse.cdt.core.ccnature</nature>\r
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+eclipse.preferences.version=1\r
+inEditor=false\r
+onBuild=false\r
--- /dev/null
+eclipse.preferences.version=1\r
+org.eclipse.cdt.debug.core.toggleBreakpointModel=com.ti.ccstudio.debug.CCSBreakpointMarker\r
--- /dev/null
+eclipse.preferences.version=1\r
+encoding//Debug/demo/subdir_rules.mk=UTF-8\r
+encoding//Debug/demo/subdir_vars.mk=UTF-8\r
+encoding//Debug/makefile=UTF-8\r
+encoding//Debug/objects.mk=UTF-8\r
+encoding//Debug/os/subdir_rules.mk=UTF-8\r
+encoding//Debug/os/subdir_vars.mk=UTF-8\r
+encoding//Debug/sources.mk=UTF-8\r
+encoding//Debug/startup/subdir_rules.mk=UTF-8\r
+encoding//Debug/startup/subdir_vars.mk=UTF-8\r
+encoding//Debug/subdir_rules.mk=UTF-8\r
+encoding//Debug/subdir_vars.mk=UTF-8\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<configurations XML_version="1.2" id="configurations_0">\r
+ <configuration XML_version="1.2" id="configuration_0">\r
+ <instance XML_version="1.2" desc="Texas Instruments XDS100v2 USB Emulator" href="connections/TIXDS100v2_Connection.xml" id="Texas Instruments XDS100v2 USB Emulator" xml="TIXDS100v2_Connection.xml" xmlpath="connections"/>\r
+ <connection XML_version="1.2" id="Texas Instruments XDS100v2 USB Emulator">\r
+ <instance XML_version="1.2" href="drivers/tixds100v2icepick_c.xml" id="drivers" xml="tixds100v2icepick_c.xml" xmlpath="drivers"/>\r
+ <instance XML_version="1.2" href="drivers/tixds100v2cs_dap.xml" id="drivers" xml="tixds100v2cs_dap.xml" xmlpath="drivers"/>\r
+ <instance XML_version="1.2" href="drivers/tixds100v2cortexR.xml" id="drivers" xml="tixds100v2cortexR.xml" xmlpath="drivers"/>\r
+ <platform XML_version="1.2" id="platform_0">\r
+ <instance XML_version="1.2" desc="RM48L950" href="devices/rm48l950.xml" id="RM48L950" xml="rm48l950.xml" xmlpath="devices"/>\r
+ </platform>\r
+ </connection>\r
+ </configuration>\r
+</configurations>\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+\r
+/* \r
+ * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - \r
+ * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and \r
+ * mutex behaviour. \r
+ *\r
+ * See the comments above the prvSendFrontAndBackTest() and \r
+ * prvLowPriorityMutexTask() prototypes below for more information.\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* Demo program include files. */\r
+#include "GenQTest.h"\r
+\r
+#define genqQUEUE_LENGTH ( 5 )\r
+#define genqNO_BLOCK ( 0 )\r
+\r
+#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY )\r
+#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()\r
+ * macros by using both to fill a queue, then reading from the queue to\r
+ * check the resultant queue order is as expected. Queue data is also\r
+ * peeked.\r
+ */\r
+static void prvSendFrontAndBackTest( void *pvParameters );\r
+\r
+/*\r
+ * The following three tasks are used to demonstrate the mutex behaviour.\r
+ * Each task is given a different priority to demonstrate the priority\r
+ * inheritance mechanism.\r
+ *\r
+ * The low priority task obtains a mutex. After this a high priority task\r
+ * attempts to obtain the same mutex, causing its priority to be inherited\r
+ * by the low priority task. The task with the inherited high priority then\r
+ * resumes a medium priority task to ensure it is not blocked by the medium\r
+ * priority task while it holds the inherited high priority. Once the mutex\r
+ * is returned the task with the inherited priority returns to its original\r
+ * low priority, and is therefore immediately preempted by first the high\r
+ * priority task and then the medium prioroity task before it can continue.\r
+ */\r
+static void prvLowPriorityMutexTask( void *pvParameters );\r
+static void prvMediumPriorityMutexTask( void *pvParameters );\r
+static void prvHighPriorityMutexTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
+detected in any of the tasks. */\r
+static portBASE_TYPE xErrorDetected = pdFALSE;\r
+\r
+/* Counters that are incremented on each cycle of a test. This is used to\r
+detect a stalled task - a test that is no longer running. */\r
+static volatile unsigned portLONG ulLoopCounter = 0;\r
+static volatile unsigned portLONG ulLoopCounter2 = 0;\r
+\r
+/* The variable that is guarded by the mutex in the mutex demo tasks. */\r
+static volatile unsigned portLONG ulGuardedVariable = 0;\r
+\r
+/* Handles used in the mutext test to suspend and resume the high and medium\r
+priority mutex test tasks. */\r
+static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+xQueueHandle xQueue;\r
+xSemaphoreHandle xMutex;\r
+\r
+ /* Create the queue that we are going to use for the\r
+ prvSendFrontAndBackTest demo. */\r
+ xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );\r
+\r
+ /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+ in use. The queue registry is provided as a means for kernel aware \r
+ debuggers to locate queues and has no purpose if a kernel aware debugger\r
+ is not being used. The call to vQueueAddToRegistry() will be removed\r
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
+ defined to be less than 1. */\r
+ vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" );\r
+\r
+ /* Create the demo task and pass it the queue just created. We are\r
+ passing the queue handle by value so it does not matter that it is\r
+ declared on the stack here. */\r
+ xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );\r
+\r
+ /* Create the mutex used by the prvMutexTest task. */\r
+ xMutex = xSemaphoreCreateMutex();\r
+\r
+ /* vQueueAddToRegistry() adds the mutex to the registry, if one is\r
+ in use. The registry is provided as a means for kernel aware \r
+ debuggers to locate mutexes and has no purpose if a kernel aware debugger\r
+ is not being used. The call to vQueueAddToRegistry() will be removed\r
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
+ defined to be less than 1. */\r
+ vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Gen_Queue_Mutex" );\r
+\r
+ /* Create the mutex demo tasks and pass it the mutex just created. We are\r
+ passing the mutex handle by value so it does not matter that it is declared\r
+ on the stack here. */\r
+ xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );\r
+ xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );\r
+ xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSendFrontAndBackTest( void *pvParameters )\r
+{\r
+unsigned portLONG ulData, ulData2;\r
+xQueueHandle xQueue;\r
+\r
+ #ifdef USE_STDIO\r
+ void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+ \r
+ const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";\r
+\r
+ /* Queue a message for printing to say the task has started. */\r
+ vPrintDisplayMessage( &pcTaskStartMsg );\r
+ #endif\r
+\r
+ xQueue = ( xQueueHandle ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* The queue is empty, so sending an item to the back of the queue\r
+ should have the same efect as sending it to the front of the queue.\r
+\r
+ First send to the front and check everything is as expected. */\r
+ xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+ if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* The data we sent to the queue should equal the data we just received\r
+ from the queue. */\r
+ if( ulLoopCounter != ulData )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Then do the same, sending the data to the back, checking everything\r
+ is as expected. */\r
+ if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+ if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* The data we sent to the queue should equal the data we just received\r
+ from the queue. */\r
+ if( ulLoopCounter != ulData )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+\r
+\r
+ /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */\r
+ for( ulData = 2; ulData < 5; ulData++ )\r
+ {\r
+ xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+ }\r
+\r
+ /* Now the order in the queue should be 2, 3, 4, with 2 being the first\r
+ thing to be read out. Now add 1 then 0 to the front of the queue. */\r
+ if( uxQueueMessagesWaiting( xQueue ) != 3 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+ ulData = 1;\r
+ xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+ ulData = 0;\r
+ xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+\r
+ /* Now the queue should be full, and when we read the data out we\r
+ should receive 0, 1, 2, 3, 4. */\r
+ if( uxQueueMessagesWaiting( xQueue ) != 5 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ /* Check the data we read out is in the expected order. */\r
+ for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )\r
+ {\r
+ /* Try peeking the data first. */\r
+ if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( ulData != ulData2 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+ \r
+\r
+ /* Now try receiving the data for real. The value should be the\r
+ same. Clobber the value first so we know we really received it. */\r
+ ulData2 = ~ulData2;\r
+ if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( ulData != ulData2 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+ }\r
+\r
+ /* The queue should now be empty again. */\r
+ if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+\r
+ /* Our queue is empty once more, add 10, 11 to the back. */\r
+ ulData = 10;\r
+ if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+ ulData = 11;\r
+ if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( uxQueueMessagesWaiting( xQueue ) != 2 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the\r
+ front. */\r
+ for( ulData = 9; ulData >= 7; ulData-- )\r
+ {\r
+ if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+ }\r
+\r
+ /* Now check that the queue is full, and that receiving data provides\r
+ the expected sequence of 7, 8, 9, 10, 11. */\r
+ if( uxQueueMessagesWaiting( xQueue ) != 5 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ /* Check the data we read out is in the expected order. */\r
+ for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )\r
+ {\r
+ if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( ulData != ulData2 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+ }\r
+\r
+ if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ ulLoopCounter++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowPriorityMutexTask( void *pvParameters )\r
+{\r
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+\r
+ #ifdef USE_STDIO\r
+ void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+ \r
+ const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";\r
+\r
+ /* Queue a message for printing to say the task has started. */\r
+ vPrintDisplayMessage( &pcTaskStartMsg );\r
+ #endif\r
+\r
+ for( ;; )\r
+ {\r
+ /* Take the mutex. It should be available now. */\r
+ if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Set our guarded variable to a known start value. */\r
+ ulGuardedVariable = 0;\r
+\r
+ /* Our priority should be as per that assigned when the task was\r
+ created. */\r
+ if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Now unsuspend the high priority task. This will attempt to take the\r
+ mutex, and block when it finds it cannot obtain it. */\r
+ vTaskResume( xHighPriorityMutexTask );\r
+\r
+ /* We should now have inherited the prioritoy of the high priority task,\r
+ as by now it will have attempted to get the mutex. */\r
+ if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* We can attempt to set our priority to the test priority - between the\r
+ idle priority and the medium/high test priorities, but our actual\r
+ prioroity should remain at the high priority. */\r
+ vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );\r
+ if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Now unsuspend the medium priority task. This should not run as our\r
+ inherited priority is above that of the medium priority task. */\r
+ vTaskResume( xMediumPriorityMutexTask );\r
+\r
+ /* If the did run then it will have incremented our guarded variable. */\r
+ if( ulGuardedVariable != 0 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* When we give back the semaphore our priority should be disinherited\r
+ back to the priority to which we attempted to set ourselves. This means\r
+ that when the high priority task next blocks, the medium priority task\r
+ should execute and increment the guarded variable. When we next run\r
+ both the high and medium priority tasks will have been suspended again. */\r
+ if( xSemaphoreGive( xMutex ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Check that the guarded variable did indeed increment... */\r
+ if( ulGuardedVariable != 1 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* ... and that our priority has been disinherited to\r
+ genqMUTEX_TEST_PRIORITY. */\r
+ if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* Set our priority back to our original priority ready for the next\r
+ loop around this test. */\r
+ vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );\r
+\r
+ /* Just to show we are still running. */\r
+ ulLoopCounter2++;\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif \r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMediumPriorityMutexTask( void *pvParameters )\r
+{\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* The medium priority task starts by suspending itself. The low\r
+ priority task will unsuspend this task when required. */\r
+ vTaskSuspend( NULL );\r
+\r
+ /* When this task unsuspends all it does is increment the guarded\r
+ variable, this is so the low priority task knows that it has\r
+ executed. */\r
+ ulGuardedVariable++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHighPriorityMutexTask( void *pvParameters )\r
+{\r
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* The high priority task starts by suspending itself. The low\r
+ priority task will unsuspend this task when required. */\r
+ vTaskSuspend( NULL );\r
+\r
+ /* When this task unsuspends all it does is attempt to obtain\r
+ the mutex. It should find the mutex is not available so a\r
+ block time is specified. */\r
+ if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* When we eventually obtain the mutex we just give it back then\r
+ return to suspend ready for the next test. */\r
+ if( xSemaphoreGive( xMutex ) != pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ } \r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void )\r
+{\r
+static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;\r
+\r
+ /* If the demo task is still running then we expect the loopcounters to\r
+ have incremented since this function was last called. */\r
+ if( ulLastLoopCounter == ulLoopCounter )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ if( ulLastLoopCounter2 == ulLoopCounter2 )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ ulLastLoopCounter = ulLoopCounter;\r
+ ulLastLoopCounter2 = ulLoopCounter2; \r
+\r
+ /* Errors detected in the task itself will have latched xErrorDetected\r
+ to true. */\r
+\r
+ return !xErrorDetected;\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef GEN_Q_TEST_H\r
+#define GEN_Q_TEST_H\r
+\r
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void );\r
+\r
+#endif /* GEN_Q_TEST_H */\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+\r
+/*\r
+ * Tests the behaviour of timers. Some timers are created before the scheduler\r
+ * is started, and some after.\r
+ */\r
+\r
+/* Standard includes. */\r
+#include <string.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "timers.h"\r
+\r
+/* Demo program include files. */\r
+#include "TimerDemo.h"\r
+\r
+#if ( configTIMER_TASK_PRIORITY < 1 )\r
+ #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly.\r
+#endif\r
+\r
+#define tmrdemoDONT_BLOCK ( ( portTickType ) 0 )\r
+#define tmrdemoONE_SHOT_TIMER_PERIOD ( xBasePeriod * ( portTickType ) 3 )\r
+#define trmdemoNUM_TIMER_RESETS ( ( unsigned char ) 10 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The callback functions used by the timers. These each increment a counter\r
+to indicate which timer has expired. The auto-reload timers that are used by\r
+the test task (as opposed to being used from an ISR) all share the same\r
+prvAutoReloadTimerCallback() callback function, and use the ID of the\r
+pxExpiredTimer parameter passed into that function to know which counter to\r
+increment. The other timers all have their own unique callback function and\r
+simply increment their counters without using the callback function parameter. */\r
+static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer );\r
+static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer );\r
+static void prvTimerTestTask( void *pvParameters );\r
+static void prvISRAutoReloadTimerCallback( xTimerHandle pxExpiredTimer );\r
+static void prvISROneShotTimerCallback( xTimerHandle pxExpiredTimer );\r
+\r
+/* The test functions used by the timer test task. These manipulate the auto\r
+reload and one shot timers in various ways, then delay, then inspect the timers\r
+to ensure they have behaved as expected. */\r
+static void prvTest1_CreateTimersWithoutSchedulerRunning( void );\r
+static void prvTest2_CheckTaskAndTimersInitialState( void );\r
+static void prvTest3_CheckAutoReloadExpireRates( void );\r
+static void prvTest4_CheckAutoReloadTimersCanBeStopped( void );\r
+static void prvTest5_CheckBasicOneShotTimerBehaviour( void );\r
+static void prvTest6_CheckAutoReloadResetBehaviour( void );\r
+static void prvResetStartConditionsForNextIteration( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdFAIL should any unexpected behaviour be\r
+detected in any of the demo tests. */\r
+static volatile portBASE_TYPE xTestStatus = pdPASS;\r
+\r
+/* Counter that is incremented on each cycle of a test. This is used to\r
+detect a stalled task - a test that is no longer running. */\r
+static volatile unsigned long ulLoopCounter = 0;\r
+\r
+/* A set of auto reload timers - each of which use the same callback function.\r
+The callback function uses the timer ID to index into, and then increment, a\r
+counter in the ucAutoReloadTimerCounters[] array. The auto reload timers\r
+referenced from xAutoReloadTimers[] are used by the prvTimerTestTask task. */\r
+static xTimerHandle xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
+static unsigned char ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
+\r
+/* The one shot timer is configured to use a callback function that increments\r
+ucOneShotTimerCounter each time it gets called. */\r
+static xTimerHandle xOneShotTimer = NULL;\r
+static unsigned char ucOneShotTimerCounter = ( unsigned char ) 0;\r
+\r
+/* The ISR reload timer is controlled from the tick hook to exercise the timer\r
+API functions that can be used from an ISR. It is configured to increment\r
+ucISRReloadTimerCounter each time its callback function is executed. */\r
+static xTimerHandle xISRAutoReloadTimer = NULL;\r
+static unsigned char ucISRAutoReloadTimerCounter = ( unsigned char ) 0;\r
+\r
+/* The ISR one shot timer is controlled from the tick hook to exercise the timer\r
+API functions that can be used from an ISR. It is configured to increment\r
+ucISRReloadTimerCounter each time its callback function is executed. */\r
+static xTimerHandle xISROneShotTimer = NULL;\r
+static unsigned char ucISROneShotTimerCounter = ( unsigned char ) 0;\r
+\r
+/* The period of all the timers are a multiple of the base period. The base\r
+period is configured by the parameter to vStartTimerDemoTask(). */\r
+static portTickType xBasePeriod = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartTimerDemoTask( portTickType xBasePeriodIn )\r
+{\r
+ /* Start with the timer and counter arrays clear - this is only necessary\r
+ where the compiler does not clear them automatically on start up. */\r
+ memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) );\r
+ memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) );\r
+\r
+ /* Store the period from which all the timer periods will be generated from\r
+ (multiples of). */\r
+ xBasePeriod = xBasePeriodIn;\r
+\r
+ /* Create a set of timers for use by this demo/test. */\r
+ prvTest1_CreateTimersWithoutSchedulerRunning();\r
+\r
+ /* Create the task that will control and monitor the timers. This is\r
+ created at a lower priority than the timer service task to ensure, as\r
+ far as it is concerned, commands on timers are actioned immediately\r
+ (sending a command to the timer service task will unblock the timer service\r
+ task, which will then preempt this task). */\r
+ if( xTestStatus != pdFAIL )\r
+ {\r
+ xTaskCreate( prvTimerTestTask, ( signed portCHAR * ) "Tmr Tst", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTimerTestTask( void *pvParameters )\r
+{\r
+ ( void ) pvParameters;\r
+\r
+ /* Create a one-shot timer for use later on in this test. */\r
+ xOneShotTimer = xTimerCreate( ( const signed char * ) "Oneshot Timer",/* Text name to facilitate debugging. The kernel does not use this itself. */\r
+ tmrdemoONE_SHOT_TIMER_PERIOD, /* The period for the timer. */\r
+ pdFALSE, /* Don't auto-reload - hence a one shot timer. */\r
+ ( void * ) 0, /* The timer identifier. In this case this is not used as the timer has its own callback. */\r
+ prvOneShotTimerCallback ); /* The callback to be called when the timer expires. */\r
+\r
+ if( xOneShotTimer == NULL )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+\r
+ /* Ensure all the timers are in their expected initial state. This\r
+ depends on the timer service task having a higher priority than this task. */\r
+ prvTest2_CheckTaskAndTimersInitialState();\r
+\r
+ for( ;; )\r
+ {\r
+ /* Check the auto reload timers expire at the expected/correct rates. */\r
+ prvTest3_CheckAutoReloadExpireRates();\r
+\r
+ /* Check the auto reload timers can be stopped correctly, and correctly\r
+ report their state. */\r
+ prvTest4_CheckAutoReloadTimersCanBeStopped();\r
+ \r
+ /* Check the one shot timer only calls its callback once after it has been\r
+ started, and that it reports its state correctly. */\r
+ prvTest5_CheckBasicOneShotTimerBehaviour();\r
+\r
+ /* Check timer reset behaviour. */\r
+ prvTest6_CheckAutoReloadResetBehaviour();\r
+\r
+ /* Start the timers again to restart all the tests over again. */\r
+ prvResetStartConditionsForNextIteration();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that the created task is still running and has not\r
+detected any errors. */\r
+portBASE_TYPE xAreTimerDemoTasksStillRunning( portTickType xCycleFrequency )\r
+{\r
+static unsigned long ulLastLoopCounter = 0UL;\r
+portTickType xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax;\r
+static portTickType xIterationsWithoutCounterIncrement = ( portTickType ) 0, xLastCycleFrequency;\r
+\r
+ if( xLastCycleFrequency != xCycleFrequency )\r
+ {\r
+ /* The cycle frequency has probably become much faster due to an error\r
+ elsewhere. Start counting Iterations again. */\r
+ xIterationsWithoutCounterIncrement = ( portTickType ) 0;\r
+ xLastCycleFrequency = xCycleFrequency;\r
+ } \r
+\r
+ /* Calculate the maximum number of times that it is permissible for this\r
+ function to be called without ulLoopCounter being incremented. This is\r
+ necessary because the tests in this file block for extended periods, and the\r
+ block period might be longer than the time between calls to this function. */\r
+ xMaxBlockTimeUsedByTheseTests = ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;\r
+ xLoopCounterIncrementTimeMax = xMaxBlockTimeUsedByTheseTests / xCycleFrequency;\r
+\r
+ /* If the demo task is still running then we expect the loopcounter to\r
+ have incremented every xLoopCounterIncrementTimeMax calls. */\r
+ if( ulLastLoopCounter == ulLoopCounter )\r
+ {\r
+ xIterationsWithoutCounterIncrement++;\r
+ if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax )\r
+ {\r
+ /* The tests appear to be no longer running (stalled). */\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* ulLoopCounter changed, so the count of times this function was called\r
+ without a change can be reset to zero. */\r
+ xIterationsWithoutCounterIncrement = ( portTickType ) 0;\r
+ }\r
+\r
+ ulLastLoopCounter = ulLoopCounter;\r
+\r
+ /* Errors detected in the task itself will have latched xTestStatus\r
+ to pdFAIL. */\r
+\r
+ return xTestStatus;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTest1_CreateTimersWithoutSchedulerRunning( void )\r
+{\r
+unsigned portBASE_TYPE xTimer;\r
+\r
+ for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ )\r
+ {\r
+ /* As the timer queue is not yet full, it should be possible to both create\r
+ and start a timer. These timers are being started before the scheduler has\r
+ been started, so their block times should get set to zero within the timer\r
+ API itself. */\r
+ xAutoReloadTimers[ xTimer ] = xTimerCreate( ( const signed char * )"FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */\r
+ ( ( xTimer + ( portTickType ) 1 ) * xBasePeriod ),/* The period for the timer. The plus 1 ensures a period of zero is not specified. */\r
+ pdTRUE, /* Auto-reload is set to true. */\r
+ ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */\r
+ prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */\r
+\r
+ if( xAutoReloadTimers[ xTimer ] == NULL )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ else\r
+ {\r
+ /* The scheduler has not yet started, so the block period of\r
+ portMAX_DELAY should just get set to zero in xTimerStart(). Also,\r
+ the timer queue is not yet full so xTimerStart() should return\r
+ pdPASS. */\r
+ if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ }\r
+\r
+ /* The timers queue should now be full, so it should be possible to create\r
+ another timer, but not possible to start it (the timer queue will not get\r
+ drained until the scheduler has been started. */\r
+ xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( ( const signed char * ) "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */\r
+ ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */\r
+ pdTRUE, /* Auto-reload is set to true. */\r
+ ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */\r
+ prvAutoReloadTimerCallback ); /* The callback executed when the timer expires. */\r
+\r
+ if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ else\r
+ {\r
+ if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS )\r
+ {\r
+ /* This time it would not be expected that the timer could be\r
+ started at this point. */\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ \r
+ /* Create the timers that are used from the tick interrupt to test the timer\r
+ API functions that can be called from an ISR. */\r
+ xISRAutoReloadTimer = xTimerCreate( ( const signed char * ) "ISR AR", /* The text name given to the timer. */\r
+ 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */\r
+ pdTRUE, /* This is an auto reload timer. */\r
+ ( void * ) NULL, /* The identifier is not required. */\r
+ prvISRAutoReloadTimerCallback ); /* The callback that is executed when the timer expires. */\r
+\r
+ xISROneShotTimer = xTimerCreate( ( const signed char * ) "ISR OS", /* The text name given to the timer. */\r
+ 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */\r
+ pdFALSE, /* This is a one shot timer. */\r
+ ( void * ) NULL, /* The identifier is not required. */\r
+ prvISROneShotTimerCallback ); /* The callback that is executed when the timer expires. */\r
+ \r
+ if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTest2_CheckTaskAndTimersInitialState( void )\r
+{\r
+unsigned char ucTimer;\r
+\r
+ /* Ensure all the timers are in their expected initial state. This depends\r
+ on the timer service task having a higher priority than this task.\r
+\r
+ auto reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active,\r
+ and auto reload timer configTIMER_QUEUE_LENGTH should not yet be active (it\r
+ could not be started prior to the scheduler being started when it was\r
+ created). */\r
+ for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+ {\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTest3_CheckAutoReloadExpireRates( void )\r
+{\r
+unsigned char ucMaxAllowableValue, ucMinAllowableValue, ucTimer;\r
+portTickType xBlockPeriod, xTimerPeriod, xExpectedNumber;\r
+\r
+ /* Check the auto reload timers expire at the expected rates. */\r
+\r
+ \r
+ /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow\r
+ all the auto reload timers to expire at least once. */\r
+ xBlockPeriod = ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;\r
+ vTaskDelay( xBlockPeriod );\r
+\r
+ /* Check that all the auto reload timers have called their callback \r
+ function the expected number of times. */\r
+ for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+ {\r
+ /* The expected number of expiries is equal to the block period divided\r
+ by the timer period. */\r
+ xTimerPeriod = ( ( ( portTickType ) ucTimer + ( portTickType ) 1 ) * xBasePeriod );\r
+ xExpectedNumber = xBlockPeriod / xTimerPeriod;\r
+ \r
+ ucMaxAllowableValue = ( ( unsigned char ) xExpectedNumber ) ;\r
+ ucMinAllowableValue = ( ( unsigned char ) xExpectedNumber - ( unsigned char ) 1 );\r
+\r
+ if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) ||\r
+ ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue )\r
+ )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+\r
+ if( xTestStatus == pdPASS )\r
+ {\r
+ /* No errors have been reported so increment the loop counter so the\r
+ check task knows this task is still running. */\r
+ ulLoopCounter++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTest4_CheckAutoReloadTimersCanBeStopped( void )\r
+{ \r
+unsigned char ucTimer;\r
+\r
+ /* Check the auto reload timers can be stopped correctly, and correctly\r
+ report their state. */\r
+\r
+ /* Stop all the active timers. */\r
+ for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+ {\r
+ /* The timer has not been stopped yet! */\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Now stop the timer. This will appear to happen immediately to\r
+ this task because this task is running at a priority below the\r
+ timer service task. */\r
+ xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
+\r
+ /* The timer should now be inactive. */\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* The timer in array position configTIMER_QUEUE_LENGTH should not\r
+ be active. The critical section is used to ensure the timer does\r
+ not call its callback between the next line running and the array\r
+ being cleared back to zero, as that would mask an error condition. */\r
+ if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( unsigned char ) 0 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Clear the timer callback count. */\r
+ memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) );\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* The timers are now all inactive, so this time, after delaying, none\r
+ of the callback counters should have incremented. */\r
+ vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
+ for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+ {\r
+ if( ucAutoReloadTimerCounters[ ucTimer ] != ( unsigned char ) 0 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+\r
+ if( xTestStatus == pdPASS )\r
+ {\r
+ /* No errors have been reported so increment the loop counter so\r
+ the check task knows this task is still running. */\r
+ ulLoopCounter++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTest5_CheckBasicOneShotTimerBehaviour( void )\r
+{\r
+ /* Check the one shot timer only calls its callback once after it has been\r
+ started, and that it reports its state correctly. */\r
+\r
+ /* The one shot timer should not be active yet. */\r
+ if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Start the one shot timer and check that it reports its state correctly. */\r
+ xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
+ if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Delay for three times as long as the one shot timer period, then check\r
+ to ensure it has only called its callback once, and is now not in the\r
+ active state. */\r
+ vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( portTickType ) 3 );\r
+\r
+ if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ else\r
+ {\r
+ /* Reset the one shot timer callback count. */\r
+ ucOneShotTimerCounter = ( unsigned char ) 0;\r
+ }\r
+\r
+ if( xTestStatus == pdPASS )\r
+ {\r
+ /* No errors have been reported so increment the loop counter so the\r
+ check task knows this task is still running. */\r
+ ulLoopCounter++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTest6_CheckAutoReloadResetBehaviour( void )\r
+{\r
+unsigned char ucTimer;\r
+\r
+ /* Check timer reset behaviour. */\r
+\r
+ /* Restart the one shot timer and check it reports its status correctly. */\r
+ xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
+ if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Restart one of the auto reload timers and check that it reports its\r
+ status correctly. */\r
+ xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ )\r
+ {\r
+ /* Delay for half as long as the one shot timer period, then reset it.\r
+ It should never expire while this is done, so its callback count should\r
+ never increment. */\r
+ vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 );\r
+\r
+ /* Check both running timers are still active, but have not called their\r
+ callback functions. */\r
+ if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( unsigned char ) 0 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Reset both running timers. */\r
+ xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK );\r
+ xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
+\r
+ if( xTestStatus == pdPASS )\r
+ {\r
+ /* No errors have been reported so increment the loop counter so\r
+ the check task knows this task is still running. */\r
+ ulLoopCounter++;\r
+ }\r
+ }\r
+\r
+ /* Finally delay long enough for both running timers to expire. */\r
+ vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
+\r
+ /* The timers were not reset during the above delay period so should now\r
+ both have called their callback functions. */\r
+ if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* The one shot timer should no longer be active, while the auto reload\r
+ timer should still be active. */\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Stop the auto reload timer again. */\r
+ xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
+\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Clear the timer callback counts, ready for another iteration of these\r
+ tests. */\r
+ ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( unsigned char ) 0;\r
+ ucOneShotTimerCounter = ( unsigned char ) 0;\r
+\r
+ if( xTestStatus == pdPASS )\r
+ {\r
+ /* No errors have been reported so increment the loop counter so the check\r
+ task knows this task is still running. */\r
+ ulLoopCounter++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvResetStartConditionsForNextIteration( void )\r
+{\r
+unsigned char ucTimer;\r
+\r
+ /* Start the timers again to start all the tests over again. */\r
+\r
+ /* Start the timers again. */\r
+ for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+ {\r
+ /* The timer has not been started yet! */\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+\r
+ /* Now start the timer. This will appear to happen immediately to\r
+ this task because this task is running at a priority below the timer\r
+ service task. */\r
+ xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
+\r
+ /* The timer should now be active. */\r
+ if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+\r
+ if( xTestStatus == pdPASS )\r
+ {\r
+ /* No errors have been reported so increment the loop counter so the\r
+ check task knows this task is still running. */\r
+ ulLoopCounter++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTimerPeriodicISRTests( void )\r
+{\r
+static portTickType uxTick = ( portTickType ) -1;\r
+\r
+/* The xHigherPriorityTaskWoken parameter is not used in this case as this\r
+function is called from the tick hook anyway. However the API required it\r
+to be present. */\r
+portBASE_TYPE xHigherPriorityTaskWoken = pdTRUE;\r
+portTickType xMargin;\r
+\r
+ if( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) )\r
+ {\r
+ /* The timer service task is not the highest priority task, so it cannot\r
+ be assumed that timings will be exact. Timers should never call their\r
+ callback before their expiry time, but a margin is permissible for calling\r
+ their callback after their expiry time. If exact timing is required then\r
+ configTIMER_TASK_PRIORITY must be set to ensure the timer service task\r
+ is the highest priority task in the system. */\r
+ xMargin = 5;\r
+ }\r
+ else\r
+ {\r
+ xMargin = 1;\r
+ }\r
+\r
+ /* This test is called from the tick ISR even when the scheduler is suspended.\r
+ Therefore, it is possible for the xTickCount to be temporarily less than the\r
+ uxTicks count maintained in this function. That can result in calculated\r
+ unblock times being too short, as this function is not called as missed ticks\r
+ (ticks that occur while the scheduler is suspended) are unwound to re-instate\r
+ the real tick value. Therefore, if this happens, just abandon the test\r
+ and start again. */\r
+ if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )\r
+ {\r
+ uxTick = ( portTickType ) -1;\r
+ }\r
+ else\r
+ {\r
+ uxTick++;\r
+ }\r
+\r
+ if( uxTick == 0 )\r
+ {\r
+ /* The timers will have been created, but not started. Start them\r
+ now by setting their period. */\r
+ ucISRAutoReloadTimerCounter = 0;\r
+ ucISROneShotTimerCounter = 0;\r
+ xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, &xHigherPriorityTaskWoken );\r
+ xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, &xHigherPriorityTaskWoken );\r
+ }\r
+ else if( uxTick == xBasePeriod )\r
+ {\r
+ /* Neither timer should have expired yet. */\r
+ if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ else if( uxTick == ( xBasePeriod + xMargin ) )\r
+ {\r
+ /* Both timers should now have expired once. The auto reload timer will\r
+ still be active, but the one shot timer should now have stopped. */\r
+ if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ else if( uxTick == ( 2 * xBasePeriod ) )\r
+ {\r
+ /* The auto reload timer will still be active, but the one shot timer\r
+ should now have stopped - however, at this time neither of the timers\r
+ should have expired again since the last test. */\r
+ if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ } \r
+ }\r
+ else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) )\r
+ {\r
+ /* The auto reload timer will still be active, but the one shot timer\r
+ should now have stopped. At this time the auto reload timer should have\r
+ expired again, but the one shot timer count should not have changed. */\r
+ if( ucISRAutoReloadTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 1 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( portTickType ) 2U ) ) )\r
+ {\r
+ /* The auto reload timer will still be active, but the one shot timer\r
+ should now have stopped. Again though, at this time, neither timer call\r
+ back should have been called since the last test. */\r
+ if( ucISRAutoReloadTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 1 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ } \r
+ else if( uxTick == ( 3 * xBasePeriod ) )\r
+ {\r
+ /* Start the one shot timer again. */\r
+ xTimerStartFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
+ }\r
+ else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) )\r
+ {\r
+ /* The auto reload timer and one shot timer will be active. At\r
+ this time the auto reload timer should have expired again, but the one\r
+ shot timer count should not have changed yet. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 1 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ /* Now stop the auto reload timer. The one shot timer was started\r
+ a few ticks ago. */\r
+ xTimerStopFromISR( xISRAutoReloadTimer, &xHigherPriorityTaskWoken );\r
+ } \r
+ else if( uxTick == ( 4 * xBasePeriod ) )\r
+ {\r
+ /* The auto reload timer is now stopped, and the one shot timer is\r
+ active, but at this time neither timer should have expired since the\r
+ last test. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 1 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ } \r
+ else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) )\r
+ {\r
+ /* The auto reload timer is now stopped, and the one shot timer is\r
+ active. The one shot timer should have expired again, but the auto\r
+ reload timer should not have executed its callback. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ } \r
+ else if( uxTick == ( ( 8 * xBasePeriod ) + xMargin ) )\r
+ {\r
+ /* The auto reload timer is now stopped, and the one shot timer has\r
+ already expired and then stopped itself. Both callback counters should\r
+ not have incremented since the last test. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ /* Now reset the one shot timer. */\r
+ xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
+ } \r
+ else if( uxTick == ( 9 * xBasePeriod ) )\r
+ {\r
+ /* Only the one shot timer should be running, but it should not have\r
+ expired since the last test. Check the callback counters have not\r
+ incremented, then reset the one shot timer again. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
+ } \r
+ else if( uxTick == ( 10 * xBasePeriod ) )\r
+ {\r
+ /* Only the one shot timer should be running, but it should not have\r
+ expired since the last test. Check the callback counters have not\r
+ incremented, then reset the one shot timer again. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
+ }\r
+ else if( uxTick == ( 11 * xBasePeriod ) )\r
+ {\r
+ /* Only the one shot timer should be running, but it should not have\r
+ expired since the last test. Check the callback counters have not\r
+ incremented, then reset the one shot timer once again. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 2 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
+ } \r
+ else if( uxTick == ( ( 12 * xBasePeriod ) + xMargin ) )\r
+ {\r
+ /* Only the one shot timer should have been running and this time it\r
+ should have expired. Check its callback count has been incremented.\r
+ The auto reload timer is still not running so should still have the same\r
+ count value. This time the one shot timer is not reset so should not\r
+ restart from its expiry period again. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ }\r
+ else if( uxTick == ( 15 * xBasePeriod ) )\r
+ {\r
+ /* Neither timer should be running now. Check neither callback count\r
+ has incremented, then go back to the start to run these tests all\r
+ over again. */\r
+ if( ucISRAutoReloadTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ if( ucISROneShotTimerCounter != 3 )\r
+ {\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+ \r
+ uxTick = ( portTickType ) -1;\r
+ } \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*** Timer callback functions are defined below here. ***/\r
+\r
+static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer )\r
+{\r
+portBASE_TYPE xTimerID;\r
+\r
+ xTimerID = ( portBASE_TYPE ) pvTimerGetTimerID( pxExpiredTimer );\r
+ if( xTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) )\r
+ {\r
+ ( ucAutoReloadTimerCounters[ xTimerID ] )++;\r
+ }\r
+ else\r
+ {\r
+ /* The timer ID appears to be unexpected (invalid). */\r
+ xTestStatus = pdFAIL;\r
+ configASSERT( xTestStatus );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer )\r
+{\r
+ /* The parameter is not used in this case as only one timer uses this\r
+ callback function. */\r
+ ( void ) pxExpiredTimer;\r
+\r
+ ucOneShotTimerCounter++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvISRAutoReloadTimerCallback( xTimerHandle pxExpiredTimer )\r
+{\r
+ /* The parameter is not used in this case as only one timer uses this\r
+ callback function. */\r
+ ( void ) pxExpiredTimer;\r
+\r
+ ucISRAutoReloadTimerCounter++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvISROneShotTimerCallback( xTimerHandle pxExpiredTimer )\r
+{\r
+ /* The parameter is not used in this case as only one timer uses this\r
+ callback function. */\r
+ ( void ) pxExpiredTimer;\r
+\r
+ ucISROneShotTimerCounter++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef TIMER_DEMO_H\r
+#define TIMER_DEMO_H\r
+\r
+void vStartTimerDemoTask( portTickType xBaseFrequencyIn );\r
+portBASE_TYPE xAreTimerDemoTasksStillRunning( portTickType xCycleFrequency );\r
+void vTimerPeriodicISRTests( void );\r
+\r
+#endif /* TIMER_DEMO_H */\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+\r
+/* \r
+ * Simple demonstration of the usage of counting semaphore.\r
+ */\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* Demo program include files. */\r
+#include "countsem.h"\r
+\r
+/* The maximum count value that the semaphore used for the demo can hold. */\r
+#define countMAX_COUNT_VALUE ( 200 )\r
+\r
+/* Constants used to indicate whether or not the semaphore should have been\r
+created with its maximum count value, or its minimum count value. These \r
+numbers are used to ensure that the pointers passed in as the task parameters\r
+are valid. */\r
+#define countSTART_AT_MAX_COUNT ( 0xaa )\r
+#define countSTART_AT_ZERO ( 0x55 )\r
+\r
+/* Two tasks are created for the test. One uses a semaphore created with its\r
+count value set to the maximum, and one with the count value set to zero. */\r
+#define countNUM_TEST_TASKS ( 2 )\r
+#define countDONT_BLOCK ( 0 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
+detected in any of the tasks. */\r
+static volatile portBASE_TYPE xErrorDetected = pdFALSE;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The demo task. This simply counts the semaphore up to its maximum value,\r
+ * the counts it back down again. The result of each semaphore 'give' and\r
+ * 'take' is inspected, with an error being flagged if it is found not to be\r
+ * the expected result.\r
+ */\r
+static void prvCountingSemaphoreTask( void *pvParameters );\r
+\r
+/*\r
+ * Utility function to increment the semaphore count value up from zero to\r
+ * countMAX_COUNT_VALUE.\r
+ */\r
+static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter );\r
+\r
+/*\r
+ * Utility function to decrement the semaphore count value up from \r
+ * countMAX_COUNT_VALUE to zero.\r
+ */\r
+static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The structure that is passed into the task as the task parameter. */\r
+typedef struct COUNT_SEM_STRUCT\r
+{\r
+ /* The semaphore to be used for the demo. */\r
+ xSemaphoreHandle xSemaphore;\r
+\r
+ /* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with\r
+ its count value set to its max count value, or countSTART_AT_ZERO if it\r
+ should have been created with its count value set to 0. */\r
+ unsigned portBASE_TYPE uxExpectedStartCount; \r
+\r
+ /* Incremented on each cycle of the demo task. Used to detect a stalled\r
+ task. */\r
+ unsigned portBASE_TYPE uxLoopCounter; \r
+} xCountSemStruct;\r
+\r
+/* Two structures are defined, one is passed to each test task. */\r
+static volatile xCountSemStruct xParameters[ countNUM_TEST_TASKS ];\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartCountingSemaphoreTasks( void )\r
+{\r
+ /* Create the semaphores that we are going to use for the test/demo. The\r
+ first should be created such that it starts at its maximum count value,\r
+ the second should be created such that it starts with a count value of zero. */\r
+ xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE );\r
+ xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT;\r
+ xParameters[ 0 ].uxLoopCounter = 0;\r
+\r
+ xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 );\r
+ xParameters[ 1 ].uxExpectedStartCount = 0;\r
+ xParameters[ 1 ].uxLoopCounter = 0;\r
+\r
+ /* vQueueAddToRegistry() adds the semaphore to the registry, if one is\r
+ in use. The registry is provided as a means for kernel aware \r
+ debuggers to locate semaphores and has no purpose if a kernel aware debugger\r
+ is not being used. The call to vQueueAddToRegistry() will be removed\r
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
+ defined to be less than 1. */\r
+ vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 0 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_1" );\r
+ vQueueAddToRegistry( ( xQueueHandle ) xParameters[ 1 ].xSemaphore, ( signed portCHAR * ) "Counting_Sem_2" );\r
+\r
+\r
+ /* Were the semaphores created? */\r
+ if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) )\r
+ {\r
+ /* Create the demo tasks, passing in the semaphore to use as the parameter. */\r
+ xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT1...", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL );\r
+ xTaskCreate( prvCountingSemaphoreTask, ( signed portCHAR * ) "CNT2...", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvDecrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter )\r
+{\r
+unsigned portBASE_TYPE ux;\r
+\r
+ /* If the semaphore count is at its maximum then we should not be able to\r
+ 'give' the semaphore. */\r
+ if( xSemaphoreGive( xSemaphore ) == pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */\r
+ for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )\r
+ {\r
+ if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )\r
+ {\r
+ /* We expected to be able to take the semaphore. */\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ ( *puxLoopCounter )++;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ /* If the semaphore count is zero then we should not be able to 'take' \r
+ the semaphore. */\r
+ if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvIncrementSemaphoreCount( xSemaphoreHandle xSemaphore, unsigned portBASE_TYPE *puxLoopCounter )\r
+{\r
+unsigned portBASE_TYPE ux;\r
+\r
+ /* If the semaphore count is zero then we should not be able to 'take' \r
+ the semaphore. */\r
+ if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ /* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */\r
+ for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )\r
+ {\r
+ if( xSemaphoreGive( xSemaphore ) != pdPASS )\r
+ {\r
+ /* We expected to be able to take the semaphore. */\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ ( *puxLoopCounter )++;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ /* If the semaphore count is at its maximum then we should not be able to\r
+ 'give' the semaphore. */\r
+ if( xSemaphoreGive( xSemaphore ) == pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCountingSemaphoreTask( void *pvParameters )\r
+{\r
+xCountSemStruct *pxParameter;\r
+\r
+ #ifdef USE_STDIO\r
+ void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+ \r
+ const portCHAR * const pcTaskStartMsg = "Counting semaphore demo started.\r\n";\r
+\r
+ /* Queue a message for printing to say the task has started. */\r
+ vPrintDisplayMessage( &pcTaskStartMsg );\r
+ #endif\r
+\r
+ /* The semaphore to be used was passed as the parameter. */\r
+ pxParameter = ( xCountSemStruct * ) pvParameters;\r
+\r
+ /* Did we expect to find the semaphore already at its max count value, or\r
+ at zero? */\r
+ if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT )\r
+ {\r
+ prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );\r
+ }\r
+\r
+ /* Now we expect the semaphore count to be 0, so this time there is an\r
+ error if we can take the semaphore. */\r
+ if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS )\r
+ {\r
+ xErrorDetected = pdTRUE;\r
+ }\r
+\r
+ for( ;; )\r
+ {\r
+ prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );\r
+ prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void )\r
+{\r
+static unsigned portBASE_TYPE uxLastCount0 = 0, uxLastCount1 = 0;\r
+portBASE_TYPE xReturn = pdPASS;\r
+\r
+ /* Return fail if any 'give' or 'take' did not result in the expected\r
+ behaviour. */\r
+ if( xErrorDetected != pdFALSE )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ /* Return fail if either task is not still incrementing its loop counter. */\r
+ if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ uxLastCount0 = xParameters[ 0 ].uxLoopCounter;\r
+ }\r
+\r
+ if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ uxLastCount1 = xParameters[ 1 ].uxLoopCounter;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef COUNT_SEMAPHORE_TEST_H\r
+#define COUNT_SEMAPHORE_TEST_H\r
+\r
+void vStartCountingSemaphoreTasks( void );\r
+portBASE_TYPE xAreCountingSemaphoreTasksStillRunning( void );\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/*\r
+ * The first test creates three tasks - two counter tasks (one continuous count \r
+ * and one limited count) and one controller. A "count" variable is shared \r
+ * between all three tasks. The two counter tasks should never be in a "ready" \r
+ * state at the same time. The controller task runs at the same priority as \r
+ * the continuous count task, and at a lower priority than the limited count \r
+ * task.\r
+ *\r
+ * One counter task loops indefinitely, incrementing the shared count variable\r
+ * on each iteration. To ensure it has exclusive access to the variable it\r
+ * raises it's priority above that of the controller task before each \r
+ * increment, lowering it again to it's original priority before starting the\r
+ * next iteration.\r
+ *\r
+ * The other counter task increments the shared count variable on each\r
+ * iteration of it's loop until the count has reached a limit of 0xff - at\r
+ * which point it suspends itself. It will not start a new loop until the \r
+ * controller task has made it "ready" again by calling vTaskResume (). \r
+ * This second counter task operates at a higher priority than controller \r
+ * task so does not need to worry about mutual exclusion of the counter \r
+ * variable.\r
+ *\r
+ * The controller task is in two sections. The first section controls and\r
+ * monitors the continuous count task. When this section is operational the \r
+ * limited count task is suspended. Likewise, the second section controls \r
+ * and monitors the limited count task. When this section is operational the \r
+ * continuous count task is suspended.\r
+ *\r
+ * In the first section the controller task first takes a copy of the shared\r
+ * count variable. To ensure mutual exclusion on the count variable it\r
+ * suspends the continuous count task, resuming it again when the copy has been\r
+ * taken. The controller task then sleeps for a fixed period - during which\r
+ * the continuous count task will execute and increment the shared variable.\r
+ * When the controller task wakes it checks that the continuous count task\r
+ * has executed by comparing the copy of the shared variable with its current\r
+ * value. This time, to ensure mutual exclusion, the scheduler itself is \r
+ * suspended with a call to vTaskSuspendAll (). This is for demonstration \r
+ * purposes only and is not a recommended technique due to its inefficiency.\r
+ *\r
+ * After a fixed number of iterations the controller task suspends the \r
+ * continuous count task, and moves on to its second section.\r
+ *\r
+ * At the start of the second section the shared variable is cleared to zero.\r
+ * The limited count task is then woken from it's suspension by a call to\r
+ * vTaskResume (). As this counter task operates at a higher priority than\r
+ * the controller task the controller task should not run again until the\r
+ * shared variable has been counted up to the limited value causing the counter\r
+ * task to suspend itself. The next line after vTaskResume () is therefore\r
+ * a check on the shared variable to ensure everything is as expected.\r
+ *\r
+ *\r
+ * The second test consists of a couple of very simple tasks that post onto a \r
+ * queue while the scheduler is suspended. This test was added to test parts\r
+ * of the scheduler not exercised by the first test.\r
+ *\r
+ */\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* Demo app include files. */\r
+#include "dynamic.h"\r
+\r
+/* Function that implements the "limited count" task as described above. */\r
+static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters );\r
+\r
+/* Function that implements the "continuous count" task as described above. */\r
+static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters );\r
+\r
+/* Function that implements the controller task as described above. */\r
+static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters );\r
+\r
+static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters );\r
+\r
+/* Demo task specific constants. */\r
+#define priSTACK_SIZE ( configMINIMAL_STACK_SIZE )\r
+#define priSLEEP_TIME ( ( portTickType ) 128 / portTICK_RATE_MS )\r
+#define priLOOPS ( 5 )\r
+#define priMAX_COUNT ( ( unsigned long ) 0xff )\r
+#define priNO_BLOCK ( ( portTickType ) 0 )\r
+#define priSUSPENDED_QUEUE_LENGTH ( 1 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Handles to the two counter tasks. These could be passed in as parameters\r
+to the controller task to prevent them having to be file scope. */\r
+static xTaskHandle xContinousIncrementHandle, xLimitedIncrementHandle;\r
+\r
+/* The shared counter variable. This is passed in as a parameter to the two \r
+counter variables for demonstration purposes. */\r
+static unsigned long ulCounter;\r
+\r
+/* Variables used to check that the tasks are still operating without error.\r
+Each complete iteration of the controller task increments this variable\r
+provided no errors have been found. The variable maintaining the same value\r
+is therefore indication of an error. */\r
+static volatile unsigned short usCheckVariable = ( unsigned short ) 0;\r
+static volatile portBASE_TYPE xSuspendedQueueSendError = pdFALSE;\r
+static volatile portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE;\r
+\r
+/* Queue used by the second test. */\r
+xQueueHandle xSuspendedTestQueue;\r
+\r
+/*-----------------------------------------------------------*/\r
+/*\r
+ * Start the three tasks as described at the top of the file.\r
+ * Note that the limited count task is given a higher priority.\r
+ */\r
+void vStartDynamicPriorityTasks( void )\r
+{\r
+ xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) );\r
+\r
+ /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+ in use. The queue registry is provided as a means for kernel aware \r
+ debuggers to locate queues and has no purpose if a kernel aware debugger\r
+ is not being used. The call to vQueueAddToRegistry() will be removed\r
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
+ defined to be less than 1. */\r
+ vQueueAddToRegistry( xSuspendedTestQueue, ( signed char * ) "Suspended_Test_Queue" );\r
+\r
+ xTaskCreate( vContinuousIncrementTask, ( signed char * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinousIncrementHandle );\r
+ xTaskCreate( vLimitedIncrementTask, ( signed char * ) "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );\r
+ xTaskCreate( vCounterControlTask, ( signed char * ) "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+ xTaskCreate( vQueueSendWhenSuspendedTask, ( signed char * ) "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+ xTaskCreate( vQueueReceiveWhenSuspendedTask, ( signed char * ) "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Just loops around incrementing the shared variable until the limit has been\r
+ * reached. Once the limit has been reached it suspends itself. \r
+ */\r
+static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters )\r
+{\r
+unsigned long *pulCounter;\r
+\r
+ /* Take a pointer to the shared variable from the parameters passed into\r
+ the task. */\r
+ pulCounter = ( unsigned long * ) pvParameters;\r
+\r
+ /* This will run before the control task, so the first thing it does is\r
+ suspend - the control task will resume it when ready. */\r
+ vTaskSuspend( NULL );\r
+\r
+ for( ;; )\r
+ {\r
+ /* Just count up to a value then suspend. */\r
+ ( *pulCounter )++; \r
+ \r
+ if( *pulCounter >= priMAX_COUNT )\r
+ {\r
+ vTaskSuspend( NULL );\r
+ } \r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Just keep counting the shared variable up. The control task will suspend\r
+ * this task when it wants.\r
+ */\r
+static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters )\r
+{\r
+unsigned long *pulCounter;\r
+unsigned portBASE_TYPE uxOurPriority;\r
+\r
+ /* Take a pointer to the shared variable from the parameters passed into\r
+ the task. */\r
+ pulCounter = ( unsigned long * ) pvParameters;\r
+\r
+ /* Query our priority so we can raise it when exclusive access to the \r
+ shared variable is required. */\r
+ uxOurPriority = uxTaskPriorityGet( NULL );\r
+\r
+ for( ;; )\r
+ {\r
+ /* Raise our priority above the controller task to ensure a context\r
+ switch does not occur while we are accessing this variable. */\r
+ vTaskPrioritySet( NULL, uxOurPriority + 1 );\r
+ ( *pulCounter )++; \r
+ vTaskPrioritySet( NULL, uxOurPriority );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Controller task as described above.\r
+ */\r
+static portTASK_FUNCTION( vCounterControlTask, pvParameters )\r
+{\r
+unsigned long ulLastCounter;\r
+short sLoops;\r
+short sError = pdFALSE;\r
+\r
+ /* Just to stop warning messages. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* Start with the counter at zero. */\r
+ ulCounter = ( unsigned long ) 0;\r
+\r
+ /* First section : */\r
+\r
+ /* Check the continuous count task is running. */\r
+ for( sLoops = 0; sLoops < priLOOPS; sLoops++ )\r
+ {\r
+ /* Suspend the continuous count task so we can take a mirror of the\r
+ shared variable without risk of corruption. */\r
+ vTaskSuspend( xContinousIncrementHandle );\r
+ ulLastCounter = ulCounter;\r
+ vTaskResume( xContinousIncrementHandle );\r
+ \r
+ /* Now delay to ensure the other task has processor time. */\r
+ vTaskDelay( priSLEEP_TIME );\r
+\r
+ /* Check the shared variable again. This time to ensure mutual \r
+ exclusion the whole scheduler will be locked. This is just for\r
+ demo purposes! */\r
+ vTaskSuspendAll();\r
+ {\r
+ if( ulLastCounter == ulCounter )\r
+ {\r
+ /* The shared variable has not changed. There is a problem\r
+ with the continuous count task so flag an error. */\r
+ sError = pdTRUE;\r
+ }\r
+ }\r
+ xTaskResumeAll();\r
+ }\r
+\r
+\r
+ /* Second section: */\r
+\r
+ /* Suspend the continuous counter task so it stops accessing the shared variable. */\r
+ vTaskSuspend( xContinousIncrementHandle );\r
+\r
+ /* Reset the variable. */\r
+ ulCounter = ( unsigned long ) 0;\r
+\r
+ /* Resume the limited count task which has a higher priority than us.\r
+ We should therefore not return from this call until the limited count\r
+ task has suspended itself with a known value in the counter variable. */\r
+ vTaskResume( xLimitedIncrementHandle );\r
+\r
+ /* Does the counter variable have the expected value? */\r
+ if( ulCounter != priMAX_COUNT )\r
+ {\r
+ sError = pdTRUE;\r
+ }\r
+\r
+ if( sError == pdFALSE )\r
+ {\r
+ /* If no errors have occurred then increment the check variable. */\r
+ portENTER_CRITICAL();\r
+ usCheckVariable++;\r
+ portEXIT_CRITICAL();\r
+ }\r
+\r
+ /* Resume the continuous count task and do it all again. */\r
+ vTaskResume( xContinousIncrementHandle );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters )\r
+{\r
+static unsigned long ulValueToSend = ( unsigned long ) 0;\r
+\r
+ /* Just to stop warning messages. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ vTaskSuspendAll();\r
+ {\r
+ /* We must not block while the scheduler is suspended! */\r
+ if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE )\r
+ {\r
+ xSuspendedQueueSendError = pdTRUE;\r
+ }\r
+ }\r
+ xTaskResumeAll();\r
+\r
+ vTaskDelay( priSLEEP_TIME );\r
+\r
+ ++ulValueToSend;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters )\r
+{\r
+static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue;\r
+portBASE_TYPE xGotValue;\r
+\r
+ /* Just to stop warning messages. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ do\r
+ {\r
+ /* Suspending the scheduler here is fairly pointless and \r
+ undesirable for a normal application. It is done here purely\r
+ to test the scheduler. The inner xTaskResumeAll() should\r
+ never return pdTRUE as the scheduler is still locked by the\r
+ outer call. */\r
+ vTaskSuspendAll();\r
+ {\r
+ vTaskSuspendAll();\r
+ {\r
+ xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK );\r
+ }\r
+ if( xTaskResumeAll() )\r
+ {\r
+ xSuspendedQueueReceiveError = pdTRUE;\r
+ }\r
+ }\r
+ xTaskResumeAll();\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ {\r
+ taskYIELD();\r
+ }\r
+ #endif\r
+\r
+ } while( xGotValue == pdFALSE );\r
+\r
+ if( ulReceivedValue != ulExpectedValue )\r
+ {\r
+ xSuspendedQueueReceiveError = pdTRUE;\r
+ }\r
+\r
+ ++ulExpectedValue;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Called to check that all the created tasks are still running without error. */\r
+portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void )\r
+{\r
+/* Keep a history of the check variables so we know if it has been incremented \r
+since the last call. */\r
+static unsigned short usLastTaskCheck = ( unsigned short ) 0;\r
+portBASE_TYPE xReturn = pdTRUE;\r
+\r
+ /* Check the tasks are still running by ensuring the check variable\r
+ is still incrementing. */\r
+\r
+ if( usCheckVariable == usLastTaskCheck )\r
+ {\r
+ /* The check has not incremented so an error exists. */\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ if( xSuspendedQueueSendError == pdTRUE )\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ if( xSuspendedQueueReceiveError == pdTRUE )\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ usLastTaskCheck = usCheckVariable;\r
+ return xReturn;\r
+}\r
--- /dev/null
+/*\r
+ FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+#ifndef DYNAMIC_MANIPULATION_H\r
+#define DYNAMIC_MANIPULATION_H\r
+\r
+void vStartDynamicPriorityTasks( void );\r
+portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
--- /dev/null
+/** @file gio.c \r
+* @brief GIO Driver Inmplmentation File\r
+* @date 10.June.2010\r
+* @version 1.01.000\r
+*\r
+*/\r
+\r
+/* (c) Texas Instruments 2009-2010, All rights reserved. */\r
+\r
+\r
+#include "gio.h"\r
+\r
+\r
+/** @fn void gioInit(void)\r
+* @brief Initializes the GIO Driver\r
+*\r
+* This function initializes the GIO module and set the GIO ports \r
+* to the inital values.\r
+*/\r
+void gioInit(void)\r
+{\r
+ /** bring GIO module out of reset */\r
+ gioREG->GCR0 = 1;\r
+ gioREG->INTENACLR = 0xFF;\r
+ gioREG->LVLCLR = 0xFF; \r
+\r
+ /** @b initalise @b Port @b A */\r
+\r
+ /** - Port A output values */\r
+ gioPORTA->DOUT = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port A direction */\r
+ gioPORTA->DIR = 1 /* Bit 0 */\r
+ | (1 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port A open drain enable */\r
+ gioPORTA->PDR = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port A pullup / pulldown selection */\r
+ gioPORTA->PSL = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port A pullup / pulldown enable*/\r
+ gioPORTA->PULDIS = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** @b initalise @b Port @b B */\r
+\r
+ /** - Port B output values */\r
+ gioPORTB->DOUT = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port B direction */\r
+ gioPORTB->DIR = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port B open drain enable */\r
+ gioPORTB->PDR = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port B pullup / pulldown selection */\r
+ gioPORTB->PSL = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - Port B pullup / pulldown enable*/\r
+ gioPORTB->PULDIS = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+\r
+ /** @b initalise @b interrupts */\r
+\r
+ /** - interrupt polarity */\r
+ gioREG->POL = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+ /** - interrupt level */\r
+ gioREG->LVLSET = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+\r
+\r
+ /** - clear all pending interrupts */\r
+ gioREG->FLG = 0xFF;\r
+\r
+ /** - enable interrupts */\r
+ gioREG->INTENASET = 0 /* Bit 0 */\r
+ | (0 << 1) /* Bit 1 */\r
+ | (0 << 2) /* Bit 2 */\r
+ | (0 << 3) /* Bit 3 */\r
+ | (0 << 4) /* Bit 4 */\r
+ | (0 << 5) /* Bit 5 */\r
+ | (0 << 6) /* Bit 6 */\r
+ | (0 << 7); /* Bit 7 */\r
+}\r
+\r
+\r
+/** @fn void gioSetDirection(gioPORT_t *port, unsigned dir)\r
+* @brief Set Port Direction\r
+* @param[in] port pointer to GIO port:\r
+* - gioPORTA: PortA pointer\r
+* - gioPORTB: PortB pointer\r
+* @param[in] dir value to write to DIR register\r
+*\r
+* Set the direction of GIO pins at runtime.\r
+*/\r
+void gioSetDirection(gioPORT_t *port, unsigned dir)\r
+{\r
+ port->DIR = dir;\r
+}\r
+\r
+\r
+/** @fn void gioSetBit(gioPORT_t *port, unsigned bit, unsigned value)\r
+* @brief Write Bit\r
+* @param[in] port pointer to GIO port:\r
+* - gioPORTA: PortA pointer\r
+* - gioPORTB: PortB pointer\r
+* @param[in] bit number 0-7 that specifies the bit to be written to.\r
+* - 0: LSB\r
+* - 7: MSB\r
+* @param[in] value binrary value to write to bit\r
+*\r
+* Writes a value to the specified pin of the given GIO port\r
+*/\r
+void gioSetBit(gioPORT_t *port, unsigned bit, unsigned value)\r
+{\r
+ if (value)\r
+ {\r
+ port->DSET = 1 << bit;\r
+ }\r
+ else\r
+ {\r
+ port->DCLR = 1 << bit;\r
+ }\r
+}\r
+\r
+\r
+/** @fn void gioSetPort(gioPORT_t *port, unsigned value)\r
+* @brief Write Port Value\r
+* @param[in] port pointer to GIO port:\r
+* - gioPORTA: PortA pointer\r
+* - gioPORTB: PortB pointer\r
+* @param[in] value value to write to port\r
+*\r
+* Writes a value to all pin of a given GIO port\r
+*/\r
+void gioSetPort(gioPORT_t *port, unsigned value)\r
+{\r
+ port->DOUT = value;\r
+}\r
+\r
+\r
+/** @fn unsigned gioGetBit(gioPORT_t *port, unsigned bit)\r
+* @brief Read Bit\r
+* @param[in] port pointer to GIO port:\r
+* - gioPORTA: PortA pointer\r
+* - gioPORTB: PortB pointer\r
+* @param[in] bit number 0-7 that specifies the bit to be written to.\r
+* - 0: LSB\r
+* - 7: MSB\r
+*\r
+* Reads a the current value from the specified pin of the given GIO port\r
+*/\r
+unsigned gioGetBit(gioPORT_t *port, unsigned bit)\r
+{\r
+ return (port->DIN >> bit) & 1U;\r
+}\r
+\r
+\r
+/** @fn unsigned gioGetPort(gioPORT_t *port)\r
+* @brief Read Port Value\r
+* @param[in] port pointer to GIO port:\r
+* - gioPORTA: PortA pointer\r
+* - gioPORTB: PortB pointer\r
+*\r
+* Reads a the current value of a given GIO port\r
+*/\r
+unsigned gioGetPort(gioPORT_t *port)\r
+{\r
+ return port->DIN;\r
+}\r
+\r
+\r
+/** @fn void gioEnableNotification(unsigned bit)\r
+* @brief Enable Interrupt\r
+* @param[in] bit interrupt pin to enable\r
+* - 0: LSB\r
+* - 7: MSB\r
+*\r
+* Enables an innterrupt pin of PortA\r
+*/\r
+void gioEnableNotification(unsigned bit)\r
+{\r
+ gioREG->INTENASET = 1 << bit;\r
+}\r
+\r
+\r
+/** @fn void gioDisableNotification(unsigned bit)\r
+* @brief Disable Interrupt\r
+* @param[in] bit interrupt pin to enable\r
+* - 0: LSB\r
+* - 7: MSB\r
+*\r
+* Disables an innterrupt pin of PortA\r
+*/\r
+void gioDisableNotification(unsigned bit)\r
+{\r
+ gioREG->INTENACLR = 1 << bit;\r
+}\r
--- /dev/null
+/** @file gio.h\r
+* @brief GIO Driver Definition File\r
+* @date 11.August.2009\r
+* @version 1.01.000\r
+* \r
+*/\r
+\r
+/* (c) Texas Instruments 2009-2010, All rights reserved. */\r
+\r
+\r
+#ifndef __GIO_H__\r
+#define __GIO_H__\r
+\r
+/** @struct gioBase\r
+* @brief GIO Base Register Definition\r
+*\r
+* This structure is used to access the GIO module egisters.\r
+*/\r
+/** @typedef gioBASE_t\r
+* @brief GIO Register Frame Type Definition\r
+*\r
+* This type is used to access the GIO Registers.\r
+*/\r
+typedef volatile struct gioBase\r
+{\r
+ unsigned GCR0; /**< 0x0000: Global Control Register */\r
+ unsigned PWDN; /**< 0x0004: Power Down Register */\r
+ unsigned INTDET; /**< 0x0008: Interrupt Detect Regsiter*/\r
+ unsigned POL; /**< 0x000C: Interrupt Polarity Register */\r
+ unsigned INTENASET; /**< 0x0010: Interrupt Enable Set Register */\r
+ unsigned INTENACLR; /**< 0x0014: Interrupt Enable Clear Register */\r
+ unsigned LVLSET; /**< 0x0018: Interrupt Priority Set Register */\r
+ unsigned LVLCLR; /**< 0x001C: Interrupt Priority Clear Register */\r
+ unsigned FLG; /**< 0x0020: Interrupt Flag Register */\r
+ unsigned OFFSET0; /**< 0x0024: Interrupt Offset A Register */\r
+ unsigned OFFSET1; /**< 0x0028: Interrupt Offset B Register */\r
+} gioBASE_t;\r
+\r
+\r
+/** @struct gioPort\r
+* @brief GIO Port Register Definition\r
+*/\r
+/** @typedef gioPORT_t\r
+* @brief GIO Port Register Type Definition\r
+*\r
+* This type is used to access the GIO Port Registers.\r
+*/\r
+typedef volatile struct gioPort\r
+{\r
+ unsigned DIR; /**< 0x0000: Data Direction Register */\r
+ unsigned DIN; /**< 0x0004: Data Input Register */\r
+ unsigned DOUT; /**< 0x0008: Data Output Register */\r
+ unsigned DSET; /**< 0x000C: Data Output Set Register */\r
+ unsigned DCLR; /**< 0x0010: Data Output Clear Register */\r
+ unsigned PDR; /**< 0x0014: Open Drain Regsiter */\r
+ unsigned PULDIS; /**< 0x0018: Pullup Disable Register */\r
+ unsigned PSL; /**< 0x001C: Pull Up/Down Selection Register */\r
+} gioPORT_t;\r
+\r
+\r
+/** @def gioREG\r
+* @brief GIO Register Frame Pointer\r
+*\r
+* This pointer is used by the GIO driver to access the gio module registers.\r
+*/\r
+#define gioREG ((gioBASE_t *)0xFFF7BC00U)\r
+\r
+/** @def gioPORTA\r
+* @brief GIO Port (A) Register Pointer\r
+*\r
+* Pointer used by the GIO driver to access PORTA\r
+*/\r
+#define gioPORTA ((gioPORT_t *)0xFFF7BC34U)\r
+\r
+/** @def gioPORTB\r
+* @brief GIO Port (B) Register Pointer\r
+*\r
+* Pointer used by the GIO driver to access PORTB\r
+*/\r
+#define gioPORTB ((gioPORT_t *)0xFFF7BC54U)\r
+\r
+\r
+/* GIO Interface Functions */\r
+void gioInit(void);\r
+void gioSetDirection(gioPORT_t *port, unsigned dir);\r
+void gioSetBit(gioPORT_t *port, unsigned bit, unsigned value);\r
+void gioSetPort(gioPORT_t *port, unsigned value);\r
+unsigned gioGetBit(gioPORT_t *port, unsigned bit);\r
+unsigned gioGetPort(gioPORT_t *port);\r
+void gioEnableNotification(unsigned bit);\r
+void gioDisableNotification(unsigned bit);\r
+void gioNotification(int bit);\r
+\r
+#endif\r
--- /dev/null
+;-------------------------------------------------\r
+;\r
+ .def vRegTestTask1\r
+ .ref usRegTest1Counter\r
+ .text\r
+ .arm\r
+;\r
+vRegTestTask1:\r
+ ; Fill each general purpose register with a known value.\r
+ mov r0, #0xFF\r
+ mov r1, #0x11\r
+ mov r2, #0x22\r
+ mov r3, #0x33\r
+ mov r4, #0x44 \r
+ mov r5, #0x55\r
+ mov r6, #0x66\r
+ mov r7, #0x77\r
+ mov r8, #0x88\r
+ mov r9, #0x99\r
+ mov r10, #0xAA\r
+ mov r11, #0xBB\r
+ mov r12, #0xCC\r
+ mov r14, #0xEE\r
+ \r
+regTestLoop1:\r
+ ; Force yeild\r
+ swi #0\r
+\r
+ ; Test each general purpose register to check that it still contains the\r
+ ; expected known value, jumping to vRegTest1Error if any register contains\r
+ ; an unexpected value.\r
+ cmp r0, #0xFF\r
+ bne regTestError1 \r
+ cmp r1, #0x11\r
+ bne regTestError1 \r
+ cmp r2, #0x22\r
+ bne regTestError1 \r
+ cmp r3, #0x33\r
+ bne regTestError1 \r
+ cmp r4, #0x44\r
+ bne regTestError1 \r
+ cmp r5, #0x55\r
+ bne regTestError1 \r
+ cmp r6, #0x66\r
+ bne regTestError1 \r
+ cmp r7, #0x77\r
+ bne regTestError1 \r
+ cmp r8, #0x88\r
+ bne regTestError1 \r
+ cmp r9, #0x99\r
+ bne regTestError1 \r
+ cmp r10, #0xAA\r
+ bne regTestError1 \r
+ cmp r11, #0xBB\r
+ bne regTestError1 \r
+ cmp r12, #0xCC\r
+ bne regTestError1 \r
+ cmp r14, #0xEE\r
+ bne regTestError1 \r
+ \r
+ ; This task is still running without jumping to vRegTest1Error, so increment\r
+ ; the loop counter so the check task knows the task is running error free.\r
+ stmfd sp!, { r0-r1 }\r
+ ldr r0, count1\r
+ ldr r1, [r0]\r
+ add r1, r1, #1\r
+ str r1, [r0]\r
+ ldmfd sp!, { r0-r1 }\r
+ \r
+ ; Loop again, performing the same tests.\r
+ b regTestLoop1\r
+\r
+count1 .word usRegTest1Counter\r
+ \r
+regTestError1:\r
+ b regTestError1\r
+\r
+\r
+;-------------------------------------------------\r
+;\r
+ .def vRegTestTask2\r
+ .ref usRegTest2Counter\r
+ .text\r
+ .arm\r
+;\r
+vRegTestTask2:\r
+ ; Fill each general purpose register with a known value.\r
+ mov r0, #0xFF000000\r
+ mov r1, #0x11000000\r
+ mov r2, #0x22000000\r
+ mov r3, #0x33000000\r
+ mov r4, #0x44000000 \r
+ mov r5, #0x55000000\r
+ mov r6, #0x66000000\r
+ mov r7, #0x77000000\r
+ mov r8, #0x88000000\r
+ mov r9, #0x99000000\r
+ mov r10, #0xAA000000\r
+ mov r11, #0xBB000000\r
+ mov r12, #0xCC000000\r
+ mov r14, #0xEE000000\r
+ \r
+regTestLoop2:\r
+ ; Force yeild\r
+ swi #0\r
+\r
+ ; Test each general purpose register to check that it still contains the\r
+ ; expected known value, jumping to vRegTest1Error if any register contains\r
+ ; an unexpected value.\r
+ cmp r0, #0xFF000000\r
+ bne regTestError2 \r
+ cmp r1, #0x11000000\r
+ bne regTestError2 \r
+ cmp r2, #0x22000000\r
+ bne regTestError2 \r
+ cmp r3, #0x33000000\r
+ bne regTestError2 \r
+ cmp r4, #0x44000000\r
+ bne regTestError2 \r
+ cmp r5, #0x55000000\r
+ bne regTestError2 \r
+ cmp r6, #0x66000000\r
+ bne regTestError2 \r
+ cmp r7, #0x77000000\r
+ bne regTestError2 \r
+ cmp r8, #0x88000000\r
+ bne regTestError2 \r
+ cmp r9, #0x99000000\r
+ bne regTestError2 \r
+ cmp r10, #0xAA000000\r
+ bne regTestError2 \r
+ cmp r11, #0xBB000000\r
+ bne regTestError2 \r
+ cmp r12, #0xCC000000\r
+ bne regTestError2 \r
+ cmp r14, #0xEE000000\r
+ bne regTestError2 \r
+ \r
+ ; This task is still running without jumping to vRegTest1Error, so increment\r
+ ; the loop counter so the check task knows the task is running error free.\r
+ stmfd sp!, { r0-r1 }\r
+ ldr r0, count2\r
+ ldr r1, [r0]\r
+ add r1, r1, #1\r
+ str r1, [r0]\r
+ ldmfd sp!, { r0-r1 }\r
+ \r
+ ; Loop again, performing the same tests.\r
+ b regTestLoop2\r
+\r
+count2 .word usRegTest2Counter\r
+ \r
+regTestError2:\r
+ b regTestError2\r
+\r
+;-------------------------------------------------\r
+ \r
+ \r
+ \r
--- /dev/null
+/* main.c \r
+ *\r
+ * "Check" callback function - Called each time the 'check' timer expires. The\r
+ * check timer executes every five seconds. Its main function is to check that \r
+ * all the standard demo tasks are still operational. Each time it executes it \r
+ * sends a status code to the LCD task. The LCD task interprets the code and \r
+ * displays an appropriate message - which will be PASS if no tasks have \r
+ * reported any errors, or a message stating which task has reported an error.\r
+ *\r
+ * "Reg test" tasks - These fill the registers with known values, then check\r
+ * that each register still contains its expected value. Each task uses\r
+ * different values. The tasks run with very low priority so get preempted\r
+ * very frequently. A check variable is incremented on each iteration of the\r
+ * test loop. A register containing an unexpected value is indicative of an\r
+ * error in the context switching mechanism and will result in a branch to a\r
+ * null loop - which in turn will prevent the check variable from incrementing\r
+ * any further and allow the check timer callback (described a above) to \r
+ * determine that an error has occurred. The nature of the reg test tasks \r
+ * necessitates that they are written in assembly code.\r
+ *\r
+ * Tick hook function - called inside the RTOS tick function, this simple \r
+ * example does nothing but toggle an LED.\r
+ *\r
+ */\r
+\r
+#include <stdio.h>\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "timers.h"\r
+#include "queue.h"\r
+#include "gio.h"\r
+#include "TimerDemo.h"\r
+#include "countsem.h"\r
+#include "GenQTest.h"\r
+#include "dynamic.h"\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+/* Codes sent within messages to the LCD task so the LCD task can interpret\r
+exactly what the message it just received was. These are sent in the\r
+cMessageID member of the message structure (defined below). */\r
+//#define mainMESSAGE_BUTTON_UP ( 1 )\r
+//#define mainMESSAGE_BUTTON_SEL ( 2 )\r
+#define mainMESSAGE_STATUS ( 3 )\r
+\r
+/* When the cMessageID member of the message sent to the MSG task is\r
+mainMESSAGE_STATUS then these definitions are sent in the ulMessageValue member\r
+of the same message and indicate what the status actually is. */\r
+#define mainERROR_DYNAMIC_TASKS ( pdPASS + 1 )\r
+#define mainERROR_COM_TEST ( pdPASS + 2 )\r
+#define mainERROR_GEN_QUEUE_TEST ( pdPASS + 3 )\r
+#define mainERROR_REG_TEST ( pdPASS + 4 )\r
+#define mainERROR_TIMER_TEST ( pdPASS + 5 )\r
+#define mainERROR_COUNT_SEM_TEST ( pdPASS + 6 )\r
+\r
+/* Priorities used by the test and demo tasks. */\r
+#define mainMSG_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY )\r
+\r
+/* Just used to ensure parameters are passed into tasks correctly. */\r
+#define mainTASK_PARAMETER_CHECK_VALUE ((void *)0xDEAD)\r
+\r
+/* The length of the queue (the number of items the queue can hold) that is used\r
+to send messages from tasks and interrupts the the MSG task. */\r
+#define mainQUEUE_LENGTH ( 5 )\r
+\r
+/* The base period used by the timer test tasks. */\r
+#define mainTIMER_TEST_PERIOD ( 50 )\r
+\r
+/* The frequency at which the check timer (described in the comments at the top\r
+of this file) will call its callback function. */\r
+#define mainCHECK_TIMER_PERIOD ( 5000UL / ( unsigned long ) portTICK_RATE_MS )\r
+\r
+/* Misc. */\r
+#define mainDONT_BLOCK ( 0 )\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+/* external regsiter check tasks, this checks that the context store/restore works */\r
+\r
+extern void vRegTestTask1(void *pvParameters); \r
+extern void vRegTestTask2(void *pvParameters); \r
+\r
+/*\r
+ * Definition of the MSG/controller task described in the comments at the top\r
+ * of this file.\r
+ */\r
+static void prvMsgTask( void *pvParameters );\r
+\r
+/*\r
+ * Converts a status message value into an appropriate string for display on\r
+ * the LCD. The string is written to pcBuffer.\r
+ */\r
+static void prvGenerateStatusMessage( char *pcBuffer, unsigned long ulStatusValue );\r
+\r
+/*\r
+ * Defines the 'check' functionality as described at the top of this file. This\r
+ * function is the callback function for the 'check' timer. */\r
+static void vCheckTimerCallback( xTimerHandle xTimer );\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+static signed char buffer[1024];\r
+\r
+void vStatsTask(void *pvParameters)\r
+{\r
+ printf("**** Task Statistics Started\n");\r
+ for (;;)\r
+ {\r
+ vTaskDelay(15000);\r
+ vTaskGetRunTimeStats(buffer);\r
+ printf("%s\n", buffer);\r
+ }\r
+}\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+/* variable incremente in the IDLE hook */\r
+volatile unsigned usIdleCounter = 0;\r
+\r
+/* Variables that are incremented on each iteration of the reg test tasks -\r
+provided the tasks have not reported any errors. The check task inspects these\r
+variables to ensure they are still incrementing as expected. If a variable\r
+stops incrementing then it is likely that its associate task has stalled. */\r
+volatile unsigned usRegTest1Counter = 0, usRegTest2Counter = 0;\r
+\r
+/* The handle of the queue used to send messages from tasks and interrupts to\r
+ the MSG task. */\r
+static xQueueHandle xMsgQueue = NULL;\r
+\r
+/* The 'check' timer, as described at the top of this file. */\r
+static xTimerHandle xCheckTimer = NULL;\r
+\r
+/* The definition of each message sent from tasks and interrupts to the MSG\r
+task. */\r
+typedef struct\r
+{\r
+ char cMessageID; /* << States what the message is. */\r
+ unsigned ulMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID). */\r
+} xQueueMessage;\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+void main()\r
+{\r
+ /* initalise DIO ports */\r
+ gioInit();\r
+ \r
+ gioSetBit(gioPORTA, 0, 1);\r
+ gioSetBit(gioPORTA, 0, 0);\r
+\r
+\r
+ /* Create the queue used by tasks and interrupts to send strings to the MSG task. */\r
+ xMsgQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );\r
+\r
+ /* If the queue could not be created then don't create any tasks that might\r
+ attempt to use the queue. */\r
+ if( xMsgQueue != NULL )\r
+ {\r
+ /* Create STATS task, this prints out a summary of running tasks every 15s */\r
+ xTaskCreate(vStatsTask, (signed char *)"STATS..", 600, NULL, 6, NULL);\r
+\r
+ /* Create the standard demo tasks. */\r
+ vStartDynamicPriorityTasks();\r
+ vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );\r
+ vStartCountingSemaphoreTasks();\r
+ \r
+ /* Note that creating the timer test/demo tasks will fill the timer\r
+ command queue. This is intentional, and forms part of the test the tasks\r
+ perform. It does mean however that, after this function is called, no\r
+ more timer commands can be sent until after the scheduler has been\r
+ started (at which point the timer daemon will drained the timer command\r
+ queue, freeing up space for more commands to be received). */\r
+ vStartTimerDemoTask(mainTIMER_TEST_PERIOD);\r
+ \r
+ /* Create the MSGl and register test tasks. */\r
+ xTaskCreate(prvMsgTask, (signed char *)"MSG....", 500, mainTASK_PARAMETER_CHECK_VALUE, mainMSG_TASK_PRIORITY, NULL );\r
+ xTaskCreate(vRegTestTask1, (signed char *)"REG1...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);\r
+ xTaskCreate(vRegTestTask2, (signed char *)"REG2...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);\r
+ \r
+ \r
+ /* Create the 'check' timer - the timer that periodically calls the\r
+ check function as described at the top of this file. Note that, for\r
+ the reasons stated in the comments above the call to \r
+ vStartTimerDemoTask(), that the check timer is not actually started \r
+ until after the scheduler has been started. */\r
+ xCheckTimer = xTimerCreate( ( const signed char * ) "Check Timer", mainCHECK_TIMER_PERIOD, pdTRUE, ( void * ) 0, vCheckTimerCallback ); \r
+ \r
+ /* start FreeRTOS Scheduler */\r
+ vTaskStartScheduler();\r
+ }\r
+ \r
+ /* If all is well then this line will never be reached. If it is reached\r
+ then it is likely that there was insufficient (FreeRTOS) heap memory space\r
+ to create the idle task. This may have been trapped by the malloc() failed\r
+ hook function, if one is configured. */ \r
+ for (;;);\r
+}\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+static void prvMsgTask( void *pvParameters )\r
+{\r
+ xQueueMessage xReceivedMessage;\r
+ static char cBuffer[50]; \r
+\r
+ printf("**** Msg Task Started\n");\r
+\r
+ /* Now the scheduler has been started (it must have been for this task to\r
+ be running), start the check timer too. The call to xTimerStart() will\r
+ block until the command has been accepted. */\r
+ if( xCheckTimer != NULL )\r
+ {\r
+ xTimerStart( xCheckTimer, portMAX_DELAY );\r
+ }\r
+\r
+ /* First print out the number of bytes that remain in the FreeRTOS heap. This\r
+ is done after a short delay to ensure all the demo tasks have created all\r
+ the objects they are going to use. */\r
+ vTaskDelay( mainTIMER_TEST_PERIOD * 10 );\r
+ printf("**** %d heap free\n", (int)xPortGetFreeHeapSize());\r
+ \r
+ /* Just as a test of the port, and for no functional reason, check the task\r
+ parameter contains its expected value. */\r
+ if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )\r
+ {\r
+ printf("**** Invalid parameter ****\n\n");\r
+ }\r
+\r
+ for( ;; )\r
+ {\r
+ /* Wait for a message to be received. Using portMAX_DELAY as the block\r
+ time will result in an indefinite wait provided INCLUDE_vTaskSuspend is\r
+ set to 1 in FreeRTOSConfig.h, therefore there is no need to check the\r
+ function return value and the function will only return when a value\r
+ has been received. */\r
+ xQueueReceive( xMsgQueue, &xReceivedMessage, portMAX_DELAY );\r
+\r
+ /* What is this message? What does it contain? */\r
+ switch( xReceivedMessage.cMessageID )\r
+ {\r
+#if 0 \r
+ case mainMESSAGE_BUTTON_UP : /* The button poll task has just\r
+ informed this task that the up\r
+ button on the joystick input has\r
+ been pressed or released. */\r
+ sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue );\r
+ break;\r
+\r
+ case mainMESSAGE_BUTTON_SEL : /* The select button interrupt\r
+ just informed this task that the\r
+ select button has been pressed.\r
+ In this case the pointer to the \r
+ string to print is sent directly \r
+ in the ulMessageValue member of \r
+ the message. This just \r
+ demonstrates a different \r
+ communication technique. */\r
+ sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );\r
+ break;\r
+#endif \r
+ case mainMESSAGE_STATUS : /* The tick interrupt hook\r
+ function has just informed this\r
+ task of the system status.\r
+ Generate a string in accordance\r
+ with the status value. */\r
+ prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue );\r
+ break;\r
+ \r
+ default : sprintf( cBuffer, "Unknown message" );\r
+ break;\r
+ }\r
+ /* Output the message that was placed into the cBuffer array within the\r
+ switch statement above, then move onto the next line ready for the next\r
+ message to arrive on the queue. */\r
+ printf("**** Message Received: %s\n", cBuffer);\r
+ } \r
+}\r
+\r
+static void prvGenerateStatusMessage(char *pcBuffer, unsigned long ulStatusValue)\r
+{\r
+ /* Just a utility function to convert a status value into a meaningful\r
+ string for output. */\r
+ switch( ulStatusValue )\r
+ {\r
+ case pdPASS : sprintf( pcBuffer, "Status = PASS" );\r
+ break;\r
+ case mainERROR_DYNAMIC_TASKS : sprintf( pcBuffer, "Err: Dynamic tsks" );\r
+ break;\r
+ case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: COM test" );\r
+ break;\r
+ case mainERROR_GEN_QUEUE_TEST : sprintf( pcBuffer, "Error: Gen Q test" );\r
+ break;\r
+ case mainERROR_REG_TEST : sprintf( pcBuffer, "Error: Reg test" );\r
+ break;\r
+ case mainERROR_TIMER_TEST : sprintf( pcBuffer, "Error: Tmr test" );\r
+ break;\r
+ case mainERROR_COUNT_SEM_TEST : sprintf( pcBuffer, "Error: Count sem" );\r
+ break;\r
+ default : sprintf( pcBuffer, "Unknown status" );\r
+ break;\r
+ }\r
+}\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+static void vCheckTimerCallback( xTimerHandle xTimer )\r
+{\r
+ static unsigned short usLastRegTest1Counter = 0, usLastRegTest2Counter = 0;\r
+\r
+ /* Define the status message that is sent to the LCD task. By default the\r
+ status is PASS. */\r
+ static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS };\r
+\r
+ /* This is the callback function used by the 'check' timer, as described\r
+ at the top of this file. */\r
+\r
+ /* The parameter is not used. */\r
+ ( void ) xTimer;\r
+ \r
+ /* See if the standard demo tasks are executing as expected, changing\r
+ the message that is sent to the LCD task from PASS to an error code if\r
+ any tasks set reports an error. */\r
+#if 0 \r
+ if( xAreComTestTasksStillRunning() != pdPASS )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_COM_TEST;\r
+ }\r
+#endif\r
+ if( xAreDynamicPriorityTasksStillRunning() != pdPASS )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS;\r
+ }\r
+ \r
+ if( xAreGenericQueueTasksStillRunning() != pdPASS )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;\r
+ } \r
+ \r
+ if( xAreCountingSemaphoreTasksStillRunning() != pdPASS )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_COUNT_SEM_TEST;\r
+ }\r
+ \r
+ if( xAreTimerDemoTasksStillRunning( ( portTickType ) mainCHECK_TIMER_PERIOD ) != pdPASS )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_TIMER_TEST;\r
+ }\r
+\r
+ /* Check the reg test tasks are still cycling. They will stop\r
+ incrementing their loop counters if they encounter an error. */\r
+ if( usRegTest1Counter == usLastRegTest1Counter )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
+ }\r
+\r
+ if( usRegTest2Counter == usLastRegTest2Counter )\r
+ {\r
+ xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
+ }\r
+\r
+ usLastRegTest1Counter = usRegTest1Counter;\r
+ usLastRegTest2Counter = usRegTest2Counter;\r
+ \r
+ /* This is called from a timer callback so must not block! */\r
+ xQueueSendToBack( xMsgQueue, &xStatusMessage, mainDONT_BLOCK );\r
+}\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+void vApplicationTickHook( void )\r
+{\r
+ static unsigned long ulCounter = 0;\r
+\r
+ /* Is it time to toggle the pin again? */\r
+ ulCounter++;\r
+\r
+ /* Just periodically toggle a pin to show that the tick interrupt is\r
+ running. */\r
+ if( ( ulCounter & 0xff ) == 0 )\r
+ {\r
+ gioSetBit(gioPORTA, 0, 1);\r
+ gioSetBit(gioPORTA, 0, 0);\r
+ }\r
+}\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+void vApplicationMallocFailedHook( void )\r
+{\r
+ /* Called if a call to pvPortMalloc() fails because there is insufficient\r
+ free memory available in the FreeRTOS heap. pvPortMalloc() is called\r
+ internally by FreeRTOS API functions that create tasks, queues or\r
+ semaphores. */\r
+ taskDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+ \r
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
+{\r
+ /* Run time stack overflow checking is performed if\r
+ configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook\r
+ function is called if a stack overflow is detected. */\r
+ taskDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+void vApplicationIdleHook(void)\r
+{\r
+ usIdleCounter++; \r
+}\r
+\r
+\r
+/* ----------------------------------------------------------------------------------------------------------- */\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef INC_FREERTOS_H\r
+#define INC_FREERTOS_H\r
+\r
+\r
+/*\r
+ * Include the generic headers required for the FreeRTOS port being used.\r
+ */\r
+#include <stddef.h>\r
+\r
+/* Basic FreeRTOS definitions. */\r
+#include "projdefs.h"\r
+\r
+/* Application specific configuration options. */\r
+#include "FreeRTOSConfig.h"\r
+\r
+/* Definitions specific to the port being used. */\r
+#include "portable.h"\r
+\r
+\r
+/* Defines the prototype to which the application task hook function must\r
+conform. */\r
+typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );\r
+\r
+\r
+\r
+\r
+\r
+/*\r
+ * Check all the required application specific macros have been defined.\r
+ * These macros are application specific and (as downloaded) are defined\r
+ * within FreeRTOSConfig.h.\r
+ */\r
+\r
+#ifndef configUSE_PREEMPTION\r
+ #error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef configUSE_IDLE_HOOK\r
+ #error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef configUSE_TICK_HOOK\r
+ #error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef configUSE_CO_ROUTINES\r
+ #error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_vTaskPrioritySet\r
+ #error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_uxTaskPriorityGet\r
+ #error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_vTaskDelete \r
+ #error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_vTaskSuspend \r
+ #error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_vTaskDelayUntil\r
+ #error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_vTaskDelay\r
+ #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef configUSE_16_BIT_TICKS\r
+ #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
+#endif\r
+\r
+#ifndef INCLUDE_xTaskGetIdleTaskHandle\r
+ #define INCLUDE_xTaskGetIdleTaskHandle 0\r
+#endif\r
+\r
+#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle\r
+ #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0\r
+#endif\r
+\r
+#ifndef INCLUDE_xQueueGetMutexHolder\r
+ #define INCLUDE_xQueueGetMutexHolder 0\r
+#endif\r
+\r
+#ifndef INCLUDE_pcTaskGetTaskName\r
+ #define INCLUDE_pcTaskGetTaskName 0\r
+#endif\r
+\r
+#ifndef configUSE_APPLICATION_TASK_TAG\r
+ #define configUSE_APPLICATION_TASK_TAG 0\r
+#endif\r
+\r
+#ifndef INCLUDE_uxTaskGetStackHighWaterMark\r
+ #define INCLUDE_uxTaskGetStackHighWaterMark 0\r
+#endif\r
+\r
+#ifndef configUSE_RECURSIVE_MUTEXES\r
+ #define configUSE_RECURSIVE_MUTEXES 0\r
+#endif\r
+\r
+#ifndef configUSE_MUTEXES\r
+ #define configUSE_MUTEXES 0\r
+#endif\r
+\r
+#ifndef configUSE_TIMERS\r
+ #define configUSE_TIMERS 0\r
+#endif\r
+\r
+#ifndef configUSE_COUNTING_SEMAPHORES\r
+ #define configUSE_COUNTING_SEMAPHORES 0\r
+#endif\r
+\r
+#ifndef configUSE_ALTERNATIVE_API\r
+ #define configUSE_ALTERNATIVE_API 0\r
+#endif\r
+\r
+#ifndef portCRITICAL_NESTING_IN_TCB\r
+ #define portCRITICAL_NESTING_IN_TCB 0\r
+#endif\r
+\r
+#ifndef configMAX_TASK_NAME_LEN\r
+ #define configMAX_TASK_NAME_LEN 16\r
+#endif\r
+\r
+#ifndef configIDLE_SHOULD_YIELD\r
+ #define configIDLE_SHOULD_YIELD 1\r
+#endif\r
+\r
+#if configMAX_TASK_NAME_LEN < 1\r
+ #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h\r
+#endif\r
+\r
+#ifndef INCLUDE_xTaskResumeFromISR\r
+ #define INCLUDE_xTaskResumeFromISR 1\r
+#endif\r
+\r
+#ifndef configASSERT\r
+ #define configASSERT( x )\r
+#endif\r
+\r
+#ifndef portALIGNMENT_ASSERT_pxCurrentTCB\r
+ #define portALIGNMENT_ASSERT_pxCurrentTCB configASSERT\r
+#endif\r
+\r
+/* The timers module relies on xTaskGetSchedulerState(). */\r
+#if configUSE_TIMERS == 1\r
+\r
+ #ifndef configTIMER_TASK_PRIORITY\r
+ #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.\r
+ #endif /* configTIMER_TASK_PRIORITY */\r
+\r
+ #ifndef configTIMER_QUEUE_LENGTH\r
+ #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.\r
+ #endif /* configTIMER_QUEUE_LENGTH */\r
+\r
+ #ifndef configTIMER_TASK_STACK_DEPTH\r
+ #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.\r
+ #endif /* configTIMER_TASK_STACK_DEPTH */\r
+\r
+#endif /* configUSE_TIMERS */\r
+\r
+#ifndef INCLUDE_xTaskGetSchedulerState\r
+ #define INCLUDE_xTaskGetSchedulerState 0\r
+#endif\r
+\r
+#ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
+ #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
+#endif\r
+\r
+\r
+#ifndef portSET_INTERRUPT_MASK_FROM_ISR\r
+ #define portSET_INTERRUPT_MASK_FROM_ISR() 0\r
+#endif\r
+\r
+#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR\r
+ #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue\r
+#endif\r
+\r
+#ifndef portCLEAN_UP_TCB\r
+ #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB\r
+#endif\r
+\r
+#ifndef portSETUP_TCB\r
+ #define portSETUP_TCB( pxTCB ) ( void ) pxTCB\r
+#endif\r
+\r
+#ifndef configQUEUE_REGISTRY_SIZE\r
+ #define configQUEUE_REGISTRY_SIZE 0U\r
+#endif\r
+\r
+#if ( configQUEUE_REGISTRY_SIZE < 1 )\r
+ #define vQueueAddToRegistry( xQueue, pcName )\r
+ #define vQueueUnregisterQueue( xQueue )\r
+#endif\r
+\r
+#ifndef portPOINTER_SIZE_TYPE\r
+ #define portPOINTER_SIZE_TYPE unsigned long\r
+#endif\r
+\r
+/* Remove any unused trace macros. */\r
+#ifndef traceSTART\r
+ /* Used to perform any necessary initialisation - for example, open a file\r
+ into which trace is to be written. */\r
+ #define traceSTART()\r
+#endif\r
+\r
+#ifndef traceEND\r
+ /* Use to close a trace, for example close a file into which trace has been\r
+ written. */\r
+ #define traceEND()\r
+#endif\r
+\r
+#ifndef traceTASK_SWITCHED_IN\r
+ /* Called after a task has been selected to run. pxCurrentTCB holds a pointer\r
+ to the task control block of the selected task. */\r
+ #define traceTASK_SWITCHED_IN()\r
+#endif\r
+\r
+#ifndef traceTASK_SWITCHED_OUT\r
+ /* Called before a task has been selected to run. pxCurrentTCB holds a pointer\r
+ to the task control block of the task being switched out. */\r
+ #define traceTASK_SWITCHED_OUT()\r
+#endif\r
+\r
+#ifndef traceTASK_PRIORITY_INHERIT\r
+ /* Called when a task attempts to take a mutex that is already held by a\r
+ lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task\r
+ that holds the mutex. uxInheritedPriority is the priority the mutex holder\r
+ will inherit (the priority of the task that is attempting to obtain the\r
+ muted. */\r
+ #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )\r
+#endif\r
+\r
+#ifndef traceTASK_PRIORITY_DISINHERIT\r
+ /* Called when a task releases a mutex, the holding of which had resulted in\r
+ the task inheriting the priority of a higher priority task. \r
+ pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the\r
+ mutex. uxOriginalPriority is the task's configured (base) priority. */\r
+ #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )\r
+#endif\r
+\r
+#ifndef traceBLOCKING_ON_QUEUE_RECEIVE\r
+ /* Task is about to block because it cannot read from a\r
+ queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore\r
+ upon which the read was attempted. pxCurrentTCB points to the TCB of the\r
+ task that attempted the read. */\r
+ #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )\r
+#endif\r
+\r
+#ifndef traceBLOCKING_ON_QUEUE_SEND\r
+ /* Task is about to block because it cannot write to a\r
+ queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore\r
+ upon which the write was attempted. pxCurrentTCB points to the TCB of the\r
+ task that attempted the write. */\r
+ #define traceBLOCKING_ON_QUEUE_SEND( pxQueue )\r
+#endif\r
+\r
+#ifndef configCHECK_FOR_STACK_OVERFLOW\r
+ #define configCHECK_FOR_STACK_OVERFLOW 0\r
+#endif\r
+\r
+/* The following event macros are embedded in the kernel API calls. */\r
+\r
+#ifndef traceMOVED_TASK_TO_READY_STATE\r
+ #define traceMOVED_TASK_TO_READY_STATE( pxTCB )\r
+#endif\r
+\r
+#ifndef traceQUEUE_CREATE \r
+ #define traceQUEUE_CREATE( pxNewQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_CREATE_FAILED\r
+ #define traceQUEUE_CREATE_FAILED( ucQueueType )\r
+#endif\r
+\r
+#ifndef traceCREATE_MUTEX\r
+ #define traceCREATE_MUTEX( pxNewQueue )\r
+#endif\r
+\r
+#ifndef traceCREATE_MUTEX_FAILED\r
+ #define traceCREATE_MUTEX_FAILED()\r
+#endif\r
+\r
+#ifndef traceGIVE_MUTEX_RECURSIVE\r
+ #define traceGIVE_MUTEX_RECURSIVE( pxMutex )\r
+#endif\r
+\r
+#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED\r
+ #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )\r
+#endif\r
+\r
+#ifndef traceTAKE_MUTEX_RECURSIVE\r
+ #define traceTAKE_MUTEX_RECURSIVE( pxMutex )\r
+#endif\r
+\r
+#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED\r
+ #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex )\r
+#endif\r
+\r
+#ifndef traceCREATE_COUNTING_SEMAPHORE\r
+ #define traceCREATE_COUNTING_SEMAPHORE()\r
+#endif\r
+\r
+#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED\r
+ #define traceCREATE_COUNTING_SEMAPHORE_FAILED()\r
+#endif\r
+\r
+#ifndef traceQUEUE_SEND\r
+ #define traceQUEUE_SEND( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_SEND_FAILED\r
+ #define traceQUEUE_SEND_FAILED( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_RECEIVE\r
+ #define traceQUEUE_RECEIVE( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_PEEK\r
+ #define traceQUEUE_PEEK( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_RECEIVE_FAILED\r
+ #define traceQUEUE_RECEIVE_FAILED( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_SEND_FROM_ISR\r
+ #define traceQUEUE_SEND_FROM_ISR( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_SEND_FROM_ISR_FAILED\r
+ #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_RECEIVE_FROM_ISR\r
+ #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED\r
+ #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )\r
+#endif\r
+\r
+#ifndef traceQUEUE_DELETE\r
+ #define traceQUEUE_DELETE( pxQueue )\r
+#endif\r
+\r
+#ifndef traceTASK_CREATE\r
+ #define traceTASK_CREATE( pxNewTCB )\r
+#endif\r
+\r
+#ifndef traceTASK_CREATE_FAILED\r
+ #define traceTASK_CREATE_FAILED()\r
+#endif\r
+\r
+#ifndef traceTASK_DELETE\r
+ #define traceTASK_DELETE( pxTaskToDelete )\r
+#endif\r
+\r
+#ifndef traceTASK_DELAY_UNTIL\r
+ #define traceTASK_DELAY_UNTIL()\r
+#endif\r
+\r
+#ifndef traceTASK_DELAY\r
+ #define traceTASK_DELAY()\r
+#endif\r
+\r
+#ifndef traceTASK_PRIORITY_SET\r
+ #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )\r
+#endif\r
+\r
+#ifndef traceTASK_SUSPEND\r
+ #define traceTASK_SUSPEND( pxTaskToSuspend )\r
+#endif\r
+\r
+#ifndef traceTASK_RESUME\r
+ #define traceTASK_RESUME( pxTaskToResume )\r
+#endif\r
+\r
+#ifndef traceTASK_RESUME_FROM_ISR\r
+ #define traceTASK_RESUME_FROM_ISR( pxTaskToResume )\r
+#endif\r
+\r
+#ifndef traceTASK_INCREMENT_TICK\r
+ #define traceTASK_INCREMENT_TICK( xTickCount )\r
+#endif\r
+\r
+#ifndef traceTIMER_CREATE\r
+ #define traceTIMER_CREATE( pxNewTimer )\r
+#endif\r
+\r
+#ifndef traceTIMER_CREATE_FAILED\r
+ #define traceTIMER_CREATE_FAILED()\r
+#endif\r
+\r
+#ifndef traceTIMER_COMMAND_SEND\r
+ #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )\r
+#endif\r
+\r
+#ifndef traceTIMER_EXPIRED\r
+ #define traceTIMER_EXPIRED( pxTimer )\r
+#endif\r
+\r
+#ifndef traceTIMER_COMMAND_RECEIVED\r
+ #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )\r
+#endif\r
+\r
+#ifndef configGENERATE_RUN_TIME_STATS\r
+ #define configGENERATE_RUN_TIME_STATS 0\r
+#endif\r
+\r
+#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+\r
+ #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS\r
+ #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.\r
+ #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */\r
+\r
+ #ifndef portGET_RUN_TIME_COUNTER_VALUE\r
+ #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE\r
+ #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information.\r
+ #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */\r
+ #endif /* portGET_RUN_TIME_COUNTER_VALUE */\r
+\r
+#endif /* configGENERATE_RUN_TIME_STATS */\r
+\r
+#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS\r
+ #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\r
+#endif\r
+\r
+#ifndef configUSE_MALLOC_FAILED_HOOK\r
+ #define configUSE_MALLOC_FAILED_HOOK 0\r
+#endif\r
+\r
+#ifndef portPRIVILEGE_BIT\r
+ #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )\r
+#endif\r
+\r
+#ifndef portYIELD_WITHIN_API\r
+ #define portYIELD_WITHIN_API portYIELD\r
+#endif\r
+\r
+#ifndef pvPortMallocAligned\r
+ #define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )\r
+#endif\r
+\r
+#ifndef vPortFreeAligned\r
+ #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )\r
+#endif\r
+\r
+#endif /* INC_FREERTOS_H */\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest information,\r
+ license and contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under\r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. \r
+ *\r
+ * See http://www.freertos.org/a00110.html.\r
+ *----------------------------------------------------------*/\r
+\r
+#define configUSE_PREEMPTION 1\r
+#define configUSE_IDLE_HOOK 1\r
+#define configUSE_TICK_HOOK 1\r
+#define configUSE_TRACE_FACILITY 0\r
+#define configUSE_16_BIT_TICKS 0\r
+#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 90000000 ) /* Timer clock. */\r
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )\r
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 8 )\r
+#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) 32768 )\r
+#define configMAX_TASK_NAME_LEN ( 16 )\r
+#define configIDLE_SHOULD_YIELD 1\r
+#define configGENERATE_RUN_TIME_STATS 1\r
+#define configUSE_MALLOC_FAILED_HOOK 1\r
+\r
+#define configCHECK_FOR_STACK_OVERFLOW 2\r
+\r
+/* Co-routine definitions. */\r
+#define configUSE_CO_ROUTINES 0\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+\r
+/* Mutexes */\r
+#define configUSE_MUTEXES 1\r
+#define configUSE_RECURSIVE_MUTEXES 0\r
+\r
+/* Semaphores */\r
+#define configUSE_COUNTING_SEMAPHORES 1\r
+\r
+/* Timers */\r
+#define configUSE_TIMERS 1\r
+#define configTIMER_TASK_PRIORITY ( 2 )\r
+#define configTIMER_QUEUE_LENGTH 10\r
+#define configTIMER_TASK_STACK_DEPTH ( 128 )\r
+\r
+/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */\r
+#define INCLUDE_vTaskPrioritySet 1\r
+#define INCLUDE_uxTaskPriorityGet 1\r
+#define INCLUDE_vTaskDelete 0\r
+#define INCLUDE_vTaskCleanUpResources 0\r
+#define INCLUDE_vTaskSuspend 1\r
+#define INCLUDE_xTaskResumeFromISR 0\r
+#define INCLUDE_vTaskDelayUntil 1\r
+#define INCLUDE_vTaskDelay 1\r
+#define INCLUDE_xTaskGetSchedulerState 1\r
+#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
+\r
+#endif /* FREERTOS_CONFIG_H */\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef STACK_MACROS_H\r
+#define STACK_MACROS_H\r
+\r
+/*\r
+ * Call the stack overflow hook function if the stack of the task being swapped\r
+ * out is currently overflowed, or looks like it might have overflowed in the\r
+ * past.\r
+ *\r
+ * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check\r
+ * the current stack state only - comparing the current top of stack value to\r
+ * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1\r
+ * will also cause the last few stack bytes to be checked to ensure the value\r
+ * to which the bytes were set when the task was created have not been\r
+ * overwritten. Note this second test does not guarantee that an overflowed\r
+ * stack will always be recognised.\r
+ */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW == 0 )\r
+\r
+ /* FreeRTOSConfig.h is not set to check for stack overflows. */\r
+ #define taskFIRST_CHECK_FOR_STACK_OVERFLOW()\r
+ #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW == 1 )\r
+\r
+ /* FreeRTOSConfig.h is only set to use the first method of\r
+ overflow checking. */\r
+ #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )\r
+\r
+ /* Only the current stack state is to be checked. */\r
+ #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \\r
+ { \\r
+ /* Is the currently saved stack pointer within the stack limit? */ \\r
+ if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ }\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )\r
+\r
+ /* Only the current stack state is to be checked. */\r
+ #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \\r
+ { \\r
+ \\r
+ /* Is the currently saved stack pointer within the stack limit? */ \\r
+ if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ }\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )\r
+\r
+ #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \\r
+ { \\r
+ static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
+ \\r
+ \\r
+ /* Has the extremity of the task stack ever been written over? */ \\r
+ if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ }\r
+\r
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )\r
+\r
+ #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \\r
+ { \\r
+ char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \\r
+ static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
+ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
+ \\r
+ \\r
+ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \\r
+ \\r
+ /* Has the extremity of the task stack ever been written over? */ \\r
+ if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
+ { \\r
+ vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
+ } \\r
+ }\r
+\r
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+#endif /* STACK_MACROS_H */\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "croutine.h"\r
+\r
+/*\r
+ * Some kernel aware debuggers require data to be viewed to be global, rather\r
+ * than file scope.\r
+ */\r
+#ifdef portREMOVE_STATIC_QUALIFIER\r
+ #define static\r
+#endif\r
+\r
+\r
+/* Lists for ready and blocked co-routines. --------------------*/\r
+static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */\r
+static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */\r
+static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */\r
+static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */\r
+static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */\r
+static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */\r
+\r
+/* Other file private variables. --------------------------------*/\r
+corCRCB * pxCurrentCoRoutine = NULL;\r
+static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;\r
+static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;\r
+\r
+/* The initial state of the co-routine when it is created. */\r
+#define corINITIAL_STATE ( 0 )\r
+\r
+/*\r
+ * Place the co-routine represented by pxCRCB into the appropriate ready queue\r
+ * for the priority. It is inserted at the end of the list.\r
+ *\r
+ * This macro accesses the co-routine ready lists and therefore must not be\r
+ * used from within an ISR.\r
+ */\r
+#define prvAddCoRoutineToReadyQueue( pxCRCB ) \\r
+{ \\r
+ if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \\r
+ { \\r
+ uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \\r
+ } \\r
+ vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \\r
+} \r
+\r
+/*\r
+ * Utility to ready all the lists used by the scheduler. This is called\r
+ * automatically upon the creation of the first co-routine.\r
+ */\r
+static void prvInitialiseCoRoutineLists( void );\r
+\r
+/*\r
+ * Co-routines that are readied by an interrupt cannot be placed directly into\r
+ * the ready lists (there is no mutual exclusion). Instead they are placed in\r
+ * in the pending ready list in order that they can later be moved to the ready\r
+ * list by the co-routine scheduler.\r
+ */\r
+static void prvCheckPendingReadyList( void );\r
+\r
+/*\r
+ * Macro that looks at the list of co-routines that are currently delayed to\r
+ * see if any require waking.\r
+ *\r
+ * Co-routines are stored in the queue in the order of their wake time -\r
+ * meaning once one co-routine has been found whose timer has not expired\r
+ * we need not look any further down the list.\r
+ */\r
+static void prvCheckDelayedList( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+corCRCB *pxCoRoutine;\r
+\r
+ /* Allocate the memory that will store the co-routine control block. */\r
+ pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );\r
+ if( pxCoRoutine )\r
+ {\r
+ /* If pxCurrentCoRoutine is NULL then this is the first co-routine to\r
+ be created and the co-routine data structures need initialising. */\r
+ if( pxCurrentCoRoutine == NULL )\r
+ {\r
+ pxCurrentCoRoutine = pxCoRoutine;\r
+ prvInitialiseCoRoutineLists();\r
+ }\r
+\r
+ /* Check the priority is within limits. */\r
+ if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )\r
+ {\r
+ uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;\r
+ }\r
+\r
+ /* Fill out the co-routine control block from the function parameters. */\r
+ pxCoRoutine->uxState = corINITIAL_STATE;\r
+ pxCoRoutine->uxPriority = uxPriority;\r
+ pxCoRoutine->uxIndex = uxIndex;\r
+ pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;\r
+\r
+ /* Initialise all the other co-routine control block parameters. */\r
+ vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );\r
+ vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );\r
+\r
+ /* Set the co-routine control block as a link back from the xListItem.\r
+ This is so we can get back to the containing CRCB from a generic item\r
+ in a list. */\r
+ listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );\r
+ listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );\r
+ \r
+ /* Event lists are always in priority order. */\r
+ listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );\r
+ \r
+ /* Now the co-routine has been initialised it can be added to the ready\r
+ list at the correct priority. */\r
+ prvAddCoRoutineToReadyQueue( pxCoRoutine );\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ { \r
+ xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
+ }\r
+ \r
+ return xReturn; \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )\r
+{\r
+portTickType xTimeToWake;\r
+\r
+ /* Calculate the time to wake - this may overflow but this is\r
+ not a problem. */\r
+ xTimeToWake = xCoRoutineTickCount + xTicksToDelay;\r
+\r
+ /* We must remove ourselves from the ready list before adding\r
+ ourselves to the blocked list as the same list item is used for\r
+ both lists. */\r
+ vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );\r
+\r
+ /* The list item will be inserted in wake time order. */\r
+ listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );\r
+\r
+ if( xTimeToWake < xCoRoutineTickCount )\r
+ {\r
+ /* Wake time has overflowed. Place this item in the\r
+ overflow list. */\r
+ vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );\r
+ }\r
+ else\r
+ {\r
+ /* The wake time has not overflowed, so we can use the\r
+ current block list. */\r
+ vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );\r
+ }\r
+\r
+ if( pxEventList )\r
+ {\r
+ /* Also add the co-routine to an event list. If this is done then the\r
+ function must be called with interrupts disabled. */\r
+ vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckPendingReadyList( void )\r
+{\r
+ /* Are there any co-routines waiting to get moved to the ready list? These\r
+ are co-routines that have been readied by an ISR. The ISR cannot access\r
+ the ready lists itself. */\r
+ while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )\r
+ {\r
+ corCRCB *pxUnblockedCRCB;\r
+\r
+ /* The pending ready list can be accessed by an ISR. */\r
+ portDISABLE_INTERRUPTS();\r
+ { \r
+ pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); \r
+ vListRemove( &( pxUnblockedCRCB->xEventListItem ) );\r
+ }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ vListRemove( &( pxUnblockedCRCB->xGenericListItem ) );\r
+ prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); \r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckDelayedList( void )\r
+{\r
+corCRCB *pxCRCB;\r
+\r
+ xPassedTicks = xTaskGetTickCount() - xLastTickCount;\r
+ while( xPassedTicks )\r
+ {\r
+ xCoRoutineTickCount++;\r
+ xPassedTicks--;\r
+\r
+ /* If the tick count has overflowed we need to swap the ready lists. */\r
+ if( xCoRoutineTickCount == 0 )\r
+ {\r
+ xList * pxTemp;\r
+\r
+ /* Tick count has overflowed so we need to swap the delay lists. If there are\r
+ any items in pxDelayedCoRoutineList here then there is an error! */\r
+ pxTemp = pxDelayedCoRoutineList;\r
+ pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;\r
+ pxOverflowDelayedCoRoutineList = pxTemp;\r
+ }\r
+\r
+ /* See if this tick has made a timeout expire. */\r
+ while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )\r
+ {\r
+ pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );\r
+\r
+ if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) \r
+ { \r
+ /* Timeout not yet expired. */ \r
+ break; \r
+ } \r
+\r
+ portDISABLE_INTERRUPTS();\r
+ {\r
+ /* The event could have occurred just before this critical\r
+ section. If this is the case then the generic list item will\r
+ have been moved to the pending ready list and the following\r
+ line is still valid. Also the pvContainer parameter will have\r
+ been set to NULL so the following lines are also valid. */\r
+ vListRemove( &( pxCRCB->xGenericListItem ) ); \r
+\r
+ /* Is the co-routine waiting on an event also? */ \r
+ if( pxCRCB->xEventListItem.pvContainer ) \r
+ { \r
+ vListRemove( &( pxCRCB->xEventListItem ) ); \r
+ }\r
+ }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ prvAddCoRoutineToReadyQueue( pxCRCB ); \r
+ } \r
+ }\r
+\r
+ xLastTickCount = xCoRoutineTickCount;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCoRoutineSchedule( void )\r
+{\r
+ /* See if any co-routines readied by events need moving to the ready lists. */\r
+ prvCheckPendingReadyList();\r
+\r
+ /* See if any delayed co-routines have timed out. */\r
+ prvCheckDelayedList();\r
+\r
+ /* Find the highest priority queue that contains ready co-routines. */\r
+ while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )\r
+ {\r
+ if( uxTopCoRoutineReadyPriority == 0 )\r
+ {\r
+ /* No more co-routines to check. */\r
+ return;\r
+ }\r
+ --uxTopCoRoutineReadyPriority;\r
+ }\r
+\r
+ /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines\r
+ of the same priority get an equal share of the processor time. */\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );\r
+\r
+ /* Call the co-routine. */\r
+ ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );\r
+\r
+ return;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitialiseCoRoutineLists( void )\r
+{\r
+unsigned portBASE_TYPE uxPriority;\r
+\r
+ for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )\r
+ {\r
+ vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );\r
+ }\r
+\r
+ vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );\r
+ vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );\r
+ vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );\r
+\r
+ /* Start with pxDelayedCoRoutineList using list1 and the\r
+ pxOverflowDelayedCoRoutineList using list2. */\r
+ pxDelayedCoRoutineList = &xDelayedCoRoutineList1;\r
+ pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )\r
+{\r
+corCRCB *pxUnblockedCRCB;\r
+signed portBASE_TYPE xReturn;\r
+\r
+ /* This function is called from within an interrupt. It can only access\r
+ event lists and the pending ready list. This function assumes that a\r
+ check has already been made to ensure pxEventList is not empty. */\r
+ pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );\r
+ vListRemove( &( pxUnblockedCRCB->xEventListItem ) );\r
+ vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );\r
+\r
+ if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef CO_ROUTINE_H\r
+#define CO_ROUTINE_H\r
+\r
+#ifndef INC_FREERTOS_H\r
+ #error "include FreeRTOS.h must appear in source files before include croutine.h"\r
+#endif\r
+\r
+#include "list.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* Used to hide the implementation of the co-routine control block. The\r
+control block structure however has to be included in the header due to\r
+the macro implementation of the co-routine functionality. */\r
+typedef void * xCoRoutineHandle;\r
+\r
+/* Defines the prototype to which co-routine functions must conform. */\r
+typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );\r
+\r
+typedef struct corCoRoutineControlBlock\r
+{\r
+ crCOROUTINE_CODE pxCoRoutineFunction;\r
+ xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */\r
+ xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */\r
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */\r
+ unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */\r
+ unsigned short uxState; /*< Used internally by the co-routine implementation. */\r
+} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */\r
+\r
+/**\r
+ * croutine. h\r
+ *<pre>\r
+ portBASE_TYPE xCoRoutineCreate(\r
+ crCOROUTINE_CODE pxCoRoutineCode,\r
+ unsigned portBASE_TYPE uxPriority,\r
+ unsigned portBASE_TYPE uxIndex\r
+ );</pre>\r
+ *\r
+ * Create a new co-routine and add it to the list of co-routines that are\r
+ * ready to run.\r
+ *\r
+ * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine\r
+ * functions require special syntax - see the co-routine section of the WEB\r
+ * documentation for more information.\r
+ *\r
+ * @param uxPriority The priority with respect to other co-routines at which\r
+ * the co-routine will run.\r
+ *\r
+ * @param uxIndex Used to distinguish between different co-routines that\r
+ * execute the same function. See the example below and the co-routine section\r
+ * of the WEB documentation for further information.\r
+ *\r
+ * @return pdPASS if the co-routine was successfully created and added to a ready\r
+ * list, otherwise an error code defined with ProjDefs.h.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Co-routine to be created.\r
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
+ // This may not be necessary for const variables.\r
+ static const char cLedToFlash[ 2 ] = { 5, 6 };\r
+ static const portTickType uxFlashRates[ 2 ] = { 200, 400 };\r
+\r
+ // Must start every co-routine with a call to crSTART();\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // This co-routine just delays for a fixed period, then toggles\r
+ // an LED. Two co-routines are created using this function, so\r
+ // the uxIndex parameter is used to tell the co-routine which\r
+ // LED to flash and how long to delay. This assumes xQueue has\r
+ // already been created.\r
+ vParTestToggleLED( cLedToFlash[ uxIndex ] );\r
+ crDELAY( xHandle, uxFlashRates[ uxIndex ] );\r
+ }\r
+\r
+ // Must end every co-routine with a call to crEND();\r
+ crEND();\r
+ }\r
+\r
+ // Function that creates two co-routines.\r
+ void vOtherFunction( void )\r
+ {\r
+ unsigned char ucParameterToPass;\r
+ xTaskHandle xHandle;\r
+ \r
+ // Create two co-routines at priority 0. The first is given index 0\r
+ // so (from the code above) toggles LED 5 every 200 ticks. The second\r
+ // is given index 1 so toggles LED 6 every 400 ticks.\r
+ for( uxIndex = 0; uxIndex < 2; uxIndex++ )\r
+ {\r
+ xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xCoRoutineCreate xCoRoutineCreate\r
+ * \ingroup Tasks\r
+ */\r
+signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );\r
+\r
+\r
+/**\r
+ * croutine. h\r
+ *<pre>\r
+ void vCoRoutineSchedule( void );</pre>\r
+ *\r
+ * Run a co-routine.\r
+ *\r
+ * vCoRoutineSchedule() executes the highest priority co-routine that is able\r
+ * to run. The co-routine will execute until it either blocks, yields or is\r
+ * preempted by a task. Co-routines execute cooperatively so one\r
+ * co-routine cannot be preempted by another, but can be preempted by a task.\r
+ *\r
+ * If an application comprises of both tasks and co-routines then\r
+ * vCoRoutineSchedule should be called from the idle task (in an idle task\r
+ * hook).\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // This idle task hook will schedule a co-routine each time it is called.\r
+ // The rest of the idle task will execute between co-routine calls.\r
+ void vApplicationIdleHook( void )\r
+ {\r
+ vCoRoutineSchedule();\r
+ }\r
+\r
+ // Alternatively, if you do not require any other part of the idle task to\r
+ // execute, the idle task hook can call vCoRoutineScheduler() within an\r
+ // infinite loop.\r
+ void vApplicationIdleHook( void )\r
+ {\r
+ for( ;; )\r
+ {\r
+ vCoRoutineSchedule();\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule\r
+ * \ingroup Tasks\r
+ */\r
+void vCoRoutineSchedule( void );\r
+\r
+/**\r
+ * croutine. h\r
+ * <pre>\r
+ crSTART( xCoRoutineHandle xHandle );</pre>\r
+ *\r
+ * This macro MUST always be called at the start of a co-routine function.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Co-routine to be created.\r
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
+ static long ulAVariable;\r
+\r
+ // Must start every co-routine with a call to crSTART();\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // Co-routine functionality goes here.\r
+ }\r
+\r
+ // Must end every co-routine with a call to crEND();\r
+ crEND();\r
+ }</pre>\r
+ * \defgroup crSTART crSTART\r
+ * \ingroup Tasks\r
+ */\r
+#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:\r
+\r
+/**\r
+ * croutine. h\r
+ * <pre>\r
+ crEND();</pre>\r
+ *\r
+ * This macro MUST always be called at the end of a co-routine function.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Co-routine to be created.\r
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
+ static long ulAVariable;\r
+\r
+ // Must start every co-routine with a call to crSTART();\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // Co-routine functionality goes here.\r
+ }\r
+\r
+ // Must end every co-routine with a call to crEND();\r
+ crEND();\r
+ }</pre>\r
+ * \defgroup crSTART crSTART\r
+ * \ingroup Tasks\r
+ */\r
+#define crEND() }\r
+\r
+/*\r
+ * These macros are intended for internal use by the co-routine implementation\r
+ * only. The macros should not be used directly by application writers.\r
+ */\r
+#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):\r
+#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):\r
+\r
+/**\r
+ * croutine. h\r
+ *<pre>\r
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>\r
+ *\r
+ * Delay a co-routine for a fixed period of time.\r
+ *\r
+ * crDELAY can only be called from the co-routine function itself - not\r
+ * from within a function called by the co-routine function. This is because\r
+ * co-routines do not maintain their own stack.\r
+ *\r
+ * @param xHandle The handle of the co-routine to delay. This is the xHandle\r
+ * parameter of the co-routine function.\r
+ *\r
+ * @param xTickToDelay The number of ticks that the co-routine should delay\r
+ * for. The actual amount of time this equates to is defined by\r
+ * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS\r
+ * can be used to convert ticks to milliseconds.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Co-routine to be created.\r
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
+ // This may not be necessary for const variables.\r
+ // We are to delay for 200ms.\r
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;\r
+\r
+ // Must start every co-routine with a call to crSTART();\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // Delay for 200ms.\r
+ crDELAY( xHandle, xDelayTime );\r
+\r
+ // Do something here.\r
+ }\r
+\r
+ // Must end every co-routine with a call to crEND();\r
+ crEND();\r
+ }</pre>\r
+ * \defgroup crDELAY crDELAY\r
+ * \ingroup Tasks\r
+ */\r
+#define crDELAY( xHandle, xTicksToDelay ) \\r
+ if( ( xTicksToDelay ) > 0 ) \\r
+ { \\r
+ vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \\r
+ } \\r
+ crSET_STATE0( ( xHandle ) );\r
+\r
+/**\r
+ * <pre>\r
+ crQUEUE_SEND(\r
+ xCoRoutineHandle xHandle,\r
+ xQueueHandle pxQueue,\r
+ void *pvItemToQueue,\r
+ portTickType xTicksToWait,\r
+ portBASE_TYPE *pxResult\r
+ )</pre>\r
+ *\r
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
+ *\r
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
+ * xQueueSend() and xQueueReceive() can only be used from tasks.\r
+ *\r
+ * crQUEUE_SEND can only be called from the co-routine function itself - not\r
+ * from within a function called by the co-routine function. This is because\r
+ * co-routines do not maintain their own stack.\r
+ *\r
+ * See the co-routine section of the WEB documentation for information on\r
+ * passing data between tasks and co-routines and between ISR's and\r
+ * co-routines.\r
+ *\r
+ * @param xHandle The handle of the calling co-routine. This is the xHandle\r
+ * parameter of the co-routine function.\r
+ *\r
+ * @param pxQueue The handle of the queue on which the data will be posted.\r
+ * The handle is obtained as the return value when the queue is created using\r
+ * the xQueueCreate() API function.\r
+ *\r
+ * @param pvItemToQueue A pointer to the data being posted onto the queue.\r
+ * The number of bytes of each queued item is specified when the queue is\r
+ * created. This number of bytes is copied from pvItemToQueue into the queue\r
+ * itself.\r
+ *\r
+ * @param xTickToDelay The number of ticks that the co-routine should block\r
+ * to wait for space to become available on the queue, should space not be\r
+ * available immediately. The actual amount of time this equates to is defined\r
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example\r
+ * below).\r
+ *\r
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
+ * data was successfully posted onto the queue, otherwise it will be set to an\r
+ * error defined within ProjDefs.h.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Co-routine function that blocks for a fixed period then posts a number onto\r
+ // a queue.\r
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
+ static portBASE_TYPE xNumberToPost = 0;\r
+ static portBASE_TYPE xResult;\r
+\r
+ // Co-routines must begin with a call to crSTART().\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // This assumes the queue has already been created.\r
+ crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );\r
+\r
+ if( xResult != pdPASS )\r
+ {\r
+ // The message was not posted!\r
+ }\r
+\r
+ // Increment the number to be posted onto the queue.\r
+ xNumberToPost++;\r
+\r
+ // Delay for 100 ticks.\r
+ crDELAY( xHandle, 100 );\r
+ }\r
+\r
+ // Co-routines must end with a call to crEND().\r
+ crEND();\r
+ }</pre>\r
+ * \defgroup crQUEUE_SEND crQUEUE_SEND\r
+ * \ingroup Tasks\r
+ */\r
+#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \\r
+{ \\r
+ *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \\r
+ if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
+ { \\r
+ crSET_STATE0( ( xHandle ) ); \\r
+ *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \\r
+ } \\r
+ if( *pxResult == errQUEUE_YIELD ) \\r
+ { \\r
+ crSET_STATE1( ( xHandle ) ); \\r
+ *pxResult = pdPASS; \\r
+ } \\r
+}\r
+\r
+/**\r
+ * croutine. h\r
+ * <pre>\r
+ crQUEUE_RECEIVE(\r
+ xCoRoutineHandle xHandle,\r
+ xQueueHandle pxQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait,\r
+ portBASE_TYPE *pxResult\r
+ )</pre>\r
+ *\r
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
+ *\r
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
+ * xQueueSend() and xQueueReceive() can only be used from tasks.\r
+ *\r
+ * crQUEUE_RECEIVE can only be called from the co-routine function itself - not\r
+ * from within a function called by the co-routine function. This is because\r
+ * co-routines do not maintain their own stack.\r
+ *\r
+ * See the co-routine section of the WEB documentation for information on\r
+ * passing data between tasks and co-routines and between ISR's and\r
+ * co-routines.\r
+ *\r
+ * @param xHandle The handle of the calling co-routine. This is the xHandle\r
+ * parameter of the co-routine function.\r
+ *\r
+ * @param pxQueue The handle of the queue from which the data will be received.\r
+ * The handle is obtained as the return value when the queue is created using\r
+ * the xQueueCreate() API function.\r
+ *\r
+ * @param pvBuffer The buffer into which the received item is to be copied.\r
+ * The number of bytes of each queued item is specified when the queue is\r
+ * created. This number of bytes is copied into pvBuffer.\r
+ *\r
+ * @param xTickToDelay The number of ticks that the co-routine should block\r
+ * to wait for data to become available from the queue, should data not be\r
+ * available immediately. The actual amount of time this equates to is defined\r
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the\r
+ * crQUEUE_SEND example).\r
+ *\r
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
+ * data was successfully retrieved from the queue, otherwise it will be set to\r
+ * an error code as defined within ProjDefs.h.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // A co-routine receives the number of an LED to flash from a queue. It\r
+ // blocks on the queue until the number is received.\r
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
+ static portBASE_TYPE xResult;\r
+ static unsigned portBASE_TYPE uxLEDToFlash;\r
+\r
+ // All co-routines must start with a call to crSTART().\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // Wait for data to become available on the queue.\r
+ crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
+\r
+ if( xResult == pdPASS )\r
+ {\r
+ // We received the LED to flash - flash it!\r
+ vParTestToggleLED( uxLEDToFlash );\r
+ }\r
+ }\r
+\r
+ crEND();\r
+ }</pre>\r
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE\r
+ * \ingroup Tasks\r
+ */\r
+#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \\r
+{ \\r
+ *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \\r
+ if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
+ { \\r
+ crSET_STATE0( ( xHandle ) ); \\r
+ *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \\r
+ } \\r
+ if( *( pxResult ) == errQUEUE_YIELD ) \\r
+ { \\r
+ crSET_STATE1( ( xHandle ) ); \\r
+ *( pxResult ) = pdPASS; \\r
+ } \\r
+}\r
+\r
+/**\r
+ * croutine. h\r
+ * <pre>\r
+ crQUEUE_SEND_FROM_ISR(\r
+ xQueueHandle pxQueue,\r
+ void *pvItemToQueue,\r
+ portBASE_TYPE xCoRoutinePreviouslyWoken\r
+ )</pre>\r
+ *\r
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
+ * functions used by tasks.\r
+ *\r
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
+ * ISR.\r
+ *\r
+ * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue\r
+ * that is being used from within a co-routine.\r
+ *\r
+ * See the co-routine section of the WEB documentation for information on\r
+ * passing data between tasks and co-routines and between ISR's and\r
+ * co-routines.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto\r
+ * the same queue multiple times from a single interrupt. The first call\r
+ * should always pass in pdFALSE. Subsequent calls should pass in\r
+ * the value returned from the previous call.\r
+ *\r
+ * @return pdTRUE if a co-routine was woken by posting onto the queue. This is\r
+ * used by the ISR to determine if a context switch may be required following\r
+ * the ISR.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // A co-routine that blocks on a queue waiting for characters to be received.\r
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ char cRxedChar;\r
+ portBASE_TYPE xResult;\r
+\r
+ // All co-routines must start with a call to crSTART().\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // Wait for data to become available on the queue. This assumes the\r
+ // queue xCommsRxQueue has already been created!\r
+ crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
+\r
+ // Was a character received?\r
+ if( xResult == pdPASS )\r
+ {\r
+ // Process the character here.\r
+ }\r
+ }\r
+\r
+ // All co-routines must end with a call to crEND().\r
+ crEND();\r
+ }\r
+\r
+ // An ISR that uses a queue to send characters received on a serial port to\r
+ // a co-routine.\r
+ void vUART_ISR( void )\r
+ {\r
+ char cRxedChar;\r
+ portBASE_TYPE xCRWokenByPost = pdFALSE;\r
+\r
+ // We loop around reading characters until there are none left in the UART.\r
+ while( UART_RX_REG_NOT_EMPTY() )\r
+ {\r
+ // Obtain the character from the UART.\r
+ cRxedChar = UART_RX_REG;\r
+\r
+ // Post the character onto a queue. xCRWokenByPost will be pdFALSE\r
+ // the first time around the loop. If the post causes a co-routine\r
+ // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.\r
+ // In this manner we can ensure that if more than one co-routine is\r
+ // blocked on the queue only one is woken by this ISR no matter how\r
+ // many characters are posted to the queue.\r
+ xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );\r
+ }\r
+ }</pre>\r
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR\r
+ * \ingroup Tasks\r
+ */\r
+#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )\r
+\r
+\r
+/**\r
+ * croutine. h\r
+ * <pre>\r
+ crQUEUE_SEND_FROM_ISR(\r
+ xQueueHandle pxQueue,\r
+ void *pvBuffer,\r
+ portBASE_TYPE * pxCoRoutineWoken\r
+ )</pre>\r
+ *\r
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
+ * functions used by tasks.\r
+ *\r
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
+ * ISR.\r
+ *\r
+ * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data\r
+ * from a queue that is being used from within a co-routine (a co-routine\r
+ * posted to the queue).\r
+ *\r
+ * See the co-routine section of the WEB documentation for information on\r
+ * passing data between tasks and co-routines and between ISR's and\r
+ * co-routines.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvBuffer A pointer to a buffer into which the received item will be\r
+ * placed. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from the queue into\r
+ * pvBuffer.\r
+ *\r
+ * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become\r
+ * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a\r
+ * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise\r
+ * *pxCoRoutineWoken will remain unchanged.\r
+ *\r
+ * @return pdTRUE an item was successfully received from the queue, otherwise\r
+ * pdFALSE.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // A co-routine that posts a character to a queue then blocks for a fixed\r
+ // period. The character is incremented each time.\r
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
+ {\r
+ // cChar holds its value while this co-routine is blocked and must therefore\r
+ // be declared static.\r
+ static char cCharToTx = 'a';\r
+ portBASE_TYPE xResult;\r
+\r
+ // All co-routines must start with a call to crSTART().\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ // Send the next character to the queue.\r
+ crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );\r
+\r
+ if( xResult == pdPASS )\r
+ {\r
+ // The character was successfully posted to the queue.\r
+ }\r
+ else\r
+ {\r
+ // Could not post the character to the queue.\r
+ }\r
+\r
+ // Enable the UART Tx interrupt to cause an interrupt in this\r
+ // hypothetical UART. The interrupt will obtain the character\r
+ // from the queue and send it.\r
+ ENABLE_RX_INTERRUPT();\r
+\r
+ // Increment to the next character then block for a fixed period.\r
+ // cCharToTx will maintain its value across the delay as it is\r
+ // declared static.\r
+ cCharToTx++;\r
+ if( cCharToTx > 'x' )\r
+ {\r
+ cCharToTx = 'a';\r
+ }\r
+ crDELAY( 100 );\r
+ }\r
+\r
+ // All co-routines must end with a call to crEND().\r
+ crEND();\r
+ }\r
+\r
+ // An ISR that uses a queue to receive characters to send on a UART.\r
+ void vUART_ISR( void )\r
+ {\r
+ char cCharToTx;\r
+ portBASE_TYPE xCRWokenByPost = pdFALSE;\r
+\r
+ while( UART_TX_REG_EMPTY() )\r
+ {\r
+ // Are there any characters in the queue waiting to be sent?\r
+ // xCRWokenByPost will automatically be set to pdTRUE if a co-routine\r
+ // is woken by the post - ensuring that only a single co-routine is\r
+ // woken no matter how many times we go around this loop.\r
+ if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )\r
+ {\r
+ SEND_CHARACTER( cCharToTx );\r
+ }\r
+ }\r
+ }</pre>\r
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR\r
+ * \ingroup Tasks\r
+ */\r
+#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )\r
+\r
+/*\r
+ * This function is intended for internal use by the co-routine macros only.\r
+ * The macro nature of the co-routine implementation requires that the\r
+ * prototype appears here. The function should not be used by application\r
+ * writers.\r
+ *\r
+ * Removes the current co-routine from its ready list and places it in the\r
+ * appropriate delayed list.\r
+ */\r
+void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );\r
+\r
+/*\r
+ * This function is intended for internal use by the queue implementation only.\r
+ * The function should not be used by application writers.\r
+ *\r
+ * Removes the highest priority co-routine from the event list and places it in\r
+ * the pending ready list.\r
+ */\r
+signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* CO_ROUTINE_H */\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+\r
+/*\r
+ * The simplest possible implementation of pvPortMalloc(). Note that this\r
+ * implementation does NOT allow allocated memory to be freed again.\r
+ *\r
+ * See heap_2.c and heap_3.c for alternative implementations, and the memory\r
+ * management pages of http://www.FreeRTOS.org for more information.\r
+ */\r
+#include <stdlib.h>\r
+\r
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
+all the API functions to use the MPU wrappers. That should only be done when\r
+task.h is included from an application file. */\r
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+#pragma DATA_SECTION(xHeap, ".heap")\r
+#pragma DATA_ALIGN(xHeap, 8)\r
+\r
+/* Allocate the memory for the heap. The struct is used to force byte\r
+alignment without using any non-portable code. */\r
+static union xRTOS_HEAP\r
+{\r
+ unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];\r
+} xHeap;\r
+\r
+static size_t xNextFreeByte = ( size_t ) 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void *pvPortMalloc( size_t xWantedSize )\r
+{\r
+void *pvReturn = NULL; \r
+\r
+ /* Ensure that blocks are always aligned to the required number of bytes. */\r
+ #if portBYTE_ALIGNMENT != 1\r
+ if( xWantedSize & portBYTE_ALIGNMENT_MASK )\r
+ {\r
+ /* Byte alignment required. */\r
+ xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );\r
+ }\r
+ #endif\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ /* Check there is enough room left for the allocation. */\r
+ if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&\r
+ ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */\r
+ {\r
+ /* Return the next free byte then increment the index past this\r
+ block. */\r
+ pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] );\r
+ xNextFreeByte += xWantedSize; \r
+ } \r
+ }\r
+ xTaskResumeAll();\r
+ \r
+ #if( configUSE_MALLOC_FAILED_HOOK == 1 )\r
+ {\r
+ if( pvReturn == NULL )\r
+ {\r
+ extern void vApplicationMallocFailedHook( void );\r
+ vApplicationMallocFailedHook();\r
+ }\r
+ }\r
+ #endif \r
+\r
+ return pvReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortFree( void *pv )\r
+{\r
+ /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c \r
+ for alternative implementations, and the memory management pages of \r
+ http://www.FreeRTOS.org for more information. */\r
+ ( void ) pv;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortInitialiseBlocks( void )\r
+{\r
+ /* Only required when static memory is not cleared. */\r
+ xNextFreeByte = ( size_t ) 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+size_t xPortGetFreeHeapSize( void )\r
+{\r
+ return ( configTOTAL_HEAP_SIZE - xNextFreeByte );\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+\r
+#include <stdlib.h>\r
+#include "FreeRTOS.h"\r
+#include "list.h"\r
+\r
+/*-----------------------------------------------------------\r
+ * PUBLIC LIST API documented in list.h\r
+ *----------------------------------------------------------*/\r
+\r
+void vListInitialise( xList *pxList )\r
+{\r
+ /* The list structure contains a list item which is used to mark the\r
+ end of the list. To initialise the list the list end is inserted\r
+ as the only list entry. */\r
+ pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );\r
+\r
+ /* The list end value is the highest possible value in the list to\r
+ ensure it remains at the end of the list. */\r
+ pxList->xListEnd.xItemValue = portMAX_DELAY;\r
+\r
+ /* The list end next and previous pointers point to itself so we know\r
+ when the list is empty. */\r
+ pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );\r
+ pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );\r
+\r
+ pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vListInitialiseItem( xListItem *pxItem )\r
+{\r
+ /* Make sure the list item is not recorded as being on a list. */\r
+ pxItem->pvContainer = NULL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )\r
+{\r
+volatile xListItem * pxIndex;\r
+\r
+ /* Insert a new list item into pxList, but rather than sort the list,\r
+ makes the new list item the last item to be removed by a call to\r
+ pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by\r
+ the pxIndex member. */\r
+ pxIndex = pxList->pxIndex;\r
+\r
+ pxNewListItem->pxNext = pxIndex->pxNext;\r
+ pxNewListItem->pxPrevious = pxList->pxIndex;\r
+ pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;\r
+ pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;\r
+ pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;\r
+\r
+ /* Remember which list the item is in. */\r
+ pxNewListItem->pvContainer = ( void * ) pxList;\r
+\r
+ ( pxList->uxNumberOfItems )++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vListInsert( xList *pxList, xListItem *pxNewListItem )\r
+{\r
+volatile xListItem *pxIterator;\r
+portTickType xValueOfInsertion;\r
+\r
+ /* Insert the new list item into the list, sorted in ulListItem order. */\r
+ xValueOfInsertion = pxNewListItem->xItemValue;\r
+\r
+ /* If the list already contains a list item with the same item value then\r
+ the new list item should be placed after it. This ensures that TCB's which\r
+ are stored in ready lists (all of which have the same ulListItem value)\r
+ get an equal share of the CPU. However, if the xItemValue is the same as\r
+ the back marker the iteration loop below will not end. This means we need\r
+ to guard against this by checking the value first and modifying the\r
+ algorithm slightly if necessary. */\r
+ if( xValueOfInsertion == portMAX_DELAY )\r
+ {\r
+ pxIterator = pxList->xListEnd.pxPrevious;\r
+ }\r
+ else\r
+ {\r
+ /* *** NOTE ***********************************************************\r
+ If you find your application is crashing here then likely causes are:\r
+ 1) Stack overflow -\r
+ see http://www.freertos.org/Stacks-and-stack-overflow-checking.html\r
+ 2) Incorrect interrupt priority assignment, especially on Cortex-M3\r
+ parts where numerically high priority values denote low actual\r
+ interrupt priories, which can seem counter intuitive. See\r
+ configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html\r
+ 3) Calling an API function from within a critical section or when\r
+ the scheduler is suspended.\r
+ 4) Using a queue or semaphore before it has been initialised or\r
+ before the scheduler has been started (are interrupts firing\r
+ before vTaskStartScheduler() has been called?).\r
+ See http://www.freertos.org/FAQHelp.html for more tips.\r
+ **********************************************************************/\r
+ \r
+ for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )\r
+ {\r
+ /* There is nothing to do here, we are just iterating to the\r
+ wanted insertion position. */\r
+ }\r
+ }\r
+\r
+ pxNewListItem->pxNext = pxIterator->pxNext;\r
+ pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;\r
+ pxNewListItem->pxPrevious = pxIterator;\r
+ pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;\r
+\r
+ /* Remember which list the item is in. This allows fast removal of the\r
+ item later. */\r
+ pxNewListItem->pvContainer = ( void * ) pxList;\r
+\r
+ ( pxList->uxNumberOfItems )++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vListRemove( xListItem *pxItemToRemove )\r
+{\r
+xList * pxList;\r
+\r
+ pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;\r
+ pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;\r
+ \r
+ /* The list item knows which list it is in. Obtain the list from the list\r
+ item. */\r
+ pxList = ( xList * ) pxItemToRemove->pvContainer;\r
+\r
+ /* Make sure the index is left pointing to a valid item. */\r
+ if( pxList->pxIndex == pxItemToRemove )\r
+ {\r
+ pxList->pxIndex = pxItemToRemove->pxPrevious;\r
+ }\r
+\r
+ pxItemToRemove->pvContainer = NULL;\r
+ ( pxList->uxNumberOfItems )--;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/*\r
+ * This is the list implementation used by the scheduler. While it is tailored\r
+ * heavily for the schedulers needs, it is also available for use by\r
+ * application code.\r
+ *\r
+ * xLists can only store pointers to xListItems. Each xListItem contains a\r
+ * numeric value (xItemValue). Most of the time the lists are sorted in\r
+ * descending item value order.\r
+ *\r
+ * Lists are created already containing one list item. The value of this\r
+ * item is the maximum possible that can be stored, it is therefore always at\r
+ * the end of the list and acts as a marker. The list member pxHead always\r
+ * points to this marker - even though it is at the tail of the list. This\r
+ * is because the tail contains a wrap back pointer to the true head of\r
+ * the list.\r
+ *\r
+ * In addition to it's value, each list item contains a pointer to the next\r
+ * item in the list (pxNext), a pointer to the list it is in (pxContainer)\r
+ * and a pointer to back to the object that contains it. These later two\r
+ * pointers are included for efficiency of list manipulation. There is\r
+ * effectively a two way link between the object containing the list item and\r
+ * the list item itself.\r
+ *\r
+ *\r
+ * \page ListIntroduction List Implementation\r
+ * \ingroup FreeRTOSIntro\r
+ */\r
+\r
+\r
+#ifndef LIST_H\r
+#define LIST_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+/*\r
+ * Definition of the only type of object that a list can contain.\r
+ */\r
+struct xLIST_ITEM\r
+{\r
+ portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */\r
+ volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */\r
+ volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */\r
+ void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */\r
+ void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */\r
+};\r
+typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */\r
+\r
+struct xMINI_LIST_ITEM\r
+{\r
+ portTickType xItemValue;\r
+ volatile struct xLIST_ITEM *pxNext;\r
+ volatile struct xLIST_ITEM *pxPrevious;\r
+};\r
+typedef struct xMINI_LIST_ITEM xMiniListItem;\r
+\r
+/*\r
+ * Definition of the type of queue used by the scheduler.\r
+ */\r
+typedef struct xLIST\r
+{\r
+ volatile unsigned portBASE_TYPE uxNumberOfItems;\r
+ volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */\r
+ volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */\r
+} xList;\r
+\r
+/*\r
+ * Access macro to set the owner of a list item. The owner of a list item\r
+ * is the object (usually a TCB) that contains the list item.\r
+ *\r
+ * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
+ * \ingroup LinkedList\r
+ */\r
+#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) ( pxOwner )\r
+\r
+/*\r
+ * Access macro to get the owner of a list item. The owner of a list item\r
+ * is the object (usually a TCB) that contains the list item.\r
+ *\r
+ * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
+ * \ingroup LinkedList\r
+ */\r
+#define listGET_LIST_ITEM_OWNER( pxListItem ) ( pxListItem )->pvOwner\r
+\r
+/*\r
+ * Access macro to set the value of the list item. In most cases the value is\r
+ * used to sort the list in descending order.\r
+ *\r
+ * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE\r
+ * \ingroup LinkedList\r
+ */\r
+#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue )\r
+\r
+/*\r
+ * Access macro to retrieve the value of the list item. The value can\r
+ * represent anything - for example a the priority of a task, or the time at\r
+ * which a task should be unblocked.\r
+ *\r
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
+ * \ingroup LinkedList\r
+ */\r
+#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )\r
+\r
+/*\r
+ * Access macro the retrieve the value of the list item at the head of a given\r
+ * list.\r
+ *\r
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
+ * \ingroup LinkedList\r
+ */\r
+#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )\r
+\r
+/*\r
+ * Access macro to determine if a list contains any items. The macro will\r
+ * only have the value true if the list is empty.\r
+ *\r
+ * \page listLIST_IS_EMPTY listLIST_IS_EMPTY\r
+ * \ingroup LinkedList\r
+ */\r
+#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )\r
+\r
+/*\r
+ * Access macro to return the number of items in the list.\r
+ */\r
+#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )\r
+\r
+/*\r
+ * Access function to obtain the owner of the next entry in a list.\r
+ *\r
+ * The list member pxIndex is used to walk through a list. Calling\r
+ * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list\r
+ * and returns that entries pxOwner parameter. Using multiple calls to this\r
+ * function it is therefore possible to move through every item contained in\r
+ * a list.\r
+ *\r
+ * The pxOwner parameter of a list item is a pointer to the object that owns\r
+ * the list item. In the scheduler this is normally a task control block.\r
+ * The pxOwner parameter effectively creates a two way link between the list\r
+ * item and its owner.\r
+ *\r
+ * @param pxList The list from which the next item owner is to be returned.\r
+ *\r
+ * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY\r
+ * \ingroup LinkedList\r
+ */\r
+#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \\r
+{ \\r
+xList * const pxConstList = ( pxList ); \\r
+ /* Increment the index to the next item and return the item, ensuring */ \\r
+ /* we don't return the marker used at the end of the list. */ \\r
+ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \\r
+ if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \\r
+ { \\r
+ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \\r
+ } \\r
+ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \\r
+}\r
+\r
+\r
+/*\r
+ * Access function to obtain the owner of the first entry in a list. Lists\r
+ * are normally sorted in ascending item value order.\r
+ *\r
+ * This function returns the pxOwner member of the first item in the list.\r
+ * The pxOwner parameter of a list item is a pointer to the object that owns\r
+ * the list item. In the scheduler this is normally a task control block.\r
+ * The pxOwner parameter effectively creates a two way link between the list\r
+ * item and its owner.\r
+ *\r
+ * @param pxList The list from which the owner of the head item is to be\r
+ * returned.\r
+ *\r
+ * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY\r
+ * \ingroup LinkedList\r
+ */\r
+#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )\r
+\r
+/*\r
+ * Check to see if a list item is within a list. The list item maintains a\r
+ * "container" pointer that points to the list it is in. All this macro does\r
+ * is check to see if the container and the list match.\r
+ *\r
+ * @param pxList The list we want to know if the list item is within.\r
+ * @param pxListItem The list item we want to know if is in the list.\r
+ * @return pdTRUE is the list item is in the list, otherwise pdFALSE.\r
+ * pointer against\r
+ */\r
+#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )\r
+\r
+/*\r
+ * This provides a crude means of knowing if a list has been initialised, as\r
+ * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()\r
+ * function.\r
+ */\r
+#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )\r
+\r
+/*\r
+ * Must be called before a list is used! This initialises all the members\r
+ * of the list structure and inserts the xListEnd item into the list as a\r
+ * marker to the back of the list.\r
+ *\r
+ * @param pxList Pointer to the list being initialised.\r
+ *\r
+ * \page vListInitialise vListInitialise\r
+ * \ingroup LinkedList\r
+ */\r
+void vListInitialise( xList *pxList );\r
+\r
+/*\r
+ * Must be called before a list item is used. This sets the list container to\r
+ * null so the item does not think that it is already contained in a list.\r
+ *\r
+ * @param pxItem Pointer to the list item being initialised.\r
+ *\r
+ * \page vListInitialiseItem vListInitialiseItem\r
+ * \ingroup LinkedList\r
+ */\r
+void vListInitialiseItem( xListItem *pxItem );\r
+\r
+/*\r
+ * Insert a list item into a list. The item will be inserted into the list in\r
+ * a position determined by its item value (descending item value order).\r
+ *\r
+ * @param pxList The list into which the item is to be inserted.\r
+ *\r
+ * @param pxNewListItem The item to that is to be placed in the list.\r
+ *\r
+ * \page vListInsert vListInsert\r
+ * \ingroup LinkedList\r
+ */\r
+void vListInsert( xList *pxList, xListItem *pxNewListItem );\r
+\r
+/*\r
+ * Insert a list item into a list. The item will be inserted in a position\r
+ * such that it will be the last item within the list returned by multiple\r
+ * calls to listGET_OWNER_OF_NEXT_ENTRY.\r
+ *\r
+ * The list member pvIndex is used to walk through a list. Calling\r
+ * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.\r
+ * Placing an item in a list using vListInsertEnd effectively places the item\r
+ * in the list position pointed to by pvIndex. This means that every other\r
+ * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before\r
+ * the pvIndex parameter again points to the item being inserted.\r
+ *\r
+ * @param pxList The list into which the item is to be inserted.\r
+ *\r
+ * @param pxNewListItem The list item to be inserted into the list.\r
+ *\r
+ * \page vListInsertEnd vListInsertEnd\r
+ * \ingroup LinkedList\r
+ */\r
+void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );\r
+\r
+/*\r
+ * Remove an item from a list. The list item has a pointer to the list that\r
+ * it is in, so only the list item need be passed into the function.\r
+ *\r
+ * @param vListRemove The item to be removed. The item will remove itself from\r
+ * the list pointed to by it's pxContainer parameter.\r
+ *\r
+ * \page vListRemove vListRemove\r
+ * \ingroup LinkedList\r
+ */\r
+void vListRemove( xListItem *pxItemToRemove );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef MPU_WRAPPERS_H\r
+#define MPU_WRAPPERS_H\r
+\r
+/* This file redefines API functions to be called through a wrapper macro, but\r
+only for ports that are using the MPU. */\r
+#ifdef portUSING_MPU_WRAPPERS\r
+\r
+ /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is\r
+ included from queue.c or task.c to prevent it from having an effect within\r
+ those files. */\r
+ #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+ #define xTaskGenericCreate MPU_xTaskGenericCreate\r
+ #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions\r
+ #define vTaskDelete MPU_vTaskDelete\r
+ #define vTaskDelayUntil MPU_vTaskDelayUntil\r
+ #define vTaskDelay MPU_vTaskDelay\r
+ #define uxTaskPriorityGet MPU_uxTaskPriorityGet\r
+ #define vTaskPrioritySet MPU_vTaskPrioritySet\r
+ #define vTaskSuspend MPU_vTaskSuspend\r
+ #define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended\r
+ #define vTaskResume MPU_vTaskResume\r
+ #define vTaskSuspendAll MPU_vTaskSuspendAll\r
+ #define xTaskResumeAll MPU_xTaskResumeAll\r
+ #define xTaskGetTickCount MPU_xTaskGetTickCount\r
+ #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks\r
+ #define vTaskList MPU_vTaskList\r
+ #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats\r
+ #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag\r
+ #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag\r
+ #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook\r
+ #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark\r
+ #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle\r
+ #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState\r
+\r
+ #define xQueueGenericCreate MPU_xQueueGenericCreate\r
+ #define xQueueCreateMutex MPU_xQueueCreateMutex\r
+ #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive\r
+ #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive\r
+ #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore\r
+ #define xQueueGenericSend MPU_xQueueGenericSend\r
+ #define xQueueAltGenericSend MPU_xQueueAltGenericSend\r
+ #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive\r
+ #define xQueueGenericReceive MPU_xQueueGenericReceive\r
+ #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting\r
+ #define vQueueDelete MPU_vQueueDelete\r
+\r
+ #define pvPortMalloc MPU_pvPortMalloc\r
+ #define vPortFree MPU_vPortFree\r
+ #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize\r
+ #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks\r
+\r
+ #if configQUEUE_REGISTRY_SIZE > 0\r
+ #define vQueueAddToRegistry MPU_vQueueAddToRegistry\r
+ #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue\r
+ #endif\r
+\r
+ /* Remove the privileged function macro. */\r
+ #define PRIVILEGED_FUNCTION\r
+\r
+ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */\r
+\r
+ /* Ensure API functions go in the privileged execution section. */\r
+ #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))\r
+ #define PRIVILEGED_DATA __attribute__((section("privileged_data")))\r
+ //#define PRIVILEGED_DATA\r
+\r
+ #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */\r
+\r
+#else /* portUSING_MPU_WRAPPERS */\r
+\r
+ #define PRIVILEGED_FUNCTION\r
+ #define PRIVILEGED_DATA\r
+ #define portUSING_MPU_WRAPPERS 0\r
+\r
+#endif /* portUSING_MPU_WRAPPERS */\r
+\r
+\r
+#endif /* MPU_WRAPPERS_H */\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Include Files */\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Global Variables */\r
+\r
+unsigned portLONG ulCriticalNesting = 9999;\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Macros */\r
+\r
+#define portINITIAL_SPSR ((portSTACK_TYPE) 0x1F)\r
+#define portINITIAL_FPSCR ((portSTACK_TYPE) 0x00)\r
+#define portINSTRUCTION_SIZE ((portSTACK_TYPE) 0x04)\r
+#define portTHUMB_MODE_BIT ((portSTACK_TYPE) 0x20)\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* pxPortInitialiseStack */\r
+\r
+portSTACK_TYPE * pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters)\r
+{\r
+ portSTACK_TYPE *pxOriginalTOS = pxTopOfStack;\r
+ \r
+ *pxTopOfStack-- = (portSTACK_TYPE) pxCode + portINSTRUCTION_SIZE; \r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0xaaaaaaaa;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) pxOriginalTOS;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x12121212;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x11111111;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x10101010;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x09090909;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x08080808;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x07070707;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x06060606;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x05050505;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x04040404;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x03030303;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x02020202;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x01010101;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) pvParameters;\r
+\r
+#if __TI_VFPV3D16_SUPPORT__\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x3F3F3F3F;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x3E3E3E3E;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x3D3D3D3D;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x3C3C3C3C;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x3B3B3B3B;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x3A3A3A3A;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x39393939;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x38383838;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x37373737;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x36363636;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x35353535;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x34343434;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x33333333;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x32323232;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x31313131;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x30303030;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x2F2F2F2F;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x2E2E2E2E;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x2D2D2D2D;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x2C2C2C2C;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x2B2B2B2B;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x2A2A2A2A;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x29292929;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x28282828;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x27272727;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x26262626;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x25252525;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x24242424;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x23232323;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x22222222;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x21212121;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) 0x20202020;\r
+ *pxTopOfStack-- = (portSTACK_TYPE) portINITIAL_FPSCR;\r
+#endif\r
+\r
+\r
+ *pxTopOfStack = (portSTACK_TYPE) ((_get_CPSR() & ~0xFF) | portINITIAL_SPSR);\r
+\r
+ if (((unsigned long) pxCode & 0x01UL) != 0x00)\r
+ {\r
+ *pxTopOfStack |= portTHUMB_MODE_BIT;\r
+ }\r
+\r
+ return pxTopOfStack;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* prvSetupTimerInterrupt */\r
+\r
+static void prvSetupTimerInterrupt(void)\r
+{\r
+#if (configGENERATE_RUN_TIME_STATS == 1)\r
+ RTI->GCTRL &= ~0x00000001U;\r
+#else\r
+ RTI->GCTRL = 0x00000000U;\r
+#endif\r
+ RTI->TBCTRL = 0x00000000U;\r
+ RTI->COMPCTRL = 0x00000000U;\r
+ RTI->CNT[0U].UCx = 0x00000000U;\r
+ RTI->CNT[0U].FRCx = 0x00000000U;\r
+ RTI->CNT[0U].CPUCx = 0x00000001U;\r
+ RTI->CMP[0U].COMPx = configCPU_CLOCK_HZ / 2 / configTICK_RATE_HZ;\r
+ RTI->CMP[0U].UDCPx = configCPU_CLOCK_HZ / 2 / configTICK_RATE_HZ;\r
+ RTI->INTFLAG = 0x0007000FU;\r
+ RTI->CLEARINT = 0x00070F0FU;\r
+ RTI->SETINT = 0x00000001U;\r
+ RTI->GCTRL |= 0x00000001U;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* vPortStartFirstTask */\r
+\r
+/* vPortStartFirstSTask() is defined in portASM.asm */\r
+extern void vPortStartFirstTask(void);\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* xPortStartScheduler */\r
+\r
+portBASE_TYPE xPortStartScheduler(void)\r
+{\r
+ /* Start the timer that generates the tick ISR. */\r
+ prvSetupTimerInterrupt();\r
+ /* Enable critical sections */\r
+ ulCriticalNesting = 0;\r
+ /* Start the first task. This is done from portASM.asm as ARM mode must be\r
+ used. */\r
+ vPortStartFirstTask(); \r
+ /* Should not get here! */\r
+ return 0;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* vPortEndScheduler */\r
+\r
+void vPortEndScheduler(void)\r
+{\r
+ /* It is unlikely that the ARM port will require this function as there\r
+ is nothing to return to. If this is required - stop the tick ISR then\r
+ return back to main. */\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* vNonPreemptiveTick / vPreemptiveTick */\r
+\r
+#if configUSE_PREEMPTION == 0\r
+\r
+ /* The cooperative scheduler requires a normal IRQ service routine to \r
+ * simply increment the system tick. */\r
+ __interrupt void vNonPreemptiveTick( void ) \r
+ {\r
+ /* clear clock interrupt flag */\r
+ RTI->INTFLAG = 0x00000001;\r
+\r
+ /* Increment the tick count - this may make a delaying task ready\r
+ to run - but a context switch is not performed. */ \r
+ vTaskIncrementTick();\r
+ }\r
+\r
+ #else\r
+\r
+ /*\r
+ **************************************************************************\r
+ * The preemptive scheduler ISR is written in assembler and can be found \r
+ * in the portASM.asm file. This will only get used if portUSE_PREEMPTION\r
+ * is set to 1 in portmacro.h\r
+ ************************************************************************** \r
+ */\r
+ void vPreemptiveTick(void);\r
+\r
+#endif\r
+\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* vPortEnterCritical */\r
+\r
+void vPortEnterCritical(void)\r
+{\r
+ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */\r
+ portDISABLE_INTERRUPTS();\r
+ /* Now interrupts are disabled ulCriticalNesting can be accessed \r
+ directly. Increment ulCriticalNesting to keep a count of how many times\r
+ portENTER_CRITICAL() has been called. */\r
+ ulCriticalNesting++;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* vPortExitCritical */\r
+\r
+void vPortExitCritical(void)\r
+{\r
+ if(ulCriticalNesting > 0)\r
+ {\r
+ /* Decrement the nesting count as we are leaving a critical section. */\r
+ ulCriticalNesting--;\r
+\r
+ /* If the nesting level has reached zero then interrupts should be \r
+ re-enabled. */\r
+ if(ulCriticalNesting == 0)\r
+ {\r
+ /* Enable interrupts as per portENABLE_INTERRUPTS(). */\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+ }\r
+}\r
+\r
+/*----------------------------------------------------------------------------*/\r
--- /dev/null
+;/*\r
+; FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+; \r
+;\r
+; ***************************************************************************\r
+; * *\r
+; * FreeRTOS tutorial books are available in pdf and paperback. *\r
+; * Complete, revised, and edited pdf reference manuals are also *\r
+; * available. *\r
+; * *\r
+; * Purchasing FreeRTOS documentation will not only help you, by *\r
+; * ensuring you get running as quickly as possible and with an *\r
+; * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+; * the FreeRTOS project to continue with its mission of providing *\r
+; * professional grade, cross platform, de facto standard solutions *\r
+; * for microcontrollers - completely free of charge! *\r
+; * *\r
+; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+; * *\r
+; * Thank you for using FreeRTOS, and thank you for your support! *\r
+; * *\r
+; ***************************************************************************\r
+;\r
+;\r
+; This file is part of the FreeRTOS distribution.\r
+;\r
+; FreeRTOS is free software; you can redistribute it and/or modify it under\r
+; the terms of the GNU General Public License (version 2) as published by the\r
+; Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+; >>>NOTE<<< The modification to the GPL is included to allow you to\r
+; distribute a combined work that includes FreeRTOS without being obliged to\r
+; provide the source code for proprietary components outside of the FreeRTOS\r
+; kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+; more details. You should have received a copy of the GNU General Public\r
+; License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+; can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+; by writing to Richard Barry, contact details for whom are available on the\r
+; FreeRTOS WEB site.\r
+;\r
+; 1 tab == 4 spaces!\r
+;\r
+; http://www.FreeRTOS.org - Documentation, latest information, license and\r
+; contact details.\r
+;\r
+; http://www.SafeRTOS.com - A version that is certified for use in safety\r
+; critical systems.\r
+;\r
+; http://www.OpenRTOS.com - Commercial support, development, porting,\r
+; licensing and training services.\r
+;*/\r
+\r
+; TCJ: Using SSI interrupt todo portYIELD_WITHIN_API, means that we do not need\r
+; to save ulCriticalNesting in the task context\r
+\r
+ .text\r
+ .arm\r
+\r
+;-------------------------------------------------------------------------------\r
+;\r
+; Save Task Context \r
+;\r
+portSAVE_CONTEXT .macro\r
+ stmfd sp!, {r0}\r
+ stmfd sp, {sp}^\r
+ sub sp, sp, #4\r
+ ldmfd sp!, {r0}\r
+ stmfd r0!, {lr}\r
+ mov lr, r0\r
+ ldmfd sp!, {r0}\r
+ stmfd lr, {r0-lr}^\r
+ sub lr, lr, #0x3C\r
+ .if (__TI_VFPV3D16_SUPPORT__)\r
+ fstmdbd lr!, {d0-d15}\r
+ mrs r0, spsr\r
+ fmrx r1, fpscr\r
+ stmfd lr!, {r0,r1}\r
+ .else\r
+ mrs r0, spsr\r
+ stmfd lr!, {r0}\r
+ .endif\r
+ ldr r0, curTCB\r
+ ldr r0, [r0]\r
+ str lr, [r0]\r
+ .endm\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+; Restore Task Context\r
+;\r
+portRESTORE_CONTEXT .macro\r
+ ldr r0, curTCB\r
+ ldr r0, [r0]\r
+ ldr lr, [r0]\r
+ .if (__TI_VFPV3D16_SUPPORT__)\r
+ ldmfd lr!, {r0,r1}\r
+ fldmiad lr!, {d0-d15}\r
+ fmxr fpscr, r1\r
+ .else\r
+ ldmfd lr!, {r0}\r
+ .endif\r
+ msr spsr_csxf, r0\r
+ ldmfd lr, {r0-r14}^\r
+ ldr lr, [lr, #0x3C]\r
+ subs pc, lr, #4\r
+ .endm\r
+\r
+;-------------------------------------------------------------------------------\r
+; Start First Task\r
+\r
+ .def vPortStartFirstTask\r
+\r
+vPortStartFirstTask\r
+ portRESTORE_CONTEXT\r
+\r
+;-------------------------------------------------------------------------------\r
+; Yield Processor\r
+\r
+ .def vPortYieldProcessor\r
+ .ref vTaskSwitchContext\r
+\r
+vPortYieldProcessor\r
+ add lr, lr, #4\r
+ portSAVE_CONTEXT\r
+ bl vTaskSwitchContext\r
+ portRESTORE_CONTEXT\r
+\r
+;-------------------------------------------------------------------------------\r
+; Yield Processor From Within FreeRTOS API\r
+\r
+ .def vPortYeildWithinAPI\r
+\r
+vPortYeildWithinAPI\r
+ portSAVE_CONTEXT\r
+ ; clear SSI flag\r
+ movw r0, #0xFFF4\r
+ movt r0, #0xFFFF\r
+ ldr r0, [r0];\r
+ ; switch task\r
+ bl vTaskSwitchContext\r
+ portRESTORE_CONTEXT\r
+\r
+;-------------------------------------------------------------------------------\r
+; Preemptive Tick\r
+\r
+ .def vPreemptiveTick\r
+ .ref vTaskIncrementTick\r
+\r
+vPreemptiveTick\r
+ portSAVE_CONTEXT\r
+ ; clear interrupt flag\r
+ movw r0, #0xFC88\r
+ movt r0, #0xFFFF\r
+ mov r1, #1\r
+ str r1, [r0]\r
+ bl vTaskIncrementTick\r
+ bl vTaskSwitchContext\r
+ portRESTORE_CONTEXT\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+ .ref pxCurrentTCB\r
+curTCB .word pxCurrentTCB\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/*-----------------------------------------------------------\r
+ * Portable layer API. Each function must be defined for each port.\r
+ *----------------------------------------------------------*/\r
+\r
+#ifndef PORTABLE_H\r
+#define PORTABLE_H\r
+\r
+/* Include the macro file relevant to the port being used. */\r
+\r
+#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT\r
+ #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"\r
+ typedef void ( __interrupt __far *pxISR )();\r
+#endif\r
+\r
+#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT\r
+ #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"\r
+ typedef void ( __interrupt __far *pxISR )();\r
+#endif\r
+\r
+#ifdef GCC_MEGA_AVR\r
+ #include "../portable/GCC/ATMega323/portmacro.h"\r
+#endif\r
+\r
+#ifdef IAR_MEGA_AVR\r
+ #include "../portable/IAR/ATMega323/portmacro.h"\r
+#endif\r
+\r
+#ifdef MPLAB_PIC24_PORT\r
+ #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"\r
+#endif\r
+\r
+#ifdef MPLAB_DSPIC_PORT\r
+ #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"\r
+#endif\r
+\r
+#ifdef MPLAB_PIC18F_PORT\r
+ #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"\r
+#endif\r
+\r
+#ifdef MPLAB_PIC32MX_PORT\r
+ #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"\r
+#endif\r
+\r
+#ifdef _FEDPICC\r
+ #include "libFreeRTOS/Include/portmacro.h"\r
+#endif\r
+\r
+#ifdef SDCC_CYGNAL\r
+ #include "../../Source/portable/SDCC/Cygnal/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_ARM7\r
+ #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_ARM7_ECLIPSE\r
+ #include "portmacro.h"\r
+#endif\r
+\r
+#ifdef ROWLEY_LPC23xx\r
+ #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"\r
+#endif\r
+\r
+#ifdef IAR_MSP430\r
+ #include "..\..\Source\portable\IAR\MSP430\portmacro.h" \r
+#endif\r
+ \r
+#ifdef GCC_MSP430\r
+ #include "../../Source/portable/GCC/MSP430F449/portmacro.h"\r
+#endif\r
+\r
+#ifdef ROWLEY_MSP430\r
+ #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"\r
+#endif\r
+\r
+#ifdef ARM7_LPC21xx_KEIL_RVDS\r
+ #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"\r
+#endif\r
+\r
+#ifdef SAM7_GCC\r
+ #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"\r
+#endif\r
+\r
+#ifdef SAM7_IAR\r
+ #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"\r
+#endif\r
+\r
+#ifdef SAM9XE_IAR\r
+ #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"\r
+#endif\r
+\r
+#ifdef LPC2000_IAR\r
+ #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"\r
+#endif\r
+\r
+#ifdef STR71X_IAR\r
+ #include "..\..\Source\portable\IAR\STR71x\portmacro.h"\r
+#endif\r
+\r
+#ifdef STR75X_IAR\r
+ #include "..\..\Source\portable\IAR\STR75x\portmacro.h"\r
+#endif\r
+ \r
+#ifdef STR75X_GCC\r
+ #include "..\..\Source\portable\GCC\STR75x\portmacro.h"\r
+#endif\r
+\r
+#ifdef STR91X_IAR\r
+ #include "..\..\Source\portable\IAR\STR91x\portmacro.h"\r
+#endif\r
+ \r
+#ifdef GCC_H8S\r
+ #include "../../Source/portable/GCC/H8S2329/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_AT91FR40008\r
+ #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"\r
+#endif\r
+\r
+#ifdef RVDS_ARMCM3_LM3S102\r
+ #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_ARMCM3_LM3S102\r
+ #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_ARMCM3\r
+ #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"\r
+#endif\r
+\r
+#ifdef IAR_ARM_CM3\r
+ #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"\r
+#endif\r
+\r
+#ifdef IAR_ARMCM3_LM\r
+ #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"\r
+#endif\r
+ \r
+#ifdef HCS12_CODE_WARRIOR\r
+ #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"\r
+#endif \r
+\r
+#ifdef MICROBLAZE_GCC\r
+ #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"\r
+#endif\r
+\r
+#ifdef TERN_EE\r
+ #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_HCS12\r
+ #include "../../Source/portable/GCC/HCS12/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_MCF5235\r
+ #include "../../Source/portable/GCC/MCF5235/portmacro.h"\r
+#endif\r
+\r
+#ifdef COLDFIRE_V2_GCC\r
+ #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"\r
+#endif\r
+\r
+#ifdef COLDFIRE_V2_CODEWARRIOR\r
+ #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_PPC405\r
+ #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"\r
+#endif\r
+\r
+#ifdef GCC_PPC440\r
+ #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"\r
+#endif\r
+\r
+#ifdef _16FX_SOFTUNE\r
+ #include "..\..\Source\portable\Softune\MB96340\portmacro.h"\r
+#endif\r
+\r
+#ifdef BCC_INDUSTRIAL_PC_PORT\r
+ /* A short file name has to be used in place of the normal\r
+ FreeRTOSConfig.h when using the Borland compiler. */\r
+ #include "frconfig.h"\r
+ #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"\r
+ typedef void ( __interrupt __far *pxISR )();\r
+#endif\r
+\r
+#ifdef BCC_FLASH_LITE_186_PORT\r
+ /* A short file name has to be used in place of the normal\r
+ FreeRTOSConfig.h when using the Borland compiler. */\r
+ #include "frconfig.h"\r
+ #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"\r
+ typedef void ( __interrupt __far *pxISR )();\r
+#endif\r
+\r
+#ifdef __GNUC__\r
+ #ifdef __AVR32_AVR32A__\r
+ #include "portmacro.h"\r
+ #endif\r
+#endif\r
+\r
+#ifdef __ICCAVR32__\r
+ #ifdef __CORE__\r
+ #if __CORE__ == __AVR32A__\r
+ #include "portmacro.h"\r
+ #endif\r
+ #endif\r
+#endif\r
+\r
+#ifdef __91467D\r
+ #include "portmacro.h"\r
+#endif\r
+\r
+#ifdef __96340\r
+ #include "portmacro.h"\r
+#endif\r
+\r
+\r
+#ifdef __IAR_V850ES_Fx3__\r
+ #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
+#endif\r
+\r
+#ifdef __IAR_V850ES_Jx3__\r
+ #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
+#endif\r
+\r
+#ifdef __IAR_V850ES_Jx3_L__\r
+ #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
+#endif\r
+\r
+#ifdef __IAR_V850ES_Jx2__\r
+ #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
+#endif\r
+\r
+#ifdef __IAR_V850ES_Hx2__\r
+ #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
+#endif\r
+\r
+#ifdef __IAR_78K0R_Kx3__\r
+ #include "../../Source/portable/IAR/78K0R/portmacro.h"\r
+#endif\r
+ \r
+#ifdef __IAR_78K0R_Kx3L__\r
+ #include "../../Source/portable/IAR/78K0R/portmacro.h"\r
+#endif\r
+ \r
+/* Catch all to ensure portmacro.h is included in the build. Newer demos\r
+have the path as part of the project options, rather than as relative from\r
+the project location. If portENTER_CRITICAL() has not been defined then\r
+portmacro.h has not yet been included - as every portmacro.h provides a\r
+portENTER_CRITICAL() definition. Check the demo application for your demo\r
+to find the path to the correct portmacro.h file. */\r
+#ifndef portENTER_CRITICAL\r
+ #include "portmacro.h" \r
+#endif\r
+ \r
+#if portBYTE_ALIGNMENT == 8\r
+ #define portBYTE_ALIGNMENT_MASK ( 0x0007 )\r
+#endif\r
+\r
+#if portBYTE_ALIGNMENT == 4\r
+ #define portBYTE_ALIGNMENT_MASK ( 0x0003 )\r
+#endif\r
+\r
+#if portBYTE_ALIGNMENT == 2\r
+ #define portBYTE_ALIGNMENT_MASK ( 0x0001 )\r
+#endif\r
+\r
+#if portBYTE_ALIGNMENT == 1\r
+ #define portBYTE_ALIGNMENT_MASK ( 0x0000 )\r
+#endif\r
+\r
+#ifndef portBYTE_ALIGNMENT_MASK\r
+ #error "Invalid portBYTE_ALIGNMENT definition"\r
+#endif\r
+\r
+#ifndef portNUM_CONFIGURABLE_REGIONS\r
+ #define portNUM_CONFIGURABLE_REGIONS 1\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "mpu_wrappers.h"\r
+\r
+/*\r
+ * Setup the stack of a new task so it is ready to be placed under the\r
+ * scheduler control. The registers have to be placed on the stack in\r
+ * the order that the port expects to find them.\r
+ *\r
+ */\r
+#if( portUSING_MPU_WRAPPERS == 1 )\r
+ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;\r
+#else\r
+ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );\r
+#endif\r
+\r
+/*\r
+ * Map to the memory management routines required for the port.\r
+ */\r
+void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;\r
+void vPortFree( void *pv ) PRIVILEGED_FUNCTION;\r
+void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;\r
+size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Setup the hardware ready for the scheduler to take control. This generally\r
+ * sets up a tick interrupt and sets timers for the correct tick frequency.\r
+ */\r
+portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so\r
+ * the hardware is left in its original condition after the scheduler stops\r
+ * executing.\r
+ */\r
+void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * The structures and methods of manipulating the MPU are contained within the\r
+ * port layer.\r
+ *\r
+ * Fills the xMPUSettings structure with the memory region information\r
+ * contained in xRegions.\r
+ */\r
+#if( portUSING_MPU_WRAPPERS == 1 ) \r
+ struct xMEMORY_REGION;\r
+ void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* PORTABLE_H */\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef __OS_PORTMACRO_H__\r
+#define __OS_PORTMACRO_H__\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* RTI Register Frame Definition */\r
+\r
+struct rti\r
+{\r
+ unsigned GCTRL;\r
+ unsigned TBCTRL;\r
+ unsigned CAPCTRL;\r
+ unsigned COMPCTRL;\r
+ struct\r
+ {\r
+ unsigned FRCx;\r
+ unsigned UCx;\r
+ unsigned CPUCx;\r
+ unsigned : 32;\r
+ unsigned CAFRCx;\r
+ unsigned CAUCx;\r
+ unsigned : 32;\r
+ unsigned : 32;\r
+ } CNT[2U];\r
+ struct\r
+ {\r
+ unsigned COMPx;\r
+ unsigned UDCPx;\r
+ } CMP[4U];\r
+ unsigned TBLCOMP;\r
+ unsigned TBHCOMP;\r
+ unsigned : 32;\r
+ unsigned : 32;\r
+ unsigned SETINT;\r
+ unsigned CLEARINT;\r
+ unsigned INTFLAG;\r
+ unsigned : 32;\r
+ unsigned DWDCTRL;\r
+ unsigned DWDPRLD;\r
+ unsigned WDSTATUS;\r
+ unsigned WDKEY;\r
+ unsigned WDCNTR;\r
+};\r
+\r
+#define RTI ((volatile struct rti *)0xFFFFFC00U)\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Type Definitions */\r
+\r
+#define portCHAR char\r
+#define portFLOAT float\r
+#define portDOUBLE double\r
+#define portLONG long\r
+#define portSHORT short\r
+#define portSTACK_TYPE unsigned long\r
+#define portBASE_TYPE long\r
+\r
+#if (configUSE_16_BIT_TICKS == 1)\r
+ typedef unsigned portSHORT portTickType;\r
+ #define portMAX_DELAY (portTickType) 0xFFFF\r
+#else\r
+ typedef unsigned portLONG portTickType;\r
+ #define portMAX_DELAY (portTickType) 0xFFFFFFFFF\r
+#endif\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Architecture Definitions */\r
+\r
+#define portSTACK_GROWTH (-1)\r
+#define portTICK_RATE_MS ((portTickType) 1000 / configTICK_RATE_HZ) \r
+#define portBYTE_ALIGNMENT 8\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* External Functions */\r
+\r
+extern void vPortEnterCritical(void);\r
+extern void vPortExitCritical(void);\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Functions Macros */\r
+\r
+#define portYIELD() _call_swi(0)\r
+#define portYIELD_WITHIN_API() { *(volatile unsigned *)0xFFFFFFB0 = 0x7500; *(volatile unsigned *)0xFFFFFFB0; }\r
+#define portYIELD_FROM_ISR() { *(volatile unsigned *)0xFFFFFFB0 = 0x7500; *(volatile unsigned *)0xFFFFFFB0; }\r
+#define portENTER_CRITICAL() vPortEnterCritical()\r
+#define portEXIT_CRITICAL() vPortExitCritical()\r
+#define portDISABLE_INTERRUPTS() asm(" CPSID I")\r
+#define portENABLE_INTERRUPTS() asm(" CPSIE I")\r
+\r
+#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)\r
+#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)\r
+\r
+#if (configGENERATE_RUN_TIME_STATS == 1)\r
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() \\r
+{ \\r
+ RTI->GCTRL = 0x00000000U; \\r
+ RTI->TBCTRL = 0x00000000U; \\r
+ RTI->COMPCTRL = 0x00000000U; \\r
+ RTI->CNT[1U].UCx = 0x00000000U; \\r
+ RTI->CNT[1U].FRCx = 0x00000000U; \\r
+ RTI->CNT[1U].CPUCx = (configCPU_CLOCK_HZ / 2 / configTICK_RATE_HZ) / 16; \\r
+ RTI->CMP[1U].UDCPx = (configCPU_CLOCK_HZ / 2 / configTICK_RATE_HZ) / 16; \\r
+ RTI->GCTRL = 0x00000002U; \\r
+}\r
+#define portGET_RUN_TIME_COUNTER_VALUE() (RTI->CNT[1].FRCx)\r
+#endif\r
+\r
+#endif\r
+\r
+/*----------------------------------------------------------------------------*/\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef PROJDEFS_H\r
+#define PROJDEFS_H\r
+\r
+/* Defines the prototype to which task functions must conform. */\r
+typedef void (*pdTASK_CODE)( void * );\r
+\r
+#define pdTRUE ( 1 )\r
+#define pdFALSE ( 0 )\r
+\r
+#define pdPASS ( 1 )\r
+#define pdFAIL ( 0 )\r
+#define errQUEUE_EMPTY ( 0 )\r
+#define errQUEUE_FULL ( 0 )\r
+\r
+/* Error definitions. */\r
+#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )\r
+#define errNO_TASK_TO_RUN ( -2 )\r
+#define errQUEUE_BLOCKED ( -4 )\r
+#define errQUEUE_YIELD ( -5 )\r
+\r
+#endif /* PROJDEFS_H */\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
+all the API functions to use the MPU wrappers. That should only be done when\r
+task.h is included from an application file. */\r
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
+ #include "croutine.h"\r
+#endif\r
+\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+/*-----------------------------------------------------------\r
+ * PUBLIC LIST API documented in list.h\r
+ *----------------------------------------------------------*/\r
+\r
+/* Constants used with the cRxLock and xTxLock structure members. */\r
+#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )\r
+#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )\r
+\r
+#define queueERRONEOUS_UNBLOCK ( -1 )\r
+\r
+/* For internal use only. */\r
+#define queueSEND_TO_BACK ( 0 )\r
+#define queueSEND_TO_FRONT ( 1 )\r
+\r
+/* Effectively make a union out of the xQUEUE structure. */\r
+#define pxMutexHolder pcTail\r
+#define uxQueueType pcHead\r
+#define uxRecursiveCallCount pcReadFrom\r
+#define queueQUEUE_IS_MUTEX NULL\r
+\r
+/* Semaphores do not actually store or copy data, so have an items size of\r
+zero. */\r
+#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )\r
+#define queueDONT_BLOCK ( ( portTickType ) 0U )\r
+#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U )\r
+\r
+/* These definitions *must* match those in queue.h. */\r
+#define queueQUEUE_TYPE_BASE ( 0U )\r
+#define queueQUEUE_TYPE_MUTEX ( 1U )\r
+#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
+#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
+#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
+\r
+/*\r
+ * Definition of the queue used by the scheduler.\r
+ * Items are queued by copy, not reference.\r
+ */\r
+typedef struct QueueDefinition\r
+{\r
+ signed char *pcHead; /*< Points to the beginning of the queue storage area. */\r
+ signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
+\r
+ signed char *pcWriteTo; /*< Points to the free next place in the storage area. */\r
+ signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */\r
+\r
+ xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */\r
+ xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */\r
+\r
+ volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */\r
+ unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */\r
+ unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */\r
+\r
+ volatile signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */\r
+ volatile signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */\r
+ \r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ unsigned char ucQueueNumber;\r
+ unsigned char ucQueueType;\r
+ #endif\r
+\r
+} xQUEUE;\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Inside this file xQueueHandle is a pointer to a xQUEUE structure.\r
+ * To keep the definition private the API header file defines it as a\r
+ * pointer to void.\r
+ */\r
+typedef xQUEUE * xQueueHandle;\r
+\r
+/*\r
+ * Prototypes for public functions are included here so we don't have to\r
+ * include the API header file (as it defines xQueueHandle differently). These\r
+ * functions are documented in the API header file.\r
+ */\r
+xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION;\r
+unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;\r
+xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Co-routine queue functions differ from task queue functions. Co-routines are\r
+ * an optional component.\r
+ */\r
+#if configUSE_CO_ROUTINES == 1\r
+ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;\r
+ signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
+ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+#endif\r
+\r
+/*\r
+ * The queue registry is just a means for kernel aware debuggers to locate\r
+ * queue structures. It has no other purpose so is an optional component.\r
+ */\r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+\r
+ /* The type stored within the queue registry array. This allows a name\r
+ to be assigned to each queue making kernel aware debugging a little\r
+ more user friendly. */\r
+ typedef struct QUEUE_REGISTRY_ITEM\r
+ {\r
+ signed char *pcQueueName;\r
+ xQueueHandle xHandle;\r
+ } xQueueRegistryItem;\r
+\r
+ /* The queue registry is simply an array of xQueueRegistryItem structures.\r
+ The pcQueueName member of a structure being NULL is indicative of the\r
+ array position being vacant. */\r
+ xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];\r
+\r
+ /* Removes a queue from the registry by simply setting the pcQueueName\r
+ member to NULL. */\r
+ static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
+ void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;\r
+#endif\r
+\r
+/*\r
+ * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not\r
+ * prevent an ISR from adding or removing items to the queue, but does prevent\r
+ * an ISR from removing tasks from the queue event lists. If an ISR finds a\r
+ * queue is locked it will instead increment the appropriate queue lock count\r
+ * to indicate that a task may require unblocking. When the queue in unlocked\r
+ * these lock counts are inspected, and the appropriate action taken.\r
+ */\r
+static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Uses a critical section to determine if there is any data in a queue.\r
+ *\r
+ * @return pdTRUE if the queue contains no items, otherwise pdFALSE.\r
+ */\r
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Uses a critical section to determine if there is any space in a queue.\r
+ *\r
+ * @return pdTRUE if there is no space, otherwise pdFALSE;\r
+ */\r
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Copies an item into the queue, either at the front of the queue or the\r
+ * back of the queue.\r
+ */\r
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Copies an item out of a queue.\r
+ */\r
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Macro to mark a queue as locked. Locking a queue prevents an ISR from\r
+ * accessing the queue event lists.\r
+ */\r
+#define prvLockQueue( pxQueue ) \\r
+ taskENTER_CRITICAL(); \\r
+ { \\r
+ if( ( pxQueue )->xRxLock == queueUNLOCKED ) \\r
+ { \\r
+ ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \\r
+ } \\r
+ if( ( pxQueue )->xTxLock == queueUNLOCKED ) \\r
+ { \\r
+ ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \\r
+ } \\r
+ } \\r
+ taskEXIT_CRITICAL()\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * PUBLIC QUEUE MANAGEMENT API documented in queue.h\r
+ *----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )\r
+{\r
+ configASSERT( pxQueue );\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );\r
+ pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;\r
+ pxQueue->pcWriteTo = pxQueue->pcHead;\r
+ pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );\r
+ pxQueue->xRxLock = queueUNLOCKED;\r
+ pxQueue->xTxLock = queueUNLOCKED;\r
+\r
+ if( xNewQueue == pdFALSE )\r
+ {\r
+ /* If there are tasks blocked waiting to read from the queue, then \r
+ the tasks will remain blocked as after this function exits the queue \r
+ will still be empty. If there are tasks blocked waiting to write to \r
+ the queue, then one should be unblocked as after this function exits \r
+ it will be possible to write to it. */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Ensure the event queues start in the correct state. */\r
+ vListInitialise( &( pxQueue->xTasksWaitingToSend ) );\r
+ vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); \r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* A value is returned for calling semantic consistency with previous\r
+ versions. */\r
+ return pdPASS;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType )\r
+{\r
+xQUEUE *pxNewQueue;\r
+size_t xQueueSizeInBytes;\r
+xQueueHandle xReturn = NULL;\r
+\r
+ /* Remove compiler warnings about unused parameters should\r
+ configUSE_TRACE_FACILITY not be set to 1. */\r
+ ( void ) ucQueueType;\r
+\r
+ /* Allocate the new queue structure. */\r
+ if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
+ if( pxNewQueue != NULL )\r
+ {\r
+ /* Create the list of pointers to queue items. The queue is one byte\r
+ longer than asked for to make wrap checking easier/faster. */\r
+ xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;\r
+\r
+ pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );\r
+ if( pxNewQueue->pcHead != NULL )\r
+ {\r
+ /* Initialise the queue members as described above where the\r
+ queue type is defined. */\r
+ pxNewQueue->uxLength = uxQueueLength;\r
+ pxNewQueue->uxItemSize = uxItemSize;\r
+ xQueueGenericReset( pxNewQueue, pdTRUE );\r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ {\r
+ pxNewQueue->ucQueueType = ucQueueType;\r
+ }\r
+ #endif /* configUSE_TRACE_FACILITY */\r
+\r
+ traceQUEUE_CREATE( pxNewQueue );\r
+ xReturn = pxNewQueue;\r
+ }\r
+ else\r
+ {\r
+ traceQUEUE_CREATE_FAILED( ucQueueType );\r
+ vPortFree( pxNewQueue );\r
+ }\r
+ }\r
+ }\r
+\r
+ configASSERT( xReturn );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_MUTEXES == 1 )\r
+\r
+ xQueueHandle xQueueCreateMutex( unsigned char ucQueueType )\r
+ {\r
+ xQUEUE *pxNewQueue;\r
+\r
+ /* Prevent compiler warnings about unused parameters if\r
+ configUSE_TRACE_FACILITY does not equal 1. */\r
+ ( void ) ucQueueType;\r
+\r
+ /* Allocate the new queue structure. */\r
+ pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
+ if( pxNewQueue != NULL )\r
+ {\r
+ /* Information required for priority inheritance. */\r
+ pxNewQueue->pxMutexHolder = NULL;\r
+ pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
+\r
+ /* Queues used as a mutex no data is actually copied into or out\r
+ of the queue. */\r
+ pxNewQueue->pcWriteTo = NULL;\r
+ pxNewQueue->pcReadFrom = NULL;\r
+\r
+ /* Each mutex has a length of 1 (like a binary semaphore) and\r
+ an item size of 0 as nothing is actually copied into or out\r
+ of the mutex. */\r
+ pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;\r
+ pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U;\r
+ pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U;\r
+ pxNewQueue->xRxLock = queueUNLOCKED;\r
+ pxNewQueue->xTxLock = queueUNLOCKED;\r
+\r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ {\r
+ pxNewQueue->ucQueueType = ucQueueType;\r
+ }\r
+ #endif\r
+\r
+ /* Ensure the event queues start with the correct state. */\r
+ vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
+ vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
+\r
+ traceCREATE_MUTEX( pxNewQueue );\r
+\r
+ /* Start with the semaphore in the expected state. */\r
+ xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );\r
+ }\r
+ else\r
+ {\r
+ traceCREATE_MUTEX_FAILED();\r
+ }\r
+\r
+ configASSERT( pxNewQueue );\r
+ return pxNewQueue;\r
+ }\r
+\r
+#endif /* configUSE_MUTEXES */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xQueueGetMutexHolder == 1 ) )\r
+\r
+ void* xQueueGetMutexHolder( xQueueHandle xSemaphore )\r
+ {\r
+ void *pxReturn;\r
+\r
+ /* This function is called by xSemaphoreGetMutexHolder(), and should not\r
+ be called directly. Note: This is is a good way of determining if the\r
+ calling task is the mutex holder, but not a good way of determining the\r
+ identity of the mutex holder, as the holder may change between the \r
+ following critical section exiting and the function returning. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( xSemaphore->uxQueueType == queueQUEUE_IS_MUTEX )\r
+ {\r
+ pxReturn = ( void * ) xSemaphore->pxMutexHolder;\r
+ }\r
+ else\r
+ {\r
+ pxReturn = NULL;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ \r
+ return pxReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_RECURSIVE_MUTEXES == 1 )\r
+\r
+ portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ configASSERT( pxMutex );\r
+\r
+ /* If this is the task that holds the mutex then pxMutexHolder will not\r
+ change outside of this task. If this task does not hold the mutex then\r
+ pxMutexHolder can never coincidentally equal the tasks handle, and as\r
+ this is the only condition we are interested in it does not matter if\r
+ pxMutexHolder is accessed simultaneously by another task. Therefore no\r
+ mutual exclusion is required to test the pxMutexHolder variable. */\r
+ if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
+ {\r
+ traceGIVE_MUTEX_RECURSIVE( pxMutex );\r
+\r
+ /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to\r
+ the task handle, therefore no underflow check is required. Also,\r
+ uxRecursiveCallCount is only modified by the mutex holder, and as\r
+ there can only be one, no mutual exclusion is required to modify the\r
+ uxRecursiveCallCount member. */\r
+ ( pxMutex->uxRecursiveCallCount )--;\r
+\r
+ /* Have we unwound the call count? */\r
+ if( pxMutex->uxRecursiveCallCount == 0 )\r
+ {\r
+ /* Return the mutex. This will automatically unblock any other\r
+ task that might be waiting to access the mutex. */\r
+ xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
+ }\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ /* We cannot give the mutex because we are not the holder. */\r
+ xReturn = pdFAIL;\r
+\r
+ traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_RECURSIVE_MUTEXES */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_RECURSIVE_MUTEXES == 1\r
+\r
+ portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ configASSERT( pxMutex );\r
+\r
+ /* Comments regarding mutual exclusion as per those within\r
+ xQueueGiveMutexRecursive(). */\r
+\r
+ traceTAKE_MUTEX_RECURSIVE( pxMutex );\r
+\r
+ if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )\r
+ {\r
+ ( pxMutex->uxRecursiveCallCount )++;\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );\r
+\r
+ /* pdPASS will only be returned if we successfully obtained the mutex,\r
+ we may have blocked to reach here. */\r
+ if( xReturn == pdPASS )\r
+ {\r
+ ( pxMutex->uxRecursiveCallCount )++;\r
+ }\r
+ else\r
+ {\r
+ traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configUSE_RECURSIVE_MUTEXES */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_COUNTING_SEMAPHORES == 1\r
+\r
+ xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
+ {\r
+ xQueueHandle pxHandle;\r
+\r
+ pxHandle = xQueueGenericCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );\r
+\r
+ if( pxHandle != NULL )\r
+ {\r
+ pxHandle->uxMessagesWaiting = uxInitialCount;\r
+\r
+ traceCREATE_COUNTING_SEMAPHORE();\r
+ }\r
+ else\r
+ {\r
+ traceCREATE_COUNTING_SEMAPHORE_FAILED();\r
+ }\r
+\r
+ configASSERT( pxHandle );\r
+ return pxHandle;\r
+ }\r
+\r
+#endif /* configUSE_COUNTING_SEMAPHORES */\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
+{\r
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
+xTimeOutType xTimeOut;\r
+\r
+ configASSERT( pxQueue );\r
+ configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
+\r
+ /* This function relaxes the coding standard somewhat to allow return\r
+ statements within the function itself. This is done in the interest\r
+ of execution time efficiency. */\r
+ for( ;; )\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Is there room on the queue now? To be running we must be\r
+ the highest priority task wanting to access the queue. */\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ {\r
+ traceQUEUE_SEND( pxQueue );\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
+ /* If there was a task waiting for data to arrive on the\r
+ queue then unblock it now. */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
+ {\r
+ /* The unblocked task has a priority higher than\r
+ our own so yield immediately. Yes it is ok to do\r
+ this from within the critical section - the kernel\r
+ takes care of that. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* Return to the original privilege level before exiting the\r
+ function. */\r
+ return pdPASS;\r
+ }\r
+ else\r
+ {\r
+ if( xTicksToWait == ( portTickType ) 0 )\r
+ {\r
+ /* The queue was full and no block time is specified (or\r
+ the block time has expired) so leave now. */\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* Return to the original privilege level before exiting\r
+ the function. */\r
+ traceQUEUE_SEND_FAILED( pxQueue );\r
+ return errQUEUE_FULL;\r
+ }\r
+ else if( xEntryTimeSet == pdFALSE )\r
+ {\r
+ /* The queue was full and a block time was specified so\r
+ configure the timeout structure. */\r
+ vTaskSetTimeOutState( &xTimeOut );\r
+ xEntryTimeSet = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* Interrupts and other tasks can send to and receive from the queue\r
+ now the critical section has been exited. */\r
+\r
+ vTaskSuspendAll();\r
+ prvLockQueue( pxQueue );\r
+\r
+ /* Update the timeout state to see if it has expired yet. */\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+ {\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
+ {\r
+ traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+\r
+ /* Unlocking the queue means queue events can effect the\r
+ event list. It is possible that interrupts occurring now\r
+ remove this task from the event list again - but as the\r
+ scheduler is suspended the task will go onto the pending\r
+ ready last instead of the actual ready list. */\r
+ prvUnlockQueue( pxQueue );\r
+\r
+ /* Resuming the scheduler will move tasks from the pending\r
+ ready list into the ready list - so it is feasible that this\r
+ task is already in a ready list before it yields - in which\r
+ case the yield will not cause a context switch unless there\r
+ is also a higher priority task in the pending ready list. */\r
+ if( xTaskResumeAll() == pdFALSE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Try again. */\r
+ prvUnlockQueue( pxQueue );\r
+ ( void ) xTaskResumeAll();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The timeout has expired. */\r
+ prvUnlockQueue( pxQueue );\r
+ ( void ) xTaskResumeAll();\r
+\r
+ /* Return to the original privilege level before exiting the\r
+ function. */\r
+ traceQUEUE_SEND_FAILED( pxQueue );\r
+ return errQUEUE_FULL;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_ALTERNATIVE_API == 1\r
+\r
+ signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
+ {\r
+ signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
+ xTimeOutType xTimeOut;\r
+\r
+ configASSERT( pxQueue );\r
+ configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
+\r
+ for( ;; )\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Is there room on the queue now? To be running we must be\r
+ the highest priority task wanting to access the queue. */\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ {\r
+ traceQUEUE_SEND( pxQueue );\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
+ /* If there was a task waiting for data to arrive on the\r
+ queue then unblock it now. */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
+ {\r
+ /* The unblocked task has a priority higher than\r
+ our own so yield immediately. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+\r
+ taskEXIT_CRITICAL();\r
+ return pdPASS;\r
+ }\r
+ else\r
+ {\r
+ if( xTicksToWait == ( portTickType ) 0 )\r
+ {\r
+ taskEXIT_CRITICAL();\r
+ return errQUEUE_FULL;\r
+ }\r
+ else if( xEntryTimeSet == pdFALSE )\r
+ {\r
+ vTaskSetTimeOutState( &xTimeOut );\r
+ xEntryTimeSet = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+ {\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
+ {\r
+ traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ taskEXIT_CRITICAL();\r
+ traceQUEUE_SEND_FAILED( pxQueue );\r
+ return errQUEUE_FULL;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ }\r
+ }\r
+\r
+#endif /* configUSE_ALTERNATIVE_API */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_ALTERNATIVE_API == 1\r
+\r
+ signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
+ {\r
+ signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
+ xTimeOutType xTimeOut;\r
+ signed char *pcOriginalReadPosition;\r
+\r
+ configASSERT( pxQueue );\r
+ configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
+\r
+ for( ;; )\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ /* Remember our read position in case we are just peeking. */\r
+ pcOriginalReadPosition = pxQueue->pcReadFrom;\r
+\r
+ prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+\r
+ if( xJustPeeking == pdFALSE )\r
+ {\r
+ traceQUEUE_RECEIVE( pxQueue );\r
+\r
+ /* We are actually removing data. */\r
+ --( pxQueue->uxMessagesWaiting );\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+ {\r
+ /* Record the information required to implement\r
+ priority inheritance should it become necessary. */\r
+ pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ traceQUEUE_PEEK( pxQueue );\r
+\r
+ /* We are not removing the data, so reset our read\r
+ pointer. */\r
+ pxQueue->pcReadFrom = pcOriginalReadPosition;\r
+\r
+ /* The data is being left in the queue, so see if there are\r
+ any other tasks waiting for the data. */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ /* Tasks that are removed from the event list will get added to\r
+ the pending ready list as the scheduler is still suspended. */\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority than this task. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ taskEXIT_CRITICAL();\r
+ return pdPASS;\r
+ }\r
+ else\r
+ {\r
+ if( xTicksToWait == ( portTickType ) 0 )\r
+ {\r
+ taskEXIT_CRITICAL();\r
+ traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+ return errQUEUE_EMPTY;\r
+ }\r
+ else if( xEntryTimeSet == pdFALSE )\r
+ {\r
+ vTaskSetTimeOutState( &xTimeOut );\r
+ xEntryTimeSet = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+ {\r
+ if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
+ {\r
+ traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+ {\r
+ portENTER_CRITICAL();\r
+ vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+ portEXIT_CRITICAL();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ taskEXIT_CRITICAL();\r
+ traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+ return errQUEUE_EMPTY;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ }\r
+ }\r
+\r
+\r
+#endif /* configUSE_ALTERNATIVE_API */\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+unsigned portBASE_TYPE uxSavedInterruptStatus;\r
+\r
+ configASSERT( pxQueue );\r
+ configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
+\r
+ /* Similar to xQueueGenericSend, except we don't block if there is no room\r
+ in the queue. Also we don't directly wake a task that was blocked on a\r
+ queue read, instead we return a flag to say whether a context switch is\r
+ required or not (i.e. has a task with a higher priority than us been woken\r
+ by this post). */\r
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ {\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ {\r
+ traceQUEUE_SEND_FROM_ISR( pxQueue );\r
+\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+\r
+ /* If the queue is locked we do not alter the event list. This will\r
+ be done when the queue is unlocked later. */\r
+ if( pxQueue->xTxLock == queueUNLOCKED )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority so record that a\r
+ context switch is required. */\r
+ if( pxHigherPriorityTaskWoken != NULL )\r
+ {\r
+ *pxHigherPriorityTaskWoken = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Increment the lock count so the task that unlocks the queue\r
+ knows that data was posted while it was locked. */\r
+ ++( pxQueue->xTxLock );\r
+ }\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );\r
+ xReturn = errQUEUE_FULL;\r
+ }\r
+ }\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
+{\r
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
+xTimeOutType xTimeOut;\r
+signed char *pcOriginalReadPosition;\r
+\r
+ configASSERT( pxQueue );\r
+ configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
+\r
+ /* This function relaxes the coding standard somewhat to allow return\r
+ statements within the function itself. This is done in the interest\r
+ of execution time efficiency. */\r
+\r
+ for( ;; )\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Is there data in the queue now? To be running we must be\r
+ the highest priority task wanting to access the queue. */\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ /* Remember our read position in case we are just peeking. */\r
+ pcOriginalReadPosition = pxQueue->pcReadFrom;\r
+\r
+ prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+\r
+ if( xJustPeeking == pdFALSE )\r
+ {\r
+ traceQUEUE_RECEIVE( pxQueue );\r
+\r
+ /* We are actually removing data. */\r
+ --( pxQueue->uxMessagesWaiting );\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+ {\r
+ /* Record the information required to implement\r
+ priority inheritance should it become necessary. */\r
+ pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ traceQUEUE_PEEK( pxQueue );\r
+\r
+ /* We are not removing the data, so reset our read\r
+ pointer. */\r
+ pxQueue->pcReadFrom = pcOriginalReadPosition;\r
+\r
+ /* The data is being left in the queue, so see if there are\r
+ any other tasks waiting for the data. */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ /* Tasks that are removed from the event list will get added to\r
+ the pending ready list as the scheduler is still suspended. */\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority than this task. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+\r
+ taskEXIT_CRITICAL();\r
+ return pdPASS;\r
+ }\r
+ else\r
+ {\r
+ if( xTicksToWait == ( portTickType ) 0 )\r
+ {\r
+ /* The queue was empty and no block time is specified (or\r
+ the block time has expired) so leave now. */\r
+ taskEXIT_CRITICAL();\r
+ traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+ return errQUEUE_EMPTY;\r
+ }\r
+ else if( xEntryTimeSet == pdFALSE )\r
+ {\r
+ /* The queue was empty and a block time was specified so\r
+ configure the timeout structure. */\r
+ vTaskSetTimeOutState( &xTimeOut );\r
+ xEntryTimeSet = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* Interrupts and other tasks can send to and receive from the queue\r
+ now the critical section has been exited. */\r
+\r
+ vTaskSuspendAll();\r
+ prvLockQueue( pxQueue );\r
+\r
+ /* Update the timeout state to see if it has expired yet. */\r
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+ {\r
+ if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
+ {\r
+ traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+ {\r
+ portENTER_CRITICAL();\r
+ {\r
+ vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+ }\r
+ portEXIT_CRITICAL();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+ prvUnlockQueue( pxQueue );\r
+ if( xTaskResumeAll() == pdFALSE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Try again. */\r
+ prvUnlockQueue( pxQueue );\r
+ ( void ) xTaskResumeAll();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ prvUnlockQueue( pxQueue );\r
+ ( void ) xTaskResumeAll();\r
+ traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+ return errQUEUE_EMPTY;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+unsigned portBASE_TYPE uxSavedInterruptStatus;\r
+\r
+ configASSERT( pxQueue );\r
+ configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );\r
+\r
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ {\r
+ /* We cannot block from an ISR, so check there is data available. */\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
+\r
+ prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+ --( pxQueue->uxMessagesWaiting );\r
+\r
+ /* If the queue is locked we will not modify the event list. Instead\r
+ we update the lock count so the task that unlocks the queue will know\r
+ that an ISR has removed data while the queue was locked. */\r
+ if( pxQueue->xRxLock == queueUNLOCKED )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority than us so\r
+ force a context switch. */\r
+ if( pxHigherPriorityTaskWoken != NULL )\r
+ {\r
+ *pxHigherPriorityTaskWoken = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Increment the lock count so the task that unlocks the queue\r
+ knows that data was removed while it was locked. */\r
+ ++( pxQueue->xRxLock );\r
+ }\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );\r
+ }\r
+ }\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )\r
+{\r
+unsigned portBASE_TYPE uxReturn;\r
+\r
+ configASSERT( pxQueue );\r
+\r
+ taskENTER_CRITICAL();\r
+ uxReturn = pxQueue->uxMessagesWaiting;\r
+ taskEXIT_CRITICAL();\r
+\r
+ return uxReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )\r
+{\r
+unsigned portBASE_TYPE uxReturn;\r
+\r
+ configASSERT( pxQueue );\r
+\r
+ uxReturn = pxQueue->uxMessagesWaiting;\r
+\r
+ return uxReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vQueueDelete( xQueueHandle pxQueue )\r
+{\r
+ configASSERT( pxQueue );\r
+\r
+ traceQUEUE_DELETE( pxQueue );\r
+ vQueueUnregisterQueue( pxQueue );\r
+ vPortFree( pxQueue->pcHead );\r
+ vPortFree( pxQueue );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue )\r
+ {\r
+ return pxQueue->ucQueueNumber;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber )\r
+ {\r
+ pxQueue->ucQueueNumber = ucQueueNumber;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ unsigned char ucQueueGetQueueType( xQueueHandle pxQueue )\r
+ {\r
+ return pxQueue->ucQueueType;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
+{\r
+ if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+ {\r
+ /* The mutex is no longer being held. */\r
+ vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
+ pxQueue->pxMutexHolder = NULL;\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ else if( xPosition == queueSEND_TO_BACK )\r
+ {\r
+ memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );\r
+ pxQueue->pcWriteTo += pxQueue->uxItemSize;\r
+ if( pxQueue->pcWriteTo >= pxQueue->pcTail )\r
+ {\r
+ pxQueue->pcWriteTo = pxQueue->pcHead;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );\r
+ pxQueue->pcReadFrom -= pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom < pxQueue->pcHead )\r
+ {\r
+ pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
+ }\r
+ }\r
+\r
+ ++( pxQueue->uxMessagesWaiting );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )\r
+{\r
+ if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )\r
+ {\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ {\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvUnlockQueue( xQueueHandle pxQueue )\r
+{\r
+ /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */\r
+\r
+ /* The lock counts contains the number of extra data items placed or\r
+ removed from the queue while the queue was locked. When a queue is\r
+ locked items can be added or removed, but the event lists cannot be\r
+ updated. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* See if data was added to the queue while it was locked. */\r
+ while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )\r
+ {\r
+ /* Data was posted while the queue was locked. Are any tasks\r
+ blocked waiting for data to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ /* Tasks that are removed from the event list will get added to\r
+ the pending ready list as the scheduler is still suspended. */\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The task waiting has a higher priority so record that a\r
+ context switch is required. */\r
+ vTaskMissedYield();\r
+ }\r
+\r
+ --( pxQueue->xTxLock );\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ pxQueue->xTxLock = queueUNLOCKED;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* Do the same for the Rx lock. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ vTaskMissedYield();\r
+ }\r
+\r
+ --( pxQueue->xRxLock );\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ pxQueue->xRxLock = queueUNLOCKED;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ taskENTER_CRITICAL();\r
+ xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ configASSERT( pxQueue );\r
+ xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ taskENTER_CRITICAL();\r
+ xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ configASSERT( pxQueue );\r
+ xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_CO_ROUTINES == 1\r
+signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ /* If the queue is already full we may have to block. A critical section\r
+ is required to prevent an interrupt removing something from the queue\r
+ between the check to see if the queue is full and blocking on the queue. */\r
+ portDISABLE_INTERRUPTS();\r
+ {\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
+ {\r
+ /* The queue is full - do we want to block or just leave without\r
+ posting? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
+ {\r
+ /* As this is called from a coroutine we cannot block directly, but\r
+ return indicating that we need to block. */\r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_BLOCKED;\r
+ }\r
+ else\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_FULL;\r
+ }\r
+ }\r
+ }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ portNOP();\r
+\r
+ portDISABLE_INTERRUPTS();\r
+ {\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ {\r
+ /* There is room in the queue, copy the data into the queue. */\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
+ xReturn = pdPASS;\r
+\r
+ /* Were any co-routines waiting for data to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ /* In this instance the co-routine could be placed directly\r
+ into the ready list as we are within a critical section.\r
+ Instead the same pending ready list mechanism is used as if\r
+ the event were caused from within an interrupt. */\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ /* The co-routine waiting has a higher priority so record\r
+ that a yield might be appropriate. */\r
+ xReturn = errQUEUE_YIELD;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ xReturn = errQUEUE_FULL;\r
+ }\r
+ }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ return xReturn;\r
+}\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_CO_ROUTINES == 1\r
+signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ /* If the queue is already empty we may have to block. A critical section\r
+ is required to prevent an interrupt adding something to the queue\r
+ between the check to see if the queue is empty and blocking on the queue. */\r
+ portDISABLE_INTERRUPTS();\r
+ {\r
+ if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ /* There are no messages in the queue, do we want to block or just\r
+ leave with nothing? */\r
+ if( xTicksToWait > ( portTickType ) 0 )\r
+ {\r
+ /* As this is a co-routine we cannot block directly, but return\r
+ indicating that we need to block. */\r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_BLOCKED;\r
+ }\r
+ else\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ return errQUEUE_FULL;\r
+ }\r
+ }\r
+ }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ portNOP();\r
+\r
+ portDISABLE_INTERRUPTS();\r
+ {\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ /* Data is available from the queue. */\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ {\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ --( pxQueue->uxMessagesWaiting );\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+\r
+ xReturn = pdPASS;\r
+\r
+ /* Were any co-routines waiting for space to become available? */\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ /* In this instance the co-routine could be placed directly\r
+ into the ready list as we are within a critical section.\r
+ Instead the same pending ready list mechanism is used as if\r
+ the event were caused from within an interrupt. */\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ xReturn = errQUEUE_YIELD;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ }\r
+ portENABLE_INTERRUPTS();\r
+\r
+ return xReturn;\r
+}\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+\r
+#if configUSE_CO_ROUTINES == 1\r
+signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )\r
+{\r
+ /* Cannot block within an ISR so if there is no space on the queue then\r
+ exit without doing anything. */\r
+ if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+ {\r
+ prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
+\r
+ /* We only want to wake one co-routine per ISR, so check that a\r
+ co-routine has not already been woken. */\r
+ if( xCoRoutinePreviouslyWoken == pdFALSE )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+ {\r
+ return pdTRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return xCoRoutinePreviouslyWoken;\r
+}\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_CO_ROUTINES == 1\r
+signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+\r
+ /* We cannot block from an ISR, so check there is data available. If\r
+ not then just leave without doing anything. */\r
+ if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+ {\r
+ /* Copy the data from the queue. */\r
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+ if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+ {\r
+ pxQueue->pcReadFrom = pxQueue->pcHead;\r
+ }\r
+ --( pxQueue->uxMessagesWaiting );\r
+ memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+\r
+ if( ( *pxCoRoutineWoken ) == pdFALSE )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+ {\r
+ *pxCoRoutineWoken = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+\r
+ void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )\r
+ {\r
+ unsigned portBASE_TYPE ux;\r
+\r
+ /* See if there is an empty space in the registry. A NULL name denotes\r
+ a free slot. */\r
+ for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )\r
+ {\r
+ if( xQueueRegistry[ ux ].pcQueueName == NULL )\r
+ {\r
+ /* Store the information on this queue. */\r
+ xQueueRegistry[ ux ].pcQueueName = pcQueueName;\r
+ xQueueRegistry[ ux ].xHandle = xQueue;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+\r
+ static void vQueueUnregisterQueue( xQueueHandle xQueue )\r
+ {\r
+ unsigned portBASE_TYPE ux;\r
+\r
+ /* See if the handle of the queue being unregistered in actually in the\r
+ registry. */\r
+ for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )\r
+ {\r
+ if( xQueueRegistry[ ux ].xHandle == xQueue )\r
+ {\r
+ /* Set the name to NULL to show that this slot if free again. */\r
+ xQueueRegistry[ ux ].pcQueueName = NULL;\r
+ break;\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_TIMERS == 1\r
+\r
+ void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait )\r
+ {\r
+ /* This function should not be called by application code hence the\r
+ 'Restricted' in its name. It is not part of the public API. It is\r
+ designed for use by kernel code, and has special calling requirements.\r
+ It can result in vListInsert() being called on a list that can only\r
+ possibly ever have one item in it, so the list will be fast, but even\r
+ so it should be called with the scheduler locked and not from a critical\r
+ section. */\r
+\r
+ /* Only do anything if there are no messages in the queue. This function\r
+ will not actually cause the task to block, just place it on a blocked\r
+ list. It will not block until the scheduler is unlocked - at which\r
+ time a yield will be performed. If an item is added to the queue while\r
+ the queue is locked, and the calling task blocks on the queue, then the\r
+ calling task will be immediately unblocked when the queue is unlocked. */\r
+ prvLockQueue( pxQueue );\r
+ if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ /* There is nothing in the queue, block for the specified period. */\r
+ vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+ }\r
+ prvUnlockQueue( pxQueue );\r
+ }\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+\r
+#ifndef QUEUE_H\r
+#define QUEUE_H\r
+\r
+#ifndef INC_FREERTOS_H\r
+ #error "include FreeRTOS.h" must appear in source files before "include queue.h"\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+#include "mpu_wrappers.h"\r
+\r
+/**\r
+ * Type by which queues are referenced. For example, a call to xQueueCreate\r
+ * returns (via a pointer parameter) an xQueueHandle variable that can then\r
+ * be used as a parameter to xQueueSend(), xQueueReceive(), etc.\r
+ */\r
+typedef void * xQueueHandle;\r
+\r
+\r
+/* For internal use only. */\r
+#define queueSEND_TO_BACK ( 0 )\r
+#define queueSEND_TO_FRONT ( 1 )\r
+\r
+/* For internal use only. These definitions *must* match those in queue.c. */\r
+#define queueQUEUE_TYPE_BASE ( 0U )\r
+#define queueQUEUE_TYPE_MUTEX ( 1U )\r
+#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
+#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
+#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ xQueueHandle xQueueCreate(\r
+ unsigned portBASE_TYPE uxQueueLength,\r
+ unsigned portBASE_TYPE uxItemSize\r
+ );\r
+ * </pre>\r
+ *\r
+ * Creates a new queue instance. This allocates the storage required by the\r
+ * new queue and returns a handle for the queue.\r
+ *\r
+ * @param uxQueueLength The maximum number of items that the queue can contain.\r
+ *\r
+ * @param uxItemSize The number of bytes each item in the queue will require.\r
+ * Items are queued by copy, not by reference, so this is the number of bytes\r
+ * that will be copied for each posted item. Each item on the queue must be\r
+ * the same size.\r
+ *\r
+ * @return If the queue is successfully create then a handle to the newly\r
+ * created queue is returned. If the queue cannot be created then 0 is\r
+ * returned.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ };\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+ if( xQueue1 == 0 )\r
+ {\r
+ // Queue was not created and must not be used.\r
+ }\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue2 == 0 )\r
+ {\r
+ // Queue was not created and must not be used.\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueCreate xQueueCreate\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendToToFront(\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ );\r
+ * </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSend().\r
+ *\r
+ * Post an item to the front of a queue. The item is queued by copy, not by\r
+ * reference. This function must not be called from an interrupt service\r
+ * routine. See xQueueSendFromISR () for an alternative which may be used\r
+ * in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full. The call will return immediately if this is set to 0 and the\r
+ * queue is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned long ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendToBack(\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ );\r
+ * </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSend().\r
+ *\r
+ * Post an item to the back of a queue. The item is queued by copy, not by\r
+ * reference. This function must not be called from an interrupt service\r
+ * routine. See xQueueSendFromISR () for an alternative which may be used\r
+ * in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full. The call will return immediately if this is set to 0 and the queue\r
+ * is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned long ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSend(\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ );\r
+ * </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSend(). It is included for\r
+ * backward compatibility with versions of FreeRTOS.org that did not\r
+ * include the xQueueSendToFront() and xQueueSendToBack() macros. It is\r
+ * equivalent to xQueueSendToBack().\r
+ *\r
+ * Post an item on a queue. The item is queued by copy, not by reference.\r
+ * This function must not be called from an interrupt service routine.\r
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full. The call will return immediately if this is set to 0 and the\r
+ * queue is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned long ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
+\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueGenericSend(\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portTickType xTicksToWait\r
+ portBASE_TYPE xCopyPosition\r
+ );\r
+ * </pre>\r
+ *\r
+ * It is preferred that the macros xQueueSend(), xQueueSendToFront() and\r
+ * xQueueSendToBack() are used in place of calling this function directly.\r
+ *\r
+ * Post an item on a queue. The item is queued by copy, not by reference.\r
+ * This function must not be called from an interrupt service routine.\r
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full. The call will return immediately if this is set to 0 and the\r
+ * queue is full. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ *\r
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
+ * at the front of the queue (for high priority messages).\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned long ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 unsigned long values.\r
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+ // ...\r
+\r
+ if( xQueue1 != 0 )\r
+ {\r
+ // Send an unsigned long. Wait for 10 ticks for space to become\r
+ // available if necessary.\r
+ if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )\r
+ {\r
+ // Failed to post the message, even after 10 ticks.\r
+ }\r
+ }\r
+\r
+ if( xQueue2 != 0 )\r
+ {\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueuePeek(\r
+ xQueueHandle xQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait\r
+ );</pre>\r
+ *\r
+ * This is a macro that calls the xQueueGenericReceive() function.\r
+ *\r
+ * Receive an item from a queue without removing the item from the queue.\r
+ * The item is received by copy so a buffer of adequate size must be\r
+ * provided. The number of bytes copied into the buffer was defined when\r
+ * the queue was created.\r
+ *\r
+ * Successfully received items remain on the queue so will be returned again\r
+ * by the next call, or a call to xQueueReceive().\r
+ *\r
+ * This macro must not be used in an interrupt service routine.\r
+ *\r
+ * @param pxQueue The handle to the queue from which the item is to be\r
+ * received.\r
+ *\r
+ * @param pvBuffer Pointer to the buffer into which the received item will\r
+ * be copied.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for an item to receive should the queue be empty at the time\r
+ * of the call. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue\r
+ * is empty.\r
+ *\r
+ * @return pdTRUE if an item was successfully received from the queue,\r
+ * otherwise pdFALSE.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ xQueueHandle xQueue;\r
+\r
+ // Task to create a queue and post a value.\r
+ void vATask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
+\r
+ // ...\r
+\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+\r
+ // ... Rest of task code.\r
+ }\r
+\r
+ // Task to peek the data from the queue.\r
+ void vADifferentTask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxRxedMessage;\r
+\r
+ if( xQueue != 0 )\r
+ {\r
+ // Peek a message on the created queue. Block for 10 ticks if a\r
+ // message is not immediately available.\r
+ if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+ {\r
+ // pcRxedMessage now points to the struct AMessage variable posted\r
+ // by vATask, but the item still remains on the queue.\r
+ }\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueReceive xQueueReceive\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueReceive(\r
+ xQueueHandle xQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait\r
+ );</pre>\r
+ *\r
+ * This is a macro that calls the xQueueGenericReceive() function.\r
+ *\r
+ * Receive an item from a queue. The item is received by copy so a buffer of\r
+ * adequate size must be provided. The number of bytes copied into the buffer\r
+ * was defined when the queue was created.\r
+ *\r
+ * Successfully received items are removed from the queue.\r
+ *\r
+ * This function must not be used in an interrupt service routine. See\r
+ * xQueueReceiveFromISR for an alternative that can.\r
+ *\r
+ * @param pxQueue The handle to the queue from which the item is to be\r
+ * received.\r
+ *\r
+ * @param pvBuffer Pointer to the buffer into which the received item will\r
+ * be copied.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for an item to receive should the queue be empty at the time\r
+ * of the call. xQueueReceive() will return immediately if xTicksToWait\r
+ * is zero and the queue is empty. The time is defined in tick periods so the\r
+ * constant portTICK_RATE_MS should be used to convert to real time if this is\r
+ * required.\r
+ *\r
+ * @return pdTRUE if an item was successfully received from the queue,\r
+ * otherwise pdFALSE.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ xQueueHandle xQueue;\r
+\r
+ // Task to create a queue and post a value.\r
+ void vATask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
+\r
+ // ...\r
+\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+\r
+ // ... Rest of task code.\r
+ }\r
+\r
+ // Task to receive from the queue.\r
+ void vADifferentTask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxRxedMessage;\r
+\r
+ if( xQueue != 0 )\r
+ {\r
+ // Receive a message on the created queue. Block for 10 ticks if a\r
+ // message is not immediately available.\r
+ if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+ {\r
+ // pcRxedMessage now points to the struct AMessage variable posted\r
+ // by vATask.\r
+ }\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueReceive xQueueReceive\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )\r
+\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueGenericReceive(\r
+ xQueueHandle xQueue,\r
+ void *pvBuffer,\r
+ portTickType xTicksToWait\r
+ portBASE_TYPE xJustPeek\r
+ );</pre>\r
+ *\r
+ * It is preferred that the macro xQueueReceive() be used rather than calling\r
+ * this function directly.\r
+ *\r
+ * Receive an item from a queue. The item is received by copy so a buffer of\r
+ * adequate size must be provided. The number of bytes copied into the buffer\r
+ * was defined when the queue was created.\r
+ *\r
+ * This function must not be used in an interrupt service routine. See\r
+ * xQueueReceiveFromISR for an alternative that can.\r
+ *\r
+ * @param pxQueue The handle to the queue from which the item is to be\r
+ * received.\r
+ *\r
+ * @param pvBuffer Pointer to the buffer into which the received item will\r
+ * be copied.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for an item to receive should the queue be empty at the time\r
+ * of the call. The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ * xQueueGenericReceive() will return immediately if the queue is empty and\r
+ * xTicksToWait is 0.\r
+ *\r
+ * @param xJustPeek When set to true, the item received from the queue is not\r
+ * actually removed from the queue - meaning a subsequent call to\r
+ * xQueueReceive() will return the same item. When set to false, the item\r
+ * being received from the queue is also removed from the queue.\r
+ *\r
+ * @return pdTRUE if an item was successfully received from the queue,\r
+ * otherwise pdFALSE.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ struct AMessage\r
+ {\r
+ char ucMessageID;\r
+ char ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ xQueueHandle xQueue;\r
+\r
+ // Task to create a queue and post a value.\r
+ void vATask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxMessage;\r
+\r
+ // Create a queue capable of containing 10 pointers to AMessage structures.\r
+ // These should be passed by pointer as they contain a lot of data.\r
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
+\r
+ // ...\r
+\r
+ // Send a pointer to a struct AMessage object. Don't block if the\r
+ // queue is already full.\r
+ pxMessage = & xMessage;\r
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+\r
+ // ... Rest of task code.\r
+ }\r
+\r
+ // Task to receive from the queue.\r
+ void vADifferentTask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxRxedMessage;\r
+\r
+ if( xQueue != 0 )\r
+ {\r
+ // Receive a message on the created queue. Block for 10 ticks if a\r
+ // message is not immediately available.\r
+ if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+ {\r
+ // pcRxedMessage now points to the struct AMessage variable posted\r
+ // by vATask.\r
+ }\r
+ }\r
+\r
+ // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueReceive xQueueReceive\r
+ * \ingroup QueueManagement\r
+ */\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek );\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );</pre>\r
+ *\r
+ * Return the number of messages stored in a queue.\r
+ *\r
+ * @param xQueue A handle to the queue being queried.\r
+ *\r
+ * @return The number of messages available in the queue.\r
+ *\r
+ * \page uxQueueMessagesWaiting uxQueueMessagesWaiting\r
+ * \ingroup QueueManagement\r
+ */\r
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>void vQueueDelete( xQueueHandle xQueue );</pre>\r
+ *\r
+ * Delete a queue - freeing all the memory allocated for storing of items\r
+ * placed on the queue.\r
+ *\r
+ * @param xQueue A handle to the queue to be deleted.\r
+ *\r
+ * \page vQueueDelete vQueueDelete\r
+ * \ingroup QueueManagement\r
+ */\r
+void vQueueDelete( xQueueHandle pxQueue );\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendToFrontFromISR(\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
+ </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSendFromISR().\r
+ *\r
+ * Post an item to the front of a queue. It is safe to use this macro from\r
+ * within an interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR. In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
+ * errQUEUE_FULL.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+ <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ char cIn;\r
+ portBASE_TYPE xHigherPrioritTaskWoken;\r
+\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
+\r
+ // Post the byte.\r
+ xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
+\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+ // Now the buffer is empty we can switch context if necessary.\r
+ if( xHigherPriorityTaskWoken )\r
+ {\r
+ taskYIELD ();\r
+ }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToFrontFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )\r
+\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendToBackFromISR(\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
+ </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSendFromISR().\r
+ *\r
+ * Post an item to the back of a queue. It is safe to use this macro from\r
+ * within an interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR. In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
+ * errQUEUE_FULL.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+ <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ char cIn;\r
+ portBASE_TYPE xHigherPriorityTaskWoken;\r
+\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
+\r
+ // Post the byte.\r
+ xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
+\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+ // Now the buffer is empty we can switch context if necessary.\r
+ if( xHigherPriorityTaskWoken )\r
+ {\r
+ taskYIELD ();\r
+ }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendFromISR(\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
+ </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSendFromISR(). It is included\r
+ * for backward compatibility with versions of FreeRTOS.org that did not\r
+ * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()\r
+ * macros.\r
+ *\r
+ * Post an item to the back of a queue. It is safe to use this function from\r
+ * within an interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR. In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xQueueSendFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
+ * errQUEUE_FULL.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+ <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ char cIn;\r
+ portBASE_TYPE xHigherPriorityTaskWoken;\r
+\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
+\r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
+\r
+ // Post the byte.\r
+ xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
+\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+ // Now the buffer is empty we can switch context if necessary.\r
+ if( xHigherPriorityTaskWoken )\r
+ {\r
+ // Actual macro used here is port specific.\r
+ taskYIELD_FROM_ISR ();\r
+ }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendFromISR( pxQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueGenericSendFromISR(\r
+ xQueueHandle pxQueue,\r
+ const void *pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken,\r
+ portBASE_TYPE xCopyPosition\r
+ );\r
+ </pre>\r
+ *\r
+ * It is preferred that the macros xQueueSendFromISR(),\r
+ * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place\r
+ * of calling this function directly.\r
+ *\r
+ * Post an item on a queue. It is safe to use this function from within an\r
+ * interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR. In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
+ * at the front of the queue (for high priority messages).\r
+ *\r
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
+ * errQUEUE_FULL.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+ <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ char cIn;\r
+ portBASE_TYPE xHigherPriorityTaskWokenByPost;\r
+\r
+ // We have not woken a task at the start of the ISR.\r
+ xHigherPriorityTaskWokenByPost = pdFALSE;\r
+\r
+ // Loop until the buffer is empty.\r
+ do\r
+ {\r
+ // Obtain a byte from the buffer.\r
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
+\r
+ // Post each byte.\r
+ xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );\r
+\r
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+ // Now the buffer is empty we can switch context if necessary. Note that the\r
+ // name of the yield function required is port specific.\r
+ if( xHigherPriorityTaskWokenByPost )\r
+ {\r
+ taskYIELD_YIELD_FROM_ISR();\r
+ }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueReceiveFromISR(\r
+ xQueueHandle pxQueue,\r
+ void *pvBuffer,\r
+ portBASE_TYPE *pxTaskWoken\r
+ );\r
+ * </pre>\r
+ *\r
+ * Receive an item from a queue. It is safe to use this function from within an\r
+ * interrupt service routine.\r
+ *\r
+ * @param pxQueue The handle to the queue from which the item is to be\r
+ * received.\r
+ *\r
+ * @param pvBuffer Pointer to the buffer into which the received item will\r
+ * be copied.\r
+ *\r
+ * @param pxTaskWoken A task may be blocked waiting for space to become\r
+ * available on the queue. If xQueueReceiveFromISR causes such a task to\r
+ * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will\r
+ * remain unchanged.\r
+ *\r
+ * @return pdTRUE if an item was successfully received from the queue,\r
+ * otherwise pdFALSE.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+\r
+ xQueueHandle xQueue;\r
+\r
+ // Function to create a queue and post some values.\r
+ void vAFunction( void *pvParameters )\r
+ {\r
+ char cValueToPost;\r
+ const portTickType xBlockTime = ( portTickType )0xff;\r
+\r
+ // Create a queue capable of containing 10 characters.\r
+ xQueue = xQueueCreate( 10, sizeof( char ) );\r
+ if( xQueue == 0 )\r
+ {\r
+ // Failed to create the queue.\r
+ }\r
+\r
+ // ...\r
+\r
+ // Post some characters that will be used within an ISR. If the queue\r
+ // is full then this task will block for xBlockTime ticks.\r
+ cValueToPost = 'a';\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ cValueToPost = 'b';\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+\r
+ // ... keep posting characters ... this task may block when the queue\r
+ // becomes full.\r
+\r
+ cValueToPost = 'c';\r
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
+ }\r
+\r
+ // ISR that outputs all the characters received on the queue.\r
+ void vISR_Routine( void )\r
+ {\r
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;\r
+ char cRxedChar;\r
+\r
+ while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )\r
+ {\r
+ // A character was received. Output the character now.\r
+ vOutputCharacter( cRxedChar );\r
+\r
+ // If removing the character from the queue woke the task that was\r
+ // posting onto the queue cTaskWokenByReceive will have been set to\r
+ // pdTRUE. No matter how many times this loop iterates only one\r
+ // task will be woken.\r
+ }\r
+\r
+ if( cTaskWokenByPost != ( char ) pdFALSE;\r
+ {\r
+ taskYIELD ();\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken );\r
+\r
+/*\r
+ * Utilities to query queues that are safe to use from an ISR. These utilities\r
+ * should be used only from witin an ISR, or within a critical section.\r
+ */\r
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );\r
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );\r
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );\r
+\r
+\r
+/*\r
+ * xQueueAltGenericSend() is an alternative version of xQueueGenericSend().\r
+ * Likewise xQueueAltGenericReceive() is an alternative version of\r
+ * xQueueGenericReceive().\r
+ *\r
+ * The source code that implements the alternative (Alt) API is much\r
+ * simpler because it executes everything from within a critical section.\r
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the\r
+ * preferred fully featured API too. The fully featured API has more\r
+ * complex code that takes longer to execute, but makes much less use of\r
+ * critical sections. Therefore the alternative API sacrifices interrupt\r
+ * responsiveness to gain execution speed, whereas the fully featured API\r
+ * sacrifices execution speed to ensure better interrupt responsiveness.\r
+ */\r
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
+#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )\r
+#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
+#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )\r
+#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )\r
+\r
+/*\r
+ * The functions defined above are for passing data to and from tasks. The\r
+ * functions below are the equivalents for passing data to and from\r
+ * co-routines.\r
+ *\r
+ * These functions are called from the co-routine macro implementation and\r
+ * should not be called directly from application code. Instead use the macro\r
+ * wrappers defined within croutine.h.\r
+ */\r
+signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
+signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
+signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );\r
+signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
+\r
+/*\r
+ * For internal use only. Use xSemaphoreCreateMutex(), \r
+ * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling \r
+ * these functions directly.\r
+ */\r
+xQueueHandle xQueueCreateMutex( unsigned char ucQueueType );\r
+xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );\r
+void* xQueueGetMutexHolder( xQueueHandle xSemaphore );\r
+\r
+/*\r
+ * For internal use only. Use xSemaphoreTakeMutexRecursive() or\r
+ * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.\r
+ */\r
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime );\r
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex );\r
+\r
+/*\r
+ * Reset a queue back to its original empty state. pdPASS is returned if the\r
+ * queue is successfully reset. pdFAIL is returned if the queue could not be\r
+ * reset because there are tasks blocked on the queue waiting to either\r
+ * receive from the queue or send to the queue.\r
+ */\r
+#define xQueueReset( pxQueue ) xQueueGenericReset( pxQueue, pdFALSE )\r
+\r
+/*\r
+ * The registry is provided as a means for kernel aware debuggers to\r
+ * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add\r
+ * a queue, semaphore or mutex handle to the registry if you want the handle\r
+ * to be available to a kernel aware debugger. If you are not using a kernel\r
+ * aware debugger then this function can be ignored.\r
+ *\r
+ * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the\r
+ * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0\r
+ * within FreeRTOSConfig.h for the registry to be available. Its value\r
+ * does not effect the number of queues, semaphores and mutexes that can be\r
+ * created - just the number that the registry can hold.\r
+ *\r
+ * @param xQueue The handle of the queue being added to the registry. This\r
+ * is the handle returned by a call to xQueueCreate(). Semaphore and mutex\r
+ * handles can also be passed in here.\r
+ *\r
+ * @param pcName The name to be associated with the handle. This is the\r
+ * name that the kernel aware debugger will display.\r
+ */\r
+#if configQUEUE_REGISTRY_SIZE > 0U\r
+ void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName );\r
+#endif\r
+\r
+/*\r
+ * Generic version of the queue creation function, which is in turn called by \r
+ * any queue, semaphore or mutex creation function or macro.\r
+ */\r
+xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );\r
+\r
+/* Not public API functions. */\r
+void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );\r
+portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* QUEUE_H */\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef SEMAPHORE_H\r
+#define SEMAPHORE_H\r
+\r
+#ifndef INC_FREERTOS_H\r
+ #error "include FreeRTOS.h" must appear in source files before "include semphr.h"\r
+#endif\r
+\r
+#include "queue.h"\r
+\r
+typedef xQueueHandle xSemaphoreHandle;\r
+\r
+#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U )\r
+#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U )\r
+#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U )\r
+\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>\r
+ *\r
+ * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.\r
+ * The queue length is 1 as this is a binary semaphore. The data size is 0\r
+ * as we don't want to actually store any data - we just want to know if the\r
+ * queue is empty or full.\r
+ *\r
+ * This type of semaphore can be used for pure synchronisation between tasks or\r
+ * between an interrupt and a task. The semaphore need not be given back once\r
+ * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
+ * another continuously 'takes' the semaphore. For this reason this type of\r
+ * semaphore does not use a priority inheritance mechanism. For an alternative\r
+ * that does use priority inheritance see xSemaphoreCreateMutex().\r
+ *\r
+ * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore;\r
+\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
+ // This is a macro so pass the variable in directly.\r
+ vSemaphoreCreateBinary( xSemaphore );\r
+\r
+ if( xSemaphore != NULL )\r
+ {\r
+ // The semaphore was created successfully.\r
+ // The semaphore can now be used. \r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary\r
+ * \ingroup Semaphores\r
+ */\r
+#define vSemaphoreCreateBinary( xSemaphore ) \\r
+ { \\r
+ ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \\r
+ if( ( xSemaphore ) != NULL ) \\r
+ { \\r
+ xSemaphoreGive( ( xSemaphore ) ); \\r
+ } \\r
+ }\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreTake( \r
+ * xSemaphoreHandle xSemaphore, \r
+ * portTickType xBlockTime \r
+ * )</pre>\r
+ *\r
+ * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been\r
+ * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
+ * xSemaphoreCreateCounting().\r
+ *\r
+ * @param xSemaphore A handle to the semaphore being taken - obtained when\r
+ * the semaphore was created.\r
+ *\r
+ * @param xBlockTime The time in ticks to wait for the semaphore to become\r
+ * available. The macro portTICK_RATE_MS can be used to convert this to a\r
+ * real time. A block time of zero can be used to poll the semaphore. A block\r
+ * time of portMAX_DELAY can be used to block indefinitely (provided\r
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).\r
+ *\r
+ * @return pdTRUE if the semaphore was obtained. pdFALSE\r
+ * if xBlockTime expired without the semaphore becoming available.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore = NULL;\r
+\r
+ // A task that creates a semaphore.\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Create the semaphore to guard a shared resource.\r
+ vSemaphoreCreateBinary( xSemaphore );\r
+ }\r
+\r
+ // A task that uses the semaphore.\r
+ void vAnotherTask( void * pvParameters )\r
+ {\r
+ // ... Do other things.\r
+\r
+ if( xSemaphore != NULL )\r
+ {\r
+ // See if we can obtain the semaphore. If the semaphore is not available\r
+ // wait 10 ticks to see if it becomes free. \r
+ if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )\r
+ {\r
+ // We were able to obtain the semaphore and can now access the\r
+ // shared resource.\r
+\r
+ // ...\r
+\r
+ // We have finished accessing the shared resource. Release the \r
+ // semaphore.\r
+ xSemaphoreGive( xSemaphore );\r
+ }\r
+ else\r
+ {\r
+ // We could not obtain the semaphore and can therefore not access\r
+ // the shared resource safely.\r
+ }\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xSemaphoreTake xSemaphoreTake\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )\r
+\r
+/**\r
+ * semphr. h\r
+ * xSemaphoreTakeRecursive( \r
+ * xSemaphoreHandle xMutex, \r
+ * portTickType xBlockTime \r
+ * )\r
+ *\r
+ * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore. \r
+ * The mutex must have previously been created using a call to \r
+ * xSemaphoreCreateRecursiveMutex();\r
+ * \r
+ * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
+ * macro to be available.\r
+ * \r
+ * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
+ *\r
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
+ * doesn't become available again until the owner has called \r
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example, \r
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
+ * not be available to any other task until it has also 'given' the mutex back\r
+ * exactly five times.\r
+ *\r
+ * @param xMutex A handle to the mutex being obtained. This is the\r
+ * handle returned by xSemaphoreCreateRecursiveMutex();\r
+ *\r
+ * @param xBlockTime The time in ticks to wait for the semaphore to become\r
+ * available. The macro portTICK_RATE_MS can be used to convert this to a\r
+ * real time. A block time of zero can be used to poll the semaphore. If\r
+ * the task already owns the semaphore then xSemaphoreTakeRecursive() will\r
+ * return immediately no matter what the value of xBlockTime. \r
+ *\r
+ * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime\r
+ * expired without the semaphore becoming available.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xMutex = NULL;\r
+\r
+ // A task that creates a mutex.\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Create the mutex to guard a shared resource.\r
+ xMutex = xSemaphoreCreateRecursiveMutex();\r
+ }\r
+\r
+ // A task that uses the mutex.\r
+ void vAnotherTask( void * pvParameters )\r
+ {\r
+ // ... Do other things.\r
+\r
+ if( xMutex != NULL )\r
+ {\r
+ // See if we can obtain the mutex. If the mutex is not available\r
+ // wait 10 ticks to see if it becomes free. \r
+ if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )\r
+ {\r
+ // We were able to obtain the mutex and can now access the\r
+ // shared resource.\r
+\r
+ // ...\r
+ // For some reason due to the nature of the code further calls to \r
+ // xSemaphoreTakeRecursive() are made on the same mutex. In real\r
+ // code these would not be just sequential calls as this would make\r
+ // no sense. Instead the calls are likely to be buried inside\r
+ // a more complex call structure.\r
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
+\r
+ // The mutex has now been 'taken' three times, so will not be \r
+ // available to another task until it has also been given back\r
+ // three times. Again it is unlikely that real code would have\r
+ // these calls sequentially, but instead buried in a more complex\r
+ // call structure. This is just for illustrative purposes.\r
+ xSemaphoreGiveRecursive( xMutex );\r
+ xSemaphoreGiveRecursive( xMutex );\r
+ xSemaphoreGiveRecursive( xMutex );\r
+\r
+ // Now the mutex can be taken by other tasks.\r
+ }\r
+ else\r
+ {\r
+ // We could not obtain the mutex and can therefore not access\r
+ // the shared resource safely.\r
+ }\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )\r
+\r
+\r
+/* \r
+ * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().\r
+ *\r
+ * The source code that implements the alternative (Alt) API is much \r
+ * simpler because it executes everything from within a critical section. \r
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
+ * preferred fully featured API too. The fully featured API has more \r
+ * complex code that takes longer to execute, but makes much less use of \r
+ * critical sections. Therefore the alternative API sacrifices interrupt \r
+ * responsiveness to gain execution speed, whereas the fully featured API\r
+ * sacrifices execution speed to ensure better interrupt responsiveness.\r
+ */\r
+#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>\r
+ *\r
+ * <i>Macro</i> to release a semaphore. The semaphore must have previously been\r
+ * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
+ * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().\r
+ *\r
+ * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for\r
+ * an alternative which can be used from an ISR.\r
+ *\r
+ * This macro must also not be used on semaphores created using \r
+ * xSemaphoreCreateRecursiveMutex().\r
+ *\r
+ * @param xSemaphore A handle to the semaphore being released. This is the\r
+ * handle returned when the semaphore was created.\r
+ *\r
+ * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.\r
+ * Semaphores are implemented using queues. An error can occur if there is\r
+ * no space on the queue to post a message - indicating that the \r
+ * semaphore was not first obtained correctly.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore = NULL;\r
+\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Create the semaphore to guard a shared resource.\r
+ vSemaphoreCreateBinary( xSemaphore );\r
+\r
+ if( xSemaphore != NULL )\r
+ {\r
+ if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
+ {\r
+ // We would expect this call to fail because we cannot give\r
+ // a semaphore without first "taking" it!\r
+ }\r
+\r
+ // Obtain the semaphore - don't block if the semaphore is not\r
+ // immediately available.\r
+ if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )\r
+ {\r
+ // We now have the semaphore and can access the shared resource.\r
+\r
+ // ...\r
+\r
+ // We have finished accessing the shared resource so can free the\r
+ // semaphore.\r
+ if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
+ {\r
+ // We would not expect this call to fail because we must have\r
+ // obtained the semaphore to get here.\r
+ }\r
+ }\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xSemaphoreGive xSemaphoreGive\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>\r
+ *\r
+ * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.\r
+ * The mutex must have previously been created using a call to \r
+ * xSemaphoreCreateRecursiveMutex();\r
+ * \r
+ * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
+ * macro to be available.\r
+ *\r
+ * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
+ * \r
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
+ * doesn't become available again until the owner has called \r
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example, \r
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
+ * not be available to any other task until it has also 'given' the mutex back\r
+ * exactly five times.\r
+ *\r
+ * @param xMutex A handle to the mutex being released, or 'given'. This is the\r
+ * handle returned by xSemaphoreCreateMutex();\r
+ *\r
+ * @return pdTRUE if the semaphore was given.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xMutex = NULL;\r
+\r
+ // A task that creates a mutex.\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Create the mutex to guard a shared resource.\r
+ xMutex = xSemaphoreCreateRecursiveMutex();\r
+ }\r
+\r
+ // A task that uses the mutex.\r
+ void vAnotherTask( void * pvParameters )\r
+ {\r
+ // ... Do other things.\r
+\r
+ if( xMutex != NULL )\r
+ {\r
+ // See if we can obtain the mutex. If the mutex is not available\r
+ // wait 10 ticks to see if it becomes free. \r
+ if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )\r
+ {\r
+ // We were able to obtain the mutex and can now access the\r
+ // shared resource.\r
+\r
+ // ...\r
+ // For some reason due to the nature of the code further calls to \r
+ // xSemaphoreTakeRecursive() are made on the same mutex. In real\r
+ // code these would not be just sequential calls as this would make\r
+ // no sense. Instead the calls are likely to be buried inside\r
+ // a more complex call structure.\r
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
+ xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );\r
+\r
+ // The mutex has now been 'taken' three times, so will not be \r
+ // available to another task until it has also been given back\r
+ // three times. Again it is unlikely that real code would have\r
+ // these calls sequentially, it would be more likely that the calls\r
+ // to xSemaphoreGiveRecursive() would be called as a call stack\r
+ // unwound. This is just for demonstrative purposes.\r
+ xSemaphoreGiveRecursive( xMutex );\r
+ xSemaphoreGiveRecursive( xMutex );\r
+ xSemaphoreGiveRecursive( xMutex );\r
+\r
+ // Now the mutex can be taken by other tasks.\r
+ }\r
+ else\r
+ {\r
+ // We could not obtain the mutex and can therefore not access\r
+ // the shared resource safely.\r
+ }\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )\r
+\r
+/* \r
+ * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().\r
+ *\r
+ * The source code that implements the alternative (Alt) API is much \r
+ * simpler because it executes everything from within a critical section. \r
+ * This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
+ * preferred fully featured API too. The fully featured API has more \r
+ * complex code that takes longer to execute, but makes much less use of \r
+ * critical sections. Therefore the alternative API sacrifices interrupt \r
+ * responsiveness to gain execution speed, whereas the fully featured API\r
+ * sacrifices execution speed to ensure better interrupt responsiveness.\r
+ */\r
+#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>\r
+ xSemaphoreGiveFromISR( \r
+ xSemaphoreHandle xSemaphore, \r
+ signed portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ )</pre>\r
+ *\r
+ * <i>Macro</i> to release a semaphore. The semaphore must have previously been\r
+ * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().\r
+ *\r
+ * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
+ * must not be used with this macro.\r
+ *\r
+ * This macro can be used from an ISR.\r
+ *\r
+ * @param xSemaphore A handle to the semaphore being released. This is the\r
+ * handle returned when the semaphore was created.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ \#define LONG_TIME 0xffff\r
+ \#define TICKS_TO_WAIT 10\r
+ xSemaphoreHandle xSemaphore = NULL;\r
+\r
+ // Repetitive task.\r
+ void vATask( void * pvParameters )\r
+ {\r
+ for( ;; )\r
+ {\r
+ // We want this task to run every 10 ticks of a timer. The semaphore \r
+ // was created before this task was started.\r
+\r
+ // Block waiting for the semaphore to become available.\r
+ if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )\r
+ {\r
+ // It is time to execute.\r
+\r
+ // ...\r
+\r
+ // We have finished our task. Return to the top of the loop where\r
+ // we will block on the semaphore until it is time to execute \r
+ // again. Note when using the semaphore for synchronisation with an\r
+ // ISR in this manner there is no need to 'give' the semaphore back.\r
+ }\r
+ }\r
+ }\r
+\r
+ // Timer ISR\r
+ void vTimerISR( void * pvParameters )\r
+ {\r
+ static unsigned char ucLocalTickCount = 0;\r
+ static signed portBASE_TYPE xHigherPriorityTaskWoken;\r
+\r
+ // A timer tick has occurred.\r
+\r
+ // ... Do other time functions.\r
+\r
+ // Is it time for vATask () to run?\r
+ xHigherPriorityTaskWoken = pdFALSE;\r
+ ucLocalTickCount++;\r
+ if( ucLocalTickCount >= TICKS_TO_WAIT )\r
+ {\r
+ // Unblock the task by releasing the semaphore.\r
+ xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );\r
+\r
+ // Reset the count so we release the semaphore again in 10 ticks time.\r
+ ucLocalTickCount = 0;\r
+ }\r
+\r
+ if( xHigherPriorityTaskWoken != pdFALSE )\r
+ {\r
+ // We can force a context switch here. Context switching from an\r
+ // ISR uses port specific syntax. Check the demo task for your port\r
+ // to find the syntax required.\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>\r
+ xSemaphoreTakeFromISR( \r
+ xSemaphoreHandle xSemaphore, \r
+ signed portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ )</pre>\r
+ *\r
+ * <i>Macro</i> to take a semaphore from an ISR. The semaphore must have \r
+ * previously been created with a call to vSemaphoreCreateBinary() or \r
+ * xSemaphoreCreateCounting().\r
+ *\r
+ * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
+ * must not be used with this macro.\r
+ *\r
+ * This macro can be used from an ISR, however taking a semaphore from an ISR\r
+ * is not a common operation. It is likely to only be useful when taking a\r
+ * counting semaphore when an interrupt is obtaining an object from a resource\r
+ * pool (when the semaphore count indicates the number of resources available).\r
+ *\r
+ * @param xSemaphore A handle to the semaphore being taken. This is the\r
+ * handle returned when the semaphore was created.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @return pdTRUE if the semaphore was successfully taken, otherwise \r
+ * pdFALSE\r
+ */\r
+#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>\r
+ *\r
+ * <i>Macro</i> that implements a mutex semaphore by using the existing queue \r
+ * mechanism.\r
+ *\r
+ * Mutexes created using this macro can be accessed using the xSemaphoreTake()\r
+ * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and \r
+ * xSemaphoreGiveRecursive() macros should not be used.\r
+ * \r
+ * This type of semaphore uses a priority inheritance mechanism so a task \r
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
+ * semaphore it is no longer required. \r
+ *\r
+ * Mutex type semaphores cannot be used from within interrupt service routines. \r
+ *\r
+ * See vSemaphoreCreateBinary() for an alternative implementation that can be \r
+ * used for pure synchronisation (where one task or interrupt always 'gives' the \r
+ * semaphore and another always 'takes' the semaphore) and from within interrupt \r
+ * service routines.\r
+ *\r
+ * @return xSemaphore Handle to the created mutex semaphore. Should be of type \r
+ * xSemaphoreHandle.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore;\r
+\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
+ // This is a macro so pass the variable in directly.\r
+ xSemaphore = xSemaphoreCreateMutex();\r
+\r
+ if( xSemaphore != NULL )\r
+ {\r
+ // The semaphore was created successfully.\r
+ // The semaphore can now be used. \r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )\r
+\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>\r
+ *\r
+ * <i>Macro</i> that implements a recursive mutex by using the existing queue \r
+ * mechanism.\r
+ *\r
+ * Mutexes created using this macro can be accessed using the \r
+ * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The \r
+ * xSemaphoreTake() and xSemaphoreGive() macros should not be used.\r
+ *\r
+ * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex \r
+ * doesn't become available again until the owner has called \r
+ * xSemaphoreGiveRecursive() for each successful 'take' request. For example, \r
+ * if a task successfully 'takes' the same mutex 5 times then the mutex will \r
+ * not be available to any other task until it has also 'given' the mutex back\r
+ * exactly five times.\r
+ * \r
+ * This type of semaphore uses a priority inheritance mechanism so a task \r
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
+ * semaphore it is no longer required. \r
+ *\r
+ * Mutex type semaphores cannot be used from within interrupt service routines. \r
+ *\r
+ * See vSemaphoreCreateBinary() for an alternative implementation that can be \r
+ * used for pure synchronisation (where one task or interrupt always 'gives' the \r
+ * semaphore and another always 'takes' the semaphore) and from within interrupt \r
+ * service routines.\r
+ *\r
+ * @return xSemaphore Handle to the created mutex semaphore. Should be of type \r
+ * xSemaphoreHandle.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore;\r
+\r
+ void vATask( void * pvParameters )\r
+ {\r
+ // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
+ // This is a macro so pass the variable in directly.\r
+ xSemaphore = xSemaphoreCreateRecursiveMutex();\r
+\r
+ if( xSemaphore != NULL )\r
+ {\r
+ // The semaphore was created successfully.\r
+ // The semaphore can now be used. \r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>\r
+ *\r
+ * <i>Macro</i> that creates a counting semaphore by using the existing \r
+ * queue mechanism. \r
+ *\r
+ * Counting semaphores are typically used for two things:\r
+ *\r
+ * 1) Counting events. \r
+ *\r
+ * In this usage scenario an event handler will 'give' a semaphore each time\r
+ * an event occurs (incrementing the semaphore count value), and a handler \r
+ * task will 'take' a semaphore each time it processes an event \r
+ * (decrementing the semaphore count value). The count value is therefore \r
+ * the difference between the number of events that have occurred and the \r
+ * number that have been processed. In this case it is desirable for the \r
+ * initial count value to be zero.\r
+ *\r
+ * 2) Resource management.\r
+ *\r
+ * In this usage scenario the count value indicates the number of resources\r
+ * available. To obtain control of a resource a task must first obtain a \r
+ * semaphore - decrementing the semaphore count value. When the count value\r
+ * reaches zero there are no free resources. When a task finishes with the\r
+ * resource it 'gives' the semaphore back - incrementing the semaphore count\r
+ * value. In this case it is desirable for the initial count value to be\r
+ * equal to the maximum count value, indicating that all resources are free.\r
+ *\r
+ * @param uxMaxCount The maximum count value that can be reached. When the \r
+ * semaphore reaches this value it can no longer be 'given'.\r
+ *\r
+ * @param uxInitialCount The count value assigned to the semaphore when it is\r
+ * created.\r
+ *\r
+ * @return Handle to the created semaphore. Null if the semaphore could not be\r
+ * created.\r
+ * \r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore;\r
+\r
+ void vATask( void * pvParameters )\r
+ {\r
+ xSemaphoreHandle xSemaphore = NULL;\r
+\r
+ // Semaphore cannot be used before a call to xSemaphoreCreateCounting().\r
+ // The max value to which the semaphore can count should be 10, and the\r
+ // initial value assigned to the count should be 0.\r
+ xSemaphore = xSemaphoreCreateCounting( 10, 0 );\r
+\r
+ if( xSemaphore != NULL )\r
+ {\r
+ // The semaphore was created successfully.\r
+ // The semaphore can now be used. \r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>void vSemaphoreDelete( xSemaphoreHandle xSemaphore );</pre>\r
+ *\r
+ * Delete a semaphore. This function must be used with care. For example,\r
+ * do not delete a mutex type semaphore if the mutex is held by a task.\r
+ *\r
+ * @param xSemaphore A handle to the semaphore to be deleted.\r
+ *\r
+ * \page vSemaphoreDelete vSemaphoreDelete\r
+ * \ingroup Semaphores\r
+ */\r
+#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) )\r
+\r
+/**\r
+ * semphr.h\r
+ * <pre>xTaskHandle xSemaphoreGetMutexHolder( xSemaphoreHandle xMutex );</pre>\r
+ *\r
+ * If xMutex is indeed a mutex type semaphore, return the current mutex holder.\r
+ * If xMutex is not a mutex type semaphore, or the mutex is available (not held\r
+ * by a task), return NULL.\r
+ *\r
+ * Note: This Is is a good way of determining if the calling task is the mutex \r
+ * holder, but not a good way of determining the identity of the mutex holder as\r
+ * the holder may change between the function exiting and the returned value\r
+ * being tested.\r
+ */\r
+#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )\r
+\r
+#endif /* SEMAPHORE_H */\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - Selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+\r
+#ifndef TASK_H\r
+#define TASK_H\r
+\r
+#ifndef INC_FREERTOS_H\r
+ #error "include FreeRTOS.h must appear in source files before include task.h"\r
+#endif\r
+\r
+#include "portable.h"\r
+#include "list.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*-----------------------------------------------------------\r
+ * MACROS AND DEFINITIONS\r
+ *----------------------------------------------------------*/\r
+\r
+#define tskKERNEL_VERSION_NUMBER "V7.2.0"\r
+\r
+/**\r
+ * task. h\r
+ *\r
+ * Type by which tasks are referenced. For example, a call to xTaskCreate\r
+ * returns (via a pointer parameter) an xTaskHandle variable that can then\r
+ * be used as a parameter to vTaskDelete to delete the task.\r
+ *\r
+ * \page xTaskHandle xTaskHandle\r
+ * \ingroup Tasks\r
+ */\r
+typedef void * xTaskHandle;\r
+\r
+/*\r
+ * Used internally only.\r
+ */\r
+typedef struct xTIME_OUT\r
+{\r
+ portBASE_TYPE xOverflowCount;\r
+ portTickType xTimeOnEntering;\r
+} xTimeOutType;\r
+\r
+/*\r
+ * Defines the memory ranges allocated to the task when an MPU is used.\r
+ */\r
+typedef struct xMEMORY_REGION\r
+{\r
+ void *pvBaseAddress;\r
+ unsigned long ulLengthInBytes;\r
+ unsigned long ulParameters;\r
+} xMemoryRegion;\r
+\r
+/*\r
+ * Parameters required to create an MPU protected task.\r
+ */\r
+typedef struct xTASK_PARAMTERS\r
+{\r
+ pdTASK_CODE pvTaskCode;\r
+ const signed char * const pcName;\r
+ unsigned short usStackDepth;\r
+ void *pvParameters;\r
+ unsigned portBASE_TYPE uxPriority;\r
+ portSTACK_TYPE *puxStackBuffer;\r
+ xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];\r
+} xTaskParameters;\r
+\r
+/*\r
+ * Defines the priority used by the idle task. This must not be modified.\r
+ *\r
+ * \ingroup TaskUtils\r
+ */\r
+#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0U )\r
+\r
+/**\r
+ * task. h\r
+ *\r
+ * Macro for forcing a context switch.\r
+ *\r
+ * \page taskYIELD taskYIELD\r
+ * \ingroup SchedulerControl\r
+ */\r
+#define taskYIELD() portYIELD()\r
+\r
+/**\r
+ * task. h\r
+ *\r
+ * Macro to mark the start of a critical code region. Preemptive context\r
+ * switches cannot occur when in a critical region.\r
+ *\r
+ * NOTE: This may alter the stack (depending on the portable implementation)\r
+ * so must be used with care!\r
+ *\r
+ * \page taskENTER_CRITICAL taskENTER_CRITICAL\r
+ * \ingroup SchedulerControl\r
+ */\r
+#define taskENTER_CRITICAL() portENTER_CRITICAL()\r
+\r
+/**\r
+ * task. h\r
+ *\r
+ * Macro to mark the end of a critical code region. Preemptive context\r
+ * switches cannot occur when in a critical region.\r
+ *\r
+ * NOTE: This may alter the stack (depending on the portable implementation)\r
+ * so must be used with care!\r
+ *\r
+ * \page taskEXIT_CRITICAL taskEXIT_CRITICAL\r
+ * \ingroup SchedulerControl\r
+ */\r
+#define taskEXIT_CRITICAL() portEXIT_CRITICAL()\r
+\r
+/**\r
+ * task. h\r
+ *\r
+ * Macro to disable all maskable interrupts.\r
+ *\r
+ * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS\r
+ * \ingroup SchedulerControl\r
+ */\r
+#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()\r
+\r
+/**\r
+ * task. h\r
+ *\r
+ * Macro to enable microcontroller interrupts.\r
+ *\r
+ * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS\r
+ * \ingroup SchedulerControl\r
+ */\r
+#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()\r
+\r
+/* Definitions returned by xTaskGetSchedulerState(). */\r
+#define taskSCHEDULER_NOT_STARTED 0\r
+#define taskSCHEDULER_RUNNING 1\r
+#define taskSCHEDULER_SUSPENDED 2\r
+\r
+/*-----------------------------------------------------------\r
+ * TASK CREATION API\r
+ *----------------------------------------------------------*/\r
+\r
+/**\r
+ * task. h\r
+ *<pre>\r
+ portBASE_TYPE xTaskCreate(\r
+ pdTASK_CODE pvTaskCode,\r
+ const char * const pcName,\r
+ unsigned short usStackDepth,\r
+ void *pvParameters,\r
+ unsigned portBASE_TYPE uxPriority,\r
+ xTaskHandle *pvCreatedTask\r
+ );</pre>\r
+ *\r
+ * Create a new task and add it to the list of tasks that are ready to run.\r
+ *\r
+ * xTaskCreate() can only be used to create a task that has unrestricted\r
+ * access to the entire microcontroller memory map. Systems that include MPU\r
+ * support can alternatively create an MPU constrained task using\r
+ * xTaskCreateRestricted().\r
+ *\r
+ * @param pvTaskCode Pointer to the task entry function. Tasks\r
+ * must be implemented to never return (i.e. continuous loop).\r
+ *\r
+ * @param pcName A descriptive name for the task. This is mainly used to\r
+ * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default\r
+ * is 16.\r
+ *\r
+ * @param usStackDepth The size of the task stack specified as the number of\r
+ * variables the stack can hold - not the number of bytes. For example, if\r
+ * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes\r
+ * will be allocated for stack storage.\r
+ *\r
+ * @param pvParameters Pointer that will be used as the parameter for the task\r
+ * being created.\r
+ *\r
+ * @param uxPriority The priority at which the task should run. Systems that\r
+ * include MPU support can optionally create tasks in a privileged (system)\r
+ * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For\r
+ * example, to create a privileged task at priority 2 the uxPriority parameter\r
+ * should be set to ( 2 | portPRIVILEGE_BIT ).\r
+ *\r
+ * @param pvCreatedTask Used to pass back a handle by which the created task\r
+ * can be referenced.\r
+ *\r
+ * @return pdPASS if the task was successfully created and added to a ready\r
+ * list, otherwise an error code defined in the file errors. h\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Task to be created.\r
+ void vTaskCode( void * pvParameters )\r
+ {\r
+ for( ;; )\r
+ {\r
+ // Task code goes here.\r
+ }\r
+ }\r
+\r
+ // Function that creates a task.\r
+ void vOtherFunction( void )\r
+ {\r
+ static unsigned char ucParameterToPass;\r
+ xTaskHandle xHandle;\r
+\r
+ // Create the task, storing the handle. Note that the passed parameter ucParameterToPass\r
+ // must exist for the lifetime of the task, so in this case is declared static. If it was just an\r
+ // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time\r
+ // the new task attempts to access it.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );\r
+\r
+ // Use the handle to delete the task.\r
+ vTaskDelete( xHandle );\r
+ }\r
+ </pre>\r
+ * \defgroup xTaskCreate xTaskCreate\r
+ * \ingroup Tasks\r
+ */\r
+#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )\r
+\r
+/**\r
+ * task. h\r
+ *<pre>\r
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );</pre>\r
+ *\r
+ * xTaskCreateRestricted() should only be used in systems that include an MPU\r
+ * implementation.\r
+ *\r
+ * Create a new task and add it to the list of tasks that are ready to run.\r
+ * The function parameters define the memory regions and associated access\r
+ * permissions allocated to the task.\r
+ *\r
+ * @param pxTaskDefinition Pointer to a structure that contains a member\r
+ * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API\r
+ * documentation) plus an optional stack buffer and the memory region\r
+ * definitions.\r
+ *\r
+ * @param pxCreatedTask Used to pass back a handle by which the created task\r
+ * can be referenced.\r
+ *\r
+ * @return pdPASS if the task was successfully created and added to a ready\r
+ * list, otherwise an error code defined in the file errors. h\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+// Create an xTaskParameters structure that defines the task to be created.\r
+static const xTaskParameters xCheckTaskParameters =\r
+{\r
+ vATask, // pvTaskCode - the function that implements the task.\r
+ "ATask", // pcName - just a text name for the task to assist debugging.\r
+ 100, // usStackDepth - the stack size DEFINED IN WORDS.\r
+ NULL, // pvParameters - passed into the task function as the function parameters.\r
+ ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.\r
+ cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.\r
+\r
+ // xRegions - Allocate up to three separate memory regions for access by\r
+ // the task, with appropriate access permissions. Different processors have\r
+ // different memory alignment requirements - refer to the FreeRTOS documentation\r
+ // for full information.\r
+ { \r
+ // Base address Length Parameters\r
+ { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },\r
+ { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },\r
+ { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }\r
+ }\r
+};\r
+\r
+int main( void )\r
+{\r
+xTaskHandle xHandle;\r
+\r
+ // Create a task from the const structure defined above. The task handle\r
+ // is requested (the second parameter is not NULL) but in this case just for\r
+ // demonstration purposes as its not actually used.\r
+ xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );\r
+\r
+ // Start the scheduler.\r
+ vTaskStartScheduler();\r
+\r
+ // Will only get here if there was insufficient memory to create the idle\r
+ // task.\r
+ for( ;; );\r
+}\r
+ </pre>\r
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
+ * \ingroup Tasks\r
+ */\r
+#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )\r
+\r
+/**\r
+ * task. h\r
+ *<pre>\r
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );</pre>\r
+ *\r
+ * Memory regions are assigned to a restricted task when the task is created by\r
+ * a call to xTaskCreateRestricted(). These regions can be redefined using\r
+ * vTaskAllocateMPURegions().\r
+ *\r
+ * @param xTask The handle of the task being updated.\r
+ *\r
+ * @param xRegions A pointer to an xMemoryRegion structure that contains the\r
+ * new memory region definitions.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+// Define an array of xMemoryRegion structures that configures an MPU region\r
+// allowing read/write access for 1024 bytes starting at the beginning of the\r
+// ucOneKByte array. The other two of the maximum 3 definable regions are\r
+// unused so set to zero.\r
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =\r
+{ \r
+ // Base address Length Parameters\r
+ { ucOneKByte, 1024, portMPU_REGION_READ_WRITE },\r
+ { 0, 0, 0 },\r
+ { 0, 0, 0 }\r
+};\r
+\r
+void vATask( void *pvParameters )\r
+{\r
+ // This task was created such that it has access to certain regions of\r
+ // memory as defined by the MPU configuration. At some point it is\r
+ // desired that these MPU regions are replaced with that defined in the\r
+ // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions()\r
+ // for this purpose. NULL is used as the task handle to indicate that this\r
+ // function should modify the MPU regions of the calling task.\r
+ vTaskAllocateMPURegions( NULL, xAltRegions );\r
+ \r
+ // Now the task can continue its function, but from this point on can only\r
+ // access its stack and the ucOneKByte array (unless any other statically\r
+ // defined or shared regions have been declared elsewhere).\r
+}\r
+ </pre>\r
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
+ * \ingroup Tasks\r
+ */\r
+void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskDelete( xTaskHandle pxTask );</pre>\r
+ *\r
+ * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Remove a task from the RTOS real time kernels management. The task being\r
+ * deleted will be removed from all ready, blocked, suspended and event lists.\r
+ *\r
+ * NOTE: The idle task is responsible for freeing the kernel allocated\r
+ * memory from tasks that have been deleted. It is therefore important that\r
+ * the idle task is not starved of microcontroller processing time if your\r
+ * application makes any calls to vTaskDelete (). Memory allocated by the\r
+ * task code is not automatically freed, and should be freed before the task\r
+ * is deleted.\r
+ *\r
+ * See the demo application file death.c for sample code that utilises\r
+ * vTaskDelete ().\r
+ *\r
+ * @param pxTask The handle of the task to be deleted. Passing NULL will\r
+ * cause the calling task to be deleted.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vOtherFunction( void )\r
+ {\r
+ xTaskHandle xHandle;\r
+\r
+ // Create the task, storing the handle.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+\r
+ // Use the handle to delete the task.\r
+ vTaskDelete( xHandle );\r
+ }\r
+ </pre>\r
+ * \defgroup vTaskDelete vTaskDelete\r
+ * \ingroup Tasks\r
+ */\r
+void vTaskDelete( xTaskHandle pxTaskToDelete ) PRIVILEGED_FUNCTION;\r
+\r
+/*-----------------------------------------------------------\r
+ * TASK CONTROL API\r
+ *----------------------------------------------------------*/\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskDelay( portTickType xTicksToDelay );</pre>\r
+ *\r
+ * Delay a task for a given number of ticks. The actual time that the\r
+ * task remains blocked depends on the tick rate. The constant\r
+ * portTICK_RATE_MS can be used to calculate real time from the tick\r
+ * rate - with the resolution of one tick period.\r
+ *\r
+ * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ *\r
+ * vTaskDelay() specifies a time at which the task wishes to unblock relative to\r
+ * the time at which vTaskDelay() is called. For example, specifying a block\r
+ * period of 100 ticks will cause the task to unblock 100 ticks after\r
+ * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method\r
+ * of controlling the frequency of a cyclical task as the path taken through the\r
+ * code, as well as other task and interrupt activity, will effect the frequency\r
+ * at which vTaskDelay() gets called and therefore the time at which the task\r
+ * next executes. See vTaskDelayUntil() for an alternative API function designed\r
+ * to facilitate fixed frequency execution. It does this by specifying an\r
+ * absolute time (rather than a relative time) at which the calling task should\r
+ * unblock.\r
+ *\r
+ * @param xTicksToDelay The amount of time, in tick periods, that\r
+ * the calling task should block.\r
+ *\r
+ * Example usage:\r
+\r
+ void vTaskFunction( void * pvParameters )\r
+ {\r
+ void vTaskFunction( void * pvParameters )\r
+ {\r
+ // Block for 500ms.\r
+ const portTickType xDelay = 500 / portTICK_RATE_MS;\r
+\r
+ for( ;; )\r
+ {\r
+ // Simply toggle the LED every 500ms, blocking between each toggle.\r
+ vToggleLED();\r
+ vTaskDelay( xDelay );\r
+ }\r
+ }\r
+\r
+ * \defgroup vTaskDelay vTaskDelay\r
+ * \ingroup TaskCtrl\r
+ */\r
+void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );</pre>\r
+ *\r
+ * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Delay a task until a specified time. This function can be used by cyclical\r
+ * tasks to ensure a constant execution frequency.\r
+ *\r
+ * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will\r
+ * cause a task to block for the specified number of ticks from the time vTaskDelay () is\r
+ * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed\r
+ * execution frequency as the time between a task starting to execute and that task\r
+ * calling vTaskDelay () may not be fixed [the task may take a different path though the\r
+ * code between calls, or may get interrupted or preempted a different number of times\r
+ * each time it executes].\r
+ *\r
+ * Whereas vTaskDelay () specifies a wake time relative to the time at which the function\r
+ * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to\r
+ * unblock.\r
+ *\r
+ * The constant portTICK_RATE_MS can be used to calculate real time from the tick\r
+ * rate - with the resolution of one tick period.\r
+ *\r
+ * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the\r
+ * task was last unblocked. The variable must be initialised with the current time\r
+ * prior to its first use (see the example below). Following this the variable is\r
+ * automatically updated within vTaskDelayUntil ().\r
+ *\r
+ * @param xTimeIncrement The cycle time period. The task will be unblocked at\r
+ * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the\r
+ * same xTimeIncrement parameter value will cause the task to execute with\r
+ * a fixed interface period.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ // Perform an action every 10 ticks.\r
+ void vTaskFunction( void * pvParameters )\r
+ {\r
+ portTickType xLastWakeTime;\r
+ const portTickType xFrequency = 10;\r
+\r
+ // Initialise the xLastWakeTime variable with the current time.\r
+ xLastWakeTime = xTaskGetTickCount ();\r
+ for( ;; )\r
+ {\r
+ // Wait for the next cycle.\r
+ vTaskDelayUntil( &xLastWakeTime, xFrequency );\r
+\r
+ // Perform action here.\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup vTaskDelayUntil vTaskDelayUntil\r
+ * \ingroup TaskCtrl\r
+ */\r
+void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );</pre>\r
+ *\r
+ * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Obtain the priority of any task.\r
+ *\r
+ * @param pxTask Handle of the task to be queried. Passing a NULL\r
+ * handle results in the priority of the calling task being returned.\r
+ *\r
+ * @return The priority of pxTask.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vAFunction( void )\r
+ {\r
+ xTaskHandle xHandle;\r
+\r
+ // Create a task, storing the handle.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+\r
+ // ...\r
+\r
+ // Use the handle to obtain the priority of the created task.\r
+ // It was created with tskIDLE_PRIORITY, but may have changed\r
+ // it itself.\r
+ if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )\r
+ {\r
+ // The task has changed it's priority.\r
+ }\r
+\r
+ // ...\r
+\r
+ // Is our priority higher than the created task?\r
+ if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )\r
+ {\r
+ // Our priority (obtained using NULL handle) is higher.\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet\r
+ * \ingroup TaskCtrl\r
+ */\r
+unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>\r
+ *\r
+ * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Set the priority of any task.\r
+ *\r
+ * A context switch will occur before the function returns if the priority\r
+ * being set is higher than the currently executing task.\r
+ *\r
+ * @param pxTask Handle to the task for which the priority is being set.\r
+ * Passing a NULL handle results in the priority of the calling task being set.\r
+ *\r
+ * @param uxNewPriority The priority to which the task will be set.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vAFunction( void )\r
+ {\r
+ xTaskHandle xHandle;\r
+\r
+ // Create a task, storing the handle.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+\r
+ // ...\r
+\r
+ // Use the handle to raise the priority of the created task.\r
+ vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );\r
+\r
+ // ...\r
+\r
+ // Use a NULL handle to raise our priority to the same value.\r
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );\r
+ }\r
+ </pre>\r
+ * \defgroup vTaskPrioritySet vTaskPrioritySet\r
+ * \ingroup TaskCtrl\r
+ */\r
+void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskSuspend( xTaskHandle pxTaskToSuspend );</pre>\r
+ *\r
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Suspend any task. When suspended a task will never get any microcontroller\r
+ * processing time, no matter what its priority.\r
+ *\r
+ * Calls to vTaskSuspend are not accumulative -\r
+ * i.e. calling vTaskSuspend () twice on the same task still only requires one\r
+ * call to vTaskResume () to ready the suspended task.\r
+ *\r
+ * @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL\r
+ * handle will cause the calling task to be suspended.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vAFunction( void )\r
+ {\r
+ xTaskHandle xHandle;\r
+\r
+ // Create a task, storing the handle.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+\r
+ // ...\r
+\r
+ // Use the handle to suspend the created task.\r
+ vTaskSuspend( xHandle );\r
+\r
+ // ...\r
+\r
+ // The created task will not run during this period, unless\r
+ // another task calls vTaskResume( xHandle ).\r
+\r
+ //...\r
+\r
+\r
+ // Suspend ourselves.\r
+ vTaskSuspend( NULL );\r
+\r
+ // We cannot get here unless another task calls vTaskResume\r
+ // with our handle as the parameter.\r
+ }\r
+ </pre>\r
+ * \defgroup vTaskSuspend vTaskSuspend\r
+ * \ingroup TaskCtrl\r
+ */\r
+void vTaskSuspend( xTaskHandle pxTaskToSuspend ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskResume( xTaskHandle pxTaskToResume );</pre>\r
+ *\r
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Resumes a suspended task.\r
+ *\r
+ * A task that has been suspended by one of more calls to vTaskSuspend ()\r
+ * will be made available for running again by a single call to\r
+ * vTaskResume ().\r
+ *\r
+ * @param pxTaskToResume Handle to the task being readied.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vAFunction( void )\r
+ {\r
+ xTaskHandle xHandle;\r
+\r
+ // Create a task, storing the handle.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
+\r
+ // ...\r
+\r
+ // Use the handle to suspend the created task.\r
+ vTaskSuspend( xHandle );\r
+\r
+ // ...\r
+\r
+ // The created task will not run during this period, unless\r
+ // another task calls vTaskResume( xHandle ).\r
+\r
+ //...\r
+\r
+\r
+ // Resume the suspended task ourselves.\r
+ vTaskResume( xHandle );\r
+\r
+ // The created task will once again get microcontroller processing\r
+ // time in accordance with it priority within the system.\r
+ }\r
+ </pre>\r
+ * \defgroup vTaskResume vTaskResume\r
+ * \ingroup TaskCtrl\r
+ */\r
+void vTaskResume( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void xTaskResumeFromISR( xTaskHandle pxTaskToResume );</pre>\r
+ *\r
+ * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be\r
+ * available. See the configuration section for more information.\r
+ *\r
+ * An implementation of vTaskResume() that can be called from within an ISR.\r
+ *\r
+ * A task that has been suspended by one of more calls to vTaskSuspend ()\r
+ * will be made available for running again by a single call to\r
+ * xTaskResumeFromISR ().\r
+ *\r
+ * @param pxTaskToResume Handle to the task being readied.\r
+ *\r
+ * \defgroup vTaskResumeFromISR vTaskResumeFromISR\r
+ * \ingroup TaskCtrl\r
+ */\r
+portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume ) PRIVILEGED_FUNCTION;\r
+\r
+/*-----------------------------------------------------------\r
+ * SCHEDULER CONTROL\r
+ *----------------------------------------------------------*/\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskStartScheduler( void );</pre>\r
+ *\r
+ * Starts the real time kernel tick processing. After calling the kernel\r
+ * has control over which tasks are executed and when. This function\r
+ * does not return until an executing task calls vTaskEndScheduler ().\r
+ *\r
+ * At least one task should be created via a call to xTaskCreate ()\r
+ * before calling vTaskStartScheduler (). The idle task is created\r
+ * automatically when the first application task is created.\r
+ *\r
+ * See the demo application file main.c for an example of creating\r
+ * tasks and starting the kernel.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vAFunction( void )\r
+ {\r
+ // Create at least one task before starting the kernel.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+\r
+ // Start the real time kernel with preemption.\r
+ vTaskStartScheduler ();\r
+\r
+ // Will not get here unless a task calls vTaskEndScheduler ()\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup vTaskStartScheduler vTaskStartScheduler\r
+ * \ingroup SchedulerControl\r
+ */\r
+void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskEndScheduler( void );</pre>\r
+ *\r
+ * Stops the real time kernel tick. All created tasks will be automatically\r
+ * deleted and multitasking (either preemptive or cooperative) will\r
+ * stop. Execution then resumes from the point where vTaskStartScheduler ()\r
+ * was called, as if vTaskStartScheduler () had just returned.\r
+ *\r
+ * See the demo application file main. c in the demo/PC directory for an\r
+ * example that uses vTaskEndScheduler ().\r
+ *\r
+ * vTaskEndScheduler () requires an exit function to be defined within the\r
+ * portable layer (see vPortEndScheduler () in port. c for the PC port). This\r
+ * performs hardware specific operations such as stopping the kernel tick.\r
+ *\r
+ * vTaskEndScheduler () will cause all of the resources allocated by the\r
+ * kernel to be freed - but will not free resources allocated by application\r
+ * tasks.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vTaskCode( void * pvParameters )\r
+ {\r
+ for( ;; )\r
+ {\r
+ // Task code goes here.\r
+\r
+ // At some point we want to end the real time kernel processing\r
+ // so call ...\r
+ vTaskEndScheduler ();\r
+ }\r
+ }\r
+\r
+ void vAFunction( void )\r
+ {\r
+ // Create at least one task before starting the kernel.\r
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+\r
+ // Start the real time kernel with preemption.\r
+ vTaskStartScheduler ();\r
+\r
+ // Will only get here when the vTaskCode () task has called\r
+ // vTaskEndScheduler (). When we get here we are back to single task\r
+ // execution.\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup vTaskEndScheduler vTaskEndScheduler\r
+ * \ingroup SchedulerControl\r
+ */\r
+void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>void vTaskSuspendAll( void );</pre>\r
+ *\r
+ * Suspends all real time kernel activity while keeping interrupts (including the\r
+ * kernel tick) enabled.\r
+ *\r
+ * After calling vTaskSuspendAll () the calling task will continue to execute\r
+ * without risk of being swapped out until a call to xTaskResumeAll () has been\r
+ * made.\r
+ *\r
+ * API functions that have the potential to cause a context switch (for example,\r
+ * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler\r
+ * is suspended.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vTask1( void * pvParameters )\r
+ {\r
+ for( ;; )\r
+ {\r
+ // Task code goes here.\r
+\r
+ // ...\r
+\r
+ // At some point the task wants to perform a long operation during\r
+ // which it does not want to get swapped out. It cannot use\r
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
+ // operation may cause interrupts to be missed - including the\r
+ // ticks.\r
+\r
+ // Prevent the real time kernel swapping out the task.\r
+ vTaskSuspendAll ();\r
+\r
+ // Perform the operation here. There is no need to use critical\r
+ // sections as we have all the microcontroller processing time.\r
+ // During this time interrupts will still operate and the kernel\r
+ // tick count will be maintained.\r
+\r
+ // ...\r
+\r
+ // The operation is complete. Restart the kernel.\r
+ xTaskResumeAll ();\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup vTaskSuspendAll vTaskSuspendAll\r
+ * \ingroup SchedulerControl\r
+ */\r
+void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>char xTaskResumeAll( void );</pre>\r
+ *\r
+ * Resumes real time kernel activity following a call to vTaskSuspendAll ().\r
+ * After a call to vTaskSuspendAll () the kernel will take control of which\r
+ * task is executing at any time.\r
+ *\r
+ * @return If resuming the scheduler caused a context switch then pdTRUE is\r
+ * returned, otherwise pdFALSE is returned.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ void vTask1( void * pvParameters )\r
+ {\r
+ for( ;; )\r
+ {\r
+ // Task code goes here.\r
+\r
+ // ...\r
+\r
+ // At some point the task wants to perform a long operation during\r
+ // which it does not want to get swapped out. It cannot use\r
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
+ // operation may cause interrupts to be missed - including the\r
+ // ticks.\r
+\r
+ // Prevent the real time kernel swapping out the task.\r
+ vTaskSuspendAll ();\r
+\r
+ // Perform the operation here. There is no need to use critical\r
+ // sections as we have all the microcontroller processing time.\r
+ // During this time interrupts will still operate and the real\r
+ // time kernel tick count will be maintained.\r
+\r
+ // ...\r
+\r
+ // The operation is complete. Restart the kernel. We want to force\r
+ // a context switch - but there is no point if resuming the scheduler\r
+ // caused a context switch already.\r
+ if( !xTaskResumeAll () )\r
+ {\r
+ taskYIELD ();\r
+ }\r
+ }\r
+ }\r
+ </pre>\r
+ * \defgroup xTaskResumeAll xTaskResumeAll\r
+ * \ingroup SchedulerControl\r
+ */\r
+signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <pre>signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask );</pre>\r
+ *\r
+ * Utility task that simply returns pdTRUE if the task referenced by xTask is\r
+ * currently in the Suspended state, or pdFALSE if the task referenced by xTask\r
+ * is in any other state.\r
+ *\r
+ */\r
+signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
+\r
+/*-----------------------------------------------------------\r
+ * TASK UTILITIES\r
+ *----------------------------------------------------------*/\r
+\r
+/**\r
+ * task. h\r
+ * <PRE>portTickType xTaskGetTickCount( void );</PRE>\r
+ *\r
+ * @return The count of ticks since vTaskStartScheduler was called.\r
+ *\r
+ * \page xTaskGetTickCount xTaskGetTickCount\r
+ * \ingroup TaskUtils\r
+ */\r
+portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <PRE>portTickType xTaskGetTickCountFromISR( void );</PRE>\r
+ *\r
+ * @return The count of ticks since vTaskStartScheduler was called.\r
+ *\r
+ * This is a version of xTaskGetTickCount() that is safe to be called from an\r
+ * ISR - provided that portTickType is the natural word size of the\r
+ * microcontroller being used or interrupt nesting is either not supported or\r
+ * not being used.\r
+ *\r
+ * \page xTaskGetTickCount xTaskGetTickCount\r
+ * \ingroup TaskUtils\r
+ */\r
+portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <PRE>unsigned short uxTaskGetNumberOfTasks( void );</PRE>\r
+ *\r
+ * @return The number of tasks that the real time kernel is currently managing.\r
+ * This includes all ready, blocked and suspended tasks. A task that\r
+ * has been deleted but not yet freed by the idle task will also be\r
+ * included in the count.\r
+ *\r
+ * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks\r
+ * \ingroup TaskUtils\r
+ */\r
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <PRE>signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );</PRE>\r
+ *\r
+ * @return The text (human readable) name of the task referenced by the handle\r
+ * xTaskToQueury. A task can query its own name by either passing in its own\r
+ * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be\r
+ * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available.\r
+ *\r
+ * \page pcTaskGetTaskName pcTaskGetTaskName\r
+ * \ingroup TaskUtils\r
+ */\r
+signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );\r
+\r
+/**\r
+ * task. h\r
+ * <PRE>void vTaskList( char *pcWriteBuffer );</PRE>\r
+ *\r
+ * configUSE_TRACE_FACILITY must be defined as 1 for this function to be\r
+ * available. See the configuration section for more information.\r
+ *\r
+ * NOTE: This function will disable interrupts for its duration. It is\r
+ * not intended for normal application runtime use but as a debug aid.\r
+ *\r
+ * Lists all the current tasks, along with their current state and stack\r
+ * usage high water mark.\r
+ *\r
+ * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or\r
+ * suspended ('S').\r
+ *\r
+ * @param pcWriteBuffer A buffer into which the above mentioned details\r
+ * will be written, in ascii form. This buffer is assumed to be large\r
+ * enough to contain the generated report. Approximately 40 bytes per\r
+ * task should be sufficient.\r
+ *\r
+ * \page vTaskList vTaskList\r
+ * \ingroup TaskUtils\r
+ */\r
+void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task. h\r
+ * <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>\r
+ *\r
+ * configGENERATE_RUN_TIME_STATS must be defined as 1 for this function\r
+ * to be available. The application must also then provide definitions\r
+ * for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and\r
+ * portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter\r
+ * and return the timers current count value respectively. The counter\r
+ * should be at least 10 times the frequency of the tick count.\r
+ *\r
+ * NOTE: This function will disable interrupts for its duration. It is\r
+ * not intended for normal application runtime use but as a debug aid.\r
+ *\r
+ * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total\r
+ * accumulated execution time being stored for each task. The resolution\r
+ * of the accumulated time value depends on the frequency of the timer\r
+ * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.\r
+ * Calling vTaskGetRunTimeStats() writes the total execution time of each\r
+ * task into a buffer, both as an absolute count value and as a percentage\r
+ * of the total system execution time.\r
+ *\r
+ * @param pcWriteBuffer A buffer into which the execution times will be\r
+ * written, in ascii form. This buffer is assumed to be large enough to\r
+ * contain the generated report. Approximately 40 bytes per task should\r
+ * be sufficient.\r
+ *\r
+ * \page vTaskGetRunTimeStats vTaskGetRunTimeStats\r
+ * \ingroup TaskUtils\r
+ */\r
+void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * task.h\r
+ * <PRE>unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );</PRE>\r
+ *\r
+ * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for\r
+ * this function to be available.\r
+ *\r
+ * Returns the high water mark of the stack associated with xTask. That is,\r
+ * the minimum free stack space there has been (in words, so on a 32 bit machine\r
+ * a value of 1 means 4 bytes) since the task started. The smaller the returned\r
+ * number the closer the task has come to overflowing its stack.\r
+ *\r
+ * @param xTask Handle of the task associated with the stack to be checked.\r
+ * Set xTask to NULL to check the stack of the calling task.\r
+ *\r
+ * @return The smallest amount of free stack space there has been (in bytes)\r
+ * since the task referenced by xTask was created.\r
+ */\r
+unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
+\r
+/* When using trace macros it is sometimes necessary to include tasks.h before\r
+FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined,\r
+so the following two prototypes will cause a compilation error. This can be\r
+fixed by simply guarding against the inclusion of these two prototypes unless\r
+they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration\r
+constant. */\r
+#ifdef configUSE_APPLICATION_TASK_TAG\r
+ #if configUSE_APPLICATION_TASK_TAG == 1\r
+ /**\r
+ * task.h\r
+ * <pre>void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>\r
+ *\r
+ * Sets pxHookFunction to be the task hook function used by the task xTask.\r
+ * Passing xTask as NULL has the effect of setting the calling tasks hook\r
+ * function.\r
+ */\r
+ void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION;\r
+\r
+ /**\r
+ * task.h\r
+ * <pre>void xTaskGetApplicationTaskTag( xTaskHandle xTask );</pre>\r
+ *\r
+ * Returns the pxHookFunction value assigned to the task xTask.\r
+ */\r
+ pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION;\r
+ #endif /* configUSE_APPLICATION_TASK_TAG ==1 */\r
+#endif /* ifdef configUSE_APPLICATION_TASK_TAG */\r
+\r
+/**\r
+ * task.h\r
+ * <pre>portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );</pre>\r
+ *\r
+ * Calls the hook function associated with xTask. Passing xTask as NULL has\r
+ * the effect of calling the Running tasks (the calling task) hook function.\r
+ *\r
+ * pvParameter is passed to the hook function for the task to interpret as it\r
+ * wants.\r
+ */\r
+portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * xTaskGetIdleTaskHandle() is only available if \r
+ * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.\r
+ *\r
+ * Simply returns the handle of the idle task. It is not valid to call\r
+ * xTaskGetIdleTaskHandle() before the scheduler has been started.\r
+ */\r
+xTaskHandle xTaskGetIdleTaskHandle( void );\r
+\r
+/*-----------------------------------------------------------\r
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
+ *----------------------------------------------------------*/\r
+\r
+/*\r
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY\r
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS\r
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
+ *\r
+ * Called from the real time kernel tick (either preemptive or cooperative),\r
+ * this increments the tick count and checks if any tasks that are blocked\r
+ * for a finite period required removing from a blocked list and placing on\r
+ * a ready list.\r
+ */\r
+void vTaskIncrementTick( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
+ *\r
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
+ *\r
+ * Removes the calling task from the ready list and places it both\r
+ * on the list of tasks waiting for a particular event, and the\r
+ * list of delayed tasks. The task will be removed from both lists\r
+ * and replaced on the ready list should either the event occur (and\r
+ * there be no higher priority tasks waiting on the same event) or\r
+ * the delay period expires.\r
+ *\r
+ * @param pxEventList The list containing tasks that are blocked waiting\r
+ * for the event to occur.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time that the task should wait\r
+ * for the event to occur. This is specified in kernel ticks,the constant\r
+ * portTICK_RATE_MS can be used to convert kernel ticks into a real time\r
+ * period.\r
+ */\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
+ *\r
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
+ *\r
+ * This function performs nearly the same function as vTaskPlaceOnEventList().\r
+ * The difference being that this function does not permit tasks to block\r
+ * indefinitely, whereas vTaskPlaceOnEventList() does.\r
+ *\r
+ * @return pdTRUE if the task being removed has a higher priority than the task\r
+ * making the call, otherwise pdFALSE.\r
+ */\r
+void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
+ *\r
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
+ *\r
+ * Removes a task from both the specified event list and the list of blocked\r
+ * tasks, and places it on a ready queue.\r
+ *\r
+ * xTaskRemoveFromEventList () will be called if either an event occurs to\r
+ * unblock a task, or the block timeout period expires.\r
+ *\r
+ * @return pdTRUE if the task being removed has a higher priority than the task\r
+ * making the call, otherwise pdFALSE.\r
+ */\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY\r
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS\r
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
+ *\r
+ * Sets the pointer to the current TCB to the TCB of the highest priority task\r
+ * that is ready to run.\r
+ */\r
+void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Return the handle of the calling task.\r
+ */\r
+xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Capture the current time status for future reference.\r
+ */\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Compare the time status now with that previously captured to see if the\r
+ * timeout has expired.\r
+ */\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Shortcut used by the queue implementation to prevent unnecessary call to\r
+ * taskYIELD();\r
+ */\r
+void vTaskMissedYield( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Returns the scheduler state as taskSCHEDULER_RUNNING,\r
+ * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.\r
+ */\r
+portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Raises the priority of the mutex holder to that of the calling task should\r
+ * the mutex holder have a priority less than the calling task.\r
+ */\r
+void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Set the priority of a task back to its proper priority in the case that it\r
+ * inherited a higher priority while it was holding a semaphore.\r
+ */\r
+void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Generic version of the task creation function which is in turn called by the\r
+ * xTaskCreate() and xTaskCreateRestricted() macros.\r
+ */\r
+signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Get the uxTCBNumber assigned to the task referenced by the xTask parameter.\r
+ */\r
+unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );\r
+\r
+/* \r
+ * Set the uxTCBNumber of the task referenced by the xTask parameter to\r
+ * ucHandle.\r
+ */\r
+void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle );\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* TASK_H */\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
+all the API functions to use the MPU wrappers. That should only be done when\r
+task.h is included from an application file. */\r
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "timers.h"\r
+#include "StackMacros.h"\r
+\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+/*\r
+ * Macro to define the amount of stack available to the idle task.\r
+ */\r
+#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE\r
+\r
+/*\r
+ * Task control block. A task control block (TCB) is allocated to each task,\r
+ * and stores the context of the task.\r
+ */\r
+typedef struct tskTaskControlBlock\r
+{\r
+ volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
+\r
+ #if ( portUSING_MPU_WRAPPERS == 1 )\r
+ xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
+ #endif \r
+ \r
+ xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
+ xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
+ portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
+ signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
+\r
+ #if ( portSTACK_GROWTH > 0 )\r
+ portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
+ #endif\r
+\r
+ #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+ unsigned portBASE_TYPE uxCriticalNesting;\r
+ #endif\r
+\r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ unsigned portBASE_TYPE uxTCBNumber; /*< This stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */\r
+ unsigned portBASE_TYPE uxTaskNumber; /*< This stores a number specifically for use by third party trace code. */\r
+ #endif\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
+ #endif\r
+\r
+ #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+ pdTASK_HOOK_CODE pxTaskTag;\r
+ #endif\r
+\r
+ #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+ unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
+ #endif\r
+\r
+} tskTCB;\r
+\r
+\r
+/*\r
+ * Some kernel aware debuggers require data to be viewed to be global, rather\r
+ * than file scope.\r
+ */\r
+#ifdef portREMOVE_STATIC_QUALIFIER\r
+ #define static\r
+#endif\r
+\r
+/*lint -e956 */\r
+PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;\r
+\r
+/* Lists for ready and blocked tasks. --------------------*/\r
+\r
+PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */\r
+PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */\r
+PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */\r
+PRIVILEGED_DATA static xList * volatile pxDelayedTaskList ; /*< Points to the delayed task list currently being used. */\r
+PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */\r
+PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */\r
+\r
+#if ( INCLUDE_vTaskDelete == 1 )\r
+\r
+ PRIVILEGED_DATA static xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */\r
+ PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0U;\r
+\r
+#endif\r
+\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+ PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */\r
+\r
+#endif\r
+\r
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
+ \r
+ PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL;\r
+ \r
+#endif\r
+\r
+/* File private variables. --------------------------------*/\r
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U;\r
+PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U;\r
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;\r
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;\r
+PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;\r
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE;\r
+PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxMissedTicks = ( unsigned portBASE_TYPE ) 0U;\r
+PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;\r
+PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;\r
+PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U;\r
+PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;\r
+\r
+#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+\r
+ PRIVILEGED_DATA static char pcStatsString[ 50 ] ;\r
+ PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */\r
+ static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/* Debugging and trace facilities private variables and macros. ------------*/\r
+\r
+/*\r
+ * The value used to fill the stack of a task when the task is created. This\r
+ * is used purely for checking the high water mark for tasks.\r
+ */\r
+#define tskSTACK_FILL_BYTE ( 0xa5U )\r
+\r
+/*\r
+ * Macros used by vListTask to indicate which state a task is in.\r
+ */\r
+#define tskBLOCKED_CHAR ( ( signed char ) 'B' )\r
+#define tskREADY_CHAR ( ( signed char ) 'R' )\r
+#define tskDELETED_CHAR ( ( signed char ) 'D' )\r
+#define tskSUSPENDED_CHAR ( ( signed char ) 'S' )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Place the task represented by pxTCB into the appropriate ready queue for\r
+ * the task. It is inserted at the end of the list. One quirk of this is\r
+ * that if the task being inserted is at the same priority as the currently\r
+ * executing task, then it will only be rescheduled after the currently\r
+ * executing task has been rescheduled.\r
+ */\r
+#define prvAddTaskToReadyQueue( pxTCB ) \\r
+ traceMOVED_TASK_TO_READY_STATE( pxTCB ) \\r
+ if( ( pxTCB )->uxPriority > uxTopReadyPriority ) \\r
+ { \\r
+ uxTopReadyPriority = ( pxTCB )->uxPriority; \\r
+ } \\r
+ vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Macro that looks at the list of tasks that are currently delayed to see if\r
+ * any require waking.\r
+ *\r
+ * Tasks are stored in the queue in the order of their wake time - meaning\r
+ * once one tasks has been found whose timer has not expired we need not look\r
+ * any further down the list.\r
+ */\r
+#define prvCheckDelayedTasks() \\r
+{ \\r
+portTickType xItemValue; \\r
+ \\r
+ /* Is the tick count greater than or equal to the wake time of the first \\r
+ task referenced from the delayed tasks list? */ \\r
+ if( xTickCount >= xNextTaskUnblockTime ) \\r
+ { \\r
+ for( ;; ) \\r
+ { \\r
+ if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \\r
+ { \\r
+ /* The delayed list is empty. Set xNextTaskUnblockTime to the \\r
+ maximum possible value so it is extremely unlikely that the \\r
+ if( xTickCount >= xNextTaskUnblockTime ) test will pass next \\r
+ time through. */ \\r
+ xNextTaskUnblockTime = portMAX_DELAY; \\r
+ break; \\r
+ } \\r
+ else \\r
+ { \\r
+ /* The delayed list is not empty, get the value of the item at \\r
+ the head of the delayed list. This is the time at which the \\r
+ task at the head of the delayed list should be removed from \\r
+ the Blocked state. */ \\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \\r
+ xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \\r
+ \\r
+ if( xTickCount < xItemValue ) \\r
+ { \\r
+ /* It is not time to unblock this item yet, but the item \\r
+ value is the time at which the task at the head of the \\r
+ blocked list should be removed from the Blocked state - \\r
+ so record the item value in xNextTaskUnblockTime. */ \\r
+ xNextTaskUnblockTime = xItemValue; \\r
+ break; \\r
+ } \\r
+ \\r
+ /* It is time to remove the item from the Blocked state. */ \\r
+ vListRemove( &( pxTCB->xGenericListItem ) ); \\r
+ \\r
+ /* Is the task waiting on an event also? */ \\r
+ if( pxTCB->xEventListItem.pvContainer != NULL ) \\r
+ { \\r
+ vListRemove( &( pxTCB->xEventListItem ) ); \\r
+ } \\r
+ prvAddTaskToReadyQueue( pxTCB ); \\r
+ } \\r
+ } \\r
+ } \\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Several functions take an xTaskHandle parameter that can optionally be NULL,\r
+ * where NULL is used to indicate that the handle of the currently executing\r
+ * task should be used in place of the parameter. This macro simply checks to\r
+ * see if the parameter is NULL and returns a pointer to the appropriate TCB.\r
+ */\r
+#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) )\r
+\r
+/* Callback function prototypes. --------------------------*/\r
+extern void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );\r
+extern void vApplicationTickHook( void );\r
+ \r
+/* File private functions. --------------------------------*/\r
+\r
+/*\r
+ * Utility to ready a TCB for a given task. Mainly just copies the parameters\r
+ * into the TCB structure.\r
+ */\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Utility to ready all the lists used by the scheduler. This is called\r
+ * automatically upon the creation of the first task.\r
+ */\r
+static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * The idle task, which as all tasks is implemented as a never ending loop.\r
+ * The idle task is automatically created and added to the ready lists upon\r
+ * creation of the first user task.\r
+ *\r
+ * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific\r
+ * language extensions. The equivalent prototype for this function is:\r
+ *\r
+ * void prvIdleTask( void *pvParameters );\r
+ *\r
+ */\r
+static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );\r
+\r
+/*\r
+ * Utility to free all memory allocated by the scheduler to hold a TCB,\r
+ * including the stack pointed to by the TCB.\r
+ *\r
+ * This does not free memory allocated by the task itself (i.e. memory\r
+ * allocated by calls to pvPortMalloc from within the tasks application code).\r
+ */\r
+#if ( INCLUDE_vTaskDelete == 1 )\r
+\r
+ static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*\r
+ * Used only by the idle task. This checks to see if anything has been placed\r
+ * in the list of tasks waiting to be deleted. If so the task is cleaned up\r
+ * and its TCB deleted.\r
+ */\r
+static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * The currently executing task is entering the Blocked state. Add the task to\r
+ * either the current or the overflow delayed task list.\r
+ */\r
+static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Allocates memory from the heap for a TCB and associated stack. Checks the\r
+ * allocation was successful.\r
+ */\r
+static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Called from vTaskList. vListTasks details all the tasks currently under\r
+ * control of the scheduler. The tasks may be in one of a number of lists.\r
+ * prvListTaskWithinSingleList accepts a list and details the tasks from\r
+ * within just that list.\r
+ *\r
+ * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM\r
+ * NORMAL APPLICATION CODE.\r
+ */\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*\r
+ * When a task is created, the stack of the task is filled with a known value.\r
+ * This function determines the 'high water mark' of the task stack by\r
+ * determining how much of the stack remains at the original preset value.\r
+ */\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+\r
+ static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+\r
+/*lint +e956 */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * TASK CREATION API documented in task.h\r
+ *----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )\r
+{\r
+signed portBASE_TYPE xReturn;\r
+tskTCB * pxNewTCB;\r
+\r
+ configASSERT( pxTaskCode );\r
+ configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) );\r
+\r
+ /* Allocate the memory required by the TCB and stack for the new task,\r
+ checking that the allocation was successful. */\r
+ pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );\r
+\r
+ if( pxNewTCB != NULL )\r
+ {\r
+ portSTACK_TYPE *pxTopOfStack;\r
+\r
+ #if( portUSING_MPU_WRAPPERS == 1 )\r
+ /* Should the task be created in privileged mode? */\r
+ portBASE_TYPE xRunPrivileged;\r
+ if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )\r
+ {\r
+ xRunPrivileged = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ xRunPrivileged = pdFALSE;\r
+ }\r
+ uxPriority &= ~portPRIVILEGE_BIT;\r
+ #endif /* portUSING_MPU_WRAPPERS == 1 */\r
+\r
+ /* Calculate the top of stack address. This depends on whether the\r
+ stack grows from high memory to low (as per the 80x86) or visa versa.\r
+ portSTACK_GROWTH is used to make the result positive or negative as\r
+ required by the port. */\r
+ #if( portSTACK_GROWTH < 0 )\r
+ {\r
+ pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 );\r
+ pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );\r
+\r
+ /* Check the alignment of the calculated top of stack is correct. */\r
+ configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
+ }\r
+ #else\r
+ {\r
+ pxTopOfStack = pxNewTCB->pxStack;\r
+ \r
+ /* Check the alignment of the stack buffer is correct. */\r
+ configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
+\r
+ /* If we want to use stack checking on architectures that use\r
+ a positive stack growth direction then we also need to store the\r
+ other extreme of the stack space. */\r
+ pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
+ }\r
+ #endif\r
+\r
+ /* Setup the newly allocated TCB with the initial state of the task. */\r
+ prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );\r
+\r
+ /* Initialize the TCB stack to look as if the task was already running,\r
+ but had been interrupted by the scheduler. The return address is set\r
+ to the start of the task function. Once the stack has been initialised\r
+ the top of stack variable is updated. */\r
+ #if( portUSING_MPU_WRAPPERS == 1 )\r
+ {\r
+ pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );\r
+ }\r
+ #else\r
+ {\r
+ pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );\r
+ }\r
+ #endif\r
+\r
+ /* Check the alignment of the initialised stack. */\r
+ portALIGNMENT_ASSERT_pxCurrentTCB( ( ( ( unsigned long ) pxNewTCB->pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
+\r
+ if( ( void * ) pxCreatedTask != NULL )\r
+ {\r
+ /* Pass the TCB out - in an anonymous way. The calling function/\r
+ task can use this as a handle to delete the task later if\r
+ required.*/\r
+ *pxCreatedTask = ( xTaskHandle ) pxNewTCB;\r
+ }\r
+ \r
+ /* We are going to manipulate the task queues to add this task to a\r
+ ready list, so must make sure no interrupts occur. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ uxCurrentNumberOfTasks++;\r
+ if( pxCurrentTCB == NULL )\r
+ {\r
+ /* There are no other tasks, or all the other tasks are in\r
+ the suspended state - make this the current task. */\r
+ pxCurrentTCB = pxNewTCB;\r
+\r
+ if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )\r
+ {\r
+ /* This is the first task to be created so do the preliminary\r
+ initialisation required. We will not recover if this call\r
+ fails, but we will report the failure. */\r
+ prvInitialiseTaskLists();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* If the scheduler is not already running, make this task the\r
+ current task if it is the highest priority task to be created\r
+ so far. */\r
+ if( xSchedulerRunning == pdFALSE )\r
+ {\r
+ if( pxCurrentTCB->uxPriority <= uxPriority )\r
+ {\r
+ pxCurrentTCB = pxNewTCB;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Remember the top priority to make context switching faster. Use\r
+ the priority in pxNewTCB as this has been capped to a valid value. */\r
+ if( pxNewTCB->uxPriority > uxTopUsedPriority )\r
+ {\r
+ uxTopUsedPriority = pxNewTCB->uxPriority;\r
+ }\r
+\r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ {\r
+ /* Add a counter into the TCB for tracing only. */\r
+ pxNewTCB->uxTCBNumber = uxTaskNumber;\r
+ }\r
+ #endif\r
+ uxTaskNumber++;\r
+\r
+ prvAddTaskToReadyQueue( pxNewTCB );\r
+\r
+ xReturn = pdPASS;\r
+ portSETUP_TCB( pxNewTCB );\r
+ traceTASK_CREATE( pxNewTCB );\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ }\r
+ else\r
+ {\r
+ xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
+ traceTASK_CREATE_FAILED();\r
+ }\r
+\r
+ if( xReturn == pdPASS )\r
+ {\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ /* If the created task is of a higher priority than the current task\r
+ then it should run now. */\r
+ if( pxCurrentTCB->uxPriority < uxPriority )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskDelete == 1 )\r
+\r
+ void vTaskDelete( xTaskHandle pxTaskToDelete )\r
+ {\r
+ tskTCB *pxTCB;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Ensure a yield is performed if the current task is being\r
+ deleted. */\r
+ if( pxTaskToDelete == pxCurrentTCB )\r
+ {\r
+ pxTaskToDelete = NULL;\r
+ }\r
+\r
+ /* If null is passed in here then we are deleting ourselves. */\r
+ pxTCB = prvGetTCBFromHandle( pxTaskToDelete );\r
+\r
+ /* Remove task from the ready list and place in the termination list.\r
+ This will stop the task from be scheduled. The idle task will check\r
+ the termination list and free up any memory allocated by the\r
+ scheduler for the TCB and stack. */\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+ /* Is the task waiting on an event also? */\r
+ if( pxTCB->xEventListItem.pvContainer != NULL )\r
+ {\r
+ vListRemove( &( pxTCB->xEventListItem ) );\r
+ }\r
+\r
+ vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );\r
+\r
+ /* Increment the ucTasksDeleted variable so the idle task knows\r
+ there is a task that has been deleted and that it should therefore\r
+ check the xTasksWaitingTermination list. */\r
+ ++uxTasksDeleted;\r
+\r
+ /* Increment the uxTaskNumberVariable also so kernel aware debuggers\r
+ can detect that the task lists need re-generating. */\r
+ uxTaskNumber++;\r
+\r
+ traceTASK_DELETE( pxTCB );\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ /* Force a reschedule if we have just deleted the current task. */\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ if( ( void * ) pxTaskToDelete == NULL )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * TASK CONTROL API documented in task.h\r
+ *----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskDelayUntil == 1 )\r
+\r
+ void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )\r
+ {\r
+ portTickType xTimeToWake;\r
+ portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;\r
+\r
+ configASSERT( pxPreviousWakeTime );\r
+ configASSERT( ( xTimeIncrement > 0U ) );\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ /* Generate the tick time at which the task wants to wake. */\r
+ xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;\r
+\r
+ if( xTickCount < *pxPreviousWakeTime )\r
+ {\r
+ /* The tick count has overflowed since this function was\r
+ lasted called. In this case the only time we should ever\r
+ actually delay is if the wake time has also overflowed,\r
+ and the wake time is greater than the tick time. When this\r
+ is the case it is as if neither time had overflowed. */\r
+ if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xTickCount ) )\r
+ {\r
+ xShouldDelay = pdTRUE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The tick time has not overflowed. In this case we will\r
+ delay if either the wake time has overflowed, and/or the\r
+ tick time is less than the wake time. */\r
+ if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xTickCount ) )\r
+ {\r
+ xShouldDelay = pdTRUE;\r
+ }\r
+ }\r
+\r
+ /* Update the wake time ready for the next call. */\r
+ *pxPreviousWakeTime = xTimeToWake;\r
+\r
+ if( xShouldDelay != pdFALSE )\r
+ {\r
+ traceTASK_DELAY_UNTIL();\r
+\r
+ /* We must remove ourselves from the ready list before adding\r
+ ourselves to the blocked list as the same list item is used for\r
+ both lists. */\r
+ vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ }\r
+ xAlreadyYielded = xTaskResumeAll();\r
+\r
+ /* Force a reschedule if xTaskResumeAll has not already done so, we may\r
+ have put ourselves to sleep. */\r
+ if( xAlreadyYielded == pdFALSE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskDelay == 1 )\r
+\r
+ void vTaskDelay( portTickType xTicksToDelay )\r
+ {\r
+ portTickType xTimeToWake;\r
+ signed portBASE_TYPE xAlreadyYielded = pdFALSE;\r
+\r
+ /* A delay time of zero just forces a reschedule. */\r
+ if( xTicksToDelay > ( portTickType ) 0U )\r
+ {\r
+ vTaskSuspendAll();\r
+ {\r
+ traceTASK_DELAY();\r
+\r
+ /* A task that is removed from the event list while the\r
+ scheduler is suspended will not get placed in the ready\r
+ list or removed from the blocked list until the scheduler\r
+ is resumed.\r
+\r
+ This task cannot be in an event list as it is the currently\r
+ executing task. */\r
+\r
+ /* Calculate the time to wake - this may overflow but this is\r
+ not a problem. */\r
+ xTimeToWake = xTickCount + xTicksToDelay;\r
+\r
+ /* We must remove ourselves from the ready list before adding\r
+ ourselves to the blocked list as the same list item is used for\r
+ both lists. */\r
+ vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ xAlreadyYielded = xTaskResumeAll();\r
+ }\r
+\r
+ /* Force a reschedule if xTaskResumeAll has not already done so, we may\r
+ have put ourselves to sleep. */\r
+ if( xAlreadyYielded == pdFALSE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_uxTaskPriorityGet == 1 )\r
+\r
+ unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )\r
+ {\r
+ tskTCB *pxTCB;\r
+ unsigned portBASE_TYPE uxReturn;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* If null is passed in here then we are changing the\r
+ priority of the calling function. */\r
+ pxTCB = prvGetTCBFromHandle( pxTask );\r
+ uxReturn = pxTCB->uxPriority;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return uxReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskPrioritySet == 1 )\r
+\r
+ void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )\r
+ {\r
+ tskTCB *pxTCB;\r
+ unsigned portBASE_TYPE uxCurrentPriority;\r
+ portBASE_TYPE xYieldRequired = pdFALSE;\r
+\r
+ configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );\r
+\r
+ /* Ensure the new priority is valid. */\r
+ if( uxNewPriority >= configMAX_PRIORITIES )\r
+ {\r
+ uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;\r
+ }\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( pxTask == pxCurrentTCB )\r
+ {\r
+ pxTask = NULL;\r
+ }\r
+\r
+ /* If null is passed in here then we are changing the\r
+ priority of the calling function. */\r
+ pxTCB = prvGetTCBFromHandle( pxTask );\r
+\r
+ traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ uxCurrentPriority = pxTCB->uxBasePriority;\r
+ }\r
+ #else\r
+ {\r
+ uxCurrentPriority = pxTCB->uxPriority;\r
+ }\r
+ #endif\r
+\r
+ if( uxCurrentPriority != uxNewPriority )\r
+ {\r
+ /* The priority change may have readied a task of higher\r
+ priority than the calling task. */\r
+ if( uxNewPriority > uxCurrentPriority )\r
+ {\r
+ if( pxTask != NULL )\r
+ {\r
+ /* The priority of another task is being raised. If we\r
+ were raising the priority of the currently running task\r
+ there would be no need to switch as it must have already\r
+ been the highest priority task. */\r
+ xYieldRequired = pdTRUE;\r
+ }\r
+ }\r
+ else if( pxTask == NULL )\r
+ {\r
+ /* Setting our own priority down means there may now be another\r
+ task of higher priority that is ready to execute. */\r
+ xYieldRequired = pdTRUE;\r
+ }\r
+\r
+\r
+\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ /* Only change the priority being used if the task is not\r
+ currently using an inherited priority. */\r
+ if( pxTCB->uxBasePriority == pxTCB->uxPriority )\r
+ {\r
+ pxTCB->uxPriority = uxNewPriority;\r
+ }\r
+\r
+ /* The base priority gets set whatever. */\r
+ pxTCB->uxBasePriority = uxNewPriority;\r
+ }\r
+ #else\r
+ {\r
+ pxTCB->uxPriority = uxNewPriority;\r
+ }\r
+ #endif\r
+\r
+ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );\r
+\r
+ /* If the task is in the blocked or suspended list we need do\r
+ nothing more than change it's priority variable. However, if\r
+ the task is in a ready list it needs to be removed and placed\r
+ in the queue appropriate to its new priority. */\r
+ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) )\r
+ {\r
+ /* The task is currently in its ready list - remove before adding\r
+ it to it's new ready list. As we are in a critical section we\r
+ can do this even if the scheduler is suspended. */\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+ }\r
+\r
+ if( xYieldRequired == pdTRUE )\r
+ {\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+ void vTaskSuspend( xTaskHandle pxTaskToSuspend )\r
+ {\r
+ tskTCB *pxTCB;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Ensure a yield is performed if the current task is being\r
+ suspended. */\r
+ if( pxTaskToSuspend == pxCurrentTCB )\r
+ {\r
+ pxTaskToSuspend = NULL;\r
+ }\r
+\r
+ /* If null is passed in here then we are suspending ourselves. */\r
+ pxTCB = prvGetTCBFromHandle( pxTaskToSuspend );\r
+\r
+ traceTASK_SUSPEND( pxTCB );\r
+\r
+ /* Remove task from the ready/delayed list and place in the suspended list. */\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+ /* Is the task waiting on an event also? */\r
+ if( pxTCB->xEventListItem.pvContainer != NULL )\r
+ {\r
+ vListRemove( &( pxTCB->xEventListItem ) );\r
+ }\r
+\r
+ vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ if( ( void * ) pxTaskToSuspend == NULL )\r
+ {\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ /* We have just suspended the current task. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ else\r
+ {\r
+ /* The scheduler is not running, but the task that was pointed\r
+ to by pxCurrentTCB has just been suspended and pxCurrentTCB\r
+ must be adjusted to point to a different task. */\r
+ if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )\r
+ {\r
+ /* No other tasks are ready, so set pxCurrentTCB back to\r
+ NULL so when the next task is created pxCurrentTCB will\r
+ be set to point to it no matter what its relative priority\r
+ is. */\r
+ pxCurrentTCB = NULL;\r
+ }\r
+ else\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+ signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask )\r
+ {\r
+ portBASE_TYPE xReturn = pdFALSE;\r
+ const tskTCB * const pxTCB = ( tskTCB * ) xTask;\r
+\r
+ /* It does not make sense to check if the calling task is suspended. */\r
+ configASSERT( xTask );\r
+\r
+ /* Is the task we are attempting to resume actually in the\r
+ suspended list? */\r
+ if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ {\r
+ /* Has the task already been resumed from within an ISR? */\r
+ if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+ {\r
+ /* Is it in the suspended list because it is in the\r
+ Suspended state? It is possible to be in the suspended\r
+ list because it is blocked on a task with no timeout\r
+ specified. */\r
+ if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE )\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+ void vTaskResume( xTaskHandle pxTaskToResume )\r
+ {\r
+ tskTCB *pxTCB;\r
+\r
+ /* It does not make sense to resume the calling task. */\r
+ configASSERT( pxTaskToResume );\r
+\r
+ /* Remove the task from whichever list it is currently in, and place\r
+ it in the ready list. */\r
+ pxTCB = ( tskTCB * ) pxTaskToResume;\r
+\r
+ /* The parameter cannot be NULL as it is impossible to resume the\r
+ currently executing task. */\r
+ if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
+ {\r
+ traceTASK_RESUME( pxTCB );\r
+\r
+ /* As we are in a critical section we can access the ready\r
+ lists even if the scheduler is suspended. */\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+\r
+ /* We may have just resumed a higher priority task. */\r
+ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+ {\r
+ /* This yield may not cause the task just resumed to run, but\r
+ will leave the lists in the correct state for the next yield. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ }\r
+ }\r
+\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )\r
+\r
+ portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )\r
+ {\r
+ portBASE_TYPE xYieldRequired = pdFALSE;\r
+ tskTCB *pxTCB;\r
+ unsigned portBASE_TYPE uxSavedInterruptStatus;\r
+\r
+ configASSERT( pxTaskToResume );\r
+\r
+ pxTCB = ( tskTCB * ) pxTaskToResume;\r
+\r
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ {\r
+ if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE )\r
+ {\r
+ traceTASK_RESUME_FROM_ISR( pxTCB );\r
+\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+ }\r
+ else\r
+ {\r
+ /* We cannot access the delayed or ready lists, so will hold this\r
+ task pending until the scheduler is resumed, at which point a\r
+ yield will be performed if necessary. */\r
+ vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
+ }\r
+ }\r
+ }\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
+\r
+ return xYieldRequired;\r
+ }\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * PUBLIC SCHEDULER CONTROL documented in task.h\r
+ *----------------------------------------------------------*/\r
+\r
+\r
+void vTaskStartScheduler( void )\r
+{\r
+portBASE_TYPE xReturn;\r
+\r
+ /* Add the idle task at the lowest priority. */\r
+ #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
+ {\r
+ /* Create the idle task, storing its handle in xIdleTaskHandle so it can\r
+ be returned by the xTaskGetIdleTaskHandle() function. */\r
+ xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle );\r
+ }\r
+ #else\r
+ {\r
+ /* Create the idle task without storing its handle. */\r
+ xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );\r
+ }\r
+ #endif\r
+\r
+ #if ( configUSE_TIMERS == 1 )\r
+ {\r
+ if( xReturn == pdPASS )\r
+ {\r
+ xReturn = xTimerCreateTimerTask();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if( xReturn == pdPASS )\r
+ {\r
+ /* Interrupts are turned off here, to ensure a tick does not occur\r
+ before or during the call to xPortStartScheduler(). The stacks of\r
+ the created tasks contain a status word with interrupts switched on\r
+ so interrupts will automatically get re-enabled when the first task\r
+ starts to run.\r
+\r
+ STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE\r
+ DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ xSchedulerRunning = pdTRUE;\r
+ xTickCount = ( portTickType ) 0U;\r
+\r
+ /* If configGENERATE_RUN_TIME_STATS is defined then the following\r
+ macro must be defined to configure the timer/counter used to generate\r
+ the run time counter time base. */\r
+ portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();\r
+ \r
+ /* Setting up the timer tick is hardware specific and thus in the\r
+ portable interface. */\r
+ if( xPortStartScheduler() != pdFALSE )\r
+ {\r
+ /* Should not reach here as if the scheduler is running the\r
+ function will not return. */\r
+ }\r
+ else\r
+ {\r
+ /* Should only reach here if a task calls xTaskEndScheduler(). */\r
+ }\r
+ }\r
+\r
+ /* This line will only be reached if the kernel could not be started. */\r
+ configASSERT( xReturn );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTaskEndScheduler( void )\r
+{\r
+ /* Stop the scheduler interrupts and call the portable scheduler end\r
+ routine so the original ISRs can be restored if necessary. The port\r
+ layer must ensure interrupts enable bit is left in the correct state. */\r
+ portDISABLE_INTERRUPTS();\r
+ xSchedulerRunning = pdFALSE;\r
+ vPortEndScheduler();\r
+}\r
+/*----------------------------------------------------------*/\r
+\r
+void vTaskSuspendAll( void )\r
+{\r
+ /* A critical section is not required as the variable is of type\r
+ portBASE_TYPE. */\r
+ ++uxSchedulerSuspended;\r
+}\r
+/*----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xTaskResumeAll( void )\r
+{\r
+register tskTCB *pxTCB;\r
+signed portBASE_TYPE xAlreadyYielded = pdFALSE;\r
+\r
+ /* If uxSchedulerSuspended is zero then this function does not match a\r
+ previous call to vTaskSuspendAll(). */\r
+ configASSERT( uxSchedulerSuspended );\r
+\r
+ /* It is possible that an ISR caused a task to be removed from an event\r
+ list while the scheduler was suspended. If this was the case then the\r
+ removed task will have been added to the xPendingReadyList. Once the\r
+ scheduler has been resumed it is safe to move all the pending ready\r
+ tasks from this list into their appropriate ready list. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ --uxSchedulerSuspended;\r
+\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ portBASE_TYPE xYieldRequired = pdFALSE;\r
+\r
+ /* Move any readied tasks from the pending list into the\r
+ appropriate ready list. */\r
+ while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE )\r
+ {\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) );\r
+ vListRemove( &( pxTCB->xEventListItem ) );\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+\r
+ /* If we have moved a task that has a priority higher than\r
+ the current task then we should yield. */\r
+ if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+ {\r
+ xYieldRequired = pdTRUE;\r
+ }\r
+ }\r
+\r
+ /* If any ticks occurred while the scheduler was suspended then\r
+ they should be processed now. This ensures the tick count does not\r
+ slip, and that any delayed tasks are resumed at the correct time. */\r
+ if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ vTaskIncrementTick();\r
+ --uxMissedTicks;\r
+ }\r
+\r
+ /* As we have processed some ticks it is appropriate to yield\r
+ to ensure the highest priority task that is ready to run is\r
+ the task actually running. */\r
+ #if configUSE_PREEMPTION == 1\r
+ {\r
+ xYieldRequired = pdTRUE;\r
+ }\r
+ #endif\r
+ }\r
+\r
+ if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )\r
+ {\r
+ xAlreadyYielded = pdTRUE;\r
+ xMissedYield = pdFALSE;\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xAlreadyYielded;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * PUBLIC TASK UTILITIES documented in task.h\r
+ *----------------------------------------------------------*/\r
+\r
+\r
+\r
+portTickType xTaskGetTickCount( void )\r
+{\r
+portTickType xTicks;\r
+\r
+ /* Critical section required if running on a 16 bit processor. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ xTicks = xTickCount;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xTicks;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portTickType xTaskGetTickCountFromISR( void )\r
+{\r
+portTickType xReturn;\r
+unsigned portBASE_TYPE uxSavedInterruptStatus;\r
+\r
+ uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ xReturn = xTickCount;\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )\r
+{\r
+ /* A critical section is not required because the variables are of type\r
+ portBASE_TYPE. */\r
+ return uxCurrentNumberOfTasks;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_pcTaskGetTaskName == 1 )\r
+\r
+ signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery )\r
+ {\r
+ tskTCB *pxTCB;\r
+\r
+ /* If null is passed in here then the name of the calling task is being queried. */\r
+ pxTCB = prvGetTCBFromHandle( xTaskToQuery );\r
+ configASSERT( pxTCB );\r
+ return &( pxTCB->pcTaskName[ 0 ] );\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ void vTaskList( signed char *pcWriteBuffer )\r
+ {\r
+ unsigned portBASE_TYPE uxQueue;\r
+\r
+ /* This is a VERY costly function that should be used for debug only.\r
+ It leaves interrupts disabled for a LONG time. */\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ /* Run through all the lists that could potentially contain a TCB and\r
+ report the task name, state and stack high water mark. */\r
+\r
+ *pcWriteBuffer = ( signed char ) 0x00;\r
+ strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );\r
+\r
+ uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;\r
+\r
+ do\r
+ {\r
+ uxQueue--;\r
+\r
+ if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )\r
+ {\r
+ prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );\r
+ }\r
+ }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );\r
+\r
+ if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )\r
+ {\r
+ prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );\r
+ }\r
+\r
+ if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )\r
+ {\r
+ prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );\r
+ }\r
+\r
+ #if( INCLUDE_vTaskDelete == 1 )\r
+ {\r
+ if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )\r
+ {\r
+ prvListTaskWithinSingleList( pcWriteBuffer, &xTasksWaitingTermination, tskDELETED_CHAR );\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ {\r
+ if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )\r
+ {\r
+ prvListTaskWithinSingleList( pcWriteBuffer, &xSuspendedTaskList, tskSUSPENDED_CHAR );\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ xTaskResumeAll();\r
+ }\r
+\r
+#endif\r
+/*----------------------------------------------------------*/\r
+\r
+#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+\r
+ void vTaskGetRunTimeStats( signed char *pcWriteBuffer )\r
+ {\r
+ unsigned portBASE_TYPE uxQueue;\r
+ unsigned long ulTotalRunTime;\r
+\r
+ /* This is a VERY costly function that should be used for debug only.\r
+ It leaves interrupts disabled for a LONG time. */\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
+ portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
+ #else\r
+ ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
+ #endif\r
+\r
+ /* Divide ulTotalRunTime by 100 to make the percentage caluclations\r
+ simpler in the prvGenerateRunTimeStatsForTasksInList() function. */\r
+ ulTotalRunTime /= 100UL;\r
+ \r
+ /* Run through all the lists that could potentially contain a TCB,\r
+ generating a table of run timer percentages in the provided\r
+ buffer. */\r
+\r
+ *pcWriteBuffer = ( signed char ) 0x00;\r
+ strcat( ( char * ) pcWriteBuffer, ( const char * ) "\r\n" );\r
+\r
+ uxQueue = uxTopUsedPriority + ( unsigned portBASE_TYPE ) 1U;\r
+\r
+ do\r
+ {\r
+ uxQueue--;\r
+\r
+ if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE )\r
+ {\r
+ prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), ulTotalRunTime );\r
+ }\r
+ }while( uxQueue > ( unsigned short ) tskIDLE_PRIORITY );\r
+\r
+ if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE )\r
+ {\r
+ prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, ulTotalRunTime );\r
+ }\r
+\r
+ if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE )\r
+ {\r
+ prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, ulTotalRunTime );\r
+ }\r
+\r
+ #if ( INCLUDE_vTaskDelete == 1 )\r
+ {\r
+ if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE )\r
+ {\r
+ prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, &xTasksWaitingTermination, ulTotalRunTime );\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ {\r
+ if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE )\r
+ {\r
+ prvGenerateRunTimeStatsForTasksInList( pcWriteBuffer, &xSuspendedTaskList, ulTotalRunTime );\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ xTaskResumeAll();\r
+ }\r
+\r
+#endif\r
+/*----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
+\r
+ xTaskHandle xTaskGetIdleTaskHandle( void )\r
+ {\r
+ /* If xTaskGetIdleTaskHandle() is called before the scheduler has been\r
+ started, then xIdleTaskHandle will be NULL. */\r
+ configASSERT( ( xIdleTaskHandle != NULL ) );\r
+ return xIdleTaskHandle;\r
+ }\r
+ \r
+#endif\r
+\r
+/*-----------------------------------------------------------\r
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
+ * documented in task.h\r
+ *----------------------------------------------------------*/\r
+\r
+void vTaskIncrementTick( void )\r
+{\r
+tskTCB * pxTCB;\r
+\r
+ /* Called by the portable layer each time a tick interrupt occurs.\r
+ Increments the tick then checks to see if the new tick value will cause any\r
+ tasks to be unblocked. */\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ ++xTickCount;\r
+ if( xTickCount == ( portTickType ) 0U )\r
+ {\r
+ xList *pxTemp;\r
+\r
+ /* Tick count has overflowed so we need to swap the delay lists.\r
+ If there are any items in pxDelayedTaskList here then there is\r
+ an error! */\r
+ configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) );\r
+ \r
+ pxTemp = pxDelayedTaskList;\r
+ pxDelayedTaskList = pxOverflowDelayedTaskList;\r
+ pxOverflowDelayedTaskList = pxTemp;\r
+ xNumOfOverflows++;\r
+ \r
+ if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
+ {\r
+ /* The new current delayed list is empty. Set\r
+ xNextTaskUnblockTime to the maximum possible value so it is\r
+ extremely unlikely that the \r
+ if( xTickCount >= xNextTaskUnblockTime ) test will pass until\r
+ there is an item in the delayed list. */\r
+ xNextTaskUnblockTime = portMAX_DELAY;\r
+ }\r
+ else\r
+ {\r
+ /* The new current delayed list is not empty, get the value of\r
+ the item at the head of the delayed list. This is the time at\r
+ which the task at the head of the delayed list should be removed\r
+ from the Blocked state. */\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );\r
+ xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );\r
+ }\r
+ }\r
+\r
+ /* See if this tick has made a timeout expire. */\r
+ prvCheckDelayedTasks();\r
+ }\r
+ else\r
+ {\r
+ ++uxMissedTicks;\r
+\r
+ /* The tick hook gets called at regular intervals, even if the\r
+ scheduler is locked. */\r
+ #if ( configUSE_TICK_HOOK == 1 )\r
+ {\r
+ vApplicationTickHook();\r
+ }\r
+ #endif\r
+ }\r
+\r
+ #if ( configUSE_TICK_HOOK == 1 )\r
+ {\r
+ /* Guard against the tick hook being called when the missed tick\r
+ count is being unwound (when the scheduler is being unlocked. */\r
+ if( uxMissedTicks == ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ vApplicationTickHook();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ traceTASK_INCREMENT_TICK( xTickCount );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+ void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction )\r
+ {\r
+ tskTCB *xTCB;\r
+\r
+ /* If xTask is NULL then we are setting our own task hook. */\r
+ if( xTask == NULL )\r
+ {\r
+ xTCB = ( tskTCB * ) pxCurrentTCB;\r
+ }\r
+ else\r
+ {\r
+ xTCB = ( tskTCB * ) xTask;\r
+ }\r
+\r
+ /* Save the hook function in the TCB. A critical section is required as\r
+ the value can be accessed from an interrupt. */\r
+ taskENTER_CRITICAL();\r
+ xTCB->pxTaskTag = pxHookFunction;\r
+ taskEXIT_CRITICAL();\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+ pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask )\r
+ {\r
+ tskTCB *xTCB;\r
+ pdTASK_HOOK_CODE xReturn;\r
+\r
+ /* If xTask is NULL then we are setting our own task hook. */\r
+ if( xTask == NULL )\r
+ {\r
+ xTCB = ( tskTCB * ) pxCurrentTCB;\r
+ }\r
+ else\r
+ {\r
+ xTCB = ( tskTCB * ) xTask;\r
+ }\r
+\r
+ /* Save the hook function in the TCB. A critical section is required as\r
+ the value can be accessed from an interrupt. */\r
+ taskENTER_CRITICAL();\r
+ xReturn = xTCB->pxTaskTag;\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+ portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )\r
+ {\r
+ tskTCB *xTCB;\r
+ portBASE_TYPE xReturn;\r
+\r
+ /* If xTask is NULL then we are calling our own task hook. */\r
+ if( xTask == NULL )\r
+ {\r
+ xTCB = ( tskTCB * ) pxCurrentTCB;\r
+ }\r
+ else\r
+ {\r
+ xTCB = ( tskTCB * ) xTask;\r
+ }\r
+\r
+ if( xTCB->pxTaskTag != NULL )\r
+ {\r
+ xReturn = xTCB->pxTaskTag( pvParameter );\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTaskSwitchContext( void )\r
+{\r
+ if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ /* The scheduler is currently suspended - do not allow a context\r
+ switch. */\r
+ xMissedYield = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ traceTASK_SWITCHED_OUT();\r
+ \r
+ #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+ {\r
+ unsigned long ulTempCounter;\r
+ \r
+ #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
+ portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter );\r
+ #else\r
+ ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();\r
+ #endif\r
+ \r
+ /* Add the amount of time the task has been running to the accumulated\r
+ time so far. The time the task started running was stored in\r
+ ulTaskSwitchedInTime. Note that there is no overflow protection here\r
+ so count values are only valid until the timer overflows. Generally\r
+ this will be about 1 hour assuming a 1uS timer increment. */\r
+ pxCurrentTCB->ulRunTimeCounter += ( ulTempCounter - ulTaskSwitchedInTime );\r
+ ulTaskSwitchedInTime = ulTempCounter;\r
+ }\r
+ #endif\r
+ \r
+ taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
+ taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
+ \r
+ /* Find the highest priority queue that contains ready tasks. */\r
+ while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
+ {\r
+ configASSERT( uxTopReadyPriority );\r
+ --uxTopReadyPriority;\r
+ }\r
+ \r
+ /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the\r
+ same priority get an equal share of the processor time. */\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\r
+ \r
+ traceTASK_SWITCHED_IN();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
+{\r
+portTickType xTimeToWake;\r
+\r
+ configASSERT( pxEventList );\r
+\r
+ /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE\r
+ SCHEDULER SUSPENDED. */\r
+\r
+ /* Place the event list item of the TCB in the appropriate event list.\r
+ This is placed in the list in priority order so the highest priority task\r
+ is the first to be woken by the event. */\r
+ vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );\r
+\r
+ /* We must remove ourselves from the ready list before adding ourselves\r
+ to the blocked list as the same list item is used for both lists. We have\r
+ exclusive access to the ready lists as the scheduler is locked. */\r
+ vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ {\r
+ if( xTicksToWait == portMAX_DELAY )\r
+ {\r
+ /* Add ourselves to the suspended task list instead of a delayed task\r
+ list to ensure we are not woken by a timing event. We will block\r
+ indefinitely. */\r
+ vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ }\r
+ else\r
+ {\r
+ /* Calculate the time at which the task should be woken if the event does\r
+ not occur. This may overflow but this doesn't matter. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ }\r
+ #else\r
+ {\r
+ /* Calculate the time at which the task should be woken if the event does\r
+ not occur. This may overflow but this doesn't matter. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_TIMERS == 1\r
+\r
+ void vTaskPlaceOnEventListRestricted( const xList * const pxEventList, portTickType xTicksToWait )\r
+ {\r
+ portTickType xTimeToWake;\r
+\r
+ configASSERT( pxEventList );\r
+\r
+ /* This function should not be called by application code hence the\r
+ 'Restricted' in its name. It is not part of the public API. It is\r
+ designed for use by kernel code, and has special calling requirements -\r
+ it should be called from a critical section. */\r
+\r
+ \r
+ /* Place the event list item of the TCB in the appropriate event list.\r
+ In this case it is assume that this is the only task that is going to\r
+ be waiting on this event list, so the faster vListInsertEnd() function\r
+ can be used in place of vListInsert. */\r
+ vListInsertEnd( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );\r
+\r
+ /* We must remove this task from the ready list before adding it to the\r
+ blocked list as the same list item is used for both lists. This\r
+ function is called form a critical section. */\r
+ vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+\r
+ /* Calculate the time at which the task should be woken if the event does\r
+ not occur. This may overflow but this doesn't matter. */\r
+ xTimeToWake = xTickCount + xTicksToWait;\r
+ prvAddCurrentTaskToDelayedList( xTimeToWake );\r
+ }\r
+ \r
+#endif /* configUSE_TIMERS */\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )\r
+{\r
+tskTCB *pxUnblockedTCB;\r
+portBASE_TYPE xReturn;\r
+\r
+ /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE\r
+ SCHEDULER SUSPENDED. It can also be called from within an ISR. */\r
+\r
+ /* The event list is sorted in priority order, so we can remove the\r
+ first in the list, remove the TCB from the delayed list, and add\r
+ it to the ready list.\r
+\r
+ If an event is for a queue that is locked then this function will never\r
+ get called - the lock count on the queue will get modified instead. This\r
+ means we can always expect exclusive access to the event list here.\r
+ \r
+ This function assumes that a check has already been made to ensure that\r
+ pxEventList is not empty. */\r
+ pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );\r
+ configASSERT( pxUnblockedTCB );\r
+ vListRemove( &( pxUnblockedTCB->xEventListItem ) );\r
+\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ vListRemove( &( pxUnblockedTCB->xGenericListItem ) );\r
+ prvAddTaskToReadyQueue( pxUnblockedTCB );\r
+ }\r
+ else\r
+ {\r
+ /* We cannot access the delayed or ready lists, so will hold this\r
+ task pending until the scheduler is resumed. */\r
+ vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );\r
+ }\r
+\r
+ if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+ {\r
+ /* Return true if the task removed from the event list has\r
+ a higher priority than the calling task. This allows\r
+ the calling task to know if it should force a context\r
+ switch now. */\r
+ xReturn = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )\r
+{\r
+ configASSERT( pxTimeOut );\r
+ pxTimeOut->xOverflowCount = xNumOfOverflows;\r
+ pxTimeOut->xTimeOnEntering = xTickCount;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )\r
+{\r
+portBASE_TYPE xReturn;\r
+\r
+ configASSERT( pxTimeOut );\r
+ configASSERT( pxTicksToWait );\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is\r
+ the maximum block time then the task should block indefinitely, and\r
+ therefore never time out. */\r
+ if( *pxTicksToWait == portMAX_DELAY )\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+ else /* We are not blocking indefinitely, perform the checks below. */\r
+ #endif\r
+\r
+ if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( ( portTickType ) xTickCount >= ( portTickType ) pxTimeOut->xTimeOnEntering ) )\r
+ {\r
+ /* The tick count is greater than the time at which vTaskSetTimeout()\r
+ was called, but has also overflowed since vTaskSetTimeOut() was called.\r
+ It must have wrapped all the way around and gone past us again. This\r
+ passed since vTaskSetTimeout() was called. */\r
+ xReturn = pdTRUE;\r
+ }\r
+ else if( ( ( portTickType ) ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering ) ) < ( portTickType ) *pxTicksToWait )\r
+ {\r
+ /* Not a genuine timeout. Adjust parameters for time remaining. */\r
+ *pxTicksToWait -= ( ( portTickType ) xTickCount - ( portTickType ) pxTimeOut->xTimeOnEntering );\r
+ vTaskSetTimeOutState( pxTimeOut );\r
+ xReturn = pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTaskMissedYield( void )\r
+{\r
+ xMissedYield = pdTRUE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+ unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask )\r
+ {\r
+ unsigned portBASE_TYPE uxReturn;\r
+ tskTCB *pxTCB;\r
+ \r
+ if( xTask != NULL )\r
+ {\r
+ pxTCB = ( tskTCB * ) xTask;\r
+ uxReturn = pxTCB->uxTaskNumber;\r
+ }\r
+ else\r
+ {\r
+ uxReturn = 0U;\r
+ }\r
+ \r
+ return uxReturn;\r
+ }\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+ void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle )\r
+ {\r
+ tskTCB *pxTCB;\r
+ \r
+ if( xTask != NULL )\r
+ {\r
+ pxTCB = ( tskTCB * ) xTask;\r
+ pxTCB->uxTaskNumber = uxHandle;\r
+ }\r
+ }\r
+#endif\r
+\r
+\r
+/*\r
+ * -----------------------------------------------------------\r
+ * The Idle task.\r
+ * ----------------------------------------------------------\r
+ *\r
+ * The portTASK_FUNCTION() macro is used to allow port/compiler specific\r
+ * language extensions. The equivalent prototype for this function is:\r
+ *\r
+ * void prvIdleTask( void *pvParameters );\r
+ *\r
+ */\r
+static portTASK_FUNCTION( prvIdleTask, pvParameters )\r
+{\r
+ /* Stop warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* See if any tasks have been deleted. */\r
+ prvCheckTasksWaitingTermination();\r
+\r
+ #if ( configUSE_PREEMPTION == 0 )\r
+ {\r
+ /* If we are not using preemption we keep forcing a task switch to\r
+ see if any other task has become available. If we are using\r
+ preemption we don't need to do this as any task becoming available\r
+ will automatically get the processor anyway. */\r
+ taskYIELD();\r
+ }\r
+ #endif\r
+\r
+ #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )\r
+ {\r
+ /* When using preemption tasks of equal priority will be\r
+ timesliced. If a task that is sharing the idle priority is ready\r
+ to run then the idle task should yield before the end of the\r
+ timeslice.\r
+\r
+ A critical region is not required here as we are just reading from\r
+ the list, and an occasional incorrect value will not matter. If\r
+ the ready list at the idle priority contains more than one task\r
+ then a task other than the idle task is ready to execute. */\r
+ if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 )\r
+ {\r
+ taskYIELD();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if ( configUSE_IDLE_HOOK == 1 )\r
+ {\r
+ extern void vApplicationIdleHook( void );\r
+\r
+ /* Call the user defined function from within the idle task. This\r
+ allows the application designer to add background functionality\r
+ without the overhead of a separate task.\r
+ NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,\r
+ CALL A FUNCTION THAT MIGHT BLOCK. */\r
+ vApplicationIdleHook();\r
+ }\r
+ #endif\r
+ }\r
+} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------\r
+ * File private functions documented at the top of the file.\r
+ *----------------------------------------------------------*/\r
+\r
+\r
+\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth )\r
+{\r
+ /* Store the function name in the TCB. */\r
+ #if configMAX_TASK_NAME_LEN > 1\r
+ {\r
+ /* Don't bring strncpy into the build unnecessarily. */\r
+ strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned short ) configMAX_TASK_NAME_LEN );\r
+ }\r
+ #endif\r
+ pxTCB->pcTaskName[ ( unsigned short ) configMAX_TASK_NAME_LEN - ( unsigned short ) 1 ] = ( signed char ) '\0';\r
+\r
+ /* This is used as an array index so must ensure it's not too large. First\r
+ remove the privilege bit if one is present. */\r
+ if( uxPriority >= configMAX_PRIORITIES )\r
+ {\r
+ uxPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;\r
+ }\r
+\r
+ pxTCB->uxPriority = uxPriority;\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ pxTCB->uxBasePriority = uxPriority;\r
+ }\r
+ #endif\r
+\r
+ vListInitialiseItem( &( pxTCB->xGenericListItem ) );\r
+ vListInitialiseItem( &( pxTCB->xEventListItem ) );\r
+\r
+ /* Set the pxTCB as a link back from the xListItem. This is so we can get\r
+ back to the containing TCB from a generic item in a list. */\r
+ listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );\r
+\r
+ /* Event lists are always in priority order. */\r
+ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );\r
+ listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );\r
+\r
+ #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+ {\r
+ pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0U;\r
+ }\r
+ #endif\r
+\r
+ #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+ {\r
+ pxTCB->pxTaskTag = NULL;\r
+ }\r
+ #endif\r
+\r
+ #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+ {\r
+ pxTCB->ulRunTimeCounter = 0UL;\r
+ }\r
+ #endif\r
+\r
+ #if ( portUSING_MPU_WRAPPERS == 1 )\r
+ {\r
+ vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );\r
+ }\r
+ #else\r
+ {\r
+ ( void ) xRegions;\r
+ ( void ) usStackDepth;\r
+ }\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( portUSING_MPU_WRAPPERS == 1 )\r
+\r
+ void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions )\r
+ {\r
+ tskTCB *pxTCB;\r
+ \r
+ if( xTaskToModify == pxCurrentTCB )\r
+ {\r
+ xTaskToModify = NULL;\r
+ }\r
+\r
+ /* If null is passed in here then we are deleting ourselves. */\r
+ pxTCB = prvGetTCBFromHandle( xTaskToModify );\r
+\r
+ vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );\r
+ }\r
+ /*-----------------------------------------------------------*/\r
+#endif\r
+\r
+static void prvInitialiseTaskLists( void )\r
+{\r
+unsigned portBASE_TYPE uxPriority;\r
+\r
+ for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < configMAX_PRIORITIES; uxPriority++ )\r
+ {\r
+ vListInitialise( ( xList * ) &( pxReadyTasksLists[ uxPriority ] ) );\r
+ }\r
+\r
+ vListInitialise( ( xList * ) &xDelayedTaskList1 );\r
+ vListInitialise( ( xList * ) &xDelayedTaskList2 );\r
+ vListInitialise( ( xList * ) &xPendingReadyList );\r
+\r
+ #if ( INCLUDE_vTaskDelete == 1 )\r
+ {\r
+ vListInitialise( ( xList * ) &xTasksWaitingTermination );\r
+ }\r
+ #endif\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ {\r
+ vListInitialise( ( xList * ) &xSuspendedTaskList );\r
+ }\r
+ #endif\r
+\r
+ /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList\r
+ using list2. */\r
+ pxDelayedTaskList = &xDelayedTaskList1;\r
+ pxOverflowDelayedTaskList = &xDelayedTaskList2;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckTasksWaitingTermination( void )\r
+{\r
+ #if ( INCLUDE_vTaskDelete == 1 )\r
+ {\r
+ portBASE_TYPE xListIsEmpty;\r
+\r
+ /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called\r
+ too often in the idle task. */\r
+ if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0U )\r
+ {\r
+ vTaskSuspendAll();\r
+ xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );\r
+ xTaskResumeAll();\r
+\r
+ if( xListIsEmpty == pdFALSE )\r
+ {\r
+ tskTCB *pxTCB;\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+ --uxCurrentNumberOfTasks;\r
+ --uxTasksDeleted;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ prvDeleteTCB( pxTCB );\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake )\r
+{\r
+ /* The list item will be inserted in wake time order. */\r
+ listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
+\r
+ if( xTimeToWake < xTickCount )\r
+ {\r
+ /* Wake time has overflowed. Place this item in the overflow list. */\r
+ vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ }\r
+ else\r
+ {\r
+ /* The wake time has not overflowed, so we can use the current block list. */\r
+ vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+\r
+ /* If the task entering the blocked state was placed at the head of the\r
+ list of blocked tasks then xNextTaskUnblockTime needs to be updated\r
+ too. */\r
+ if( xTimeToWake < xNextTaskUnblockTime )\r
+ {\r
+ xNextTaskUnblockTime = xTimeToWake;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer )\r
+{\r
+tskTCB *pxNewTCB;\r
+\r
+ /* Allocate space for the TCB. Where the memory comes from depends on\r
+ the implementation of the port malloc function. */\r
+ pxNewTCB = ( tskTCB * ) pvPortMalloc( sizeof( tskTCB ) );\r
+\r
+ if( pxNewTCB != NULL )\r
+ {\r
+ /* Allocate space for the stack used by the task being created.\r
+ The base of the stack memory stored in the TCB so the task can\r
+ be deleted later if required. */\r
+ pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t )usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer );\r
+\r
+ if( pxNewTCB->pxStack == NULL )\r
+ {\r
+ /* Could not allocate the stack. Delete the allocated TCB. */\r
+ vPortFree( pxNewTCB );\r
+ pxNewTCB = NULL;\r
+ }\r
+ else\r
+ {\r
+ /* Just to help debugging. */\r
+ memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( portSTACK_TYPE ) );\r
+ }\r
+ }\r
+\r
+ return pxNewTCB;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ static void prvListTaskWithinSingleList( const signed char *pcWriteBuffer, xList *pxList, signed char cStatus )\r
+ {\r
+ volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
+ unsigned short usStackRemaining;\r
+ PRIVILEGED_DATA static char pcStatusString[ configMAX_TASK_NAME_LEN + 30 ];\r
+\r
+ /* Write the details of all the TCB's in pxList into the buffer. */\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );\r
+ do\r
+ {\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );\r
+ #if ( portSTACK_GROWTH > 0 )\r
+ {\r
+ usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack );\r
+ }\r
+ #else\r
+ {\r
+ usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );\r
+ }\r
+ #endif \r
+ \r
+ sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber );\r
+ strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString );\r
+\r
+ } while( pxNextTCB != pxFirstTCB );\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+\r
+ static void prvGenerateRunTimeStatsForTasksInList( const signed char *pcWriteBuffer, xList *pxList, unsigned long ulTotalRunTime )\r
+ {\r
+ volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
+ unsigned long ulStatsAsPercentage;\r
+\r
+ /* Write the run time stats of all the TCB's in pxList into the buffer. */\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );\r
+ do\r
+ {\r
+ /* Get next TCB in from the list. */\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );\r
+\r
+ /* Divide by zero check. */\r
+ if( ulTotalRunTime > 0UL )\r
+ {\r
+ /* Has the task run at all? */\r
+ if( pxNextTCB->ulRunTimeCounter == 0UL )\r
+ {\r
+ /* The task has used no CPU time at all. */\r
+ sprintf( pcStatsString, ( char * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName );\r
+ }\r
+ else\r
+ {\r
+ /* What percentage of the total run time has the task used?\r
+ This will always be rounded down to the nearest integer.\r
+ ulTotalRunTime has already been divided by 100. */\r
+ ulStatsAsPercentage = pxNextTCB->ulRunTimeCounter / ulTotalRunTime;\r
+\r
+ if( ulStatsAsPercentage > 0UL )\r
+ {\r
+ #ifdef portLU_PRINTF_SPECIFIER_REQUIRED\r
+ {\r
+ sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage ); \r
+ }\r
+ #else\r
+ {\r
+ /* sizeof( int ) == sizeof( long ) so a smaller\r
+ printf() library can be used. */\r
+ sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ /* If the percentage is zero here then the task has\r
+ consumed less than 1% of the total run time. */\r
+ #ifdef portLU_PRINTF_SPECIFIER_REQUIRED\r
+ {\r
+ sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter ); \r
+ }\r
+ #else\r
+ {\r
+ /* sizeof( int ) == sizeof( long ) so a smaller\r
+ printf() library can be used. */\r
+ sprintf( pcStatsString, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, ( unsigned int ) pxNextTCB->ulRunTimeCounter );\r
+ }\r
+ #endif\r
+ }\r
+ }\r
+\r
+ strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatsString );\r
+ }\r
+\r
+ } while( pxNextTCB != pxFirstTCB );\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+\r
+ static unsigned short usTaskCheckFreeStackSpace( const unsigned char * pucStackByte )\r
+ {\r
+ register unsigned short usCount = 0U;\r
+\r
+ while( *pucStackByte == tskSTACK_FILL_BYTE )\r
+ {\r
+ pucStackByte -= portSTACK_GROWTH;\r
+ usCount++;\r
+ }\r
+\r
+ usCount /= sizeof( portSTACK_TYPE );\r
+\r
+ return usCount;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
+\r
+ unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )\r
+ {\r
+ tskTCB *pxTCB;\r
+ unsigned char *pcEndOfStack;\r
+ unsigned portBASE_TYPE uxReturn;\r
+\r
+ pxTCB = prvGetTCBFromHandle( xTask );\r
+\r
+ #if portSTACK_GROWTH < 0\r
+ {\r
+ pcEndOfStack = ( unsigned char * ) pxTCB->pxStack;\r
+ }\r
+ #else\r
+ {\r
+ pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack;\r
+ }\r
+ #endif\r
+\r
+ uxReturn = ( unsigned portBASE_TYPE ) usTaskCheckFreeStackSpace( pcEndOfStack );\r
+\r
+ return uxReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_vTaskDelete == 1 )\r
+\r
+ static void prvDeleteTCB( tskTCB *pxTCB )\r
+ {\r
+ /* This call is required specifically for the TriCore port. It must be\r
+ above the vPortFree() calls. The call is also used by ports/demos that\r
+ want to allocate and clean RAM statically. */\r
+ portCLEAN_UP_TCB( pxTCB );\r
+\r
+ /* Free up the memory allocated by the scheduler for the task. It is up to\r
+ the task to free any memory allocated at the application level. */\r
+ vPortFreeAligned( pxTCB->pxStack );\r
+ vPortFree( pxTCB );\r
+ }\r
+\r
+#endif\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )\r
+\r
+ xTaskHandle xTaskGetCurrentTaskHandle( void )\r
+ {\r
+ xTaskHandle xReturn;\r
+\r
+ /* A critical section is not required as this is not called from\r
+ an interrupt and the current TCB will always be the same for any\r
+ individual execution thread. */\r
+ xReturn = pxCurrentTCB;\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )\r
+\r
+ portBASE_TYPE xTaskGetSchedulerState( void )\r
+ {\r
+ portBASE_TYPE xReturn;\r
+\r
+ if( xSchedulerRunning == pdFALSE )\r
+ {\r
+ xReturn = taskSCHEDULER_NOT_STARTED;\r
+ }\r
+ else\r
+ {\r
+ if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ xReturn = taskSCHEDULER_RUNNING;\r
+ }\r
+ else\r
+ {\r
+ xReturn = taskSCHEDULER_SUSPENDED;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_MUTEXES == 1 )\r
+\r
+ void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )\r
+ {\r
+ tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+ configASSERT( pxMutexHolder );\r
+\r
+ if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
+ {\r
+ /* Adjust the mutex holder state to account for its new priority. */\r
+ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
+\r
+ /* If the task being modified is in the ready state it will need to\r
+ be moved in to a new list. */\r
+ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ {\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+ /* Inherit the priority before being moved into the new list. */\r
+ pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+ }\r
+ else\r
+ {\r
+ /* Just inherit the priority. */\r
+ pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+ }\r
+\r
+ traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_MUTEXES == 1 )\r
+\r
+ void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )\r
+ {\r
+ tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+ if( pxMutexHolder != NULL )\r
+ {\r
+ if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
+ {\r
+ /* We must be the running task to be able to give the mutex back.\r
+ Remove ourselves from the ready list we currently appear in. */\r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+ /* Disinherit the priority before adding the task into the new\r
+ ready list. */\r
+ traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );\r
+ pxTCB->uxPriority = pxTCB->uxBasePriority;\r
+ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+ }\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+\r
+ void vTaskEnterCritical( void )\r
+ {\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ ( pxCurrentTCB->uxCriticalNesting )++;\r
+ }\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+\r
+void vTaskExitCritical( void )\r
+{\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ if( pxCurrentTCB->uxCriticalNesting > 0U )\r
+ {\r
+ ( pxCurrentTCB->uxCriticalNesting )--;\r
+\r
+ if( pxCurrentTCB->uxCriticalNesting == 0U )\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
+all the API functions to use the MPU wrappers. That should only be done when\r
+task.h is included from an application file. */\r
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "timers.h"\r
+\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+/* This entire source file will be skipped if the application is not configured\r
+to include software timer functionality. This #if is closed at the very bottom\r
+of this file. If you want to include software timer functionality then ensure\r
+configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */\r
+#if ( configUSE_TIMERS == 1 )\r
+\r
+/* Misc definitions. */\r
+#define tmrNO_DELAY ( portTickType ) 0U\r
+\r
+/* The definition of the timers themselves. */\r
+typedef struct tmrTimerControl\r
+{\r
+ const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */\r
+ xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */\r
+ portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */\r
+ unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */\r
+ void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */\r
+ tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */\r
+} xTIMER;\r
+\r
+/* The definition of messages that can be sent and received on the timer\r
+queue. */\r
+typedef struct tmrTimerQueueMessage\r
+{\r
+ portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */\r
+ portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */\r
+ xTIMER * pxTimer; /*<< The timer to which the command will be applied. */\r
+} xTIMER_MESSAGE;\r
+\r
+\r
+/* The list in which active timers are stored. Timers are referenced in expire\r
+time order, with the nearest expiry time at the front of the list. Only the\r
+timer service task is allowed to access xActiveTimerList. */\r
+PRIVILEGED_DATA static xList xActiveTimerList1;\r
+PRIVILEGED_DATA static xList xActiveTimerList2;\r
+PRIVILEGED_DATA static xList *pxCurrentTimerList;\r
+PRIVILEGED_DATA static xList *pxOverflowTimerList;\r
+\r
+/* A queue that is used to send commands to the timer service task. */\r
+PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;\r
+\r
+#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
+ \r
+ PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;\r
+ \r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Initialise the infrastructure used by the timer service task if it has not\r
+ * been initialised already.\r
+ */\r
+static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * The timer service task (daemon). Timer functionality is controlled by this\r
+ * task. Other tasks communicate with the timer service task using the\r
+ * xTimerQueue queue.\r
+ */\r
+static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Called by the timer service task to interpret and process a command it\r
+ * received on the timer queue.\r
+ */\r
+static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,\r
+ * depending on if the expire time causes a timer counter overflow.\r
+ */\r
+static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * An active timer has reached its expire time. Reload the timer if it is an\r
+ * auto reload timer, then call its callback.\r
+ */\r
+static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * The tick count has overflowed. Switch the timer lists after ensuring the\r
+ * current timer list does not still reference some timers.\r
+ */\r
+static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE\r
+ * if a tick count overflow occurred since prvSampleTimeNow() was last called.\r
+ */\r
+static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * If the timer list contains any active timers then return the expire time of\r
+ * the timer that will expire first and set *pxListWasEmpty to false. If the\r
+ * timer list does not contain any timers then return 0 and set *pxListWasEmpty\r
+ * to pdTRUE.\r
+ */\r
+static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * If a timer has expired, process it. Otherwise, block the timer service task\r
+ * until either a timer does expire or a command is received.\r
+ */\r
+static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xTimerCreateTimerTask( void )\r
+{\r
+portBASE_TYPE xReturn = pdFAIL;\r
+\r
+ /* This function is called when the scheduler is started if\r
+ configUSE_TIMERS is set to 1. Check that the infrastructure used by the\r
+ timer service task has been created/initialised. If timers have already\r
+ been created then the initialisation will already have been performed. */\r
+ prvCheckForValidListAndQueue();\r
+\r
+ if( xTimerQueue != NULL )\r
+ {\r
+ #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
+ {\r
+ /* Create the timer task, storing its handle in xTimerTaskHandle so\r
+ it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */\r
+ xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle ); \r
+ }\r
+ #else\r
+ {\r
+ /* Create the timer task without storing its handle. */\r
+ xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);\r
+ }\r
+ #endif\r
+ }\r
+\r
+ configASSERT( xReturn );\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )\r
+{\r
+xTIMER *pxNewTimer;\r
+\r
+ /* Allocate the timer structure. */\r
+ if( xTimerPeriodInTicks == ( portTickType ) 0U )\r
+ {\r
+ pxNewTimer = NULL;\r
+ configASSERT( ( xTimerPeriodInTicks > 0 ) );\r
+ }\r
+ else\r
+ {\r
+ pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );\r
+ if( pxNewTimer != NULL )\r
+ {\r
+ /* Ensure the infrastructure used by the timer service task has been\r
+ created/initialised. */\r
+ prvCheckForValidListAndQueue();\r
+ \r
+ /* Initialise the timer structure members using the function parameters. */\r
+ pxNewTimer->pcTimerName = pcTimerName;\r
+ pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;\r
+ pxNewTimer->uxAutoReload = uxAutoReload;\r
+ pxNewTimer->pvTimerID = pvTimerID;\r
+ pxNewTimer->pxCallbackFunction = pxCallbackFunction;\r
+ vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );\r
+ \r
+ traceTIMER_CREATE( pxNewTimer );\r
+ }\r
+ else\r
+ {\r
+ traceTIMER_CREATE_FAILED();\r
+ }\r
+ }\r
+ \r
+ return ( xTimerHandle ) pxNewTimer;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime )\r
+{\r
+portBASE_TYPE xReturn = pdFAIL;\r
+xTIMER_MESSAGE xMessage;\r
+\r
+ /* Send a message to the timer service task to perform a particular action\r
+ on a particular timer definition. */\r
+ if( xTimerQueue != NULL )\r
+ {\r
+ /* Send a command to the timer service task to start the xTimer timer. */\r
+ xMessage.xMessageID = xCommandID;\r
+ xMessage.xMessageValue = xOptionalValue;\r
+ xMessage.pxTimer = ( xTIMER * ) xTimer;\r
+\r
+ if( pxHigherPriorityTaskWoken == NULL )\r
+ {\r
+ if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )\r
+ {\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );\r
+ }\r
+ else\r
+ {\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );\r
+ }\r
+ \r
+ traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );\r
+ }\r
+ \r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
+\r
+ xTaskHandle xTimerGetTimerDaemonTaskHandle( void )\r
+ {\r
+ /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been\r
+ started, then xTimerTaskHandle will be NULL. */\r
+ configASSERT( ( xTimerTaskHandle != NULL ) );\r
+ return xTimerTaskHandle;\r
+ }\r
+ \r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )\r
+{\r
+xTIMER *pxTimer;\r
+portBASE_TYPE xResult;\r
+\r
+ /* Remove the timer from the list of active timers. A check has already\r
+ been performed to ensure the list is not empty. */\r
+ pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
+ vListRemove( &( pxTimer->xTimerListItem ) );\r
+ traceTIMER_EXPIRED( pxTimer );\r
+\r
+ /* If the timer is an auto reload timer then calculate the next\r
+ expiry time and re-insert the timer in the list of active timers. */\r
+ if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
+ {\r
+ /* This is the only time a timer is inserted into a list using\r
+ a time relative to anything other than the current time. It\r
+ will therefore be inserted into the correct list relative to\r
+ the time this task thinks it is now, even if a command to\r
+ switch lists due to a tick count overflow is already waiting in\r
+ the timer queue. */\r
+ if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )\r
+ {\r
+ /* The timer expired before it was added to the active timer\r
+ list. Reload it now. */\r
+ xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );\r
+ configASSERT( xResult );\r
+ ( void ) xResult;\r
+ }\r
+ }\r
+\r
+ /* Call the timer callback. */\r
+ pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTimerTask( void *pvParameters )\r
+{\r
+portTickType xNextExpireTime;\r
+portBASE_TYPE xListWasEmpty;\r
+\r
+ /* Just to avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* Query the timers list to see if it contains any timers, and if so,\r
+ obtain the time at which the next timer will expire. */\r
+ xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
+\r
+ /* If a timer has expired, process it. Otherwise, block this task\r
+ until either a timer does expire, or a command is received. */\r
+ prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
+ \r
+ /* Empty the command queue. */\r
+ prvProcessReceivedCommands(); \r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )\r
+{\r
+portTickType xTimeNow;\r
+portBASE_TYPE xTimerListsWereSwitched;\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ /* Obtain the time now to make an assessment as to whether the timer\r
+ has expired or not. If obtaining the time causes the lists to switch\r
+ then don't process this timer as any timers that remained in the list\r
+ when the lists were switched will have been processed within the\r
+ prvSampelTimeNow() function. */\r
+ xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );\r
+ if( xTimerListsWereSwitched == pdFALSE )\r
+ {\r
+ /* The tick count has not overflowed, has the timer expired? */\r
+ if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )\r
+ {\r
+ xTaskResumeAll();\r
+ prvProcessExpiredTimer( xNextExpireTime, xTimeNow );\r
+ }\r
+ else\r
+ {\r
+ /* The tick count has not overflowed, and the next expire\r
+ time has not been reached yet. This task should therefore\r
+ block to wait for the next expire time or a command to be\r
+ received - whichever comes first. The following line cannot\r
+ be reached unless xNextExpireTime > xTimeNow, except in the\r
+ case when the current timer list is empty. */\r
+ vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );\r
+\r
+ if( xTaskResumeAll() == pdFALSE )\r
+ {\r
+ /* Yield to wait for either a command to arrive, or the block time\r
+ to expire. If a command arrived between the critical section being\r
+ exited and this yield then the yield will not cause the task\r
+ to block. */\r
+ portYIELD_WITHIN_API();\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ xTaskResumeAll();\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty )\r
+{\r
+portTickType xNextExpireTime;\r
+\r
+ /* Timers are listed in expiry time order, with the head of the list\r
+ referencing the task that will expire first. Obtain the time at which\r
+ the timer with the nearest expiry time will expire. If there are no\r
+ active timers then just set the next expire time to 0. That will cause\r
+ this task to unblock when the tick count overflows, at which point the\r
+ timer lists will be switched and the next expiry time can be\r
+ re-assessed. */\r
+ *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );\r
+ if( *pxListWasEmpty == pdFALSE )\r
+ {\r
+ xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );\r
+ }\r
+ else\r
+ {\r
+ /* Ensure the task unblocks when the tick count rolls over. */\r
+ xNextExpireTime = ( portTickType ) 0U;\r
+ }\r
+\r
+ return xNextExpireTime;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )\r
+{\r
+portTickType xTimeNow;\r
+PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U;\r
+\r
+ xTimeNow = xTaskGetTickCount();\r
+ \r
+ if( xTimeNow < xLastTime )\r
+ {\r
+ prvSwitchTimerLists( xLastTime );\r
+ *pxTimerListsWereSwitched = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ *pxTimerListsWereSwitched = pdFALSE;\r
+ }\r
+ \r
+ xLastTime = xTimeNow;\r
+ \r
+ return xTimeNow;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )\r
+{\r
+portBASE_TYPE xProcessTimerNow = pdFALSE;\r
+\r
+ listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );\r
+ listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\r
+ \r
+ if( xNextExpiryTime <= xTimeNow )\r
+ {\r
+ /* Has the expiry time elapsed between the command to start/reset a\r
+ timer was issued, and the time the command was processed? */\r
+ if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks )\r
+ {\r
+ /* The time between a command being issued and the command being\r
+ processed actually exceeds the timers period. */\r
+ xProcessTimerNow = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )\r
+ {\r
+ /* If, since the command was issued, the tick count has overflowed\r
+ but the expiry time has not, then the timer must have already passed\r
+ its expiry time and should be processed immediately. */\r
+ xProcessTimerNow = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );\r
+ }\r
+ }\r
+\r
+ return xProcessTimerNow;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvProcessReceivedCommands( void )\r
+{\r
+xTIMER_MESSAGE xMessage;\r
+xTIMER *pxTimer;\r
+portBASE_TYPE xTimerListsWereSwitched, xResult;\r
+portTickType xTimeNow;\r
+\r
+ /* In this case the xTimerListsWereSwitched parameter is not used, but it\r
+ must be present in the function call. */\r
+ xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );\r
+\r
+ while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL )\r
+ {\r
+ pxTimer = xMessage.pxTimer;\r
+\r
+ /* Is the timer already in a list of active timers? When the command\r
+ is trmCOMMAND_PROCESS_TIMER_OVERFLOW, the timer will be NULL as the\r
+ command is to the task rather than to an individual timer. */\r
+ if( pxTimer != NULL )\r
+ {\r
+ if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )\r
+ {\r
+ /* The timer is in a list, remove it. */\r
+ vListRemove( &( pxTimer->xTimerListItem ) );\r
+ }\r
+ }\r
+\r
+ traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );\r
+ \r
+ switch( xMessage.xMessageID )\r
+ {\r
+ case tmrCOMMAND_START : \r
+ /* Start or restart a timer. */\r
+ if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE )\r
+ {\r
+ /* The timer expired before it was added to the active timer\r
+ list. Process it now. */\r
+ pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+\r
+ if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
+ {\r
+ xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );\r
+ configASSERT( xResult );\r
+ ( void ) xResult;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case tmrCOMMAND_STOP : \r
+ /* The timer has already been removed from the active list.\r
+ There is nothing to do here. */\r
+ break;\r
+\r
+ case tmrCOMMAND_CHANGE_PERIOD :\r
+ pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;\r
+ configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );\r
+ prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );\r
+ break;\r
+\r
+ case tmrCOMMAND_DELETE :\r
+ /* The timer has already been removed from the active list,\r
+ just free up the memory. */\r
+ vPortFree( pxTimer );\r
+ break;\r
+\r
+ default : \r
+ /* Don't expect to get here. */\r
+ break;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSwitchTimerLists( portTickType xLastTime )\r
+{\r
+portTickType xNextExpireTime, xReloadTime;\r
+xList *pxTemp;\r
+xTIMER *pxTimer;\r
+portBASE_TYPE xResult;\r
+\r
+ /* Remove compiler warnings if configASSERT() is not defined. */\r
+ ( void ) xLastTime;\r
+ \r
+ /* The tick count has overflowed. The timer lists must be switched.\r
+ If there are any timers still referenced from the current timer list\r
+ then they must have expired and should be processed before the lists\r
+ are switched. */\r
+ while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )\r
+ {\r
+ xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );\r
+\r
+ /* Remove the timer from the list. */\r
+ pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
+ vListRemove( &( pxTimer->xTimerListItem ) );\r
+\r
+ /* Execute its callback, then send a command to restart the timer if\r
+ it is an auto-reload timer. It cannot be restarted here as the lists\r
+ have not yet been switched. */\r
+ pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+\r
+ if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
+ {\r
+ /* Calculate the reload value, and if the reload value results in\r
+ the timer going into the same timer list then it has already expired\r
+ and the timer should be re-inserted into the current list so it is\r
+ processed again within this loop. Otherwise a command should be sent\r
+ to restart the timer to ensure it is only inserted into a list after\r
+ the lists have been swapped. */\r
+ xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );\r
+ if( xReloadTime > xNextExpireTime )\r
+ {\r
+ listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );\r
+ listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\r
+ vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );\r
+ }\r
+ else\r
+ {\r
+ xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );\r
+ configASSERT( xResult );\r
+ ( void ) xResult;\r
+ }\r
+ }\r
+ }\r
+\r
+ pxTemp = pxCurrentTimerList;\r
+ pxCurrentTimerList = pxOverflowTimerList;\r
+ pxOverflowTimerList = pxTemp;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckForValidListAndQueue( void )\r
+{\r
+ /* Check that the list from which active timers are referenced, and the\r
+ queue used to communicate with the timer service, have been\r
+ initialised. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( xTimerQueue == NULL )\r
+ {\r
+ vListInitialise( &xActiveTimerList1 );\r
+ vListInitialise( &xActiveTimerList2 );\r
+ pxCurrentTimerList = &xActiveTimerList1;\r
+ pxOverflowTimerList = &xActiveTimerList2;\r
+ xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) );\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )\r
+{\r
+portBASE_TYPE xTimerIsInActiveList;\r
+xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
+\r
+ /* Is the timer in the list of active timers? */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Checking to see if it is in the NULL list in effect checks to see if\r
+ it is referenced from either the current or the overflow timer lists in\r
+ one go, but the logic has to be reversed, hence the '!'. */\r
+ xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return xTimerIsInActiveList;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void *pvTimerGetTimerID( xTimerHandle xTimer )\r
+{\r
+xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
+\r
+ return pxTimer->pvTimerID;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This entire source file will be skipped if the application is not configured\r
+to include software timer functionality. If you want to include software timer\r
+functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */\r
+#endif /* configUSE_TIMERS == 1 */\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+ >>>NOTE<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+ \r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong? *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+\r
+#ifndef TIMERS_H\r
+#define TIMERS_H\r
+\r
+#ifndef INC_FREERTOS_H\r
+ #error "include FreeRTOS.h must appear in source files before include timers.h"\r
+#endif\r
+\r
+#include "portable.h"\r
+#include "list.h"\r
+#include "task.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* IDs for commands that can be sent/received on the timer queue. These are to\r
+be used solely through the macros that make up the public software timer API,\r
+as defined below. */\r
+#define tmrCOMMAND_START 0\r
+#define tmrCOMMAND_STOP 1\r
+#define tmrCOMMAND_CHANGE_PERIOD 2\r
+#define tmrCOMMAND_DELETE 3\r
+\r
+/*-----------------------------------------------------------\r
+ * MACROS AND DEFINITIONS\r
+ *----------------------------------------------------------*/\r
+\r
+ /**\r
+ * Type by which software timers are referenced. For example, a call to\r
+ * xTimerCreate() returns an xTimerHandle variable that can then be used to\r
+ * reference the subject timer in calls to other software timer API functions\r
+ * (for example, xTimerStart(), xTimerReset(), etc.).\r
+ */\r
+typedef void * xTimerHandle;\r
+\r
+/* Define the prototype to which timer callback functions must conform. */\r
+typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );\r
+\r
+/**\r
+ * xTimerHandle xTimerCreate( const signed char *pcTimerName,\r
+ * portTickType xTimerPeriodInTicks,\r
+ * unsigned portBASE_TYPE uxAutoReload,\r
+ * void * pvTimerID,\r
+ * tmrTIMER_CALLBACK pxCallbackFunction );\r
+ *\r
+ * Creates a new software timer instance. This allocates the storage required\r
+ * by the new timer, initialises the new timers internal state, and returns a\r
+ * handle by which the new timer can be referenced.\r
+ *\r
+ * Timers are created in the dormant state. The xTimerStart(), xTimerReset(),\r
+ * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and\r
+ * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the\r
+ * active state.\r
+ *\r
+ * @param pcTimerName A text name that is assigned to the timer. This is done\r
+ * purely to assist debugging. The kernel itself only ever references a timer by\r
+ * its handle, and never by its name.\r
+ *\r
+ * @param xTimerPeriodInTicks The timer period. The time is defined in tick periods so\r
+ * the constant portTICK_RATE_MS can be used to convert a time that has been\r
+ * specified in milliseconds. For example, if the timer must expire after 100\r
+ * ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer\r
+ * must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS )\r
+ * provided configTICK_RATE_HZ is less than or equal to 1000.\r
+ *\r
+ * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will\r
+ * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If\r
+ * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and\r
+ * enter the dormant state after it expires.\r
+ *\r
+ * @param pvTimerID An identifier that is assigned to the timer being created.\r
+ * Typically this would be used in the timer callback function to identify which\r
+ * timer expired when the same callback function is assigned to more than one\r
+ * timer.\r
+ *\r
+ * @param pxCallbackFunction The function to call when the timer expires.\r
+ * Callback functions must have the prototype defined by tmrTIMER_CALLBACK,\r
+ * which is "void vCallbackFunction( xTimerHandle xTimer );".\r
+ *\r
+ * @return If the timer is successfully create then a handle to the newly\r
+ * created timer is returned. If the timer cannot be created (because either\r
+ * there is insufficient FreeRTOS heap remaining to allocate the timer\r
+ * structures, or the timer period was set to 0) then 0 is returned.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * #define NUM_TIMERS 5\r
+ *\r
+ * // An array to hold handles to the created timers.\r
+ * xTimerHandle xTimers[ NUM_TIMERS ];\r
+ *\r
+ * // An array to hold a count of the number of times each timer expires.\r
+ * long lExpireCounters[ NUM_TIMERS ] = { 0 };\r
+ *\r
+ * // Define a callback function that will be used by multiple timer instances.\r
+ * // The callback function does nothing but count the number of times the\r
+ * // associated timer expires, and stop the timer once the timer has expired\r
+ * // 10 times.\r
+ * void vTimerCallback( xTimerHandle pxTimer )\r
+ * {\r
+ * long lArrayIndex;\r
+ * const long xMaxExpiryCountBeforeStopping = 10;\r
+ *\r
+ * // Optionally do something if the pxTimer parameter is NULL.\r
+ * configASSERT( pxTimer );\r
+ * \r
+ * // Which timer expired?\r
+ * lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );\r
+ *\r
+ * // Increment the number of times that pxTimer has expired.\r
+ * lExpireCounters[ lArrayIndex ] += 1;\r
+ *\r
+ * // If the timer has expired 10 times then stop it from running.\r
+ * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )\r
+ * {\r
+ * // Do not use a block time if calling a timer API function from a\r
+ * // timer callback function, as doing so could cause a deadlock!\r
+ * xTimerStop( pxTimer, 0 );\r
+ * }\r
+ * }\r
+ *\r
+ * void main( void )\r
+ * {\r
+ * long x;\r
+ *\r
+ * // Create then start some timers. Starting the timers before the scheduler\r
+ * // has been started means the timers will start running immediately that\r
+ * // the scheduler starts.\r
+ * for( x = 0; x < NUM_TIMERS; x++ )\r
+ * {\r
+ * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.\r
+ * ( 100 * x ), // The timer period in ticks.\r
+ * pdTRUE, // The timers will auto-reload themselves when they expire.\r
+ * ( void * ) x, // Assign each timer a unique id equal to its array index.\r
+ * vTimerCallback // Each timer calls the same callback when it expires.\r
+ * );\r
+ *\r
+ * if( xTimers[ x ] == NULL )\r
+ * {\r
+ * // The timer was not created.\r
+ * }\r
+ * else\r
+ * {\r
+ * // Start the timer. No block time is specified, and even if one was\r
+ * // it would be ignored because the scheduler has not yet been\r
+ * // started.\r
+ * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )\r
+ * {\r
+ * // The timer could not be set into the Active state.\r
+ * }\r
+ * }\r
+ * }\r
+ *\r
+ * // ...\r
+ * // Create tasks here.\r
+ * // ...\r
+ *\r
+ * // Starting the scheduler will start the timers running as they have already\r
+ * // been set into the active state.\r
+ * xTaskStartScheduler();\r
+ *\r
+ * // Should not reach here.\r
+ * for( ;; );\r
+ * }\r
+ */\r
+xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * void *pvTimerGetTimerID( xTimerHandle xTimer );\r
+ *\r
+ * Returns the ID assigned to the timer.\r
+ *\r
+ * IDs are assigned to timers using the pvTimerID parameter of the call to\r
+ * xTimerCreated() that was used to create the timer.\r
+ *\r
+ * If the same callback function is assigned to multiple timers then the timer\r
+ * ID can be used within the callback function to identify which timer actually\r
+ * expired.\r
+ *\r
+ * @param xTimer The timer being queried.\r
+ *\r
+ * @return The ID assigned to the timer being queried.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * See the xTimerCreate() API function example usage scenario.\r
+ */\r
+void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer );\r
+ *\r
+ * Queries a timer to see if it is active or dormant.\r
+ *\r
+ * A timer will be dormant if:\r
+ * 1) It has been created but not started, or\r
+ * 2) It is an expired on-shot timer that has not been restarted.\r
+ *\r
+ * Timers are created in the dormant state. The xTimerStart(), xTimerReset(),\r
+ * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and\r
+ * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the\r
+ * active state.\r
+ *\r
+ * @param xTimer The timer being queried.\r
+ *\r
+ * @return pdFALSE will be returned if the timer is dormant. A value other than\r
+ * pdFALSE will be returned if the timer is active.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // This function assumes xTimer has already been created.\r
+ * void vAFunction( xTimerHandle xTimer )\r
+ * {\r
+ * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"\r
+ * {\r
+ * // xTimer is active, do something.\r
+ * }\r
+ * else\r
+ * {\r
+ * // xTimer is not active, do something else.\r
+ * }\r
+ * }\r
+ */\r
+portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;\r
+\r
+/**\r
+ * xTimerGetTimerDaemonTaskHandle() is only available if \r
+ * INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.\r
+ *\r
+ * Simply returns the handle of the timer service/daemon task. It it not valid\r
+ * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.\r
+ */\r
+xTaskHandle xTimerGetTimerDaemonTaskHandle( void );\r
+\r
+/**\r
+ * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );\r
+ *\r
+ * Timer functionality is provided by a timer service/daemon task. Many of the\r
+ * public FreeRTOS timer API functions send commands to the timer service task\r
+ * though a queue called the timer command queue. The timer command queue is\r
+ * private to the kernel itself and is not directly accessible to application\r
+ * code. The length of the timer command queue is set by the\r
+ * configTIMER_QUEUE_LENGTH configuration constant.\r
+ *\r
+ * xTimerStart() starts a timer that was previously created using the\r
+ * xTimerCreate() API function. If the timer had already been started and was\r
+ * already in the active state, then xTimerStart() has equivalent functionality\r
+ * to the xTimerReset() API function.\r
+ *\r
+ * Starting a timer ensures the timer is in the active state. If the timer\r
+ * is not stopped, deleted, or reset in the mean time, the callback function\r
+ * associated with the timer will get called 'n' ticks after xTimerStart() was\r
+ * called, where 'n' is the timers defined period.\r
+ *\r
+ * It is valid to call xTimerStart() before the scheduler has been started, but\r
+ * when this is done the timer will not actually start until the scheduler is\r
+ * started, and the timers expiry time will be relative to when the scheduler is\r
+ * started, not relative to when xTimerStart() was called.\r
+ *\r
+ * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart()\r
+ * to be available.\r
+ *\r
+ * @param xTimer The handle of the timer being started/restarted.\r
+ *\r
+ * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * be held in the Blocked state to wait for the start command to be successfully\r
+ * sent to the timer command queue, should the queue already be full when\r
+ * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called\r
+ * before the scheduler is started.\r
+ *\r
+ * @return pdFAIL will be returned if the start command could not be sent to\r
+ * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * be returned if the command was successfully sent to the timer command queue.\r
+ * When the command is actually processed will depend on the priority of the\r
+ * timer service/daemon task relative to other tasks in the system, although the\r
+ * timers expiry time is relative to when xTimerStart() is actually called. The\r
+ * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
+ * configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * See the xTimerCreate() API function example usage scenario.\r
+ *\r
+ */\r
+#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime );\r
+ *\r
+ * Timer functionality is provided by a timer service/daemon task. Many of the\r
+ * public FreeRTOS timer API functions send commands to the timer service task\r
+ * though a queue called the timer command queue. The timer command queue is\r
+ * private to the kernel itself and is not directly accessible to application\r
+ * code. The length of the timer command queue is set by the\r
+ * configTIMER_QUEUE_LENGTH configuration constant.\r
+ *\r
+ * xTimerStop() stops a timer that was previously started using either of the\r
+ * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(),\r
+ * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions.\r
+ *\r
+ * Stopping a timer ensures the timer is not in the active state.\r
+ *\r
+ * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop()\r
+ * to be available.\r
+ *\r
+ * @param xTimer The handle of the timer being stopped.\r
+ *\r
+ * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * be held in the Blocked state to wait for the stop command to be successfully\r
+ * sent to the timer command queue, should the queue already be full when\r
+ * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called\r
+ * before the scheduler is started.\r
+ *\r
+ * @return pdFAIL will be returned if the stop command could not be sent to\r
+ * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * be returned if the command was successfully sent to the timer command queue.\r
+ * When the command is actually processed will depend on the priority of the\r
+ * timer service/daemon task relative to other tasks in the system. The timer\r
+ * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
+ * configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * See the xTimerCreate() API function example usage scenario.\r
+ *\r
+ */\r
+#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer,\r
+ * portTickType xNewPeriod,\r
+ * portTickType xBlockTime );\r
+ *\r
+ * Timer functionality is provided by a timer service/daemon task. Many of the\r
+ * public FreeRTOS timer API functions send commands to the timer service task\r
+ * though a queue called the timer command queue. The timer command queue is\r
+ * private to the kernel itself and is not directly accessible to application\r
+ * code. The length of the timer command queue is set by the\r
+ * configTIMER_QUEUE_LENGTH configuration constant.\r
+ *\r
+ * xTimerChangePeriod() changes the period of a timer that was previously\r
+ * created using the xTimerCreate() API function.\r
+ *\r
+ * xTimerChangePeriod() can be called to change the period of an active or\r
+ * dormant state timer.\r
+ *\r
+ * The configUSE_TIMERS configuration constant must be set to 1 for\r
+ * xTimerChangePeriod() to be available.\r
+ *\r
+ * @param xTimer The handle of the timer that is having its period changed.\r
+ *\r
+ * @param xNewPeriod The new period for xTimer. Timer periods are specified in\r
+ * tick periods, so the constant portTICK_RATE_MS can be used to convert a time\r
+ * that has been specified in milliseconds. For example, if the timer must\r
+ * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,\r
+ * if the timer must expire after 500ms, then xNewPeriod can be set to\r
+ * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than\r
+ * or equal to 1000.\r
+ *\r
+ * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * be held in the Blocked state to wait for the change period command to be\r
+ * successfully sent to the timer command queue, should the queue already be\r
+ * full when xTimerChangePeriod() was called. xBlockTime is ignored if\r
+ * xTimerChangePeriod() is called before the scheduler is started.\r
+ *\r
+ * @return pdFAIL will be returned if the change period command could not be\r
+ * sent to the timer command queue even after xBlockTime ticks had passed.\r
+ * pdPASS will be returned if the command was successfully sent to the timer\r
+ * command queue. When the command is actually processed will depend on the\r
+ * priority of the timer service/daemon task relative to other tasks in the\r
+ * system. The timer service/daemon task priority is set by the\r
+ * configTIMER_TASK_PRIORITY configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // This function assumes xTimer has already been created. If the timer\r
+ * // referenced by xTimer is already active when it is called, then the timer\r
+ * // is deleted. If the timer referenced by xTimer is not active when it is\r
+ * // called, then the period of the timer is set to 500ms and the timer is\r
+ * // started.\r
+ * void vAFunction( xTimerHandle xTimer )\r
+ * {\r
+ * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"\r
+ * {\r
+ * // xTimer is already active - delete it.\r
+ * xTimerDelete( xTimer );\r
+ * }\r
+ * else\r
+ * {\r
+ * // xTimer is not active, change its period to 500ms. This will also\r
+ * // cause the timer to start. Block for a maximum of 100 ticks if the\r
+ * // change period command cannot immediately be sent to the timer\r
+ * // command queue.\r
+ * if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS )\r
+ * {\r
+ * // The command was successfully sent.\r
+ * }\r
+ * else\r
+ * {\r
+ * // The command could not be sent, even after waiting for 100 ticks\r
+ * // to pass. Take appropriate action here.\r
+ * }\r
+ * }\r
+ * }\r
+ */\r
+ #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime );\r
+ *\r
+ * Timer functionality is provided by a timer service/daemon task. Many of the\r
+ * public FreeRTOS timer API functions send commands to the timer service task\r
+ * though a queue called the timer command queue. The timer command queue is\r
+ * private to the kernel itself and is not directly accessible to application\r
+ * code. The length of the timer command queue is set by the\r
+ * configTIMER_QUEUE_LENGTH configuration constant.\r
+ *\r
+ * xTimerDelete() deletes a timer that was previously created using the\r
+ * xTimerCreate() API function.\r
+ *\r
+ * The configUSE_TIMERS configuration constant must be set to 1 for\r
+ * xTimerDelete() to be available.\r
+ *\r
+ * @param xTimer The handle of the timer being deleted.\r
+ *\r
+ * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * be held in the Blocked state to wait for the delete command to be\r
+ * successfully sent to the timer command queue, should the queue already be\r
+ * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()\r
+ * is called before the scheduler is started.\r
+ *\r
+ * @return pdFAIL will be returned if the delete command could not be sent to\r
+ * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * be returned if the command was successfully sent to the timer command queue.\r
+ * When the command is actually processed will depend on the priority of the\r
+ * timer service/daemon task relative to other tasks in the system. The timer\r
+ * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
+ * configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * See the xTimerChangePeriod() API function example usage scenario.\r
+ */\r
+#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime );\r
+ *\r
+ * Timer functionality is provided by a timer service/daemon task. Many of the\r
+ * public FreeRTOS timer API functions send commands to the timer service task\r
+ * though a queue called the timer command queue. The timer command queue is\r
+ * private to the kernel itself and is not directly accessible to application\r
+ * code. The length of the timer command queue is set by the\r
+ * configTIMER_QUEUE_LENGTH configuration constant.\r
+ *\r
+ * xTimerReset() re-starts a timer that was previously created using the\r
+ * xTimerCreate() API function. If the timer had already been started and was\r
+ * already in the active state, then xTimerReset() will cause the timer to\r
+ * re-evaluate its expiry time so that it is relative to when xTimerReset() was\r
+ * called. If the timer was in the dormant state then xTimerReset() has\r
+ * equivalent functionality to the xTimerStart() API function.\r
+ *\r
+ * Resetting a timer ensures the timer is in the active state. If the timer\r
+ * is not stopped, deleted, or reset in the mean time, the callback function\r
+ * associated with the timer will get called 'n' ticks after xTimerReset() was\r
+ * called, where 'n' is the timers defined period.\r
+ *\r
+ * It is valid to call xTimerReset() before the scheduler has been started, but\r
+ * when this is done the timer will not actually start until the scheduler is\r
+ * started, and the timers expiry time will be relative to when the scheduler is\r
+ * started, not relative to when xTimerReset() was called.\r
+ *\r
+ * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset()\r
+ * to be available.\r
+ *\r
+ * @param xTimer The handle of the timer being reset/started/restarted.\r
+ *\r
+ * @param xBlockTime Specifies the time, in ticks, that the calling task should\r
+ * be held in the Blocked state to wait for the reset command to be successfully\r
+ * sent to the timer command queue, should the queue already be full when\r
+ * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called\r
+ * before the scheduler is started.\r
+ *\r
+ * @return pdFAIL will be returned if the reset command could not be sent to\r
+ * the timer command queue even after xBlockTime ticks had passed. pdPASS will\r
+ * be returned if the command was successfully sent to the timer command queue.\r
+ * When the command is actually processed will depend on the priority of the\r
+ * timer service/daemon task relative to other tasks in the system, although the\r
+ * timers expiry time is relative to when xTimerStart() is actually called. The\r
+ * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
+ * configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
+ * // without a key being pressed, then the LCD back-light is switched off. In\r
+ * // this case, the timer is a one-shot timer.\r
+ *\r
+ * xTimerHandle xBacklightTimer = NULL;\r
+ *\r
+ * // The callback function assigned to the one-shot timer. In this case the\r
+ * // parameter is not used.\r
+ * void vBacklightTimerCallback( xTimerHandle pxTimer )\r
+ * {\r
+ * // The timer expired, therefore 5 seconds must have passed since a key\r
+ * // was pressed. Switch off the LCD back-light.\r
+ * vSetBacklightState( BACKLIGHT_OFF );\r
+ * }\r
+ *\r
+ * // The key press event handler.\r
+ * void vKeyPressEventHandler( char cKey )\r
+ * {\r
+ * // Ensure the LCD back-light is on, then reset the timer that is\r
+ * // responsible for turning the back-light off after 5 seconds of\r
+ * // key inactivity. Wait 10 ticks for the command to be successfully sent\r
+ * // if it cannot be sent immediately.\r
+ * vSetBacklightState( BACKLIGHT_ON );\r
+ * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS )\r
+ * {\r
+ * // The reset command was not executed successfully. Take appropriate\r
+ * // action here.\r
+ * }\r
+ *\r
+ * // Perform the rest of the key processing here.\r
+ * }\r
+ *\r
+ * void main( void )\r
+ * {\r
+ * long x;\r
+ *\r
+ * // Create then start the one-shot timer that is responsible for turning\r
+ * // the back-light off if no keys are pressed within a 5 second period.\r
+ * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.\r
+ * ( 5000 / portTICK_RATE_MS), // The timer period in ticks.\r
+ * pdFALSE, // The timer is a one-shot timer.\r
+ * 0, // The id is not used by the callback so can take any value.\r
+ * vBacklightTimerCallback // The callback function that switches the LCD back-light off.\r
+ * );\r
+ *\r
+ * if( xBacklightTimer == NULL )\r
+ * {\r
+ * // The timer was not created.\r
+ * }\r
+ * else\r
+ * {\r
+ * // Start the timer. No block time is specified, and even if one was\r
+ * // it would be ignored because the scheduler has not yet been\r
+ * // started.\r
+ * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )\r
+ * {\r
+ * // The timer could not be set into the Active state.\r
+ * }\r
+ * }\r
+ *\r
+ * // ...\r
+ * // Create tasks here.\r
+ * // ...\r
+ *\r
+ * // Starting the scheduler will start the timer running as it has already\r
+ * // been set into the active state.\r
+ * xTaskStartScheduler();\r
+ *\r
+ * // Should not reach here.\r
+ * for( ;; );\r
+ * }\r
+ */\r
+#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer,\r
+ * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
+ *\r
+ * A version of xTimerStart() that can be called from an interrupt service\r
+ * routine.\r
+ *\r
+ * @param xTimer The handle of the timer being started/restarted.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
+ * of its time in the Blocked state, waiting for messages to arrive on the timer\r
+ * command queue. Calling xTimerStartFromISR() writes a message to the timer\r
+ * command queue, so has the potential to transition the timer service/daemon\r
+ * task out of the Blocked state. If calling xTimerStartFromISR() causes the\r
+ * timer service/daemon task to leave the Blocked state, and the timer service/\r
+ * daemon task has a priority equal to or greater than the currently executing\r
+ * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
+ * get set to pdTRUE internally within the xTimerStartFromISR() function. If\r
+ * xTimerStartFromISR() sets this value to pdTRUE then a context switch should\r
+ * be performed before the interrupt exits.\r
+ *\r
+ * @return pdFAIL will be returned if the start command could not be sent to\r
+ * the timer command queue. pdPASS will be returned if the command was\r
+ * successfully sent to the timer command queue. When the command is actually\r
+ * processed will depend on the priority of the timer service/daemon task\r
+ * relative to other tasks in the system, although the timers expiry time is\r
+ * relative to when xTimerStartFromISR() is actually called. The timer service/daemon\r
+ * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // This scenario assumes xBacklightTimer has already been created. When a\r
+ * // key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
+ * // without a key being pressed, then the LCD back-light is switched off. In\r
+ * // this case, the timer is a one-shot timer, and unlike the example given for\r
+ * // the xTimerReset() function, the key press event handler is an interrupt\r
+ * // service routine.\r
+ *\r
+ * // The callback function assigned to the one-shot timer. In this case the\r
+ * // parameter is not used.\r
+ * void vBacklightTimerCallback( xTimerHandle pxTimer )\r
+ * {\r
+ * // The timer expired, therefore 5 seconds must have passed since a key\r
+ * // was pressed. Switch off the LCD back-light.\r
+ * vSetBacklightState( BACKLIGHT_OFF );\r
+ * }\r
+ *\r
+ * // The key press interrupt service routine.\r
+ * void vKeyPressEventInterruptHandler( void )\r
+ * {\r
+ * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+ *\r
+ * // Ensure the LCD back-light is on, then restart the timer that is\r
+ * // responsible for turning the back-light off after 5 seconds of\r
+ * // key inactivity. This is an interrupt service routine so can only\r
+ * // call FreeRTOS API functions that end in "FromISR".\r
+ * vSetBacklightState( BACKLIGHT_ON );\r
+ *\r
+ * // xTimerStartFromISR() or xTimerResetFromISR() could be called here\r
+ * // as both cause the timer to re-calculate its expiry time.\r
+ * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was\r
+ * // declared (in this function).\r
+ * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
+ * {\r
+ * // The start command was not executed successfully. Take appropriate\r
+ * // action here.\r
+ * }\r
+ *\r
+ * // Perform the rest of the key processing here.\r
+ *\r
+ * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
+ * // should be performed. The syntax required to perform a context switch\r
+ * // from inside an ISR varies from port to port, and from compiler to\r
+ * // compiler. Inspect the demos for the port you are using to find the\r
+ * // actual syntax required.\r
+ * if( xHigherPriorityTaskWoken != pdFALSE )\r
+ * {\r
+ * // Call the interrupt safe yield function here (actual function\r
+ * // depends on the FreeRTOS port being used.\r
+ * }\r
+ * }\r
+ */\r
+#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer,\r
+ * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
+ *\r
+ * A version of xTimerStop() that can be called from an interrupt service\r
+ * routine.\r
+ *\r
+ * @param xTimer The handle of the timer being stopped.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
+ * of its time in the Blocked state, waiting for messages to arrive on the timer\r
+ * command queue. Calling xTimerStopFromISR() writes a message to the timer\r
+ * command queue, so has the potential to transition the timer service/daemon\r
+ * task out of the Blocked state. If calling xTimerStopFromISR() causes the\r
+ * timer service/daemon task to leave the Blocked state, and the timer service/\r
+ * daemon task has a priority equal to or greater than the currently executing\r
+ * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
+ * get set to pdTRUE internally within the xTimerStopFromISR() function. If\r
+ * xTimerStopFromISR() sets this value to pdTRUE then a context switch should\r
+ * be performed before the interrupt exits.\r
+ *\r
+ * @return pdFAIL will be returned if the stop command could not be sent to\r
+ * the timer command queue. pdPASS will be returned if the command was\r
+ * successfully sent to the timer command queue. When the command is actually\r
+ * processed will depend on the priority of the timer service/daemon task\r
+ * relative to other tasks in the system. The timer service/daemon task\r
+ * priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // This scenario assumes xTimer has already been created and started. When\r
+ * // an interrupt occurs, the timer should be simply stopped.\r
+ *\r
+ * // The interrupt service routine that stops the timer.\r
+ * void vAnExampleInterruptServiceRoutine( void )\r
+ * {\r
+ * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+ *\r
+ * // The interrupt has occurred - simply stop the timer.\r
+ * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined\r
+ * // (within this function). As this is an interrupt service routine, only\r
+ * // FreeRTOS API functions that end in "FromISR" can be used.\r
+ * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
+ * {\r
+ * // The stop command was not executed successfully. Take appropriate\r
+ * // action here.\r
+ * }\r
+ *\r
+ * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
+ * // should be performed. The syntax required to perform a context switch\r
+ * // from inside an ISR varies from port to port, and from compiler to\r
+ * // compiler. Inspect the demos for the port you are using to find the\r
+ * // actual syntax required.\r
+ * if( xHigherPriorityTaskWoken != pdFALSE )\r
+ * {\r
+ * // Call the interrupt safe yield function here (actual function\r
+ * // depends on the FreeRTOS port being used.\r
+ * }\r
+ * }\r
+ */\r
+#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer,\r
+ * portTickType xNewPeriod,\r
+ * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
+ *\r
+ * A version of xTimerChangePeriod() that can be called from an interrupt\r
+ * service routine.\r
+ *\r
+ * @param xTimer The handle of the timer that is having its period changed.\r
+ *\r
+ * @param xNewPeriod The new period for xTimer. Timer periods are specified in\r
+ * tick periods, so the constant portTICK_RATE_MS can be used to convert a time\r
+ * that has been specified in milliseconds. For example, if the timer must\r
+ * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,\r
+ * if the timer must expire after 500ms, then xNewPeriod can be set to\r
+ * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than\r
+ * or equal to 1000.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
+ * of its time in the Blocked state, waiting for messages to arrive on the timer\r
+ * command queue. Calling xTimerChangePeriodFromISR() writes a message to the\r
+ * timer command queue, so has the potential to transition the timer service/\r
+ * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR()\r
+ * causes the timer service/daemon task to leave the Blocked state, and the\r
+ * timer service/daemon task has a priority equal to or greater than the\r
+ * currently executing task (the task that was interrupted), then\r
+ * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the\r
+ * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets\r
+ * this value to pdTRUE then a context switch should be performed before the\r
+ * interrupt exits.\r
+ *\r
+ * @return pdFAIL will be returned if the command to change the timers period\r
+ * could not be sent to the timer command queue. pdPASS will be returned if the\r
+ * command was successfully sent to the timer command queue. When the command\r
+ * is actually processed will depend on the priority of the timer service/daemon\r
+ * task relative to other tasks in the system. The timer service/daemon task\r
+ * priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // This scenario assumes xTimer has already been created and started. When\r
+ * // an interrupt occurs, the period of xTimer should be changed to 500ms.\r
+ *\r
+ * // The interrupt service routine that changes the period of xTimer.\r
+ * void vAnExampleInterruptServiceRoutine( void )\r
+ * {\r
+ * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+ *\r
+ * // The interrupt has occurred - change the period of xTimer to 500ms.\r
+ * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined\r
+ * // (within this function). As this is an interrupt service routine, only\r
+ * // FreeRTOS API functions that end in "FromISR" can be used.\r
+ * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
+ * {\r
+ * // The command to change the timers period was not executed\r
+ * // successfully. Take appropriate action here.\r
+ * }\r
+ *\r
+ * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
+ * // should be performed. The syntax required to perform a context switch\r
+ * // from inside an ISR varies from port to port, and from compiler to\r
+ * // compiler. Inspect the demos for the port you are using to find the\r
+ * // actual syntax required.\r
+ * if( xHigherPriorityTaskWoken != pdFALSE )\r
+ * {\r
+ * // Call the interrupt safe yield function here (actual function\r
+ * // depends on the FreeRTOS port being used.\r
+ * }\r
+ * }\r
+ */\r
+#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )\r
+\r
+/**\r
+ * portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer,\r
+ * portBASE_TYPE *pxHigherPriorityTaskWoken );\r
+ *\r
+ * A version of xTimerReset() that can be called from an interrupt service\r
+ * routine.\r
+ *\r
+ * @param xTimer The handle of the timer that is to be started, reset, or\r
+ * restarted.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
+ * of its time in the Blocked state, waiting for messages to arrive on the timer\r
+ * command queue. Calling xTimerResetFromISR() writes a message to the timer\r
+ * command queue, so has the potential to transition the timer service/daemon\r
+ * task out of the Blocked state. If calling xTimerResetFromISR() causes the\r
+ * timer service/daemon task to leave the Blocked state, and the timer service/\r
+ * daemon task has a priority equal to or greater than the currently executing\r
+ * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
+ * get set to pdTRUE internally within the xTimerResetFromISR() function. If\r
+ * xTimerResetFromISR() sets this value to pdTRUE then a context switch should\r
+ * be performed before the interrupt exits.\r
+ *\r
+ * @return pdFAIL will be returned if the reset command could not be sent to\r
+ * the timer command queue. pdPASS will be returned if the command was\r
+ * successfully sent to the timer command queue. When the command is actually\r
+ * processed will depend on the priority of the timer service/daemon task\r
+ * relative to other tasks in the system, although the timers expiry time is\r
+ * relative to when xTimerResetFromISR() is actually called. The timer service/daemon\r
+ * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * // This scenario assumes xBacklightTimer has already been created. When a\r
+ * // key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
+ * // without a key being pressed, then the LCD back-light is switched off. In\r
+ * // this case, the timer is a one-shot timer, and unlike the example given for\r
+ * // the xTimerReset() function, the key press event handler is an interrupt\r
+ * // service routine.\r
+ *\r
+ * // The callback function assigned to the one-shot timer. In this case the\r
+ * // parameter is not used.\r
+ * void vBacklightTimerCallback( xTimerHandle pxTimer )\r
+ * {\r
+ * // The timer expired, therefore 5 seconds must have passed since a key\r
+ * // was pressed. Switch off the LCD back-light.\r
+ * vSetBacklightState( BACKLIGHT_OFF );\r
+ * }\r
+ *\r
+ * // The key press interrupt service routine.\r
+ * void vKeyPressEventInterruptHandler( void )\r
+ * {\r
+ * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+ *\r
+ * // Ensure the LCD back-light is on, then reset the timer that is\r
+ * // responsible for turning the back-light off after 5 seconds of\r
+ * // key inactivity. This is an interrupt service routine so can only\r
+ * // call FreeRTOS API functions that end in "FromISR".\r
+ * vSetBacklightState( BACKLIGHT_ON );\r
+ *\r
+ * // xTimerStartFromISR() or xTimerResetFromISR() could be called here\r
+ * // as both cause the timer to re-calculate its expiry time.\r
+ * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was\r
+ * // declared (in this function).\r
+ * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
+ * {\r
+ * // The reset command was not executed successfully. Take appropriate\r
+ * // action here.\r
+ * }\r
+ *\r
+ * // Perform the rest of the key processing here.\r
+ *\r
+ * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
+ * // should be performed. The syntax required to perform a context switch\r
+ * // from inside an ISR varies from port to port, and from compiler to\r
+ * // compiler. Inspect the demos for the port you are using to find the\r
+ * // actual syntax required.\r
+ * if( xHigherPriorityTaskWoken != pdFALSE )\r
+ * {\r
+ * // Call the interrupt safe yield function here (actual function\r
+ * // depends on the FreeRTOS port being used.\r
+ * }\r
+ * }\r
+ */\r
+#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )\r
+\r
+/*\r
+ * Functions beyond this part are not part of the public API and are intended\r
+ * for use by the kernel only.\r
+ */\r
+portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* TIMERS_H */\r
+\r
+\r
+\r
--- /dev/null
+/*----------------------------------------------------------------------------*/\r
+/* sys_common.h 10/20/10 15:19:19 */\r
+/* */\r
+/* (c) Texas Instruments 2003-2010, All rights reserved. */\r
+/* */\r
+\r
+\r
+#ifndef __sys_common_h__\r
+#define __sys_common_h__\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* NULL */\r
+\r
+#ifndef NULL\r
+#define NULL ((void *) 0)\r
+#endif\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Error Codes */\r
+\r
+#define IO_E_OK 0U\r
+#define IO_E_BUSY 1U\r
+#define IO_E_UNKNOWN_MODE 2U\r
+#define IO_E_OVR 3U\r
+#define IO_E_FCN_SUSPENDED 16U\r
+#define IO_E_PARAM_IGNORED 17U\r
+#define IO_E_INVALID_CHANNEL_ID 18U\r
+#define IO_E_INVALID_VALUE 19U\r
+#define IO_E_INVALID_SIZE 20U\r
+#define IO_E_INVALID_POSITION 21U\r
+#define IO_E_INVALID_NOTIF_TYPE 22U\r
+#define IO_E_MISSING_INIT 64U\r
+#define IO_E_INVALID_GROUP_ID 66U\r
+#define IO_E_INVALID_POINTER 67U\r
+#define IO_E_INVALID_NODE 68U\r
+#define IO_E_INVALID_CAN_ID 69U\r
+#define IO_E_INVALID_OVR 70U\r
+#define IO_E_INVALID_CONFIG 72U\r
+#define IO_E_MISSING_CONNECT 73U\r
+#define IO_E_MISSING_DISCONNECT 74U\r
+#define IO_E_ALREADY_CONNECTED 75U\r
+#define IO_E_GRP_NOTACTIVATED 80U\r
+#define IO_E_INVALID_RESULT 81U\r
+#define IO_E_TIMEOUT 82U\r
+#define IO_E_INVALID_PARITY 83U\r
+#define IO_E_SINGLE_ERROR 84U\r
+#define IO_E_DOUBLE_ERROR 85U\r
+#define IO_E_SINGLE_ERROR_EVEN 86U\r
+#define IO_E_SINGLE_ERROR_ODD 87U\r
+#define IO_E_DOUBLE_ERROR_EVEN 88U\r
+#define IO_E_DOUBLE_ERROR_ODD 89U\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Device Types */\r
+\r
+#define IO_SPI 0U\r
+#define IO_DIO 1U\r
+#define IO_TIM 2U\r
+#define IO_PWM 3U\r
+#define IO_CCU 4U\r
+#define IO_RTI 5U\r
+#define IO_WDT 6U\r
+#define IO_ADC 7U\r
+#define IO_SCI 8U\r
+#define IO_FLS 9U\r
+#define IO_CAN 10U\r
+#define IO_QSPI 11U\r
+#define IO_MSPI 11U\r
+#define IO_LIN 12U\r
+#define IO_CRC 13U\r
+#define IO_DMA 14U\r
+#define IO_HTU 15U\r
+#define IO_PWD 16U\r
+#define IO_HET 17U\r
+#define IO_ESM 18U\r
+#define IO_I2C 19U\r
+#define IO_ECC 20U\r
+#define IO_VIM 21U\r
+#define IO_STC 22U\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Device States */\r
+\r
+#define IO_STATE_IDLE 0U\r
+#define IO_STATE_ACTIVE 1U\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Notification Types */\r
+\r
+#define IO_N_RISING_EDGE 0U\r
+#define IO_N_FALLING_EDGE 1U\r
+#define IO_N_THRESHOLD_1 2U\r
+#define IO_N_THRESHOLD_2 3U\r
+#define IO_N_CAPTURE 4U\r
+#define IO_N_ALL 5U\r
+#define IO_N_ROLLOVER 6U\r
+#define IO_N_READY 7U\r
+#define IO_N_FCN_SUSPENDED 8U\r
+#define IO_N_PARITY_ERROR 9U\r
+#define IO_N_FRAMING_ERROR 10U\r
+#define IO_N_BUFFER_OVERRUN 11U\r
+#define IO_N_RECEIVE 12U\r
+#define IO_N_TRANSMIT 13U\r
+#define IO_N_TX_ERROR 15U\r
+#define IO_N_RX_ERROR 16U\r
+#define IO_N_BAUDRATE_ERROR 17U\r
+#define IO_N_PHASE_ERROR 18U\r
+#define IO_N_OCSET 19U\r
+#define IO_N_OCRESET 20U\r
+#define IO_N_RX_LOST 21U\r
+#define IO_N_ACTIVE 22U\r
+#define IO_N_WARNING 23U\r
+#define IO_N_PASSIVE 24U\r
+#define IO_N_BUS_OFF 25U\r
+#define IO_N_WAKE_UP 26U\r
+#define IO_N_LAST_ERROR 27U\r
+#define IO_N_GRP_READY 30U\r
+#define IO_N_ERROR 31U\r
+#define IO_N_HDR_RECEIVE 32U\r
+#define IO_N_HDR_TRANSMIT 33U\r
+#define IO_N_ID_ERROR 34U\r
+#define IO_N_CHECKSUM_ERROR 35U\r
+#define IO_N_BIT_ERROR 36U\r
+#define IO_N_FRAME_TIMEOUT 37U\r
+#define IO_N_BUS_ERROR 38U\r
+#define IO_N_SYNC_FIELD_ERROR 39U\r
+#define IO_N_WAKE_UP_RECEIVE 40U\r
+#define IO_N_WAKE_UP_TRANSMIT 41U\r
+#define IO_N_ADJUST_BAUDRATE 42U\r
+#define IO_N_BUS_IDLE_TIMEOUT 43U\r
+#define IO_N_WAKE_UP_TIMEOUT 44U\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Programming Interface Constants */\r
+\r
+#define IO_LOW 0U\r
+#define IO_HIGH 1U\r
+#define IO_INVALID 0xFFFFU\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Data Types */\r
+\r
+typedef T_U32 IO_ErrorType;\r
+typedef T_U32 IO_DeviceType;\r
+typedef T_U32 IO_FunctionNrType;\r
+typedef T_U32 IO_DeviceStateType;\r
+typedef T_U32 IO_ChannelType;\r
+typedef T_U32 IO_ModeType;\r
+typedef T_U32 IO_ValueType;\r
+typedef T_U32 IO_U32;\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Error hook */\r
+\r
+void IO_ErrorHook(IO_DeviceType device, IO_ErrorType error);\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* ISR Function Prototypes */\r
+\r
+void IO_PHANTOM_INT(void);\r
+void IO_ESM_INT_HIGH(void);\r
+void IO_TIM0_INT(void);\r
+void IO_TIM1_INT(void);\r
+void IO_DIO_INT_HIGH(void);\r
+void IO_HET_INT_HIGH(void);\r
+void IO_HTU_INT_HIGH(void);\r
+void IO_MIBSPI1_INT_HIGH(void);\r
+void IO_LIN_INT_HIGH(void);\r
+void IO_MIBADC_INT_GROUP0(void);\r
+void IO_MIBADC_INT_GROUP1(void);\r
+void IO_CAN1_INT_HIGH(void);\r
+void IO_SPI2_INT_HIGH(void);\r
+void IO_ESM_INT_LOW(void);\r
+void IO_DIO_INT_LOW(void);\r
+void IO_HET_INT_LOW(void);\r
+void IO_HTU_INT_LOW(void);\r
+void IO_MIBSPI1_INT_LOW(void);\r
+void IO_LIN_INT_LOW(void);\r
+void IO_MIBADC_INT_GROUP2(void);\r
+void IO_CAN1_INT_LOW(void);\r
+void IO_SPI2_INT_LOW(void);\r
+void IO_MIBADC_INT_MAG(void);\r
+void IO_DMA_INT_FTCA(void);\r
+void IO_DMA_INT_LFSA(void);\r
+void IO_CAN2_INT_HIGH(void);\r
+void IO_MIBSPI3_INT_HIGH(void);\r
+void IO_MIBSPI3_INT_LOW(void);\r
+void IO_DMA_INT_HBCA(void);\r
+void IO_DMA_INT_BTCA(void);\r
+void IO_CAN2_INT_LOW(void);\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Notification Function Prototypes */\r
+\r
+\r
+#endif\r
+/*----------------------------------------------------------------------------*/\r
+\r
--- /dev/null
+;-------------------------------------------------------------------------------\r
+; sys_core.asm\r
+;\r
+; (c) Texas Instruments 2009, All rights reserved.\r
+;\r
+\r
+ .text\r
+ .arm\r
+\r
+;-------------------------------------------------------------------------------\r
+; Initialize CPU Registers\r
+\r
+ .def _coreInitRegisters\r
+\r
+_coreInitRegisters:\r
+ mov r0, lr\r
+ mov r1, #0x0000\r
+ mov r2, #0x0000\r
+ mov r3, #0x0000\r
+ mov r4, #0x0000\r
+ mov r5, #0x0000\r
+ mov r6, #0x0000\r
+ mov r7, #0x0000\r
+ mov r8, #0x0000\r
+ mov r9, #0x0000\r
+ mov r10, #0x0000\r
+ mov r11, #0x0000\r
+ mov r12, #0x0000\r
+ mov r13, #0x0000\r
+ cps #0x11 \r
+ mov lr, r0\r
+ mov r8, #0x0000\r
+ mov r9, #0x0000\r
+ mov r10, #0x0000\r
+ mov r11, #0x0000\r
+ mov r12, #0x0000\r
+ mov r13, #0x0000\r
+ cps #0x12 \r
+ mov r13, #0x0000\r
+ mov lr, r0\r
+ cps #0x17\r
+ mov r13, #0x0000\r
+ mov lr, r0\r
+ cps #0x1B\r
+ mov r13, #0x0000\r
+ mov lr, r0\r
+ cps #0x13\r
+ mov r13, #0x0000\r
+\r
+ .if (__TI_VFPV3D16_SUPPORT__)\r
+ fmdrr d0, r1, r1\r
+ fmdrr d1, r1, r1\r
+ fmdrr d2, r1, r1\r
+ fmdrr d3, r1, r1\r
+ fmdrr d4, r1, r1\r
+ fmdrr d5, r1, r1\r
+ fmdrr d6, r1, r1\r
+ fmdrr d7, r1, r1\r
+ fmdrr d8, r1, r1\r
+ fmdrr d9, r1, r1\r
+ fmdrr d10, r1, r1\r
+ fmdrr d11, r1, r1\r
+ fmdrr d12, r1, r1\r
+ fmdrr d13, r1, r1\r
+ fmdrr d14, r1, r1\r
+ fmdrr d15, r1, r1\r
+ .endif\r
+\r
+ bl $+4\r
+ bl $+4\r
+ bl $+4\r
+ bl $+4\r
+ bx r0\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
+; Initialize Stack Pointers\r
+\r
+ .def _coreInitStackPointer\r
+\r
+_coreInitStackPointer:\r
+ msr cpsr_c, #0xD1\r
+ ldr sp, fiqSp\r
+ msr cpsr_c, #0xD2\r
+ ldr sp, irqSp\r
+ msr cpsr_c, #0xD7\r
+ ldr sp, abortSp\r
+ msr cpsr_c, #0xDB\r
+ ldr sp, undefSp\r
+ msr cpsr_c, #0xDF\r
+ ldr sp, userSp\r
+ msr cpsr_c, #0xD3\r
+ ldr sp, svcSp\r
+ bx lr\r
+\r
+userSp .word 0x00000000+0x00000000\r
+svcSp .word 0x08000000+0x00000100\r
+fiqSp .word 0x00000000+0x00000000\r
+irqSp .word 0x08000100+0x00000100\r
+abortSp .word 0x00000000+0x00000000\r
+undefSp .word 0x00000000+0x00000000\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
+; Enable VFP Unit\r
+\r
+ .def _coreEnableVfp\r
+\r
+_coreEnableVfp:\r
+ .if (__TI_VFPV3D16_SUPPORT__)\r
+ mrc p15, #0x00, r0, c1, c0, #0x02\r
+ orr r0, r0, #0xF00000\r
+ mcr p15, #0x00, r0, c1, c0, #0x02\r
+ mov r0, #0x40000000\r
+ fmxr fpexc, r0\r
+ .endif\r
+ bx lr\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
+; Enable Event Bus Export\r
+\r
+ .def _coreEnableEventBusExport\r
+\r
+_coreEnableEventBusExport:\r
+ mrc p15, #0x00, r0, c9, c12, #0x00\r
+ orr r0, r0, #0x10\r
+ mcr p15, #0x00, r0, c9, c12, #0x00\r
+ bx lr\r
+\r
+;-------------------------------------------------------------------------------\r
+; Enable RAM ECC Support\r
+\r
+ .def _coreEnableRamEcc\r
+\r
+_coreEnableRamEcc:\r
+ mrc p15, #0x00, r0, c1, c0, #0x01\r
+ orr r0, r0, #0x0C000000\r
+ mcr p15, #0x00, r0, c1, c0, #0x01\r
+ bx lr\r
+\r
+;-------------------------------------------------------------------------------\r
+; Enable Flash ECC Support\r
+\r
+ .def _coreEnableFlashEcc\r
+\r
+_coreEnableFlashEcc:\r
+ mrc p15, #0x00, r0, c1, c0, #0x01\r
+ orr r0, r0, #0x02000000\r
+ mcr p15, #0x00, r0, c1, c0, #0x01\r
+ bx lr\r
+\r
+;-------------------------------------------------------------------------------\r
+; Enable Offset via Vic controller\r
+\r
+ .def _coreEnableIrqVicOffset\r
+\r
+_coreEnableIrqVicOffset:\r
+ mrc p15, #0, r0, c1, c0, #0\r
+ orr r0, r0, #0x01000000\r
+ mcr p15, #0, r0, c1, c0, #0\r
+ bx lr\r
+ \r
+;-------------------------------------------------------------------------------\r
+\r
--- /dev/null
+/** @file sys_core.h\r
+* @brief System Core Header File\r
+* @date 23.July.2009\r
+* @version 1.00.000\r
+* \r
+* This file contains:\r
+* - Core Interface Functions\r
+* .\r
+* which are relevant for the System driver.\r
+*/\r
+\r
+/* (c) Texas Instruments 2009, All rights reserved. */\r
+\r
+#ifndef __SYS_CORE_H__\r
+#define __SYS_CORE_H__\r
+\r
+/* System Core Interface Functions */\r
+\r
+/** @fn void _coreInitRegisters_(void)\r
+* @brief Initialize Core register\r
+*/\r
+void _coreInitRegisters(void);\r
+\r
+/** @fn void _coreInitStackPointer_(void)\r
+* @brief Initialize Core stack pointer\r
+*/\r
+void _coreInitStackPointer(void);\r
+\r
+/** @fn void _coreEnableIrqVicOffset_(void)\r
+* @brief Enable Irq offset propagation via Vic controller\r
+*/\r
+void _coreEnableIrqVicOffset(void);\r
+\r
+\r
+/** @fn void _coreEnableEventBusExport_(void)\r
+* @brief Enable event bus export for external monitoring modules\r
+* @note It is required to enable event bus export to process ecc issues.\r
+*\r
+* This function enables event bus exports to external monitoring modules\r
+* like tightly coupled RAM wrapper, Flash wrapper and error signaling module.\r
+*/\r
+void _coreEnableEventBusExport(void);\r
+\r
+/** @fn void _coreEnableRamEcc_(void)\r
+* @brief Enable external ecc error for RAM odd and even bank\r
+* @note It is required to enable event bus export to process ecc issues.\r
+*/\r
+void _coreEnableRamEcc(void);\r
+\r
+/** @fn void _coreEnableFlashEcc_(void)\r
+* @brief Enable external ecc error for the Flash\r
+* @note It is required to enable event bus export to process ecc issues.\r
+*/\r
+void _coreEnableFlashEcc(void);\r
+\r
+/** @fn void _coreEnableVfp(void)\r
+* @brief Enable Cortex-R4 FPU\r
+*/\r
+void _coreEnableVfp();\r
+\r
+#endif\r
--- /dev/null
+;-------------------------------------------------------------------------------\r
+; sys_intvecs.asm\r
+;\r
+; (c) Texas Instruments 2009-2010, All rights reserved.\r
+;\r
+\r
+ .sect ".intvecs"\r
+\r
+;-------------------------------------------------------------------------------\r
+; import reference for interrupt routines\r
+\r
+ .ref _c_int00\r
+ .ref vPortYieldProcessor\r
+\r
+;-------------------------------------------------------------------------------\r
+; interrupt vectors\r
+\r
+ b _c_int00\r
+ b #-8\r
+ b vPortYieldProcessor\r
+ b #-8\r
+ b #-8\r
+ b #-8\r
+ ldr pc,[pc,#-0x1b0]\r
+ ldr pc,[pc,#-0x1b0]\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
--- /dev/null
+;-------------------------------------------------------------------------------\r
+; sys_memory.asm\r
+;\r
+; (c) Texas Instruments 2009, All rights reserved.\r
+;\r
+\r
+ .text\r
+ .arm\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
+; Initialize memory\r
+\r
+ .def _memoryInit\r
+\r
+_memoryInit:\r
+ ldr r12, regMinitGcr ; MINITGCR register pointer \r
+ mov r4, #0xA\r
+ str r4, [r12]\r
+ ldr r4, ramInitMask ; load RAM initialization mask\r
+ str r4, [r12, #4]\r
+mloop\r
+ ldr r5, [r12, #12]\r
+ tst r5, #0x100\r
+ beq mloop\r
+ mov r4, #5\r
+ str r4, [r12]\r
+ bx lr\r
+ \r
+ramInitMask .word 0x00000001\r
+regMinitGcr .word 0xFFFFFF5C\r
+\r
+ \r
+\r
+;-------------------------------------------------------------------------------\r
+\r
--- /dev/null
+/** @file sys_memory.h\r
+* @brief System Memory Header File\r
+* @date 23.July.2009\r
+* @version 1.00.000\r
+* \r
+* This file contains:\r
+* - Memory Interface Functions\r
+* .\r
+* which are relevant for the System driver.\r
+*/\r
+\r
+/* (c) Texas Instruments 2009, All rights reserved. */\r
+\r
+#ifndef __SYS_MEMORY_H__\r
+#define __SYS_MEMORY_H__\r
+\r
+/** @fn void _memoryInit_(void)\r
+* @brief Automatic hardware memory initialization\r
+*/\r
+void _memoryInit(void);\r
+\r
+#endif\r
--- /dev/null
+/** @file sys_phantom.c \r
+* @brief Phantom Interrupt Source File\r
+* @date 15.July.2009\r
+* @version 1.00.000\r
+*\r
+* This file contains:\r
+* - Phantom Interrupt Handler\r
+*/\r
+\r
+/* (c) Texas Instruments 2009, All rights reserved. */\r
+\r
+/* Phantom Interrupt Handler */\r
+\r
+#pragma INTERRUPT(phantomInterrupt, IRQ)\r
+\r
+void phantomInterrupt(void)\r
+{\r
+ for(;;);\r
+}\r
--- /dev/null
+/** @file sys_startup.c \r
+* @brief Startup Source File\r
+* @date 05.November.2010\r
+* @version 1.01.001\r
+*\r
+* This file contains:\r
+* - Include Files\r
+* - Type Definitions\r
+* - External Functions\r
+* - VIM RAM Setup\r
+* - Startup Routine\r
+* .\r
+* which are relevant for the Starup.\r
+*/\r
+\r
+/* (c) Texas Instruments 2010, All rights reserved. */\r
+\r
+/* Include Files */\r
+\r
+#include "sys_types.h"\r
+#include "sys_common.h"\r
+#include "sys_system.h"\r
+#include "sys_vim.h"\r
+#include "sys_core.h"\r
+#include "sys_memory.h"\r
+\r
+\r
+/* External Functions */\r
+\r
+extern void __TI_auto_init(void);\r
+extern void main(void);\r
+extern void exit(int);\r
+\r
+/* Vim Ram Definition */\r
+/** @struct vimRam\r
+* @brief Vim Ram Definition\r
+*\r
+* This type is used to access the Vim Ram.\r
+*/\r
+/** @typedef vimRAM_t\r
+* @brief Vim Ram Type Definition\r
+*\r
+* This type is used to access the Vim Ram.\r
+*/\r
+typedef volatile struct vimRam\r
+{\r
+ t_isrFuncPTR ISR[VIM_CHANNELS];\r
+} vimRAM_t;\r
+\r
+#define vimRAM ((vimRAM_t *)0xFFF82000U)\r
+\r
+static const t_isrFuncPTR s_vim_init[] =\r
+{\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ vPreemptiveTick, /* RTI */\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ vPortYeildWithinAPI, /* software interrupt */\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+ phantomInterrupt,\r
+};\r
+\r
+\r
+/* Startup Routine */\r
+\r
+#pragma INTERRUPT(_c_int00, RESET)\r
+\r
+void _c_int00()\r
+{\r
+ /* Enable VFP Unit */\r
+ _coreEnableVfp();\r
+\r
+ /* Initialize Core Registers */\r
+ _coreInitRegisters();\r
+\r
+ /* Initialize Stack Pointers */\r
+ _coreInitStackPointer();\r
+\r
+ /* Enable IRQ offset via Vic controller */\r
+ _coreEnableIrqVicOffset();\r
+\r
+ /* Initialize System */\r
+ systemInit();\r
+\r
+ /* Initialize VIM table */\r
+ {\r
+ unsigned i;\r
+\r
+ for (i = 0; i < 96U; i++)\r
+ {\r
+ vimRAM->ISR[i] = s_vim_init[i];\r
+ }\r
+ }\r
+\r
+ /* set IRQ/FIQ priorities */\r
+ vimREG->FIRQPR0 = SYS_FIQ\r
+ | (SYS_FIQ << 1U)\r
+ | (SYS_IRQ << 2U)\r
+ | (SYS_IRQ << 3U)\r
+ | (SYS_IRQ << 4U)\r
+ | (SYS_IRQ << 5U)\r
+ | (SYS_IRQ << 6U)\r
+ | (SYS_IRQ << 7U)\r
+ | (SYS_IRQ << 8U)\r
+ | (SYS_IRQ << 9U)\r
+ | (SYS_IRQ << 10U)\r
+ | (SYS_IRQ << 11U)\r
+ | (SYS_IRQ << 12U)\r
+ | (SYS_IRQ << 13U)\r
+ | (SYS_IRQ << 14U)\r
+ | (SYS_IRQ << 15U)\r
+ | (SYS_IRQ << 16U)\r
+ | (SYS_IRQ << 17U)\r
+ | (SYS_IRQ << 18U)\r
+ | (SYS_IRQ << 19U)\r
+ | (SYS_IRQ << 20U)\r
+ | (SYS_IRQ << 21U)\r
+ | (SYS_IRQ << 22U)\r
+ | (SYS_IRQ << 23U)\r
+ | (SYS_IRQ << 24U)\r
+ | (SYS_IRQ << 25U)\r
+ | (SYS_IRQ << 26U)\r
+ | (SYS_IRQ << 27U)\r
+ | (SYS_IRQ << 28U)\r
+ | (SYS_IRQ << 29U)\r
+ | (SYS_IRQ << 30U)\r
+ | (SYS_IRQ << 31U);\r
+\r
+ vimREG->FIRQPR1 = SYS_IRQ\r
+ | (SYS_IRQ << 1U)\r
+ | (SYS_IRQ << 2U)\r
+ | (SYS_IRQ << 3U)\r
+ | (SYS_IRQ << 4U)\r
+ | (SYS_IRQ << 5U)\r
+ | (SYS_IRQ << 6U)\r
+ | (SYS_IRQ << 7U)\r
+ | (SYS_IRQ << 8U)\r
+ | (SYS_IRQ << 9U)\r
+ | (SYS_IRQ << 10U)\r
+ | (SYS_IRQ << 11U)\r
+ | (SYS_IRQ << 12U)\r
+ | (SYS_IRQ << 13U)\r
+ | (SYS_IRQ << 14U)\r
+ | (SYS_IRQ << 15U)\r
+ | (SYS_IRQ << 16U)\r
+ | (SYS_IRQ << 17U)\r
+ | (SYS_IRQ << 18U)\r
+ | (SYS_IRQ << 19U)\r
+ | (SYS_IRQ << 20U)\r
+ | (SYS_IRQ << 21U)\r
+ | (SYS_IRQ << 22U)\r
+ | (SYS_IRQ << 23U)\r
+ | (SYS_IRQ << 24U)\r
+ | (SYS_IRQ << 25U)\r
+ | (SYS_IRQ << 26U)\r
+ | (SYS_IRQ << 27U)\r
+ | (SYS_IRQ << 28U)\r
+ | (SYS_IRQ << 29U)\r
+ | (SYS_IRQ << 30U);\r
+\r
+ /* enable interrupts */\r
+ vimREG->REQMASKSET0 = 1U\r
+ | (0U << 1)\r
+ | (1U << 2) /* RTI */\r
+ | (0U << 3)\r
+ | (0U << 4)\r
+ | (0U << 5)\r
+ | (0U << 6)\r
+ | (0U << 7)\r
+ | (0U << 8)\r
+ | (0U << 9)\r
+ | (0U << 10)\r
+ | (0U << 11)\r
+ | (0U << 12)\r
+ | (0U << 13)\r
+ | (0U << 14)\r
+ | (0U << 15)\r
+ | (0U << 16)\r
+ | (0U << 17)\r
+ | (0U << 18)\r
+ | (0U << 19)\r
+ | (0U << 20)\r
+ | (1U << 21) /* Software Interrupt */\r
+ | (0U << 22)\r
+ | (0U << 23)\r
+ | (0U << 24)\r
+ | (0U << 25)\r
+ | (0U << 26)\r
+ | (0U << 27)\r
+ | (0U << 28)\r
+ | (0U << 29)\r
+ | (0U << 30)\r
+ | (0U << 31);\r
+\r
+ vimREG->REQMASKSET1 = 0U\r
+ | (0U << 1)\r
+ | (0U << 2)\r
+ | (0U << 3)\r
+ | (0U << 4)\r
+ | (0U << 5)\r
+ | (0U << 6)\r
+ | (0U << 7)\r
+ | (0U << 8)\r
+ | (0U << 9)\r
+ | (0U << 10)\r
+ | (0U << 11)\r
+ | (0U << 12)\r
+ | (0U << 13)\r
+ | (0U << 14)\r
+ | (0U << 15)\r
+ | (0U << 16)\r
+ | (0U << 17)\r
+ | (0U << 18)\r
+ | (0U << 19)\r
+ | (0U << 20)\r
+ | (0U << 21)\r
+ | (0U << 22)\r
+ | (0U << 23)\r
+ | (0U << 24)\r
+ | (0U << 25)\r
+ | (0U << 26)\r
+ | (0U << 27)\r
+ | (0U << 28)\r
+ | (0U << 29)\r
+ | (0U << 30);\r
+\r
+\r
+ /* initalise global variable and constructors */\r
+ __TI_auto_init();\r
+\r
+ /* call the application */\r
+ main();\r
+ exit(0);\r
+}\r
--- /dev/null
+/** @file system.c \r
+* @brief System Driver Source File\r
+* @date 05.November.2010\r
+* @version 1.01.000\r
+*\r
+* This file contains:\r
+* - API Funcions\r
+* .\r
+* which are relevant for the System driver.\r
+*/\r
+\r
+/* (c) Texas Instruments 2010, All rights reserved. */\r
+\r
+\r
+/* Include Files */\r
+\r
+#include "sys_system.h"\r
+\r
+\r
+/** @fn void systemInit(void)\r
+* @brief Initializes System Driver\r
+*\r
+* This function initializes the System driver.\r
+*\r
+*/\r
+\r
+\r
+void systemInit(void)\r
+{\r
+ /** @b Initialize @b Flash @b Wrapper: */\r
+\r
+ /** - Setup flash read mode, address wait states and data wait states */\r
+ flashWREG->FRDCNTL = 0x01000000U \r
+ | (3U << 8U) \r
+ | (1U << 4U) \r
+ | 1U;\r
+#if 0\r
+ /** - Setup flash bank power modes */\r
+ flashWREG->FBFALLBACK = 0x05050000\r
+ | (SYS_ACTIVE << 14U) \r
+ | (SYS_SLEEP << 12U) \r
+ | (SYS_SLEEP << 10U) \r
+ | (SYS_SLEEP << 8U) \r
+ | (SYS_SLEEP << 6U) \r
+ | (SYS_SLEEP << 4U) \r
+ | (SYS_ACTIVE << 2U) \r
+ | SYS_ACTIVE;\r
+\r
+ /** @b Initialize @b Lpo: */\r
+\r
+ {\r
+ unsigned trim = *(volatile unsigned short *)0xF00801B4;\r
+ \r
+ if (trim != 0xFFFF)\r
+ {\r
+ systemREG1->LPOMONCTL = (1U << 24U) \r
+ | (0U << 16U) \r
+ | trim; \r
+ }\r
+ else\r
+ {\r
+ systemREG1->LPOMONCTL = (1U << 24U) \r
+ | (0U << 16U) \r
+ | (systemREG1->LPOMONCTL & 0xFFFF);\r
+ }\r
+ }\r
+#endif\r
+ /** @b Initialize @b Pll: */\r
+\r
+ /** - Setup pll control register 1:\r
+ * - Setup reset on oscillator slip \r
+ * - Setup bypass on pll slip\r
+ * - Setup Pll output clock divider\r
+ * - Setup reset on oscillator fail\r
+ * - Setup reference clock divider \r
+ * - Setup Pll multiplier \r
+ */\r
+\r
+#if 0\r
+ /* 180Mhz */\r
+ systemREG1->PLLCTL1 = 0x00000000U \r
+ | 0x20000000U \r
+ | (0U << 24U) \r
+ | 0x00000000U \r
+ | (5U << 16U) \r
+ | (134U << 8U);\r
+#endif\r
+\r
+#if 1\r
+ /* 160Mhz */\r
+ systemREG1->PLLCTL1 = 0x00000000U\r
+ | 0x20000000U\r
+ | (0U << 24U)\r
+ | 0x00000000U\r
+ | (5U << 16U)\r
+ | (113U << 8U);\r
+#endif\r
+\r
+ /** - Setup pll control register 1 \r
+ * - Enable/Disable frequency modulation\r
+ * - Setup spreading rate\r
+ * - Setup bandwidth adjustment\r
+ * - Setup internal Pll output divider\r
+ * - Setup spreading amount\r
+ */\r
+ systemREG1->PLLCTL2 = 0x00000000U\r
+ | (255U << 22U)\r
+ | (7U << 12U)\r
+ | (1U << 9U)\r
+ | 61U;\r
+\r
+\r
+ /** @b Initialize @b Clock @b Tree: */\r
+\r
+ /** - Start clock source lock */\r
+ systemREG1->CSDISCLR = 0x00000000U\r
+ | 0x00000000U \r
+ | 0x00000000U \r
+ | 0x00000000U \r
+ | 0x00000002U; \r
+\r
+ /** - Wait for until clocks are locked */\r
+ while ((systemREG1->CSVSTAT & 0x00000002U) == 0x00); /* wait for PLL */\r
+\r
+ /** - Setup GCLK, HCLK and VCLK clock source for normal operation, power down mode and after wakeup */\r
+ systemREG1->GHVSRC = (SYS_PLL << 24U) \r
+ | (SYS_PLL << 16U) \r
+ | SYS_PLL;\r
+\r
+ /** - Power-up all peripharals */\r
+ pcrREG->PSPWRDWNCLR0 = 0xFFFFFFFFU;\r
+ pcrREG->PSPWRDWNCLR1 = 0xFFFFFFFFU;\r
+ pcrREG->PSPWRDWNCLR2 = 0xFFFFFFFFU;\r
+ pcrREG->PSPWRDWNCLR3 = 0xFFFFFFFFU;\r
+\r
+ /** - Setup synchronous peripheral clock dividers for VCLK1 and VCLK2 */\r
+ systemREG1->PENA = 0U;\r
+ systemREG1->VCLKR = 15U;\r
+ systemREG1->VCLK2R = 1U;\r
+ systemREG1->VCLKR = 1U;\r
+\r
+ systemREG2->CLK2CNTRL = (1U << 8U)\r
+ | 1U;\r
+\r
+ /** - Setup RTICLK1 and RTICLK2 clocks */\r
+ systemREG1->RCLKSRC = (1U << 24U)\r
+ | (SYS_VCLK << 16U) \r
+ | (1U << 8U) \r
+ | SYS_VCLK;\r
+\r
+ /** - Setup asynchronous peripheral clock sources for AVCLK1 and AVCLK2 */\r
+ systemREG1->VCLKASRC = (SYS_FR_PLL << 8U)\r
+ | SYS_VCLK;\r
+\r
+ /** - Setup asynchronous peripheral clock sources for AVCLK3 and AVCLK4 */\r
+ systemREG2->VCLKACON1 = (0U << 24U)\r
+ | (0U << 20U)\r
+ | (SYS_EXTERNAL2 << 16U)\r
+ | (3U << 8U)\r
+ | (0U << 4U)\r
+ | SYS_EXTERNAL;\r
+\r
+ /** - Enable Peripherals */\r
+ systemREG1->PENA = 1U;\r
+\r
+ /** @note: HCLK >= VCLK2 >= VCLK_sys */\r
+}\r
+\r
--- /dev/null
+/** @file system.h\r
+* @brief System Driver Header File\r
+* @date 23.July.2009\r
+* @version 1.01.001\r
+* \r
+* This file contains:\r
+* - Definitions\r
+* - Types\r
+* .\r
+* which are relevant for the System driver.\r
+*/\r
+\r
+/* (c) Texas Instruments 2009-2010, All rights reserved. */\r
+\r
+#ifndef __SYS_SYSTEM_H__\r
+#define __SYS_SYSTEM_H__\r
+\r
+\r
+/* USER CODE BEGIN (0) */\r
+/* USER CODE END */\r
+\r
+\r
+/* System General Definitions */\r
+\r
+/** @enum systemInterrupt\r
+* @brief Alias names for clock sources\r
+*\r
+* This enumeration is used to provide alias names for the clock sources:\r
+* - IRQ\r
+* - FIQ\r
+*/\r
+enum systemInterrupt\r
+{\r
+ SYS_IRQ, /**< Alias for IRQ interrupt */\r
+ SYS_FIQ /**< Alias for FIQ interrupt */\r
+};\r
+\r
+/** @enum systemClockSource\r
+* @brief Alias names for clock sources\r
+*\r
+* This enumeration is used to provide alias names for the clock sources:\r
+* - Oscillator\r
+* - Pll\r
+* - 32 kHz Oscillator\r
+* - External1\r
+* - Low Power Oscillator Low\r
+* - Low Power Oscillator High\r
+* - Flexray Pll\r
+* - External2\r
+* - Synchronous VCLK1\r
+*/\r
+enum systemClockSource\r
+{\r
+ SYS_OSC = 0, /**< Alias for oscillator clock Source */\r
+ SYS_PLL = 1, /**< Alias for Pll clock Source */\r
+ SYS_O32 = 2, /**< Alias for 32 kHz oscillator clock Source */\r
+ SYS_EXTERNAL = 3, /**< Alias for external clock Source */\r
+ SYS_LPO_LOW = 4, /**< Alias for low power oscillator low clock Source */\r
+ SYS_LPO_HIGH = 5, /**< Alias for low power oscillator high clock Source */\r
+ SYS_FR_PLL = 6, /**< Alias for flexray pll clock Source */\r
+ SYS_EXTERNAL2 = 7, /**< Alias for external 2 clock Source */\r
+ SYS_VCLK = 9 /**< Alias for synchronous VCLK1 clock Source */\r
+};\r
+\r
+#define SYS_DOZE_MODE 0x000F3F02U\r
+#define SYS_SNOOZE_MODE 0x000F3F03U\r
+#define SYS_SLEEP_MODE 0x000FFFFFU\r
+\r
+\r
+/** @def SYS_PRE1\r
+* @brief Alias name for RTI1CLK PRE clock source\r
+*\r
+* This is an alias name for the RTI1CLK pre clock source.\r
+* This can be either:\r
+* - Oscillator\r
+* - Pll\r
+* - 32 kHz Oscillator\r
+* - External\r
+* - Low Power Oscillator Low\r
+* - Low Power Oscillator High\r
+* - Flexray Pll\r
+*/\r
+#define SYS_PRE1 SYS_PLL\r
+\r
+/** @def SYS_PRE2\r
+* @brief Alias name for RTI2CLK pre clock source\r
+*\r
+* This is an alias name for the RTI2CLK pre clock source.\r
+* This can be either:\r
+* - Oscillator\r
+* - Pll\r
+* - 32 kHz Oscillator\r
+* - External\r
+* - Low Power Oscillator Low\r
+* - Low Power Oscillator High\r
+* - Flexray Pll\r
+*/\r
+#define SYS_PRE2 SYS_PLL\r
+\r
+/* USER CODE BEGIN (1) */\r
+/* USER CODE END */\r
+\r
+\r
+/* System Register Frame 1 Definition */\r
+/** @struct systemBase1\r
+* @brief System Register Frame 1 Definition\r
+*\r
+* This type is used to access the System 1 Registers.\r
+*/\r
+/** @typedef systemBASE1_t\r
+* @brief System Register Frame 1 Type Definition\r
+*\r
+* This type is used to access the System 1 Registers.\r
+*/\r
+typedef volatile struct systemBase1\r
+{\r
+ unsigned SYSPC1; /* 0x0000 */\r
+ unsigned SYSPC2; /* 0x0004 */\r
+ unsigned SYSPC3; /* 0x0008 */\r
+ unsigned SYSPC4; /* 0x000C */\r
+ unsigned SYSPC5; /* 0x0010 */\r
+ unsigned SYSPC6; /* 0x0014 */\r
+ unsigned SYSPC7; /* 0x0018 */\r
+ unsigned SYSPC8; /* 0x001C */\r
+ unsigned SYSPC9; /* 0x0020 */\r
+ unsigned SSWPLL1; /* 0x0024 */\r
+ unsigned SSWPLL2; /* 0x0028 */\r
+ unsigned SSWPLL3; /* 0x002C */\r
+ unsigned CSDIS; /* 0x0030 */\r
+ unsigned CSDISSET; /* 0x0034 */\r
+ unsigned CSDISCLR; /* 0x0038 */\r
+ unsigned CSDDIS; /* 0x003C */\r
+ unsigned CSDDISSET; /* 0x0040 */\r
+ unsigned CSDDISCLR; /* 0x0044 */\r
+ unsigned GHVSRC; /* 0x0048 */\r
+ unsigned VCLKASRC; /* 0x004C */\r
+ unsigned RCLKSRC; /* 0x0050 */\r
+ unsigned CSVSTAT; /* 0x0054 */\r
+ unsigned MSTGCR; /* 0x0058 */\r
+ unsigned MINITGCR; /* 0x005C */\r
+ unsigned MSINENA; /* 0x0060 */\r
+ unsigned MSTFAIL; /* 0x0064 */\r
+ unsigned MSTCGSTAT; /* 0x0068 */\r
+ unsigned MINISTAT; /* 0x006C */\r
+ unsigned PLLCTL1; /* 0x0070 */\r
+ unsigned PLLCTL2; /* 0x0074 */\r
+ unsigned UERFLAG; /* 0x0078 */\r
+ unsigned DIEIDL; /* 0x007C */\r
+ unsigned DIEIDH; /* 0x0080 */\r
+ unsigned VRCTL; /* 0x0084 */\r
+ unsigned LPOMONCTL; /* 0x0088 */\r
+ unsigned CLKTEST; /* 0x008C */\r
+ unsigned DFTCTRLREG1; /* 0x0090 */\r
+ unsigned DFTCTRLREG2; /* 0x0094 */\r
+ unsigned : 32U; /* 0x0098 */\r
+ unsigned : 32U; /* 0x009C */\r
+ unsigned GPREG1; /* 0x00A0 */\r
+ unsigned BTRMSEL; /* 0x00A4 */\r
+ unsigned IMPFASTS; /* 0x00A8 */\r
+ unsigned IMPFTADD; /* 0x00AC */\r
+ unsigned SSISR1; /* 0x00B0 */\r
+ unsigned SSISR2; /* 0x00B4 */\r
+ unsigned SSISR3; /* 0x00B8 */\r
+ unsigned SSISR4; /* 0x00BC */\r
+ unsigned RAMGCR; /* 0x00C0 */\r
+ unsigned BMMCR1; /* 0x00C4 */\r
+ unsigned BMMCR2; /* 0x00C8 */\r
+ unsigned MMUGCR; /* 0x00CC */\r
+#ifdef _little_endian__\r
+ unsigned : 8U; /* 0x00D0 */\r
+ unsigned PENA : 1U; /* 0x00D0 */\r
+ unsigned : 7U; /* 0x00D0 */\r
+ unsigned VCLKR : 4U; /* 0x00D0 */\r
+ unsigned : 4U; /* 0x00D0 */\r
+ unsigned VCLK2R : 4U; /* 0x00D0 */\r
+ unsigned : 4U; /* 0x00D0 */\r
+#else\r
+ unsigned : 4U; /* 0x00D0 */\r
+ unsigned VCLK2R : 4U; /* 0x00D0 */\r
+ unsigned : 4U; /* 0x00D0 */\r
+ unsigned VCLKR : 4U; /* 0x00D0 */\r
+ unsigned : 7U; /* 0x00D0 */\r
+ unsigned PENA : 1U; /* 0x00D0 */\r
+ unsigned : 8U; /* 0x00D0 */\r
+#endif\r
+ unsigned ECPCNTL; /* 0x00D4 */\r
+ unsigned DSPGCR; /* 0x00D8 */\r
+ unsigned DEVCR1; /* 0x00DC */\r
+ unsigned SYSECR; /* 0x00E0 */\r
+ unsigned SYSESR; /* 0x00E4 */\r
+ unsigned ITIFLAG; /* 0x00E8 */\r
+ unsigned GBLSTAT; /* 0x00EC */\r
+ unsigned DEV; /* 0x00F0 */\r
+ unsigned SSIVEC; /* 0x00F4 */\r
+ unsigned SSIF; /* 0x00F8 */\r
+} systemBASE1_t;\r
+\r
+\r
+/** @def systemREG1\r
+* @brief System Register Frame 1 Pointer\r
+*\r
+* This pointer is used by the system driver to access the system frame 1 registers.\r
+*/\r
+#define systemREG1 ((systemBASE1_t *)0xFFFFFF00U)\r
+\r
+/** @def systemPORT\r
+* @brief ECLK GIO Port Register Pointer\r
+*\r
+* Pointer used by the GIO driver to access I/O PORT of System/Eclk\r
+* (use the GIO drivers to access the port pins).\r
+*/\r
+#define systemPORT ((gioPORT_t *)0xFFFFFF04U)\r
+\r
+/* USER CODE BEGIN (2) */\r
+/* USER CODE END */\r
+\r
+\r
+/* System Register Frame 2 Definition */\r
+/** @struct systemBase2\r
+* @brief System Register Frame 2 Definition\r
+*\r
+* This type is used to access the System 2 Registers.\r
+*/\r
+/** @typedef systemBASE2_t\r
+* @brief System Register Frame 2 Type Definition\r
+*\r
+* This type is used to access the System 2 Registers.\r
+*/\r
+typedef volatile struct systemBase2\r
+{\r
+ unsigned PLLCTL3; /* 0x0000 */\r
+ unsigned : 32U; /* 0x0004 */\r
+ unsigned STCCLKDIV; /* 0x0008 */\r
+ unsigned CLKHB_GLBREG; /* 0x000C */\r
+ unsigned CLKHB_RTIDREG; /* 0x0010 */\r
+ unsigned HBCD_STAT; /* 0x0014 */\r
+ unsigned : 32U; /* 0x0018 */\r
+ unsigned : 32U; /* 0x001C */\r
+ unsigned CLKTRMI1; /* 0x0020 */\r
+ unsigned ECPCNTRL0; /* 0x0024 */\r
+ unsigned ECPCNTRL1; /* 0x0028 */\r
+ unsigned ECPCNTRL2; /* 0x002C */\r
+ unsigned ECPCNTRL3; /* 0x0030 */\r
+ unsigned : 32U; /* 0x0034 */\r
+ unsigned : 32U; /* 0x0038 */\r
+ unsigned CLK2CNTRL; /* 0x003C */\r
+ unsigned VCLKACON1; /* 0x0040 */\r
+} systemBASE2_t;\r
+\r
+\r
+/** @def systemREG2\r
+* @brief System Register Frame 2 Pointer\r
+*\r
+* This pointer is used by the system driver to access the system frame 2 registers.\r
+*/\r
+#define systemREG2 ((systemBASE2_t *)0xFFFFE100U)\r
+\r
+/* USER CODE BEGIN (3) */\r
+/* USER CODE END */\r
+\r
+\r
+/** @struct pcrBase\r
+* @brief Pcr Register Frame Definition\r
+*\r
+* This type is used to access the Pcr Registers.\r
+*/\r
+/** @typedef pcrBASE_t\r
+* @brief PCR Register Frame Type Definition\r
+*\r
+* This type is used to access the PCR Registers.\r
+*/\r
+typedef volatile struct pcrBase\r
+{\r
+ unsigned PMPROTSET0; /* 0x0000 */\r
+ unsigned PMPROTSET1; /* 0x0004 */\r
+ unsigned : 32U; /* 0x0008 */\r
+ unsigned : 32U; /* 0x000C */\r
+ unsigned PMPROTCLR0; /* 0x0010 */\r
+ unsigned PMPROTCLR1; /* 0x0014 */\r
+ unsigned : 32U; /* 0x0018 */\r
+ unsigned : 32U; /* 0x001C */\r
+ unsigned PPROTSET0; /* 0x0020 */\r
+ unsigned PPROTSET1; /* 0x0024 */\r
+ unsigned PPROTSET2; /* 0x0028 */\r
+ unsigned PPROTSET3; /* 0x002C */\r
+ unsigned : 32U; /* 0x0030 */\r
+ unsigned : 32U; /* 0x0034 */\r
+ unsigned : 32U; /* 0x0038 */\r
+ unsigned : 32U; /* 0x003C */\r
+ unsigned PPROTCLR0; /* 0x0040 */\r
+ unsigned PPROTCLR1; /* 0x0044 */\r
+ unsigned PPROTCLR2; /* 0x0048 */\r
+ unsigned PPROTCLR3; /* 0x004C */\r
+ unsigned : 32U; /* 0x0050 */\r
+ unsigned : 32U; /* 0x0054 */\r
+ unsigned : 32U; /* 0x0058 */\r
+ unsigned : 32U; /* 0x005C */\r
+ unsigned PCSPWRDWNSET0; /* 0x0060 */\r
+ unsigned PCSPWRDWNSET1; /* 0x0064 */\r
+ unsigned : 32U; /* 0x0068 */\r
+ unsigned : 32U; /* 0x006C */\r
+ unsigned PCSPWRDWNCLR0; /* 0x0070 */\r
+ unsigned PCSPWRDWNCLR1; /* 0x0074 */\r
+ unsigned : 32U; /* 0x0078 */\r
+ unsigned : 32U; /* 0x007C */\r
+ unsigned PSPWRDWNSET0; /* 0x0080 */\r
+ unsigned PSPWRDWNSET1; /* 0x0084 */\r
+ unsigned PSPWRDWNSET2; /* 0x0088 */\r
+ unsigned PSPWRDWNSET3; /* 0x008C */\r
+ unsigned : 32U; /* 0x0090 */\r
+ unsigned : 32U; /* 0x0094 */\r
+ unsigned : 32U; /* 0x0098 */\r
+ unsigned : 32U; /* 0x009C */\r
+ unsigned PSPWRDWNCLR0; /* 0x00A0 */\r
+ unsigned PSPWRDWNCLR1; /* 0x00A4 */\r
+ unsigned PSPWRDWNCLR2; /* 0x00A8 */\r
+ unsigned PSPWRDWNCLR3; /* 0x00AC */\r
+} pcrBASE_t;\r
+\r
+/** @def pcrREG\r
+* @brief Pcr Register Frame Pointer\r
+*\r
+* This pointer is used by the system driver to access the Pcr registers.\r
+*/\r
+#define pcrREG ((pcrBASE_t *)0xFFFFE000U)\r
+\r
+/* USER CODE BEGIN (4) */\r
+/* USER CODE END */\r
+\r
+\r
+/* FlashW General Definitions */\r
+\r
+\r
+/** @enum flashWPowerModes\r
+* @brief Alias names for flash bank power modes\r
+*\r
+* This enumeration is used to provide alias names for the flash bank power modes:\r
+* - sleep\r
+* - standby\r
+* - active\r
+*/\r
+enum flashWPowerModes\r
+{\r
+ SYS_SLEEP = 0U, /**< Alias for flash bank power mode sleep */\r
+ SYS_STANDBY = 1U, /**< Alias for flash bank power mode standby */\r
+ SYS_ACTIVE = 3U /**< Alias for flash bank power mode active */\r
+};\r
+\r
+/* USER CODE BEGIN (5) */\r
+/* USER CODE END */\r
+\r
+\r
+/** @struct flashWBase\r
+* @brief Flash Wrapper Register Frame Definition\r
+*\r
+* This type is used to access the Flash Wrapper Registers.\r
+*/\r
+/** @typedef flashWBASE_t\r
+* @brief Flash Wrapper Register Frame Type Definition\r
+*\r
+* This type is used to access the Flash Wrapper Registers.\r
+*/\r
+typedef volatile struct flashWBase\r
+{\r
+ unsigned FRDCNTL; /* 0x0000 */\r
+ unsigned FSPRD; /* 0x0004 */\r
+ unsigned FEDACCTRL1; /* 0x0008 */\r
+ unsigned FEDACCTRL2; /* 0x000C */\r
+ unsigned FCORERRCNT; /* 0x0010 */\r
+ unsigned FCORERRADD; /* 0x0014 */\r
+ unsigned FCORERRPOS; /* 0x0018 */\r
+ unsigned FEDACSTATUS; /* 0x001C */\r
+ unsigned FUNCERRADD; /* 0x0020 */\r
+ unsigned FEDACSDIS; /* 0x0024 */\r
+ unsigned FPRIMADDTAG; /* 0x0028 */\r
+ unsigned FREDUADDTAG; /* 0x002C */\r
+ unsigned FBPROT; /* 0x0030 */\r
+ unsigned FBSE; /* 0x0034 */\r
+ unsigned FBBUSY; /* 0x0038 */\r
+ unsigned FBAC; /* 0x003C */\r
+ unsigned FBFALLBACK; /* 0x0040 */\r
+ unsigned FBPRDY; /* 0x0044 */\r
+ unsigned FPAC1; /* 0x0048 */\r
+ unsigned FPAC2; /* 0x004C */\r
+ unsigned FMAC; /* 0x0050 */\r
+ unsigned FMSTAT; /* 0x0054 */\r
+ unsigned FEMUDMSW; /* 0x0058 */\r
+ unsigned FEMUDLSW; /* 0x005C */\r
+ unsigned FEMUECC; /* 0x0060 */\r
+ unsigned FLOCK; /* 0x0064 */\r
+ unsigned FEMUADDR; /* 0x0068 */\r
+ unsigned FDIAGCTRL; /* 0x006C */\r
+ unsigned FRAWDATAH; /* 0x0070 */\r
+ unsigned FRAWDATAL; /* 0x0074 */\r
+ unsigned FRAWECC; /* 0x0078 */\r
+ unsigned FPAROVR; /* 0x007C */\r
+ unsigned FVREADCT; /* 0x0080 */\r
+ unsigned FVHVCT1; /* 0x0084 */\r
+ unsigned FVHVCT2; /* 0x0088 */\r
+ unsigned FVNVCT; /* 0x008C */\r
+ unsigned FVPPCT; /* 0x0090 */\r
+ unsigned FVWLCT; /* 0x0094 */\r
+ unsigned FEFUSE; /* 0x0098 */\r
+ unsigned : 32U; /* 0x009C */\r
+ unsigned : 32U; /* 0x00A0 */\r
+ unsigned : 32U; /* 0x00A4 */\r
+ unsigned : 32U; /* 0x00A8 */\r
+ unsigned : 32U; /* 0x00AC */\r
+ unsigned : 32U; /* 0x00B0 */\r
+ unsigned : 32U; /* 0x00B4 */\r
+ unsigned : 32U; /* 0x00B8 */\r
+ unsigned : 32U; /* 0x00BC */\r
+ unsigned FEDACSDIS2; /* 0x00C0 */\r
+ unsigned : 32U; /* 0x00C4 */\r
+ unsigned : 32U; /* 0x00C8 */\r
+ unsigned : 32U; /* 0x00CC */\r
+ unsigned : 32U; /* 0x00D0 */\r
+ unsigned : 32U; /* 0x00D4 */\r
+ unsigned : 32U; /* 0x00D8 */\r
+ unsigned : 32U; /* 0x00DC */\r
+ unsigned : 32U; /* 0x00E0 */\r
+ unsigned : 32U; /* 0x00E4 */\r
+ unsigned : 32U; /* 0x00E8 */\r
+ unsigned : 32U; /* 0x00EC */\r
+ unsigned : 32U; /* 0x00F0 */\r
+ unsigned : 32U; /* 0x00F4 */\r
+ unsigned : 32U; /* 0x00F8 */\r
+ unsigned : 32U; /* 0x00FC */\r
+ unsigned FBSTROBES; /* 0x0100 */\r
+ unsigned FPSTROBES; /* 0x0104 */\r
+ unsigned FBMODE; /* 0x0108 */\r
+ unsigned FTCR; /* 0x010C */\r
+ unsigned FADDR; /* 0x0110 */\r
+ unsigned FWRITE; /* 0x0114 */\r
+ unsigned FCBITSEL; /* 0x0118 */\r
+ unsigned FTCTRL; /* 0x011C */\r
+ unsigned FWPWRITE0; /* 0x0120 */\r
+ unsigned FWPWRITE1; /* 0x0124 */\r
+ unsigned FWPWRITE2; /* 0x0128 */\r
+ unsigned FWPWRITE3; /* 0x012C */\r
+ unsigned FWPWRITE4; /* 0x0130 */\r
+} flashWBASE_t;\r
+\r
+/** @def flashWREG\r
+* @brief Flash Wrapper Register Frame Pointer\r
+*\r
+* This pointer is used by the system driver to access the flash wrapper registers.\r
+*/\r
+#define flashWREG ((flashWBASE_t *)(0xFFF87000U))\r
+\r
+/* USER CODE BEGIN (6) */\r
+/* USER CODE END */\r
+\r
+\r
+/* System Interface Functions */\r
+void systemInit(void);\r
+void systemPowerDown(unsigned mode);\r
+\r
+\r
+/* USER CODE BEGIN (7) */\r
+/* USER CODE END */\r
+\r
+\r
+#endif\r
--- /dev/null
+/*----------------------------------------------------------------------------*/\r
+/* sys_types.h 10/20/10 15:19:19 */\r
+/* */\r
+/* (c) Texas Instruments 2003-2010, All rights reserved. */\r
+/* */\r
+\r
+\r
+#ifndef __sys_types_h__\r
+#define __sys_types_h__\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Standard Types */\r
+\r
+typedef signed char T_S8;\r
+#define MAX_S8 (127)\r
+#define MIN_S8 (-128)\r
+\r
+typedef unsigned char T_U8;\r
+#define MAX_U8 (255)\r
+#define MIN_U8 (0)\r
+\r
+typedef signed short T_S16;\r
+#define MAX_S16 (32767)\r
+#define MIN_S16 (-32767-1)\r
+\r
+typedef unsigned short T_U16;\r
+#define MAX_U16 (0xFFFFU)\r
+#define MIN_U16 (0)\r
+\r
+typedef signed int T_S32;\r
+#define MAX_S32 (2147483647L)\r
+#define MIN_S32 (-2147483647L-1)\r
+\r
+typedef unsigned int T_U32;\r
+#define MAX_U32 (0xFFFFFFFFU)\r
+#define MIN_U32 (0)\r
+\r
+typedef float T_F32;\r
+#define MAX_F32 (3.39e+38)\r
+#define MIN_F32 (1.18e-38)\r
+\r
+typedef double T_F64;\r
+#define MAX_F64 (1.79e+308)\r
+#define MIN_F64 (2.23e-308)\r
+\r
+\r
+#endif\r
+/*----------------------------------------------------------------------------*/\r
+\r
--- /dev/null
+/** @file sys_vim.h\r
+* @brief Vectored Interrupt Module Header File\r
+* @date 05.November.2010\r
+* @version 1.01.000\r
+* \r
+* This file contains:\r
+* - VIM Type Definitions\r
+* - VIM General Definitions\r
+* .\r
+* which are relevant for the Vectored Interrupt Controller.\r
+*/\r
+\r
+/* (c) Texas Instruments 2010, All rights reserved. */\r
+\r
+#ifndef __SYS_VIM_H__\r
+#define __SYS_VIM_H__\r
+\r
+/* USER CODE BEGIN (0) */\r
+/* USER CODE END */\r
+\r
+\r
+/* VIM Type Definitions */\r
+\r
+/** @typedef t_isrFuncPTR\r
+* @brief ISR Function Pointer Type Definition\r
+*\r
+* This type is used to access the ISR handler.\r
+*/\r
+typedef void (*t_isrFuncPTR)();\r
+\r
+/* USER CODE BEGIN (1) */\r
+/* USER CODE END */\r
+\r
+\r
+/* VIM General Configuration */\r
+\r
+#define VIM_CHANNELS 96U\r
+\r
+/* USER CODE BEGIN (2) */\r
+/* USER CODE END */\r
+\r
+/* Interrupt Handlers */\r
+\r
+extern void phantomInterrupt(void);\r
+extern void esmHighLevelInterrupt(void);\r
+extern void vPreemptiveTick(void);\r
+extern void vNonPreemptiveTick(void);\r
+extern void vPortYeildWithinAPI(void);\r
+\r
+\r
+/* Vim Register Frame Definition */\r
+/** @struct vimBase\r
+* @brief Vim Register Frame Definition\r
+*\r
+* This type is used to access the Vim Registers.\r
+*/\r
+/** @typedef vimBASE_t\r
+* @brief VIM Register Frame Type Definition\r
+*\r
+* This type is used to access the VIM Registers.\r
+*/\r
+typedef volatile struct vimBase\r
+{\r
+ unsigned : 24U; /* 0x0000 */\r
+ unsigned IRQIVEC : 8U; /* 0x0000 */\r
+ unsigned : 24U; /* 0x0004 */\r
+ unsigned FIQIVEC : 8U; /* 0x0004 */\r
+ unsigned : 32U; /* 0x0008 */\r
+ unsigned : 32U; /* 0x000C */\r
+ unsigned FIRQPR0; /* 0x0010 */\r
+ unsigned FIRQPR1; /* 0x0014 */\r
+ unsigned FIRQPR2; /* 0x0018 */\r
+ unsigned FIRQPR3; /* 0x001C */\r
+ unsigned INTREQ0; /* 0x0020 */\r
+ unsigned INTREQ1; /* 0x0024 */\r
+ unsigned INTREQ2; /* 0x0028 */\r
+ unsigned INTREQ3; /* 0x002C */\r
+ unsigned REQMASKSET0; /* 0x0030 */\r
+ unsigned REQMASKSET1; /* 0x0034 */\r
+ unsigned REQMASKSET2; /* 0x0038 */\r
+ unsigned REQMASKSET3; /* 0x003C */\r
+ unsigned REQMASKCLR0; /* 0x0040 */\r
+ unsigned REQMASKCLR1; /* 0x0044 */\r
+ unsigned REQMASKCLR2; /* 0x0048 */\r
+ unsigned REQMASKCLR3; /* 0x004C */\r
+ unsigned WAKEMASKSET0; /* 0x0050 */\r
+ unsigned WAKEMASKSET1; /* 0x0054 */\r
+ unsigned WAKEMASKSET2; /* 0x0058 */\r
+ unsigned WAKEMASKSET3; /* 0x005C */\r
+ unsigned WAKEMASKCLR0; /* 0x0060 */\r
+ unsigned WAKEMASKCLR1; /* 0x0064 */\r
+ unsigned WAKEMASKCLR2; /* 0x0068 */\r
+ unsigned WAKEMASKCLR3; /* 0x006C */\r
+ unsigned IRQVECREG; /* 0x0070 */\r
+ unsigned FIQVECREQ; /* 0x0074 */\r
+ unsigned : 9U; /* 0x0078 */\r
+ unsigned CAPEVTSRC1 : 7U; /* 0x0078 */\r
+ unsigned : 9U; /* 0x0078 */\r
+ unsigned CAPEVTSRC0 : 7U; /* 0x0078 */\r
+ unsigned : 32U; /* 0x007C */\r
+ unsigned char CHANMAP[64U]; /* 0x0080-0x017C */\r
+} vimBASE_t;\r
+\r
+#define vimREG ((vimBASE_t *)0xFFFFFE00U)\r
+\r
+/* USER CODE BEGIN (3) */\r
+/* USER CODE END */\r
+\r
+\r
+#endif\r
--- /dev/null
+/*----------------------------------------------------------------------------*/\r
+/* sys_link.cmd */\r
+/* */\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Linker Settings */\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Memory Map */\r
+\r
+MEMORY\r
+{\r
+ VECTORS (X) : origin=0x00000000 length=0x00000020\r
+ FLASH0 (RX) : origin=0x00000020 length=0x0017FFE0\r
+ FLASH1 (RX) : origin=0x00180000 length=0x00180000\r
+ STACKS (RW) : origin=0x08000000 length=0x00000200\r
+ RAM (RW) : origin=0x08000200 length=0x0003FE00\r
+ }\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Section Configuration */\r
+\r
+SECTIONS\r
+{\r
+ .intvecs : {} > VECTORS\r
+ .text : {} > FLASH0 | FLASH1\r
+ .const : {} > FLASH0 | FLASH1\r
+ .cinit : {} > FLASH0 | FLASH1\r
+ .pinit : {} > FLASH0 | FLASH1\r
+ .heap : {} > RAM\r
+ .bss : {} > RAM\r
+ .data : {} > RAM\r
+ .sysmem : {} > RAM\r
+}\r
+\r
+/*----------------------------------------------------------------------------*/\r
+\r