source: Rename project from "test" to "shoh"
This commit is contained in:
331
source/shoh/.cproject
Normal file
331
source/shoh/.cproject
Normal file
@@ -0,0 +1,331 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="com.crt.advproject.config.exe.debug.401943083">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.401943083" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings>
|
||||
<externalSetting/>
|
||||
</externalSettings>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="Debug build" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.debug.401943083" name="Debug" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size "${BuildArtifactFileName}"; # arm-none-eabi-objcopy -v -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin" ; # checksum -p ${TargetChip} -d "${BuildArtifactFileBaseName}.bin"; ">
|
||||
<folderInfo id="com.crt.advproject.config.exe.debug.401943083." name="/" resourcePath="">
|
||||
<toolChain id="com.crt.advproject.toolchain.exe.debug.1524701083" name="NXP MCU Tools" superClass="com.crt.advproject.toolchain.exe.debug">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.debug.1390504167" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.exe.debug"/>
|
||||
<builder buildPath="${workspace_loc:/test}/Debug" id="com.crt.advproject.builder.exe.debug.1520735843" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.debug"/>
|
||||
<tool id="com.crt.advproject.cpp.exe.debug.427412446" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.debug">
|
||||
<option id="com.crt.advproject.cpp.thumb.484198778" name="Thumb mode" superClass="com.crt.advproject.cpp.thumb" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.cpp.specs.1937728462" name="Specs" superClass="com.crt.advproject.cpp.specs" useByScannerDiscovery="false" value="com.crt.advproject.cpp.specs.newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.cpp.arch.613352647" name="Architecture" superClass="com.crt.advproject.cpp.arch" useByScannerDiscovery="true" value="com.crt.advproject.cpp.target.cm0" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.2117032708" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DEBUG"/>
|
||||
<listOptionValue builtIn="false" value="__CODE_RED"/>
|
||||
<listOptionValue builtIn="false" value="__NEWLIB__"/>
|
||||
<listOptionValue builtIn="false" value="CORE_M0PLUS"/>
|
||||
<listOptionValue builtIn="false" value="__MTB_BUFFER_SIZE=256"/>
|
||||
<listOptionValue builtIn="false" value="__USE_ROMDIVIDE"/>
|
||||
<listOptionValue builtIn="false" value="__USE_LPCOPEN"/>
|
||||
<listOptionValue builtIn="false" value="CPP_USE_HEAP"/>
|
||||
<listOptionValue builtIn="false" value="__LPC11U6X__"/>
|
||||
</option>
|
||||
<option id="gnu.cpp.compiler.option.other.other.479361349" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions" valueType="string"/>
|
||||
<option id="gnu.cpp.compiler.option.optimization.flags.1144777019" name="Other optimization flags" superClass="gnu.cpp.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-common" valueType="string"/>
|
||||
<option id="com.crt.advproject.cpp.hdrlib.2011557786" name="Library headers" superClass="com.crt.advproject.cpp.hdrlib" useByScannerDiscovery="false" value="Newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.cpp.fpu.1211390952" name="Floating point" superClass="com.crt.advproject.cpp.fpu" useByScannerDiscovery="true"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.417443680" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.cpp.misc.dialect.4036734" name="Language standard" superClass="com.crt.advproject.cpp.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.cpp17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.cpp.input.2005422649" superClass="com.crt.advproject.compiler.cpp.input"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.gcc.exe.debug.1201217380" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.debug">
|
||||
<option id="com.crt.advproject.gcc.thumb.290070234" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.gcc.hdrlib.1860573279" name="Library headers" superClass="com.crt.advproject.gcc.hdrlib" useByScannerDiscovery="false" value="Newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gcc.specs.1590015901" name="Specs" superClass="com.crt.advproject.gcc.specs" useByScannerDiscovery="false" value="com.crt.advproject.gcc.specs.newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gcc.arch.922608191" name="Architecture" superClass="com.crt.advproject.gcc.arch" useByScannerDiscovery="true" value="com.crt.advproject.gcc.target.cm0" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.826143364" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DEBUG"/>
|
||||
<listOptionValue builtIn="false" value="__CODE_RED"/>
|
||||
<listOptionValue builtIn="false" value="__NEWLIB__"/>
|
||||
<listOptionValue builtIn="false" value="CORE_M0PLUS"/>
|
||||
<listOptionValue builtIn="false" value="__MTB_BUFFER_SIZE=256"/>
|
||||
<listOptionValue builtIn="false" value="__USE_ROMDIVIDE"/>
|
||||
<listOptionValue builtIn="false" value="__USE_LPCOPEN"/>
|
||||
<listOptionValue builtIn="false" value="CPP_USE_HEAP"/>
|
||||
<listOptionValue builtIn="false" value="__LPC11U6X__"/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.misc.other.921205983" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.optimization.flags.1696333281" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-common" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.553421246" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.c.misc.dialect.82852045" name="Language standard" superClass="com.crt.advproject.c.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.c17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.input.765511076" superClass="com.crt.advproject.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.gas.exe.debug.1514460309" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.debug">
|
||||
<option id="com.crt.advproject.gas.thumb.1980177486" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.gas.hdrlib.1362489965" name="Library headers" superClass="com.crt.advproject.gas.hdrlib" useByScannerDiscovery="false" value="Newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gas.specs.1605608770" name="Specs" superClass="com.crt.advproject.gas.specs" useByScannerDiscovery="false" value="com.crt.advproject.gas.specs.newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gas.arch.1662424538" name="Architecture" superClass="com.crt.advproject.gas.arch" useByScannerDiscovery="false" value="com.crt.advproject.gas.target.cm0" valueType="enumerated"/>
|
||||
<option id="gnu.both.asm.option.flags.crt.92010878" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" useByScannerDiscovery="false" value="-c -x assembler-with-cpp -D__NEWLIB__ -DDEBUG -D__CODE_RED -DCORE_M0PLUS -D__USE_ROMDIVIDE -D__USE_LPCOPEN -D__LPC11U6X__" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.both.asm.option.include.paths.456350910" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1836378919" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="com.crt.advproject.assembler.input.339410672" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.link.cpp.exe.debug.727798809" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.debug">
|
||||
<option id="com.crt.advproject.link.cpp.thumb.632067029" name="Thumb mode" superClass="com.crt.advproject.link.cpp.thumb" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.link.memory.load.image.cpp.1738960397" name="Plain load image" superClass="com.crt.advproject.link.memory.load.image.cpp" useByScannerDiscovery="false" value="" valueType="string"/>
|
||||
<option defaultValue="com.crt.advproject.heapAndStack.lpcXpressoStyle.cpp" id="com.crt.advproject.link.memory.heapAndStack.style.cpp.1976229986" name="Heap and Stack placement" superClass="com.crt.advproject.link.memory.heapAndStack.style.cpp" useByScannerDiscovery="false" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.link.memory.heapAndStack.cpp.1393747744" name="Heap and Stack options" superClass="com.crt.advproject.link.memory.heapAndStack.cpp" useByScannerDiscovery="false" value="&Heap:Default;Post Data;Default&Stack:Default;End;Default" valueType="string"/>
|
||||
<option id="com.crt.advproject.link.memory.data.cpp.829211692" name="Global data placement" superClass="com.crt.advproject.link.memory.data.cpp" useByScannerDiscovery="false" value="" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.memory.sections.cpp.779180690" name="Extra linker script input sections" superClass="com.crt.advproject.link.memory.sections.cpp" useByScannerDiscovery="false" valueType="stringList"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.cpp.multicore.master.userobjs.1070617149" name="Slave Objects (not visible)" superClass="com.crt.advproject.link.cpp.multicore.master.userobjs" useByScannerDiscovery="false" valueType="userObjs"/>
|
||||
<option id="com.crt.advproject.link.cpp.multicore.slave.785072063" name="Multicore configuration" superClass="com.crt.advproject.link.cpp.multicore.slave" useByScannerDiscovery="false"/>
|
||||
<option id="com.crt.advproject.link.cpp.arch.511150181" name="Architecture" superClass="com.crt.advproject.link.cpp.arch" useByScannerDiscovery="false" value="com.crt.advproject.link.cpp.target.cm0" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.link.cpp.script.1663118727" name="Linker script" superClass="com.crt.advproject.link.cpp.script" useByScannerDiscovery="false" value=""test_Debug.ld"" valueType="string"/>
|
||||
<option id="com.crt.advproject.link.cpp.manage.1299418049" name="Manage linker script" superClass="com.crt.advproject.link.cpp.manage" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="gnu.cpp.link.option.nostdlibs.1645986372" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.other.1082286413" name="Other options (-Xlinker [option])" superClass="gnu.cpp.link.option.other" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="-Map="${BuildArtifactFileBaseName}.map""/>
|
||||
<listOptionValue builtIn="false" value="--cref"/>
|
||||
<listOptionValue builtIn="false" value="--gc-sections"/>
|
||||
<listOptionValue builtIn="false" value="-print-memory-usage"/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.link.cpp.hdrlib.1671574638" name="Library" superClass="com.crt.advproject.link.cpp.hdrlib" useByScannerDiscovery="false" value="com.crt.advproject.cpp.link.hdrlib.newlib.nohost" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.295350087" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="lpc_board_nxp_lpcxpresso_11u68"/>
|
||||
<listOptionValue builtIn="false" value="lpc_chip_11u6x"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.1056782957" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/Debug}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/Debug}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.link.cpp.crpenable.335096734" name="Enable automatic placement of Code Read Protection field in image" superClass="com.crt.advproject.link.cpp.crpenable" useByScannerDiscovery="false"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1709924631" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.link.exe.debug.2080680827" name="MCU Linker" superClass="com.crt.advproject.link.exe.debug">
|
||||
<option id="com.crt.advproject.link.gcc.hdrlib.839128888" name="Library" superClass="com.crt.advproject.link.gcc.hdrlib"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.tool.debug.debug.364746107" name="MCU Debugger" superClass="com.crt.advproject.tool.debug.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="freertos"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="com.crt.advproject.config.exe.release.1972323893">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.release.1972323893" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="Release build" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.release.1972323893" name="Release" parent="com.crt.advproject.config.exe.release" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size "${BuildArtifactFileName}"; # arm-none-eabi-objcopy -v -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin" ; # checksum -p ${TargetChip} -d "${BuildArtifactFileBaseName}.bin"; ">
|
||||
<folderInfo id="com.crt.advproject.config.exe.release.1972323893." name="/" resourcePath="">
|
||||
<toolChain id="com.crt.advproject.toolchain.exe.release.1032522170" name="NXP MCU Tools" superClass="com.crt.advproject.toolchain.exe.release">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.release.761786777" name="ARM-based MCU (Release)" superClass="com.crt.advproject.platform.exe.release"/>
|
||||
<builder buildPath="${workspace_loc:/test}/Release" id="com.crt.advproject.builder.exe.release.346455727" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.release"/>
|
||||
<tool id="com.crt.advproject.cpp.exe.release.318991644" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.release">
|
||||
<option id="com.crt.advproject.cpp.thumb.282963457" name="Thumb mode" superClass="com.crt.advproject.cpp.thumb" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.cpp.specs.1138045980" name="Specs" superClass="com.crt.advproject.cpp.specs" useByScannerDiscovery="false" value="com.crt.advproject.cpp.specs.newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.cpp.arch.1153925998" name="Architecture" superClass="com.crt.advproject.cpp.arch" useByScannerDiscovery="true" value="com.crt.advproject.cpp.target.cm0" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.preprocessor.def.441203352" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="NDEBUG"/>
|
||||
<listOptionValue builtIn="false" value="__CODE_RED"/>
|
||||
<listOptionValue builtIn="false" value="__NEWLIB__"/>
|
||||
<listOptionValue builtIn="false" value="CORE_M0PLUS"/>
|
||||
<listOptionValue builtIn="false" value="__MTB_BUFFER_SIZE=256"/>
|
||||
<listOptionValue builtIn="false" value="__USE_ROMDIVIDE"/>
|
||||
<listOptionValue builtIn="false" value="__USE_LPCOPEN"/>
|
||||
<listOptionValue builtIn="false" value="CPP_USE_HEAP"/>
|
||||
<listOptionValue builtIn="false" value="__LPC11U6X__"/>
|
||||
</option>
|
||||
<option id="gnu.cpp.compiler.option.other.other.96095824" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions" valueType="string"/>
|
||||
<option id="gnu.cpp.compiler.option.optimization.flags.1487444982" name="Other optimization flags" superClass="gnu.cpp.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-common -Os" valueType="string"/>
|
||||
<option id="com.crt.advproject.cpp.hdrlib.858750993" name="Library headers" superClass="com.crt.advproject.cpp.hdrlib" useByScannerDiscovery="false" value="Newlib" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.722676070" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
</option>
|
||||
<inputType id="com.crt.advproject.compiler.cpp.input.903614193" superClass="com.crt.advproject.compiler.cpp.input"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.gcc.exe.release.2083517403" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.release">
|
||||
<option id="com.crt.advproject.gcc.thumb.1903701781" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.gcc.hdrlib.157396081" name="Library headers" superClass="com.crt.advproject.gcc.hdrlib" useByScannerDiscovery="false" value="Newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gcc.specs.835433196" name="Specs" superClass="com.crt.advproject.gcc.specs" useByScannerDiscovery="false" value="com.crt.advproject.gcc.specs.newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gcc.arch.1170515999" name="Architecture" superClass="com.crt.advproject.gcc.arch" useByScannerDiscovery="true" value="com.crt.advproject.gcc.target.cm0" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.208191868" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="NDEBUG"/>
|
||||
<listOptionValue builtIn="false" value="__CODE_RED"/>
|
||||
<listOptionValue builtIn="false" value="__NEWLIB__"/>
|
||||
<listOptionValue builtIn="false" value="CORE_M0PLUS"/>
|
||||
<listOptionValue builtIn="false" value="__MTB_BUFFER_SIZE=256"/>
|
||||
<listOptionValue builtIn="false" value="__USE_ROMDIVIDE"/>
|
||||
<listOptionValue builtIn="false" value="__USE_LPCOPEN"/>
|
||||
<listOptionValue builtIn="false" value="CPP_USE_HEAP"/>
|
||||
<listOptionValue builtIn="false" value="__LPC11U6X__"/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.misc.other.1884852709" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.optimization.flags.2141594776" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-common" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1942745624" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.c.misc.dialect.1008527937" name="Language standard" superClass="com.crt.advproject.c.misc.dialect" useByScannerDiscovery="true" value="com.crt.advproject.misc.dialect.c17" valueType="enumerated"/>
|
||||
<inputType id="com.crt.advproject.compiler.input.246185412" superClass="com.crt.advproject.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.gas.exe.release.1492116417" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.release">
|
||||
<option id="com.crt.advproject.gas.thumb.273959030" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.gas.hdrlib.1723198101" name="Library headers" superClass="com.crt.advproject.gas.hdrlib" value="Newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gas.specs.1976698768" name="Specs" superClass="com.crt.advproject.gas.specs" value="com.crt.advproject.gas.specs.newlib" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.gas.arch.262619541" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm0" valueType="enumerated"/>
|
||||
<option id="gnu.both.asm.option.flags.crt.952537915" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__NEWLIB__ -DDEBUG -D__CODE_RED -DCORE_M0PLUS -D__USE_ROMDIVIDE -D__USE_LPCOPEN -D__LPC11U6X__" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.both.asm.option.include.paths.550385257" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/shoh/freertos/inc}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1117166373" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
<inputType id="com.crt.advproject.assembler.input.2071009798" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.link.cpp.exe.release.2136689956" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.release">
|
||||
<option id="com.crt.advproject.link.cpp.thumb.571585566" name="Thumb mode" superClass="com.crt.advproject.link.cpp.thumb" value="true" valueType="boolean"/>
|
||||
<option id="com.crt.advproject.link.memory.load.image.cpp.1178379429" name="Plain load image" superClass="com.crt.advproject.link.memory.load.image.cpp" value="" valueType="string"/>
|
||||
<option defaultValue="com.crt.advproject.heapAndStack.lpcXpressoStyle.cpp" id="com.crt.advproject.link.memory.heapAndStack.style.cpp.434149851" name="Heap and Stack placement" superClass="com.crt.advproject.link.memory.heapAndStack.style.cpp" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.link.memory.heapAndStack.cpp.136827787" name="Heap and Stack options" superClass="com.crt.advproject.link.memory.heapAndStack.cpp" value="&Heap:Default;Post Data;Default&Stack:Default;End;Default" valueType="string"/>
|
||||
<option id="com.crt.advproject.link.memory.data.cpp.1711736548" name="Global data placement" superClass="com.crt.advproject.link.memory.data.cpp" value="" valueType="string"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.memory.sections.cpp.752526836" name="Extra linker script input sections" superClass="com.crt.advproject.link.memory.sections.cpp" valueType="stringList"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.cpp.multicore.master.userobjs.1097113488" name="Slave Objects (not visible)" superClass="com.crt.advproject.link.cpp.multicore.master.userobjs" valueType="userObjs"/>
|
||||
<option id="com.crt.advproject.link.cpp.multicore.slave.1746915932" name="Multicore configuration" superClass="com.crt.advproject.link.cpp.multicore.slave"/>
|
||||
<option id="com.crt.advproject.link.cpp.arch.1802557179" name="Architecture" superClass="com.crt.advproject.link.cpp.arch" value="com.crt.advproject.link.cpp.target.cm0" valueType="enumerated"/>
|
||||
<option id="com.crt.advproject.link.cpp.script.34463823" name="Linker script" superClass="com.crt.advproject.link.cpp.script" value=""test_Release.ld"" valueType="string"/>
|
||||
<option id="com.crt.advproject.link.cpp.manage.1489257243" name="Manage linker script" superClass="com.crt.advproject.link.cpp.manage" value="true" valueType="boolean"/>
|
||||
<option id="gnu.cpp.link.option.nostdlibs.1993372682" name="No startup or default libs (-nostdlib)" superClass="gnu.cpp.link.option.nostdlibs" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.other.1226051657" name="Other options (-Xlinker [option])" superClass="gnu.cpp.link.option.other" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="-Map="${BuildArtifactFileBaseName}.map""/>
|
||||
<listOptionValue builtIn="false" value="--cref"/>
|
||||
<listOptionValue builtIn="false" value="--gc-sections"/>
|
||||
<listOptionValue builtIn="false" value="-print-memory-usage"/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.link.cpp.hdrlib.1954399800" name="Library" superClass="com.crt.advproject.link.cpp.hdrlib" value="com.crt.advproject.cpp.link.hdrlib.newlib.nohost" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1003543049" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="lpc_board_nxp_lpcxpresso_11u68"/>
|
||||
<listOptionValue builtIn="false" value="lpc_chip_11u6x"/>
|
||||
</option>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.2115357650" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_board_nxp_lpcxpresso_11u68/Release}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/lpc_chip_11u6x/Release}""/>
|
||||
</option>
|
||||
<option id="com.crt.advproject.link.cpp.crpenable.1477577380" name="Enable automatic placement of Code Read Protection field in image" superClass="com.crt.advproject.link.cpp.crpenable"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.823387233" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="com.crt.advproject.link.exe.release.1570932350" name="MCU Linker" superClass="com.crt.advproject.link.exe.release"/>
|
||||
<tool id="com.crt.advproject.tool.debug.release.1062881216" name="MCU Debugger" superClass="com.crt.advproject.tool.debug.release"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="freertos"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="test.com.crt.advproject.projecttype.exe.1174795317" name="Executable" projectType="com.crt.advproject.projecttype.exe"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="com.crt.config">
|
||||
<projectStorage><?xml version="1.0" encoding="UTF-8"?>
|
||||
<TargetConfig>
|
||||
<Properties property_2="LPC11U6x_256K.cfx" property_3="NXP" property_4="LPC11U68" property_count="5" version="100300"/>
|
||||
<infoList vendor="NXP">
|
||||
<info chip="LPC11U68" flash_driver="LPC11U6x_256K.cfx" match_id="0x0" name="LPC11U68" stub="crt_emu_cm3_gen">
|
||||
<chip>
|
||||
<name>LPC11U68</name>
|
||||
<family>LPC11U6x</family>
|
||||
<vendor>NXP (formerly Philips)</vendor>
|
||||
<reset board="None" core="Real" sys="Real"/>
|
||||
<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/>
|
||||
<memory can_program="true" id="Flash" is_ro="true" type="Flash"/>
|
||||
<memory id="RAM" type="RAM"/>
|
||||
<memory id="Periph" is_volatile="true" type="Peripheral"/>
|
||||
<memoryInstance derived_from="Flash" id="MFlash256" location="0x0" size="0x40000"/>
|
||||
<memoryInstance derived_from="RAM" id="Ram0_32" location="0x10000000" size="0x8000"/>
|
||||
<memoryInstance derived_from="RAM" id="Ram1_2" location="0x20000000" size="0x800"/>
|
||||
<memoryInstance derived_from="RAM" id="Ram2USB_2" location="0x20004000" size="0x800"/>
|
||||
</chip>
|
||||
<processor>
|
||||
<name gcc_name="cortex-m0">Cortex-M0</name>
|
||||
<family>Cortex-M</family>
|
||||
</processor>
|
||||
</info>
|
||||
</infoList>
|
||||
</TargetConfig></projectStorage>
|
||||
</storageModule>
|
||||
<storageModule moduleId="com.crt.advproject">
|
||||
<boardId>LPCXpresso11U68</boardId>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.401943083;com.crt.advproject.config.exe.debug.401943083.;com.crt.advproject.gas.exe.debug.1514460309;com.crt.advproject.assembler.input.339410672">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.release.1972323893;com.crt.advproject.config.exe.release.1972323893.;com.crt.advproject.gcc.exe.release.2083517403;com.crt.advproject.compiler.input.246185412">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.401943083;com.crt.advproject.config.exe.debug.401943083.;com.crt.advproject.cpp.exe.debug.427412446;com.crt.advproject.compiler.cpp.input.2005422649">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.401943083;com.crt.advproject.config.exe.debug.401943083.;com.crt.advproject.gcc.exe.debug.1201217380;com.crt.advproject.compiler.input.765511076">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.release.1972323893;com.crt.advproject.config.exe.release.1972323893.;com.crt.advproject.gas.exe.release.1492116417;com.crt.advproject.assembler.input.2071009798">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.release.1972323893;com.crt.advproject.config.exe.release.1972323893.;com.crt.advproject.cpp.exe.release.318991644;com.crt.advproject.compiler.cpp.input.903614193">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfileCPP"/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
1
source/shoh/.gitignore
vendored
Normal file
1
source/shoh/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/Debug/
|
||||
29
source/shoh/.project
Normal file
29
source/shoh/.project
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>shoh</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>lpc_board_nxp_lpcxpresso_11u68</project>
|
||||
<project>lpc_chip_11u6x</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
25
source/shoh/.settings/language.settings.xml
Normal file
25
source/shoh/.settings/language.settings.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="com.crt.advproject.config.exe.debug.401943083" name="Debug">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="com.crt.advproject.GCCBuildCommandParser" keep-relative-paths="false" name="MCU GCC Build Output Parser" parameter="(arm-none-eabi-gcc)|(arm-none-eabi-[gc]\+\+)|(gcc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
|
||||
<provider class="com.crt.advproject.specs.MCUGCCBuiltinSpecsDetector" console="false" env-hash="545853207619283262" id="com.crt.advproject.GCCBuildSpecCompilerParser" keep-relative-paths="false" name="MCU GCC Built-in Compiler Parser" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
</extension>
|
||||
</configuration>
|
||||
<configuration id="com.crt.advproject.config.exe.release.1972323893" name="Release">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider copy-of="extension" id="com.crt.advproject.GCCBuildCommandParser"/>
|
||||
<provider class="com.crt.advproject.specs.MCUGCCBuiltinSpecsDetector" console="false" env-hash="532161512192414976" id="com.crt.advproject.GCCBuildSpecCompilerParser" keep-relative-paths="false" name="MCU GCC Built-in Compiler Parser" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
158
source/shoh/freertos/FreeRTOSConfig.h
Normal file
158
source/shoh/freertos/FreeRTOSConfig.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details. You should have received a copy of the GNU General Public
|
||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||
by writing to Richard Barry, contact details for whom are available on the
|
||||
FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||
contact details.
|
||||
|
||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||
critical systems.
|
||||
|
||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
#ifndef __IASMARM__
|
||||
/* For SystemCoreClock */
|
||||
#include "board.h"
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||
#define configMAX_PRIORITIES (8UL)
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 1024 + 512) )
|
||||
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 8
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TICKLESS_IDLE 1
|
||||
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Software timer definitions. This example uses I2C to write to the LEDs. As
|
||||
this takes a finite time, and because a timer callback writes to an LED, the
|
||||
priority of the timer task is kept to a minimum to ensure it does not disrupt
|
||||
test tasks that check their own execution times. */
|
||||
#define configUSE_TIMERS 0
|
||||
#define configTIMER_TASK_PRIORITY ( 0 )
|
||||
#define configTIMER_QUEUE_LENGTH 5
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#define configPRIO_BITS 5 /* 32 priority levels */
|
||||
#endif
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||
function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x1f
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
|
||||
|
||||
#define configUSE_CUSTOM_TICK 0
|
||||
|
||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||
standard names - or at least those used in the unmodified vector table. */
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
||||
1440
source/shoh/freertos/inc/FreeRTOS.h
Normal file
1440
source/shoh/freertos/inc/FreeRTOS.h
Normal file
File diff suppressed because it is too large
Load Diff
34
source/shoh/freertos/inc/StackMacros.h
Normal file
34
source/shoh/freertos/inc/StackMacros.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */
|
||||
#warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in a future release.
|
||||
#endif
|
||||
|
||||
#include "stack_macros.h"
|
||||
419
source/shoh/freertos/inc/atomic.h
Normal file
419
source/shoh/freertos/inc/atomic.h
Normal file
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file atomic.h
|
||||
* @brief FreeRTOS atomic operation support.
|
||||
*
|
||||
* This file implements atomic functions by disabling interrupts globally.
|
||||
* Implementations with architecture specific atomic instructions can be
|
||||
* provided under each compiler directory.
|
||||
*/
|
||||
|
||||
#ifndef ATOMIC_H
|
||||
#define ATOMIC_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h must appear in source files before include atomic.h"
|
||||
#endif
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* Port specific definitions -- entering/exiting critical section.
|
||||
* Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
|
||||
*
|
||||
* Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
|
||||
* ATOMIC_ENTER_CRITICAL().
|
||||
*
|
||||
*/
|
||||
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
|
||||
|
||||
/* Nested interrupt scheme is supported in this port. */
|
||||
#define ATOMIC_ENTER_CRITICAL() \
|
||||
UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
|
||||
|
||||
#define ATOMIC_EXIT_CRITICAL() \
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
|
||||
|
||||
#else
|
||||
|
||||
/* Nested interrupt scheme is NOT supported in this port. */
|
||||
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
|
||||
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
|
||||
|
||||
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
|
||||
|
||||
/*
|
||||
* Port specific definition -- "always inline".
|
||||
* Inline is compiler specific, and may not always get inlined depending on your
|
||||
* optimization level. Also, inline is considered as performance optimization
|
||||
* for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
|
||||
* instead of resulting error, simply define it away.
|
||||
*/
|
||||
#ifndef portFORCE_INLINE
|
||||
#define portFORCE_INLINE
|
||||
#endif
|
||||
|
||||
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
|
||||
#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
|
||||
|
||||
/*----------------------------- Swap && CAS ------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic compare-and-swap
|
||||
*
|
||||
* @brief Performs an atomic compare-and-swap operation on the specified values.
|
||||
*
|
||||
* @param[in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and checked.
|
||||
* @param[in] ulExchange If condition meets, write this value to memory.
|
||||
* @param[in] ulComparand Swap condition.
|
||||
*
|
||||
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||
*
|
||||
* @note This function only swaps *pulDestination with ulExchange, if previous
|
||||
* *pulDestination value equals ulComparand.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
|
||||
uint32_t ulExchange,
|
||||
uint32_t ulComparand )
|
||||
{
|
||||
uint32_t ulReturnValue;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
if( *pulDestination == ulComparand )
|
||||
{
|
||||
*pulDestination = ulExchange;
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||
}
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulReturnValue;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic swap (pointers)
|
||||
*
|
||||
* @brief Atomically sets the address pointed to by *ppvDestination to the value
|
||||
* of *pvExchange.
|
||||
*
|
||||
* @param[in, out] ppvDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and written back to.
|
||||
* @param[in] pvExchange Pointer value to be written to *ppvDestination.
|
||||
*
|
||||
* @return The initial value of *ppvDestination.
|
||||
*/
|
||||
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
|
||||
void * pvExchange )
|
||||
{
|
||||
void * pReturnValue;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
pReturnValue = *ppvDestination;
|
||||
*ppvDestination = pvExchange;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return pReturnValue;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic compare-and-swap (pointers)
|
||||
*
|
||||
* @brief Performs an atomic compare-and-swap operation on the specified pointer
|
||||
* values.
|
||||
*
|
||||
* @param[in, out] ppvDestination Pointer to memory location from where a pointer
|
||||
* value is to be loaded and checked.
|
||||
* @param[in] pvExchange If condition meets, write this value to memory.
|
||||
* @param[in] pvComparand Swap condition.
|
||||
*
|
||||
* @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
|
||||
*
|
||||
* @note This function only swaps *ppvDestination with pvExchange, if previous
|
||||
* *ppvDestination value equals pvComparand.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
|
||||
void * pvExchange,
|
||||
void * pvComparand )
|
||||
{
|
||||
uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
if( *ppvDestination == pvComparand )
|
||||
{
|
||||
*ppvDestination = pvExchange;
|
||||
ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulReturnValue;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------- Arithmetic ------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic add
|
||||
*
|
||||
* @brief Atomically adds count to the value of the specified pointer points to.
|
||||
*
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be added to *pulAddend.
|
||||
*
|
||||
* @return previous *pulAddend value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
|
||||
uint32_t ulCount )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulAddend;
|
||||
*pulAddend += ulCount;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic subtract
|
||||
*
|
||||
* @brief Atomically subtracts count from the value of the specified pointer
|
||||
* pointers to.
|
||||
*
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
* @param[in] ulCount Value to be subtract from *pulAddend.
|
||||
*
|
||||
* @return previous *pulAddend value.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
|
||||
uint32_t ulCount )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulAddend;
|
||||
*pulAddend -= ulCount;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic increment
|
||||
*
|
||||
* @brief Atomically increments the value of the specified pointer points to.
|
||||
*
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
*
|
||||
* @return *pulAddend value before increment.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulAddend;
|
||||
*pulAddend += 1;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic decrement
|
||||
*
|
||||
* @brief Atomically decrements the value of the specified pointer points to
|
||||
*
|
||||
* @param[in,out] pulAddend Pointer to memory location from where value is to be
|
||||
* loaded and written back to.
|
||||
*
|
||||
* @return *pulAddend value before decrement.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulAddend;
|
||||
*pulAddend -= 1;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
|
||||
/*----------------------------- Bitwise Logical ------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic OR
|
||||
*
|
||||
* @brief Performs an atomic OR operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ORed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulDestination;
|
||||
*pulDestination |= ulValue;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic AND
|
||||
*
|
||||
* @brief Performs an atomic AND operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be ANDed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulDestination;
|
||||
*pulDestination &= ulValue;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic NAND
|
||||
*
|
||||
* @brief Performs an atomic NAND operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be NANDed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulDestination;
|
||||
*pulDestination = ~( ulCurrent & ulValue );
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Atomic XOR
|
||||
*
|
||||
* @brief Performs an atomic XOR operation on the specified values.
|
||||
*
|
||||
* @param [in, out] pulDestination Pointer to memory location from where value is
|
||||
* to be loaded and written back to.
|
||||
* @param [in] ulValue Value to be XORed with *pulDestination.
|
||||
*
|
||||
* @return The original value of *pulDestination.
|
||||
*/
|
||||
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
|
||||
uint32_t ulValue )
|
||||
{
|
||||
uint32_t ulCurrent;
|
||||
|
||||
ATOMIC_ENTER_CRITICAL();
|
||||
{
|
||||
ulCurrent = *pulDestination;
|
||||
*pulDestination ^= ulValue;
|
||||
}
|
||||
ATOMIC_EXIT_CRITICAL();
|
||||
|
||||
return ulCurrent;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* ATOMIC_H */
|
||||
753
source/shoh/freertos/inc/croutine.h
Normal file
753
source/shoh/freertos/inc/croutine.h
Normal file
@@ -0,0 +1,753 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CO_ROUTINE_H
|
||||
#define CO_ROUTINE_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
||||
#endif
|
||||
|
||||
#include "list.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* Used to hide the implementation of the co-routine control block. The
|
||||
* control block structure however has to be included in the header due to
|
||||
* the macro implementation of the co-routine functionality. */
|
||||
typedef void * CoRoutineHandle_t;
|
||||
|
||||
/* Defines the prototype to which co-routine functions must conform. */
|
||||
typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t,
|
||||
UBaseType_t );
|
||||
|
||||
typedef struct corCoRoutineControlBlock
|
||||
{
|
||||
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||
ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||
ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||
UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||
UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||
uint16_t uxState; /*< Used internally by the co-routine implementation. */
|
||||
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* BaseType_t xCoRoutineCreate(
|
||||
* crCOROUTINE_CODE pxCoRoutineCode,
|
||||
* UBaseType_t uxPriority,
|
||||
* UBaseType_t uxIndex
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
* Create a new co-routine and add it to the list of co-routines that are
|
||||
* ready to run.
|
||||
*
|
||||
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
|
||||
* functions require special syntax - see the co-routine section of the WEB
|
||||
* documentation for more information.
|
||||
*
|
||||
* @param uxPriority The priority with respect to other co-routines at which
|
||||
* the co-routine will run.
|
||||
*
|
||||
* @param uxIndex Used to distinguish between different co-routines that
|
||||
* execute the same function. See the example below and the co-routine section
|
||||
* of the WEB documentation for further information.
|
||||
*
|
||||
* @return pdPASS if the co-routine was successfully created and added to a ready
|
||||
* list, otherwise an error code defined with ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Co-routine to be created.
|
||||
* void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* // This may not be necessary for const variables.
|
||||
* static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||
* static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // This co-routine just delays for a fixed period, then toggles
|
||||
* // an LED. Two co-routines are created using this function, so
|
||||
* // the uxIndex parameter is used to tell the co-routine which
|
||||
* // LED to flash and how int32_t to delay. This assumes xQueue has
|
||||
* // already been created.
|
||||
* vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||
* crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }
|
||||
*
|
||||
* // Function that creates two co-routines.
|
||||
* void vOtherFunction( void )
|
||||
* {
|
||||
* uint8_t ucParameterToPass;
|
||||
* TaskHandle_t xHandle;
|
||||
*
|
||||
* // Create two co-routines at priority 0. The first is given index 0
|
||||
* // so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||
* // is given index 1 so toggles LED 6 every 400 ticks.
|
||||
* for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||
* {
|
||||
* xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||
UBaseType_t uxPriority,
|
||||
UBaseType_t uxIndex );
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* void vCoRoutineSchedule( void );
|
||||
* @endcode
|
||||
*
|
||||
* Run a co-routine.
|
||||
*
|
||||
* vCoRoutineSchedule() executes the highest priority co-routine that is able
|
||||
* to run. The co-routine will execute until it either blocks, yields or is
|
||||
* preempted by a task. Co-routines execute cooperatively so one
|
||||
* co-routine cannot be preempted by another, but can be preempted by a task.
|
||||
*
|
||||
* If an application comprises of both tasks and co-routines then
|
||||
* vCoRoutineSchedule should be called from the idle task (in an idle task
|
||||
* hook).
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // This idle task hook will schedule a co-routine each time it is called.
|
||||
* // The rest of the idle task will execute between co-routine calls.
|
||||
* void vApplicationIdleHook( void )
|
||||
* {
|
||||
* vCoRoutineSchedule();
|
||||
* }
|
||||
*
|
||||
* // Alternatively, if you do not require any other part of the idle task to
|
||||
* // execute, the idle task hook can call vCoRoutineSchedule() within an
|
||||
* // infinite loop.
|
||||
* void vApplicationIdleHook( void )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* vCoRoutineSchedule();
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
void vCoRoutineSchedule( void );
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* crSTART( CoRoutineHandle_t xHandle );
|
||||
* @endcode
|
||||
*
|
||||
* This macro MUST always be called at the start of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Co-routine to be created.
|
||||
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static int32_t ulAVariable;
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Co-routine functionality goes here.
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crSTART( pxCRCB ) \
|
||||
switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \
|
||||
case 0:
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* crEND();
|
||||
* @endcode
|
||||
*
|
||||
* This macro MUST always be called at the end of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Co-routine to be created.
|
||||
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static int32_t ulAVariable;
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Co-routine functionality goes here.
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crEND() }
|
||||
|
||||
/*
|
||||
* These macros are intended for internal use by the co-routine implementation
|
||||
* only. The macros should not be used directly by application writers.
|
||||
*/
|
||||
#define crSET_STATE0( xHandle ) \
|
||||
( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \
|
||||
case ( __LINE__ * 2 ):
|
||||
#define crSET_STATE1( xHandle ) \
|
||||
( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \
|
||||
case ( ( __LINE__ * 2 ) + 1 ):
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
|
||||
* @endcode
|
||||
*
|
||||
* Delay a co-routine for a fixed period of time.
|
||||
*
|
||||
* crDELAY can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* @param xHandle The handle of the co-routine to delay. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||
* for. The actual amount of time this equates to is defined by
|
||||
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS
|
||||
* can be used to convert ticks to milliseconds.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Co-routine to be created.
|
||||
* void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* // This may not be necessary for const variables.
|
||||
* // We are to delay for 200ms.
|
||||
* static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||
*
|
||||
* // Must start every co-routine with a call to crSTART();
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Delay for 200ms.
|
||||
* crDELAY( xHandle, xDelayTime );
|
||||
*
|
||||
* // Do something here.
|
||||
* }
|
||||
*
|
||||
* // Must end every co-routine with a call to crEND();
|
||||
* crEND();
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crDELAY crDELAY
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crDELAY( xHandle, xTicksToDelay ) \
|
||||
if( ( xTicksToDelay ) > 0 ) \
|
||||
{ \
|
||||
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
|
||||
} \
|
||||
crSET_STATE0( ( xHandle ) );
|
||||
|
||||
/**
|
||||
* @code{c}
|
||||
* crQUEUE_SEND(
|
||||
* CoRoutineHandle_t xHandle,
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvItemToQueue,
|
||||
* TickType_t xTicksToWait,
|
||||
* BaseType_t *pxResult
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||
*
|
||||
* crQUEUE_SEND can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param pxQueue The handle of the queue on which the data will be posted.
|
||||
* The handle is obtained as the return value when the queue is created using
|
||||
* the xQueueCreate() API function.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the data being posted onto the queue.
|
||||
* The number of bytes of each queued item is specified when the queue is
|
||||
* created. This number of bytes is copied from pvItemToQueue into the queue
|
||||
* itself.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||
* to wait for space to become available on the queue, should space not be
|
||||
* available immediately. The actual amount of time this equates to is defined
|
||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
|
||||
* below).
|
||||
*
|
||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||
* data was successfully posted onto the queue, otherwise it will be set to an
|
||||
* error defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Co-routine function that blocks for a fixed period then posts a number onto
|
||||
* // a queue.
|
||||
* static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static BaseType_t xNumberToPost = 0;
|
||||
* static BaseType_t xResult;
|
||||
*
|
||||
* // Co-routines must begin with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // This assumes the queue has already been created.
|
||||
* crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||
*
|
||||
* if( xResult != pdPASS )
|
||||
* {
|
||||
* // The message was not posted!
|
||||
* }
|
||||
*
|
||||
* // Increment the number to be posted onto the queue.
|
||||
* xNumberToPost++;
|
||||
*
|
||||
* // Delay for 100 ticks.
|
||||
* crDELAY( xHandle, 100 );
|
||||
* }
|
||||
*
|
||||
* // Co-routines must end with a call to crEND().
|
||||
* crEND();
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
||||
{ \
|
||||
*( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \
|
||||
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||
{ \
|
||||
crSET_STATE0( ( xHandle ) ); \
|
||||
*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \
|
||||
} \
|
||||
if( *pxResult == errQUEUE_YIELD ) \
|
||||
{ \
|
||||
crSET_STATE1( ( xHandle ) ); \
|
||||
*pxResult = pdPASS; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* crQUEUE_RECEIVE(
|
||||
* CoRoutineHandle_t xHandle,
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvBuffer,
|
||||
* TickType_t xTicksToWait,
|
||||
* BaseType_t *pxResult
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||
*
|
||||
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param pxQueue The handle of the queue from which the data will be received.
|
||||
* The handle is obtained as the return value when the queue is created using
|
||||
* the xQueueCreate() API function.
|
||||
*
|
||||
* @param pvBuffer The buffer into which the received item is to be copied.
|
||||
* The number of bytes of each queued item is specified when the queue is
|
||||
* created. This number of bytes is copied into pvBuffer.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||
* to wait for data to become available from the queue, should data not be
|
||||
* available immediately. The actual amount of time this equates to is defined
|
||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
|
||||
* crQUEUE_SEND example).
|
||||
*
|
||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||
* data was successfully retrieved from the queue, otherwise it will be set to
|
||||
* an error code as defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // A co-routine receives the number of an LED to flash from a queue. It
|
||||
* // blocks on the queue until the number is received.
|
||||
* static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
* static BaseType_t xResult;
|
||||
* static UBaseType_t uxLEDToFlash;
|
||||
*
|
||||
* // All co-routines must start with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Wait for data to become available on the queue.
|
||||
* crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
*
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // We received the LED to flash - flash it!
|
||||
* vParTestToggleLED( uxLEDToFlash );
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* crEND();
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
||||
{ \
|
||||
*( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \
|
||||
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||
{ \
|
||||
crSET_STATE0( ( xHandle ) ); \
|
||||
*( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 ); \
|
||||
} \
|
||||
if( *( pxResult ) == errQUEUE_YIELD ) \
|
||||
{ \
|
||||
crSET_STATE1( ( xHandle ) ); \
|
||||
*( pxResult ) = pdPASS; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* crQUEUE_SEND_FROM_ISR(
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvItemToQueue,
|
||||
* BaseType_t xCoRoutinePreviouslyWoken
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
* functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||
* ISR.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
|
||||
* that is being used from within a co-routine.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||
* queue. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||
* into the queue storage area.
|
||||
*
|
||||
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
|
||||
* the same queue multiple times from a single interrupt. The first call
|
||||
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||
* the value returned from the previous call.
|
||||
*
|
||||
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
|
||||
* used by the ISR to determine if a context switch may be required following
|
||||
* the ISR.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // A co-routine that blocks on a queue waiting for characters to be received.
|
||||
* static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* char cRxedChar;
|
||||
* BaseType_t xResult;
|
||||
*
|
||||
* // All co-routines must start with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Wait for data to become available on the queue. This assumes the
|
||||
* // queue xCommsRxQueue has already been created!
|
||||
* crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
*
|
||||
* // Was a character received?
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // Process the character here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // All co-routines must end with a call to crEND().
|
||||
* crEND();
|
||||
* }
|
||||
*
|
||||
* // An ISR that uses a queue to send characters received on a serial port to
|
||||
* // a co-routine.
|
||||
* void vUART_ISR( void )
|
||||
* {
|
||||
* char cRxedChar;
|
||||
* BaseType_t xCRWokenByPost = pdFALSE;
|
||||
*
|
||||
* // We loop around reading characters until there are none left in the UART.
|
||||
* while( UART_RX_REG_NOT_EMPTY() )
|
||||
* {
|
||||
* // Obtain the character from the UART.
|
||||
* cRxedChar = UART_RX_REG;
|
||||
*
|
||||
* // Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||
* // the first time around the loop. If the post causes a co-routine
|
||||
* // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||
* // In this manner we can ensure that if more than one co-routine is
|
||||
* // blocked on the queue only one is woken by this ISR no matter how
|
||||
* // many characters are posted to the queue.
|
||||
* xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) \
|
||||
xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* @code{c}
|
||||
* crQUEUE_SEND_FROM_ISR(
|
||||
* QueueHandle_t pxQueue,
|
||||
* void *pvBuffer,
|
||||
* BaseType_t * pxCoRoutineWoken
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
* functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||
* ISR.
|
||||
*
|
||||
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
|
||||
* from a queue that is being used from within a co-routine (a co-routine
|
||||
* posted to the queue).
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvBuffer A pointer to a buffer into which the received item will be
|
||||
* placed. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from the queue into
|
||||
* pvBuffer.
|
||||
*
|
||||
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
|
||||
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
|
||||
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
|
||||
* *pxCoRoutineWoken will remain unchanged.
|
||||
*
|
||||
* @return pdTRUE an item was successfully received from the queue, otherwise
|
||||
* pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // A co-routine that posts a character to a queue then blocks for a fixed
|
||||
* // period. The character is incremented each time.
|
||||
* static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
* {
|
||||
* // cChar holds its value while this co-routine is blocked and must therefore
|
||||
* // be declared static.
|
||||
* static char cCharToTx = 'a';
|
||||
* BaseType_t xResult;
|
||||
*
|
||||
* // All co-routines must start with a call to crSTART().
|
||||
* crSTART( xHandle );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Send the next character to the queue.
|
||||
* crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||
*
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // The character was successfully posted to the queue.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Could not post the character to the queue.
|
||||
* }
|
||||
*
|
||||
* // Enable the UART Tx interrupt to cause an interrupt in this
|
||||
* // hypothetical UART. The interrupt will obtain the character
|
||||
* // from the queue and send it.
|
||||
* ENABLE_RX_INTERRUPT();
|
||||
*
|
||||
* // Increment to the next character then block for a fixed period.
|
||||
* // cCharToTx will maintain its value across the delay as it is
|
||||
* // declared static.
|
||||
* cCharToTx++;
|
||||
* if( cCharToTx > 'x' )
|
||||
* {
|
||||
* cCharToTx = 'a';
|
||||
* }
|
||||
* crDELAY( 100 );
|
||||
* }
|
||||
*
|
||||
* // All co-routines must end with a call to crEND().
|
||||
* crEND();
|
||||
* }
|
||||
*
|
||||
* // An ISR that uses a queue to receive characters to send on a UART.
|
||||
* void vUART_ISR( void )
|
||||
* {
|
||||
* char cCharToTx;
|
||||
* BaseType_t xCRWokenByPost = pdFALSE;
|
||||
*
|
||||
* while( UART_TX_REG_EMPTY() )
|
||||
* {
|
||||
* // Are there any characters in the queue waiting to be sent?
|
||||
* // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||
* // is woken by the post - ensuring that only a single co-routine is
|
||||
* // woken no matter how many times we go around this loop.
|
||||
* if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||
* {
|
||||
* SEND_CHARACTER( cCharToTx );
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) \
|
||||
xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the co-routine macros only.
|
||||
* The macro nature of the co-routine implementation requires that the
|
||||
* prototype appears here. The function should not be used by application
|
||||
* writers.
|
||||
*
|
||||
* Removes the current co-routine from its ready list and places it in the
|
||||
* appropriate delayed list.
|
||||
*/
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||
List_t * pxEventList );
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the queue implementation only.
|
||||
* The function should not be used by application writers.
|
||||
*
|
||||
* Removes the highest priority co-routine from the event list and places it in
|
||||
* the pending ready list.
|
||||
*/
|
||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList );
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* CO_ROUTINE_H */
|
||||
281
source/shoh/freertos/inc/deprecated_definitions.h
Normal file
281
source/shoh/freertos/inc/deprecated_definitions.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DEPRECATED_DEFINITIONS_H
|
||||
#define DEPRECATED_DEFINITIONS_H
|
||||
|
||||
|
||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||
* pre-processor definition was used to ensure the pre-processor found the correct
|
||||
* portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||
* of setting the compiler's include path such that it found the correct
|
||||
* portmacro.h file - removing the need for the constant and allowing the
|
||||
* portmacro.h file to be located anywhere in relation to the port being used. The
|
||||
* definitions below remain in the code for backward compatibility only. New
|
||||
* projects should not use them. */
|
||||
|
||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||
typedef void ( __interrupt __far * pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||
typedef void ( __interrupt __far * pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MEGA_AVR
|
||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC24_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_DSPIC_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC18F_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC32MX_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FEDPICC
|
||||
#include "libFreeRTOS/Include/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDCC_CYGNAL
|
||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7
|
||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7_ECLIPSE
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_LPC23xx
|
||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MSP430
|
||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MSP430
|
||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_MSP430
|
||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_GCC
|
||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM9XE_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPC2000_IAR
|
||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR71X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_GCC
|
||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR91X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_H8S
|
||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_AT91FR40008
|
||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef RVDS_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARM_CM3
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARMCM3_LM
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef HCS12_CODE_WARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROBLAZE_GCC
|
||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef TERN_EE
|
||||
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_HCS12
|
||||
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MCF5235
|
||||
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_GCC
|
||||
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC405
|
||||
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC440
|
||||
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _16FX_SOFTUNE
|
||||
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||
|
||||
/* A short file name has to be used in place of the normal
|
||||
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||
typedef void ( __interrupt __far * pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef BCC_FLASH_LITE_186_PORT
|
||||
|
||||
/* A short file name has to be used in place of the normal
|
||||
* FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far * pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __AVR32_AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __ICCAVR32__
|
||||
#ifdef __CORE__
|
||||
#if __CORE__ == __AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __91467D
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __96340
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __IAR_V850ES_Fx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3_L__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Hx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3L__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||
783
source/shoh/freertos/inc/event_groups.h
Normal file
783
source/shoh/freertos/inc/event_groups.h
Normal file
@@ -0,0 +1,783 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EVENT_GROUPS_H
|
||||
#define EVENT_GROUPS_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
||||
#endif
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "timers.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**
|
||||
* An event group is a collection of bits to which an application can assign a
|
||||
* meaning. For example, an application may create an event group to convey
|
||||
* the status of various CAN bus related events in which bit 0 might mean "A CAN
|
||||
* message has been received and is ready for processing", bit 1 might mean "The
|
||||
* application has queued a message that is ready for sending onto the CAN
|
||||
* network", and bit 2 might mean "It is time to send a SYNC message onto the
|
||||
* CAN network" etc. A task can then test the bit values to see which events
|
||||
* are active, and optionally enter the Blocked state to wait for a specified
|
||||
* bit or a group of specified bits to be active. To continue the CAN bus
|
||||
* example, a CAN controlling task can enter the Blocked state (and therefore
|
||||
* not consume any processing time) until either bit 0, bit 1 or bit 2 are
|
||||
* active, at which time the bit that was actually active would inform the task
|
||||
* which action it had to take (process a received message, send a message, or
|
||||
* send a SYNC).
|
||||
*
|
||||
* The event groups implementation contains intelligence to avoid race
|
||||
* conditions that would otherwise occur were an application to use a simple
|
||||
* variable for the same purpose. This is particularly important with respect
|
||||
* to when a bit within an event group is to be cleared, and when bits have to
|
||||
* be set and then tested atomically - as is the case where event groups are
|
||||
* used to create a synchronisation point between multiple tasks (a
|
||||
* 'rendezvous').
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*
|
||||
* Type by which event groups are referenced. For example, a call to
|
||||
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then
|
||||
* be used as a parameter to other event group functions.
|
||||
*
|
||||
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
struct EventGroupDef_t;
|
||||
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||
|
||||
/*
|
||||
* The type that holds event bits always matches TickType_t - therefore the
|
||||
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
|
||||
* 32 bits if set to 0.
|
||||
*
|
||||
* \defgroup EventBits_t EventBits_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventGroupHandle_t xEventGroupCreate( void );
|
||||
* @endcode
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||
* block of memory, in which the event group's structure is stored. If an event
|
||||
* groups is created using xEventGroupCreate() then the required memory is
|
||||
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||
* (see https://www.FreeRTOS.org/a00111.html). If an event group is created
|
||||
* using xEventGroupCreateStatic() then the application writer must instead
|
||||
* provide the memory that will get used by the event group.
|
||||
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||
* without using any dynamic memory allocation.
|
||||
*
|
||||
* Although event groups are not related to ticks, for internal implementation
|
||||
* reasons the number of bits available for use in an event group is dependent
|
||||
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||
* event bits within an event group.
|
||||
*
|
||||
* @return If the event group was created then a handle to the event group is
|
||||
* returned. If there was insufficient FreeRTOS heap available to create the
|
||||
* event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Declare a variable to hold the created event group.
|
||||
* EventGroupHandle_t xCreatedEventGroup;
|
||||
*
|
||||
* // Attempt to create the event group.
|
||||
* xCreatedEventGroup = xEventGroupCreate();
|
||||
*
|
||||
* // Was the event group created successfully?
|
||||
* if( xCreatedEventGroup == NULL )
|
||||
* {
|
||||
* // The event group was not created because there was insufficient
|
||||
* // FreeRTOS heap available.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // The event group was created.
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xEventGroupCreate xEventGroupCreate
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||
* block of memory, in which the event group's structure is stored. If an event
|
||||
* groups is created using xEventGroupCreate() then the required memory is
|
||||
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||
* (see https://www.FreeRTOS.org/a00111.html). If an event group is created
|
||||
* using xEventGroupCreateStatic() then the application writer must instead
|
||||
* provide the memory that will get used by the event group.
|
||||
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||
* without using any dynamic memory allocation.
|
||||
*
|
||||
* Although event groups are not related to ticks, for internal implementation
|
||||
* reasons the number of bits available for use in an event group is dependent
|
||||
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||
* event bits within an event group.
|
||||
*
|
||||
* @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
|
||||
* StaticEventGroup_t, which will be then be used to hold the event group's data
|
||||
* structures, removing the need for the memory to be allocated dynamically.
|
||||
*
|
||||
* @return If the event group was created then a handle to the event group is
|
||||
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // StaticEventGroup_t is a publicly accessible structure that has the same
|
||||
* // size and alignment requirements as the real event group structure. It is
|
||||
* // provided as a mechanism for applications to know the size of the event
|
||||
* // group (which is dependent on the architecture and configuration file
|
||||
* // settings) without breaking the strict data hiding policy by exposing the
|
||||
* // real event group internals. This StaticEventGroup_t variable is passed
|
||||
* // into the xSemaphoreCreateEventGroupStatic() function and is used to store
|
||||
* // the event group's data structures
|
||||
* StaticEventGroup_t xEventGroupBuffer;
|
||||
*
|
||||
* // Create the event group without dynamically allocating any memory.
|
||||
* xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||
* @endcode
|
||||
*/
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
* const EventBits_t uxBitsToWaitFor,
|
||||
* const BaseType_t xClearOnExit,
|
||||
* const BaseType_t xWaitForAllBits,
|
||||
* const TickType_t xTicksToWait );
|
||||
* @endcode
|
||||
*
|
||||
* [Potentially] block to wait for one or more bits to be set within a
|
||||
* previously created event group.
|
||||
*
|
||||
* This function cannot be called from an interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are being tested. The
|
||||
* event group must have previously been created using a call to
|
||||
* xEventGroupCreate().
|
||||
*
|
||||
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. For example, to wait for bit 0 and/or bit 2 set
|
||||
* uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
|
||||
* uxBitsToWaitFor to 0x07. Etc.
|
||||
*
|
||||
* @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
|
||||
* uxBitsToWaitFor that are set within the event group will be cleared before
|
||||
* xEventGroupWaitBits() returns if the wait condition was met (if the function
|
||||
* returns for a reason other than a timeout). If xClearOnExit is set to
|
||||
* pdFALSE then the bits set in the event group are not altered when the call to
|
||||
* xEventGroupWaitBits() returns.
|
||||
*
|
||||
* @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
|
||||
* xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
|
||||
* are set or the specified block time expires. If xWaitForAllBits is set to
|
||||
* pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
|
||||
* in uxBitsToWaitFor is set or the specified block time expires. The block
|
||||
* time is specified by the xTicksToWait parameter.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||
* for one/all (depending on the xWaitForAllBits value) of the bits specified by
|
||||
* uxBitsToWaitFor to become set. A value of portMAX_DELAY can be used to block
|
||||
* indefinitely (provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
|
||||
*
|
||||
* @return The value of the event group at the time either the bits being waited
|
||||
* for became set, or the block time expired. Test the return value to know
|
||||
* which bits were set. If xEventGroupWaitBits() returned because its timeout
|
||||
* expired then not all the bits being waited for will be set. If
|
||||
* xEventGroupWaitBits() returned because the bits it was waiting for were set
|
||||
* then the returned value is the event group value before any bits were
|
||||
* automatically cleared in the case that xClearOnExit parameter was set to
|
||||
* pdTRUE.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* #define BIT_0 ( 1 << 0 )
|
||||
* #define BIT_4 ( 1 << 4 )
|
||||
*
|
||||
* void aFunction( EventGroupHandle_t xEventGroup )
|
||||
* {
|
||||
* EventBits_t uxBits;
|
||||
* const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||
*
|
||||
* // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
||||
* // the event group. Clear the bits before exiting.
|
||||
* uxBits = xEventGroupWaitBits(
|
||||
* xEventGroup, // The event group being tested.
|
||||
* BIT_0 | BIT_4, // The bits within the event group to wait for.
|
||||
* pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
||||
* pdFALSE, // Don't wait for both bits, either bit will do.
|
||||
* xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
||||
*
|
||||
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
* {
|
||||
* // xEventGroupWaitBits() returned because both bits were set.
|
||||
* }
|
||||
* else if( ( uxBits & BIT_0 ) != 0 )
|
||||
* {
|
||||
* // xEventGroupWaitBits() returned because just BIT_0 was set.
|
||||
* }
|
||||
* else if( ( uxBits & BIT_4 ) != 0 )
|
||||
* {
|
||||
* // xEventGroupWaitBits() returned because just BIT_4 was set.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
||||
* // without either BIT_0 or BIT_4 becoming set.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||
* @endcode
|
||||
*
|
||||
* Clear bits within an event group. This function cannot be called from an
|
||||
* interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||
*
|
||||
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
|
||||
* in the event group. For example, to clear bit 3 only, set uxBitsToClear to
|
||||
* 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
|
||||
*
|
||||
* @return The value of the event group before the specified bits were cleared.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* #define BIT_0 ( 1 << 0 )
|
||||
* #define BIT_4 ( 1 << 4 )
|
||||
*
|
||||
* void aFunction( EventGroupHandle_t xEventGroup )
|
||||
* {
|
||||
* EventBits_t uxBits;
|
||||
*
|
||||
* // Clear bit 0 and bit 4 in xEventGroup.
|
||||
* uxBits = xEventGroupClearBits(
|
||||
* xEventGroup, // The event group being updated.
|
||||
* BIT_0 | BIT_4 );// The bits being cleared.
|
||||
*
|
||||
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
* {
|
||||
* // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
||||
* // called. Both will now be clear (not set).
|
||||
* }
|
||||
* else if( ( uxBits & BIT_0 ) != 0 )
|
||||
* {
|
||||
* // Bit 0 was set before xEventGroupClearBits() was called. It will
|
||||
* // now be clear.
|
||||
* }
|
||||
* else if( ( uxBits & BIT_4 ) != 0 )
|
||||
* {
|
||||
* // Bit 4 was set before xEventGroupClearBits() was called. It will
|
||||
* // now be clear.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Neither bit 0 nor bit 4 were set in the first place.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
* @endcode
|
||||
*
|
||||
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because there
|
||||
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||
* set. FreeRTOS does not allow nondeterministic operations to be performed
|
||||
* while interrupts are disabled, so protects event groups that are accessed
|
||||
* from tasks by suspending the scheduler rather than disabling interrupts. As
|
||||
* a result event groups cannot be accessed directly from an interrupt service
|
||||
* routine. Therefore xEventGroupClearBitsFromISR() sends a message to the
|
||||
* timer task to have the clear operation performed in the context of the timer
|
||||
* task.
|
||||
*
|
||||
* @note If this function returns pdPASS then the timer task is ready to run
|
||||
* and a portYIELD_FROM_ISR(pdTRUE) should be executed to perform the needed
|
||||
* clear on the event group. This behavior is different from
|
||||
* xEventGroupSetBitsFromISR because the parameter xHigherPriorityTaskWoken is
|
||||
* not present.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||
*
|
||||
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
|
||||
* For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3
|
||||
* and bit 0 set uxBitsToClear to 0x09.
|
||||
*
|
||||
* @return If the request to execute the function was posted successfully then
|
||||
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* #define BIT_0 ( 1 << 0 )
|
||||
* #define BIT_4 ( 1 << 4 )
|
||||
*
|
||||
* // An event group which it is assumed has already been created by a call to
|
||||
* // xEventGroupCreate().
|
||||
* EventGroupHandle_t xEventGroup;
|
||||
*
|
||||
* void anInterruptHandler( void )
|
||||
* {
|
||||
* // Clear bit 0 and bit 4 in xEventGroup.
|
||||
* xResult = xEventGroupClearBitsFromISR(
|
||||
* xEventGroup, // The event group being updated.
|
||||
* BIT_0 | BIT_4 ); // The bits being set.
|
||||
*
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // The message was posted successfully.
|
||||
* portYIELD_FROM_ISR(pdTRUE);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \
|
||||
xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
* @endcode
|
||||
*
|
||||
* Set bits within an event group.
|
||||
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
||||
* is a version that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group will automatically unblock tasks that are
|
||||
* blocked waiting for the bits.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be set.
|
||||
*
|
||||
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||
* and bit 0 set uxBitsToSet to 0x09.
|
||||
*
|
||||
* @return The value of the event group at the time the call to
|
||||
* xEventGroupSetBits() returns. There are two reasons why the returned value
|
||||
* might have the bits specified by the uxBitsToSet parameter cleared. First,
|
||||
* if setting a bit results in a task that was waiting for the bit leaving the
|
||||
* blocked state then it is possible the bit will be cleared automatically
|
||||
* (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
|
||||
* unblocked (or otherwise Ready state) task that has a priority above that of
|
||||
* the task that called xEventGroupSetBits() will execute and may change the
|
||||
* event group value before the call to xEventGroupSetBits() returns.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* #define BIT_0 ( 1 << 0 )
|
||||
* #define BIT_4 ( 1 << 4 )
|
||||
*
|
||||
* void aFunction( EventGroupHandle_t xEventGroup )
|
||||
* {
|
||||
* EventBits_t uxBits;
|
||||
*
|
||||
* // Set bit 0 and bit 4 in xEventGroup.
|
||||
* uxBits = xEventGroupSetBits(
|
||||
* xEventGroup, // The event group being updated.
|
||||
* BIT_0 | BIT_4 );// The bits being set.
|
||||
*
|
||||
* if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
* {
|
||||
* // Both bit 0 and bit 4 remained set when the function returned.
|
||||
* }
|
||||
* else if( ( uxBits & BIT_0 ) != 0 )
|
||||
* {
|
||||
* // Bit 0 remained set when the function returned, but bit 4 was
|
||||
* // cleared. It might be that bit 4 was cleared automatically as a
|
||||
* // task that was waiting for bit 4 was removed from the Blocked
|
||||
* // state.
|
||||
* }
|
||||
* else if( ( uxBits & BIT_4 ) != 0 )
|
||||
* {
|
||||
* // Bit 4 remained set when the function returned, but bit 0 was
|
||||
* // cleared. It might be that bit 0 was cleared automatically as a
|
||||
* // task that was waiting for bit 0 was removed from the Blocked
|
||||
* // state.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // Neither bit 0 nor bit 4 remained set. It might be that a task
|
||||
* // was waiting for both of the bits to be set, and the bits were
|
||||
* // cleared as the task left the Blocked state.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because there
|
||||
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||
* set. FreeRTOS does not allow nondeterministic operations to be performed in
|
||||
* interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR()
|
||||
* sends a message to the timer task to have the set operation performed in the
|
||||
* context of the timer task - where a scheduler lock is used in place of a
|
||||
* critical section.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be set.
|
||||
*
|
||||
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||
* and bit 0 set uxBitsToSet to 0x09.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function
|
||||
* will result in a message being sent to the timer daemon task. If the
|
||||
* priority of the timer daemon task is higher than the priority of the
|
||||
* currently running task (the task the interrupt interrupted) then
|
||||
* *pxHigherPriorityTaskWoken will be set to pdTRUE by
|
||||
* xEventGroupSetBitsFromISR(), indicating that a context switch should be
|
||||
* requested before the interrupt exits. For that reason
|
||||
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
|
||||
* example code below.
|
||||
*
|
||||
* @return If the request to execute the function was posted successfully then
|
||||
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* #define BIT_0 ( 1 << 0 )
|
||||
* #define BIT_4 ( 1 << 4 )
|
||||
*
|
||||
* // An event group which it is assumed has already been created by a call to
|
||||
* // xEventGroupCreate().
|
||||
* EventGroupHandle_t xEventGroup;
|
||||
*
|
||||
* void anInterruptHandler( void )
|
||||
* {
|
||||
* BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||
*
|
||||
* // xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
||||
* xHigherPriorityTaskWoken = pdFALSE;
|
||||
*
|
||||
* // Set bit 0 and bit 4 in xEventGroup.
|
||||
* xResult = xEventGroupSetBitsFromISR(
|
||||
* xEventGroup, // The event group being updated.
|
||||
* BIT_0 | BIT_4 // The bits being set.
|
||||
* &xHigherPriorityTaskWoken );
|
||||
*
|
||||
* // Was the message posted successfully?
|
||||
* if( xResult == pdPASS )
|
||||
* {
|
||||
* // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||
* // switch should be requested. The macro used is port specific and
|
||||
* // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||
* // refer to the documentation page for the port being used.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \
|
||||
xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
* const EventBits_t uxBitsToSet,
|
||||
* const EventBits_t uxBitsToWaitFor,
|
||||
* TickType_t xTicksToWait );
|
||||
* @endcode
|
||||
*
|
||||
* Atomically set bits within an event group, then wait for a combination of
|
||||
* bits to be set within the same event group. This functionality is typically
|
||||
* used to synchronise multiple tasks, where each task has to wait for the other
|
||||
* tasks to reach a synchronisation point before proceeding.
|
||||
*
|
||||
* This function cannot be used from an interrupt.
|
||||
*
|
||||
* The function will return before its block time expires if the bits specified
|
||||
* by the uxBitsToWait parameter are set, or become set within that time. In
|
||||
* this case all the bits specified by uxBitsToWait will be automatically
|
||||
* cleared before the function returns.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are being tested. The
|
||||
* event group must have previously been created using a call to
|
||||
* xEventGroupCreate().
|
||||
*
|
||||
* @param uxBitsToSet The bits to set in the event group before determining
|
||||
* if, and possibly waiting for, all the bits specified by the uxBitsToWait
|
||||
* parameter are set.
|
||||
*
|
||||
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. For example, to wait for bit 0 and bit 2 set
|
||||
* uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set
|
||||
* uxBitsToWaitFor to 0x07. Etc.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||
* for all of the bits specified by uxBitsToWaitFor to become set.
|
||||
*
|
||||
* @return The value of the event group at the time either the bits being waited
|
||||
* for became set, or the block time expired. Test the return value to know
|
||||
* which bits were set. If xEventGroupSync() returned because its timeout
|
||||
* expired then not all the bits being waited for will be set. If
|
||||
* xEventGroupSync() returned because all the bits it was waiting for were
|
||||
* set then the returned value is the event group value before any bits were
|
||||
* automatically cleared.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Bits used by the three tasks.
|
||||
* #define TASK_0_BIT ( 1 << 0 )
|
||||
* #define TASK_1_BIT ( 1 << 1 )
|
||||
* #define TASK_2_BIT ( 1 << 2 )
|
||||
*
|
||||
* #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
||||
*
|
||||
* // Use an event group to synchronise three tasks. It is assumed this event
|
||||
* // group has already been created elsewhere.
|
||||
* EventGroupHandle_t xEventBits;
|
||||
*
|
||||
* void vTask0( void *pvParameters )
|
||||
* {
|
||||
* EventBits_t uxReturn;
|
||||
* TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Perform task functionality here.
|
||||
*
|
||||
* // Set bit 0 in the event flag to note this task has reached the
|
||||
* // sync point. The other two tasks will set the other two bits defined
|
||||
* // by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
||||
* // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
||||
* // for this to happen.
|
||||
* uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
||||
*
|
||||
* if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
||||
* {
|
||||
* // All three tasks reached the synchronisation point before the call
|
||||
* // to xEventGroupSync() timed out.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* void vTask1( void *pvParameters )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Perform task functionality here.
|
||||
*
|
||||
* // Set bit 1 in the event flag to note this task has reached the
|
||||
* // synchronisation point. The other two tasks will set the other two
|
||||
* // bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||
* // synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||
* // indefinitely for this to happen.
|
||||
* xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||
*
|
||||
* // xEventGroupSync() was called with an indefinite block time, so
|
||||
* // this task will only reach here if the synchronisation was made by all
|
||||
* // three tasks, so there is no need to test the return value.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* void vTask2( void *pvParameters )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Perform task functionality here.
|
||||
*
|
||||
* // Set bit 2 in the event flag to note this task has reached the
|
||||
* // synchronisation point. The other two tasks will set the other two
|
||||
* // bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||
* // synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||
* // indefinitely for this to happen.
|
||||
* xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||
*
|
||||
* // xEventGroupSync() was called with an indefinite block time, so
|
||||
* // this task will only reach here if the synchronisation was made by all
|
||||
* // three tasks, so there is no need to test the return value.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
* \defgroup xEventGroupSync xEventGroupSync
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
||||
* @endcode
|
||||
*
|
||||
* Returns the current value of the bits in an event group. This function
|
||||
* cannot be used from an interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group being queried.
|
||||
*
|
||||
* @return The event group bits at the time xEventGroupGetBits() was called.
|
||||
*
|
||||
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( ( xEventGroup ), 0 )
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||
* @endcode
|
||||
*
|
||||
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||
*
|
||||
* @param xEventGroup The event group being queried.
|
||||
*
|
||||
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
|
||||
*
|
||||
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
* @code{c}
|
||||
* void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||
* @endcode
|
||||
*
|
||||
* Delete an event group that was previously created by a call to
|
||||
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
||||
* unblocked and obtain 0 as the event group's value.
|
||||
*
|
||||
* @param xEventGroup The event group being deleted.
|
||||
*/
|
||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* For internal use only. */
|
||||
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupSetNumber( void * xEventGroup,
|
||||
UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* EVENT_GROUPS_H */
|
||||
503
source/shoh/freertos/inc/list.h
Normal file
503
source/shoh/freertos/inc/list.h
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the list implementation used by the scheduler. While it is tailored
|
||||
* heavily for the schedulers needs, it is also available for use by
|
||||
* application code.
|
||||
*
|
||||
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||
* ascending item value order.
|
||||
*
|
||||
* Lists are created already containing one list item. The value of this
|
||||
* item is the maximum possible that can be stored, it is therefore always at
|
||||
* the end of the list and acts as a marker. The list member pxHead always
|
||||
* points to this marker - even though it is at the tail of the list. This
|
||||
* is because the tail contains a wrap back pointer to the true head of
|
||||
* the list.
|
||||
*
|
||||
* In addition to it's value, each list item contains a pointer to the next
|
||||
* item in the list (pxNext), a pointer to the list it is in (pxContainer)
|
||||
* and a pointer to back to the object that contains it. These later two
|
||||
* pointers are included for efficiency of list manipulation. There is
|
||||
* effectively a two way link between the object containing the list item and
|
||||
* the list item itself.
|
||||
*
|
||||
*
|
||||
* \page ListIntroduction List Implementation
|
||||
* \ingroup FreeRTOSIntro
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "FreeRTOS.h must be included before list.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The list structure members are modified from within interrupts, and therefore
|
||||
* by rights should be declared volatile. However, they are only modified in a
|
||||
* functionally atomic way (within critical sections of with the scheduler
|
||||
* suspended) and are either passed by reference into a function or indexed via
|
||||
* a volatile variable. Therefore, in all use cases tested so far, the volatile
|
||||
* qualifier can be omitted in order to provide a moderate performance
|
||||
* improvement without adversely affecting functional behaviour. The assembly
|
||||
* instructions generated by the IAR, ARM and GCC compilers when the respective
|
||||
* compiler's options were set for maximum optimisation has been inspected and
|
||||
* deemed to be as intended. That said, as compiler technology advances, and
|
||||
* especially if aggressive cross module optimisation is used (a use case that
|
||||
* has not been exercised to any great extend) then it is feasible that the
|
||||
* volatile qualifier will be needed for correct optimisation. It is expected
|
||||
* that a compiler removing essential code because, without the volatile
|
||||
* qualifier on the list structure members and with aggressive cross module
|
||||
* optimisation, the compiler deemed the code unnecessary will result in
|
||||
* complete and obvious failure of the scheduler. If this is ever experienced
|
||||
* then the volatile qualifier can be inserted in the relevant places within the
|
||||
* list structures by simply defining configLIST_VOLATILE to volatile in
|
||||
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
||||
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
||||
* will simply #define configLIST_VOLATILE away completely.
|
||||
*
|
||||
* To use volatile list structure members then add the following line to
|
||||
* FreeRTOSConfig.h (without the quotes):
|
||||
* "#define configLIST_VOLATILE volatile"
|
||||
*/
|
||||
#ifndef configLIST_VOLATILE
|
||||
#define configLIST_VOLATILE
|
||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* Macros that can be used to place known values within the list structures,
|
||||
* then check that the known values do not get corrupted during the execution of
|
||||
* the application. These may catch the list data structures being overwritten in
|
||||
* memory. They will not catch data errors caused by incorrect configuration or
|
||||
* use of FreeRTOS.*/
|
||||
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
||||
/* Define the macros to do nothing. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE
|
||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE
|
||||
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
|
||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
|
||||
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
|
||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||
#define listTEST_LIST_INTEGRITY( pxList )
|
||||
#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
|
||||
/* Define macros that add new members into the list structures. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
||||
|
||||
/* Define macros that set the new structure members to known values. */
|
||||
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||
|
||||
/* Define macros that will assert if one of the structure members does not
|
||||
* contain its expected value. */
|
||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
||||
|
||||
|
||||
/*
|
||||
* Definition of the only type of object that a list can contain.
|
||||
*/
|
||||
struct xLIST;
|
||||
struct xLIST_ITEM
|
||||
{
|
||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in ascending order. */
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
||||
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. */
|
||||
struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
};
|
||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||
|
||||
#if ( configUSE_MINI_LIST_ITEM == 1 )
|
||||
struct xMINI_LIST_ITEM
|
||||
{
|
||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
configLIST_VOLATILE TickType_t xItemValue;
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||
};
|
||||
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||
#else
|
||||
typedef struct xLIST_ITEM MiniListItem_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of the type of queue used by the scheduler.
|
||||
*/
|
||||
typedef struct xLIST
|
||||
{
|
||||
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
volatile UBaseType_t uxNumberOfItems;
|
||||
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||
MiniListItem_t 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. */
|
||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
} List_t;
|
||||
|
||||
/*
|
||||
* Access macro to set the owner of a list item. The owner of a list item
|
||||
* is the object (usually a TCB) that contains the list item.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
|
||||
|
||||
/*
|
||||
* Access macro to get the owner of a list item. The owner of a list item
|
||||
* is the object (usually a TCB) that contains the list item.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||
|
||||
/*
|
||||
* Access macro to set the value of the list item. In most cases the value is
|
||||
* used to sort the list in ascending order.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
||||
|
||||
/*
|
||||
* Access macro to retrieve the value of the list item. The value can
|
||||
* represent anything - for example the priority of a task, or the time at
|
||||
* which a task should be unblocked.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||
|
||||
/*
|
||||
* Access macro to retrieve the value of the list item at the head of a given
|
||||
* list.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
||||
|
||||
/*
|
||||
* Return the list item at the head of the list.
|
||||
*
|
||||
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||
|
||||
/*
|
||||
* Return the next list item.
|
||||
*
|
||||
* \page listGET_NEXT listGET_NEXT
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
||||
|
||||
/*
|
||||
* Return the list item that marks the end of the list
|
||||
*
|
||||
* \page listGET_END_MARKER listGET_END_MARKER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
||||
|
||||
/*
|
||||
* Access macro to determine if a list contains any items. The macro will
|
||||
* only have the value true if the list is empty.
|
||||
*
|
||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
||||
|
||||
/*
|
||||
* Access macro to return the number of items in the list.
|
||||
*/
|
||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the next entry in a list.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
||||
* and returns that entry's pxOwner parameter. Using multiple calls to this
|
||||
* function it is therefore possible to move through every item contained in
|
||||
* a list.
|
||||
*
|
||||
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||
* the list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxTCB pxTCB is set to the address of the owner of the next list item.
|
||||
* @param pxList The list from which the next item owner is to be returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||
{ \
|
||||
List_t * const pxConstList = ( pxList ); \
|
||||
/* Increment the index to the next item and return the item, ensuring */ \
|
||||
/* we don't return the marker used at the end of the list. */ \
|
||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
|
||||
{ \
|
||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||
} \
|
||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of uxListRemove() that does not return a value. Provided as a slight
|
||||
* optimisation for xTaskIncrementTick() by being inline.
|
||||
*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
* it is in, so only the list item need be passed into the function.
|
||||
*
|
||||
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||
* the list pointed to by it's pxContainer parameter.
|
||||
*
|
||||
* @return The number of items that remain in the list after the list item has
|
||||
* been removed.
|
||||
*
|
||||
* \page listREMOVE_ITEM listREMOVE_ITEM
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listREMOVE_ITEM( pxItemToRemove ) \
|
||||
{ \
|
||||
/* The list item knows which list it is in. Obtain the list from the list \
|
||||
* item. */ \
|
||||
List_t * const pxList = ( pxItemToRemove )->pxContainer; \
|
||||
\
|
||||
( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \
|
||||
( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \
|
||||
/* Make sure the index is left pointing to a valid item. */ \
|
||||
if( pxList->pxIndex == ( pxItemToRemove ) ) \
|
||||
{ \
|
||||
pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \
|
||||
} \
|
||||
\
|
||||
( pxItemToRemove )->pxContainer = NULL; \
|
||||
( pxList->uxNumberOfItems )--; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Inline version of vListInsertEnd() to provide slight optimisation for
|
||||
* xTaskIncrementTick().
|
||||
*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
* such that it will be the last item within the list returned by multiple
|
||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||
* in the list position pointed to by pxIndex. This means that every other
|
||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||
* the pxIndex parameter again points to the item being inserted.
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The list item to be inserted into the list.
|
||||
*
|
||||
* \page listINSERT_END listINSERT_END
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listINSERT_END( pxList, pxNewListItem ) \
|
||||
{ \
|
||||
ListItem_t * const pxIndex = ( pxList )->pxIndex; \
|
||||
\
|
||||
/* Only effective when configASSERT() is also defined, these tests may catch \
|
||||
* the list data structures being overwritten in memory. They will not catch \
|
||||
* data errors caused by incorrect configuration or use of FreeRTOS. */ \
|
||||
listTEST_LIST_INTEGRITY( ( pxList ) ); \
|
||||
listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) ); \
|
||||
\
|
||||
/* Insert a new list item into ( pxList ), but rather than sort the list, \
|
||||
* makes the new list item the last item to be removed by a call to \
|
||||
* listGET_OWNER_OF_NEXT_ENTRY(). */ \
|
||||
( pxNewListItem )->pxNext = pxIndex; \
|
||||
( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \
|
||||
\
|
||||
pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \
|
||||
pxIndex->pxPrevious = ( pxNewListItem ); \
|
||||
\
|
||||
/* Remember which list the item is in. */ \
|
||||
( pxNewListItem )->pxContainer = ( pxList ); \
|
||||
\
|
||||
( ( pxList )->uxNumberOfItems )++; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the first entry in a list. Lists
|
||||
* are normally sorted in ascending item value order.
|
||||
*
|
||||
* This function returns the pxOwner member of the first item in the list.
|
||||
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||
* the list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxList The list from which the owner of the head item is to be
|
||||
* returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )
|
||||
|
||||
/*
|
||||
* Check to see if a list item is within a list. The list item maintains a
|
||||
* "container" pointer that points to the list it is in. All this macro does
|
||||
* is check to see if the container and the list match.
|
||||
*
|
||||
* @param pxList The list we want to know if the list item is within.
|
||||
* @param pxListItem The list item we want to know if is in the list.
|
||||
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||
*/
|
||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
|
||||
|
||||
/*
|
||||
* Return the list a list item is contained within (referenced from).
|
||||
*
|
||||
* @param pxListItem The list item being queried.
|
||||
* @return A pointer to the List_t object that references the pxListItem
|
||||
*/
|
||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
|
||||
|
||||
/*
|
||||
* This provides a crude means of knowing if a list has been initialised, as
|
||||
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
|
||||
* function.
|
||||
*/
|
||||
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
||||
|
||||
/*
|
||||
* Must be called before a list is used! This initialises all the members
|
||||
* of the list structure and inserts the xListEnd item into the list as a
|
||||
* marker to the back of the list.
|
||||
*
|
||||
* @param pxList Pointer to the list being initialised.
|
||||
*
|
||||
* \page vListInitialise vListInitialise
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Must be called before a list item is used. This sets the list container to
|
||||
* null so the item does not think that it is already contained in a list.
|
||||
*
|
||||
* @param pxItem Pointer to the list item being initialised.
|
||||
*
|
||||
* \page vListInitialiseItem vListInitialiseItem
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted into the list in
|
||||
* a position determined by its item value (ascending item value order).
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The item that is to be placed in the list.
|
||||
*
|
||||
* \page vListInsert vListInsert
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsert( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
* such that it will be the last item within the list returned by multiple
|
||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||
* in the list position pointed to by pxIndex. This means that every other
|
||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||
* the pxIndex parameter again points to the item being inserted.
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The list item to be inserted into the list.
|
||||
*
|
||||
* \page vListInsertEnd vListInsertEnd
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsertEnd( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
* it is in, so only the list item need be passed into the function.
|
||||
*
|
||||
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||
* the list pointed to by it's pxContainer parameter.
|
||||
*
|
||||
* @return The number of items that remain in the list after the list item has
|
||||
* been removed.
|
||||
*
|
||||
* \page uxListRemove uxListRemove
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* ifndef LIST_H */
|
||||
856
source/shoh/freertos/inc/message_buffer.h
Normal file
856
source/shoh/freertos/inc/message_buffer.h
Normal file
@@ -0,0 +1,856 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Message buffers build functionality on top of FreeRTOS stream buffers.
|
||||
* Whereas stream buffers are used to send a continuous stream of data from one
|
||||
* task or interrupt to another, message buffers are used to send variable
|
||||
* length discrete messages from one task or interrupt to another. Their
|
||||
* implementation is light weight, making them particularly suited for interrupt
|
||||
* to task and core to core communication scenarios.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* timeout to 0.
|
||||
*
|
||||
* Message buffers hold variable length messages. To enable that, when a
|
||||
* message is written to the message buffer an additional sizeof( size_t ) bytes
|
||||
* are also written to store the message's length (that happens internally, with
|
||||
* the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so writing a 10 byte message to a message buffer on a 32-bit
|
||||
* architecture will actually reduce the available space in the message buffer
|
||||
* by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
|
||||
* of the message).
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_MESSAGE_BUFFER_H
|
||||
#define FREERTOS_MESSAGE_BUFFER_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h must appear in source files before include message_buffer.h"
|
||||
#endif
|
||||
|
||||
/* Message buffers are built onto of stream buffers. */
|
||||
#include "stream_buffer.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#if defined( __cplusplus )
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**
|
||||
* Type by which message buffers are referenced. For example, a call to
|
||||
* xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
|
||||
* then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
|
||||
* etc. Message buffer is essentially built as a stream buffer hence its handle
|
||||
* is also set to same type as a stream buffer handle.
|
||||
*/
|
||||
typedef StreamBufferHandle_t MessageBufferHandle_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
|
||||
* @endcode
|
||||
*
|
||||
* Creates a new message buffer using dynamically allocated memory. See
|
||||
* xMessageBufferCreateStatic() for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||
* FreeRTOSConfig.h for xMessageBufferCreate() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The total number of bytes (not messages) the message
|
||||
* buffer will be able to hold at any one time. When a message is written to
|
||||
* the message buffer an additional sizeof( size_t ) bytes are also written to
|
||||
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||
* take up 14 bytes of message buffer space.
|
||||
*
|
||||
* @param pxSendCompletedCallback Callback invoked when a send operation to the
|
||||
* message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
|
||||
* is called without the parameter, then it will use the default implementation
|
||||
* provided by sbSEND_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param pxReceiveCompletedCallback Callback invoked when a receive operation from
|
||||
* the message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
|
||||
* is called without the parameter, it will use the default implementation provided
|
||||
* by sbRECEIVE_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @return If NULL is returned, then the message buffer cannot be created
|
||||
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||
* the message buffer data structures and storage area. A non-NULL value being
|
||||
* returned indicates that the message buffer has been created successfully -
|
||||
* the returned value should be stored as the handle to the created message
|
||||
* buffer.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
*
|
||||
* void vAFunction( void )
|
||||
* {
|
||||
* MessageBufferHandle_t xMessageBuffer;
|
||||
* const size_t xMessageBufferSizeBytes = 100;
|
||||
*
|
||||
* // Create a message buffer that can hold 100 bytes. The memory used to hold
|
||||
* // both the message buffer structure and the messages themselves is allocated
|
||||
* // dynamically. Each message added to the buffer consumes an additional 4
|
||||
* // bytes which are used to hold the length of the message.
|
||||
* xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
|
||||
*
|
||||
* if( xMessageBuffer == NULL )
|
||||
* {
|
||||
* // There was not enough heap memory space available to create the
|
||||
* // message buffer.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // The message buffer was created successfully and can now be used.
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
* \defgroup xMessageBufferCreate xMessageBufferCreate
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferCreate( xBufferSizeBytes ) \
|
||||
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, NULL, NULL )
|
||||
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
|
||||
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
* uint8_t *pucMessageBufferStorageArea,
|
||||
* StaticMessageBuffer_t *pxStaticMessageBuffer );
|
||||
* @endcode
|
||||
* Creates a new message buffer using statically allocated memory. See
|
||||
* xMessageBufferCreate() for a version that uses dynamically allocated memory.
|
||||
*
|
||||
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||
* pucMessageBufferStorageArea parameter. When a message is written to the
|
||||
* message buffer an additional sizeof( size_t ) bytes are also written to store
|
||||
* the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so on most 32-bit architecture a 10 byte message will take up
|
||||
* 14 bytes of message buffer space. The maximum number of bytes that can be
|
||||
* stored in the message buffer is actually (xBufferSizeBytes - 1).
|
||||
*
|
||||
* @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
|
||||
* least xBufferSizeBytes big. This is the array to which messages are
|
||||
* copied when they are written to the message buffer.
|
||||
*
|
||||
* @param pxStaticMessageBuffer Must point to a variable of type
|
||||
* StaticMessageBuffer_t, which will be used to hold the message buffer's data
|
||||
* structure.
|
||||
*
|
||||
* @param pxSendCompletedCallback Callback invoked when a new message is sent to the message buffer.
|
||||
* If the parameter is NULL or xMessageBufferCreate() is called without the parameter, then it will use the default
|
||||
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param pxReceiveCompletedCallback Callback invoked when a message is read from a
|
||||
* message buffer. If the parameter is NULL or xMessageBufferCreate() is called without the parameter, it will
|
||||
* use the default implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @return If the message buffer is created successfully then a handle to the
|
||||
* created message buffer is returned. If either pucMessageBufferStorageArea or
|
||||
* pxStaticmessageBuffer are NULL then NULL is returned.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
*
|
||||
* // Used to dimension the array used to hold the messages. The available space
|
||||
* // will actually be one less than this, so 999.
|
||||
#define STORAGE_SIZE_BYTES 1000
|
||||
*
|
||||
* // Defines the memory that will actually hold the messages within the message
|
||||
* // buffer.
|
||||
* static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||
*
|
||||
* // The variable used to hold the message buffer structure.
|
||||
* StaticMessageBuffer_t xMessageBufferStruct;
|
||||
*
|
||||
* void MyFunction( void )
|
||||
* {
|
||||
* MessageBufferHandle_t xMessageBuffer;
|
||||
*
|
||||
* xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStorageBuffer ),
|
||||
* ucStorageBuffer,
|
||||
* &xMessageBufferStruct );
|
||||
*
|
||||
* // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
|
||||
* // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
|
||||
* // reference the created message buffer in other message buffer API calls.
|
||||
*
|
||||
* // Other code that uses the message buffer can go here.
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
* \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \
|
||||
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL )
|
||||
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
|
||||
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
|
||||
* const void *pvTxData,
|
||||
* size_t xDataLengthBytes,
|
||||
* TickType_t xTicksToWait );
|
||||
* @endcode
|
||||
*
|
||||
* Sends a discrete message to the message buffer. The message can be any
|
||||
* length that fits within the buffer's free space, and is copied into the
|
||||
* buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the message that is to be copied into the
|
||||
* message buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the calling task should remain
|
||||
* in the Blocked state to wait for enough space to become available in the
|
||||
* message buffer, should the message buffer have insufficient space when
|
||||
* xMessageBufferSend() is called. The calling task will never block if
|
||||
* xTicksToWait is zero. The block time is specified in tick periods, so the
|
||||
* absolute time it represents is dependent on the tick frequency. The macro
|
||||
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
|
||||
* a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause
|
||||
* the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
*
|
||||
* @return The number of bytes written to the message buffer. If the call to
|
||||
* xMessageBufferSend() times out before there was enough space to write the
|
||||
* message into the message buffer then zero is returned. If the call did not
|
||||
* time out then xDataLengthBytes is returned.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* void vAFunction( MessageBufferHandle_t xMessageBuffer )
|
||||
* {
|
||||
* size_t xBytesSent;
|
||||
* uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||
* char *pcStringToSend = "String to send";
|
||||
* const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
*
|
||||
* // Send an array to the message buffer, blocking for a maximum of 100ms to
|
||||
* // wait for enough space to be available in the message buffer.
|
||||
* xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||
*
|
||||
* if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||
* {
|
||||
* // The call to xMessageBufferSend() times out before there was enough
|
||||
* // space in the buffer for the data to be written.
|
||||
* }
|
||||
*
|
||||
* // Send the string to the message buffer. Return immediately if there is
|
||||
* // not enough space in the buffer.
|
||||
* xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||
*
|
||||
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||
* {
|
||||
* // The string could not be added to the message buffer because there was
|
||||
* // not enough free space in the buffer.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xMessageBufferSend xMessageBufferSend
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) \
|
||||
xStreamBufferSend( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( xTicksToWait ) )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
* const void *pvTxData,
|
||||
* size_t xDataLengthBytes,
|
||||
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a discrete message to
|
||||
* the message buffer. The message can be any length that fits within the
|
||||
* buffer's free space, and is copied into the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferSend() to write to a message buffer from a task. Use
|
||||
* xMessageBufferSendFromISR() to write to a message buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to which a message is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the message that is to be copied into the
|
||||
* message buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The length of the message. That is, the number of
|
||||
* bytes to copy from pvTxData into the message buffer. When a message is
|
||||
* written to the message buffer an additional sizeof( size_t ) bytes are also
|
||||
* written to store the message's length. sizeof( size_t ) is typically 4 bytes
|
||||
* on a 32-bit architecture, so on most 32-bit architecture setting
|
||||
* xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
|
||||
* bytes (20 bytes of message data and 4 bytes to hold the message length).
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for data. Calling
|
||||
* xMessageBufferSendFromISR() can make data available, and so cause a task that
|
||||
* was waiting for data to leave the Blocked state. If calling
|
||||
* xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently executing task (the
|
||||
* task that was interrupted), then, internally, xMessageBufferSendFromISR()
|
||||
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||
* xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. This will
|
||||
* ensure that the interrupt returns directly to the highest priority Ready
|
||||
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||
* is passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The number of bytes actually written to the message buffer. If the
|
||||
* message buffer didn't have enough free space for the message to be stored
|
||||
* then 0 is returned, otherwise xDataLengthBytes is returned.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* // A message buffer that has already been created.
|
||||
* MessageBufferHandle_t xMessageBuffer;
|
||||
*
|
||||
* void vAnInterruptServiceRoutine( void )
|
||||
* {
|
||||
* size_t xBytesSent;
|
||||
* char *pcStringToSend = "String to send";
|
||||
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
*
|
||||
* // Attempt to send the string to the message buffer.
|
||||
* xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
|
||||
* ( void * ) pcStringToSend,
|
||||
* strlen( pcStringToSend ),
|
||||
* &xHigherPriorityTaskWoken );
|
||||
*
|
||||
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||
* {
|
||||
* // The string could not be added to the message buffer because there was
|
||||
* // not enough free space in the buffer.
|
||||
* }
|
||||
*
|
||||
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
* // xMessageBufferSendFromISR() then a task that has a priority above the
|
||||
* // priority of the currently executing task was unblocked and a context
|
||||
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||
* // task. In most FreeRTOS ports this is done by simply passing
|
||||
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||
* // variables value, and perform the context switch if necessary. Check the
|
||||
* // documentation for the port in use for port specific instructions.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) \
|
||||
xStreamBufferSendFromISR( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
|
||||
* void *pvRxData,
|
||||
* size_t xBufferLengthBytes,
|
||||
* TickType_t xTicksToWait );
|
||||
* @endcode
|
||||
*
|
||||
* Receives a discrete message from a message buffer. Messages can be of
|
||||
* variable length and are copied out of the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received message is
|
||||
* to be copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||
* parameter. This sets the maximum length of the message that can be received.
|
||||
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||
* will be left in the message buffer and 0 will be returned.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for a message, should the message buffer be empty.
|
||||
* xMessageBufferReceive() will return immediately if xTicksToWait is zero and
|
||||
* the message buffer is empty. The block time is specified in tick periods, so
|
||||
* the absolute time it represents is dependent on the tick frequency. The
|
||||
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
*
|
||||
* @return The length, in bytes, of the message read from the message buffer, if
|
||||
* any. If xMessageBufferReceive() times out before a message became available
|
||||
* then zero is returned. If the length of the message is greater than
|
||||
* xBufferLengthBytes then the message will be left in the message buffer and
|
||||
* zero is returned.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* void vAFunction( MessageBuffer_t xMessageBuffer )
|
||||
* {
|
||||
* uint8_t ucRxData[ 20 ];
|
||||
* size_t xReceivedBytes;
|
||||
* const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
*
|
||||
* // Receive the next message from the message buffer. Wait in the Blocked
|
||||
* // state (so not using any CPU processing time) for a maximum of 100ms for
|
||||
* // a message to become available.
|
||||
* xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
|
||||
* ( void * ) ucRxData,
|
||||
* sizeof( ucRxData ),
|
||||
* xBlockTime );
|
||||
*
|
||||
* if( xReceivedBytes > 0 )
|
||||
* {
|
||||
* // A ucRxData contains a message that is xReceivedBytes long. Process
|
||||
* // the message here....
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xMessageBufferReceive xMessageBufferReceive
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) \
|
||||
xStreamBufferReceive( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( xTicksToWait ) )
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
|
||||
* void *pvRxData,
|
||||
* size_t xBufferLengthBytes,
|
||||
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* An interrupt safe version of the API function that receives a discrete
|
||||
* message from a message buffer. Messages can be of variable length and are
|
||||
* copied out of the buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xMessageBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xMessageBufferRead()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xMessageBufferReceive() to read from a message buffer from a task. Use
|
||||
* xMessageBufferReceiveFromISR() to read from a message buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer from which a message
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received message is
|
||||
* to be copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
|
||||
* parameter. This sets the maximum length of the message that can be received.
|
||||
* If xBufferLengthBytes is too small to hold the next message then the message
|
||||
* will be left in the message buffer and 0 will be returned.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* xMessageBufferReceiveFromISR() can make space available, and so cause a task
|
||||
* that is waiting for space to leave the Blocked state. If calling
|
||||
* xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||
* the unblocked task has a priority higher than the currently executing task
|
||||
* (the task that was interrupted), then, internally,
|
||||
* xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||
* If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. That will
|
||||
* ensure the interrupt returns directly to the highest priority Ready state
|
||||
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||
* passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The length, in bytes, of the message read from the message buffer, if
|
||||
* any.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* // A message buffer that has already been created.
|
||||
* MessageBuffer_t xMessageBuffer;
|
||||
*
|
||||
* void vAnInterruptServiceRoutine( void )
|
||||
* {
|
||||
* uint8_t ucRxData[ 20 ];
|
||||
* size_t xReceivedBytes;
|
||||
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
*
|
||||
* // Receive the next message from the message buffer.
|
||||
* xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
|
||||
* ( void * ) ucRxData,
|
||||
* sizeof( ucRxData ),
|
||||
* &xHigherPriorityTaskWoken );
|
||||
*
|
||||
* if( xReceivedBytes > 0 )
|
||||
* {
|
||||
* // A ucRxData contains a message that is xReceivedBytes long. Process
|
||||
* // the message here....
|
||||
* }
|
||||
*
|
||||
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
* // xMessageBufferReceiveFromISR() then a task that has a priority above the
|
||||
* // priority of the currently executing task was unblocked and a context
|
||||
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||
* // task. In most FreeRTOS ports this is done by simply passing
|
||||
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||
* // variables value, and perform the context switch if necessary. Check the
|
||||
* // documentation for the port in use for port specific instructions.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) \
|
||||
xStreamBufferReceiveFromISR( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Deletes a message buffer that was previously created using a call to
|
||||
* xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message
|
||||
* buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
|
||||
* then the allocated memory is freed.
|
||||
*
|
||||
* A message buffer handle must not be used after the message buffer has been
|
||||
* deleted.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer to be deleted.
|
||||
*
|
||||
*/
|
||||
#define vMessageBufferDelete( xMessageBuffer ) \
|
||||
vStreamBufferDelete( xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
* @code{c}
|
||||
* BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Tests to see if a message buffer is full. A message buffer is full if it
|
||||
* cannot accept any more messages, of any size, until space is made available
|
||||
* by a message being removed from the message buffer.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return If the message buffer referenced by xMessageBuffer is full then
|
||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||
*/
|
||||
#define xMessageBufferIsFull( xMessageBuffer ) \
|
||||
xStreamBufferIsFull( xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
* @code{c}
|
||||
* BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Tests to see if a message buffer is empty (does not contain any messages).
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return If the message buffer referenced by xMessageBuffer is empty then
|
||||
* pdTRUE is returned. Otherwise pdFALSE is returned.
|
||||
*
|
||||
*/
|
||||
#define xMessageBufferIsEmpty( xMessageBuffer ) \
|
||||
xStreamBufferIsEmpty( xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
* @code{c}
|
||||
* BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Resets a message buffer to its initial empty state, discarding any message it
|
||||
* contained.
|
||||
*
|
||||
* A message buffer can only be reset if there are no tasks blocked on it.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being reset.
|
||||
*
|
||||
* @return If the message buffer was reset then pdPASS is returned. If the
|
||||
* message buffer could not be reset because either there was a task blocked on
|
||||
* the message queue to wait for space to become available, or to wait for a
|
||||
* a message to be available, then pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferReset xMessageBufferReset
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReset( xMessageBuffer ) \
|
||||
xStreamBufferReset( xMessageBuffer )
|
||||
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
* @code{c}
|
||||
* size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer );
|
||||
* @endcode
|
||||
* Returns the number of bytes of free space in the message buffer.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be written to the message buffer before
|
||||
* the message buffer would be full. When a message is written to the message
|
||||
* buffer an additional sizeof( size_t ) bytes are also written to store the
|
||||
* message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit
|
||||
* architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
|
||||
* of the largest message that can be written to the message buffer is 6 bytes.
|
||||
*
|
||||
* \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSpaceAvailable( xMessageBuffer ) \
|
||||
xStreamBufferSpacesAvailable( xMessageBuffer )
|
||||
#define xMessageBufferSpacesAvailable( xMessageBuffer ) \
|
||||
xStreamBufferSpacesAvailable( xMessageBuffer ) /* Corrects typo in original macro name. */
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
* @code{c}
|
||||
* size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer );
|
||||
* @endcode
|
||||
* Returns the length (in bytes) of the next message in a message buffer.
|
||||
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
||||
* passed into xMessageBufferReceive() was too small to hold the next message.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||
*
|
||||
* @return The length (in bytes) of the next message in the message buffer, or 0
|
||||
* if the message buffer is empty.
|
||||
*
|
||||
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
||||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferNextLengthBytes( xMessageBuffer ) \
|
||||
xStreamBufferNextMessageLengthBytes( xMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||
* from the Blocked state. xMessageBufferSendCompletedFromISR() does the same
|
||||
* thing. It is provided to enable application writers to implement their own
|
||||
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the stream buffer to which data was
|
||||
* written.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xMessageBufferSendCompletedFromISR(). If calling
|
||||
* xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
|
||||
xStreamBufferSendCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is read out of a message buffer or stream buffer. If there was a task
|
||||
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||
* remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR()
|
||||
* does the same thing. It is provided to enable application writers to
|
||||
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||
* ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xMessageBuffer The handle of the stream buffer from which data was
|
||||
* read.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xMessageBufferReceiveCompletedFromISR(). If calling
|
||||
* xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
|
||||
xStreamBufferReceiveCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#if defined( __cplusplus )
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
|
||||
264
source/shoh/freertos/inc/mpu_prototypes.h
Normal file
264
source/shoh/freertos/inc/mpu_prototypes.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* When the MPU is used the standard (non MPU) API functions are mapped to
|
||||
* equivalents that start "MPU_", the prototypes for which are defined in this
|
||||
* header files. This will cause the application code to call the MPU_ version
|
||||
* which wraps the non-MPU version with privilege promoting then demoting code,
|
||||
* so the kernel code always runs will full privileges.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MPU_PROTOTYPES_H
|
||||
#define MPU_PROTOTYPES_H
|
||||
|
||||
/* MPU versions of task.h API functions. */
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint16_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask,
|
||||
TaskStatus_t * pxTaskStatus,
|
||||
BaseType_t xGetFreeStackSpace,
|
||||
eTaskState eState ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
|
||||
UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
|
||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
|
||||
TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue ) FREERTOS_SYSTEM_CALL;
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
|
||||
BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||
void * pvParameter ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||
const UBaseType_t uxArraySize,
|
||||
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
|
||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
|
||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
|
||||
UBaseType_t uxIndexToNotify,
|
||||
uint32_t ulValue,
|
||||
eNotifyAction eAction,
|
||||
uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
|
||||
uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
uint32_t * pulNotificationValue,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||
BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
|
||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear,
|
||||
uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||
TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of queue.h API functions. */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
|
||||
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
|
||||
const UBaseType_t uxInitialCount,
|
||||
StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
|
||||
const char * pcName ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
|
||||
const UBaseType_t uxItemSize,
|
||||
uint8_t * pucQueueStorage,
|
||||
StaticQueue_t * pxStaticQueue,
|
||||
const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL;
|
||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
|
||||
BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
|
||||
UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of timers.h API functions. */
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL;
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
|
||||
const TickType_t xTimerPeriodInTicks,
|
||||
const UBaseType_t uxAutoReload,
|
||||
void * const pvTimerID,
|
||||
TimerCallbackFunction_t pxCallbackFunction,
|
||||
StaticTimer_t * pxTimerBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
|
||||
void * pvNewID ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||
void * pvParameter1,
|
||||
uint32_t ulParameter2,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
|
||||
const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer,
|
||||
const BaseType_t xCommandID,
|
||||
const TickType_t xOptionalValue,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of event_group.h API functions. */
|
||||
EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL;
|
||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* MPU versions of message/stream_buffer.h API functions. */
|
||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void * pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void * pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
|
||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||
size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL;
|
||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
|
||||
|
||||
#endif /* MPU_PROTOTYPES_H */
|
||||
184
source/shoh/freertos/inc/mpu_wrappers.h
Normal file
184
source/shoh/freertos/inc/mpu_wrappers.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MPU_WRAPPERS_H
|
||||
#define MPU_WRAPPERS_H
|
||||
|
||||
/* This file redefines API functions to be called through a wrapper macro, but
|
||||
* only for ports that are using the MPU. */
|
||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||
|
||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||
* included from queue.c or task.c to prevent it from having an effect within
|
||||
* those files. */
|
||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/*
|
||||
* Map standard (non MPU) API functions to equivalents that start
|
||||
* "MPU_". This will cause the application code to call the MPU_
|
||||
* version, which wraps the non-MPU version with privilege promoting
|
||||
* then demoting code, so the kernel code always runs will full
|
||||
* privileges.
|
||||
*/
|
||||
|
||||
/* Map standard task.h API functions to the MPU equivalents. */
|
||||
#define xTaskCreate MPU_xTaskCreate
|
||||
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
||||
#define vTaskDelete MPU_vTaskDelete
|
||||
#define vTaskDelay MPU_vTaskDelay
|
||||
#define xTaskDelayUntil MPU_xTaskDelayUntil
|
||||
#define xTaskAbortDelay MPU_xTaskAbortDelay
|
||||
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||
#define eTaskGetState MPU_eTaskGetState
|
||||
#define vTaskGetInfo MPU_vTaskGetInfo
|
||||
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||
#define vTaskSuspend MPU_vTaskSuspend
|
||||
#define vTaskResume MPU_vTaskResume
|
||||
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||
#define pcTaskGetName MPU_pcTaskGetName
|
||||
#define xTaskGetHandle MPU_xTaskGetHandle
|
||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
|
||||
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
|
||||
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
|
||||
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||
#define vTaskList MPU_vTaskList
|
||||
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||
#define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter
|
||||
#define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent
|
||||
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
||||
#define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait
|
||||
#define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake
|
||||
#define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear
|
||||
#define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear
|
||||
#define xTaskCatchUpTicks MPU_xTaskCatchUpTicks
|
||||
|
||||
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
|
||||
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||
|
||||
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||
#define xQueueReceive MPU_xQueueReceive
|
||||
#define xQueuePeek MPU_xQueuePeek
|
||||
#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake
|
||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||
#define vQueueDelete MPU_vQueueDelete
|
||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
|
||||
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
|
||||
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
||||
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
|
||||
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||
|
||||
#if ( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||
#define pcQueueGetName MPU_pcQueueGetName
|
||||
#endif
|
||||
|
||||
/* Map standard timer.h API functions to the MPU equivalents. */
|
||||
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
||||
#define vTimerSetTimerID MPU_vTimerSetTimerID
|
||||
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
|
||||
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
||||
#define pcTimerGetName MPU_pcTimerGetName
|
||||
#define vTimerSetReloadMode MPU_vTimerSetReloadMode
|
||||
#define uxTimerGetReloadMode MPU_uxTimerGetReloadMode
|
||||
#define xTimerGetPeriod MPU_xTimerGetPeriod
|
||||
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
||||
|
||||
/* Map standard event_group.h API functions to the MPU equivalents. */
|
||||
#define xEventGroupCreate MPU_xEventGroupCreate
|
||||
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
||||
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
||||
#define xEventGroupClearBits MPU_xEventGroupClearBits
|
||||
#define xEventGroupSetBits MPU_xEventGroupSetBits
|
||||
#define xEventGroupSync MPU_xEventGroupSync
|
||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||
|
||||
/* Map standard message/stream_buffer.h API functions to the MPU
|
||||
* equivalents. */
|
||||
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
||||
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
||||
#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty
|
||||
#define xStreamBufferReset MPU_xStreamBufferReset
|
||||
#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable
|
||||
#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable
|
||||
#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel
|
||||
#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate
|
||||
#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic
|
||||
|
||||
|
||||
/* Remove the privileged function macro, but keep the PRIVILEGED_DATA
|
||||
* macro so applications can place data in privileged access sections
|
||||
* (useful when using statically allocated objects). */
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
|
||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
/* Ensure API functions go in the privileged execution section. */
|
||||
#define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) )
|
||||
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
|
||||
#define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) )
|
||||
|
||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
#else /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA
|
||||
#define FREERTOS_SYSTEM_CALL
|
||||
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
|
||||
#endif /* MPU_WRAPPERS_H */
|
||||
238
source/shoh/freertos/inc/portable.h
Normal file
238
source/shoh/freertos/inc/portable.h
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Portable layer API. Each function must be defined for each port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||
* pre-processor definition was used to ensure the pre-processor found the correct
|
||||
* portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||
* of setting the compiler's include path such that it found the correct
|
||||
* portmacro.h file - removing the need for the constant and allowing the
|
||||
* portmacro.h file to be located anywhere in relation to the port being used.
|
||||
* Purely for reasons of backward compatibility the old method is still valid, but
|
||||
* to make it clear that new projects should not use it, support for the port
|
||||
* specific constants has been moved into the deprecated_definitions.h header
|
||||
* file. */
|
||||
#include "deprecated_definitions.h"
|
||||
|
||||
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||
* did not result in a portmacro.h header file being included - and it should be
|
||||
* included here. In this case the path to the correct portmacro.h header file
|
||||
* must be set in the compiler's include path. */
|
||||
#ifndef portENTER_CRITICAL
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 32
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
||||
#elif portBYTE_ALIGNMENT == 16
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
||||
#elif portBYTE_ALIGNMENT == 8
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||
#elif portBYTE_ALIGNMENT == 4
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||
#elif portBYTE_ALIGNMENT == 2
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||
#elif portBYTE_ALIGNMENT == 1
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||
#else /* if portBYTE_ALIGNMENT == 32 */
|
||||
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||
#endif /* if portBYTE_ALIGNMENT == 32 */
|
||||
|
||||
#ifndef portUSING_MPU_WRAPPERS
|
||||
#define portUSING_MPU_WRAPPERS 0
|
||||
#endif
|
||||
|
||||
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef portHAS_STACK_OVERFLOW_CHECKING
|
||||
#define portHAS_STACK_OVERFLOW_CHECKING 0
|
||||
#endif
|
||||
|
||||
#ifndef portARCH_NAME
|
||||
#define portARCH_NAME NULL
|
||||
#endif
|
||||
|
||||
#ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP
|
||||
/* Defaults to 0 for backward compatibility. */
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#include "mpu_wrappers.h"
|
||||
|
||||
/*
|
||||
* Setup the stack of a new task so it is ready to be placed under the
|
||||
* scheduler control. The registers have to be placed on the stack in
|
||||
* the order that the port expects to find them.
|
||||
*
|
||||
*/
|
||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
StackType_t * pxEndOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters,
|
||||
BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||
#if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
StackType_t * pxEndOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
|
||||
|
||||
/* Used by heap_5.c to define the start address and size of each memory region
|
||||
* that together comprise the total FreeRTOS heap space. */
|
||||
typedef struct HeapRegion
|
||||
{
|
||||
uint8_t * pucStartAddress;
|
||||
size_t xSizeInBytes;
|
||||
} HeapRegion_t;
|
||||
|
||||
/* Used to pass information about the heap out of vPortGetHeapStats(). */
|
||||
typedef struct xHeapStats
|
||||
{
|
||||
size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
|
||||
size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||
size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||
size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
|
||||
size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
|
||||
size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
|
||||
size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */
|
||||
} HeapStats_t;
|
||||
|
||||
/*
|
||||
* Used to define multiple heap regions for use by heap_5.c. This function
|
||||
* must be called before any calls to pvPortMalloc() - not creating a task,
|
||||
* queue, semaphore, mutex, software timer, event group, etc. will result in
|
||||
* pvPortMalloc being called.
|
||||
*
|
||||
* pxHeapRegions passes in an array of HeapRegion_t structures - each of which
|
||||
* defines a region of memory that can be used as the heap. The array is
|
||||
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
||||
* with the lowest start address must appear first in the array.
|
||||
*/
|
||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Returns a HeapStats_t structure filled with information about the current
|
||||
* heap state.
|
||||
*/
|
||||
void vPortGetHeapStats( HeapStats_t * pxHeapStats );
|
||||
|
||||
/*
|
||||
* Map to the memory management routines required for the port.
|
||||
*/
|
||||
void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||
void * pvPortCalloc( size_t xNum,
|
||||
size_t xSize ) PRIVILEGED_FUNCTION;
|
||||
void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
|
||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 )
|
||||
void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||
void vPortFreeStack( void * pv ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define pvPortMallocStack pvPortMalloc
|
||||
#define vPortFreeStack vPortFree
|
||||
#endif
|
||||
|
||||
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
|
||||
/**
|
||||
* task.h
|
||||
* @code{c}
|
||||
* void vApplicationMallocFailedHook( void )
|
||||
* @endcode
|
||||
*
|
||||
* This hook function is called when allocation failed.
|
||||
*/
|
||||
void vApplicationMallocFailedHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the hardware ready for the scheduler to take control. This generally
|
||||
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||
* the hardware is left in its original condition after the scheduler stops
|
||||
* executing.
|
||||
*/
|
||||
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* The structures and methods of manipulating the MPU are contained within the
|
||||
* port layer.
|
||||
*
|
||||
* Fills the xMPUSettings structure with the memory region information
|
||||
* contained in xRegions.
|
||||
*/
|
||||
#if ( portUSING_MPU_WRAPPERS == 1 )
|
||||
struct xMEMORY_REGION;
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
|
||||
const struct xMEMORY_REGION * const xRegions,
|
||||
StackType_t * pxBottomOfStack,
|
||||
uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* PORTABLE_H */
|
||||
128
source/shoh/freertos/inc/portmacro.h
Normal file
128
source/shoh/freertos/inc/portmacro.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "chip.h"
|
||||
#include "board.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||
* not need to be guarded with a critical section. */
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } while( 0 )
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulSetInterruptMaskFromISR( void ) __attribute__( ( naked ) );
|
||||
extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__( ( naked ) );
|
||||
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMaskFromISR( x )
|
||||
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
|
||||
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
#define portNOP()
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
122
source/shoh/freertos/inc/projdefs.h
Normal file
122
source/shoh/freertos/inc/projdefs.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROJDEFS_H
|
||||
#define PROJDEFS_H
|
||||
|
||||
/*
|
||||
* Defines the prototype to which task functions must conform. Defined in this
|
||||
* file to ensure the type is known before portable.h is included.
|
||||
*/
|
||||
typedef void (* TaskFunction_t)( void * );
|
||||
|
||||
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
||||
* overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||
* definition here is not suitable for your application. */
|
||||
#ifndef pdMS_TO_TICKS
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000U ) )
|
||||
#endif
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||
|
||||
/* FreeRTOS error definitions. */
|
||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||
#define errQUEUE_BLOCKED ( -4 )
|
||||
#define errQUEUE_YIELD ( -5 )
|
||||
|
||||
/* Macros used for basic data corruption checks. */
|
||||
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
|
||||
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
||||
#endif
|
||||
|
||||
#if ( configUSE_16_BIT_TICKS == 1 )
|
||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
||||
#else
|
||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
||||
#endif
|
||||
|
||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||
* itself. */
|
||||
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
||||
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
||||
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
||||
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
|
||||
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
|
||||
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
|
||||
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
|
||||
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
|
||||
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
|
||||
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
|
||||
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
|
||||
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
|
||||
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
|
||||
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
|
||||
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
|
||||
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
|
||||
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
|
||||
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
|
||||
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
|
||||
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
|
||||
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
|
||||
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
|
||||
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
||||
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
|
||||
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
|
||||
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
||||
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
||||
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
|
||||
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
|
||||
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
|
||||
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
|
||||
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
|
||||
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
|
||||
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
|
||||
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
|
||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||
|
||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||
* itself. */
|
||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||
#define pdFREERTOS_BIG_ENDIAN 1
|
||||
|
||||
/* Re-defining endian values for generic naming. */
|
||||
#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN
|
||||
#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN
|
||||
|
||||
|
||||
#endif /* PROJDEFS_H */
|
||||
1722
source/shoh/freertos/inc/queue.h
Normal file
1722
source/shoh/freertos/inc/queue.h
Normal file
File diff suppressed because it is too large
Load Diff
1193
source/shoh/freertos/inc/semphr.h
Normal file
1193
source/shoh/freertos/inc/semphr.h
Normal file
File diff suppressed because it is too large
Load Diff
137
source/shoh/freertos/inc/stack_macros.h
Normal file
137
source/shoh/freertos/inc/stack_macros.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STACK_MACROS_H
|
||||
#define STACK_MACROS_H
|
||||
|
||||
/*
|
||||
* Call the stack overflow hook function if the stack of the task being swapped
|
||||
* out is currently overflowed, or looks like it might have overflowed in the
|
||||
* past.
|
||||
*
|
||||
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
|
||||
* the current stack state only - comparing the current top of stack value to
|
||||
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
|
||||
* will also cause the last few stack bytes to be checked to ensure the value
|
||||
* to which the bytes were set when the task was created have not been
|
||||
* overwritten. Note this second test does not guarantee that an overflowed
|
||||
* stack will always be recognised.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* portSTACK_LIMIT_PADDING is a number of extra words to consider to be in
|
||||
* use on the stack.
|
||||
*/
|
||||
#ifndef portSTACK_LIMIT_PADDING
|
||||
#define portSTACK_LIMIT_PADDING 0
|
||||
#endif
|
||||
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
\
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||
\
|
||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||
\
|
||||
\
|
||||
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||
\
|
||||
/* Has the extremity of the task stack ever been written over? */ \
|
||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Remove stack overflow macro if not being used. */
|
||||
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* STACK_MACROS_H */
|
||||
913
source/shoh/freertos/inc/stream_buffer.h
Normal file
913
source/shoh/freertos/inc/stream_buffer.h
Normal file
@@ -0,0 +1,913 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stream buffers are used to send a continuous stream of data from one task or
|
||||
* interrupt to another. Their implementation is light weight, making them
|
||||
* particularly suited for interrupt to task and core to core communication
|
||||
* scenarios.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferReceive()) inside a critical section section and set the
|
||||
* receive block time to 0.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STREAM_BUFFER_H
|
||||
#define STREAM_BUFFER_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h must appear in source files before include stream_buffer.h"
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#if defined( __cplusplus )
|
||||
extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/**
|
||||
* Type by which stream buffers are referenced. For example, a call to
|
||||
* xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
|
||||
* then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
|
||||
* etc.
|
||||
*/
|
||||
struct StreamBufferDef_t;
|
||||
typedef struct StreamBufferDef_t * StreamBufferHandle_t;
|
||||
|
||||
/**
|
||||
* Type used as a stream buffer's optional callback.
|
||||
*/
|
||||
typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t xIsInsideISR,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken );
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
|
||||
* @endcode
|
||||
*
|
||||
* Creates a new stream buffer using dynamically allocated memory. See
|
||||
* xStreamBufferCreateStatic() for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*
|
||||
* configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
|
||||
* FreeRTOSConfig.h for xStreamBufferCreate() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The total number of bytes the stream buffer will be
|
||||
* able to hold at any one time.
|
||||
*
|
||||
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||
* unblocked when a single byte is written to the buffer or the task's block
|
||||
* time expires. As another example, if a task is blocked on a read of an empty
|
||||
* stream buffer that has a trigger level of 10 then the task will not be
|
||||
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||
* block time expires. If a reading task's block time expires before the
|
||||
* trigger level is reached then the task will still receive however many bytes
|
||||
* are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to
|
||||
* trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default
|
||||
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a
|
||||
* stream buffer. If the parameter is NULL, it will use the default
|
||||
* implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @return If NULL is returned, then the stream buffer cannot be created
|
||||
* because there is insufficient heap memory available for FreeRTOS to allocate
|
||||
* the stream buffer data structures and storage area. A non-NULL value being
|
||||
* returned indicates that the stream buffer has been created successfully -
|
||||
* the returned value should be stored as the handle to the created stream
|
||||
* buffer.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
*
|
||||
* void vAFunction( void )
|
||||
* {
|
||||
* StreamBufferHandle_t xStreamBuffer;
|
||||
* const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
|
||||
*
|
||||
* // Create a stream buffer that can hold 100 bytes. The memory used to hold
|
||||
* // both the stream buffer structure and the data in the stream buffer is
|
||||
* // allocated dynamically.
|
||||
* xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
|
||||
*
|
||||
* if( xStreamBuffer == NULL )
|
||||
* {
|
||||
* // There was not enough heap memory space available to create the
|
||||
* // stream buffer.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // The stream buffer was created successfully and can now be used.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xStreamBufferCreate xStreamBufferCreate
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
|
||||
#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \
|
||||
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, NULL, NULL )
|
||||
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
|
||||
xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
|
||||
* size_t xTriggerLevelBytes,
|
||||
* uint8_t *pucStreamBufferStorageArea,
|
||||
* StaticStreamBuffer_t *pxStaticStreamBuffer );
|
||||
* @endcode
|
||||
* Creates a new stream buffer using statically allocated memory. See
|
||||
* xStreamBufferCreate() for a version that uses dynamically allocated memory.
|
||||
*
|
||||
* configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for
|
||||
* xStreamBufferCreateStatic() to be available.
|
||||
*
|
||||
* @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
|
||||
* pucStreamBufferStorageArea parameter.
|
||||
*
|
||||
* @param xTriggerLevelBytes The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data is
|
||||
* moved out of the blocked state. For example, if a task is blocked on a read
|
||||
* of an empty stream buffer that has a trigger level of 1 then the task will be
|
||||
* unblocked when a single byte is written to the buffer or the task's block
|
||||
* time expires. As another example, if a task is blocked on a read of an empty
|
||||
* stream buffer that has a trigger level of 10 then the task will not be
|
||||
* unblocked until the stream buffer contains at least 10 bytes or the task's
|
||||
* block time expires. If a reading task's block time expires before the
|
||||
* trigger level is reached then the task will still receive however many bytes
|
||||
* are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
|
||||
* least xBufferSizeBytes big. This is the array to which streams are
|
||||
* copied when they are written to the stream buffer.
|
||||
*
|
||||
* @param pxStaticStreamBuffer Must point to a variable of type
|
||||
* StaticStreamBuffer_t, which will be used to hold the stream buffer's data
|
||||
* structure.
|
||||
*
|
||||
* @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to
|
||||
* trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default
|
||||
* implementation provided by sbSEND_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a
|
||||
* stream buffer. If the parameter is NULL, it will use the default
|
||||
* implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
|
||||
* configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @return If the stream buffer is created successfully then a handle to the
|
||||
* created stream buffer is returned. If either pucStreamBufferStorageArea or
|
||||
* pxStaticstreamBuffer are NULL then NULL is returned.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
*
|
||||
* // Used to dimension the array used to hold the streams. The available space
|
||||
* // will actually be one less than this, so 999.
|
||||
#define STORAGE_SIZE_BYTES 1000
|
||||
*
|
||||
* // Defines the memory that will actually hold the streams within the stream
|
||||
* // buffer.
|
||||
* static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
|
||||
*
|
||||
* // The variable used to hold the stream buffer structure.
|
||||
* StaticStreamBuffer_t xStreamBufferStruct;
|
||||
*
|
||||
* void MyFunction( void )
|
||||
* {
|
||||
* StreamBufferHandle_t xStreamBuffer;
|
||||
* const size_t xTriggerLevel = 1;
|
||||
*
|
||||
* xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ),
|
||||
* xTriggerLevel,
|
||||
* ucStorageBuffer,
|
||||
* &xStreamBufferStruct );
|
||||
*
|
||||
* // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
|
||||
* // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
|
||||
* // reference the created stream buffer in other stream buffer API calls.
|
||||
*
|
||||
* // Other code that uses the stream buffer can go here.
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
* \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
|
||||
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \
|
||||
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL )
|
||||
|
||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
|
||||
#define xStreamBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
|
||||
xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
* const void *pvTxData,
|
||||
* size_t xDataLengthBytes,
|
||||
* TickType_t xTicksToWait );
|
||||
* @endcode
|
||||
*
|
||||
* Sends bytes to a stream buffer. The bytes are copied into the stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferReceive()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the buffer that holds the bytes to be copied
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for enough space to become available in the stream
|
||||
* buffer, should the stream buffer contain too little space to hold the
|
||||
* another xDataLengthBytes bytes. The block time is specified in tick periods,
|
||||
* so the absolute time it represents is dependent on the tick frequency. The
|
||||
* macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out
|
||||
* before it can write all xDataLengthBytes into the buffer it will still write
|
||||
* as many bytes as possible. A task does not use any CPU time when it is in
|
||||
* the blocked state.
|
||||
*
|
||||
* @return The number of bytes written to the stream buffer. If a task times
|
||||
* out before it can write all xDataLengthBytes into the buffer it will still
|
||||
* write as many bytes as possible.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* void vAFunction( StreamBufferHandle_t xStreamBuffer )
|
||||
* {
|
||||
* size_t xBytesSent;
|
||||
* uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
|
||||
* char *pcStringToSend = "String to send";
|
||||
* const TickType_t x100ms = pdMS_TO_TICKS( 100 );
|
||||
*
|
||||
* // Send an array to the stream buffer, blocking for a maximum of 100ms to
|
||||
* // wait for enough space to be available in the stream buffer.
|
||||
* xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
|
||||
*
|
||||
* if( xBytesSent != sizeof( ucArrayToSend ) )
|
||||
* {
|
||||
* // The call to xStreamBufferSend() times out before there was enough
|
||||
* // space in the buffer for the data to be written, but it did
|
||||
* // successfully write xBytesSent bytes.
|
||||
* }
|
||||
*
|
||||
* // Send the string to the stream buffer. Return immediately if there is not
|
||||
* // enough space in the buffer.
|
||||
* xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
|
||||
*
|
||||
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||
* {
|
||||
* // The entire string could not be added to the stream buffer because
|
||||
* // there was not enough free space in the buffer, but xBytesSent bytes
|
||||
* // were sent. Could try again to send the remaining bytes.
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xStreamBufferSend xStreamBufferSend
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void * pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
* const void *pvTxData,
|
||||
* size_t xDataLengthBytes,
|
||||
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||
* the stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferReceive()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferSend() to write to a stream buffer from a task. Use
|
||||
* xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
|
||||
* service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which a stream is
|
||||
* being sent.
|
||||
*
|
||||
* @param pvTxData A pointer to the data that is to be copied into the stream
|
||||
* buffer.
|
||||
*
|
||||
* @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
|
||||
* into the stream buffer.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for data. Calling
|
||||
* xStreamBufferSendFromISR() can make data available, and so cause a task that
|
||||
* was waiting for data to leave the Blocked state. If calling
|
||||
* xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority higher than the currently executing task (the
|
||||
* task that was interrupted), then, internally, xStreamBufferSendFromISR()
|
||||
* will set *pxHigherPriorityTaskWoken to pdTRUE. If
|
||||
* xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. This will
|
||||
* ensure that the interrupt returns directly to the highest priority Ready
|
||||
* state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it
|
||||
* is passed into the function. See the example code below for an example.
|
||||
*
|
||||
* @return The number of bytes actually written to the stream buffer, which will
|
||||
* be less than xDataLengthBytes if the stream buffer didn't have enough free
|
||||
* space for all the bytes to be written.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* // A stream buffer that has already been created.
|
||||
* StreamBufferHandle_t xStreamBuffer;
|
||||
*
|
||||
* void vAnInterruptServiceRoutine( void )
|
||||
* {
|
||||
* size_t xBytesSent;
|
||||
* char *pcStringToSend = "String to send";
|
||||
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
*
|
||||
* // Attempt to send the string to the stream buffer.
|
||||
* xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
|
||||
* ( void * ) pcStringToSend,
|
||||
* strlen( pcStringToSend ),
|
||||
* &xHigherPriorityTaskWoken );
|
||||
*
|
||||
* if( xBytesSent != strlen( pcStringToSend ) )
|
||||
* {
|
||||
* // There was not enough free space in the stream buffer for the entire
|
||||
* // string to be written, ut xBytesSent bytes were written.
|
||||
* }
|
||||
*
|
||||
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
* // xStreamBufferSendFromISR() then a task that has a priority above the
|
||||
* // priority of the currently executing task was unblocked and a context
|
||||
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||
* // task. In most FreeRTOS ports this is done by simply passing
|
||||
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||
* // variables value, and perform the context switch if necessary. Check the
|
||||
* // documentation for the port in use for port specific instructions.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
const void * pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
* void *pvRxData,
|
||||
* size_t xBufferLengthBytes,
|
||||
* TickType_t xTicksToWait );
|
||||
* @endcode
|
||||
*
|
||||
* Receives bytes from a stream buffer.
|
||||
*
|
||||
* ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer
|
||||
* implementation (so also the message buffer implementation, as message buffers
|
||||
* are built on top of stream buffers) assumes there is only one task or
|
||||
* interrupt that will write to the buffer (the writer), and only one task or
|
||||
* interrupt that will read from the buffer (the reader). It is safe for the
|
||||
* writer and reader to be different tasks or interrupts, but, unlike other
|
||||
* FreeRTOS objects, it is not safe to have multiple different writers or
|
||||
* multiple different readers. If there are to be multiple different writers
|
||||
* then the application writer must place each call to a writing API function
|
||||
* (such as xStreamBufferSend()) inside a critical section and set the send
|
||||
* block time to 0. Likewise, if there are to be multiple different readers
|
||||
* then the application writer must place each call to a reading API function
|
||||
* (such as xStreamBufferReceive()) inside a critical section and set the receive
|
||||
* block time to 0.
|
||||
*
|
||||
* Use xStreamBufferReceive() to read from a stream buffer from a task. Use
|
||||
* xStreamBufferReceiveFromISR() to read from a stream buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which bytes are to
|
||||
* be received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received bytes will be
|
||||
* copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||
* maximum set by xBufferLengthBytes.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for data to become available if the stream buffer is
|
||||
* empty. xStreamBufferReceive() will return immediately if xTicksToWait is
|
||||
* zero. The block time is specified in tick periods, so the absolute time it
|
||||
* represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can
|
||||
* be used to convert a time specified in milliseconds into a time specified in
|
||||
* ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait
|
||||
* indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
|
||||
* in FreeRTOSConfig.h. A task does not use any CPU time when it is in the
|
||||
* Blocked state.
|
||||
*
|
||||
* @return The number of bytes actually read from the stream buffer, which will
|
||||
* be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed
|
||||
* out before xBufferLengthBytes were available.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* void vAFunction( StreamBuffer_t xStreamBuffer )
|
||||
* {
|
||||
* uint8_t ucRxData[ 20 ];
|
||||
* size_t xReceivedBytes;
|
||||
* const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
|
||||
*
|
||||
* // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
|
||||
* // Wait in the Blocked state (so not using any CPU processing time) for a
|
||||
* // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
|
||||
* // available.
|
||||
* xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
|
||||
* ( void * ) ucRxData,
|
||||
* sizeof( ucRxData ),
|
||||
* xBlockTime );
|
||||
*
|
||||
* if( xReceivedBytes > 0 )
|
||||
* {
|
||||
* // A ucRxData contains another xReceivedBytes bytes of data, which can
|
||||
* // be processed here....
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xStreamBufferReceive xStreamBufferReceive
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void * pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
* void *pvRxData,
|
||||
* size_t xBufferLengthBytes,
|
||||
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* An interrupt safe version of the API function that receives bytes from a
|
||||
* stream buffer.
|
||||
*
|
||||
* Use xStreamBufferReceive() to read bytes from a stream buffer from a task.
|
||||
* Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an
|
||||
* interrupt service routine (ISR).
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which a stream
|
||||
* is being received.
|
||||
*
|
||||
* @param pvRxData A pointer to the buffer into which the received bytes are
|
||||
* copied.
|
||||
*
|
||||
* @param xBufferLengthBytes The length of the buffer pointed to by the
|
||||
* pvRxData parameter. This sets the maximum number of bytes to receive in one
|
||||
* call. xStreamBufferReceive will return as many bytes as possible up to a
|
||||
* maximum set by xBufferLengthBytes.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* xStreamBufferReceiveFromISR() can make space available, and so cause a task
|
||||
* that is waiting for space to leave the Blocked state. If calling
|
||||
* xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and
|
||||
* the unblocked task has a priority higher than the currently executing task
|
||||
* (the task that was interrupted), then, internally,
|
||||
* xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
|
||||
* If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a
|
||||
* context switch should be performed before the interrupt is exited. That will
|
||||
* ensure the interrupt returns directly to the highest priority Ready state
|
||||
* task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
|
||||
* passed into the function. See the code example below for an example.
|
||||
*
|
||||
* @return The number of bytes read from the stream buffer, if any.
|
||||
*
|
||||
* Example use:
|
||||
* @code{c}
|
||||
* // A stream buffer that has already been created.
|
||||
* StreamBuffer_t xStreamBuffer;
|
||||
*
|
||||
* void vAnInterruptServiceRoutine( void )
|
||||
* {
|
||||
* uint8_t ucRxData[ 20 ];
|
||||
* size_t xReceivedBytes;
|
||||
* BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
|
||||
*
|
||||
* // Receive the next stream from the stream buffer.
|
||||
* xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
|
||||
* ( void * ) ucRxData,
|
||||
* sizeof( ucRxData ),
|
||||
* &xHigherPriorityTaskWoken );
|
||||
*
|
||||
* if( xReceivedBytes > 0 )
|
||||
* {
|
||||
* // ucRxData contains xReceivedBytes read from the stream buffer.
|
||||
* // Process the stream here....
|
||||
* }
|
||||
*
|
||||
* // If xHigherPriorityTaskWoken was set to pdTRUE inside
|
||||
* // xStreamBufferReceiveFromISR() then a task that has a priority above the
|
||||
* // priority of the currently executing task was unblocked and a context
|
||||
* // switch should be performed to ensure the ISR returns to the unblocked
|
||||
* // task. In most FreeRTOS ports this is done by simply passing
|
||||
* // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
|
||||
* // variables value, and perform the context switch if necessary. Check the
|
||||
* // documentation for the port in use for port specific instructions.
|
||||
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
* }
|
||||
* @endcode
|
||||
* \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
void * pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Deletes a stream buffer that was previously created using a call to
|
||||
* xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream
|
||||
* buffer was created using dynamic memory (that is, by xStreamBufferCreate()),
|
||||
* then the allocated memory is freed.
|
||||
*
|
||||
* A stream buffer handle must not be used after the stream buffer has been
|
||||
* deleted.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to be deleted.
|
||||
*
|
||||
* \defgroup vStreamBufferDelete vStreamBufferDelete
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||
* does not have any free space, and therefore cannot accept any more data.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return If the stream buffer is full then pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferIsFull xStreamBufferIsFull
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||
* it does not contain any data.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return If the stream buffer is empty then pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||
* are no tasks blocked waiting to either send to or receive from the stream
|
||||
* buffer.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being reset.
|
||||
*
|
||||
* @return If the stream buffer is reset then pdPASS is returned. If there was
|
||||
* a task blocked waiting to send to or read from the stream buffer then the
|
||||
* stream buffer is not reset and pdFAIL is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferReset xStreamBufferReset
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Queries a stream buffer to see how much free space it contains, which is
|
||||
* equal to the amount of data that can be sent to the stream buffer before it
|
||||
* is full.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be written to the stream buffer before
|
||||
* the stream buffer would be full.
|
||||
*
|
||||
* \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
|
||||
* @endcode
|
||||
*
|
||||
* Queries a stream buffer to see how much data it contains, which is equal to
|
||||
* the number of bytes that can be read from the stream buffer before the stream
|
||||
* buffer would be empty.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being queried.
|
||||
*
|
||||
* @return The number of bytes that can be read from the stream buffer before
|
||||
* the stream buffer would be empty.
|
||||
*
|
||||
* \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
|
||||
* @endcode
|
||||
*
|
||||
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||
* stream buffer before a task that is blocked on the stream buffer to
|
||||
* wait for data is moved out of the blocked state. For example, if a task is
|
||||
* blocked on a read of an empty stream buffer that has a trigger level of 1
|
||||
* then the task will be unblocked when a single byte is written to the buffer
|
||||
* or the task's block time expires. As another example, if a task is blocked
|
||||
* on a read of an empty stream buffer that has a trigger level of 10 then the
|
||||
* task will not be unblocked until the stream buffer contains at least 10 bytes
|
||||
* or the task's block time expires. If a reading task's block time expires
|
||||
* before the trigger level is reached then the task will still receive however
|
||||
* many bytes are actually available. Setting a trigger level of 0 will result
|
||||
* in a trigger level of 1 being used. It is not valid to specify a trigger
|
||||
* level that is greater than the buffer size.
|
||||
*
|
||||
* A trigger level is set when the stream buffer is created, and can be modified
|
||||
* using xStreamBufferSetTriggerLevel().
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer being updated.
|
||||
*
|
||||
* @param xTriggerLevel The new trigger level for the stream buffer.
|
||||
*
|
||||
* @return If xTriggerLevel was less than or equal to the stream buffer's length
|
||||
* then the trigger level will be updated and pdTRUE is returned. Otherwise
|
||||
* pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||
size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is sent to a message buffer or stream buffer. If there was a task that
|
||||
* was blocked on the message or stream buffer waiting for data to arrive then
|
||||
* the sbSEND_COMPLETED() macro sends a notification to the task to remove it
|
||||
* from the Blocked state. xStreamBufferSendCompletedFromISR() does the same
|
||||
* thing. It is provided to enable application writers to implement their own
|
||||
* version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer to which data was
|
||||
* written.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xStreamBufferSendCompletedFromISR(). If calling
|
||||
* xStreamBufferSendCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* stream_buffer.h
|
||||
*
|
||||
* @code{c}
|
||||
* BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
* @endcode
|
||||
*
|
||||
* For advanced users only.
|
||||
*
|
||||
* The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
|
||||
* data is read out of a message buffer or stream buffer. If there was a task
|
||||
* that was blocked on the message or stream buffer waiting for data to arrive
|
||||
* then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
|
||||
* remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR()
|
||||
* does the same thing. It is provided to enable application writers to
|
||||
* implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
|
||||
* ANY OTHER TIME.
|
||||
*
|
||||
* See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
|
||||
* additional information.
|
||||
*
|
||||
* @param xStreamBuffer The handle of the stream buffer from which data was
|
||||
* read.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
|
||||
* initialised to pdFALSE before it is passed into
|
||||
* xStreamBufferReceiveCompletedFromISR(). If calling
|
||||
* xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state,
|
||||
* and the task has a priority above the priority of the currently running task,
|
||||
* then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
|
||||
* context switch should be performed before exiting the ISR.
|
||||
*
|
||||
* @return If a task was removed from the Blocked state then pdTRUE is returned.
|
||||
* Otherwise pdFALSE is returned.
|
||||
*
|
||||
* \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
|
||||
* \ingroup StreamBufferManagement
|
||||
*/
|
||||
BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||
BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* Functions below here are not part of the public API. */
|
||||
StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||
size_t xTriggerLevelBytes,
|
||||
BaseType_t xIsMessageBuffer,
|
||||
uint8_t * const pucStreamBufferStorageArea,
|
||||
StaticStreamBuffer_t * const pxStaticStreamBuffer,
|
||||
StreamBufferCallbackFunction_t pxSendCompletedCallback,
|
||||
StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
|
||||
|
||||
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
|
||||
UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#if defined( __cplusplus )
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* !defined( STREAM_BUFFER_H ) */
|
||||
3118
source/shoh/freertos/inc/task.h
Normal file
3118
source/shoh/freertos/inc/task.h
Normal file
File diff suppressed because it is too large
Load Diff
1369
source/shoh/freertos/inc/timers.h
Normal file
1369
source/shoh/freertos/inc/timers.h
Normal file
File diff suppressed because it is too large
Load Diff
94
source/shoh/freertos/src/FreeRTOSCommonHooks.c
Normal file
94
source/shoh/freertos/src/FreeRTOSCommonHooks.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* @brief Common FreeRTOS functions shared among platforms
|
||||
*
|
||||
* @note
|
||||
* Copyright(C) NXP Semiconductors, 2012
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* LPC products. This software is supplied "AS IS" without any warranties of
|
||||
* any kind, and NXP Semiconductors and its licensor disclaim any and
|
||||
* all warranties, express or implied, including all implied warranties of
|
||||
* merchantability, fitness for a particular purpose and non-infringement of
|
||||
* intellectual property rights. NXP Semiconductors assumes no responsibility
|
||||
* or liability for the use of the software, conveys no license or rights under any
|
||||
* patent, copyright, mask work right, or any other intellectual property rights in
|
||||
* or to any products. NXP Semiconductors reserves the right to make changes
|
||||
* in the software without notification. NXP Semiconductors also makes no
|
||||
* representation or warranty that such application will be suitable for the
|
||||
* specified use without further testing or modification.
|
||||
*
|
||||
* @par
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors' and its
|
||||
* licensor's relevant copyrights in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "portable.h"
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Delay for the specified number of milliSeconds */
|
||||
void FreeRTOSDelay(uint32_t ms)
|
||||
{
|
||||
portTickType xDelayTime;
|
||||
|
||||
xDelayTime = xTaskGetTickCount();
|
||||
vTaskDelayUntil(&xDelayTime, ms);
|
||||
}
|
||||
|
||||
/* FreeRTOS malloc fail hook */
|
||||
void vApplicationMallocFailedHook(void)
|
||||
{
|
||||
DEBUGSTR("DIE:ERROR:FreeRTOS: Malloc Failure!\r\n");
|
||||
taskDISABLE_INTERRUPTS();
|
||||
for (;; ) {}
|
||||
}
|
||||
|
||||
/* FreeRTOS application idle hook */
|
||||
void vApplicationIdleHook(void)
|
||||
{
|
||||
/* Best to sleep here until next systick */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/* FreeRTOS stack overflow hook */
|
||||
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName)
|
||||
{
|
||||
(void) pxTask;
|
||||
(void) pcTaskName;
|
||||
|
||||
DEBUGOUT("DIE:ERROR:FreeRTOS: Stack overflow in task %s\r\n", pcTaskName);
|
||||
/* Run time stack overflow checking is performed if
|
||||
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
|
||||
function is called if a stack overflow is detected. */
|
||||
taskDISABLE_INTERRUPTS();
|
||||
for (;; ) {}
|
||||
}
|
||||
|
||||
/* FreeRTOS application tick hook */
|
||||
void vApplicationTickHook(void)
|
||||
{}
|
||||
363
source/shoh/freertos/src/croutine.c
Normal file
363
source/shoh/freertos/src/croutine.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "croutine.h"
|
||||
|
||||
/* Remove the whole file is co-routines are not being used. */
|
||||
#if ( configUSE_CO_ROUTINES != 0 )
|
||||
|
||||
/*
|
||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||
* than file scope.
|
||||
*/
|
||||
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||
#define static
|
||||
#endif
|
||||
|
||||
|
||||
/* Lists for ready and blocked co-routines. --------------------*/
|
||||
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||
static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */
|
||||
static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||
static List_t 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. */
|
||||
|
||||
/* Other file private variables. --------------------------------*/
|
||||
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||
|
||||
/* The initial state of the co-routine when it is created. */
|
||||
#define corINITIAL_STATE ( 0 )
|
||||
|
||||
/*
|
||||
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||
* for the priority. It is inserted at the end of the list.
|
||||
*
|
||||
* This macro accesses the co-routine ready lists and therefore must not be
|
||||
* used from within an ISR.
|
||||
*/
|
||||
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
||||
{ \
|
||||
if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \
|
||||
{ \
|
||||
uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \
|
||||
} \
|
||||
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility to ready all the lists used by the scheduler. This is called
|
||||
* automatically upon the creation of the first co-routine.
|
||||
*/
|
||||
static void prvInitialiseCoRoutineLists( void );
|
||||
|
||||
/*
|
||||
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||
* the ready lists (there is no mutual exclusion). Instead they are placed in
|
||||
* in the pending ready list in order that they can later be moved to the ready
|
||||
* list by the co-routine scheduler.
|
||||
*/
|
||||
static void prvCheckPendingReadyList( void );
|
||||
|
||||
/*
|
||||
* Macro that looks at the list of co-routines that are currently delayed to
|
||||
* see if any require waking.
|
||||
*
|
||||
* Co-routines are stored in the queue in the order of their wake time -
|
||||
* meaning once one co-routine has been found whose timer has not expired
|
||||
* we need not look any further down the list.
|
||||
*/
|
||||
static void prvCheckDelayedList( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
|
||||
UBaseType_t uxPriority,
|
||||
UBaseType_t uxIndex )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
CRCB_t * pxCoRoutine;
|
||||
|
||||
/* Allocate the memory that will store the co-routine control block. */
|
||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||
|
||||
if( pxCoRoutine )
|
||||
{
|
||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||
* be created and the co-routine data structures need initialising. */
|
||||
if( pxCurrentCoRoutine == NULL )
|
||||
{
|
||||
pxCurrentCoRoutine = pxCoRoutine;
|
||||
prvInitialiseCoRoutineLists();
|
||||
}
|
||||
|
||||
/* Check the priority is within limits. */
|
||||
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
|
||||
{
|
||||
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
|
||||
}
|
||||
|
||||
/* Fill out the co-routine control block from the function parameters. */
|
||||
pxCoRoutine->uxState = corINITIAL_STATE;
|
||||
pxCoRoutine->uxPriority = uxPriority;
|
||||
pxCoRoutine->uxIndex = uxIndex;
|
||||
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
|
||||
|
||||
/* Initialise all the other co-routine control block parameters. */
|
||||
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||
|
||||
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||
* This is so we can get back to the containing CRCB from a generic item
|
||||
* in a list. */
|
||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||
|
||||
/* Event lists are always in priority order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||
|
||||
/* Now the co-routine has been initialised it can be added to the ready
|
||||
* list at the correct priority. */
|
||||
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
||||
List_t * pxEventList )
|
||||
{
|
||||
TickType_t xTimeToWake;
|
||||
|
||||
/* Calculate the time to wake - this may overflow but this is
|
||||
* not a problem. */
|
||||
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||
|
||||
/* We must remove ourselves from the ready list before adding
|
||||
* ourselves to the blocked list as the same list item is used for
|
||||
* both lists. */
|
||||
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||
|
||||
/* The list item will be inserted in wake time order. */
|
||||
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
||||
|
||||
if( xTimeToWake < xCoRoutineTickCount )
|
||||
{
|
||||
/* Wake time has overflowed. Place this item in the
|
||||
* overflow list. */
|
||||
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The wake time has not overflowed, so we can use the
|
||||
* current block list. */
|
||||
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||
}
|
||||
|
||||
if( pxEventList )
|
||||
{
|
||||
/* Also add the co-routine to an event list. If this is done then the
|
||||
* function must be called with interrupts disabled. */
|
||||
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCheckPendingReadyList( void )
|
||||
{
|
||||
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||
* are co-routines that have been readied by an ISR. The ISR cannot access
|
||||
* the ready lists itself. */
|
||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||
{
|
||||
CRCB_t * pxUnblockedCRCB;
|
||||
|
||||
/* The pending ready list can be accessed by an ISR. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) );
|
||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||
}
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCheckDelayedList( void )
|
||||
{
|
||||
CRCB_t * pxCRCB;
|
||||
|
||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||
|
||||
while( xPassedTicks )
|
||||
{
|
||||
xCoRoutineTickCount++;
|
||||
xPassedTicks--;
|
||||
|
||||
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||
if( xCoRoutineTickCount == 0 )
|
||||
{
|
||||
List_t * pxTemp;
|
||||
|
||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||
* any items in pxDelayedCoRoutineList here then there is an error! */
|
||||
pxTemp = pxDelayedCoRoutineList;
|
||||
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||
}
|
||||
|
||||
/* See if this tick has made a timeout expire. */
|
||||
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||
{
|
||||
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||
|
||||
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||
{
|
||||
/* Timeout not yet expired. */
|
||||
break;
|
||||
}
|
||||
|
||||
portDISABLE_INTERRUPTS();
|
||||
{
|
||||
/* The event could have occurred just before this critical
|
||||
* section. If this is the case then the generic list item will
|
||||
* have been moved to the pending ready list and the following
|
||||
* line is still valid. Also the pvContainer parameter will have
|
||||
* been set to NULL so the following lines are also valid. */
|
||||
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||
|
||||
/* Is the co-routine waiting on an event also? */
|
||||
if( pxCRCB->xEventListItem.pxContainer )
|
||||
{
|
||||
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
||||
}
|
||||
}
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
prvAddCoRoutineToReadyQueue( pxCRCB );
|
||||
}
|
||||
}
|
||||
|
||||
xLastTickCount = xCoRoutineTickCount;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vCoRoutineSchedule( void )
|
||||
{
|
||||
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been
|
||||
* called. prvInitialiseCoRoutineLists() is called automatically when a
|
||||
* co-routine is created. */
|
||||
if( pxDelayedCoRoutineList != NULL )
|
||||
{
|
||||
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||
prvCheckPendingReadyList();
|
||||
|
||||
/* See if any delayed co-routines have timed out. */
|
||||
prvCheckDelayedList();
|
||||
|
||||
/* Find the highest priority queue that contains ready co-routines. */
|
||||
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
|
||||
{
|
||||
if( uxTopCoRoutineReadyPriority == 0 )
|
||||
{
|
||||
/* No more co-routines to check. */
|
||||
return;
|
||||
}
|
||||
|
||||
--uxTopCoRoutineReadyPriority;
|
||||
}
|
||||
|
||||
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||
* of the same priority get an equal share of the processor time. */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||
|
||||
/* Call the co-routine. */
|
||||
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitialiseCoRoutineLists( void )
|
||||
{
|
||||
UBaseType_t uxPriority;
|
||||
|
||||
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||
{
|
||||
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
||||
}
|
||||
|
||||
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
|
||||
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
|
||||
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||
|
||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||
* pxOverflowDelayedCoRoutineList using list2. */
|
||||
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList )
|
||||
{
|
||||
CRCB_t * pxUnblockedCRCB;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* This function is called from within an interrupt. It can only access
|
||||
* event lists and the pending ready list. This function assumes that a
|
||||
* check has already been made to ensure pxEventList is not empty. */
|
||||
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||
|
||||
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||
778
source/shoh/freertos/src/event_groups.c
Normal file
778
source/shoh/freertos/src/event_groups.c
Normal file
@@ -0,0 +1,778 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
* all the API functions to use the MPU wrappers. That should only be done when
|
||||
* task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
||||
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
* for the header files above, but not in this file, in order to generate the
|
||||
* correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */
|
||||
|
||||
/* The following bit fields convey control information in a task's event list
|
||||
* item value. It is important they don't clash with the
|
||||
* taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
||||
#if configUSE_16_BIT_TICKS == 1
|
||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
||||
#define eventWAIT_FOR_ALL_BITS 0x0400U
|
||||
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
|
||||
#else
|
||||
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
|
||||
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
|
||||
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
|
||||
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
||||
#endif
|
||||
|
||||
typedef struct EventGroupDef_t
|
||||
{
|
||||
EventBits_t uxEventBits;
|
||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxEventGroupNumber;
|
||||
#endif
|
||||
|
||||
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
} EventGroup_t;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Test the bits set in uxCurrentEventBits to see if the wait condition is met.
|
||||
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
||||
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
||||
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||
* in uxCurrentEventBits.
|
||||
*/
|
||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer )
|
||||
{
|
||||
EventGroup_t * pxEventBits;
|
||||
|
||||
/* A StaticEventGroup_t object must be provided. */
|
||||
configASSERT( pxEventGroupBuffer );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
* variable of type StaticEventGroup_t equals the size of the real
|
||||
* event group structure. */
|
||||
volatile size_t xSize = sizeof( StaticEventGroup_t );
|
||||
configASSERT( xSize == sizeof( EventGroup_t ) );
|
||||
} /*lint !e529 xSize is referenced if configASSERT() is defined. */
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* The user has provided a statically allocated event group - use it. */
|
||||
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
pxEventBits->uxEventBits = 0;
|
||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* Both static and dynamic allocation can be used, so note that
|
||||
* this event group was created statically in case the event group
|
||||
* is later deleted. */
|
||||
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* xEventGroupCreateStatic should only ever be called with
|
||||
* pxEventGroupBuffer pointing to a pre-allocated (compile time
|
||||
* allocated) StaticEventGroup_t variable. */
|
||||
traceEVENT_GROUP_CREATE_FAILED();
|
||||
}
|
||||
|
||||
return pxEventBits;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
EventGroupHandle_t xEventGroupCreate( void )
|
||||
{
|
||||
EventGroup_t * pxEventBits;
|
||||
|
||||
/* Allocate the event group. Justification for MISRA deviation as
|
||||
* follows: pvPortMalloc() always ensures returned memory blocks are
|
||||
* aligned per the requirements of the MCU stack. In this case
|
||||
* pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||
* alignment requirements of the EventGroup_t structure - which (if you
|
||||
* follow it through) is the alignment requirements of the TickType_t type
|
||||
* (EventBits_t being of TickType_t itself). Therefore, whenever the
|
||||
* stack alignment requirements are greater than or equal to the
|
||||
* TickType_t alignment requirements the cast is safe. In other cases,
|
||||
* where the natural word size of the architecture is less than
|
||||
* sizeof( TickType_t ), the TickType_t variables will be accessed in two
|
||||
* or more reads operations, and the alignment requirements is only that
|
||||
* of each individual read. */
|
||||
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
|
||||
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
pxEventBits->uxEventBits = 0;
|
||||
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
{
|
||||
/* Both static and dynamic allocation can be used, so note this
|
||||
* event group was allocated statically in case the event group is
|
||||
* later deleted. */
|
||||
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
|
||||
}
|
||||
|
||||
return pxEventBits;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
EventBits_t uxOriginalBitValue, uxReturn;
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
BaseType_t xAlreadyYielded;
|
||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
|
||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
configASSERT( uxBitsToWaitFor != 0 );
|
||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||
{
|
||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
uxOriginalBitValue = pxEventBits->uxEventBits;
|
||||
|
||||
( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
|
||||
|
||||
if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
/* All the rendezvous bits are now set - no need to block. */
|
||||
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||
|
||||
/* Rendezvous always clear the bits. They will have been cleared
|
||||
* already unless this is the only task in the rendezvous. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
|
||||
xTicksToWait = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||
|
||||
/* Store the bits that the calling task is waiting for in the
|
||||
* task's event list item so the kernel knows when a match is
|
||||
* found. Then enter the blocked state. */
|
||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||
|
||||
/* This assignment is obsolete as uxReturn will get set after
|
||||
* the task unblocks, but some compilers mistakenly generate a
|
||||
* warning about uxReturn being returned without being set if the
|
||||
* assignment is omitted. */
|
||||
uxReturn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The rendezvous bits were not set, but no block time was
|
||||
* specified - just return the current event bit value. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
if( xAlreadyYielded == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* The task blocked to wait for its required bits to be set - at this
|
||||
* point either the required bits were set or the block time expired. If
|
||||
* the required bits were set they will have been stored in the task's
|
||||
* event list item, and they should now be retrieved then cleared. */
|
||||
uxReturn = uxTaskResetEventItemValue();
|
||||
|
||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||
{
|
||||
/* The task timed out, just return the current event bit value. */
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* Although the task got here because it timed out before the
|
||||
* bits it was waiting for were set, it is possible that since it
|
||||
* unblocked another task has set the bits. If this is the case
|
||||
* then it needs to clear the bits before exiting. */
|
||||
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task unblocked because the bits were set. */
|
||||
}
|
||||
|
||||
/* Control bits might be set as the task had blocked should not be
|
||||
* returned. */
|
||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
}
|
||||
|
||||
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
( void ) xTimeoutOccurred;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn, uxControlBits = 0;
|
||||
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||
|
||||
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||
* itself, and that at least one bit is being requested. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
configASSERT( uxBitsToWaitFor != 0 );
|
||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||
{
|
||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
|
||||
|
||||
/* Check to see if the wait condition is already met or not. */
|
||||
xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
|
||||
|
||||
if( xWaitConditionMet != pdFALSE )
|
||||
{
|
||||
/* The wait condition has already been met so there is no need to
|
||||
* block. */
|
||||
uxReturn = uxCurrentEventBits;
|
||||
xTicksToWait = ( TickType_t ) 0;
|
||||
|
||||
/* Clear the wait bits if requested to do so. */
|
||||
if( xClearOnExit != pdFALSE )
|
||||
{
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||
{
|
||||
/* The wait condition has not been met, but no block time was
|
||||
* specified, so just return the current value. */
|
||||
uxReturn = uxCurrentEventBits;
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task is going to block to wait for its required bits to be
|
||||
* set. uxControlBits are used to remember the specified behaviour of
|
||||
* this call to xEventGroupWaitBits() - for use when the event bits
|
||||
* unblock the task. */
|
||||
if( xClearOnExit != pdFALSE )
|
||||
{
|
||||
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
if( xWaitForAllBits != pdFALSE )
|
||||
{
|
||||
uxControlBits |= eventWAIT_FOR_ALL_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Store the bits that the calling task is waiting for in the
|
||||
* task's event list item so the kernel knows when a match is
|
||||
* found. Then enter the blocked state. */
|
||||
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||
|
||||
/* This is obsolete as it will get set after the task unblocks, but
|
||||
* some compilers mistakenly generate a warning about the variable
|
||||
* being returned without being set if it is not done. */
|
||||
uxReturn = 0;
|
||||
|
||||
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||
}
|
||||
}
|
||||
xAlreadyYielded = xTaskResumeAll();
|
||||
|
||||
if( xTicksToWait != ( TickType_t ) 0 )
|
||||
{
|
||||
if( xAlreadyYielded == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* The task blocked to wait for its required bits to be set - at this
|
||||
* point either the required bits were set or the block time expired. If
|
||||
* the required bits were set they will have been stored in the task's
|
||||
* event list item, and they should now be retrieved then cleared. */
|
||||
uxReturn = uxTaskResetEventItemValue();
|
||||
|
||||
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* The task timed out, just return the current event bit value. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* It is possible that the event bits were updated between this
|
||||
* task leaving the Blocked state and running again. */
|
||||
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||
{
|
||||
if( xClearOnExit != pdFALSE )
|
||||
{
|
||||
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
xTimeoutOccurred = pdTRUE;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task unblocked because the bits were set. */
|
||||
}
|
||||
|
||||
/* The task blocked so control bits may have been set. */
|
||||
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
}
|
||||
|
||||
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||
|
||||
/* Prevent compiler warnings when trace macros are not used. */
|
||||
( void ) xTimeoutOccurred;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
{
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
/* Check the user is not attempting to clear the bits used by the kernel
|
||||
* itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||
|
||||
/* The value returned is the event group value prior to the bits being
|
||||
* cleared. */
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
|
||||
/* Clear the bits. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
EventGroup_t const * const pxEventBits = xEventGroup;
|
||||
EventBits_t uxReturn;
|
||||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
uxReturn = pxEventBits->uxEventBits;
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||
|
||||
return uxReturn;
|
||||
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet )
|
||||
{
|
||||
ListItem_t * pxListItem;
|
||||
ListItem_t * pxNext;
|
||||
ListItem_t const * pxListEnd;
|
||||
List_t const * pxList;
|
||||
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
BaseType_t xMatchFound = pdFALSE;
|
||||
|
||||
/* Check the user is not attempting to set the bits used by the kernel
|
||||
* itself. */
|
||||
configASSERT( xEventGroup );
|
||||
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||
|
||||
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||
|
||||
pxListItem = listGET_HEAD_ENTRY( pxList );
|
||||
|
||||
/* Set the bits. */
|
||||
pxEventBits->uxEventBits |= uxBitsToSet;
|
||||
|
||||
/* See if the new bit value should unblock any tasks. */
|
||||
while( pxListItem != pxListEnd )
|
||||
{
|
||||
pxNext = listGET_NEXT( pxListItem );
|
||||
uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
|
||||
xMatchFound = pdFALSE;
|
||||
|
||||
/* Split the bits waited for from the control bits. */
|
||||
uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
|
||||
uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||
|
||||
if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
|
||||
{
|
||||
/* Just looking for single bit being set. */
|
||||
if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
xMatchFound = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
|
||||
{
|
||||
/* All bits are set. */
|
||||
xMatchFound = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Need all bits to be set, but not all the bits were set. */
|
||||
}
|
||||
|
||||
if( xMatchFound != pdFALSE )
|
||||
{
|
||||
/* The bits match. Should the bits be cleared on exit? */
|
||||
if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
uxBitsToClear |= uxBitsWaitedFor;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Store the actual event flag value in the task's event list
|
||||
* item before removing the task from the event list. The
|
||||
* eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||
* that is was unblocked due to its required bits matching, rather
|
||||
* than because it timed out. */
|
||||
vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
|
||||
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||
* used here as the list item may have been removed from the event list
|
||||
* and inserted into the ready/pending reading list. */
|
||||
pxListItem = pxNext;
|
||||
}
|
||||
|
||||
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||
* bit was set in the control word. */
|
||||
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
return pxEventBits->uxEventBits;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventGroup_t * pxEventBits = xEventGroup;
|
||||
const List_t * pxTasksWaitingForBits;
|
||||
|
||||
configASSERT( pxEventBits );
|
||||
|
||||
pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||
|
||||
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* Unblock the task, returning 0 as the event list is being deleted
|
||||
* and cannot therefore have any bits set. */
|
||||
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||
vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||
}
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||
{
|
||||
/* The event group can only have been allocated dynamically - free
|
||||
* it again. */
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
{
|
||||
/* The event group could have been allocated statically or
|
||||
* dynamically, so check before attempting to free the memory. */
|
||||
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||
{
|
||||
vPortFree( pxEventBits );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* For internal use only - execute a 'set bits' command that was pended from
|
||||
* an interrupt. */
|
||||
void vEventGroupSetBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToSet )
|
||||
{
|
||||
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||
* an interrupt. */
|
||||
void vEventGroupClearBitsCallback( void * pvEventGroup,
|
||||
const uint32_t ulBitsToClear )
|
||||
{
|
||||
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xWaitForAllBits )
|
||||
{
|
||||
BaseType_t xWaitConditionMet = pdFALSE;
|
||||
|
||||
if( xWaitForAllBits == pdFALSE )
|
||||
{
|
||||
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||
* set. Is one already set? */
|
||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||
{
|
||||
xWaitConditionMet = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||
* Are they set already? */
|
||||
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||
{
|
||||
xWaitConditionMet = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
|
||||
return xWaitConditionMet;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
BaseType_t * pxHigherPriorityTaskWoken )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
UBaseType_t uxEventGroupGetNumber( void * xEventGroup )
|
||||
{
|
||||
UBaseType_t xReturn;
|
||||
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
|
||||
if( xEventGroup == NULL )
|
||||
{
|
||||
xReturn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pxEventBits->uxEventGroupNumber;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void vEventGroupSetNumber( void * xEventGroup,
|
||||
UBaseType_t uxEventGroupNumber )
|
||||
{
|
||||
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
|
||||
}
|
||||
|
||||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
95
source/shoh/freertos/src/heap_3.c
Normal file
95
source/shoh/freertos/src/heap_3.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Implementation of pvPortMalloc() and vPortFree() that relies on the
|
||||
* compilers own malloc() and free() implementations.
|
||||
*
|
||||
* This file can only be used if the linker is configured to to generate
|
||||
* a heap memory area.
|
||||
*
|
||||
* See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the
|
||||
* memory management pages of https://www.FreeRTOS.org for more information.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
* all the API functions to use the MPU wrappers. That should only be done when
|
||||
* task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "portable.h"
|
||||
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
||||
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void * pvPortMalloc( size_t xWantedSize )
|
||||
{
|
||||
void * pvReturn;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
pvReturn = malloc( xWantedSize );
|
||||
traceMALLOC( pvReturn, xWantedSize );
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
|
||||
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
|
||||
{
|
||||
if( pvReturn == NULL )
|
||||
{
|
||||
vApplicationMallocFailedHook();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return pvReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortFree( void * pv )
|
||||
{
|
||||
if( pv != NULL )
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
free( pv );
|
||||
traceFREE( pv, 0 );
|
||||
}
|
||||
( void ) xTaskResumeAll();
|
||||
}
|
||||
}
|
||||
226
source/shoh/freertos/src/list.c
Normal file
226
source/shoh/freertos/src/list.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||
* all the API functions to use the MPU wrappers. That should only be done when
|
||||
* task.h is included from an application file. */
|
||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "list.h"
|
||||
|
||||
/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified
|
||||
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
|
||||
* defined for the header files above, but not in this file, in order to
|
||||
* generate the correct privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* PUBLIC LIST API documented in list.h
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
void vListInitialise( List_t * const pxList )
|
||||
{
|
||||
/* The list structure contains a list item which is used to mark the
|
||||
* end of the list. To initialise the list the list end is inserted
|
||||
* as the only list entry. */
|
||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
|
||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||
|
||||
/* The list end value is the highest possible value in the list to
|
||||
* ensure it remains at the end of the list. */
|
||||
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||
|
||||
/* The list end next and previous pointers point to itself so we know
|
||||
* when the list is empty. */
|
||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||
|
||||
/* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
|
||||
#if ( configUSE_MINI_LIST_ITEM == 0 )
|
||||
{
|
||||
pxList->xListEnd.pvOwner = NULL;
|
||||
pxList->xListEnd.pxContainer = NULL;
|
||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||
|
||||
/* Write known values into the list if
|
||||
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||
{
|
||||
/* Make sure the list item is not recorded as being on a list. */
|
||||
pxItem->pxContainer = NULL;
|
||||
|
||||
/* Write known values into the list item if
|
||||
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInsertEnd( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem )
|
||||
{
|
||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||
|
||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||
* the list data structures being overwritten in memory. They will not catch
|
||||
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||
listTEST_LIST_INTEGRITY( pxList );
|
||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||
|
||||
/* Insert a new list item into pxList, but rather than sort the list,
|
||||
* makes the new list item the last item to be removed by a call to
|
||||
* listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||
pxNewListItem->pxNext = pxIndex;
|
||||
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||
|
||||
/* Only used during decision coverage testing. */
|
||||
mtCOVERAGE_TEST_DELAY();
|
||||
|
||||
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
||||
pxIndex->pxPrevious = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vListInsert( List_t * const pxList,
|
||||
ListItem_t * const pxNewListItem )
|
||||
{
|
||||
ListItem_t * pxIterator;
|
||||
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||
|
||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||
* the list data structures being overwritten in memory. They will not catch
|
||||
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||
listTEST_LIST_INTEGRITY( pxList );
|
||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||
|
||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||
*
|
||||
* If the list already contains a list item with the same item value then the
|
||||
* new list item should be placed after it. This ensures that TCBs which are
|
||||
* stored in ready lists (all of which have the same xItemValue value) get a
|
||||
* share of the CPU. However, if the xItemValue is the same as the back marker
|
||||
* the iteration loop below will not end. Therefore the value is checked
|
||||
* first, and the algorithm slightly modified if necessary. */
|
||||
if( xValueOfInsertion == portMAX_DELAY )
|
||||
{
|
||||
pxIterator = pxList->xListEnd.pxPrevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* *** NOTE ***********************************************************
|
||||
* If you find your application is crashing here then likely causes are
|
||||
* listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for
|
||||
* more tips, and ensure configASSERT() is defined!
|
||||
* https://www.FreeRTOS.org/a00110.html#configASSERT
|
||||
*
|
||||
* 1) Stack overflow -
|
||||
* see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
|
||||
* 2) Incorrect interrupt priority assignment, especially on Cortex-M
|
||||
* parts where numerically high priority values denote low actual
|
||||
* interrupt priorities, which can seem counter intuitive. See
|
||||
* https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
|
||||
* of configMAX_SYSCALL_INTERRUPT_PRIORITY on
|
||||
* https://www.FreeRTOS.org/a00110.html
|
||||
* 3) Calling an API function from within a critical section or when
|
||||
* the scheduler is suspended, or calling an API function that does
|
||||
* not end in "FromISR" from an interrupt.
|
||||
* 4) Using a queue or semaphore before it has been initialised or
|
||||
* before the scheduler has been started (are interrupts firing
|
||||
* before vTaskStartScheduler() has been called?).
|
||||
* 5) If the FreeRTOS port supports interrupt nesting then ensure that
|
||||
* the priority of the tick interrupt is at or below
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
**********************************************************************/
|
||||
|
||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||
{
|
||||
/* There is nothing to do here, just iterating to the wanted
|
||||
* insertion position. */
|
||||
}
|
||||
}
|
||||
|
||||
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
||||
pxNewListItem->pxPrevious = pxIterator;
|
||||
pxIterator->pxNext = pxNewListItem;
|
||||
|
||||
/* Remember which list the item is in. This allows fast removal of the
|
||||
* item later. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||
{
|
||||
/* The list item knows which list it is in. Obtain the list from the list
|
||||
* item. */
|
||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||
|
||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||
|
||||
/* Only used during decision coverage testing. */
|
||||
mtCOVERAGE_TEST_DELAY();
|
||||
|
||||
/* Make sure the index is left pointing to a valid item. */
|
||||
if( pxList->pxIndex == pxItemToRemove )
|
||||
{
|
||||
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
pxItemToRemove->pxContainer = NULL;
|
||||
( pxList->uxNumberOfItems )--;
|
||||
|
||||
return pxList->uxNumberOfItems;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
633
source/shoh/freertos/src/port.c
Normal file
633
source/shoh/freertos/src/port.c
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.5.1
|
||||
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
* https://github.com/FreeRTOS
|
||||
*
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM CM0 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) )
|
||||
#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) )
|
||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) )
|
||||
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||
#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
|
||||
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
|
||||
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
||||
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
||||
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||
#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL )
|
||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
|
||||
#define portMIN_INTERRUPT_PRIORITY ( 255UL )
|
||||
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
|
||||
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
/* The systick is a 24-bit counter. */
|
||||
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
|
||||
|
||||
/* A fiddle factor to estimate the number of SysTick counts that would have
|
||||
* occurred while the SysTick counter is stopped during tickless idle
|
||||
* calculations. */
|
||||
#ifndef portMISSED_COUNTS_FACTOR
|
||||
#define portMISSED_COUNTS_FACTOR ( 94UL )
|
||||
#endif
|
||||
|
||||
/* Let the user override the default SysTick clock rate. If defined by the
|
||||
* user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the
|
||||
* configuration register. */
|
||||
#ifndef configSYSTICK_CLOCK_HZ
|
||||
#define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ )
|
||||
/* Ensure the SysTick is clocked at the same frequency as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT )
|
||||
#else
|
||||
/* Select the option to clock SysTick not at the same frequency as the core. */
|
||||
#define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 )
|
||||
#endif
|
||||
|
||||
/* Let the user override the pre-loading of the initial LR with the address of
|
||||
* prvTaskExitError() in case it messes up unwinding of the stack in the
|
||||
* debugger. */
|
||||
#ifdef configTASK_RETURN_ADDRESS
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
#else
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||
* file is weak to allow application writers to change the timer used to
|
||||
* generate the tick interrupt.
|
||||
*/
|
||||
void vPortSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* Exception handlers.
|
||||
*/
|
||||
void xPortPendSVHandler( void ) __attribute__( ( naked ) );
|
||||
void xPortSysTickHandler( void );
|
||||
void vPortSVCHandler( void );
|
||||
|
||||
/*
|
||||
* Start first task is a separate function so it can be tested in isolation.
|
||||
*/
|
||||
static void vPortStartFirstTask( void ) __attribute__( ( naked ) );
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
* variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulTimerCountsForOneTick = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* The maximum number of tick periods that can be suppressed is limited by the
|
||||
* 24 bit resolution of the SysTick timer.
|
||||
*/
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||
* power functionality only.
|
||||
*/
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulStoppedTimerCompensation = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
* interrupt. */
|
||||
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
|
||||
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxCode; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack -= 8; /* R11..R4. */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
volatile uint32_t ulDummy = 0UL;
|
||||
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
* its caller as there is nothing to return to. If a task wants to exit it
|
||||
* should instead call vTaskDelete( NULL ).
|
||||
*
|
||||
* Artificially force an assert() to be triggered if configASSERT() is
|
||||
* defined, then stop here so application writers can catch the error. */
|
||||
configASSERT( uxCriticalNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
while( ulDummy == 0 )
|
||||
{
|
||||
/* This file calls prvTaskExitError() after the scheduler has been
|
||||
* started to remove a compiler warning about the function being defined
|
||||
* but never called. ulDummy is used purely to quieten other warnings
|
||||
* about code appearing after this function is called - making ulDummy
|
||||
* volatile makes the compiler think the function could return and
|
||||
* therefore not output an 'unreachable code' warning for code that appears
|
||||
* after it. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortSVCHandler( void )
|
||||
{
|
||||
/* This function is no longer used, but retained for backward
|
||||
* compatibility. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortStartFirstTask( void )
|
||||
{
|
||||
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||
* table offset register that can be used to locate the initial stack value.
|
||||
* Not all M0 parts have the application vector table at address 0. */
|
||||
__asm volatile (
|
||||
" .syntax unified \n"
|
||||
" ldr r2, pxCurrentTCBConst2 \n"/* Obtain location of pxCurrentTCB. */
|
||||
" ldr r3, [r2] \n"
|
||||
" ldr r0, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" adds r0, #32 \n"/* Discard everything up to r0. */
|
||||
" msr psp, r0 \n"/* This is now the new top of stack to use in the task. */
|
||||
" movs r0, #2 \n"/* Switch to the psp stack. */
|
||||
" msr CONTROL, r0 \n"
|
||||
" isb \n"
|
||||
" pop {r0-r5} \n"/* Pop the registers that are saved automatically. */
|
||||
" mov lr, r5 \n"/* lr is now in r5. */
|
||||
" pop {r3} \n"/* Return address is now in r3. */
|
||||
" pop {r2} \n"/* Pop and discard XPSR. */
|
||||
" cpsie i \n"/* The first task has its context and interrupts can be enabled. */
|
||||
" bx r3 \n"/* Finally, jump to the user defined task code. */
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst2: .word pxCurrentTCB "
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* Make PendSV, CallSV and SysTick the same priority as the kernel. */
|
||||
portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
|
||||
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
* here already. */
|
||||
vPortSetupTimerInterrupt();
|
||||
|
||||
/* Initialise the critical nesting count ready for the first task. */
|
||||
uxCriticalNesting = 0;
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should never get here as the tasks will now be executing! Call the task
|
||||
* exit error function to prevent compiler warnings about a static function
|
||||
* not being called in the case that the application writer overrides this
|
||||
* functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||
* vTaskSwitchContext() so link time optimisation does not remove the
|
||||
* symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
* Artificially force an assert. */
|
||||
configASSERT( uxCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYield( void )
|
||||
{
|
||||
/* Set a PendSV to request a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
|
||||
/* Barriers are normally not required but do ensure the code is completely
|
||||
* within the specified behaviour for the architecture. */
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
configASSERT( uxCriticalNesting );
|
||||
uxCriticalNesting--;
|
||||
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void )
|
||||
{
|
||||
__asm volatile (
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr "
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask )
|
||||
{
|
||||
__asm volatile (
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr "
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortPendSVHandler( void )
|
||||
{
|
||||
/* This is a naked function. */
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" .syntax unified \n"
|
||||
" mrs r0, psp \n"
|
||||
" \n"
|
||||
" ldr r3, pxCurrentTCBConst \n"/* Get the location of the current TCB. */
|
||||
" ldr r2, [r3] \n"
|
||||
" \n"
|
||||
" subs r0, r0, #32 \n"/* Make space for the remaining low registers. */
|
||||
" str r0, [r2] \n"/* Save the new top of stack. */
|
||||
" stmia r0!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */
|
||||
" mov r4, r8 \n"/* Store the high registers. */
|
||||
" mov r5, r9 \n"
|
||||
" mov r6, r10 \n"
|
||||
" mov r7, r11 \n"
|
||||
" stmia r0!, {r4-r7} \n"
|
||||
" \n"
|
||||
" push {r3, r14} \n"
|
||||
" cpsid i \n"
|
||||
" bl vTaskSwitchContext \n"
|
||||
" cpsie i \n"
|
||||
" pop {r2, r3} \n"/* lr goes in r3. r2 now holds tcb pointer. */
|
||||
" \n"
|
||||
" ldr r1, [r2] \n"
|
||||
" ldr r0, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" adds r0, r0, #16 \n"/* Move to the high registers. */
|
||||
" ldmia r0!, {r4-r7} \n"/* Pop the high registers. */
|
||||
" mov r8, r4 \n"
|
||||
" mov r9, r5 \n"
|
||||
" mov r10, r6 \n"
|
||||
" mov r11, r7 \n"
|
||||
" \n"
|
||||
" msr psp, r0 \n"/* Remember the new top of stack for the task. */
|
||||
" \n"
|
||||
" subs r0, r0, #32 \n"/* Go back for the low registers that are not automatically restored. */
|
||||
" ldmia r0!, {r4-r7} \n"/* Pop low registers. */
|
||||
" \n"
|
||||
" bx r3 \n"
|
||||
" \n"
|
||||
" .align 4 \n"
|
||||
"pxCurrentTCBConst: .word pxCurrentTCB "
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
uint32_t ulPreviousMask;
|
||||
|
||||
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
/* Increment the RTOS tick. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Pend a context switch. */
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Calculate the constants required to configure the tick interrupt. */
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
{
|
||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
|
||||
}
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/* Stop and reset the SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Configure SysTick to interrupt at the requested rate. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
__attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||
{
|
||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft;
|
||||
TickType_t xModifiableIdleTime;
|
||||
|
||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
|
||||
{
|
||||
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
|
||||
}
|
||||
|
||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||
* method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
/* If a context switch is pending or a task is waiting for the scheduler
|
||||
* to be unsuspended then abandon the low power entry. */
|
||||
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
||||
{
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction
|
||||
* above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stop the SysTick momentarily. The time the SysTick is stopped for
|
||||
* is accounted for as best it can be, but using the tickless mode will
|
||||
* inevitably result in some tiny drift of the time maintained by the
|
||||
* kernel with respect to calendar time. */
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT );
|
||||
|
||||
/* Use the SysTick current-value register to determine the number of
|
||||
* SysTick decrements remaining until the next tick interrupt. If the
|
||||
* current-value register is zero, then there are actually
|
||||
* ulTimerCountsForOneTick decrements remaining, not zero, because the
|
||||
* SysTick requests the interrupt when decrementing from 1 to 0. */
|
||||
ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
|
||||
if( ulSysTickDecrementsLeft == 0 )
|
||||
{
|
||||
ulSysTickDecrementsLeft = ulTimerCountsForOneTick;
|
||||
}
|
||||
|
||||
/* Calculate the reload value required to wait xExpectedIdleTime
|
||||
* tick periods. -1 is used because this code normally executes part
|
||||
* way through the first tick period. But if the SysTick IRQ is now
|
||||
* pending, then clear the IRQ, suppressing the first tick, and correct
|
||||
* the reload value to reflect that the second tick period is already
|
||||
* underway. The expected idle time is always at least two ticks. */
|
||||
ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
|
||||
|
||||
if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 )
|
||||
{
|
||||
portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT;
|
||||
ulReloadValue -= ulTimerCountsForOneTick;
|
||||
}
|
||||
|
||||
if( ulReloadValue > ulStoppedTimerCompensation )
|
||||
{
|
||||
ulReloadValue -= ulStoppedTimerCompensation;
|
||||
}
|
||||
|
||||
/* Set the new reload value. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
|
||||
|
||||
/* Clear the SysTick count flag and set the count value back to
|
||||
* zero. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Restart SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
|
||||
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
|
||||
* set its parameter to 0 to indicate that its implementation contains
|
||||
* its own wait for interrupt or wait for event instruction, and so wfi
|
||||
* should not be executed again. However, the original expected idle
|
||||
* time variable must remain unmodified, so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile ( "dsb" ::: "memory" );
|
||||
__asm volatile ( "wfi" );
|
||||
__asm volatile ( "isb" );
|
||||
}
|
||||
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
* out of sleep mode to execute immediately. See comments above
|
||||
* the cpsid instruction above. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
/* Disable interrupts again because the clock is about to be stopped
|
||||
* and interrupts that execute while the clock is stopped will increase
|
||||
* any slippage between the time maintained by the RTOS and calendar
|
||||
* time. */
|
||||
__asm volatile ( "cpsid i" ::: "memory" );
|
||||
__asm volatile ( "dsb" );
|
||||
__asm volatile ( "isb" );
|
||||
|
||||
/* Disable the SysTick clock without reading the
|
||||
* portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||
* portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||
* the time the SysTick is stopped for is accounted for as best it can
|
||||
* be, but using the tickless mode will inevitably result in some tiny
|
||||
* drift of the time maintained by the kernel with respect to calendar
|
||||
* time*/
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT );
|
||||
|
||||
/* Determine whether the SysTick has already counted to zero. */
|
||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||
{
|
||||
uint32_t ulCalculatedLoadValue;
|
||||
|
||||
/* The tick interrupt ended the sleep (or is now pending), and
|
||||
* a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG
|
||||
* with whatever remains of the new tick period. */
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||
|
||||
/* Don't allow a tiny value, or values that have somehow
|
||||
* underflowed because the post sleep hook did something
|
||||
* that took too long or because the SysTick current-value register
|
||||
* is zero. */
|
||||
if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
|
||||
{
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
|
||||
}
|
||||
|
||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||
|
||||
/* As the pending tick will be processed as soon as this
|
||||
* function exits, the tick value maintained by the tick is stepped
|
||||
* forward by one less than the time spent waiting. */
|
||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something other than the tick interrupt ended the sleep. */
|
||||
|
||||
/* Use the SysTick current-value register to determine the
|
||||
* number of SysTick decrements remaining until the expected idle
|
||||
* time would have ended. */
|
||||
ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
||||
#if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT )
|
||||
{
|
||||
/* If the SysTick is not using the core clock, the current-
|
||||
* value register might still be zero here. In that case, the
|
||||
* SysTick didn't load from the reload register, and there are
|
||||
* ulReloadValue decrements remaining in the expected idle
|
||||
* time, not zero. */
|
||||
if( ulSysTickDecrementsLeft == 0 )
|
||||
{
|
||||
ulSysTickDecrementsLeft = ulReloadValue;
|
||||
}
|
||||
}
|
||||
#endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */
|
||||
|
||||
/* Work out how long the sleep lasted rounded to complete tick
|
||||
* periods (not the ulReload value which accounted for part
|
||||
* ticks). */
|
||||
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft;
|
||||
|
||||
/* How many complete tick periods passed while the processor
|
||||
* was waiting? */
|
||||
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
|
||||
|
||||
/* The reload value is set to whatever fraction of a single tick
|
||||
* period remains. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
||||
}
|
||||
|
||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again,
|
||||
* then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If
|
||||
* the SysTick is not using the core clock, temporarily configure it to
|
||||
* use the core clock. This configuration forces the SysTick to load
|
||||
* from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next
|
||||
* cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready
|
||||
* to receive the standard value immediately. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||
#if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT )
|
||||
{
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* The temporary usage of the core clock has served its purpose,
|
||||
* as described above. Resume usage of the other clock. */
|
||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
|
||||
|
||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||
{
|
||||
/* The partial tick period already ended. Be sure the SysTick
|
||||
* counts it only once. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0;
|
||||
}
|
||||
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
||||
}
|
||||
#endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */
|
||||
|
||||
/* Step the tick to account for any tick periods that elapsed. */
|
||||
vTaskStepTick( ulCompleteTickPeriods );
|
||||
|
||||
/* Exit with interrupts enabled. */
|
||||
__asm volatile ( "cpsie i" ::: "memory" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
3087
source/shoh/freertos/src/queue.c
Normal file
3087
source/shoh/freertos/src/queue.c
Normal file
File diff suppressed because it is too large
Load Diff
1427
source/shoh/freertos/src/stream_buffer.c
Normal file
1427
source/shoh/freertos/src/stream_buffer.c
Normal file
File diff suppressed because it is too large
Load Diff
5429
source/shoh/freertos/src/tasks.c
Normal file
5429
source/shoh/freertos/src/tasks.c
Normal file
File diff suppressed because it is too large
Load Diff
1124
source/shoh/freertos/src/timers.c
Normal file
1124
source/shoh/freertos/src/timers.c
Normal file
File diff suppressed because it is too large
Load Diff
503
source/shoh/src/FreeRTOSCPP/EventGroups.hpp
Normal file
503
source/shoh/src/FreeRTOSCPP/EventGroups.hpp
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_EVENTGROUPS_HPP
|
||||
#define FREERTOS_EVENTGROUPS_HPP
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class EventGroupBase EventGroupBase.hpp <FreeRTOS/EventGroups.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard event group interface to
|
||||
* FreeRTOS::EventGroup and FreeRTOS::StaticEventGroup.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::EventGroup or FreeRTOS::StaticEventGroup.
|
||||
*/
|
||||
class EventGroupBase {
|
||||
public:
|
||||
friend class EventGroup;
|
||||
friend class StaticEventGroup;
|
||||
|
||||
EventGroupBase(const EventGroupBase&) = delete;
|
||||
EventGroupBase& operator=(const EventGroupBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
using EventBits = std::bitset<((configUSE_16_BIT_TICKS == 1) ? 8 : 24)>;
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that checks if the underlying event group handle is not
|
||||
* NULL. This should be used to ensure an event group has been created
|
||||
* correctly.
|
||||
*
|
||||
* @retval true the handle is not NULL.
|
||||
* @retval false the handle is NULL.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>EventBits_t xEventGroupWaitBits( const
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const
|
||||
* BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t
|
||||
* xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupWaitBits.html>
|
||||
*
|
||||
* Read bits within an RTOS event group, optionally entering the Blocked state
|
||||
* (with a timeout) to wait for a bit or group of bits to become set.
|
||||
*
|
||||
* @warning This function cannot be called from an interrupt.
|
||||
*
|
||||
* @param bitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. bitsToWaitFor must not be set to 0.
|
||||
* @param clearOnExit If clearOnExit is set to true then any bits set in the
|
||||
* value passed as the bitsToWaitFor parameter will be cleared in the event
|
||||
* group before wait() returns if wait() returns for any reason other than a
|
||||
* timeout. The timeout value is set by the ticksToWait parameter. If
|
||||
* clearOnExit is set to false then the bits set in the event group are not
|
||||
* altered when the call to wait() returns.
|
||||
* @param waitForAllBits waitForAllBits is used to create either a logical AND
|
||||
* test (where all bits must be set) or a logical OR test (where one or more
|
||||
* bits must be set) as follows: If waitForAllBits is set to true then wait()
|
||||
* will return when either all the bits set in the value passed as the
|
||||
* bitsToWaitFor parameter are set in the event group or the specified block
|
||||
* time expires. If waitForAllBits is set to false then wait() will return
|
||||
* when any of the bits set in the value passed as the bitsToWaitFor parameter
|
||||
* are set in the event group or the specified block time expires.
|
||||
* @param ticksToWait The maximum amount of time (specified in 'ticks') to
|
||||
* wait for one/all (depending on the waitForAllBits value) of the bits
|
||||
* specified by bitsToWaitFor to become set.
|
||||
* @return EventBits The value of the event group at the time either the event
|
||||
* bits being waited for became set, or the block time expired. The current
|
||||
* value of the event bits in an event group will be different to the returned
|
||||
* value if a higher priority task or interrupt changed the value of an event
|
||||
* bit between the calling task leaving the Blocked state and exiting the
|
||||
* wait() function. Test the return value to know which bits were set. If
|
||||
* wait() returned because its timeout expired then not all the bits being
|
||||
* waited for will be set. If wait() returned because the bits it was waiting
|
||||
* for were set then the returned value is the event group value before any
|
||||
* bits were automatically cleared because the clearOnExit parameter was set
|
||||
* to true.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/wait.cpp
|
||||
*/
|
||||
inline EventBits wait(const EventBits& bitsToWaitFor = 0,
|
||||
const bool clearOnExit = false,
|
||||
const bool waitForAllBits = false,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return EventBits(xEventGroupWaitBits(
|
||||
handle, bitsToWaitFor.to_ulong(), (clearOnExit ? pdTRUE : pdFALSE),
|
||||
(waitForAllBits ? pdTRUE : pdFALSE), ticksToWait));
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>EventBits_t xEventGroupSetBits(
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupSetBits.html>
|
||||
*
|
||||
* Set bits (flags) within an RTOS event group. This function cannot be called
|
||||
* from an interrupt. setFromISR() is a version that can be called from an
|
||||
* interrupt.
|
||||
*
|
||||
* Setting bits in an event group will automatically unblock tasks that are
|
||||
* blocked waiting for the bits.
|
||||
*
|
||||
* @param bitsToSet A bitwise value that indicates the bit or bits to set in
|
||||
* the event group.
|
||||
* @return EventBits The value of the event group at the time the call to
|
||||
* set() returns. There are two reasons why the returned value might have the
|
||||
* bits specified by the uxBitsToSet parameter cleared:
|
||||
* 1. If setting a bit results in a task that was waiting for the bit leaving
|
||||
* the blocked state then it is possible the bit will have been cleared
|
||||
* automatically (see the clearOnExit parameter of wait()).
|
||||
* 2. Any unblocked (or otherwise Ready state) task that has a priority above
|
||||
* that of the task that called set() will execute and may change the event
|
||||
* group value before the call to set() returns.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/set.cpp
|
||||
*/
|
||||
inline EventBits set(const EventBits& bitsToSet) const {
|
||||
return EventBits(xEventGroupSetBits(handle, bitsToSet.to_ulong()));
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xEventGroupSetBitsFromISR(
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t
|
||||
* *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupSetBitsFromISR.html>
|
||||
*
|
||||
* Set bits (flags) within an RTOS event group. A version of set() that can be
|
||||
* called from an interrupt service routine (ISR).
|
||||
*
|
||||
* Setting bits in an event group will automatically unblock tasks that are
|
||||
* blocked waiting for the bits.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because
|
||||
* there are an unknown number of tasks that may be waiting for the bit or
|
||||
* bits being set. FreeRTOS does not allow non-deterministic operations to be
|
||||
* performed in interrupts or from critical sections. Therefore
|
||||
* xEventGroupSetBitFromISR() sends a message to the RTOS daemon task to have
|
||||
* the set operation performed in the context of the daemon task - where a
|
||||
* scheduler lock is used in place of a critical section.
|
||||
*
|
||||
* @note As mentioned in the paragraph above, setting bits from an ISR will
|
||||
* defer the set operation to the RTOS daemon task (also known as the timer
|
||||
* service task). The RTOS daemon task is scheduled according to its priority,
|
||||
* just like any other RTOS task. Therefore, if it is essential the set
|
||||
* operation completes immediately (before a task created by the application
|
||||
* executes) then the priority of the RTOS daemon task must be higher than the
|
||||
* priority of any application task that uses the event group. The priority of
|
||||
* the RTOS daemon task is set by the configTIMER_TASK_PRIORITY definition in
|
||||
* FreeRTOSConfig.h.
|
||||
*
|
||||
* @param higherPriorityTaskWoken As mentioned above, calling this function
|
||||
* will result in a message being sent to the RTOS daemon task. If the
|
||||
* priority of the daemon task is higher than the priority of the currently
|
||||
* running task (the task the interrupt interrupted) then
|
||||
* higherPriorityTaskWoken will be set to true by setFromISR(), indicating
|
||||
* that a context switch should be requested before the interrupt exits. For
|
||||
* that reason higherPriorityTaskWoken must be initialised to false. See the
|
||||
* example code below.
|
||||
* @param bitsToSet A bitwise value that indicates the bit or bits to set in
|
||||
* the event group.
|
||||
* @retval true If the message was sent to the RTOS daemon task.
|
||||
* @retval false Otherwise or if the timer service queue was full
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/setFromISR.cpp
|
||||
*/
|
||||
inline bool setFromISR(bool& higherPriorityTaskWoken,
|
||||
const EventBits& bitsToSet) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xEventGroupSetBitsFromISR(handle, bitsToSet.to_ulong(),
|
||||
&taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xEventGroupSetBitsFromISR(
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t
|
||||
* *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupSetBitsFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool setFromISR(const EventBits& bitsToSet) const {
|
||||
return (xEventGroupSetBitsFromISR(handle, bitsToSet.to_ulong(), NULL) ==
|
||||
pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>EventBits_t xEventGroupClearBits(
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupClearBits.html>
|
||||
*
|
||||
* Clear bits (flags) within an RTOS event group. This function cannot be
|
||||
* called from an interrupt. See clearFromISR() for a version that can be
|
||||
* called from an interrupt.
|
||||
*
|
||||
* @param bitsToClear A bitwise value that indicates the bit or bits to clear
|
||||
* in the event group.
|
||||
* @return EventBits The value of the event group before the specified bits
|
||||
* were cleared.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/clear.cpp
|
||||
*/
|
||||
inline EventBits clear(const EventBits& bitsToClear) const {
|
||||
return EventBits(xEventGroupClearBits(handle, bitsToClear.to_ulong()));
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xEventGroupClearBitsFromISR(
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupClearBitsFromISR.html>
|
||||
*
|
||||
* A version of clear() that can be called from an interrupt. The clear
|
||||
* operation is deferred to the RTOS daemon task which is also known as the
|
||||
* timer service task. The priority of the daemon task is set by the
|
||||
* configTIMER_TASK_PRIORITY setting in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param bitsToClear A bitwise value that indicates the bit or bits to clear
|
||||
* in the event group.
|
||||
* @return true If the operation was successfully deferred to the RTOS daemon
|
||||
* task.
|
||||
* @return false If the timer command queue is full.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/clearFromISR.cpp
|
||||
*/
|
||||
inline bool clearFromISR(const EventBits& bitsToClear) const {
|
||||
return (xEventGroupClearBitsFromISR(handle, bitsToClear.to_ulong()) ==
|
||||
pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>EventBits_t xEventGroupGetBits(
|
||||
* EventGroupHandle_t xEventGroup )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupGetBits.html>
|
||||
*
|
||||
* Returns the current value of the event bits (event flags) in an RTOS event
|
||||
* group. This function cannot be used from an interrupt. See getFromISR() for
|
||||
* a version that can be used in an interrupt.
|
||||
*
|
||||
* @return EventBits The value of the event bits in the event group at the
|
||||
* time get() was called.
|
||||
*/
|
||||
inline EventBits get() const { return EventBits(xEventGroupGetBits(handle)); }
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>EventBits_t xEventGroupGetBitsFromISR(
|
||||
* EventGroupHandle_t xEventGroup )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupGetBitsFromISR.html>
|
||||
*
|
||||
* A version of get() that can be called from an interrupt.
|
||||
*
|
||||
* @return EventBits The value of the event bits in the event group at the
|
||||
* time getFromISR() was called.
|
||||
*/
|
||||
inline EventBits getFromISR() const {
|
||||
return EventBits(xEventGroupGetBitsFromISR(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>EventBits_t xEventGroupSync(
|
||||
* EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const
|
||||
* EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupSync.html>
|
||||
*
|
||||
* Atomically set bits (flags) within an RTOS event group, then wait for a
|
||||
* combination of bits to be set within the same event group. This
|
||||
* functionality is typically used to synchronize multiple tasks (often called
|
||||
* a task rendezvous), where each task has to wait for the other tasks to
|
||||
* reach a synchronization point before proceeding.
|
||||
*
|
||||
* This function cannot be used from an interrupt.
|
||||
*
|
||||
* The function will return before its block time expires if the bits
|
||||
* specified by the bitsToWait parameter are set, or become set within that
|
||||
* time. In this case all the bits specified by bitsToWait will be
|
||||
* automatically cleared before the function returns.
|
||||
*
|
||||
* @param bitsToSet The bit or bits to set in the event group before
|
||||
* determining if (and possibly waiting for), all the bits specified by the
|
||||
* bitsToWait parameter are set.
|
||||
* @param bitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group.
|
||||
* @param ticksToWait The maximum amount of time (specified in 'ticks') to
|
||||
* wait for all the bits specified by the uxBitsToWaitFor parameter value to
|
||||
* become set.
|
||||
* @return EventBits
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/sync.cpp
|
||||
*/
|
||||
inline EventBits sync(const EventBits& bitsToSet = 0,
|
||||
const EventBits& bitsToWaitFor = 0,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return EventBits(xEventGroupSync(handle, bitsToSet.to_ulong(),
|
||||
bitsToWaitFor.to_ulong(), ticksToWait));
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Construct a new EventGroupBase object.
|
||||
*
|
||||
* @note Default constructor is deliberately private as this class is not
|
||||
* intended to be instantiated or derived from by the user. Use
|
||||
* FreeRTOS::EventGroup or FreeRTOS::StaticEventGroup.
|
||||
*/
|
||||
EventGroupBase() = default;
|
||||
|
||||
/**
|
||||
* EventGroup.hpp
|
||||
*
|
||||
* @brief Destroy the EventGroupBase object by calling <tt>void
|
||||
* vEventGroupDelete( EventGroupHandle_t xEventGroup )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vEventGroupDelete.html>
|
||||
*
|
||||
* Delete an event group.
|
||||
*
|
||||
* Tasks that are blocked on the event group being deleted will be unblocked,
|
||||
* and report an event group value of 0.
|
||||
*/
|
||||
~EventGroupBase() { vEventGroupDelete(this->handle); };
|
||||
|
||||
EventGroupBase(EventGroupBase&&) noexcept = default;
|
||||
EventGroupBase& operator=(EventGroupBase&&) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Handle used to refer to the event group when using the FreeRTOS
|
||||
* interface.
|
||||
*/
|
||||
EventGroupHandle_t handle = NULL;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class EventGroup EventGroups.hpp <FreeRTOS/EventGroups.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS event group.
|
||||
*
|
||||
* Each event group requires a [very] small amount of RAM that is used to hold
|
||||
* the event group's state. If an event group is created using this class then
|
||||
* the required RAM is automatically allocated from the FreeRTOS heap. If an
|
||||
* event group is created using FreeRTOS::StaticEventGroup then the RAM is
|
||||
* provided by the application writer, which requires an additional parameter,
|
||||
* but allows the RAM to be statically allocated at compile time. See the Static
|
||||
* Vs Dynamic allocation page for more information.
|
||||
*/
|
||||
class EventGroup : public EventGroupBase {
|
||||
public:
|
||||
/**
|
||||
* EventGroup.hpp
|
||||
*
|
||||
* @brief Construct a new EventGroup object by calling <tt>EventGroupHandle_t
|
||||
* xEventGroupCreate( void )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupCreate.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* queue was created successfully in case the memory required to create the
|
||||
* queue could not be allocated.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/eventGroup.cpp
|
||||
*/
|
||||
EventGroup() { this->handle = xEventGroupCreate(); }
|
||||
~EventGroup() = default;
|
||||
|
||||
EventGroup(const EventGroup&) = delete;
|
||||
EventGroup& operator=(const EventGroup&) = delete;
|
||||
|
||||
EventGroup(EventGroup&&) noexcept = default;
|
||||
EventGroup& operator=(EventGroup&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StaticEventGroup EventGroups.hpp <FreeRTOS/EventGroups.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS event group.
|
||||
*
|
||||
* Each event group requires a [very] small amount of RAM that is used to hold
|
||||
* the event group's state. If an event group is created using
|
||||
* FreeRTOS::EventGroup then the required RAM is automatically allocated from
|
||||
* the FreeRTOS heap. If an event group is created using this class then the RAM
|
||||
* is provided by the application writer, which requires an additional
|
||||
* parameter, but allows the RAM to be statically allocated at compile time. See
|
||||
* the Static Vs Dynamic allocation page for more information.
|
||||
*/
|
||||
class StaticEventGroup : public EventGroupBase {
|
||||
public:
|
||||
/**
|
||||
* EventGroups.hpp
|
||||
*
|
||||
* @brief Construct a new StaticEventGroup object by calling
|
||||
* <tt>EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t
|
||||
* *pxEventGroupBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xEventGroupCreateStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the event group, so the
|
||||
* user should create this object as a global object or with the static
|
||||
* storage specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include EventGroups/staticEventGroup.cpp
|
||||
*/
|
||||
StaticEventGroup() {
|
||||
this->handle = xEventGroupCreateStatic(&staticEventGroup);
|
||||
}
|
||||
~StaticEventGroup() = default;
|
||||
|
||||
StaticEventGroup(const StaticEventGroup&) = delete;
|
||||
StaticEventGroup& operator=(const StaticEventGroup&) = delete;
|
||||
|
||||
StaticEventGroup(StaticEventGroup&&) noexcept = default;
|
||||
StaticEventGroup& operator=(StaticEventGroup&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticEventGroup_t staticEventGroup;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_EVENTGROUPS_HPP
|
||||
409
source/shoh/src/FreeRTOSCPP/Kernel.hpp
Normal file
409
source/shoh/src/FreeRTOSCPP/Kernel.hpp
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_KERNEL_HPP
|
||||
#define FREERTOS_KERNEL_HPP
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @brief Kernel namespace that provides an interface to kernel functions.
|
||||
*
|
||||
*/
|
||||
namespace Kernel {
|
||||
enum class SchedulerState : BaseType_t {
|
||||
Suspended = taskSCHEDULER_SUSPENDED,
|
||||
NotStarted = taskSCHEDULER_NOT_STARTED,
|
||||
Running = taskSCHEDULER_RUNNING,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief If versionNumber ends with + it represents the version in development
|
||||
* after the numbered release.
|
||||
*/
|
||||
inline constexpr char versionNumber[] = tskKERNEL_VERSION_NUMBER;
|
||||
inline constexpr BaseType_t versionMajor = tskKERNEL_VERSION_MAJOR;
|
||||
inline constexpr BaseType_t versionMinor = tskKERNEL_VERSION_MINOR;
|
||||
inline constexpr BaseType_t versionBuild = tskKERNEL_VERSION_BUILD;
|
||||
|
||||
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xTaskGetSchedulerState()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00021.html#xTaskGetSchedulerState>
|
||||
*
|
||||
* @retval SchedulerState Returns the scheduler state as Running, NotStarted, or
|
||||
* Suspended.
|
||||
*/
|
||||
inline SchedulerState getSchedulerState() {
|
||||
return static_cast<SchedulerState>(xTaskGetSchedulerState());
|
||||
}
|
||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>uxTaskGetNumberOfTasks()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00021.html#usTaskGetNumberOfTasks>
|
||||
*
|
||||
* @retval UBaseType_t The number of tasks that the real time kernel is
|
||||
* currently managing. This includes all ready, blocked and suspended tasks. A
|
||||
* task that has been deleted but not yet freed by the idle task will also be
|
||||
* included in the count.
|
||||
*/
|
||||
inline UBaseType_t getNumberOfTasks() { return uxTaskGetNumberOfTasks(); }
|
||||
|
||||
#if (INCLUDE_xTaskGetIdleTaskHandle == 1 && configGENERATE_RUN_TIME_STATS == 1)
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xTaskGetIdleRunTimeCounter()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00021.html#vTaskGetIdleRunTimeCounter>
|
||||
*
|
||||
* @retval TickType_t The run-time counter for the Idle task.
|
||||
*
|
||||
* This function can be used to determine how much CPU time the idle task
|
||||
* receives. See the Run Time Stats page for a full description of the
|
||||
* run-time-stats feature.
|
||||
*
|
||||
* configGENERATE_RUN_TIME_STATS and INCLUDE_xTaskGetIdleTaskHandle must both be
|
||||
* defined as 1 for this function to be available. The application must also
|
||||
* then provide definitions for portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and
|
||||
* portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral timer/counter and
|
||||
* return the timer's current count value respectively. It is recommended to
|
||||
* make the timer at least 10 times the frequency of the tick count.
|
||||
*/
|
||||
inline TickType_t getIdleRunTimeCounter() {
|
||||
return xTaskGetIdleRunTimeCounter();
|
||||
}
|
||||
#endif /* INCLUDE_xTaskGetIdleTaskHandle && configGENERATE_RUN_TIME_STATS*/
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xTaskGetTickCount()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00021.html#xTaskGetTickCount>
|
||||
*
|
||||
* @retval TickType_t The count of ticks since
|
||||
* FreeRTOS::Kernel::startScheduler() was called.
|
||||
*/
|
||||
inline TickType_t getTickCount() { return xTaskGetTickCount(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xTaskGetTickCountFromISR()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00021.html#xTaskGetTickCountFromISR>
|
||||
*
|
||||
* @retval TickType_t The count of ticks since
|
||||
* FreeRTOS::Kernel::startScheduler() was called.
|
||||
*
|
||||
* This is a version of FreeRTOS::Kernel::getTickCount() that is safe to be
|
||||
* called from an ISR - provided that TickType_t is the natural word size of the
|
||||
* microcontroller being used or interrupt nesting is either not supported or
|
||||
* not being used.
|
||||
*/
|
||||
inline TickType_t getTickCountFromISR() { return xTaskGetTickCountFromISR(); }
|
||||
|
||||
/**
|
||||
*Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskYIELD()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00020.html#taskYIELD>
|
||||
*
|
||||
* FreeRTOS::Kernel::yield() is used to request a context switch to another
|
||||
*task. However, if there are no other tasks at a higher or equal priority to
|
||||
*the task that calls FreeRTOS::Kernel::yield() then the RTOS scheduler will
|
||||
*simply select the task that called FreeRTOS::Kernel::yield() to run again.
|
||||
*/
|
||||
inline void yield() { taskYIELD(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskENTER_CRITICAL()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html>
|
||||
*
|
||||
* Function to mark the start of a critical code region. Preemptive context
|
||||
* switches cannot occur when in a critical region.
|
||||
*
|
||||
* @note This may alter the stack (depending on the portable implementation) so
|
||||
* must be used with care!
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/enterExitCritical.cpp
|
||||
*/
|
||||
inline void enterCritical() { taskENTER_CRITICAL(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskENTER_CRITICAL_FROM_ISR()</tt>
|
||||
*
|
||||
* @see
|
||||
* <https://www.freertos.org/taskENTER_CRITICAL_FROM_ISR_taskEXIT_CRITICAL_FROM_ISR.html>
|
||||
*
|
||||
* @retval uint32_t the interrupt mask state as it was before the macro was
|
||||
* called. The value returned by FreeRTOS::Kernel::enterCriticalFromISR() must
|
||||
* be used as the interruptStatus parameter in the matching call to
|
||||
* FreeRTOS::Kernel::exitCriticalFromISR().
|
||||
*
|
||||
* Function to mark the start of a critical code region. Preemptive context
|
||||
* switches cannot occur when in a critical region.
|
||||
*
|
||||
* @note This may alter the stack (depending on the portable implementation) so
|
||||
* must be used with care!
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/enterExitCriticalFromISR.cpp
|
||||
*/
|
||||
inline uint32_t enterCriticalFromISR() { return taskENTER_CRITICAL_FROM_ISR(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskEXIT_CRITICAL()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/taskENTER_CRITICAL_taskEXIT_CRITICAL.html>
|
||||
*
|
||||
* Function to mark the end of a critical code region. Preemptive context
|
||||
* switches cannot occur when in a critical region.
|
||||
*
|
||||
* @note This may alter the stack (depending on the portable implementation) so
|
||||
* must be used with care!
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/enterExitCritical.cpp
|
||||
*/
|
||||
inline void exitCritical() { taskEXIT_CRITICAL(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskEXIT_CRITICAL_FROM_ISR()</tt>
|
||||
*
|
||||
* @see
|
||||
* <https://www.freertos.org/taskENTER_CRITICAL_FROM_ISR_taskEXIT_CRITICAL_FROM_ISR.html>
|
||||
*
|
||||
* @param interruptStatus The value used as the interruptStatus parameter must
|
||||
* be the value returned from the matching call to
|
||||
* FreeRTOS::Kernel::enterCriticalFromISR().
|
||||
*
|
||||
* Function to mark the end of a critical code region. Preemptive context
|
||||
* switches cannot occur when in a critical region.
|
||||
*
|
||||
* @note This may alter the stack (depending on the portable implementation) so
|
||||
* must be used with care!
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/enterExitCriticalFromISR.cpp
|
||||
*/
|
||||
inline void exitCriticalFromISR(const uint32_t interruptStatus) {
|
||||
taskEXIT_CRITICAL_FROM_ISR(interruptStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskDISABLE_INTERRUPTS()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00020.html#taskDISABLE_INTERRUPTS>
|
||||
*
|
||||
* Function to disable all maskable interrupts.
|
||||
*/
|
||||
inline void disableInterrupts() { taskDISABLE_INTERRUPTS(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>taskENABLE_INTERRUPTS()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00020.html#taskENABLE_INTERRUPTS>
|
||||
*
|
||||
* Function to enable microcontroller interrupts.
|
||||
*/
|
||||
inline void enableInterrupts() { taskENABLE_INTERRUPTS(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>vTaskStartScheduler()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00132.html>
|
||||
*
|
||||
* Starts the real time kernel tick processing. After calling the kernel has
|
||||
* control over which tasks are executed and when.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/startScheduler.cpp
|
||||
*/
|
||||
inline void startScheduler() { vTaskStartScheduler(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>vTaskEndScheduler()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00133.html>
|
||||
*
|
||||
* @note At the time of writing only the x86 real mode port, which runs on a PC
|
||||
* in place of DOS, implements this function.
|
||||
*
|
||||
* Stops the real time kernel tick. All created tasks will be automatically
|
||||
* deleted and multitasking (either preemptive or cooperative) will stop.
|
||||
* Execution then resumes from the point where
|
||||
* FreeRTOS::Kernel::startScheduler() was called, as if
|
||||
* FreeRTOS::Kernel::startScheduler() had just returned.
|
||||
*
|
||||
* See the demo application file main. c in the demo/PC directory for an example
|
||||
* that uses FreeRTOS::Kernel::endScheduler().
|
||||
*
|
||||
* FreeRTOS::Kernel::endScheduler() requires an exit function to be defined
|
||||
* within the portable layer (see vPortEndScheduler () in port. c for the PC
|
||||
* port). This performs hardware specific operations such as stopping the
|
||||
* kernel tick.
|
||||
*
|
||||
* FreeRTOS::Kernel::endScheduler() will cause all of the resources allocated by
|
||||
* the kernel to be freed - but will not free resources allocated by application
|
||||
* tasks.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/endScheduler.cpp
|
||||
*/
|
||||
inline void endScheduler() { vTaskEndScheduler(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>vTaskSuspendAll()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00134.html>
|
||||
*
|
||||
* Suspends the scheduler without disabling interrupts. Context switches will
|
||||
* not occur while the scheduler is suspended.
|
||||
*
|
||||
* After calling FreeRTOS::Kernel::suspendAll() the calling task will continue
|
||||
* to execute without risk of being swapped out until a call to
|
||||
* FreeRTOS::Kernel::resumeAll() has been made.
|
||||
*
|
||||
* API functions that have the potential to cause a context switch (for example,
|
||||
* FreeRTOS::Task::delayUntil(), FreeRTOS::Queue::send(), etc.) must not be
|
||||
* called while the scheduler is suspended.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/suspendAll.cpp
|
||||
*/
|
||||
inline void suspendAll() { vTaskSuspendAll(); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xTaskResumeAll()</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00135.html>
|
||||
*
|
||||
* Resumes scheduler activity after it was suspended by a call to
|
||||
* FreeRTOS::Kernel::suspendAll().
|
||||
*
|
||||
* FreeRTOS::Kernel::resumeAll() only resumes the scheduler. It does not
|
||||
* unsuspend tasks that were previously suspended by a call to
|
||||
* FreeRTOS::Task::suspend().
|
||||
*
|
||||
* @retval true If resuming the scheduler caused a context switch.
|
||||
* @retval false Otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Kernel/resumeAll.cpp
|
||||
*/
|
||||
inline bool resumeAll() { return (xTaskResumeAll() == pdTRUE); }
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>vTaskStepTick( const TickType_t xTicksToJump
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vTaskStepTick.html>
|
||||
*
|
||||
* Only available when configUSE_TICKLESS_IDLE is set to 1. If tickless mode is
|
||||
* being used, or a low power mode is implemented, then the tick interrupt will
|
||||
* not execute during idle periods. When this is the case, the tick count value
|
||||
* maintained by the scheduler needs to be kept up to date with the actual
|
||||
* execution time by being skipped forward by a time equal to the idle period.
|
||||
*
|
||||
* @param ticksToJump The number of RTOS ticks that have passed since the tick
|
||||
* interrupt was stopped.
|
||||
*/
|
||||
inline void stepTick(const TickType_t ticksToJump) {
|
||||
vTaskStepTick(ticksToJump);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kernel.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xTaskCatchUpTicks( TickType_t xTicksToCatchUp
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vTaskStepTick.html>
|
||||
*
|
||||
* This function corrects the tick count value after the application code has
|
||||
* held interrupts disabled for an extended period resulting in tick interrupts
|
||||
* having been missed.
|
||||
*
|
||||
* This function is similar to FreeRTOS::Kernel::stepTick(), however, unlike
|
||||
* FreeRTOS::Kernel::stepTick(), FreeRTOS::Kernel::catchUpTicks() may move the
|
||||
* tick count forward past a time at which a task should be removed from the
|
||||
* blocked state. That means tasks may have to be removed from the blocked
|
||||
* state as the tick count is moved.
|
||||
*
|
||||
* @param ticksToCatchUp The number of tick interrupts that have been missed due
|
||||
* to interrupts being disabled. Its value is not computed automatically, so
|
||||
* must be computed by the application writer.
|
||||
*
|
||||
* @retval true If moving the tick count forward resulted in a task leaving the
|
||||
* blocked state and a context switch being performed.
|
||||
* @retval false Otherwise.
|
||||
*/
|
||||
inline bool catchUpTicks(const TickType_t ticksToCatchUp) {
|
||||
return (xTaskCatchUpTicks(ticksToCatchUp) == pdTRUE);
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_KERNEL_HPP
|
||||
518
source/shoh/src/FreeRTOSCPP/MessageBuffer.hpp
Normal file
518
source/shoh/src/FreeRTOSCPP/MessageBuffer.hpp
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_MESSAGEBUFFER_HPP
|
||||
#define FREERTOS_MESSAGEBUFFER_HPP
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "message_buffer.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class MessageBufferBase MessageBuffer.hpp <FreeRTOS/MessageBuffer.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard message buffer interface to
|
||||
* FreeRTOS::MessageBuffer and FreeRTOS::StaticMessageBuffer.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::MessageBuffer or FreeRTOS::StaticMessageBuffer.
|
||||
*
|
||||
* @warning Uniquely among FreeRTOS objects, the stream buffer implementation
|
||||
* (so also the message buffer implementation, as message buffers are built on
|
||||
* top of stream buffers) assumes there is only one task or interrupt that will
|
||||
* write to the buffer (the writer), and only one task or interrupt that will
|
||||
* read from the buffer (the reader). It is safe for the writer and reader to
|
||||
* be different tasks or interrupts, but, unlike other FreeRTOS objects, it is
|
||||
* not safe to have multiple different writers or multiple different readers. If
|
||||
* there are to be multiple different writers then the application writer must
|
||||
* place each call to a writing API function (such as send()) inside a critical
|
||||
* section and set the send block time to 0. Likewise, if there are to be
|
||||
* multiple different readers then the application writer must place each call
|
||||
* to a reading API function (such as read()) inside a critical section and set
|
||||
* the receive block time to 0.
|
||||
*/
|
||||
class MessageBufferBase {
|
||||
public:
|
||||
friend class MessageBuffer;
|
||||
template <size_t>
|
||||
friend class StaticMessageBuffer;
|
||||
|
||||
MessageBufferBase(const MessageBufferBase&) = delete;
|
||||
MessageBufferBase& operator=(const MessageBufferBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that checks if the underlying message buffer handle is not
|
||||
* NULL. This should be used to ensure a message buffer has been created
|
||||
* correctly.
|
||||
*
|
||||
* @retval true If the handle is not NULL.
|
||||
* @retval false If the handle is NULL.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferSend(
|
||||
* MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t
|
||||
* xDataLengthBytes, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferSend.html>
|
||||
*
|
||||
* Sends a discrete message to the message buffer. The message can be any
|
||||
* length that fits within the buffer's free space, and is copied into the
|
||||
* buffer.
|
||||
*
|
||||
* Use send() to write to a message buffer from a task. Use sendFromISR() to
|
||||
* write to a message buffer from an interrupt service routine (ISR).
|
||||
*
|
||||
* @param data A pointer to the message that is to be copied into the message
|
||||
* buffer.
|
||||
* @param length The length of the message. That is, the number of bytes to
|
||||
* copy from data into the message buffer. When a message is written to the
|
||||
* message buffer an additional sizeof( size_t ) bytes are also written to
|
||||
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so on most 32-bit architecture setting length to 20
|
||||
* will reduce the free space in the message buffer by 24 bytes (20 bytes of
|
||||
* message data and 4 bytes to hold the message length).
|
||||
* @param ticksToWait The maximum amount of time the calling task should
|
||||
* remain in the Blocked state to wait for enough space to become available in
|
||||
* the message buffer, should the message buffer have insufficient space when
|
||||
* send() is called. The calling task will never block if ticksToWait is
|
||||
* zero. The block time is specified in tick periods, so the absolute time it
|
||||
* represents is dependent on the tick frequency. The macro pdMS_TO_TICKS()
|
||||
* can be used to convert a time specified in milliseconds into a time
|
||||
* specified in ticks. Setting ticksToWait to portMAX_DELAY will cause the
|
||||
* task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
* @return size_t The number of bytes written to the message buffer. If the
|
||||
* call to send() times out before there was enough space to write the message
|
||||
* into the message buffer then zero is returned. If the call did not time
|
||||
* out then length is returned.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include MessageBuffer/send.cpp
|
||||
*/
|
||||
inline size_t send(const void* data, const size_t length,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return xMessageBufferSend(handle, data, length, ticksToWait);
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferSendFromISR(
|
||||
* MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t
|
||||
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferSendFromISR.html>
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a discrete message to
|
||||
* the message buffer. The message can be any length that fits within the
|
||||
* buffer's free space, and is copied into the buffer.
|
||||
*
|
||||
* Use send() to write to a message buffer from a task. Use sendFromISR() to
|
||||
* write to a message buffer from an interrupt service routine (ISR).
|
||||
*
|
||||
* @param higherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for data. Calling sendFromISR() can make
|
||||
* data available, and so cause a task that was waiting for data to leave the
|
||||
* Blocked state. If calling sendFromISR() causes a task to leave the Blocked
|
||||
* state, and the unblocked task has a priority higher than the currently
|
||||
* executing task (the task that was interrupted), then, internally,
|
||||
* sendFromISR() will set higherPriorityTaskWoken to true. If sendFromISR()
|
||||
* sets this value to true, then normally a context switch should be performed
|
||||
* before the interrupt is exited. This will ensure that the interrupt returns
|
||||
* directly to the highest priority Ready state task. higherPriorityTaskWoken
|
||||
* should be set to false before it is passed into the function. See the code
|
||||
* example below for an example.
|
||||
* @param data A pointer to the message that is to be copied into the message
|
||||
* buffer.
|
||||
* @param length The length of the message. That is, the number of bytes to
|
||||
* copy from data into the message buffer. When a message is written to the
|
||||
* message buffer an additional sizeof( size_t ) bytes are also written to
|
||||
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so on most 32-bit architecture setting length to 20
|
||||
* will reduce the free space in the message buffer by 24 bytes (20 bytes of
|
||||
* message data and 4 bytes to hold the message length).
|
||||
* @return size_t The number of bytes actually written to the message buffer.
|
||||
* If the message buffer didn't have enough free space for the message to be
|
||||
* stored then 0 is returned, otherwise length is returned.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include MessageBuffer/sendFromISR.cpp
|
||||
*/
|
||||
inline size_t sendFromISR(bool& higherPriorityTaskWoken, const void* data,
|
||||
const size_t length) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
size_t result = xMessageBufferSendFromISR(handle, data, length, &taskWoken);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferSendFromISR(
|
||||
* MessageBufferHandle_t xMessageBuffer, const void *pvTxData, size_t
|
||||
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferSendFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline size_t sendFromISR(const void* data, const size_t length) const {
|
||||
return xMessageBufferSendFromISR(handle, data, length, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferReceive(
|
||||
* MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t
|
||||
* xBufferLengthBytes, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferReceive.html>
|
||||
*
|
||||
* Use receive() to read from a message buffer from a task.
|
||||
* UsereceiveFromISR() to read from a message buffer from an interrupt service
|
||||
* routine (ISR).
|
||||
*
|
||||
* @param buffer A pointer to the buffer into which the received message is to
|
||||
* be copied.
|
||||
* @param bufferLength The length of the buffer pointed to by the buffer
|
||||
* parameter. This sets the maximum length of the message that can be
|
||||
* received. If bufferLength is too small to hold the next message then the
|
||||
* message will be left in the message buffer and 0 will be returned.
|
||||
* @param ticksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for a message, should the message buffer be empty.
|
||||
* receive() will return immediately if ticksToWait is zero and the message
|
||||
* buffer is empty. The block time is specified in tick periods, so the
|
||||
* absolute time it represents is dependent on the tick frequency. The macro
|
||||
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting ticksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any
|
||||
* CPU time when they are in the Blocked state.
|
||||
* @return size_t The length, in bytes, of the message read from the message
|
||||
* buffer, if any. If receive() times out before a message became available
|
||||
* then zero is returned. If the length of the message is greater than
|
||||
* bufferLength then the message will be left in the message buffer and zero
|
||||
* is returned.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include MessageBuffer/receive.cpp
|
||||
*/
|
||||
inline size_t receive(void* buffer, const size_t bufferLength,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return xMessageBufferReceive(handle, buffer, bufferLength, ticksToWait);
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferReceiveFromISR(
|
||||
* MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t
|
||||
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferReceiveFromISR.html>
|
||||
*
|
||||
* Use receive() to read from a message buffer from a task.
|
||||
* UsereceiveFromISR() to read from a message buffer from an interrupt service
|
||||
* routine (ISR).
|
||||
*
|
||||
* @param higherPriorityTaskWoken It is possible that a message buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* receiveFromISR() can make space available, and so cause a task that is
|
||||
* waiting for space to leave the Blocked state. If calling receiveFromISR()
|
||||
* causes a task to leave the Blocked state, and the unblocked task has a
|
||||
* priority higher than the currently executing task (the task that was
|
||||
* interrupted), then, internally, receiveFromISR() will set
|
||||
* higherPriorityTaskWoken to true. If receiveFromISR() sets this value to
|
||||
* true, then normally a context switch should be performed before the
|
||||
* interrupt is exited. That will ensure the interrupt returns directly to the
|
||||
* highest priority Ready state task. higherPriorityTaskWoken should be set
|
||||
* to false before it is passed into the function. See the code example below
|
||||
* for an example.
|
||||
* @param buffer A pointer to the buffer into which the received message is to
|
||||
* be copied.
|
||||
* @param bufferLength The length of the buffer pointed to by the buffer
|
||||
* parameter. This sets the maximum length of the message that can be
|
||||
* received. If bufferLength is too small to hold the next message then the
|
||||
* message will be left in the message buffer and 0 will be returned.
|
||||
* @return size_t The length, in bytes, of the message read from the message
|
||||
* buffer, if any.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include MessageBuffer/receiveFromISR.cpp
|
||||
*/
|
||||
inline size_t receiveFromISR(bool& higherPriorityTaskWoken, void* buffer,
|
||||
const size_t bufferLength) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
size_t result =
|
||||
xMessageBufferReceiveFromISR(handle, buffer, bufferLength, &taskWoken);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferReceiveFromISR(
|
||||
* MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t
|
||||
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferReceiveFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline size_t receiveFromISR(void* buffer, const size_t bufferLength) const {
|
||||
return xMessageBufferReceiveFromISR(handle, buffer, bufferLength, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xMessageBufferSpacesAvailable(
|
||||
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferSpacesAvailable.html>
|
||||
*
|
||||
* Queries a message buffer to see how much free space it contains, which is
|
||||
* equal to the amount of data that can be sent to the message buffer before
|
||||
* it is full. The returned value is 4 bytes larger than the maximum message
|
||||
* size that can be sent to the message buffer.
|
||||
*
|
||||
* @return size_t The number of bytes that can be written to the message
|
||||
* buffer before the message buffer would be full. When a message is written
|
||||
* to the message buffer an additional sizeof( size_t ) bytes are also written
|
||||
* to store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so if spacesAvailable() returns 10, then the size of
|
||||
* the largest message that can be written to the message buffer is 6 bytes.
|
||||
*/
|
||||
inline size_t spacesAvailable() const {
|
||||
return xMessageBufferSpacesAvailable(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xMessageBufferReset(
|
||||
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferReset.html>
|
||||
*
|
||||
* Resets a message buffer to its initial, empty, state. Any data that was in
|
||||
* the message buffer is discarded. A message buffer can only be reset if
|
||||
* there are no tasks blocked waiting to either send to or receive from the
|
||||
* message buffer.
|
||||
*
|
||||
* @retval true If the message buffer is reset.
|
||||
* @retval false If there was a task blocked waiting to send to or read from
|
||||
* the message buffer then the message buffer will not be reset.
|
||||
*/
|
||||
inline bool reset() const { return (xMessageBufferReset(handle) == pdPASS); }
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xMessageBufferIsEmpty(
|
||||
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferIsEmpty.html>
|
||||
*
|
||||
* Queries a message buffer to see if it is empty. A message buffer is empty
|
||||
* if it does not contain any messages.
|
||||
*
|
||||
* @retval true If the message buffer is empty.
|
||||
* @retval false Otherwise.
|
||||
*/
|
||||
inline bool isEmpty() const {
|
||||
return (xMessageBufferIsEmpty(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xMessageBufferIsFull(
|
||||
* MessageBufferHandle_t xMessageBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferIsFull.html>
|
||||
*
|
||||
* Queries a message buffer to see if it is full. A message buffer is full if
|
||||
* it cannot accept any more messages, of any size, until space is made
|
||||
* available by a message being removed from the message buffer.
|
||||
*
|
||||
* @retval true If the message buffer is full.
|
||||
* @retval false Otherwise.
|
||||
*/
|
||||
inline bool isFull() const {
|
||||
return (xMessageBufferIsFull(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
private:
|
||||
MessageBufferBase() = default;
|
||||
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Destroy the MessageBufferBase object by calling <tt>void
|
||||
* vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vMessageBufferDelete.html>
|
||||
*
|
||||
* Delete a queue - freeing all the memory allocated for storing of items
|
||||
* placed on the queue.
|
||||
*/
|
||||
~MessageBufferBase() { vMessageBufferDelete(this->handle); }
|
||||
|
||||
MessageBufferBase(MessageBufferBase&&) noexcept = default;
|
||||
MessageBufferBase& operator=(MessageBufferBase&&) noexcept = default;
|
||||
|
||||
MessageBufferHandle_t handle = NULL;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class MessageBuffer MessageBuffer.hpp <FreeRTOS/MessageBuffer.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS message
|
||||
* buffer.
|
||||
*
|
||||
* A message buffer using dynamically allocated memory from the FreeRTOS heap.
|
||||
* See FreeRTOS::StaticMessageBuffer for a version that uses statically
|
||||
* allocated memory (memory that is allocated at compile time).
|
||||
*/
|
||||
class MessageBuffer : public MessageBufferBase {
|
||||
public:
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Construct a new MessageBuffer object by calling
|
||||
* <tt>MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferCreate.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* message buffer was created successfully in case the memory required to
|
||||
* create the message buffer could not be allocated.
|
||||
*
|
||||
* @param size The total number of bytes (not messages) the message buffer
|
||||
* will be able to hold at any one time. When a message is written to the
|
||||
* message buffer an additional sizeof( size_t ) bytes are also written to
|
||||
* store the message's length. sizeof( size_t ) is typically 4 bytes on a
|
||||
* 32-bit architecture, so on most 32-bit architectures a 10 byte message will
|
||||
* take up 14 bytes of message buffer space.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include MessageBuffer/messageBuffer.cpp
|
||||
*/
|
||||
explicit MessageBuffer(size_t size) {
|
||||
this->handle = xMessageBufferCreate(size);
|
||||
}
|
||||
~MessageBuffer() = default;
|
||||
|
||||
MessageBuffer(const MessageBuffer&) = delete;
|
||||
MessageBuffer& operator=(const MessageBuffer&) = delete;
|
||||
|
||||
MessageBuffer(MessageBuffer&&) noexcept = default;
|
||||
MessageBuffer& operator=(MessageBuffer&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StaticMessageBuffer MessageBuffer.hpp <FreeRTOS/MessageBuffer.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS message
|
||||
* buffer.
|
||||
*
|
||||
* If a message buffer is created using this class then the RAM is provided by
|
||||
* the application writer as part of the object instance and allows the RAM to
|
||||
* be statically allocated at compile time.
|
||||
*
|
||||
* @tparam N The size, in bytes, of the storage for the message buffer.
|
||||
*/
|
||||
template <size_t N>
|
||||
class StaticMessageBuffer : public MessageBufferBase {
|
||||
public:
|
||||
/**
|
||||
* MessageBuffer.hpp
|
||||
*
|
||||
* @brief Construct a new StaticMessageBuffer object by calling
|
||||
* <tt>MessageBufferHandle_t xMessageBufferCreateStatic( size_t
|
||||
* xBufferSizeBytes, uint8_t *pucMessageBufferStorageArea,
|
||||
* StaticMessageBuffer_t *pxStaticMessageBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xMessageBufferCreateStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the message buffer, so
|
||||
* the user should create this object as a global object or with the static
|
||||
* storage specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include MessageBuffer/staticMessageBuffer.cpp
|
||||
*/
|
||||
StaticMessageBuffer() : MessageBufferBase() {
|
||||
this->handle = xMessageBufferCreateStatic(sizeof(storage), storage,
|
||||
&staticMessageBuffer);
|
||||
}
|
||||
~StaticMessageBuffer() = default;
|
||||
|
||||
StaticMessageBuffer(const StaticMessageBuffer&) = delete;
|
||||
StaticMessageBuffer& operator=(const StaticMessageBuffer&) = delete;
|
||||
|
||||
StaticMessageBuffer(StaticMessageBuffer&&) noexcept = default;
|
||||
StaticMessageBuffer& operator=(StaticMessageBuffer&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticMessageBuffer_t staticMessageBuffer;
|
||||
uint8_t storage[N] = {0};
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_MESSAGEBUFFER_HPP
|
||||
495
source/shoh/src/FreeRTOSCPP/Mutex.hpp
Normal file
495
source/shoh/src/FreeRTOSCPP/Mutex.hpp
Normal file
@@ -0,0 +1,495 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_MUTEX_HPP
|
||||
#define FREERTOS_MUTEX_HPP
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class MutexBase Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard mutex interface to
|
||||
* FreeRTOS::Mutex, FreeRTOS::StaticMutex, FreeRTOS::RecursiveMutex, and
|
||||
* FreeRTOS::StaticRecursiveMutex.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::Mutex, FreeRTOS::StaticMutex, FreeRTOS::RecursiveMutex, and
|
||||
* FreeRTOS::StaticRecursiveMutex.
|
||||
*/
|
||||
class MutexBase {
|
||||
public:
|
||||
friend class Mutex;
|
||||
friend class StaticMutex;
|
||||
friend class RecursiveMutexBase;
|
||||
friend class RecursiveMutex;
|
||||
friend class StaticRecursiveMutex;
|
||||
|
||||
MutexBase(const MutexBase&) = delete;
|
||||
MutexBase& operator=(const MutexBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that checks if the underlying semaphore handle is not NULL.
|
||||
* This should be used to ensure a semaphore has been created correctly.
|
||||
*
|
||||
* @retval true the handle is not NULL.
|
||||
* @retval false the handle is NULL.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTake( SemaphoreHandle_t
|
||||
* xSemaphore, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00122.html>
|
||||
*
|
||||
* @param ticksToWait The time in ticks to wait for the mutex to become
|
||||
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||
* real time. A block time of zero can be used to poll the mutex.
|
||||
* @retval true If the mutex was locked.
|
||||
* @retval false If ticksToWait expired without the mutex becoming available.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/lock.cpp
|
||||
*/
|
||||
inline bool lock(const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return (xSemaphoreTake(handle, ticksToWait) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTakeFromISR ( SemaphoreHandle_t
|
||||
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||
*
|
||||
* @param higherPriorityTaskWoken It is possible (although unlikely, and
|
||||
* dependent on the semaphore type) that a mutex will have one or more tasks
|
||||
* blocked on it waiting to give the mutex. Calling lockFromISR() will make a
|
||||
* task that was blocked waiting to give the mutex leave the Blocked state. If
|
||||
* calling the API function causes a task to leave the Blocked state, and the
|
||||
* unblocked task has a priority equal to or higher than the currently
|
||||
* executing task (the task that was interrupted), then, internally, the API
|
||||
* function will set higherPriorityTaskWoken to true.
|
||||
* @return true If the mutex was successfully locked.
|
||||
* @return false If the mutex was not successfully locked because it was not
|
||||
* available.
|
||||
*/
|
||||
inline bool lockFromISR(bool& higherPriorityTaskWoken) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xSemaphoreTakeFromISR(handle, &taskWoken) == pdTRUE);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTakeFromISR ( SemaphoreHandle_t
|
||||
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool lockFromISR() const {
|
||||
return (xSemaphoreTakeFromISR(handle, NULL) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreGive( SemaphoreHandle_t xSemaphore
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00123.html>
|
||||
*
|
||||
* @warning This must not be used from an ISR.
|
||||
*
|
||||
* @return true If the mutex was unlocked.
|
||||
* @return false If an error occurred. Mutexes (semaphores) are implemented
|
||||
* using queues. An error can occur if there is no space on the queue to post
|
||||
* a message indicating that the mutex was not first locked correctly.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/unlock.cpp
|
||||
*/
|
||||
inline bool unlock() const { return (xSemaphoreGive(handle) == pdTRUE); }
|
||||
|
||||
private:
|
||||
MutexBase() = default;
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Destroy the MutexBase object by calling <tt>void vSemaphoreDelete(
|
||||
* SemaphoreHandle_t xSemaphore )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00113.html#vSemaphoreDelete>
|
||||
*
|
||||
* @note Do not delete a mutex that has tasks blocked on it (tasks that are in
|
||||
* the Blocked state waiting for the mutex to become available).
|
||||
*/
|
||||
~MutexBase() { vSemaphoreDelete(this->handle); }
|
||||
|
||||
MutexBase(MutexBase&&) noexcept = default;
|
||||
MutexBase& operator=(MutexBase&&) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Handle used to refer to the semaphore when using the FreeRTOS
|
||||
* interface.
|
||||
*/
|
||||
SemaphoreHandle_t handle = NULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class RecursiveMutexBase Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||
*
|
||||
* @brief Base class that provides the recursive mutex interface to
|
||||
* FreeRTOS::RecursiveMutex and FreeRTOS::StaticRecursiveMutex. This class
|
||||
* exists to override the lock() and unlock() functions which require different
|
||||
* underlying functions from what is used in FreeRTOS::MutexBase.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::RecursiveMutex or FreeRTOS::StaticRecursiveMutex.
|
||||
*/
|
||||
class RecursiveMutexBase : public MutexBase {
|
||||
public:
|
||||
friend class RecursiveMutex;
|
||||
friend class StaticRecursiveMutex;
|
||||
|
||||
RecursiveMutexBase(const RecursiveMutexBase&) = delete;
|
||||
RecursiveMutexBase& operator=(const RecursiveMutexBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void*);
|
||||
static void* operator new[](size_t, void*);
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTakeRecursive( SemaphoreHandle_t
|
||||
* xMutex, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreTakeRecursive.html>
|
||||
*
|
||||
* @param ticksToWait The time in ticks to wait for the mutex to become
|
||||
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||
* real time. A block time of zero can be used to poll the mutex. If the task
|
||||
* already owns the mutex then take() will return immediately no matter what
|
||||
* the value of ticksToWait.
|
||||
* @retval true If the mutex was locked.
|
||||
* @retval false If ticksToWait expired without the mutex becoming available.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/recursiveLock.cpp
|
||||
*/
|
||||
inline bool lock(const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return (xSemaphoreTakeRecursive(handle, ticksToWait) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreGiveRecursive( SemaphoreHandle_t
|
||||
* xSemaphore )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreGiveRecursive.html>
|
||||
*
|
||||
* A mutex used recursively can be locked repeatedly by the owner. The mutex
|
||||
* doesn't become available again until the owner has called unlock() for each
|
||||
* successful lock request. For example, if a task successfully locks the
|
||||
* same mutex 5 times then the mutex will not be available to any other task
|
||||
* until it has also unlocked the mutex back exactly five times.
|
||||
*
|
||||
* @return true If the mutex was unlocked.
|
||||
* @return false Otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/recursiveLock.cpp
|
||||
*/
|
||||
inline bool unlock() const {
|
||||
return (xSemaphoreGiveRecursive(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
private:
|
||||
RecursiveMutexBase() = default;
|
||||
~RecursiveMutexBase() = default;
|
||||
|
||||
RecursiveMutexBase(RecursiveMutexBase&&) noexcept = default;
|
||||
RecursiveMutexBase& operator=(RecursiveMutexBase&&) noexcept = default;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class Mutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS mutex.
|
||||
*
|
||||
* Each mutex require a small amount of RAM that is used to hold the mutex's
|
||||
* state. If a mutex is created using FreeRTOS::Mutex then the required RAM is
|
||||
* automatically allocated from the FreeRTOS heap. If a mutex is created using
|
||||
* FreeRTOS::StaticMutex then the RAM is provided by the application writer and
|
||||
* allows the RAM to be statically allocated at compile time. See the Static Vs
|
||||
* Dynamic allocation page for more information.
|
||||
*
|
||||
* Mutexes and binary semaphores are very similar but have some subtle
|
||||
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||
* semaphores do not. This makes binary semaphores the better choice for
|
||||
* implementing synchronisation (between tasks or between tasks and an
|
||||
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||
* exclusion.
|
||||
*
|
||||
* The priority of a task that locks a mutex will be temporarily raised if
|
||||
* another task of higher priority attempts to obtain the same mutex. The task
|
||||
* that owns the mutex 'inherits' the priority of the task attempting to lock
|
||||
* the same mutex. This means the mutex must always be unlocked back otherwise
|
||||
* the higher priority task will never be able to lock the mutex, and the lower
|
||||
* priority task will never 'disinherit' the priority.
|
||||
*/
|
||||
class Mutex : public MutexBase {
|
||||
public:
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Construct a new Mutex object by calling <tt>SemaphoreHandle_t
|
||||
* xSemaphoreCreateMutex( void )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/CreateMutex.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* mutex was created successfully in case the memory required to create the
|
||||
* queue could not be allocated.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/mutex.cpp
|
||||
*/
|
||||
Mutex() { this->handle = xSemaphoreCreateMutex(); }
|
||||
~Mutex() = default;
|
||||
|
||||
Mutex(const Mutex&) = delete;
|
||||
Mutex& operator=(const Mutex&) = delete;
|
||||
|
||||
Mutex(Mutex&&) noexcept = default;
|
||||
Mutex& operator=(Mutex&&) noexcept = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class RecursiveMutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS recursive
|
||||
* mutex.
|
||||
*
|
||||
* Each recursive mutex require a small amount of RAM that is used to hold the
|
||||
* recursive mutex's state. If a mutex is created using FreeRTOS::RecursiveMutex
|
||||
* then the required RAM is automatically allocated from the FreeRTOS heap. If a
|
||||
* recursive mutex is created using FreeRTOS::StaticRecursiveMutex then the RAM
|
||||
* is provided by the application writer, which requires an additional
|
||||
* parameter, but allows the RAM to be statically allocated at compile time. See
|
||||
* the Static Vs Dynamic allocation page for more information.
|
||||
*
|
||||
* Contrary to non-recursive mutexes, a task can lock a recursive mutex multiple
|
||||
* times, and the recursive mutex will only be returned after the holding task
|
||||
* has unlocked the mutex the same number of times it locked the mutex.
|
||||
*
|
||||
* Like non-recursive mutexes, recursive mutexes implement a priority
|
||||
* inheritance algorithm. The priority of a task that locks a mutex will be
|
||||
* temporarily raised if another task of higher priority attempts to obtain the
|
||||
* same mutex. The task that owns the mutex 'inherits' the priority of the task
|
||||
* attempting to lock the same mutex. This means the mutex must always be
|
||||
* unlocked otherwise the higher priority task will never be able to obtain the
|
||||
* mutex, and the lower priority task will never 'disinherit' the priority.
|
||||
*/
|
||||
class RecursiveMutex : public RecursiveMutexBase {
|
||||
public:
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Construct a new RecursiveMutex object by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreCreateRecursiveMutex.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* recursive mutex was created successfully in case the memory required to
|
||||
* create the queue could not be allocated.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/recursiveMutex.cpp
|
||||
*/
|
||||
RecursiveMutex() { this->handle = xSemaphoreCreateRecursiveMutex(); }
|
||||
~RecursiveMutex() = default;
|
||||
|
||||
RecursiveMutex(const RecursiveMutex&) = delete;
|
||||
RecursiveMutex& operator=(const RecursiveMutex&) = delete;
|
||||
|
||||
RecursiveMutex(RecursiveMutex&&) noexcept = default;
|
||||
RecursiveMutex& operator=(RecursiveMutex&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StaticMutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS mutex.
|
||||
*
|
||||
* Each mutex require a small amount of RAM that is used to hold the mutex's
|
||||
* state. If a mutex is created using FreeRTOS::Mutex then the required RAM is
|
||||
* automatically allocated from the FreeRTOS heap. If a mutex is created using
|
||||
* FreeRTOS::StaticMutex then the RAM is provided by the application writer and
|
||||
* allows the RAM to be statically allocated at compile time. See the Static Vs
|
||||
* Dynamic allocation page for more information.
|
||||
*
|
||||
* Mutexes and binary semaphores are very similar but have some subtle
|
||||
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||
* semaphores do not. This makes binary semaphores the better choice for
|
||||
* implementing synchronisation (between tasks or between tasks and an
|
||||
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||
* exclusion.
|
||||
*
|
||||
* The priority of a task that locks a mutex will be temporarily raised if
|
||||
* another task of higher priority attempts to obtain the same mutex. The task
|
||||
* that owns the mutex 'inherits' the priority of the task attempting to lock
|
||||
* the same mutex. This means the mutex must always be unlocked back otherwise
|
||||
* the higher priority task will never be able to lock the mutex, and the lower
|
||||
* priority task will never 'disinherit' the priority.
|
||||
*/
|
||||
class StaticMutex : public MutexBase {
|
||||
public:
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Construct a new StaticMutex object by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t
|
||||
* *pxMutexBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreCreateMutexStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the mutex, so the user
|
||||
* should create this object as a global object or with the static storage
|
||||
* specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/staticMutex.cpp
|
||||
*/
|
||||
StaticMutex() { this->handle = xSemaphoreCreateMutexStatic(&staticMutex); }
|
||||
~StaticMutex() = default;
|
||||
|
||||
StaticMutex(const StaticMutex&) = delete;
|
||||
StaticMutex& operator=(const StaticMutex&) = delete;
|
||||
|
||||
StaticMutex(StaticMutex&&) noexcept = default;
|
||||
StaticMutex& operator=(StaticMutex&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticSemaphore_t staticMutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class StaticRecursiveMutex Mutex.hpp <FreeRTOS/Mutex.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS recursive
|
||||
* mutex.
|
||||
*
|
||||
* Each recursive mutex require a small amount of RAM that is used to hold the
|
||||
* recursive mutex's state. If a mutex is created using FreeRTOS::RecursiveMutex
|
||||
* then the required RAM is automatically allocated from the FreeRTOS heap. If a
|
||||
* recursive mutex is created using FreeRTOS::StaticRecursiveMutex then the RAM
|
||||
* is provided by the application writer, which requires an additional
|
||||
* parameter, but allows the RAM to be statically allocated at compile time. See
|
||||
* the Static Vs Dynamic allocation page for more information.
|
||||
*
|
||||
* Contrary to non-recursive mutexes, a task can lock a recursive mutex multiple
|
||||
* times, and the recursive mutex will only be returned after the holding task
|
||||
* has unlocked the mutex the same number of times it locked the mutex.
|
||||
*
|
||||
* Like non-recursive mutexes, recursive mutexes implement a priority
|
||||
* inheritance algorithm. The priority of a task that locks a mutex will be
|
||||
* temporarily raised if another task of higher priority attempts to obtain the
|
||||
* same mutex. The task that owns the mutex 'inherits' the priority of the task
|
||||
* attempting to lock the same mutex. This means the mutex must always be
|
||||
* unlocked otherwise the higher priority task will never be able to obtain the
|
||||
* mutex, and the lower priority task will never 'disinherit' the priority.
|
||||
*/
|
||||
class StaticRecursiveMutex : public RecursiveMutexBase {
|
||||
public:
|
||||
/**
|
||||
* Mutex.hpp
|
||||
*
|
||||
* @brief Construct a new StaticRecursiveMutex object by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic(
|
||||
* StaticSemaphore_t *pxMutexBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreCreateRecursiveMutexStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the recursive mutex, so
|
||||
* the user should create this object as a global object or with the static
|
||||
* storage specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Mutex/staticRecursiveMutex.cpp
|
||||
*/
|
||||
StaticRecursiveMutex() {
|
||||
this->handle = xSemaphoreCreateRecursiveMutexStatic(&staticRecursiveMutex);
|
||||
}
|
||||
~StaticRecursiveMutex() = default;
|
||||
|
||||
StaticRecursiveMutex(const StaticRecursiveMutex&) = delete;
|
||||
StaticRecursiveMutex& operator=(const StaticRecursiveMutex&) = delete;
|
||||
|
||||
StaticRecursiveMutex(StaticRecursiveMutex&&) noexcept = default;
|
||||
StaticRecursiveMutex& operator=(StaticRecursiveMutex&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticSemaphore_t staticRecursiveMutex;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_MUTEX_HPP
|
||||
737
source/shoh/src/FreeRTOSCPP/Queue.hpp
Normal file
737
source/shoh/src/FreeRTOSCPP/Queue.hpp
Normal file
@@ -0,0 +1,737 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_QUEUE_HPP
|
||||
#define FREERTOS_QUEUE_HPP
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class QueueBase Queue.hpp <FreeRTOS/Queue.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard queue interface to
|
||||
* FreeRTOS::Queue and FreeRTOS::StaticQueue.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::Queue or FreeRTOS::StaticQueue.
|
||||
*
|
||||
* @tparam T Type to be stored in the queue.
|
||||
*/
|
||||
template <class T>
|
||||
class QueueBase {
|
||||
public:
|
||||
template <class>
|
||||
friend class Queue;
|
||||
|
||||
template <class, UBaseType_t>
|
||||
friend class StaticQueue;
|
||||
|
||||
QueueBase(const QueueBase&) = delete;
|
||||
QueueBase& operator=(const QueueBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that checks if the underlying queue handle is not NULL.
|
||||
* This should be used to ensure a queue has been created correctly.
|
||||
*
|
||||
* @retval true the handle is not NULL.
|
||||
* @retval false the handle is NULL.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xQueueSendToBack( xQueue, pvItemToQueue,
|
||||
* xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00117.html>
|
||||
*
|
||||
* Post an item to the back of a queue. The item is queued by copy, not by
|
||||
* reference. This function must not be called from an interrupt service
|
||||
* routine. See FreeRTOS::Queue::sendToBackFromISR() for an alternative which
|
||||
* may be used in an ISR.
|
||||
*
|
||||
* @param item A reference to the item that is to be placed on the queue.
|
||||
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||
* for space to become available on the queue, should it already be full. The
|
||||
* call will return immediately if this is set to 0 and the queue is full. The
|
||||
* time is defined in tick periods so the constant portTICK_PERIOD_MS should
|
||||
* be used to convert to real time if this is required.
|
||||
* @retval true if the item was successfully posted.
|
||||
* @retval false otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/sendToBack.cpp
|
||||
*/
|
||||
inline bool sendToBack(const T& item,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return (xQueueSendToBack(handle, &item, ticksToWait) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xQueueSendToBackFromISR( xQueue,
|
||||
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueSendToBackFromISR.html>
|
||||
*
|
||||
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||
* priority higher than the currently running task.
|
||||
* @param item A reference to the item that is to be placed on the queue.
|
||||
* @retval true if the item was successfully posted
|
||||
* @retval false otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/sendToBackFromISR.cpp
|
||||
*/
|
||||
inline bool sendToBackFromISR(bool& higherPriorityTaskWoken,
|
||||
const T& item) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result =
|
||||
(xQueueSendToBackFromISR(handle, &item, &taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xQueueSendToBackFromISR( xQueue,
|
||||
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueSendToBackFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool sendToBackFromISR(const T& item) const {
|
||||
return (xQueueSendToBackFromISR(handle, &item, NULL) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xQueueSendToFront( xQueue, pvItemToQueue,
|
||||
* xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueSendToFront.html>
|
||||
*
|
||||
* @param item A reference to the item that is to be placed on the queue.
|
||||
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||
* for space to become available on the queue, should it already be full. The
|
||||
* call will return immediately if this is set to 0 and the queue is full. The
|
||||
* time is defined in tick periods so the constant portTICK_PERIOD_MS should
|
||||
* be used to convert to real time if this is required.
|
||||
* @retval true if the item was successfully posted.
|
||||
* @retval false otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/sendToFront.cpp
|
||||
*/
|
||||
inline bool sendToFront(const T& item,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return (xQueueSendToFront(handle, &item, ticksToWait) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xQueueSendToFrontFromISR( xQueue,
|
||||
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueSendToFrontFromISR.html>
|
||||
*
|
||||
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||
* priority higher than the currently running task.
|
||||
* @param item A reference to the item that is to be placed on the queue.
|
||||
* @retval true if the item was successfully posted
|
||||
* @retval false otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/sendToFrontFromISR.cpp
|
||||
*/
|
||||
inline bool sendToFrontFromISR(bool& higherPriorityTaskWoken,
|
||||
const T& item) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result =
|
||||
(xQueueSendToFrontFromISR(handle, &item, &taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xQueueSendToFrontFromISR( xQueue,
|
||||
* pvItemToQueue, pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueSendToFrontFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool sendToFrontFromISR(const T& item) const {
|
||||
return (xQueueSendToFrontFromISR(handle, &item, NULL) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueReceive( QueueHandle_t
|
||||
* xQueue, void *pvBuffer, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00118.html>
|
||||
*
|
||||
* Receive an item from a queue. This function must not be used in an
|
||||
* interrupt service routine. See receiveFromISR() for an alternative that
|
||||
* can.
|
||||
*
|
||||
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||
* for an item to receive should the queue be empty at the time of the call.
|
||||
* Setting ticksToWait to 0 will cause the function to return immediately if
|
||||
* the queue is empty. The time is defined in tick periods so the constant
|
||||
* portTICK_PERIOD_MS should be used to convert to real time if this is
|
||||
* required.
|
||||
* @return std::optional<T> Object from the queue. User should check that the
|
||||
* value is present.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/receive.cpp
|
||||
*/
|
||||
inline std::optional<T> receive(
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
T buffer;
|
||||
return (xQueueReceive(handle, &buffer, ticksToWait) == pdTRUE)
|
||||
? std::optional<T>(buffer)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueReceiveFromISR(
|
||||
* QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00120.html>
|
||||
*
|
||||
* Receive an item from a queue. It is safe to use this function from within
|
||||
* an interrupt service routine.
|
||||
*
|
||||
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||
* priority higher than the currently running task.
|
||||
* @return std::optional<T> Object from the queue. User should check that the
|
||||
* value is present.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/receiveFromISR.cpp
|
||||
*/
|
||||
inline std::optional<T> receiveFromISR(bool& higherPriorityTaskWoken) const {
|
||||
T buffer;
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xQueueReceiveFromISR(handle, &buffer, &taskWoken) == pdTRUE);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result ? std::optional<T>(buffer) : std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueReceiveFromISR(
|
||||
* QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00120.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline std::optional<T> receiveFromISR() const {
|
||||
T buffer;
|
||||
return (xQueueReceiveFromISR(handle, &buffer, NULL) == pdTRUE)
|
||||
? std::optional<T>(buffer)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>UBaseType_t uxQueueMessagesWaiting(
|
||||
* QueueHandle_t xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#ucQueueMessagesWaiting>
|
||||
*
|
||||
* Return the number of messages stored in a queue.
|
||||
*
|
||||
* @retval UBaseType_t The number of messages available in the queue.
|
||||
*/
|
||||
inline UBaseType_t messagesWaiting() const {
|
||||
return uxQueueMessagesWaiting(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>UBaseType_t uxQueueMessagesWaitingFromISR(
|
||||
* QueueHandle_t xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#ucQueueMessagesWaitingFromISR>
|
||||
*
|
||||
* A version of messagesWaiting() that can be called from an ISR. Return the
|
||||
* number of messages stored in a queue.
|
||||
*
|
||||
* @retval UBaseType_t The number of messages available in the queue.
|
||||
*/
|
||||
inline UBaseType_t messagesWaitingFromISR() const {
|
||||
return uxQueueMessagesWaitingFromISR(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>UBaseType_t uxQueueSpacesAvailable(
|
||||
* QueueHandle_t xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#uxQueueSpacesAvailable>
|
||||
*
|
||||
* Return the number of free spaces in a queue.
|
||||
*
|
||||
* @retval UBaseType_t The number of free spaces available in the queue.
|
||||
*/
|
||||
inline UBaseType_t spacesAvailable() const {
|
||||
return uxQueueSpacesAvailable(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueReset( QueueHandle_t xQueue
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#xQueueReset>
|
||||
*
|
||||
* Resets a queue to its original empty state.
|
||||
*/
|
||||
inline void reset() const { xQueueReset(handle); }
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueOverwrite( QueueHandle_t
|
||||
* xQueue, const void * pvItemToQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueOverwrite.html>
|
||||
*
|
||||
* Only for use with queues that have a length of one - so the queue is either
|
||||
* empty or full.
|
||||
*
|
||||
* Post an item on a queue. If the queue is already full then overwrite the
|
||||
* value held in the queue. The item is queued by copy, not by reference.
|
||||
*
|
||||
* This function must not be called from an interrupt service routine. See
|
||||
* overwriteFromISR() for an alternative which may be used in an ISR.
|
||||
*
|
||||
* @param item A reference to the item that is to be placed on the queue.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/overwrite.cpp
|
||||
*/
|
||||
inline void overwrite(const T& item) const { xQueueOverwrite(handle, &item); }
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueOverwriteFromISR(
|
||||
* QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t
|
||||
* *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueOverwriteFromISR.html>
|
||||
*
|
||||
* A version of overwrite() that can be used in an interrupt service routine
|
||||
* (ISR).
|
||||
*
|
||||
* Only for use with queues that can hold a single item - so the queue is
|
||||
* either empty or full.
|
||||
*
|
||||
* Post an item on a queue. If the queue is already full then overwrite the
|
||||
* value held in the queue. The item is queued by copy, not by reference.
|
||||
*
|
||||
* @param higherPriorityTaskWoken A reference that will be set to true if
|
||||
* sending to the queue caused a task to unblock, and the unblocked task has a
|
||||
* priority higher than the currently running task.
|
||||
* @param item A reference to the item that is to be placed on the queue.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/overwriteFromISR.cpp
|
||||
*/
|
||||
inline void overwriteFromISR(bool& higherPriorityTaskWoken,
|
||||
const T& item) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
xQueueOverwriteFromISR(handle, &item, &taskWoken);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueOverwriteFromISR(
|
||||
* QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t
|
||||
* *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueOverwriteFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline void overwriteFromISR(const T& item) const {
|
||||
xQueueOverwriteFromISR(handle, &item, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||
* void * const pvBuffer, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueuePeek.html>
|
||||
*
|
||||
* Receive an item from a queue without removing the item from the queue.
|
||||
*
|
||||
* Successfully received items remain on the queue so will be returned again
|
||||
* by the next call, or a call to receive().
|
||||
*
|
||||
* This function must not be used in an interrupt service routine. See
|
||||
* peekFromISR() for an alternative that can be called from an interrupt
|
||||
* service routine.
|
||||
*
|
||||
* @param ticksToWait The maximum amount of time the task should block waiting
|
||||
* for an item to receive should the queue be empty at the time of the call.
|
||||
* Setting ticksToWait to 0 will cause the function to return immediately if
|
||||
* the queue is empty. The time is defined in tick periods so the constant
|
||||
* portTICK_PERIOD_MS should be used to convert to real time if this is
|
||||
* required.
|
||||
* @return std::optional<T> Object from the queue. User should check that the
|
||||
* value is present.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/peek.cpp
|
||||
*/
|
||||
inline std::optional<T> peek(
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
T buffer;
|
||||
return (xQueuePeek(handle, &buffer, ticksToWait) == pdTRUE)
|
||||
? std::optional<T>(buffer)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueuePeekFromISR( QueueHandle_t
|
||||
* xQueue, void *pvBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueuePeekFromISR.html>
|
||||
*
|
||||
* A version of peek() that can be called from an interrupt service routine
|
||||
* (ISR).
|
||||
*
|
||||
* Receive an item from a queue without removing the item from the queue.
|
||||
*
|
||||
* Successfully received items remain on the queue so will be returned again
|
||||
* by the next call, or a call to receive().
|
||||
*
|
||||
* @return std::optional<T> Object from the queue. User should check that the
|
||||
* value is present.
|
||||
*/
|
||||
inline std::optional<T> peekFromISR() const {
|
||||
T buffer;
|
||||
return (xQueuePeekFromISR(handle, &buffer) == pdTRUE)
|
||||
? std::optional<T>(buffer)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>void vQueueAddToRegistry( QueueHandle_t
|
||||
* xQueue, char *pcQueueName )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vQueueAddToRegistry.html>
|
||||
*
|
||||
* The registry is provided as a means for kernel aware debuggers to locate
|
||||
* queues, semaphores and mutexes. Call addToRegistry() add a queue,
|
||||
* semaphore or mutex handle to the registry if you want the handle to be
|
||||
* available to a kernel aware debugger. If you are not using a kernel aware
|
||||
* debugger then this function can be ignored.
|
||||
*
|
||||
* configQUEUE_REGISTRY_SIZE defines the maximum number of handles the
|
||||
* registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 within
|
||||
* FreeRTOSConfig.h for the registry to be available. Its value does not
|
||||
* effect the number of queues, semaphores and mutexes that can be created -
|
||||
* just the number that the registry can hold.
|
||||
*
|
||||
* If addToRegistry() is called more than once for the same queue, the
|
||||
* registry will store the name parameter from the most recent call to
|
||||
* addToRegistry().
|
||||
*
|
||||
* @param name The name to be associated with the handle. This is the name
|
||||
* that the kernel aware debugger will display. The queue registry only
|
||||
* stores a pointer to the string - so the string must be persistent (global
|
||||
* or preferably in ROM/Flash), not on the stack.
|
||||
*/
|
||||
inline void addToRegistry(const char* name) const {
|
||||
vQueueAddToRegistry(handle, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>void vQueueUnregisterQueue( QueueHandle_t
|
||||
* xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vQueueUnregisterQueue.html>
|
||||
*
|
||||
* The registry is provided as a means for kernel aware debuggers to locate
|
||||
* queues, semaphores and mutexes. Call addToRegistry() add a queue,
|
||||
* semaphore or mutex handle to the registry if you want the handle to be
|
||||
* available to a kernel aware debugger, and unregister() to remove the queue,
|
||||
* semaphore or mutex from the register. If you are not using a kernel aware
|
||||
* debugger then this function can be ignored.
|
||||
*/
|
||||
inline void unregister() const { vQueueUnregisterQueue(handle); }
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>const char *pcQueueGetName( QueueHandle_t
|
||||
* xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/pcQueueGetName.html>
|
||||
*
|
||||
* The queue registry is provided as a means for kernel aware debuggers to
|
||||
* locate queues, semaphores and mutexes. Call getName() to look up and return
|
||||
* the name of a queue in the queue registry from the queue's handle.
|
||||
*
|
||||
* @return If the queue referenced by the queue is in the queue registry, then
|
||||
* the text name of the queue is returned, otherwise NULL is returned.
|
||||
*/
|
||||
inline const char* getName() const { return pcQueueGetName(handle); }
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueIsQueueFullFromISR( const
|
||||
* QueueHandle_t xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#xQueueIsQueueFullFromISR>
|
||||
*
|
||||
* Queries a queue to determine if the queue is empty. This function should
|
||||
* only be used in an ISR.
|
||||
*
|
||||
* @return true if the queue is full.
|
||||
* @return false if the queue is not full.
|
||||
*/
|
||||
inline bool isFullFromISR() const {
|
||||
return (xQueueIsQueueFullFromISR(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xQueueIsQueueEmptyFromISR( const
|
||||
* QueueHandle_t xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#xQueueIsQueueEmptyFromISR>
|
||||
*
|
||||
* Queries a queue to determine if the queue is empty. This function should
|
||||
* only be used in an ISR.
|
||||
*
|
||||
* @retval true if the queue is empty.
|
||||
* @retval false if the queue is not empty.
|
||||
*/
|
||||
inline bool isEmptyFromISR() const {
|
||||
return (xQueueIsQueueEmptyFromISR(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Construct a new QueueBase object.
|
||||
*
|
||||
* @note Default constructor is deliberately private as this class is not
|
||||
* intended to be instantiated or derived from by the user. Use
|
||||
* FreeRTOS::Queue or FreeRTOS::StaticQueue.
|
||||
*/
|
||||
QueueBase() = default;
|
||||
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Destroy the QueueBase object by calling <tt>void vQueueDelete(
|
||||
* QueueHandle_t xQueue )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00018.html#vQueueDelete>
|
||||
*
|
||||
* Delete a queue - freeing all the memory allocated for storing of items
|
||||
* placed on the queue.
|
||||
*/
|
||||
~QueueBase() { vQueueDelete(this->handle); }
|
||||
|
||||
QueueBase(QueueBase&&) noexcept = default;
|
||||
QueueBase& operator=(QueueBase&&) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Handle used to refer to the queue when using the FreeRTOS interface.
|
||||
*/
|
||||
QueueHandle_t handle = NULL;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class Queue Queue.hpp <FreeRTOS/Queue.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS queue.
|
||||
*
|
||||
* Each queue requires RAM that is used to hold the queue state, and to hold the
|
||||
* items that are contained in the queue (the queue storage area). If a queue is
|
||||
* created using this class then the required RAM is automatically allocated
|
||||
* from the FreeRTOS heap.
|
||||
*
|
||||
* @tparam T Type to be stored in the queue.
|
||||
*/
|
||||
template <class T>
|
||||
class Queue : public QueueBase<T> {
|
||||
public:
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Construct a new Queue object by calling <tt>QueueHandle_t
|
||||
* xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00116.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* queue was created successfully in case the memory required to create the
|
||||
* queue could not be allocated.
|
||||
*
|
||||
* @param length The maximum number of items the queue can hold at any one
|
||||
* time.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/queue.cpp
|
||||
*/
|
||||
explicit Queue(const UBaseType_t length) {
|
||||
this->handle = xQueueCreate(length, sizeof(T));
|
||||
}
|
||||
~Queue() = default;
|
||||
|
||||
Queue(const Queue&) = delete;
|
||||
Queue& operator=(const Queue&) = delete;
|
||||
|
||||
Queue(Queue&&) noexcept = default;
|
||||
Queue& operator=(Queue&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StaticQueue Queue.hpp <FreeRTOS/Queue.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS queue.
|
||||
*
|
||||
* If a queue is created using this class then the RAM is provided by the
|
||||
* application writer as part of the object instance and allows the RAM to be
|
||||
* statically allocated at compile time.
|
||||
*
|
||||
* @tparam T Type to be stored in the queue.
|
||||
* @tparam N The maximum number of items the queue can hold at any one time.
|
||||
*/
|
||||
template <class T, UBaseType_t N>
|
||||
class StaticQueue : public QueueBase<T> {
|
||||
public:
|
||||
/**
|
||||
* Queue.hpp
|
||||
*
|
||||
* @brief Construct a new StaticQueue object by calling
|
||||
* <tt>QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLength,
|
||||
* UBaseType_t uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t
|
||||
* *pxQueueBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xQueueCreateStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the queue, so the user
|
||||
* should create this object as a global object or with the static storage
|
||||
* specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Queue/staticQueue.cpp
|
||||
*/
|
||||
StaticQueue() {
|
||||
this->handle = xQueueCreateStatic(N, sizeof(T), storage, &staticQueue);
|
||||
}
|
||||
~StaticQueue() = default;
|
||||
|
||||
StaticQueue(const StaticQueue&) = delete;
|
||||
StaticQueue& operator=(const StaticQueue&) = delete;
|
||||
|
||||
StaticQueue(StaticQueue&&) noexcept = default;
|
||||
StaticQueue& operator=(StaticQueue&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticQueue_t staticQueue;
|
||||
uint8_t storage[N * sizeof(T)];
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_QUEUE_HPP
|
||||
523
source/shoh/src/FreeRTOSCPP/Semaphore.hpp
Normal file
523
source/shoh/src/FreeRTOSCPP/Semaphore.hpp
Normal file
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_SEMAPHORE_HPP
|
||||
#define FREERTOS_SEMAPHORE_HPP
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class SemaphoreBase Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard semaphore interface to
|
||||
* FreeRTOS::BinarySemaphore, FreeRTOS::StaticBinarySemaphore,
|
||||
* FreeRTOS::CountingSemaphore, and FreeRTOS::StaticCountingSemaphore.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::BinarySemaphore, FreeRTOS::StaticBinarySemaphore,
|
||||
* FreeRTOS::CountingSemaphore, or FreeRTOS::StaticCountingSemaphore.
|
||||
*/
|
||||
class SemaphoreBase {
|
||||
public:
|
||||
friend class BinarySemaphore;
|
||||
friend class StaticBinarySemaphore;
|
||||
friend class CountingSemaphore;
|
||||
friend class StaticCountingSemaphore;
|
||||
|
||||
SemaphoreBase(const SemaphoreBase&) = delete;
|
||||
SemaphoreBase& operator=(const SemaphoreBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that checks if the underlying semaphore handle is not NULL.
|
||||
* This should be used to ensure a semaphore has been created correctly.
|
||||
*
|
||||
* @retval true the handle is not NULL.
|
||||
* @retval false the handle is NULL.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>UBaseType_t uxSemaphoreGetCount(
|
||||
* SemaphoreHandle_t xSemaphore )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/uxSemaphoreGetCount.html>
|
||||
*
|
||||
* Returns the count of a semaphore.
|
||||
*
|
||||
* @return UBaseType_t If the semaphore is a counting semaphore then the
|
||||
* semaphores current count value is returned. If the semaphore is a binary
|
||||
* semaphore then 1 is returned if the semaphore is available, and 0 is
|
||||
* returned if the semaphore is not available.
|
||||
*/
|
||||
inline UBaseType_t getCount() const { return uxSemaphoreGetCount(handle); }
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTake( SemaphoreHandle_t
|
||||
* xSemaphore, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00122.html>
|
||||
*
|
||||
* Function to obtain a semaphore.
|
||||
*
|
||||
* This macro must not be called from an ISR. takeFromISR() can be used to
|
||||
* take a semaphore from within an interrupt if required, although this would
|
||||
* not be a normal operation. Semaphores use queues as their underlying
|
||||
* mechanism, so functions are to some extent interoperable.
|
||||
*
|
||||
* @param ticksToWait The time in ticks to wait for the semaphore to become
|
||||
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||
* real time. A block time of zero can be used to poll the semaphore.
|
||||
* @retval true If the semaphore was obtained.
|
||||
* @retval false If xTicksToWait expired without the semaphore becoming
|
||||
* available.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Semaphore/take.cpp
|
||||
*/
|
||||
inline bool take(const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return (xSemaphoreTake(handle, ticksToWait) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTakeFromISR( SemaphoreHandle_t
|
||||
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||
*
|
||||
* A version of take() that can be called from an ISR. Unlike take(),
|
||||
* takeFromISR() does not permit a block time to be specified.
|
||||
*
|
||||
* @param higherPriorityTaskWoken It is possible (although unlikely, and
|
||||
* dependent on the semaphore type) that a semaphore will have one or more
|
||||
* tasks blocked on it waiting to give the semaphore. Calling takeFromISR()
|
||||
* will make a task that was blocked waiting to give the semaphore leave the
|
||||
* Blocked state. If calling the API function causes a task to leave the
|
||||
* Blocked state, and the unblocked task has a priority equal to or higher
|
||||
* than the currently executing task (the task that was interrupted), then,
|
||||
* internally, the API function will set higherPriorityTaskWoken to true. If
|
||||
* takeFromISR() sets higherPriorityTaskWoken to true, then a context switch
|
||||
* should be performed before the interrupt is exited. This will ensure that
|
||||
* the interrupt returns directly to the highest priority Ready state task.
|
||||
* The mechanism is identical to that used in the FreeRTOS::receiveFromISR()
|
||||
* function, and readers are referred to the FreeRTOS::receiveFromISR()
|
||||
* documentation for further explanation.
|
||||
* @retval true If the semaphore was successfully taken.
|
||||
* @retval false If the semaphore was not successfully taken because it was
|
||||
* not available.
|
||||
*/
|
||||
inline bool takeFromISR(bool& higherPriorityTaskWoken) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xSemaphoreTakeFromISR(handle, &taskWoken) == pdTRUE);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreTakeFromISR( SemaphoreHandle_t
|
||||
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreTakeFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool takeFromISR() const {
|
||||
return (xSemaphoreTakeFromISR(handle, NULL) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreGive( SemaphoreHandle_t xSemaphore
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00123.html>
|
||||
*
|
||||
* Function to release a semaphore.
|
||||
*
|
||||
* This must not be used from an ISR. See giveFromISR() for an alternative
|
||||
* which can be used from an ISR.
|
||||
*
|
||||
* @retval true If the semaphore was released.
|
||||
* @retval false If an error occurred. Semaphores are implemented using
|
||||
* queues. An error can occur if there is no space on the queue to post a
|
||||
* message indicating that the semaphore was not first obtained correctly.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Semaphore/give.cpp
|
||||
*/
|
||||
inline bool give() const { return (xSemaphoreGive(handle) == pdTRUE); }
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreGiveFromISR( SemaphoreHandle_t
|
||||
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00124.html>
|
||||
*
|
||||
* Function to release a semaphore.
|
||||
*
|
||||
* This macro can be used from an ISR.
|
||||
*
|
||||
* @param higherPriorityTaskWoken giveFromISR() will set
|
||||
* higherPriorityTaskWoken to true if giving the semaphore caused a task to
|
||||
* unblock, and the unblocked task has a priority higher than the currently
|
||||
* running task. If giveFromISR() sets this value to true then a context
|
||||
* switch should be requested before the interrupt is exited.
|
||||
* @retval true If the semaphore was successfully given.
|
||||
* @retval false Otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Semaphore/giveFromISR.cpp
|
||||
*/
|
||||
inline bool giveFromISR(bool& higherPriorityTaskWoken) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xSemaphoreGiveFromISR(handle, &taskWoken) == pdTRUE);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>xSemaphoreGiveFromISR( SemaphoreHandle_t
|
||||
* xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00124.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool giveFromISR() const {
|
||||
return (xSemaphoreGiveFromISR(handle, NULL) == pdTRUE);
|
||||
}
|
||||
|
||||
private:
|
||||
SemaphoreBase() = default;
|
||||
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Destroy the SemaphoreBase object by calling <tt>void
|
||||
* vSemaphoreDelete( SemaphoreHandle_t xSemaphore )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/a00113.html#vSemaphoreDelete>
|
||||
*
|
||||
* @note Do not delete a semaphore that has tasks blocked on it (tasks that
|
||||
* are in the Blocked state waiting for the semaphore to become available).
|
||||
*/
|
||||
~SemaphoreBase() { vSemaphoreDelete(this->handle); }
|
||||
|
||||
SemaphoreBase(SemaphoreBase&&) noexcept = default;
|
||||
SemaphoreBase& operator=(SemaphoreBase&&) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Handle used to refer to the semaphore when using the FreeRTOS
|
||||
* interface.
|
||||
*/
|
||||
SemaphoreHandle_t handle = NULL;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class BinarySemaphore Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS binary
|
||||
* semaphore.
|
||||
*
|
||||
* Each binary semaphore require a small amount of RAM that is used to hold the
|
||||
* semaphore's state. If a binary semaphore is created using
|
||||
* FreeRTOS::BinarySemaphore then the required RAM is automatically allocated
|
||||
* from the FreeRTOS heap. If a binary semaphore is created using
|
||||
* FreeRTOS::StaticBinarySemaphore then the RAM is provided by the application
|
||||
* writer as part of the class and allows the RAM to be statically allocated at
|
||||
* compile time. See the Static Vs Dynamic allocation page for more information.
|
||||
*
|
||||
* The semaphore is created in the 'empty' state, meaning the semaphore must
|
||||
* first be given using the give() API function before it can subsequently be
|
||||
* taken (obtained) using the take() function.
|
||||
*
|
||||
* Binary semaphores and mutexes are very similar but have some subtle
|
||||
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||
* semaphores do not. This makes binary semaphores the better choice for
|
||||
* implementing synchronisation (between tasks or between tasks and an
|
||||
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||
* exclusion.
|
||||
*
|
||||
* A binary semaphore need not be given back once obtained, so task
|
||||
* synchronisation can be implemented by one task/interrupt continuously
|
||||
* 'giving' the semaphore while another continuously 'takes' the semaphore. This
|
||||
* is demonstrated by the sample code on the giveFromISR() documentation page.
|
||||
* Note the same functionality can often be achieved in a more efficient way
|
||||
* using a direct to task notification.
|
||||
*
|
||||
* The priority of a task that 'takes' a mutex can potentially be raised if
|
||||
* another task of higher priority attempts to obtain the same mutex. The task
|
||||
* that owns the mutex 'inherits' the priority of the task attempting to 'take'
|
||||
* the same mutex. This means the mutex must always be 'given' back - otherwise
|
||||
* the higher priority task will never be able to obtain the mutex, and the
|
||||
* lower priority task will never 'disinherit' the priority. An example of a
|
||||
* mutex being used to implement mutual exclusion is provided on the take()
|
||||
* documentation page.
|
||||
*/
|
||||
class BinarySemaphore : public SemaphoreBase {
|
||||
public:
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Construct a new BinarySemaphore object by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateBinary( void )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreCreateBinary.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* binary semaphore was created successfully in case the memory required to
|
||||
* create the queue could not be allocated.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Semaphore/binarySemaphore.cpp
|
||||
*/
|
||||
BinarySemaphore() { this->handle = xSemaphoreCreateBinary(); }
|
||||
~BinarySemaphore() = default;
|
||||
|
||||
BinarySemaphore(const BinarySemaphore&) = delete;
|
||||
BinarySemaphore& operator=(const BinarySemaphore&) = delete;
|
||||
|
||||
BinarySemaphore(BinarySemaphore&&) noexcept = default;
|
||||
BinarySemaphore& operator=(BinarySemaphore&&) noexcept = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class CountingSemaphore Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS counting
|
||||
* semaphore.
|
||||
*
|
||||
* Each counting semaphore require a small amount of RAM that is used to hold
|
||||
* the semaphore's state. If a counting semaphore is created using
|
||||
* FreeRTOS::CountingSemaphore then the required RAM is automatically allocated
|
||||
* from the FreeRTOS heap. If a counting semaphore is created using
|
||||
* FreeRTOS::StaticCountingSemaphore then the RAM is provided by the application
|
||||
* writer as part of the class and allows the RAM to be statically allocated at
|
||||
* compile time. See the Static Vs Dynamic allocation page for more information.
|
||||
*
|
||||
* Counting semaphores are typically used for two things:
|
||||
* 1. <b>Counting Events:</b>
|
||||
* In this usage scenario an event handler will 'give' a semaphore each time an
|
||||
* event occurs (incrementing the semaphore count value), and a handler task
|
||||
* will 'take' a semaphore each time it processes an event (decrementing the
|
||||
* semaphore count value). The count value is therefore the difference between
|
||||
* the number of events that have occurred and the number that have been
|
||||
* processed. In this case it is desirable for the initial count value to be
|
||||
* zero. Note the same functionality can often be achieved in a more efficient
|
||||
* way using a direct to task notification.
|
||||
*
|
||||
* 2. <b>Resource Management:</b>
|
||||
* In this usage scenario the count value indicates the number of resources
|
||||
* available. To obtain control of a resource a task must first obtain a
|
||||
* semaphore - decrementing the semaphore count value. When the count value
|
||||
* reaches zero there are no free resources. When a task finishes with the
|
||||
* resource it 'gives' the semaphore back - incrementing the semaphore count
|
||||
* value. In this case it is desirable for the initial count value to be equal
|
||||
* to the maximum count value, indicating that all resources are free.
|
||||
*/
|
||||
class CountingSemaphore : public SemaphoreBase {
|
||||
public:
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Construct a new CountingSemaphore by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
|
||||
* UBaseType_t uxInitialCount)</tt>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* binary semaphore was created successfully in case the memory required to
|
||||
* create the queue could not be allocated.
|
||||
*
|
||||
* @param maxCount The maximum count value that can be reached. When the
|
||||
* semaphore reaches this value it can no longer be 'given'.
|
||||
* @param initialCount The count value assigned to the semaphore when
|
||||
* it is created.
|
||||
*/
|
||||
explicit CountingSemaphore(const UBaseType_t maxCount,
|
||||
const UBaseType_t initialCount = 0) {
|
||||
this->handle = xSemaphoreCreateCounting(maxCount, initialCount);
|
||||
}
|
||||
~CountingSemaphore() = default;
|
||||
|
||||
CountingSemaphore(const CountingSemaphore&) = delete;
|
||||
CountingSemaphore& operator=(const CountingSemaphore&) = delete;
|
||||
|
||||
CountingSemaphore(CountingSemaphore&&) noexcept = default;
|
||||
CountingSemaphore& operator=(CountingSemaphore&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StaticBinarySemaphore Semaphore.hpp <FreeRTOS/Semaphore.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS binary
|
||||
* semaphore.
|
||||
*
|
||||
* Each binary semaphore require a small amount of RAM that is used to hold the
|
||||
* semaphore's state. If a binary semaphore is created using
|
||||
* FreeRTOS::BinarySemaphore then the required RAM is automatically allocated
|
||||
* from the FreeRTOS heap. If a binary semaphore is created using
|
||||
* FreeRTOS::StaticBinarySemaphore then the RAM is provided by the application
|
||||
* writer as part of the class and allows the RAM to be statically allocated at
|
||||
* compile time. See the Static Vs Dynamic allocation page for more information.
|
||||
*
|
||||
* The semaphore is created in the 'empty' state, meaning the semaphore must
|
||||
* first be given using the give() API function before it can subsequently be
|
||||
* taken (obtained) using the take() function.
|
||||
*
|
||||
* Binary semaphores and mutexes are very similar but have some subtle
|
||||
* differences: Mutexes include a priority inheritance mechanism, binary
|
||||
* semaphores do not. This makes binary semaphores the better choice for
|
||||
* implementing synchronisation (between tasks or between tasks and an
|
||||
* interrupt), and mutexes the better choice for implementing simple mutual
|
||||
* exclusion.
|
||||
*
|
||||
* A binary semaphore need not be given back once obtained, so task
|
||||
* synchronisation can be implemented by one task/interrupt continuously
|
||||
* 'giving' the semaphore while another continuously 'takes' the semaphore. This
|
||||
* is demonstrated by the sample code on the giveFromISR() documentation page.
|
||||
* Note the same functionality can often be achieved in a more efficient way
|
||||
* using a direct to task notification.
|
||||
*
|
||||
* The priority of a task that 'takes' a mutex can potentially be raised if
|
||||
* another task of higher priority attempts to obtain the same mutex. The task
|
||||
* that owns the mutex 'inherits' the priority of the task attempting to 'take'
|
||||
* the same mutex. This means the mutex must always be 'given' back - otherwise
|
||||
* the higher priority task will never be able to obtain the mutex, and the
|
||||
* lower priority task will never 'disinherit' the priority. An example of a
|
||||
* mutex being used to implement mutual exclusion is provided on the take()
|
||||
* documentation page.
|
||||
*/
|
||||
class StaticBinarySemaphore : public SemaphoreBase {
|
||||
public:
|
||||
/**
|
||||
* Semaphore.hpp
|
||||
*
|
||||
* @brief Construct a new StaticBinarySemaphore object by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t
|
||||
* *pxSemaphoreBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreCreateBinaryStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the binary semaphore,
|
||||
* so the user should create this object as a global object or with the static
|
||||
* storage specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Semaphore/staticBinarySemaphore.cpp
|
||||
*/
|
||||
StaticBinarySemaphore() {
|
||||
this->handle = xSemaphoreCreateBinaryStatic(&staticBinarySemaphore);
|
||||
}
|
||||
~StaticBinarySemaphore() = default;
|
||||
|
||||
StaticBinarySemaphore(const StaticBinarySemaphore&) = delete;
|
||||
StaticBinarySemaphore& operator=(const StaticBinarySemaphore&) = delete;
|
||||
|
||||
StaticBinarySemaphore(StaticBinarySemaphore&&) noexcept = default;
|
||||
StaticBinarySemaphore& operator=(StaticBinarySemaphore&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticSemaphore_t staticBinarySemaphore;
|
||||
};
|
||||
|
||||
class StaticCountingSemaphore : public SemaphoreBase {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new StaticCountingSemaphore object by calling
|
||||
* <tt>SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t
|
||||
* uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t
|
||||
* *pxSemaphoreBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xSemaphoreCreateCountingStatic.html>
|
||||
*
|
||||
* @warning This class contains the storage buffer for the counting semaphore,
|
||||
* so the user should create this object as a global object or with the static
|
||||
* storage specifier so that the object instance is not on the stack.
|
||||
*
|
||||
* @param maxCount The maximum count value that can be reached. When the
|
||||
* semaphore reaches this value it can no longer be 'given'.
|
||||
* @param initialCount The count value assigned to the semaphore when it is
|
||||
* created.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Semaphore/staticCountingSemaphore.cpp
|
||||
*/
|
||||
explicit StaticCountingSemaphore(const UBaseType_t maxCount,
|
||||
const UBaseType_t initialCount = 0) {
|
||||
this->handle = xSemaphoreCreateCountingStatic(maxCount, initialCount,
|
||||
&staticCountingSemaphore);
|
||||
}
|
||||
~StaticCountingSemaphore() = default;
|
||||
|
||||
StaticCountingSemaphore(const StaticCountingSemaphore&) = delete;
|
||||
StaticCountingSemaphore& operator=(const StaticCountingSemaphore&) = delete;
|
||||
|
||||
StaticCountingSemaphore(StaticCountingSemaphore&&) noexcept = default;
|
||||
StaticCountingSemaphore& operator=(StaticCountingSemaphore&&) noexcept =
|
||||
default;
|
||||
|
||||
private:
|
||||
StaticSemaphore_t staticCountingSemaphore;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_SEMAPHORE_HPP
|
||||
566
source/shoh/src/FreeRTOSCPP/StreamBuffer.hpp
Normal file
566
source/shoh/src/FreeRTOSCPP/StreamBuffer.hpp
Normal file
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_STREAMBUFFER_HPP
|
||||
#define FREERTOS_STREAMBUFFER_HPP
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "stream_buffer.h"
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class StreamBufferBase StreamBuffer.hpp <FreeRTOS/StreamBuffer.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard stream buffer interface to
|
||||
* FreeRTOS::StreamBuffer and FreeRTOS::StaticStreamBuffer.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. Use
|
||||
* FreeRTOS::StreamBuffer or FreeRTOS::StaticStreamBuffer.
|
||||
*
|
||||
* @warning Uniquely among FreeRTOS objects, the stream buffer implementation
|
||||
* (so also the message buffer implementation, as message buffers are built on
|
||||
* top of stream buffers) assumes there is only one task or interrupt that will
|
||||
* write to the buffer (the writer), and only one task or interrupt that will
|
||||
* read from the buffer (the reader). It is safe for the writer and reader to
|
||||
* be different tasks or interrupts, but, unlike other FreeRTOS objects, it is
|
||||
* not safe to have multiple different writers or multiple different readers. If
|
||||
* there are to be multiple different writers then the application writer must
|
||||
* place each call to a writing API function (such as send()) inside a critical
|
||||
* section and set the send block time to 0. Likewise, if there are to be
|
||||
* multiple different readers then the application writer must place each call
|
||||
* to a reading API function (such as read()) inside a critical section and set
|
||||
* the receive block time to 0.
|
||||
*/
|
||||
class StreamBufferBase {
|
||||
public:
|
||||
friend class StreamBuffer;
|
||||
template <size_t>
|
||||
friend class StaticStreamBuffer;
|
||||
|
||||
StreamBufferBase(const StreamBufferBase&) = delete;
|
||||
StreamBufferBase& operator=(const StreamBufferBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that checks if the underlying stream buffer handle is not
|
||||
* NULL. This should be used to ensure a stream buffer has been created
|
||||
* correctly.
|
||||
*
|
||||
* @retval true If the handle is not NULL.
|
||||
* @retval false If the handle is NULL.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferSend(
|
||||
* StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t
|
||||
* xDataLengthBytes, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferSend.html>
|
||||
*
|
||||
* Sends bytes to a stream buffer. The bytes are copied into the stream
|
||||
* buffer.
|
||||
*
|
||||
* Use send() to write to a stream buffer from a task. Use sendFromISR() to
|
||||
* write to a stream buffer from an interrupt service routine (ISR).
|
||||
*
|
||||
* @param data A pointer to the buffer that holds the bytes to be copied into
|
||||
* the stream buffer.
|
||||
* @param length The maximum number of bytes to copy from data into the stream
|
||||
* buffer.
|
||||
* @param ticksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for enough space to become available in the stream
|
||||
* buffer, should the stream buffer contain too little space to hold the
|
||||
* another length bytes. The block time is specified in tick periods, so the
|
||||
* absolute time it represents is dependent on the tick frequency. The macro
|
||||
* pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
|
||||
* into a time specified in ticks. Setting ticksToWait to portMAX_DELAY will
|
||||
* cause the task to wait indefinitely (without timing out), provided
|
||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out
|
||||
* before it can write all length into the buffer it will still write as many
|
||||
* bytes as possible. A task does not use any CPU time when it is in the
|
||||
* blocked state.
|
||||
* @return size_t The number of bytes written to the stream buffer. If a task
|
||||
* times out before it can write all length into the buffer it will still
|
||||
* write as many bytes as possible.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include StreamBuffer/send.cpp
|
||||
*/
|
||||
inline size_t send(const void* data, const size_t length,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return xStreamBufferSend(handle, data, length, ticksToWait);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferSendFromISR(
|
||||
* StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t
|
||||
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferSendFromISR.html>
|
||||
*
|
||||
* Interrupt safe version of the API function that sends a stream of bytes to
|
||||
* the stream buffer.
|
||||
*
|
||||
* Use send() to write to a stream buffer from a task. Use sendFromISR() to
|
||||
* write to a stream buffer from an interrupt service routine (ISR).
|
||||
*
|
||||
* @param higherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for data. Calling sendFromISR() can make
|
||||
* data available, and so cause a task that was waiting for data to leave the
|
||||
* Blocked state. If calling sendFromISR() causes a task to leave the Blocked
|
||||
* state, and the unblocked task has a priority higher than the currently
|
||||
* executing task (the task that was interrupted), then, internally,
|
||||
* sendFromISR() will set higherPriorityTaskWoken to true. If sendFromISR()
|
||||
* sets this value to true, then normally a context switch should be performed
|
||||
* before the interrupt is exited. This will ensure that the interrupt
|
||||
* returns directly to the highest priority Ready state task.
|
||||
* higherPriorityTaskWoken should be set to false before it is passed into the
|
||||
* function. See the example code below for an example.
|
||||
* @param data A pointer to the buffer that holds the bytes to be copied into
|
||||
* the stream buffer.
|
||||
* @param length The maximum number of bytes to copy from data into the stream
|
||||
* buffer.
|
||||
* @return size_t The number of bytes written to the stream buffer. If a task
|
||||
* times out before it can write all length into the buffer it will still
|
||||
* write as many bytes as possible.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include StreamBuffer/sendFromISR.cpp
|
||||
*/
|
||||
inline size_t sendFromISR(bool& higherPriorityTaskWoken, const void* data,
|
||||
const size_t length) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
size_t result = xStreamBufferSendFromISR(handle, data, length, &taskWoken);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferSendFromISR(
|
||||
* StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t
|
||||
* xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferSendFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline size_t sendFromISR(const void* data, const size_t length) const {
|
||||
return xStreamBufferSendFromISR(handle, data, length, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferReceive(
|
||||
* StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t
|
||||
* xBufferLengthBytes, TickType_t xTicksToWait )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferReceive.html>
|
||||
*
|
||||
* Receives bytes from a stream buffer.
|
||||
*
|
||||
* Use receive() to read from a stream buffer from a task. Use
|
||||
* receiveFromISR() to read from a stream buffer from an interrupt service
|
||||
* routine (ISR).
|
||||
*
|
||||
* @param buffer A pointer to the buffer into which the received bytes will be
|
||||
* copied.
|
||||
* @param bufferLength The length of the buffer pointed to by the data
|
||||
* parameter. This sets the maximum number of bytes to receive in one call.
|
||||
* receive() will return as many bytes as possible up to a maximum set by
|
||||
* length.
|
||||
* @param ticksToWait The maximum amount of time the task should remain in the
|
||||
* Blocked state to wait for data to become available if the stream buffer is
|
||||
* empty. receive() will return immediately if ticksToWait is zero. The block
|
||||
* time is specified in tick periods, so the absolute time it represents is
|
||||
* dependent on the tick frequency. The macro pdMS_TO_TICKS() can be used to
|
||||
* convert a time specified in milliseconds into a time specified in ticks.
|
||||
* Setting ticksToWait to portMAX_DELAY will cause the task to wait
|
||||
* indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to
|
||||
* 1 in FreeRTOSConfig.h. A task does not use any CPU time when it is in the
|
||||
* Blocked state.
|
||||
* @return size_t The number of bytes read from the stream buffer. This will
|
||||
* be the number of bytes available up to a maximum of length.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include StreamBuffer/receive.cpp
|
||||
*/
|
||||
inline size_t receive(void* buffer, const size_t bufferLength,
|
||||
const TickType_t ticksToWait = portMAX_DELAY) const {
|
||||
return xStreamBufferReceive(handle, buffer, bufferLength, ticksToWait);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferReceiveFromISR(
|
||||
* StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t
|
||||
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferReceiveFromISR.html>
|
||||
*
|
||||
* An interrupt safe version of the API function that receives bytes from a
|
||||
* stream buffer.
|
||||
*
|
||||
* Use receive() to read from a stream buffer from a task. Use
|
||||
* receiveFromISR() to read from a stream buffer from an interrupt service
|
||||
* routine (ISR).
|
||||
*
|
||||
* @param higherPriorityTaskWoken It is possible that a stream buffer will
|
||||
* have a task blocked on it waiting for space to become available. Calling
|
||||
* receiveFromISR() can make space available, and so cause a task that is
|
||||
* waiting for space to leave the Blocked state. If calling receiveFromISR()
|
||||
* causes a task to leave the Blocked state, and the unblocked task has a
|
||||
* priority higher than the currently executing task (the task that was
|
||||
* interrupted), then, internally, receiveFromISR() will set
|
||||
* higherPriorityTaskWoken to true. If receiveFromISR() sets this value to
|
||||
* true, then normally a context switch should be performed before the
|
||||
* interrupt is exited. That will ensure the interrupt returns directly to the
|
||||
* highest priority Ready state task. higherPriorityTaskWoken should be set to
|
||||
* false before it is passed into the function. See the code example below for
|
||||
* an example.
|
||||
* @param buffer A pointer to the buffer into which the received bytes will be
|
||||
* copied.
|
||||
* @param bufferLength The length of the buffer pointed to by the buffer
|
||||
* parameter. This sets the maximum number of bytes to receive in one call.
|
||||
* receive() will return as many bytes as possible up to a maximum set by
|
||||
* length.
|
||||
* @return size_t The number of bytes read from the stream buffer, if any.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include StreamBuffer/receiveFromISR.cpp
|
||||
*/
|
||||
inline size_t receiveFromISR(bool& higherPriorityTaskWoken, void* buffer,
|
||||
const size_t bufferLength) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
size_t result =
|
||||
xStreamBufferReceiveFromISR(handle, buffer, bufferLength, &taskWoken);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferReceiveFromISR(
|
||||
* StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t
|
||||
* xBufferLengthBytes, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferReceiveFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline size_t receiveFromISR(void* buffer, const size_t bufferLength) const {
|
||||
return xStreamBufferReceiveFromISR(handle, buffer, bufferLength, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferBytesAvailable(
|
||||
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferBytesAvailable.html>
|
||||
*
|
||||
* Queries the stream buffer to see how much data it contains, which is equal
|
||||
* to the number of bytes that can be read from the stream buffer before the
|
||||
* stream buffer would be empty.
|
||||
*
|
||||
* @return size_t The number of bytes that can be read from the stream buffer
|
||||
* before the stream buffer would be empty.
|
||||
*/
|
||||
inline size_t bytesAvailable() const {
|
||||
return xStreamBufferBytesAvailable(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>size_t xStreamBufferSpacesAvailable(
|
||||
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferSpacesAvailable.html>
|
||||
*
|
||||
* Queries a stream buffer to see how much free space it contains, which is
|
||||
* equal to the amount of data that can be sent to the stream buffer before it
|
||||
* is full.
|
||||
*
|
||||
* @return size_t The number of bytes that can be written to the stream buffer
|
||||
* before the stream buffer would be full.
|
||||
*/
|
||||
inline size_t spacesAvailable() const {
|
||||
return xStreamBufferSpacesAvailable(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xStreamBufferSetTriggerLevel(
|
||||
* StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferSetTriggerLevel.html>
|
||||
*
|
||||
* A stream buffer's trigger level is the number of bytes that must be in the
|
||||
* stream buffer before a task that is blocked on the stream buffer to wait
|
||||
* for data is moved out of the blocked state. For example, if a task is
|
||||
* blocked on a read of an empty stream buffer that has a trigger level of 1
|
||||
* then the task will be unblocked when a single byte is written to the buffer
|
||||
* or the task's block time expires. As another example, if a task is blocked
|
||||
* on a read of an empty stream buffer that has a trigger level of 10 then the
|
||||
* task will not be unblocked until the stream buffer contains at least 10
|
||||
* bytes or the task's block time expires. If a reading task's block time
|
||||
* expires before the trigger level is reached then the task will still
|
||||
* receive however many bytes are actually available. Setting a trigger level
|
||||
* of 0 will result in a trigger level of 1 being used. It is not valid to
|
||||
* specify a trigger level that is greater than the buffer size.
|
||||
*
|
||||
* @param triggerLevel The new trigger level for the stream buffer.
|
||||
* @retval true If triggerLevel was less than or equal to the stream buffer's
|
||||
* length then the trigger level was updated.
|
||||
* @retval false Otherwise.
|
||||
*/
|
||||
inline bool setTriggerLevel(const size_t triggerLevel = 0) const {
|
||||
return (xStreamBufferSetTriggerLevel(handle, triggerLevel) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xStreamBufferReset(
|
||||
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferReset.html>
|
||||
*
|
||||
* Resets a stream buffer to its initial, empty, state. Any data that was in
|
||||
* the stream buffer is discarded. A stream buffer can only be reset if there
|
||||
* are no tasks blocked waiting to either send to or receive from the stream
|
||||
* buffer.
|
||||
*
|
||||
* @return true If the stream buffer is reset.
|
||||
* @return false If there was a task blocked waiting to send to or read from
|
||||
* the stream buffer then the stream buffer was not reset.
|
||||
*/
|
||||
inline bool reset() const { return (xStreamBufferReset(handle) == pdPASS); }
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xStreamBufferIsEmpty(
|
||||
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferIsEmpty.html>
|
||||
*
|
||||
* Queries a stream buffer to see if it is empty. A stream buffer is empty if
|
||||
* it does not contain any data.
|
||||
*
|
||||
* @return true If the stream buffer is empty.
|
||||
* @return false Otherwise.
|
||||
*/
|
||||
inline bool isEmpty() const {
|
||||
return (xStreamBufferIsEmpty(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xStreamBufferIsFull(
|
||||
* StreamBufferHandle_t xStreamBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferIsFull.html>
|
||||
*
|
||||
* Queries a stream buffer to see if it is full. A stream buffer is full if it
|
||||
* does not have any free space, and therefore cannot accept any more data.
|
||||
*
|
||||
* @return true If the stream buffer is full.
|
||||
* @return false Otherwise.
|
||||
*/
|
||||
inline bool isFull() const { return (xStreamBufferIsFull(handle) == pdTRUE); }
|
||||
|
||||
private:
|
||||
StreamBufferBase() = default;
|
||||
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Destroy the StreamBufferBase object by calling
|
||||
* <tt>void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/vStreamBufferDelete.html>
|
||||
*
|
||||
* Deletes a stream buffer and free the allocated memory.
|
||||
*/
|
||||
~StreamBufferBase() { vStreamBufferDelete(this->handle); }
|
||||
|
||||
StreamBufferBase(StreamBufferBase&&) noexcept = default;
|
||||
StreamBufferBase& operator=(StreamBufferBase&&) noexcept = default;
|
||||
|
||||
StreamBufferHandle_t handle = NULL;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StreamBuffer StreamBuffer.hpp <FreeRTOS/StreamBuffer.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS stream buffer.
|
||||
*
|
||||
* A stream buffer using dynamically allocated memory from the FreeRTOS heap.
|
||||
* See FreeRTOS::StaticStreamBuffer for a version that uses statically allocated
|
||||
* memory (memory that is allocated at compile time).
|
||||
*/
|
||||
class StreamBuffer : public StreamBufferBase {
|
||||
public:
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Construct a new StreamBuffer object by calling
|
||||
* <tt>StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes,
|
||||
* size_t xTriggerLevelBytes )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferCreate.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* stream buffer was created successfully in case the memory required to
|
||||
* create the message buffer could not be allocated.
|
||||
*
|
||||
* @param size The total number of bytes the stream buffer will be able to
|
||||
* hold at any one time.
|
||||
* @param triggerLevel The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data
|
||||
* is moved out of the blocked state. For example, if a task is blocked on a
|
||||
* read of an empty stream buffer that has a trigger level of 1 then the task
|
||||
* will be unblocked when a single byte is written to the buffer or the task's
|
||||
* block time expires. As another example, if a task is blocked on a read of
|
||||
* an empty stream buffer that has a trigger level of 10 then the task will
|
||||
* not be unblocked until the stream buffer contains at least 10 bytes or the
|
||||
* task's block time expires. If a reading task's block time expires before
|
||||
* the trigger level is reached then the task will still receive however many
|
||||
* bytes are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include StreamBuffer/streamBuffer.cpp
|
||||
*/
|
||||
explicit StreamBuffer(const size_t size, const size_t triggerLevel = 0) {
|
||||
this->handle = xStreamBufferCreate(size, triggerLevel);
|
||||
}
|
||||
~StreamBuffer() = default;
|
||||
|
||||
StreamBuffer(const StreamBuffer&) = delete;
|
||||
StreamBuffer& operator=(const StreamBuffer&) = delete;
|
||||
|
||||
StreamBuffer(StreamBuffer&&) noexcept = default;
|
||||
StreamBuffer& operator=(StreamBuffer&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* @class StaticStreamBuffer StreamBuffer.hpp <FreeRTOS/StreamBuffer.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS stream buffer.
|
||||
*
|
||||
* If a stream buffer is created using this class then the RAM is provided by
|
||||
* the application writer as part of the object instance and allows the RAM to
|
||||
* be statically allocated at compile time.
|
||||
*
|
||||
* @tparam N The size, in bytes, of the storage buffer for the stream buffer.
|
||||
*/
|
||||
template <size_t N>
|
||||
class StaticStreamBuffer : public StreamBufferBase {
|
||||
public:
|
||||
/**
|
||||
* StreamBuffer.hpp
|
||||
*
|
||||
* @brief Construct a new StaticStreamBuffer object by calling
|
||||
* <tt>StreamBufferHandle_t xStreamBufferCreateStatic( size_t
|
||||
* xBufferSizeBytes, size_t xTriggerLevelBytes, uint8_t
|
||||
* *pucStreamBufferStorageArea, StaticStreamBuffer_t *pxStaticStreamBuffer
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xStreamBufferCreateStatic.html>
|
||||
*
|
||||
* @param triggerLevel The number of bytes that must be in the stream
|
||||
* buffer before a task that is blocked on the stream buffer to wait for data
|
||||
* is moved out of the blocked state. For example, if a task is blocked on a
|
||||
* read of an empty stream buffer that has a trigger level of 1 then the task
|
||||
* will be unblocked when a single byte is written to the buffer or the task's
|
||||
* block time expires. As another example, if a task is blocked on a read of
|
||||
* an empty stream buffer that has a trigger level of 10 then the task will
|
||||
* not be unblocked until the stream buffer contains at least 10 bytes or the
|
||||
* task's block time expires. If a reading task's block time expires before
|
||||
* the trigger level is reached then the task will still receive however many
|
||||
* bytes are actually available. Setting a trigger level of 0 will result in a
|
||||
* trigger level of 1 being used. It is not valid to specify a trigger level
|
||||
* that is greater than the buffer size.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include StreamBuffer/staticStreamBuffer.cpp
|
||||
*/
|
||||
explicit StaticStreamBuffer(const size_t triggerLevel = 0) {
|
||||
this->handle = xStreamBufferCreateStatic(sizeof(storage), triggerLevel,
|
||||
storage, &staticStreamBuffer);
|
||||
}
|
||||
~StaticStreamBuffer() = default;
|
||||
|
||||
StaticStreamBuffer(const StaticStreamBuffer&) = delete;
|
||||
StaticStreamBuffer& operator=(const StaticStreamBuffer&) = delete;
|
||||
|
||||
StaticStreamBuffer(StaticStreamBuffer&&) noexcept = default;
|
||||
StaticStreamBuffer& operator=(StaticStreamBuffer&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticStreamBuffer_t staticStreamBuffer;
|
||||
uint8_t storage[N];
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
#endif // FREERTOS_STREAMBUFFER_HPP
|
||||
1480
source/shoh/src/FreeRTOSCPP/Task.hpp
Normal file
1480
source/shoh/src/FreeRTOSCPP/Task.hpp
Normal file
File diff suppressed because it is too large
Load Diff
928
source/shoh/src/FreeRTOSCPP/Timer.hpp
Normal file
928
source/shoh/src/FreeRTOSCPP/Timer.hpp
Normal file
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
* FreeRTOS-Cpp
|
||||
* Copyright (C) 2021 Jon Enz. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* https://github.com/jonenz/FreeRTOS-Cpp
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_TIMER_HPP
|
||||
#define FREERTOS_TIMER_HPP
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "timers.h"
|
||||
|
||||
/**
|
||||
* @brief C function that is used to interface this class with the FreeRTOS
|
||||
* kernel.
|
||||
*
|
||||
* @note This function should not be called or referenced by the user.
|
||||
*
|
||||
* @param task Pointer to an instance of FreeRTOS::TimerBase.
|
||||
*/
|
||||
void callTimerFunction(TimerHandle_t timer);
|
||||
|
||||
namespace FreeRTOS {
|
||||
|
||||
/**
|
||||
* @class TimerBase Timer.hpp <FreeRTOS/Timer.hpp>
|
||||
*
|
||||
* @brief Base class that provides the standard task interface to
|
||||
* FreeRTOS::Timer and FreeRTOS::StaticTimer.
|
||||
*
|
||||
* @note This class is not intended to be instantiated or derived from by the
|
||||
* user. Use FreeRTOS::Timer or FreeRTOS::StaticTimer as a base class for a user
|
||||
* implemented task.
|
||||
*/
|
||||
class TimerBase {
|
||||
public:
|
||||
friend class Timer;
|
||||
friend class StaticTimer;
|
||||
|
||||
TimerBase(const TimerBase&) = delete;
|
||||
TimerBase& operator=(const TimerBase&) = delete;
|
||||
|
||||
static void* operator new(size_t, void* ptr) { return ptr; }
|
||||
static void* operator new[](size_t, void* ptr) { return ptr; }
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new[](size_t) = delete;
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that acts as the entry point of the timer instance.
|
||||
*
|
||||
* @note This function is only public so that it can be accessed by the C
|
||||
* interface function <tt>callTimerFunction()</tt> and should not be called or
|
||||
* referenced by the user.
|
||||
*/
|
||||
virtual inline void timerEntry() final { timerFunction(); }
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that checks the value of the timer handle. This function
|
||||
* should be called to ensure the timer was created successfully.
|
||||
*
|
||||
* @return true If the timer was created successfully.
|
||||
* @return false If the timer was not created successfully due to insufficient
|
||||
* memory.
|
||||
*/
|
||||
inline bool isValid() const { return (handle != NULL); }
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerIsTimerActive(
|
||||
* TimerHandle_t xTimer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerIsTimerActive.html>
|
||||
*
|
||||
* Queries a software timer to see if it is active or dormant.
|
||||
*
|
||||
* A timer will be dormant if:
|
||||
* -# It has been created but not started, or
|
||||
* -# It is an expired one-shot timer that has not been restarted.
|
||||
*
|
||||
* @note Timers are created in the dormant state. The start(), reset(),
|
||||
* startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR()
|
||||
* API functions can all be used to transition a timer into the active state.
|
||||
*
|
||||
* @return false If the timer is dormant.
|
||||
* @return true Otherwise.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/isActive.cpp
|
||||
*/
|
||||
inline bool isActive() const {
|
||||
return (xTimerIsTimerActive(handle) != pdFALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerStart( TimerHandle_t
|
||||
* xTimer, TickType_t xBlockTime )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStart.html>
|
||||
*
|
||||
* start() starts a timer. If the timer had already been started and was
|
||||
* already in the active state, then start() has equivalent functionality to
|
||||
* the reset() API function.
|
||||
*
|
||||
* Starting a timer ensures the timer is in the active state. If the timer is
|
||||
* not stopped, deleted, or reset in the mean time, timerFunction() will get
|
||||
* called 'n 'ticks after start() was called, where 'n' is the timers defined
|
||||
* period.
|
||||
*
|
||||
* It is valid to call start() before the RTOS scheduler has been started, but
|
||||
* when this is done the timer will not actually start until the RTOS
|
||||
* scheduler is started, and the timers expiry time will be relative to when
|
||||
* the RTOS scheduler is started, not relative to when start() was called.
|
||||
*
|
||||
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||
* be held in the Blocked state to wait for the start command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when start() was called. blockTime is ignored if start() is called
|
||||
* before the RTOS scheduler is started.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system,
|
||||
* although the timers expiry time is relative to when start() is actually
|
||||
* called. The timer service/daemon task priority is set by the
|
||||
* configTIMER_TASK_PRIORITY configuration constant.
|
||||
* @return false If the start command could not be sent to the timer command
|
||||
* queue even after blockTime ticks had passed.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/timer.cpp
|
||||
*/
|
||||
inline bool start(const TickType_t blockTime = 0) const {
|
||||
return (xTimerStart(handle, blockTime) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerStartFromISR( TimerHandle_t
|
||||
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStartFromISR.html>
|
||||
*
|
||||
* A version of start() that can be called from an interrupt service routine.
|
||||
*
|
||||
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||
* command queue. Calling startFromISR() writes a message to the timer command
|
||||
* queue, so has the potential to transition the timer service/daemon task out
|
||||
* of the Blocked state. If calling startFromISR() causes the timer
|
||||
* service/daemon task to leave the Blocked state, and the timer service/
|
||||
* daemon task has a priority equal to or greater than the currently executing
|
||||
* task (the task that was interrupted), then higherPriorityTaskWoken will get
|
||||
* set to true internally within the startFromISR() function. If
|
||||
* startFromISR() sets this value to true, then a context switch should be
|
||||
* performed before the interrupt exits.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system,
|
||||
* although the timers expiry time is relative to when startFromISR() is
|
||||
* actually called. The timer service/daemon task priority is set by the
|
||||
* configTIMER_TASK_PRIORITY configuration constant.
|
||||
* @return false If the start command could not be sent to the timer command
|
||||
* queue.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/startFromISR.cpp
|
||||
*/
|
||||
inline bool startFromISR(bool& higherPriorityTaskWoken) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xTimerStartFromISR(handle, &taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerStartFromISR( TimerHandle_t
|
||||
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStartFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool startFromISR() const {
|
||||
return (xTimerStartFromISR(handle, NULL) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerStop( TimerHandle_t xTimer,
|
||||
* TickType_t xBlockTime )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStop.html>
|
||||
*
|
||||
* stop() stops a timer that was previously started using either of the
|
||||
* start(), reset(), startFromISR(), resetFromISR(), changePeriod() and
|
||||
* changePeriodFromISR() API functions.
|
||||
*
|
||||
* Stopping a timer ensures the timer is not in the active state.
|
||||
*
|
||||
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||
* be held in the Blocked state to wait for the stop command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when stop() was called. blockTime is ignored if stop() is called
|
||||
* before the RTOS scheduler is started.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system. The
|
||||
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||
* configuration constant.
|
||||
* @return false If the stop command could not be sent to the timer command
|
||||
* queue even after blockTime ticks had passed.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/timer.cpp
|
||||
*/
|
||||
inline bool stop(const TickType_t blockTime = 0) const {
|
||||
return (xTimerStop(handle, blockTime) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerStopFromISR( TimerHandle_t
|
||||
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStopFromISR.html>
|
||||
*
|
||||
* A version of stop() that can be called from an interrupt service routine.
|
||||
*
|
||||
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||
* command queue. Calling stopFromISR() writes a message to the timer command
|
||||
* queue, so has the potential to transition the timer service/daemon task out
|
||||
* of the Blocked state. If calling stopFromISR() causes the timer
|
||||
* service/daemon task to leave the Blocked state, and the timer service/
|
||||
* daemon task has a priority equal to or greater than the currently executing
|
||||
* task (the task that was interrupted), then higherPriorityTaskWoken will get
|
||||
* set to true internally within the stopFromISR() function. If stopFromISR()
|
||||
* sets this value to true, then a context switch should be performed before
|
||||
* the interrupt exits.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system. The
|
||||
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||
* configuration constant.
|
||||
* @return false If the start command could not be sent to the timer command
|
||||
* queue.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/stopFromISR.cpp
|
||||
*/
|
||||
inline bool stopFromISR(bool& higherPriorityTaskWoken) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xTimerStopFromISR(handle, &taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerStopFromISR( TimerHandle_t
|
||||
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerStopFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool stopFromISR() const {
|
||||
return (xTimerStopFromISR(handle, NULL) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerChangePeriod( TimerHandle_t
|
||||
* xTimer, TickType_t xNewPeriod, TickType_t xBlockTime )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerChangePeriod.html>
|
||||
*
|
||||
* changePeriod() changes the period of a timer.
|
||||
*
|
||||
* changePeriod() can be called to change the period of an active or dormant
|
||||
* state timer. Changing the period of a dormant timers will also start the
|
||||
* timer.
|
||||
*
|
||||
* @param newPeriod The new period for timer. Timer periods are specified in
|
||||
* tick periods, so the constant portTICK_PERIOD_MS can be used to convert a
|
||||
* time that has been specified in milliseconds. For example, if the timer
|
||||
* must expire after 100 ticks, then newPeriod should be set to 100.
|
||||
* Alternatively, if the timer must expire after 500ms, then newPeriod can be
|
||||
* set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less
|
||||
* than or equal to 1000.
|
||||
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||
* be held in the Blocked state to wait for the change period command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when changePeriod() was called. blockTime is ignored if changePeriod()
|
||||
* is called before the RTOS scheduler is started.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system. The
|
||||
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||
* configuration constant.
|
||||
* @return false If the change period command could not be sent to the timer
|
||||
* command queue even after blockTime ticks had passed.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/changePeriod.cpp
|
||||
*/
|
||||
inline bool changePeriod(const TickType_t newPeriod,
|
||||
const TickType_t blockTime = 0) const {
|
||||
return (xTimerChangePeriod(handle, newPeriod, blockTime) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerChangePeriodFromISR(
|
||||
* TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t
|
||||
* *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see
|
||||
* <https://www.freertos.org/FreeRTOS-timers-xTimerChangePeriodFromISR.html>
|
||||
*
|
||||
* A version of changePeriod() that can be called from an interrupt service
|
||||
* routine.
|
||||
*
|
||||
* @param newPeriod The new period for timer. Timer periods are specified in
|
||||
* tick periods, so the constant portTICK_PERIOD_MS can be used to convert a
|
||||
* time that has been specified in milliseconds. For example, if the timer
|
||||
* must expire after 100 ticks, then newPeriod should be set to 100.
|
||||
* Alternatively, if the timer must expire after 500ms, then newPeriod can be
|
||||
* set to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less
|
||||
* than or equal to 1000.
|
||||
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||
* command queue. Calling changePeriodFromISR() writes a message to the timer
|
||||
* command queue, so has the potential to transition the timer service/ daemon
|
||||
* task out of the Blocked state. If calling changePeriodFromISR() causes the
|
||||
* timer service/daemon task to leave the Blocked state, and the timer
|
||||
* service/daemon task has a priority equal to or greater than the currently
|
||||
* executing task (the task that was interrupted), then
|
||||
* higherPriorityTaskWoken will get set to true internally within the
|
||||
* changePeriodFromISR() function. If changePeriodFromISR() sets this value to
|
||||
* true, then a context switch should be performed before the interrupt exits.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system. The
|
||||
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||
* configuration constant.
|
||||
* @return false If the change period command could not be sent to the timer
|
||||
* command queue.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/changePeriodFromISR.cpp
|
||||
*/
|
||||
inline bool changePeriodFromISR(bool& higherPriorityTaskWoken,
|
||||
const TickType_t newPeriod) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result =
|
||||
(xTimerChangePeriodFromISR(handle, newPeriod, &taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerChangePeriodFromISR(
|
||||
* TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t
|
||||
* *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see
|
||||
* <https://www.freertos.org/FreeRTOS-timers-xTimerChangePeriodFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool changePeriodFromISR(const TickType_t newPeriod) const {
|
||||
return (xTimerChangePeriodFromISR(handle, newPeriod, NULL) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerDelete( TimerHandle_t
|
||||
* xTimer, TickType_t xBlockTime )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerDelete.html>
|
||||
*
|
||||
* deleteTimer() deletes a timer from the FreeRTOS timer task.
|
||||
*
|
||||
* @note This function is also called in the destructor of the timer using the
|
||||
* deleteBlockTime specified when the object was created. This function
|
||||
* should be used when the user wants to delete the timer from the FreeRTOS
|
||||
* timer task without destroying the timer object or with a different block
|
||||
* time than what was specified in the constructor.
|
||||
*
|
||||
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||
* be held in the Blocked state to wait for the delete command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when deleteTimer() was called. blockTime is ignored if deleteTimer()
|
||||
* is called before the RTOS scheduler is started.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system. The
|
||||
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||
* configuration constant.
|
||||
* @return false If the delete command could not be sent to the timer command
|
||||
* queue even after blockTime ticks had passed.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/changePeriod.cpp
|
||||
*/
|
||||
inline bool deleteTimer(const TickType_t blockTime = 0) {
|
||||
if (xTimerDelete(handle, blockTime) == pdPASS) {
|
||||
handle = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt> BaseType_t xTimerReset( TimerHandle_t
|
||||
* xTimer, TickType_t xBlockTime )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerReset.html>
|
||||
*
|
||||
* reset() re-starts a timer. If the timer had already been started and was
|
||||
* already in the active state, then reset() will cause the timer to
|
||||
* re-evaluate its expiry time so that it is relative to when reset() was
|
||||
* called. If the timer was in the dormant state then reset() has equivalent
|
||||
* functionality to the start() API function.
|
||||
*
|
||||
* Resetting a timer ensures the timer is in the active state. If the timer
|
||||
* is not stopped, deleted, or reset in the mean time, the callback function
|
||||
* associated with the timer will get called 'n' ticks after reset() was
|
||||
* called, where 'n' is the timers defined period.
|
||||
*
|
||||
* It is valid to call reset() before the RTOS scheduler has been started, but
|
||||
* when this is done the timer will not actually start until the RTOS
|
||||
* scheduler is started, and the timers expiry time will be relative to when
|
||||
* the RTOS scheduler is started, not relative to when reset() was called.
|
||||
*
|
||||
* @param blockTime Specifies the time, in ticks, that the calling task should
|
||||
* be held in the Blocked state to wait for the reset command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when reset() was called. blockTime is ignored if reset() is called
|
||||
* before the RTOS scheduler is started.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system,
|
||||
* although the timers expiry time is relative to when reset() is actually
|
||||
* called. The timer service/daemon task priority is set by the
|
||||
* configTIMER_TASK_PRIORITY configuration constant.
|
||||
* @return false If the reset command could not be sent to the timer command
|
||||
* queue even after blockTime ticks had passed.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/reset.cpp
|
||||
*/
|
||||
inline bool reset(const TickType_t blockTime = 0) const {
|
||||
return (xTimerReset(handle, blockTime) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerResetFromISR( TimerHandle_t
|
||||
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerResetFromISR.html>
|
||||
*
|
||||
* A version of reset() that can be called from an interrupt service routine.
|
||||
*
|
||||
* @param higherPriorityTaskWoken The timer service/daemon task spends most of
|
||||
* its time in the Blocked state, waiting for messages to arrive on the timer
|
||||
* command queue. Calling resetFromISR() writes a message to the timer command
|
||||
* queue, so has the potential to transition the timer service/daemon task out
|
||||
* of the Blocked state. If calling resetFromISR() causes the timer
|
||||
* service/daemon task to leave the Blocked state, and the timer
|
||||
* service/daemon task has a priority equal to or greater than the currently
|
||||
* executing task (the task that was interrupted), then
|
||||
* higherPriorityTaskWoken will get set to true internally within the
|
||||
* resetFromISR() function. If resetFromISR() sets this value to true, then a
|
||||
* context switch should be performed before the interrupt exits.
|
||||
* @return true If the command was successfully sent to the timer command
|
||||
* queue. When the command is actually processed will depend on the priority
|
||||
* of the timer service/daemon task relative to other tasks in the system,
|
||||
* although the timers expiry time is relative to when resetFromISR() is
|
||||
* actually called. The timer service/daemon task priority is set by the
|
||||
* configTIMER_TASK_PRIORITY configuration constant.
|
||||
* @return false If the change period command could not be sent to the timer
|
||||
* command queue.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/resetFromISR.cpp
|
||||
*/
|
||||
inline bool resetFromISR(bool& higherPriorityTaskWoken) const {
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
bool result = (xTimerResetFromISR(handle, &taskWoken) == pdPASS);
|
||||
if (taskWoken == pdTRUE) {
|
||||
higherPriorityTaskWoken = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>BaseType_t xTimerResetFromISR( TimerHandle_t
|
||||
* xTimer, BaseType_t *pxHigherPriorityTaskWoken )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerResetFromISR.html>
|
||||
*
|
||||
* @overload
|
||||
*/
|
||||
inline bool resetFromISR() const {
|
||||
return (xTimerResetFromISR(handle, NULL) == pdPASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>void vTimerSetReloadMode( TimerHandle_t
|
||||
* xTimer, const UBaseType_t uxAutoReload )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-Timers-vTimerSetReloadMode.html>
|
||||
*
|
||||
* Updates the 'mode' of a software timer to be either an auto reload timer or
|
||||
* a one-shot timer.
|
||||
*
|
||||
* An auto reload timer resets itself each time it expires, causing the timer
|
||||
* to expire (and therefore execute its callback) periodically.
|
||||
*
|
||||
* A one shot timer does not automatically reset itself, so will only expire
|
||||
* (and therefore execute its callback) once unless it is manually restarted.
|
||||
*
|
||||
* @param autoReload Set autoReload to true to set the timer into auto reload
|
||||
* mode, or false to set the timer into one shot mode.
|
||||
*/
|
||||
inline void setReloadMode(const bool autoReload) const {
|
||||
vTimerSetReloadMode(handle, (autoReload ? pdTRUE : pdFALSE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>const char * pcTimerGetName( TimerHandle_t
|
||||
* xTimer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-pcTimerGetName.html>
|
||||
*
|
||||
* Returns the human readable text name of a software timer.
|
||||
*
|
||||
* Text names are assigned to timers in the constructor.
|
||||
*
|
||||
* @return const char* A pointer to the text name of the timer as a standard
|
||||
* NULL terminated C string.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/getName.cpp
|
||||
*/
|
||||
inline const char* getName() const { return pcTimerGetName(handle); }
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>TickType_t xTimerGetPeriod( TimerHandle_t
|
||||
* xTimer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerGetPeriod.html>
|
||||
*
|
||||
* Returns the period of a software timer. The period is specified in ticks.
|
||||
*
|
||||
* The period of a timer is initially set using the period parameter of the
|
||||
* constructor. It can then be changed using the changePeriod() and
|
||||
* changePeriodFromISR() API functions.
|
||||
*
|
||||
* @return TickType_t The period of the timer, in ticks.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/getPeriod.cpp
|
||||
*/
|
||||
inline TickType_t getPeriod() const { return xTimerGetPeriod(handle); }
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>TickType_t xTimerGetExpiryTime(
|
||||
* TimerHandle_t xTimer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerGetExpiryTime.html>
|
||||
*
|
||||
* Returns the time at which the software timer will expire, which is the time
|
||||
* at which the timer's callback function will execute.
|
||||
*
|
||||
* If the value returned by getExpiryTime() is less than the current time then
|
||||
* the timer will expire after the tick count has overflowed and wrapped back
|
||||
* to 0. Overflows are handled in the RTOS implementation itself, so a timer's
|
||||
* callback function will execute at the correct time whether it is before or
|
||||
* after the tick count overflows.
|
||||
*
|
||||
* @return TickType_t If the timer is active, then the time at which the timer
|
||||
* will next expire is returned (which may be after the current tick count has
|
||||
* overflowed, see the notes above). If the timer is not active then the
|
||||
* return value is undefined.
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/getExpiryTime.cpp
|
||||
*/
|
||||
inline TickType_t getExpiryTime() const {
|
||||
return xTimerGetExpiryTime(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Function that calls <tt>UBaseType_t uxTimerGetReloadMode(
|
||||
* TimerHandle_t xTimer )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/uxTimerGetReloadMode.html>
|
||||
*
|
||||
* Queries the 'mode' of the software timer.
|
||||
*
|
||||
* The mode can be either an auto-reloaded timer, which automatically resets
|
||||
* itself each time it expires, or a one-shot timer, which will expire only
|
||||
* once unless it is manually restarted.
|
||||
*
|
||||
* @return true If the timer is an auto-reload timer.
|
||||
* @return false Otherwise.
|
||||
*/
|
||||
inline bool getReloadMode() const {
|
||||
return (uxTimerGetReloadMode(handle) == pdTRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Set the delete block time. This value is used when the destructor
|
||||
* calls deleteTimer().
|
||||
*
|
||||
* @param deleteBlockTime Delete block time to be set in ticks.
|
||||
*/
|
||||
inline void setDeleteBlockTime(const TickType_t deleteBlockTime = 0) {
|
||||
this->deleteBlockTime = deleteBlockTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Set the delete block time. This value is used when the destructor
|
||||
* calls deleteTimer().
|
||||
*
|
||||
* @return TickType_t Delete block time in ticks.
|
||||
*/
|
||||
inline TickType_t getDeleteBlockTime() const { return deleteBlockTime; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Abstraction function that acts as the entry point of the timer
|
||||
* callback for the user.
|
||||
*/
|
||||
virtual void timerFunction() = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Construct a new TimerBase object. This default constructor is
|
||||
* deliberately private as this class is not intended to be instantiated or
|
||||
* derived from by the user. Use FreeRTOS::Timer or FreeRTOS::StaticTimer as
|
||||
* a base class for creating a task.
|
||||
*
|
||||
* @param deleteBlockTime Set the delete block time. This value is used when
|
||||
* the destructor calls deleteTimer().
|
||||
*/
|
||||
explicit TimerBase(const TickType_t deleteBlockTime = 0)
|
||||
: deleteBlockTime(deleteBlockTime) {}
|
||||
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Destroy the TimerBase object.
|
||||
*
|
||||
* @note This destructor will check that the timer is still valid and has not
|
||||
* already been deleted by deleteTimer() before calling the function. If the
|
||||
* timer is still valid the destructor will call deleteTimer() and block for
|
||||
* up to the amount of time specified by deleteBlockTime.
|
||||
*/
|
||||
~TimerBase() {
|
||||
if (isValid()) {
|
||||
deleteTimer(getDeleteBlockTime());
|
||||
}
|
||||
}
|
||||
|
||||
TimerBase(TimerBase&&) noexcept = default;
|
||||
TimerBase& operator=(TimerBase&&) noexcept = default;
|
||||
|
||||
TimerHandle_t handle = NULL;
|
||||
TickType_t deleteBlockTime;
|
||||
};
|
||||
|
||||
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* Timer Timer.hpp <FreeRTOS/Timer.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS timer.
|
||||
*
|
||||
* Each software timer requires a small amount of RAM that is used to hold the
|
||||
* timer's state. If a timer is created using this class then this RAM is
|
||||
* automatically allocated from the FreeRTOS heap. If a software timer is
|
||||
* created using FreeRTOS::StaticTimer() then the RAM is included in the object
|
||||
* so it can be statically allocated at compile time. See the Static Vs Dynamic
|
||||
* allocation page for more information.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. The user
|
||||
* should create a class that derives from this class and implement
|
||||
* timerFunction().
|
||||
*/
|
||||
class Timer : public TimerBase {
|
||||
public:
|
||||
Timer(const Timer&) = delete;
|
||||
Timer& operator=(const Timer&) = delete;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Construct a new Timer object by calling <tt>TimerHandle_t
|
||||
* xTimerCreate( const char * const pcTimerName, const TickType_t
|
||||
* xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID,
|
||||
* TimerCallbackFunction_t pxCallbackFunction )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/FreeRTOS-timers-xTimerCreate.html>
|
||||
*
|
||||
* @warning The user should call isValid() on this object to verify that the
|
||||
* timer was created successfully in case the memory required to create the
|
||||
* timer could not be allocated.
|
||||
*
|
||||
* @note Timers are created in the dormant state. The start(), reset(),
|
||||
* startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR()
|
||||
* API functions can all be used to transition a timer into the active state.
|
||||
*
|
||||
* @note When calling <tt>xTimerCreate</tt> the constructor passes the
|
||||
* <tt>this</tt> pointer as the pvTimerID argument. This pointer is used so
|
||||
* that the interface function callTimerFunction() can invoke timerFunction()
|
||||
* for this instance of the class.
|
||||
*
|
||||
* @param period The period of the timer. The period is specified in ticks,
|
||||
* and the macro pdMS_TO_TICKS() can be used to convert a time specified in
|
||||
* milliseconds to a time specified in ticks. For example, if the timer must
|
||||
* expire after 100 ticks, then simply set period to 100. Alternatively, if
|
||||
* the timer must expire after 500ms, then set period to pdMS_TO_TICKS( 500 ).
|
||||
* pdMS_TO_TICKS() can only be used if configTICK_RATE_HZ is less than or
|
||||
* equal to 1000. The timer period must be greater than 0.
|
||||
* @param autoReload If autoReload is set to true, then the timer will expire
|
||||
* repeatedly with a frequency set by the period parameter. If autoReload is
|
||||
* set to false, then the timer will be a one-shot and enter the dormant state
|
||||
* after it expires.
|
||||
* @param name A human readable text name that is assigned to the timer. This
|
||||
* is done purely to assist debugging. The RTOS kernel itself only ever
|
||||
* references a timer by its handle, and never by its name.
|
||||
* @param deleteBlockTime Specifies the time, in ticks, that the calling task
|
||||
* should be held in the Blocked state to wait for the delete command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when the destructor is called. deleteBlockTime is ignored if the
|
||||
* destructor is called before the RTOS scheduler is started or if the timer
|
||||
* has already been deleted by deleteTimer() before the destructor is called.
|
||||
* This value can be updated by calling setDeleteBlockTime().
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/timer.cpp
|
||||
*/
|
||||
explicit Timer(const TickType_t period, const bool autoReload = false,
|
||||
const char* name = "", const TickType_t deleteBlockTime = 0)
|
||||
: TimerBase(deleteBlockTime) {
|
||||
this->handle = xTimerCreate(name, period, (autoReload ? pdTRUE : pdFALSE),
|
||||
this, callTimerFunction);
|
||||
}
|
||||
~Timer() = default;
|
||||
|
||||
Timer(Timer&&) noexcept = default;
|
||||
Timer& operator=(Timer&&) noexcept = default;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
|
||||
/**
|
||||
* Timer Timer.hpp <FreeRTOS/Timer.hpp>
|
||||
*
|
||||
* @brief Class that encapsulates the functionality of a FreeRTOS timer.
|
||||
*
|
||||
* Each software timer requires a small amount of RAM that is used to hold the
|
||||
* timer's state. If a timer is created using FreeRTOS::Timer() then this RAM is
|
||||
* automatically allocated from the FreeRTOS heap. If a software timer is
|
||||
* created this class then the RAM is included in the object so it can be
|
||||
* statically allocated at compile time. See the Static Vs Dynamic allocation
|
||||
* page for more information.
|
||||
*
|
||||
* @note This class is not intended to be instantiated by the user. The user
|
||||
* should create a class that derives from this class and implement
|
||||
* timerFunction().
|
||||
*
|
||||
* @warning This class contains the timer data structure, so any instance of
|
||||
* this class or class derived from this class should be persistent (not
|
||||
* declared on the stack of another function).
|
||||
*/
|
||||
class StaticTimer : public TimerBase {
|
||||
public:
|
||||
StaticTimer(const StaticTimer&) = delete;
|
||||
StaticTimer& operator=(const StaticTimer&) = delete;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Timer.hpp
|
||||
*
|
||||
* @brief Construct a new StaticTimer object by calling <tt>TimerHandle_t
|
||||
* xTimerCreateStatic( const char * const pcTimerName, const TickType_t
|
||||
* xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID,
|
||||
* TimerCallbackFunction_t pxCallbackFunction StaticTimer_t *pxTimerBuffer
|
||||
* )</tt>
|
||||
*
|
||||
* @see <https://www.freertos.org/xTimerCreateStatic.html>
|
||||
*
|
||||
* @note When calling <tt>xTimerCreateStatic</tt> the constructor passes the
|
||||
* <tt>this</tt> pointer as the pvTimerID argument. This pointer is used so
|
||||
* that the interface function callTimerFunction() can invoke timerFunction()
|
||||
* for this instance of the class.
|
||||
*
|
||||
* @note Timers are created in the dormant state. The start(), reset(),
|
||||
* startFromISR(), resetFromISR(), changePeriod() and changePeriodFromISR()
|
||||
* API functions can all be used to transition a timer into the active state.
|
||||
*
|
||||
* @param period The period of the timer. The period is specified in ticks,
|
||||
* and the macro pdMS_TO_TICKS() can be used to convert a time specified in
|
||||
* milliseconds to a time specified in ticks. For example, if the timer must
|
||||
* expire after 100 ticks, then simply set period to 100. Alternatively, if
|
||||
* the timer must expire after 500ms, then set period to pdMS_TO_TICKS( 500 ).
|
||||
* pdMS_TO_TICKS() can only be used if configTICK_RATE_HZ is less than or
|
||||
* equal to 1000. The timer period must be greater than 0.
|
||||
* @param autoReload If autoReload is set to true, then the timer will expire
|
||||
* repeatedly with a frequency set by the period parameter. If autoReload is
|
||||
* set to false, then the timer will be a one-shot and enter the dormant state
|
||||
* after it expires.
|
||||
* @param name A human readable text name that is assigned to the timer. This
|
||||
* is done purely to assist debugging. The RTOS kernel itself only ever
|
||||
* references a timer by its handle, and never by its name.
|
||||
* @param deleteBlockTime Specifies the time, in ticks, that the calling task
|
||||
* should be held in the Blocked state to wait for the delete command to be
|
||||
* successfully sent to the timer command queue, should the queue already be
|
||||
* full when the destructor is called. deleteBlockTime is ignored if the
|
||||
* destructor is called before the RTOS scheduler is started or if the timer
|
||||
* has already been deleted by deleteTimer() before the destructor is called.
|
||||
* This value can be updated by calling setDeleteBlockTime().
|
||||
*
|
||||
* <b>Example Usage</b>
|
||||
* @include Timer/staticTimer.cpp
|
||||
*/
|
||||
explicit StaticTimer(const TickType_t period, const bool autoReload = false,
|
||||
const char* name = "",
|
||||
const TickType_t deleteBlockTime = 0)
|
||||
: TimerBase(deleteBlockTime) {
|
||||
this->handle =
|
||||
xTimerCreateStatic(name, period, (autoReload ? pdTRUE : pdFALSE), this,
|
||||
callTimerFunction, &staticTimer);
|
||||
}
|
||||
~StaticTimer() = default;
|
||||
|
||||
StaticTimer(StaticTimer&&) noexcept = default;
|
||||
StaticTimer& operator=(StaticTimer&&) noexcept = default;
|
||||
|
||||
private:
|
||||
StaticTimer_t staticTimer;
|
||||
};
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
} // namespace FreeRTOS
|
||||
|
||||
inline void callTimerFunction(TimerHandle_t timer) {
|
||||
static_cast<FreeRTOS::TimerBase*>(pvTimerGetTimerID(timer))->timerEntry();
|
||||
}
|
||||
|
||||
#endif // FREERTOS_TIMER_HPP
|
||||
82
source/shoh/src/aeabi_romdiv_patch.s
Normal file
82
source/shoh/src/aeabi_romdiv_patch.s
Normal file
@@ -0,0 +1,82 @@
|
||||
//*****************************************************************************
|
||||
// aeabi_romdiv_patch.s
|
||||
// - Provides "patch" versions of the aeabi integer divide functions to
|
||||
// replace the standard ones pulled in from the C library, which vector
|
||||
// integer divides onto the rom division functions contained in
|
||||
// specific NXP MCUs such as LPC8xx, LPC11Uxx and LPC12xx.
|
||||
// - Note that this patching will only occur if "__USE_ROMDIVIDE" is
|
||||
// defined for the project build for both the compiler and assembler.
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright 2013-2017, 2019, 2020 NXP
|
||||
// All rights reserved.
|
||||
//
|
||||
// NXP Confidential. This software is owned or controlled by NXP and may only be
|
||||
// used strictly in accordance with the applicable license terms.
|
||||
//
|
||||
// By expressly accepting such terms or by downloading, installing, activating
|
||||
// and/or otherwise using the software, you are agreeing that you have read, and
|
||||
// that you agree to comply with and are bound by, such license terms.
|
||||
//
|
||||
// If you do not agree to be bound by the applicable license terms, then you may not
|
||||
// retain, install, activate or otherwise use the software.
|
||||
//*****************************************************************************
|
||||
#if defined(__USE_ROMDIVIDE)
|
||||
|
||||
// Note that the romdivide "divmod" functions are not actually called from
|
||||
// the below code, as these functions are actually just wrappers to the
|
||||
// main romdivide "div" functions which push the quotient and remainder onto
|
||||
// the stack, so as to be compatible with the way that C returns structures.
|
||||
//
|
||||
// This is not needed for the aeabi "divmod" functions, as the compiler
|
||||
// automatically generates code that handles the return values being passed
|
||||
// back in registers when it generates inline calls to __aeabi_idivmod and
|
||||
// __aeabi_uidivmod routines.
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
|
||||
// ========= __aeabi_idiv & __aeabi_idivmod =========
|
||||
.align 2
|
||||
.section .text.__aeabi_idiv
|
||||
|
||||
.global __aeabi_idiv
|
||||
.set __aeabi_idivmod, __aeabi_idiv // make __aeabi_uidivmod an alias
|
||||
.global __aeabi_idivmod
|
||||
.global pDivRom_idiv // pointer to the romdivide 'idiv' functione
|
||||
.func
|
||||
.thumb_func
|
||||
.type __aeabi_idiv, %function
|
||||
|
||||
__aeabi_idiv:
|
||||
push {r4, lr}
|
||||
ldr r3, =pDivRom_idiv
|
||||
ldr r3, [r3, #0] // Load address of function
|
||||
blx r3 // Call divide function
|
||||
pop {r4, pc}
|
||||
|
||||
.endfunc
|
||||
|
||||
// ======== __aeabi_uidiv & __aeabi_uidivmod ========
|
||||
.align 2
|
||||
|
||||
.section .text.__aeabi_uidiv
|
||||
|
||||
.global __aeabi_uidiv
|
||||
.set __aeabi_uidivmod, __aeabi_uidiv // make __aeabi_uidivmod an alias
|
||||
.global __aeabi_uidivmod
|
||||
.global pDivRom_uidiv // pointer to the romdivide 'uidiv' function
|
||||
.func
|
||||
.thumb_func
|
||||
.type __aeabi_uidiv, %function
|
||||
|
||||
__aeabi_uidiv:
|
||||
push {r4, lr}
|
||||
ldr r3, =pDivRom_uidiv
|
||||
ldr r3, [r3, #0] // Load address of function
|
||||
blx r3 // Call divide function
|
||||
pop {r4, pc}
|
||||
|
||||
.endfunc
|
||||
|
||||
#endif // (__USE_ROMDIVIDE)
|
||||
91
source/shoh/src/cr_cpp_config.cpp
Normal file
91
source/shoh/src/cr_cpp_config.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
//*****************************************************************************
|
||||
// +--+
|
||||
// | ++----+
|
||||
// +-++ |
|
||||
// | |
|
||||
// +-+--+ |
|
||||
// | +--+--+
|
||||
// +----+ Copyright (c) 2009-2012 Code Red Technologies Ltd.
|
||||
// +----+ Copyright 2013, 2019 NXP
|
||||
//
|
||||
// Minimal implementations of the new/delete operators and the verbose
|
||||
// terminate handler for exceptions suitable for embedded use,
|
||||
// plus optional "null" stubs for malloc/free (only used if symbol
|
||||
// CPP_NO_HEAP is defined).
|
||||
//
|
||||
//
|
||||
// Version : 120126
|
||||
//
|
||||
// Software License Agreement
|
||||
//
|
||||
// The software is owned by Code Red Technologies and/or its suppliers, and is
|
||||
// protected under applicable copyright laws. All rights are reserved. Any
|
||||
// use in violation of the foregoing restrictions may subject the user to criminal
|
||||
// sanctions under applicable laws, as well as to civil liability for the breach
|
||||
// of the terms and conditions of this license.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
|
||||
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
|
||||
// CODE RED TECHNOLOGIES LTD.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *operator new(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *operator new[](size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
void operator delete[](void *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
extern "C" int __aeabi_atexit(void *object,
|
||||
void (*destructor)(void *),
|
||||
void *dso_handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CPP_NO_HEAP
|
||||
extern "C" void *malloc(size_t) {
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
extern "C" void free(void *) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CPP_USE_CPPLIBRARY_TERMINATE_HANDLER
|
||||
/******************************************************************
|
||||
* __verbose_terminate_handler()
|
||||
*
|
||||
* This is the function that is called when an uncaught C++
|
||||
* exception is encountered. The default version within the C++
|
||||
* library prints the name of the uncaught exception, but to do so
|
||||
* it must demangle its name - which causes a large amount of code
|
||||
* to be pulled in. The below minimal implementation can reduce
|
||||
* code size noticeably. Note that this function should not return.
|
||||
******************************************************************/
|
||||
namespace __gnu_cxx {
|
||||
void __verbose_terminate_handler()
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
348
source/shoh/src/cr_startup_lpc11u6x.cpp
Normal file
348
source/shoh/src/cr_startup_lpc11u6x.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
//*****************************************************************************
|
||||
// LPC11U6x Microcontroller Startup code for use with LPCXpresso IDE
|
||||
//
|
||||
// Version : 150706
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright(C) NXP Semiconductors, 2014-2015, 2020
|
||||
// All rights reserved.
|
||||
//
|
||||
// NXP Confidential. This software is owned or controlled by NXP and may only be
|
||||
// used strictly in accordance with the applicable license terms.
|
||||
//
|
||||
// By expressly accepting such terms or by downloading, installing, activating
|
||||
// and/or otherwise using the software, you are agreeing that you have read, and
|
||||
// that you agree to comply with and are bound by, such license terms.
|
||||
//
|
||||
// If you do not agree to be bound by the applicable license terms, then you may not
|
||||
// retain, install, activate or otherwise use the software.
|
||||
//*****************************************************************************
|
||||
|
||||
#if defined (__cplusplus)
|
||||
#ifdef __REDLIB__
|
||||
#error Redlib does not support C++
|
||||
#else
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The entry point for the C++ library startup
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern "C" {
|
||||
extern void __libc_init_array(void);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
|
||||
|
||||
//*****************************************************************************
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
|
||||
// Declaration of external SystemInit function
|
||||
extern void SystemInit(void);
|
||||
#endif
|
||||
|
||||
// Patch the AEABI integer divide functions to use MCU's romdivide library
|
||||
#ifdef __USE_ROMDIVIDE
|
||||
// Location in memory that holds the address of the ROM Driver table
|
||||
#define PTR_ROM_DRIVER_TABLE ((unsigned int *)(0x1FFF1FF8))
|
||||
// Variables to store addresses of idiv and udiv functions within MCU ROM
|
||||
unsigned int *pDivRom_idiv;
|
||||
unsigned int *pDivRom_uidiv;
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Forward declaration of the default handlers. These are aliased.
|
||||
// When the application defines a handler (with the same name), this will
|
||||
// automatically take precedence over these weak definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
void ResetISR(void);
|
||||
WEAK void NMI_Handler(void);
|
||||
WEAK void HardFault_Handler(void);
|
||||
WEAK void SVC_Handler(void);
|
||||
WEAK void PendSV_Handler(void);
|
||||
WEAK void SysTick_Handler(void);
|
||||
WEAK void IntDefaultHandler(void);
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Forward declaration of the specific IRQ handlers. These are aliased
|
||||
// to the IntDefaultHandler, which is a 'forever' loop. When the application
|
||||
// defines a handler (with the same name), this will automatically take
|
||||
// precedence over these weak definitions
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PIN_INT0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT2_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT3_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT4_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT5_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT6_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void PIN_INT7_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void GINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void GINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void I2C1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void USART1_4_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void USART2_3_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void SCT0_1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void I2C0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void USART0_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void USB_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void USB_FIQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void ADCA_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void RTC_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void BOD_WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void FMC_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void DMA_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void ADCB_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
void USBWakeup_IRQHandler (void) ALIAS(IntDefaultHandler);
|
||||
|
||||
//*****************************************************************************
|
||||
// The entry point for the application.
|
||||
// __main() is the entry point for redlib based applications
|
||||
// main() is the entry point for newlib based applications
|
||||
//*****************************************************************************
|
||||
#if defined (__REDLIB__)
|
||||
extern void __main(void);
|
||||
#endif
|
||||
extern int main(void);
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External declaration for the pointer to the stack top from the Linker Script
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void _vStackTop(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External declaration for LPC MCU vector table checksum from Linker Script
|
||||
//
|
||||
//*****************************************************************************
|
||||
WEAK extern void __valid_user_code_checksum();
|
||||
|
||||
//*****************************************************************************
|
||||
#if defined (__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The vector table. Note that the proper constructs must be placed on this to
|
||||
// ensure that it ends up at physical address 0x0000.0000.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void (* const g_pfnVectors[])(void);
|
||||
__attribute__ ((used,section(".isr_vector")))
|
||||
void (* const g_pfnVectors[])(void) = {
|
||||
&_vStackTop, // The initial stack pointer
|
||||
ResetISR, // The reset handler
|
||||
NMI_Handler, // The NMI handler
|
||||
HardFault_Handler, // The hard fault handler
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
__valid_user_code_checksum, // LPC MCU Checksum
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
SVC_Handler, // SVCall handler
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
PendSV_Handler, // The PendSV handler
|
||||
SysTick_Handler, // The SysTick handler
|
||||
|
||||
// LPC11U6x specific handlers
|
||||
PIN_INT0_IRQHandler, // 0 - GPIO pin interrupt 0
|
||||
PIN_INT1_IRQHandler, // 1 - GPIO pin interrupt 1
|
||||
PIN_INT2_IRQHandler, // 2 - GPIO pin interrupt 2
|
||||
PIN_INT3_IRQHandler, // 3 - GPIO pin interrupt 3
|
||||
PIN_INT4_IRQHandler, // 4 - GPIO pin interrupt 4
|
||||
PIN_INT5_IRQHandler, // 5 - GPIO pin interrupt 5
|
||||
PIN_INT6_IRQHandler, // 6 - GPIO pin interrupt 6
|
||||
PIN_INT7_IRQHandler, // 7 - GPIO pin interrupt 7
|
||||
GINT0_IRQHandler, // 8 - GPIO GROUP0 interrupt
|
||||
GINT1_IRQHandler, // 9 - GPIO GROUP1 interrupt
|
||||
I2C1_IRQHandler, // 10 - I2C1
|
||||
USART1_4_IRQHandler, // 11 - combined USART1 & 4 interrupt
|
||||
USART2_3_IRQHandler, // 12 - combined USART2 & 3 interrupt
|
||||
SCT0_1_IRQHandler, // 13 - combined SCT0 and 1 interrupt
|
||||
SSP1_IRQHandler, // 14 - SPI/SSP1 Interrupt
|
||||
I2C0_IRQHandler, // 15 - I2C0
|
||||
TIMER16_0_IRQHandler, // 16 - CT16B0 (16-bit Timer 0)
|
||||
TIMER16_1_IRQHandler, // 17 - CT16B1 (16-bit Timer 1)
|
||||
TIMER32_0_IRQHandler, // 18 - CT32B0 (32-bit Timer 0)
|
||||
TIMER32_1_IRQHandler, // 19 - CT32B1 (32-bit Timer 1)
|
||||
SSP0_IRQHandler, // 20 - SPI/SSP0 Interrupt
|
||||
USART0_IRQHandler, // 21 - USART0
|
||||
USB_IRQHandler, // 22 - USB IRQ
|
||||
USB_FIQHandler, // 23 - USB FIQ
|
||||
ADCA_IRQHandler, // 24 - ADC A(A/D Converter)
|
||||
RTC_IRQHandler, // 25 - Real Time CLock interrpt
|
||||
BOD_WDT_IRQHandler, // 25 - Combined Brownout/Watchdog interrupt
|
||||
FMC_IRQHandler, // 27 - IP2111 Flash Memory Controller
|
||||
DMA_IRQHandler, // 28 - DMA interrupt
|
||||
ADCB_IRQHandler, // 24 - ADC B (A/D Converter)
|
||||
USBWakeup_IRQHandler, // 30 - USB wake-up interrupt
|
||||
0, // 31 - Reserved
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Functions to carry out the initialization of RW and BSS data sections. These
|
||||
// are written as separate functions rather than being inlined within the
|
||||
// ResetISR() function in order to cope with MCUs with multiple banks of
|
||||
// memory.
|
||||
//*****************************************************************************
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
|
||||
unsigned int *pulDest = (unsigned int*) start;
|
||||
unsigned int *pulSrc = (unsigned int*) romstart;
|
||||
unsigned int loop;
|
||||
for (loop = 0; loop < len; loop = loop + 4)
|
||||
*pulDest++ = *pulSrc++;
|
||||
}
|
||||
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void bss_init(unsigned int start, unsigned int len) {
|
||||
unsigned int *pulDest = (unsigned int*) start;
|
||||
unsigned int loop;
|
||||
for (loop = 0; loop < len; loop = loop + 4)
|
||||
*pulDest++ = 0;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// The following symbols are constructs generated by the linker, indicating
|
||||
// the location of various points in the "Global Section Table". This table is
|
||||
// created by the linker via the Code Red managed linker script mechanism. It
|
||||
// contains the load address, execution address and length of each RW data
|
||||
// section and the execution and length of each BSS (zero initialized) section.
|
||||
//*****************************************************************************
|
||||
extern unsigned int __data_section_table;
|
||||
extern unsigned int __data_section_table_end;
|
||||
extern unsigned int __bss_section_table;
|
||||
extern unsigned int __bss_section_table_end;
|
||||
|
||||
//*****************************************************************************
|
||||
// Reset entry point for your code.
|
||||
// Sets up a simple runtime environment and initializes the C/C++
|
||||
// library.
|
||||
//*****************************************************************************
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void
|
||||
ResetISR(void) {
|
||||
|
||||
// Optionally enable RAM banks that may be off by default at reset
|
||||
#if !defined (DONT_ENABLE_DISABLED_RAMBANKS)
|
||||
volatile unsigned int *SYSCON_SYSAHBCLKCTRL = (unsigned int *) 0x40048080;
|
||||
// Ensure that RAM1(26) and USBSRAM(27) bits in SYSAHBCLKCTRL are set
|
||||
*SYSCON_SYSAHBCLKCTRL |= (1 << 26) | (1 <<27);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copy the data sections from flash to SRAM.
|
||||
//
|
||||
unsigned int LoadAddr, ExeAddr, SectionLen;
|
||||
unsigned int *SectionTableAddr;
|
||||
|
||||
// Load base address of Global Section Table
|
||||
SectionTableAddr = &__data_section_table;
|
||||
|
||||
// Copy the data sections from flash to SRAM.
|
||||
while (SectionTableAddr < &__data_section_table_end) {
|
||||
LoadAddr = *SectionTableAddr++;
|
||||
ExeAddr = *SectionTableAddr++;
|
||||
SectionLen = *SectionTableAddr++;
|
||||
data_init(LoadAddr, ExeAddr, SectionLen);
|
||||
}
|
||||
// At this point, SectionTableAddr = &__bss_section_table;
|
||||
// Zero fill the bss segment
|
||||
while (SectionTableAddr < &__bss_section_table_end) {
|
||||
ExeAddr = *SectionTableAddr++;
|
||||
SectionLen = *SectionTableAddr++;
|
||||
bss_init(ExeAddr, SectionLen);
|
||||
}
|
||||
|
||||
// Patch the AEABI integer divide functions to use MCU's romdivide library
|
||||
#ifdef __USE_ROMDIVIDE
|
||||
// Get address of Integer division routines function table in ROM
|
||||
unsigned int *div_ptr = (unsigned int *)((unsigned int *)*(PTR_ROM_DRIVER_TABLE))[4];
|
||||
// Get addresses of integer divide routines in ROM
|
||||
// These address are then used by the code in aeabi_romdiv_patch.s
|
||||
pDivRom_idiv = (unsigned int *)div_ptr[0];
|
||||
pDivRom_uidiv = (unsigned int *)div_ptr[1];
|
||||
#endif
|
||||
|
||||
#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)
|
||||
SystemInit();
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus)
|
||||
//
|
||||
// Call C++ library initialisation
|
||||
//
|
||||
__libc_init_array();
|
||||
#endif
|
||||
|
||||
#if defined (__REDLIB__)
|
||||
// Call the Redlib library, which in turn calls main()
|
||||
__main() ;
|
||||
#else
|
||||
main();
|
||||
#endif
|
||||
//
|
||||
// main() shouldn't return, but if it does, we'll just enter an infinite loop
|
||||
//
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Default exception handlers. Override the ones here by defining your own
|
||||
// handler routines in your application code.
|
||||
//*****************************************************************************
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void NMI_Handler(void)
|
||||
{ while(1) { }
|
||||
}
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void HardFault_Handler(void)
|
||||
{ while(1) { }
|
||||
}
|
||||
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void SVC_Handler(void)
|
||||
{ while(1) { }
|
||||
}
|
||||
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void PendSV_Handler(void)
|
||||
{ while(1) { }
|
||||
}
|
||||
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void SysTick_Handler(void)
|
||||
{ while(1) { }
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Processor ends up here if an unexpected interrupt occurs or a specific
|
||||
// handler is not present in the application code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
__attribute__ ((section(".after_vectors")))
|
||||
void IntDefaultHandler(void)
|
||||
{ while(1) { }
|
||||
}
|
||||
27
source/shoh/src/crp.c
Normal file
27
source/shoh/src/crp.c
Normal file
@@ -0,0 +1,27 @@
|
||||
//*****************************************************************************
|
||||
// crp.c
|
||||
//
|
||||
// Source file to create CRP word expected by LPCXpresso IDE linker
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright(C) NXP Semiconductors, 2013, 2020
|
||||
// All rights reserved.
|
||||
//
|
||||
// NXP Confidential. This software is owned or controlled by NXP and may only be
|
||||
// used strictly in accordance with the applicable license terms.
|
||||
//
|
||||
// By expressly accepting such terms or by downloading, installing, activating
|
||||
// and/or otherwise using the software, you are agreeing that you have read, and
|
||||
// that you agree to comply with and are bound by, such license terms.
|
||||
//
|
||||
// If you do not agree to be bound by the applicable license terms, then you may not
|
||||
// retain, install, activate or otherwise use the software.
|
||||
//*****************************************************************************
|
||||
|
||||
#if defined (__CODE_RED)
|
||||
#include <NXP/crp.h>
|
||||
// Variable to store CRP value in. Will be placed automatically
|
||||
// by the linker when "Enable Code Read Protect" selected.
|
||||
// See crp.h header for more information
|
||||
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
|
||||
#endif
|
||||
44
source/shoh/src/main.cpp
Normal file
44
source/shoh/src/main.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "chip.h"
|
||||
#include "board.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <cr_section_macros.h>
|
||||
#include "FreeRTOSCPP/Kernel.hpp"
|
||||
#include "FreeRTOSCPP/Task.hpp"
|
||||
|
||||
class LedTask : public FreeRTOS::Task {
|
||||
public:
|
||||
LedTask(const UBaseType_t priority, const char* name)
|
||||
: FreeRTOS::Task(priority, configMINIMAL_STACK_SIZE, name) {}
|
||||
void taskFunction() final;
|
||||
private:
|
||||
int led;
|
||||
};
|
||||
|
||||
// Task to be created.
|
||||
void LedTask::taskFunction() {
|
||||
bool LedState = false;
|
||||
for (;;) {
|
||||
Board_LED_Set(led, LedState);
|
||||
LedState = (bool) !LedState;
|
||||
led++;
|
||||
if(led > 2){
|
||||
led = 0;
|
||||
}
|
||||
vTaskDelay(configTICK_RATE_HZ / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
SystemCoreClockUpdate();
|
||||
Board_Init();
|
||||
// Create a task before starting the kernel.
|
||||
LedTask task1((tskIDLE_PRIORITY + 1UL), "vTaskLed1");
|
||||
|
||||
// Start the real time kernel with preemption.
|
||||
FreeRTOS::Kernel::startScheduler();
|
||||
|
||||
return 1;
|
||||
}
|
||||
86
source/shoh/src/mtb.c
Normal file
86
source/shoh/src/mtb.c
Normal file
@@ -0,0 +1,86 @@
|
||||
//*****************************************************************************
|
||||
// +--+
|
||||
// | ++----+
|
||||
// +-++ |
|
||||
// | |
|
||||
// +-+--+ |
|
||||
// | +--+--+
|
||||
// +----+ Copyright (c) 2013 Code Red Technologies Ltd.
|
||||
//
|
||||
// mtb.c
|
||||
//
|
||||
// Optionally defines an array to be used as a buffer for Micro Trace
|
||||
// Buffer (MTB) instruction trace on Cortex-M0+ parts
|
||||
//
|
||||
// Version : 130502
|
||||
//
|
||||
// Software License Agreement
|
||||
//
|
||||
// The software is owned by Code Red Technologies and/or its suppliers, and is
|
||||
// protected under applicable copyright laws. All rights are reserved. Any
|
||||
// use in violation of the foregoing restrictions may subject the user to criminal
|
||||
// sanctions under applicable laws, as well as to civil liability for the breach
|
||||
// of the terms and conditions of this license.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
|
||||
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
|
||||
// CODE RED TECHNOLOGIES LTD.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
/*******************************************************************
|
||||
* Symbols controlling behavior of this code...
|
||||
*
|
||||
* __MTB_DISABLE
|
||||
* If this symbol is defined, then the buffer array for the MTB
|
||||
* will not be created.
|
||||
*
|
||||
* __MTB_BUFFER_SIZE
|
||||
* Symbol specifying the sizer of the buffer array for the MTB.
|
||||
* This must be a power of 2 in size, and fit into the available
|
||||
* RAM. The MTB buffer will also be aligned to its 'size'
|
||||
* boundary and be placed at the start of a RAM bank (which
|
||||
* should ensure minimal or zero padding due to alignment).
|
||||
*
|
||||
* __MTB_RAM_BANK
|
||||
* Allows MTB Buffer to be placed into specific RAM bank. When
|
||||
* this is not defined, the "default" (first if there are
|
||||
* several) RAM bank is used.
|
||||
*******************************************************************/
|
||||
|
||||
// Ignore with none Code Red tools
|
||||
#if defined (__CODE_RED)
|
||||
|
||||
// Allow MTB to be removed by setting a define (via command line)
|
||||
#if !defined (__MTB_DISABLE)
|
||||
|
||||
// Allow for MTB buffer size being set by define set via command line
|
||||
// Otherwise provide small default buffer
|
||||
#if !defined (__MTB_BUFFER_SIZE)
|
||||
#define __MTB_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
// Check that buffer size requested is >0 bytes in size
|
||||
#if (__MTB_BUFFER_SIZE > 0)
|
||||
// Pull in MTB related macros
|
||||
#include <cr_mtb_buffer.h>
|
||||
|
||||
// Check if MYTB buffer is to be placed in specific RAM bank
|
||||
#if defined(__MTB_RAM_BANK)
|
||||
// Place MTB buffer into explicit bank of RAM
|
||||
__CR_MTB_BUFFER_EXT(__MTB_BUFFER_SIZE,__MTB_RAM_BANK);
|
||||
#else
|
||||
// Place MTB buffer into 'default' bank of RAM
|
||||
__CR_MTB_BUFFER(__MTB_BUFFER_SIZE);
|
||||
|
||||
#endif // defined(__MTB_RAM_BANK)
|
||||
|
||||
#endif // (__MTB_BUFFER_SIZE > 0)
|
||||
|
||||
#endif // !defined (__MTB_DISABLE)
|
||||
|
||||
#endif // defined (__CODE_RED)
|
||||
|
||||
57
source/shoh/src/sysinit.c
Normal file
57
source/shoh/src/sysinit.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* @brief Common SystemInit function for LPC11u6x chips
|
||||
*
|
||||
* @note
|
||||
* Copyright 2013-2014, 2019, 2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* NXP Confidential. This software is owned or controlled by NXP and may only be
|
||||
* used strictly in accordance with the applicable license terms.
|
||||
*
|
||||
* By expressly accepting such terms or by downloading, installing, activating
|
||||
* and/or otherwise using the software, you are agreeing that you have read, and
|
||||
* that you agree to comply with and are bound by, such license terms.
|
||||
*
|
||||
* If you do not agree to be bound by the applicable license terms, then you may not
|
||||
* retain, install, activate or otherwise use the software.
|
||||
*/
|
||||
|
||||
#if defined(NO_BOARD_LIB)
|
||||
#include "chip.h"
|
||||
#else
|
||||
#include "board.h"
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(NO_BOARD_LIB)
|
||||
const uint32_t OscRateIn = 12000000;
|
||||
const uint32_t RTCOscRateIn = 32768;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Set up and initialize hardware prior to call to main */
|
||||
void SystemInit(void)
|
||||
{
|
||||
#if defined(NO_BOARD_LIB)
|
||||
/* Chip specific SystemInit */
|
||||
Chip_SystemInit();
|
||||
#else
|
||||
/* Setup system clocking and muxing */
|
||||
Board_SystemInit();
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user