mirror of https://github.com/ARMmbed/mbed-os.git
commit
ef7ab92cb8
|
|
@ -0,0 +1,234 @@
|
|||
<?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="cdt.managedbuild.toolchain.gnu.cross.base.1189539176">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176" moduleId="org.eclipse.cdt.core.settings" name="ArmCC Cortex-M3">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.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.CWDLocator" 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.ui.ArmCC Error Parser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="" artifactName="eventOS" buildProperties="" description="" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.ui.ArmCC Error Parser;org.eclipse.cdt.core.VCErrorParser" id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176" name="ArmCC Cortex-M3" parent="org.eclipse.cdt.build.core.emptycfg" postannouncebuildStep="" postbuildStep="" preannouncebuildStep="" prebuildStep="">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176.1169351817" name="/" resourcePath="">
|
||||
<toolChain errorParsers="" id="cdt.managedbuild.toolchain.gnu.cross.base.367759647" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base">
|
||||
<option id="cdt.managedbuild.option.gnu.cross.prefix.660991130" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix"/>
|
||||
<option id="cdt.managedbuild.option.gnu.cross.path.331710635" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1196089708" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
|
||||
<builder buildPath="${workspace_loc:/eventOS}/" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="cdt.managedbuild.builder.gnu.cross.836533860" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
|
||||
<tool errorParsers="" id="cdt.managedbuild.tool.gnu.cross.c.compiler.499691915" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
|
||||
<option id="gnu.c.compiler.option.include.paths.1009581990" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${ARMCC_INCLUDE}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/libService/libService}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.490997078" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.146498331" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler"/>
|
||||
<tool errorParsers="org.eclipse.cdt.core.GLDErrorParser" id="cdt.managedbuild.tool.gnu.cross.c.linker.559644121" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1546200009" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.756120679" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.360501954" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
|
||||
<tool errorParsers="org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.tool.gnu.cross.assembler.1933431042" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1501463266" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087" moduleId="org.eclipse.cdt.core.settings" name="ArmCC Cortex-M0">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.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.CWDLocator" 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.ui.ArmCC Error Parser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="" artifactName="eventOS" buildProperties="" description="" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.ui.ArmCC Error Parser;org.eclipse.cdt.core.VCErrorParser" id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087" name="ArmCC Cortex-M0" parent="org.eclipse.cdt.build.core.emptycfg" postannouncebuildStep="" postbuildStep="" preannouncebuildStep="" prebuildStep="">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087." name="/" resourcePath="">
|
||||
<toolChain errorParsers="" id="cdt.managedbuild.toolchain.gnu.cross.base.1138059958" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base">
|
||||
<option id="cdt.managedbuild.option.gnu.cross.prefix.2105129213" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix"/>
|
||||
<option id="cdt.managedbuild.option.gnu.cross.path.1568321385" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.282790878" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
|
||||
<builder buildPath="${workspace_loc:/eventOS}/" enabledIncrementalBuild="true" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="cdt.managedbuild.builder.gnu.cross.1363458610" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
|
||||
<tool errorParsers="" id="cdt.managedbuild.tool.gnu.cross.c.compiler.435164393" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
|
||||
<option id="gnu.c.compiler.option.include.paths.241649509" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${ARMCC_INCLUDE}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/libService/libService}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1949795978" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.527027148" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler"/>
|
||||
<tool errorParsers="org.eclipse.cdt.core.GLDErrorParser" id="cdt.managedbuild.tool.gnu.cross.c.linker.128423528" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1297698567" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.180972500" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.1580602139" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
|
||||
<tool errorParsers="org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.tool.gnu.cross.assembler.2001265995" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2135227594" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="0.2056004298.141662914.2121498000">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.2056004298.141662914.2121498000" moduleId="org.eclipse.cdt.core.settings" name="GCC Cortex-M3">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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"/>
|
||||
<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"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="eventOS" buildProperties="" description="" id="0.2056004298.141662914.2121498000" name="GCC Cortex-M3" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.2056004298.141662914.2121498000." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.918568439" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.918568439.1607495802" name=""/>
|
||||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1058540032" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1807153236" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1080063132" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1969769389" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1385174078" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1768833971" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.991434917" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1850008051" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="0.2056004298.141662914.2121498000.642060230">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.2056004298.141662914.2121498000.642060230" moduleId="org.eclipse.cdt.core.settings" name="GCC Cortex-M0">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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"/>
|
||||
<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"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="eventOS" buildProperties="" description="" id="0.2056004298.141662914.2121498000.642060230" name="GCC Cortex-M0" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.2056004298.141662914.2121498000.642060230." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.387353475" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.387353475.888485765" name=""/>
|
||||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.48511333" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.770690623" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.798622084" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1838730947" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1622459001" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1547926363" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1687578706" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1372610724" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="0.2056004298.141662914.1517984773.801758434.1788862897">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.2056004298.141662914.1517984773.801758434.1788862897" moduleId="org.eclipse.cdt.core.settings" name="GCC Native">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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"/>
|
||||
<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"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration buildProperties="" description="" id="0.2056004298.141662914.1517984773.801758434.1788862897" name="GCC Native" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.2056004298.141662914.1517984773.801758434.1788862897." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1101544598" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1101544598.1141380045" name=""/>
|
||||
<builder enabledIncrementalBuild="true" id="org.eclipse.cdt.build.core.settings.default.builder.1381778143" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.225856136" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.224867602" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.107634360" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1754316635" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.2029105652" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.356296733" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.75316590" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="eventOS.null.931576544" name="eventOS"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="ArmCC Cortex-M3">
|
||||
<resource resourceType="PROJECT" workspacePath="/event_loop"/>
|
||||
</configuration>
|
||||
<configuration configurationName="GCC Cortex-M0"/>
|
||||
<configuration configurationName="ArmCC Cortex-M0"/>
|
||||
<configuration configurationName="GCC Native"/>
|
||||
<configuration configurationName="GCC Cortex-M3"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.1189539176;cdt.managedbuild.toolchain.gnu.cross.base.1189539176.1169351817;cdt.managedbuild.tool.gnu.cross.c.compiler.1945983959;cdt.managedbuild.tool.gnu.c.compiler.input.2069091467">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.lib.debug.1529538572;cdt.managedbuild.config.gnu.cross.lib.debug.1529538572.;cdt.managedbuild.tool.gnu.cross.c.compiler.859614738;cdt.managedbuild.tool.gnu.c.compiler.input.1960426387">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.1189539176;cdt.managedbuild.toolchain.gnu.cross.base.1189539176.1169351817;cdt.managedbuild.tool.gnu.cross.c.compiler.896320276;cdt.managedbuild.tool.gnu.c.compiler.input.1344565279">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.1189539176;cdt.managedbuild.toolchain.gnu.cross.base.1189539176.1169351817;cdt.managedbuild.tool.gnu.cross.c.compiler.499691915;cdt.managedbuild.tool.gnu.c.compiler.input.490997078">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="0.2056004298.141662914.2121498000">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.lib.release.1360582973;cdt.managedbuild.config.gnu.cross.lib.release.1360582973.;cdt.managedbuild.tool.gnu.cross.c.compiler.59710629;cdt.managedbuild.tool.gnu.c.compiler.input.260467457">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>eventOS</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/event_loop/Debug}</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</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.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
eclipse.preferences.version=1
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/CC/delimiter=;
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/CC/operation=append
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/CC/value=gcc
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/V/delimiter=;
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/V/operation=append
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/V/value=1
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/append=true
|
||||
environment/project/0.2056004298.141662914.1517984773.801758434.1788862897/appendContributed=true
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/CPU/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/CPU/operation=replace
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/CPU/value=Cortex-M0
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/DEBUG/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/DEBUG/operation=replace
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/DEBUG/value=1
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/PLATFORM/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/PLATFORM/operation=append
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/PLATFORM/value=arm-unknown-linux-uclibcgnueabi-
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/V/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/V/operation=append
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/V/value=1
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/append=true
|
||||
environment/project/0.2056004298.141662914.2121498000.642060230/appendContributed=true
|
||||
environment/project/0.2056004298.141662914.2121498000/CPU/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000/CPU/operation=append
|
||||
environment/project/0.2056004298.141662914.2121498000/CPU/value=Cortex-M3
|
||||
environment/project/0.2056004298.141662914.2121498000/PLATFORM/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000/PLATFORM/operation=append
|
||||
environment/project/0.2056004298.141662914.2121498000/PLATFORM/value=arm-unknown-linux-uclibcgnueabi-
|
||||
environment/project/0.2056004298.141662914.2121498000/V/delimiter=;
|
||||
environment/project/0.2056004298.141662914.2121498000/V/operation=append
|
||||
environment/project/0.2056004298.141662914.2121498000/V/value=1
|
||||
environment/project/0.2056004298.141662914.2121498000/append=true
|
||||
environment/project/0.2056004298.141662914.2121498000/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CC/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CC/operation=replace
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CC/value=armcc
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CONFIG/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CONFIG/operation=replace
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CONFIG/value=generic
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CPU/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CPU/operation=replace
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/CPU/value=Cortex-M0
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/DEBUG/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/DEBUG/operation=replace
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/DEBUG/value=1
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/V/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/V/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/V/value=1
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176.535362087/appendContributed=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/CC/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/CC/operation=replace
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/CC/value=armcc
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/CPU/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/CPU/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/CPU/value=Cortex-M3
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/DEBUG/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/DEBUG/operation=replace
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/DEBUG/value=1
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/V/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/V/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/V/value=1
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1189539176/appendContributed=true
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
## [mbed-os.5.2-rc1](https://github.com/ARMmbed/sal-stack-nanostack-eventloop/releases/tag/mbed-os.5.2-rc1) (24-Sep-2016)
|
||||
[Full Changelog](https://github.com/ARMmbed/sal-stack-nanostack-eventloop/compare/mbed-os-5.0-rc1...mbed-os.5.2-rc1)
|
||||
|
||||
**New features**
|
||||
|
||||
- Move configuration parameter resolution to separate header and allow user definable configuration header to be used.
|
||||
- Port eventloop system timer to use new tick timer functions platform_tick_timer_register, platform_tick_timer_start and platform_tick_timer_stop.
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
commit 283299dbd744c91cb30810ad263798842905c054 (HEAD, tag: mbed-os.5.2-rc1, origin/master, origin/HEAD, master)
|
||||
Author: Jaakko Kukkohovi <jkukkohovi@gmail.com>
|
||||
Date: Fri Sep 23 10:05:55 2016 +0300
|
||||
|
||||
Change configuration method (#23)
|
||||
|
||||
Move configuration parameter resolution to separate header and allow
|
||||
user definable configuration header to be used.
|
||||
|
||||
commit 269b00fba6a637c363f7d1690db0889118bca010
|
||||
Author: Jaakko Kukkohovi <jkukkohovi@gmail.com>
|
||||
Date: Wed Sep 21 11:27:40 2016 +0300
|
||||
|
||||
Systimer using platform tick timer (#22)
|
||||
|
||||
* Port eventloop system timer to use new tick timer functions platform_tick_timer_register, platform_tick_timer_start and platform_tick_timer_stop.Existing functionality is preserved by implementing these functions by default using the high resolution timer as before
|
||||
* New configuration parameter use_platform_tick_timer disables the high resolution timer based tick timer implementation and allows platform to implement the tick timer functions.
|
||||
* New configuration parameter exclude_highres_timer removes the high resolution timer from the build thus providing only eventloop.
|
||||
* Minar support now implemented by providing platform tick timer using minar timers and implicitly using platform tick timers for eventloop when using minar
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Define compiler toolchain with CC or PLATFORM variables
|
||||
# Example (GCC toolchains)
|
||||
# make PLATFORM=arm-linux-gnueabi-
|
||||
# OR
|
||||
# make CC=armcc AR=ArmAR
|
||||
# OR
|
||||
# make CC=iccarm
|
||||
|
||||
LIB = libeventOS.a
|
||||
SRCS += \
|
||||
source/event.c \
|
||||
source/ns_timer.c \
|
||||
source/system_timer.c\
|
||||
source/ns_timeout.c
|
||||
|
||||
include ../libService/toolchain_rules.mk
|
||||
|
||||
override CFLAGS += -I nanostack-event-loop
|
||||
|
||||
#
|
||||
# External sources from libService
|
||||
#
|
||||
SERVLIB_DIR := ../libService
|
||||
override CFLAGS += -I$(SERVLIB_DIR)/libService
|
||||
|
||||
$(eval $(call generate_rules,$(LIB),$(SRCS)))
|
||||
|
||||
.PHONY: release
|
||||
release:
|
||||
7z a edtls-lib_$(VERSION).zip *.a *.lib include
|
||||
|
||||
.PHONY: deploy_to
|
||||
deploy_to: all
|
||||
tar --transform 's,^,event-loop/,' --append -f $(TO) *.a
|
||||
|
|
@ -20,6 +20,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
|
||||
/**
|
||||
* \enum arm_library_event_priority_e
|
||||
* \brief Event Priority level.
|
||||
|
|
@ -31,7 +33,7 @@ typedef enum arm_library_event_priority_e {
|
|||
} arm_library_event_priority_e;
|
||||
|
||||
/**
|
||||
* \enum arm_event_s
|
||||
* \struct arm_event_s
|
||||
* \brief Event structure.
|
||||
*/
|
||||
typedef struct arm_event_s {
|
||||
|
|
@ -42,18 +44,90 @@ typedef struct arm_event_s {
|
|||
void *data_ptr; /**< Application could share data pointer tasklet to tasklet */
|
||||
arm_library_event_priority_e priority;
|
||||
uint32_t event_data;
|
||||
} arm_event_s;
|
||||
} arm_event_t;
|
||||
|
||||
/* Backwards compatibility */
|
||||
typedef arm_event_t arm_event_s;
|
||||
|
||||
/**
|
||||
* \brief Send event to event scheduler.
|
||||
* \struct arm_event_storage
|
||||
* \brief Event structure storage, including list link.
|
||||
|
||||
@startuml
|
||||
|
||||
partition "Event loop" {
|
||||
(*) -->[event created] "UNQUEUED"
|
||||
"UNQUEUED" -->[event_core_write()] "QUEUED"
|
||||
"QUEUED" -->[event_core_read()] "RUNNING"
|
||||
"RUNNING" ->[event_core_free_push()] "UNQUEUED"
|
||||
}
|
||||
|
||||
partition "system_timer.c" {
|
||||
"UNQUEUED:timer" -->[eventOS_event_send_timer_allocated()] "QUEUED"
|
||||
}
|
||||
@enduml
|
||||
|
||||
*/
|
||||
typedef struct arm_event_storage {
|
||||
arm_event_s data;
|
||||
enum {
|
||||
ARM_LIB_EVENT_STARTUP_POOL,
|
||||
ARM_LIB_EVENT_DYNAMIC,
|
||||
ARM_LIB_EVENT_USER,
|
||||
ARM_LIB_EVENT_TIMER,
|
||||
} allocator;
|
||||
enum {
|
||||
ARM_LIB_EVENT_UNQUEUED,
|
||||
ARM_LIB_EVENT_QUEUED,
|
||||
ARM_LIB_EVENT_RUNNING,
|
||||
} state;
|
||||
ns_list_link_t link;
|
||||
} arm_event_storage_t;
|
||||
|
||||
/**
|
||||
* \brief Send event to event scheduler.
|
||||
*
|
||||
* \param event pointer to pushed event.
|
||||
*
|
||||
* Event data is copied by the call, and this copy persists until the
|
||||
* recipient's callback function returns. The callback function is passed
|
||||
* a pointer to a copy of the data, not the original pointer.
|
||||
*
|
||||
* \return 0 Event push OK
|
||||
* \return -1 Memory allocation Fail
|
||||
*
|
||||
*/
|
||||
extern int8_t eventOS_event_send(arm_event_s *event);
|
||||
extern int8_t eventOS_event_send(const arm_event_t *event);
|
||||
|
||||
/* Alternate names for timer function from eventOS_event_timer.h;
|
||||
* implementations may one day merge */
|
||||
#define eventOS_event_send_at(event, at) eventOS_event_timer_request_at(event, at)
|
||||
#define eventOS_event_send_in(event, in) eventOS_event_timer_request_in(event, in)
|
||||
#define eventOS_event_send_after(event, after) eventOS_event_timer_request_after(event, after)
|
||||
#define eventOS_event_send_every(event, every) eventOS_event_timer_request_every(event, every)
|
||||
|
||||
/**
|
||||
* \brief Send user-allocated event to event scheduler.
|
||||
*
|
||||
* \param event pointer to pushed event storage.
|
||||
*
|
||||
* The event structure is not copied by the call, the event system takes
|
||||
* ownership and it is threaded directly into the event queue. This avoids the
|
||||
* possibility of event sending failing due to memory exhaustion.
|
||||
*
|
||||
* event->data must be filled in on entry - the rest of the structure (link and
|
||||
* allocator) need not be.
|
||||
*
|
||||
* The structure must remain valid until the recipient is called - the
|
||||
* event system passes ownership to the receiving event handler, who may then
|
||||
* invalidate it, or send it again.
|
||||
*
|
||||
* The recipient receives a pointer to the arm_event_t data member of the
|
||||
* event - it can use NS_CONTAINER_OF() to get a pointer to the original
|
||||
* event passed to this call, or to its outer container.
|
||||
*
|
||||
* It is a program error to send a user-allocated event to a non-existent task.
|
||||
*/
|
||||
extern void eventOS_event_send_user_allocated(arm_event_storage_t *event);
|
||||
|
||||
/**
|
||||
* \brief Event handler callback register
|
||||
|
|
@ -61,13 +135,34 @@ extern int8_t eventOS_event_send(arm_event_s *event);
|
|||
* Function will register and allocate unique event id handler
|
||||
*
|
||||
* \param handler_func_ptr function pointer for event handler
|
||||
* \param init_event_type generated evevnt type for init purpose
|
||||
* \param init_event_type generated event type for init purpose
|
||||
*
|
||||
* \return >= 0 Unique event ID for this handler
|
||||
* \return < 0 Register fail
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uint8_t init_event_type);
|
||||
extern int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_t *), uint8_t init_event_type);
|
||||
|
||||
/**
|
||||
* Cancel an event.
|
||||
*
|
||||
* Queued events are removed from the event-loop queue and/or the timer queue.
|
||||
*
|
||||
* Passing a NULL pointer is allowed, and does nothing.
|
||||
*
|
||||
* Event pointers are valid from the time they are queued until the event
|
||||
* has finished running or is cancelled.
|
||||
*
|
||||
* Cancelling a currently-running event is only useful to stop scheduling
|
||||
* it if it is on a periodic timer; it has no other effect.
|
||||
*
|
||||
* Cancelling an already-cancelled or already-run single-shot event
|
||||
* is undefined behaviour.
|
||||
*
|
||||
* \param event Pointer to event handle or NULL.
|
||||
*/
|
||||
extern void eventOS_cancel(arm_event_storage_t *event);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,26 +19,191 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
#include "ns_types.h"
|
||||
#include "eventOS_event.h"
|
||||
|
||||
struct arm_event_s;
|
||||
typedef struct sys_timer_struct_s sys_timer_struct_t;
|
||||
|
||||
/* 100 Hz ticker, so 10 milliseconds per tick */
|
||||
#define EVENTOS_EVENT_TIMER_HZ 100
|
||||
|
||||
static inline uint32_t eventOS_event_timer_ticks_to_ms(uint32_t ticks)
|
||||
{
|
||||
NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Assuming whole number of ms per tick")
|
||||
return ticks * (1000 / EVENTOS_EVENT_TIMER_HZ);
|
||||
}
|
||||
|
||||
/* Convert ms to ticks, rounding up (so 9ms = 1 tick, 10ms = 1 tick, 11ms = 2 ticks) */
|
||||
static inline uint32_t eventOS_event_timer_ms_to_ticks(uint32_t ms)
|
||||
{
|
||||
NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Assuming whole number of ms per tick")
|
||||
return (ms + (1000 / EVENTOS_EVENT_TIMER_HZ) - 1) / (1000 / EVENTOS_EVENT_TIMER_HZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read current timer tick count.
|
||||
*
|
||||
* Can be used as a monotonic time source, and to schedule events with
|
||||
* eventOS_event_timer_send.
|
||||
*
|
||||
* Note that the value will wrap, so take care on comparisons.
|
||||
*
|
||||
* \return tick count.
|
||||
*/
|
||||
extern uint32_t eventOS_event_timer_ticks(void);
|
||||
|
||||
/* Comparison macros handling wrap efficiently (assuming a conventional compiler
|
||||
* which converts 0x80000000 to 0xFFFFFFFF to negative when casting to int32_t).
|
||||
*/
|
||||
#define TICKS_AFTER(a, b) ((int32_t) ((a)-(b)) > 0)
|
||||
#define TICKS_BEFORE(a, b) ((int32_t) ((a)-(b)) < 0)
|
||||
#define TICKS_AFTER_OR_AT(a, b) ((int32_t) ((a)-(b)) >= 0)
|
||||
#define TICKS_BEFORE_OR_AT(a, b) ((int32_t) ((a)-(b)) <= 0)
|
||||
|
||||
/**
|
||||
* Send an event after time expired (in milliseconds)
|
||||
*
|
||||
* \param snmessage event to send
|
||||
* Note that the current implementation has the "feature" that rounding
|
||||
* varies depending on the precise timing requested:
|
||||
* 0-20 ms => 2 x 10ms tick
|
||||
* 21-29 ms => 3 x 10ms tick
|
||||
* 30-39 ms => 4 x 10ms tick
|
||||
* 40-49 ms => 5 x 10ms tick
|
||||
* ... etc
|
||||
*
|
||||
* For improved flexibility on the event, and for more control of time,
|
||||
* you should use eventOS_event_timer_request_at().
|
||||
*
|
||||
* \param event_id event_id for event
|
||||
* \param event_type event_type for event
|
||||
* \param tasklet_id receiver for event
|
||||
* \param time time to sleep in milliseconds
|
||||
*
|
||||
* \return none
|
||||
* \return 0 on success
|
||||
* \return -1 on error (invalid tasklet_id or allocation failure)
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_event_timer_request(uint8_t snmessage, uint8_t event_type, int8_t tasklet_id, uint32_t time);
|
||||
extern int8_t eventOS_event_timer_request(uint8_t event_id, uint8_t event_type, int8_t tasklet_id, uint32_t time);
|
||||
|
||||
/**
|
||||
* Cancel an event
|
||||
* Send an event at specified time
|
||||
*
|
||||
* \param event event to cancel
|
||||
* The event will be sent when eventOS_event_timer_ticks() reaches the
|
||||
* specified value.
|
||||
*
|
||||
* \return none
|
||||
* If the specified time is in the past (ie "at" is before or at the current
|
||||
* tick value), the event will be sent immediately.
|
||||
*
|
||||
* Can also be invoked using the eventOS_event_send_at() macro in eventOS_event.h
|
||||
*
|
||||
* \param event event to send
|
||||
* \param at absolute tick time to run event at
|
||||
*
|
||||
* \return pointer to timer structure on success
|
||||
* \return NULL on error (invalid tasklet_id or allocation failure)
|
||||
*
|
||||
*/
|
||||
extern arm_event_storage_t *eventOS_event_timer_request_at(const struct arm_event_s *event, uint32_t at);
|
||||
|
||||
/**
|
||||
* Send an event in a specified time
|
||||
*
|
||||
* The event will be sent in the specified number of ticks - to
|
||||
* be precise, it is equivalent to requesting an event at
|
||||
*
|
||||
* eventOS_event_timer_ticks() + ticks
|
||||
*
|
||||
* Because of timer granularity, the elapsed time between issuing the request
|
||||
* and it running may be up to 1 tick less than the specified time.
|
||||
*
|
||||
* eg requesting 2 ticks will cause the event to be sent on the second tick from
|
||||
* now. If requested just after a tick, the delay will be nearly 2 ticks, but if
|
||||
* requested just before a tick, the delay will be just over 1 tick.
|
||||
*
|
||||
* If `in` is <= 0, the event will be sent immediately.
|
||||
*
|
||||
* Can also be invoked using the eventOS_event_send_in() macro in eventOS_event.h
|
||||
*
|
||||
* \param event event to send
|
||||
* \param in tick delay for event
|
||||
*
|
||||
* \return pointer to timer structure on success
|
||||
* \return NULL on error (invalid tasklet_id or allocation failure)
|
||||
*
|
||||
*/
|
||||
extern arm_event_storage_t *eventOS_event_timer_request_in(const struct arm_event_s *event, int32_t in);
|
||||
|
||||
/**
|
||||
* Send an event after a specified time
|
||||
*
|
||||
* The event will be sent after the specified number of ticks - to
|
||||
* be precise, it is equivalent to requesting an event at
|
||||
*
|
||||
* eventOS_event_timer_ticks() + ticks + 1
|
||||
*
|
||||
* Because of timer granularity, the elapsed time between issuing the request
|
||||
* and it running may be up to 1 tick more than the specified time.
|
||||
*
|
||||
* eg requesting 2 ticks will cause the event to be sent on the third tick from
|
||||
* now. If requested just after a tick, the delay will be nearly 3 ticks, but if
|
||||
* requested just before a tick, the delay will be just over 2 ticks.
|
||||
*
|
||||
* If `after` is < 0, the event will be sent immediately. If it is 0, the event
|
||||
* is sent on the next tick.
|
||||
*
|
||||
* Can also be invoked using the eventOS_event_send_after() macro in eventOS_event.h
|
||||
*
|
||||
* \param event event to send
|
||||
* \param after tick delay for event
|
||||
*
|
||||
* \return pointer to timer structure on success
|
||||
* \return NULL on error (invalid tasklet_id or allocation failure)
|
||||
*
|
||||
*/
|
||||
#define eventOS_event_timer_request_after(event, after) \
|
||||
eventOS_event_timer_request_in(event, (after) + 1)
|
||||
|
||||
/**
|
||||
* Send an event periodically
|
||||
*
|
||||
* The event will be sent repeatedly using the specified ticks period.
|
||||
*
|
||||
* The first call is sent at
|
||||
*
|
||||
* eventOS_event_timer_ticks() + ticks
|
||||
*
|
||||
* Subsequent events will be sent at N*ticks from the initial time.
|
||||
*
|
||||
* Period will be maintained while the device is awake, regardless of delays to
|
||||
* event scheduling. If an event has not been delivered and completed by the
|
||||
* next scheduled time, the next event will be sent immediately when it
|
||||
* finishes. This could cause a continuous stream of events if unable to keep
|
||||
* up with the period.
|
||||
*
|
||||
* Can also be invoked using the eventOS_event_send_every() macro in eventOS_event.h
|
||||
*
|
||||
* \param event event to send
|
||||
* \param period period for event
|
||||
*
|
||||
* \return pointer to timer structure on success
|
||||
* \return NULL on error (invalid tasklet_id or allocation failure)
|
||||
*
|
||||
*/
|
||||
extern arm_event_storage_t *eventOS_event_timer_request_every(const struct arm_event_s *event, int32_t period);
|
||||
|
||||
/**
|
||||
* Cancel an event timer
|
||||
*
|
||||
* This cancels a pending timed event, matched by event_id and tasklet_id.
|
||||
*
|
||||
* \param event_id event_id for event
|
||||
* \param tasklet_id receiver for event
|
||||
*
|
||||
* \return 0 on success
|
||||
* \return -1 on error (event not found)
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_event_timer_cancel(uint8_t snmessage, int8_t tasklet_id);
|
||||
extern int8_t eventOS_event_timer_cancel(uint8_t event_id, int8_t tasklet_id);
|
||||
|
||||
/**
|
||||
* System Timer shortest time in milli seconds
|
||||
|
|
@ -56,8 +221,8 @@ typedef struct timeout_entry_t timeout_t;
|
|||
|
||||
/** Request timeout callback.
|
||||
*
|
||||
* Create timeout request for specific callback. Maximum 255 timeouts can be requested.
|
||||
* Not thread safe. Should not be called from interrupt context.
|
||||
* Create timeout request for specific callback.
|
||||
*
|
||||
* \param ms timeout in milliseconds. Maximum range is same as for eventOS_event_timer_request().
|
||||
* \param callback function to call after timeout
|
||||
* \param arg arquement to pass to callback
|
||||
|
|
@ -65,8 +230,19 @@ typedef struct timeout_entry_t timeout_t;
|
|||
*/
|
||||
timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg);
|
||||
|
||||
/** Request periodic callback.
|
||||
*
|
||||
* Create timeout request for specific callback. Called periodically until eventOS_timeout_cancel() is called.
|
||||
*
|
||||
* \param every period in milliseconds. Maximum range is same as for eventOS_event_timer_request().
|
||||
* \param callback function to call after timeout
|
||||
* \param arg arquement to pass to callback
|
||||
* \return pointer to timeout structure or NULL on errors
|
||||
*/
|
||||
timeout_t *eventOS_timeout_every_ms(void (*callback)(void *), uint32_t every, void *arg);
|
||||
|
||||
/** Cancell timeout request.
|
||||
* Not thread safe. Should not be called from interrupt context.
|
||||
*
|
||||
* \param t timeout request id.
|
||||
*/
|
||||
void eventOS_timeout_cancel(timeout_t *t);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef NS_EXCLUDE_HIGHRES_TIMER
|
||||
/**
|
||||
* \brief This function perform timer init.
|
||||
*/
|
||||
|
|
@ -56,6 +58,8 @@ extern void platform_timer_disable(void);
|
|||
*/
|
||||
extern uint16_t platform_timer_get_remaining_slots(void);
|
||||
|
||||
#endif // NS_EXCLUDE_HIGHRES_TIMER
|
||||
|
||||
#ifdef NS_EVENTLOOP_USE_TICK_TIMER
|
||||
/**
|
||||
* \brief This function is API for registering low resolution tick timer callback. Also does
|
||||
|
|
|
|||
|
|
@ -17,9 +17,15 @@
|
|||
#define EVENTLOOP_CONFIG_H_
|
||||
|
||||
/*
|
||||
* Undefine all internal flags before evaluating the configuration
|
||||
* Options can be picked up from mbed-cli JSON configuration, or from
|
||||
* Yotta JSON configuration, or from a user configuration file - see below.
|
||||
*
|
||||
* Undefine all internal flags before evaluating the configuration.
|
||||
*/
|
||||
|
||||
/* Use platform-provided low-resolution tick timer for eventloop (requires "platform_tick_timer" API) */
|
||||
#undef NS_EVENTLOOP_USE_TICK_TIMER
|
||||
/* Exclude high resolution timer from build (removes need for "platform_timer" API) */
|
||||
#undef NS_EXCLUDE_HIGHRES_TIMER
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -21,37 +21,36 @@
|
|||
#include "timer_sys.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "ns_timer.h"
|
||||
|
||||
#include "event.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
|
||||
|
||||
typedef struct arm_core_tasklet_list_s {
|
||||
typedef struct arm_core_tasklet {
|
||||
int8_t id; /**< Event handler Tasklet ID */
|
||||
void (*func_ptr)(arm_event_s *);
|
||||
ns_list_link_t link;
|
||||
} arm_core_tasklet_list_s;
|
||||
} arm_core_tasklet_t;
|
||||
|
||||
typedef struct arm_core_event_s {
|
||||
arm_event_s data;
|
||||
ns_list_link_t link;
|
||||
} arm_core_event_s;
|
||||
static NS_LIST_DEFINE(arm_core_tasklet_list, arm_core_tasklet_t, link);
|
||||
static NS_LIST_DEFINE(event_queue_active, arm_event_storage_t, link);
|
||||
static NS_LIST_DEFINE(free_event_entry, arm_event_storage_t, link);
|
||||
|
||||
static NS_LIST_DEFINE(arm_core_tasklet_list, arm_core_tasklet_list_s, link);
|
||||
static NS_LIST_DEFINE(event_queue_active, arm_core_event_s, link);
|
||||
static NS_LIST_DEFINE(free_event_entry, arm_core_event_s, link);
|
||||
// Statically allocate initial pool of events.
|
||||
#define STARTUP_EVENT_POOL_SIZE 10
|
||||
static arm_event_storage_t startup_event_pool[STARTUP_EVENT_POOL_SIZE];
|
||||
|
||||
/** Curr_tasklet tell to core and platform which task_let is active, Core Update this automatic when switch Tasklet. */
|
||||
int8_t curr_tasklet = 0;
|
||||
|
||||
|
||||
static arm_core_tasklet_list_s *tasklet_dynamically_allocate(void);
|
||||
static arm_core_event_s *event_dynamically_allocate(void);
|
||||
static arm_core_event_s *event_core_get(void);
|
||||
static void event_core_write(arm_core_event_s *event);
|
||||
static arm_core_tasklet_t *tasklet_dynamically_allocate(void);
|
||||
static arm_event_storage_t *event_dynamically_allocate(void);
|
||||
static arm_event_storage_t *event_core_get(void);
|
||||
static void event_core_write(arm_event_storage_t *event);
|
||||
|
||||
static arm_core_tasklet_list_s *event_tasklet_handler_get(uint8_t tasklet_id)
|
||||
static arm_core_tasklet_t *event_tasklet_handler_get(uint8_t tasklet_id)
|
||||
{
|
||||
ns_list_foreach(arm_core_tasklet_list_s, cur, &arm_core_tasklet_list) {
|
||||
ns_list_foreach(arm_core_tasklet_t, cur, &arm_core_tasklet_list) {
|
||||
if (cur->id == tasklet_id) {
|
||||
return cur;
|
||||
}
|
||||
|
|
@ -59,6 +58,11 @@ static arm_core_tasklet_list_s *event_tasklet_handler_get(uint8_t tasklet_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool event_tasklet_handler_id_valid(uint8_t tasklet_id)
|
||||
{
|
||||
return event_tasklet_handler_get(tasklet_id);
|
||||
}
|
||||
|
||||
// XXX this can return 0, but 0 seems to mean "none" elsewhere? Or at least
|
||||
// curr_tasklet is reset to 0 in various places.
|
||||
static int8_t tasklet_get_free_id(void)
|
||||
|
|
@ -75,17 +79,17 @@ static int8_t tasklet_get_free_id(void)
|
|||
|
||||
int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uint8_t init_event_type)
|
||||
{
|
||||
arm_core_event_s *event_tmp;
|
||||
arm_event_storage_t *event_tmp;
|
||||
|
||||
// XXX Do we really want to prevent multiple tasklets with same function?
|
||||
ns_list_foreach(arm_core_tasklet_list_s, cur, &arm_core_tasklet_list) {
|
||||
ns_list_foreach(arm_core_tasklet_t, cur, &arm_core_tasklet_list) {
|
||||
if (cur->func_ptr == handler_func_ptr) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Allocate new
|
||||
arm_core_tasklet_list_s *new = tasklet_dynamically_allocate();
|
||||
arm_core_tasklet_t *new = tasklet_dynamically_allocate();
|
||||
if (!new) {
|
||||
return -2;
|
||||
}
|
||||
|
|
@ -111,44 +115,53 @@ int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uin
|
|||
return new->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send event to event scheduler.
|
||||
*
|
||||
* \param event pointer to pushed event.
|
||||
*
|
||||
* \return 0 Event push OK
|
||||
* \return -1 Memory allocation Fail
|
||||
*
|
||||
*/
|
||||
int8_t eventOS_event_send(arm_event_s *event)
|
||||
int8_t eventOS_event_send(const arm_event_t *event)
|
||||
{
|
||||
int8_t retval = -1;
|
||||
if (event_tasklet_handler_get(event->receiver)) {
|
||||
arm_core_event_s *event_tmp = event_core_get();
|
||||
arm_event_storage_t *event_tmp = event_core_get();
|
||||
if (event_tmp) {
|
||||
event_tmp->data = *event;
|
||||
event_core_write(event_tmp);
|
||||
retval = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static arm_core_event_s *event_dynamically_allocate(void)
|
||||
void eventOS_event_send_user_allocated(arm_event_storage_t *event)
|
||||
{
|
||||
return ns_dyn_mem_alloc(sizeof(arm_core_event_s));
|
||||
event->allocator = ARM_LIB_EVENT_USER;
|
||||
event_core_write(event);
|
||||
}
|
||||
|
||||
static arm_core_tasklet_list_s *tasklet_dynamically_allocate(void)
|
||||
void eventOS_event_send_timer_allocated(arm_event_storage_t *event)
|
||||
{
|
||||
return ns_dyn_mem_alloc(sizeof(arm_core_tasklet_list_s));
|
||||
event->allocator = ARM_LIB_EVENT_TIMER;
|
||||
event_core_write(event);
|
||||
}
|
||||
|
||||
|
||||
arm_core_event_s *event_core_get(void)
|
||||
void eventOS_event_cancel_critical(arm_event_storage_t *event)
|
||||
{
|
||||
arm_core_event_s *event;
|
||||
ns_list_remove(&event_queue_active, event);
|
||||
}
|
||||
|
||||
static arm_event_storage_t *event_dynamically_allocate(void)
|
||||
{
|
||||
arm_event_storage_t *event = ns_dyn_mem_temporary_alloc(sizeof(arm_event_storage_t));
|
||||
if (event) {
|
||||
event->allocator = ARM_LIB_EVENT_DYNAMIC;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
static arm_core_tasklet_t *tasklet_dynamically_allocate(void)
|
||||
{
|
||||
return ns_dyn_mem_alloc(sizeof(arm_core_tasklet_t));
|
||||
}
|
||||
|
||||
arm_event_storage_t *event_core_get(void)
|
||||
{
|
||||
arm_event_storage_t *event;
|
||||
platform_enter_critical();
|
||||
event = ns_list_get_first(&free_event_entry);
|
||||
if (event) {
|
||||
|
|
@ -164,31 +177,48 @@ arm_core_event_s *event_core_get(void)
|
|||
return event;
|
||||
}
|
||||
|
||||
static void event_core_free_push(arm_core_event_s *free)
|
||||
void event_core_free_push(arm_event_storage_t *free)
|
||||
{
|
||||
platform_enter_critical();
|
||||
ns_list_add_to_start(&free_event_entry, free);
|
||||
platform_exit_critical();
|
||||
free->state = ARM_LIB_EVENT_UNQUEUED;
|
||||
|
||||
switch (free->allocator) {
|
||||
case ARM_LIB_EVENT_STARTUP_POOL:
|
||||
platform_enter_critical();
|
||||
ns_list_add_to_start(&free_event_entry, free);
|
||||
platform_exit_critical();
|
||||
break;
|
||||
case ARM_LIB_EVENT_DYNAMIC:
|
||||
// Free all dynamically allocated events.
|
||||
ns_dyn_mem_free(free);
|
||||
break;
|
||||
case ARM_LIB_EVENT_TIMER:
|
||||
// Hand it back to the timer system
|
||||
timer_sys_event_free(free);
|
||||
break;
|
||||
case ARM_LIB_EVENT_USER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static arm_core_event_s *event_core_read(void)
|
||||
static arm_event_storage_t *event_core_read(void)
|
||||
{
|
||||
arm_core_event_s *event;
|
||||
platform_enter_critical();
|
||||
event = ns_list_get_first(&event_queue_active);
|
||||
arm_event_storage_t *event = ns_list_get_first(&event_queue_active);
|
||||
if (event) {
|
||||
event->state = ARM_LIB_EVENT_RUNNING;
|
||||
ns_list_remove(&event_queue_active, event);
|
||||
}
|
||||
platform_exit_critical();
|
||||
return event;
|
||||
}
|
||||
|
||||
void event_core_write(arm_core_event_s *event)
|
||||
void event_core_write(arm_event_storage_t *event)
|
||||
{
|
||||
platform_enter_critical();
|
||||
bool added = false;
|
||||
ns_list_foreach(arm_core_event_s, event_tmp, &event_queue_active) {
|
||||
ns_list_foreach(arm_event_storage_t, event_tmp, &event_queue_active) {
|
||||
// note enum ordering means we're checking if event_tmp is LOWER priority than event
|
||||
if (event_tmp->data.priority > event->data.priority) {
|
||||
ns_list_add_before(&event_queue_active, event_tmp, event);
|
||||
|
|
@ -199,12 +229,25 @@ void event_core_write(arm_core_event_s *event)
|
|||
if (!added) {
|
||||
ns_list_add_to_end(&event_queue_active, event);
|
||||
}
|
||||
event->state = ARM_LIB_EVENT_QUEUED;
|
||||
|
||||
/* Wake From Idle */
|
||||
platform_exit_critical();
|
||||
eventOS_scheduler_signal();
|
||||
}
|
||||
|
||||
// Requires lock to be held
|
||||
arm_event_storage_t *eventOS_event_find_by_id_critical(uint8_t tasklet_id, uint8_t event_id)
|
||||
{
|
||||
ns_list_foreach(arm_event_storage_t, cur, &event_queue_active) {
|
||||
if (cur->data.receiver == tasklet_id && cur->data.event_id == event_id) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Initialize Nanostack Core.
|
||||
|
|
@ -219,12 +262,10 @@ void eventOS_scheduler_init(void)
|
|||
ns_list_init(&event_queue_active);
|
||||
ns_list_init(&arm_core_tasklet_list);
|
||||
|
||||
//Allocate 10 entry
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
arm_core_event_s *event = event_dynamically_allocate();
|
||||
if (event) {
|
||||
ns_list_add_to_start(&free_event_entry, event);
|
||||
}
|
||||
//Add first 10 entries to "free" list
|
||||
for (unsigned i = 0; i < (sizeof(startup_event_pool) / sizeof(startup_event_pool[0])); i++) {
|
||||
startup_event_pool[i].allocator = ARM_LIB_EVENT_STARTUP_POOL;
|
||||
ns_list_add_to_start(&free_event_entry, &startup_event_pool[i]);
|
||||
}
|
||||
|
||||
/* Init Generic timer module */
|
||||
|
|
@ -234,10 +275,9 @@ void eventOS_scheduler_init(void)
|
|||
|
||||
}
|
||||
|
||||
|
||||
int8_t eventOS_scheduler_get_active_tasklet(void)
|
||||
{
|
||||
return curr_tasklet;
|
||||
return curr_tasklet;
|
||||
}
|
||||
|
||||
void eventOS_scheduler_set_active_tasklet(int8_t tasklet)
|
||||
|
|
@ -275,28 +315,34 @@ int eventOS_scheduler_timer_synch_after_sleep(uint32_t sleep_ticks)
|
|||
*/
|
||||
bool eventOS_scheduler_dispatch_event(void)
|
||||
{
|
||||
arm_core_tasklet_list_s *tasklet;
|
||||
arm_core_event_s *cur_event;
|
||||
arm_event_s event;
|
||||
|
||||
curr_tasklet = 0;
|
||||
|
||||
cur_event = event_core_read();
|
||||
if (cur_event) {
|
||||
event = cur_event->data;
|
||||
event_core_free_push(cur_event);
|
||||
tasklet = event_tasklet_handler_get(event.receiver);
|
||||
if (tasklet) {
|
||||
curr_tasklet = event.receiver;
|
||||
/* Tasklet Scheduler Call */
|
||||
tasklet->func_ptr(&event);
|
||||
/* Set Current Tasklet to Idle state */
|
||||
curr_tasklet = 0;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
arm_event_storage_t *cur_event = event_core_read();
|
||||
if (!cur_event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
curr_tasklet = cur_event->data.receiver;
|
||||
|
||||
arm_core_tasklet_t *tasklet = event_tasklet_handler_get(curr_tasklet);
|
||||
/* Do not bother with check for NULL - tasklets cannot be deleted,
|
||||
* and user-facing API eventOS_event_send() has already checked the tasklet
|
||||
* exists, so there is no possible issue there.
|
||||
*
|
||||
* For eventOS_event_send_user_allocated(), it would be a non-recoverable
|
||||
* error to not deliver the message - we have to have a receiver to pass
|
||||
* ownership to. If the lookup fails, let it crash. We want the send call
|
||||
* itself to return void to simplify logic.
|
||||
*/
|
||||
|
||||
/* Tasklet Scheduler Call */
|
||||
tasklet->func_ptr(&cur_event->data);
|
||||
event_core_free_push(cur_event);
|
||||
|
||||
/* Set Current Tasklet to Idle state */
|
||||
curr_tasklet = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void eventOS_scheduler_run_until_idle(void)
|
||||
|
|
@ -319,3 +365,37 @@ NS_NORETURN void eventOS_scheduler_run(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eventOS_cancel(arm_event_storage_t *event)
|
||||
{
|
||||
if (!event) {
|
||||
return;
|
||||
}
|
||||
|
||||
platform_enter_critical();
|
||||
|
||||
/*
|
||||
* Notify timer of cancellation.
|
||||
*/
|
||||
if (event->allocator == ARM_LIB_EVENT_TIMER) {
|
||||
timer_sys_event_cancel_critical(event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove event from the list,
|
||||
* Only queued can be removed, unqued are either timers or stale pointers
|
||||
* RUNNING cannot be removed, we are currenly "in" that event.
|
||||
*/
|
||||
if (event->state == ARM_LIB_EVENT_QUEUED) {
|
||||
eventOS_event_cancel_critical(event);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push back to "free" state
|
||||
*/
|
||||
if (event->state != ARM_LIB_EVENT_RUNNING) {
|
||||
event_core_free_push(event);
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef NS_EVENT_H_
|
||||
#define NS_EVENT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
bool event_tasklet_handler_id_valid(uint8_t tasklet_id);
|
||||
void eventOS_event_send_timer_allocated(arm_event_storage_t *event);
|
||||
|
||||
// This requires lock to be held
|
||||
arm_event_storage_t *eventOS_event_find_by_id_critical(uint8_t tasklet_id, uint8_t event_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*NS_EVENT_H_*/
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
#include "eventOS_event_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "ns_list.h"
|
||||
#include "timer_sys.h"
|
||||
|
||||
#define STARTUP_EVENT 0
|
||||
#define TIMER_EVENT 1
|
||||
|
|
@ -25,11 +26,9 @@
|
|||
struct timeout_entry_t {
|
||||
void (*callback)(void *);
|
||||
void *arg;
|
||||
uint8_t event_id;
|
||||
ns_list_link_t link;
|
||||
arm_event_storage_t *event;
|
||||
};
|
||||
|
||||
static NS_LIST_HEAD(timeout_t, link) timeout_list = NS_LIST_INIT(timeout_list);
|
||||
static int8_t timeout_tasklet_id = -1;
|
||||
|
||||
static void timeout_tasklet(arm_event_s *event)
|
||||
|
|
@ -38,31 +37,29 @@ static void timeout_tasklet(arm_event_s *event)
|
|||
return;
|
||||
}
|
||||
|
||||
timeout_t *found = NULL;
|
||||
ns_list_foreach_safe(timeout_t, cur, &timeout_list) {
|
||||
if (cur->event_id == event->event_id) {
|
||||
found = cur;
|
||||
ns_list_remove(&timeout_list, cur);
|
||||
break;
|
||||
}
|
||||
}
|
||||
timeout_t *t = event->data_ptr;
|
||||
arm_event_storage_t *storage = t->event;
|
||||
sys_timer_struct_s *timer = NS_CONTAINER_OF(storage, sys_timer_struct_s, event);
|
||||
|
||||
if (found) {
|
||||
found->callback(found->arg);
|
||||
ns_dyn_mem_free(found);
|
||||
t->callback(t->arg);
|
||||
|
||||
|
||||
// Check if this was periodic timer
|
||||
if (timer->period == 0) {
|
||||
ns_dyn_mem_free(event->data_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg)
|
||||
static timeout_t *eventOS_timeout_at_(void (*callback)(void *), void *arg, uint32_t at, uint32_t period)
|
||||
{
|
||||
uint16_t count;
|
||||
uint8_t index;
|
||||
timeout_t *e = ns_dyn_mem_alloc(sizeof(timeout_t));
|
||||
if (!e) {
|
||||
arm_event_storage_t *storage;
|
||||
|
||||
timeout_t *timeout = ns_dyn_mem_alloc(sizeof(timeout_t));
|
||||
if (!timeout) {
|
||||
return NULL;
|
||||
}
|
||||
e->callback = callback;
|
||||
e->arg = arg;
|
||||
timeout->callback = callback;
|
||||
timeout->arg = arg;
|
||||
|
||||
// Start timeout taskled if it is not running
|
||||
if (-1 == timeout_tasklet_id) {
|
||||
|
|
@ -73,37 +70,46 @@ timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
// Check that we still have indexes left. We have only 8bit timer id.
|
||||
count = ns_list_count(&timeout_list);
|
||||
if (count >= UINT8_MAX) { // Too big list, timer_id is uint8_t
|
||||
goto FAIL;
|
||||
}
|
||||
arm_event_t event = {
|
||||
.receiver = timeout_tasklet_id,
|
||||
.sender = timeout_tasklet_id,
|
||||
.event_type = TIMER_EVENT,
|
||||
.event_id = TIMER_EVENT,
|
||||
.data_ptr = timeout
|
||||
};
|
||||
|
||||
// Find next free index
|
||||
index = 0;
|
||||
AGAIN:
|
||||
ns_list_foreach(timeout_t, cur, &timeout_list) {
|
||||
if (cur->event_id == index) { // This index was used
|
||||
index++; // Check next one.
|
||||
goto AGAIN; // Start checking from begining of the list, indexes are not in order
|
||||
}
|
||||
}
|
||||
e->event_id = index;
|
||||
ns_list_add_to_end(&timeout_list, e);
|
||||
eventOS_event_timer_request(index, TIMER_EVENT, timeout_tasklet_id, ms);
|
||||
return e;
|
||||
if (period)
|
||||
storage = eventOS_event_timer_request_every(&event, period);
|
||||
else
|
||||
storage = eventOS_event_timer_request_at(&event, at);
|
||||
|
||||
timeout->event = storage;
|
||||
if (storage)
|
||||
return timeout;
|
||||
FAIL:
|
||||
ns_dyn_mem_free(e);
|
||||
ns_dyn_mem_free(timeout);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg)
|
||||
{
|
||||
return eventOS_timeout_at_(callback, arg, eventOS_event_timer_ms_to_ticks(ms)+eventOS_event_timer_ticks(), 0);
|
||||
}
|
||||
|
||||
timeout_t *eventOS_timeout_every_ms(void (*callback)(void *), uint32_t every, void *arg)
|
||||
{
|
||||
return eventOS_timeout_at_(callback, arg, 0, eventOS_event_timer_ms_to_ticks(every));
|
||||
}
|
||||
|
||||
void eventOS_timeout_cancel(timeout_t *t)
|
||||
{
|
||||
ns_list_foreach_safe(timeout_t, cur, &timeout_list) {
|
||||
if (t == cur) {
|
||||
ns_list_remove(&timeout_list, cur);
|
||||
eventOS_event_timer_cancel(cur->event_id, timeout_tasklet_id);
|
||||
ns_dyn_mem_free(cur);
|
||||
}
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
eventOS_cancel(t->event);
|
||||
|
||||
// Defer the freeing until returning from the callback
|
||||
if (t->event->state != ARM_LIB_EVENT_RUNNING) {
|
||||
ns_dyn_mem_free(t);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ typedef struct ns_timer_struct {
|
|||
|
||||
static NS_LIST_DEFINE(ns_timer_list, ns_timer_struct, link);
|
||||
|
||||
|
||||
#define NS_TIMER_RUNNING 1
|
||||
static uint8_t ns_timer_state = 0;
|
||||
|
||||
|
|
@ -347,8 +346,8 @@ int8_t eventOS_callback_timer_stop(int8_t ns_timer_id)
|
|||
current_timer->remaining_slots = 0;
|
||||
|
||||
/*Check if some timer is already active*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_ACTIVE) {
|
||||
ns_list_foreach(ns_timer_struct, curr_timer, &ns_timer_list) {
|
||||
if (curr_timer->timer_state == NS_TIMER_ACTIVE) {
|
||||
active_timer_found = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -357,12 +356,12 @@ int8_t eventOS_callback_timer_stop(int8_t ns_timer_id)
|
|||
if (!active_timer_found) {
|
||||
pl_timer_remaining_slots = platform_timer_get_remaining_slots();
|
||||
/*Find hold-labelled timer with the least remaining slots*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
current_timer->remaining_slots += pl_timer_remaining_slots;
|
||||
ns_list_foreach(ns_timer_struct, cur_timer, &ns_timer_list) {
|
||||
if (cur_timer->timer_state == NS_TIMER_HOLD) {
|
||||
cur_timer->remaining_slots += pl_timer_remaining_slots;
|
||||
|
||||
if (!first_timer || current_timer->remaining_slots < first_timer->remaining_slots) {
|
||||
first_timer = current_timer;
|
||||
if (!first_timer || cur_timer->remaining_slots < first_timer->remaining_slots) {
|
||||
first_timer = cur_timer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -372,12 +371,12 @@ int8_t eventOS_callback_timer_stop(int8_t ns_timer_id)
|
|||
/*Start HAL timer*/
|
||||
ns_timer_start_pl_timer(first_timer->remaining_slots);
|
||||
/*If some of the other hold-labelled timers have the same remaining slots as the timer_tmp, mark them active*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
if (current_timer->remaining_slots == first_timer->remaining_slots) {
|
||||
current_timer->timer_state = NS_TIMER_ACTIVE;
|
||||
ns_list_foreach(ns_timer_struct, cur_timer, &ns_timer_list) {
|
||||
if (cur_timer->timer_state == NS_TIMER_HOLD) {
|
||||
if (cur_timer->remaining_slots == first_timer->remaining_slots) {
|
||||
cur_timer->timer_state = NS_TIMER_ACTIVE;
|
||||
} else {
|
||||
current_timer->remaining_slots -= first_timer->remaining_slots;
|
||||
cur_timer->remaining_slots -= first_timer->remaining_slots;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,17 @@
|
|||
#ifndef NS_TIMER_H_
|
||||
#define NS_TIMER_H_
|
||||
|
||||
#include "platform/eventloop_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef NS_EXCLUDE_HIGHRES_TIMER
|
||||
extern int8_t ns_timer_sleep(void);
|
||||
#else
|
||||
#define ns_timer_sleep() ((int8_t) 0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,34 +18,35 @@
|
|||
#include "timer_sys.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include "platform/arm_hal_timer.h"
|
||||
#include "ns_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_event_timer.h"
|
||||
#include "event.h"
|
||||
#include "eventOS_callback_timer.h"
|
||||
|
||||
#include "ns_timer.h"
|
||||
|
||||
#ifndef ST_MAX
|
||||
#define ST_MAX 6
|
||||
#endif
|
||||
|
||||
typedef struct sys_timer_struct_s {
|
||||
uint32_t timer_sys_launch_time;
|
||||
int8_t timer_sys_launch_receiver;
|
||||
uint8_t timer_sys_launch_message;
|
||||
uint8_t timer_event_type;
|
||||
|
||||
ns_list_link_t link;
|
||||
} sys_timer_struct_s;
|
||||
static sys_timer_struct_s startup_sys_timer_pool[ST_MAX];
|
||||
|
||||
#define TIMER_SLOTS_PER_MS 20
|
||||
#define TIMER_SYS_TICK_PERIOD 10 // milliseconds
|
||||
NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Need whole number of ms per tick")
|
||||
#define TIMER_SYS_TICK_PERIOD (1000 / EVENTOS_EVENT_TIMER_HZ) // milliseconds
|
||||
|
||||
static uint32_t run_time_tick_ticks = 0;
|
||||
static NS_LIST_DEFINE(system_timer_free, sys_timer_struct_s, link);
|
||||
static NS_LIST_DEFINE(system_timer_list, sys_timer_struct_s, link);
|
||||
// timer_sys_ticks must be read in critical section to guarantee
|
||||
// atomicity on 16-bit platforms
|
||||
static volatile uint32_t timer_sys_ticks;
|
||||
|
||||
static NS_LIST_DEFINE(system_timer_free, sys_timer_struct_s, event.link);
|
||||
static NS_LIST_DEFINE(system_timer_list, sys_timer_struct_s, event.link);
|
||||
|
||||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void);
|
||||
static void timer_sys_interrupt(void);
|
||||
static void timer_sys_add(sys_timer_struct_s *timer);
|
||||
|
||||
#ifndef NS_EVENTLOOP_USE_TICK_TIMER
|
||||
static int8_t platform_tick_timer_start(uint32_t period_ms);
|
||||
|
|
@ -89,24 +90,8 @@ static int8_t platform_tick_timer_stop(void)
|
|||
*/
|
||||
void timer_sys_init(void)
|
||||
{
|
||||
run_time_tick_ticks = 0;
|
||||
|
||||
// Clear old timers
|
||||
ns_list_foreach_safe(sys_timer_struct_s, temp, &system_timer_list) {
|
||||
ns_list_remove(&system_timer_list, temp);
|
||||
ns_dyn_mem_free(temp);
|
||||
}
|
||||
// Clear old free timer entrys
|
||||
ns_list_foreach_safe(sys_timer_struct_s, temp, &system_timer_free) {
|
||||
ns_list_remove(&system_timer_free, temp);
|
||||
ns_dyn_mem_free(temp);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < ST_MAX; i++) {
|
||||
sys_timer_struct_s *temp = sys_timer_dynamically_allocate();
|
||||
if (temp) {
|
||||
ns_list_add_to_start(&system_timer_free, temp);
|
||||
}
|
||||
ns_list_add_to_start(&system_timer_free, &startup_sys_timer_pool[i]);
|
||||
}
|
||||
|
||||
platform_tick_timer_register(timer_sys_interrupt);
|
||||
|
|
@ -141,7 +126,7 @@ static void timer_sys_interrupt(void)
|
|||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void)
|
||||
{
|
||||
return (sys_timer_struct_s*)ns_dyn_mem_alloc(sizeof(sys_timer_struct_s));
|
||||
return ns_dyn_mem_alloc(sizeof(sys_timer_struct_s));
|
||||
}
|
||||
|
||||
static sys_timer_struct_s *timer_struct_get(void)
|
||||
|
|
@ -158,23 +143,149 @@ static sys_timer_struct_s *timer_struct_get(void)
|
|||
return timer;
|
||||
}
|
||||
|
||||
uint32_t timer_get_runtime_ticks(void) // only used in dev_stats_internal.c
|
||||
void timer_sys_event_free(arm_event_storage_t *event)
|
||||
{
|
||||
platform_enter_critical();
|
||||
sys_timer_struct_s *timer = NS_CONTAINER_OF(event, sys_timer_struct_s, event);
|
||||
if (timer->period == 0) {
|
||||
// Non-periodic - return to free list
|
||||
ns_list_add_to_start(&system_timer_free, timer);
|
||||
} else {
|
||||
// Periodic - check due time of next launch
|
||||
timer->launch_time += timer->period;
|
||||
if (TICKS_BEFORE_OR_AT(timer->launch_time, timer_sys_ticks)) {
|
||||
// next event is overdue - queue event now
|
||||
eventOS_event_send_timer_allocated(&timer->event);
|
||||
} else {
|
||||
// add back to timer queue for the future
|
||||
timer_sys_add(timer);
|
||||
}
|
||||
}
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
void timer_sys_event_cancel_critical(struct arm_event_storage *event)
|
||||
{
|
||||
sys_timer_struct_s *timer = NS_CONTAINER_OF(event, sys_timer_struct_s, event);
|
||||
timer->period = 0;
|
||||
// If its unqueued it is on my timer list, otherwise it is in event-loop.
|
||||
if (event->state == ARM_LIB_EVENT_UNQUEUED) {
|
||||
ns_list_remove(&system_timer_list, timer);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t eventOS_event_timer_ticks(void)
|
||||
{
|
||||
uint32_t ret_val;
|
||||
// Enter/exit critical is a bit clunky, but necessary on 16-bit platforms,
|
||||
// which won't be able to do an atomic 32-bit read.
|
||||
platform_enter_critical();
|
||||
ret_val = run_time_tick_ticks;
|
||||
ret_val = timer_sys_ticks;
|
||||
platform_exit_critical();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int8_t eventOS_event_timer_request(uint8_t snmessage, uint8_t event_type, int8_t tasklet_id, uint32_t time)
|
||||
/* Called internally with lock held */
|
||||
static void timer_sys_add(sys_timer_struct_s *timer)
|
||||
{
|
||||
int8_t res = -1;
|
||||
sys_timer_struct_s *timer = NULL;
|
||||
uint32_t at = timer->launch_time;
|
||||
|
||||
// Find first timer scheduled to run after us, and insert before it.
|
||||
// (This means timers scheduled for same time run in order of request)
|
||||
ns_list_foreach(sys_timer_struct_s, t, &system_timer_list) {
|
||||
if (TICKS_BEFORE(at, t->launch_time)) {
|
||||
ns_list_add_before(&system_timer_list, t, timer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't insert before another timer, so must be last.
|
||||
ns_list_add_to_end(&system_timer_list, timer);
|
||||
}
|
||||
|
||||
/* Called internally with lock held */
|
||||
static arm_event_storage_t *eventOS_event_timer_request_at_(const arm_event_t *event, uint32_t at, uint32_t period)
|
||||
{
|
||||
// Because we use user-allocated events, they must get delivered to avoid
|
||||
// a leak. Previously this call queued timers for invalid tasks, then they
|
||||
// would go undelivered. Now it returns an error.
|
||||
if (!event_tasklet_handler_id_valid(event->receiver)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sys_timer_struct_s *timer = timer_struct_get();
|
||||
if (!timer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timer->event.data = *event;
|
||||
timer->event.allocator = ARM_LIB_EVENT_TIMER;
|
||||
timer->event.state = ARM_LIB_EVENT_UNQUEUED;
|
||||
timer->launch_time = at;
|
||||
timer->period = period;
|
||||
|
||||
if (TICKS_BEFORE_OR_AT(at, timer_sys_ticks)) {
|
||||
eventOS_event_send_timer_allocated(&timer->event);
|
||||
} else {
|
||||
timer_sys_add(timer);
|
||||
}
|
||||
|
||||
return &timer->event;
|
||||
}
|
||||
|
||||
arm_event_storage_t *eventOS_event_timer_request_at(const arm_event_t *event, uint32_t at)
|
||||
{
|
||||
platform_enter_critical();
|
||||
|
||||
arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, at, 0);
|
||||
|
||||
platform_exit_critical();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
arm_event_storage_t *eventOS_event_timer_request_in(const arm_event_t *event, int32_t in)
|
||||
{
|
||||
platform_enter_critical();
|
||||
|
||||
arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, timer_sys_ticks + in, 0);
|
||||
|
||||
platform_exit_critical();
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
arm_event_storage_t *eventOS_event_timer_request_every(const arm_event_t *event, int32_t period)
|
||||
{
|
||||
if (period <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
platform_enter_critical();
|
||||
|
||||
arm_event_storage_t *ret = eventOS_event_timer_request_at_(event, timer_sys_ticks + period, period);
|
||||
|
||||
platform_exit_critical();
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int8_t eventOS_event_timer_request(uint8_t event_id, uint8_t event_type, int8_t tasklet_id, uint32_t time)
|
||||
{
|
||||
const arm_event_t event = {
|
||||
.event_id = event_id,
|
||||
.event_type = event_type,
|
||||
.receiver = tasklet_id,
|
||||
.sender = 0,
|
||||
.data_ptr = NULL,
|
||||
.event_data = 0,
|
||||
.priority = ARM_LIB_MED_PRIORITY_EVENT,
|
||||
};
|
||||
|
||||
// Legacy time behaviour preserved
|
||||
|
||||
// Note that someone wanting 20ms gets 2 ticks, thanks to this test. 30ms would be 4 ticks.
|
||||
// And why shouldn't they be able to get a 1-tick callback?
|
||||
if (time > 2 * TIMER_SYS_TICK_PERIOD) {
|
||||
|
|
@ -184,75 +295,76 @@ int8_t eventOS_event_timer_request(uint8_t snmessage, uint8_t event_type, int8_t
|
|||
} else {
|
||||
time = 2;
|
||||
}
|
||||
timer = timer_struct_get();
|
||||
if (timer) {
|
||||
timer->timer_sys_launch_message = snmessage;
|
||||
timer->timer_sys_launch_receiver = tasklet_id;
|
||||
timer->timer_event_type = event_type;
|
||||
timer->timer_sys_launch_time = time;
|
||||
ns_list_add_to_start(&system_timer_list, timer);
|
||||
res = 0;
|
||||
}
|
||||
|
||||
platform_enter_critical();
|
||||
arm_event_storage_t *ret = eventOS_event_timer_request_at_(&event, timer_sys_ticks + time, 0);
|
||||
platform_exit_critical();
|
||||
return res;
|
||||
return ret?0:-1;
|
||||
}
|
||||
|
||||
int8_t eventOS_event_timer_cancel(uint8_t snmessage, int8_t tasklet_id)
|
||||
int8_t eventOS_event_timer_cancel(uint8_t event_id, int8_t tasklet_id)
|
||||
{
|
||||
int8_t res = -1;
|
||||
platform_enter_critical();
|
||||
|
||||
/* First check pending timers */
|
||||
ns_list_foreach(sys_timer_struct_s, cur, &system_timer_list) {
|
||||
if (cur->timer_sys_launch_receiver == tasklet_id && cur->timer_sys_launch_message == snmessage) {
|
||||
ns_list_remove(&system_timer_list, cur);
|
||||
ns_list_add_to_start(&system_timer_free, cur);
|
||||
res = 0;
|
||||
break;
|
||||
if (cur->event.data.receiver == tasklet_id && cur->event.data.event_id == event_id) {
|
||||
eventOS_cancel(&cur->event);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
return res;
|
||||
}
|
||||
/* No pending timer, so check for already-pending event */
|
||||
arm_event_storage_t *event = eventOS_event_find_by_id_critical(tasklet_id, event_id);
|
||||
if (event && event->allocator == ARM_LIB_EVENT_TIMER) {
|
||||
eventOS_cancel(event);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* No match found */
|
||||
platform_exit_critical();
|
||||
return -1;
|
||||
|
||||
done:
|
||||
platform_exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t eventOS_event_timer_shortest_active_timer(void)
|
||||
{
|
||||
uint32_t ret_val = 0;
|
||||
|
||||
platform_enter_critical();
|
||||
ns_list_foreach(sys_timer_struct_s, cur, &system_timer_list) {
|
||||
if (ret_val == 0 || cur->timer_sys_launch_time < ret_val) {
|
||||
ret_val = cur->timer_sys_launch_time;
|
||||
}
|
||||
sys_timer_struct_s *first = ns_list_get_first(&system_timer_list);
|
||||
if (first == NULL) {
|
||||
// Weird API has 0 for "no events"
|
||||
ret_val = 0;
|
||||
} else if (TICKS_BEFORE_OR_AT(first->launch_time, timer_sys_ticks)) {
|
||||
// Which means an immediate/overdue event has to be 1
|
||||
ret_val = 1;
|
||||
} else {
|
||||
ret_val = first->launch_time - timer_sys_ticks;
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
//Convert ticks to ms
|
||||
ret_val *= TIMER_SYS_TICK_PERIOD;
|
||||
return ret_val;
|
||||
return eventOS_event_timer_ticks_to_ms(ret_val);
|
||||
}
|
||||
|
||||
void system_timer_tick_update(uint32_t ticks)
|
||||
{
|
||||
platform_enter_critical();
|
||||
//Keep runtime time
|
||||
run_time_tick_ticks += ticks;
|
||||
timer_sys_ticks += ticks;
|
||||
ns_list_foreach_safe(sys_timer_struct_s, cur, &system_timer_list) {
|
||||
if (cur->timer_sys_launch_time <= ticks) {
|
||||
arm_event_s event = {
|
||||
.receiver = cur->timer_sys_launch_receiver,
|
||||
.sender = 0, /**< Event sender Tasklet ID */
|
||||
.data_ptr = NULL,
|
||||
.event_type = cur->timer_event_type,
|
||||
.event_id = cur->timer_sys_launch_message,
|
||||
.event_data = 0,
|
||||
.priority = ARM_LIB_MED_PRIORITY_EVENT,
|
||||
};
|
||||
eventOS_event_send(&event);
|
||||
if (TICKS_BEFORE_OR_AT(cur->launch_time, timer_sys_ticks)) {
|
||||
// Unthread from our list
|
||||
ns_list_remove(&system_timer_list, cur);
|
||||
ns_list_add_to_start(&system_timer_free, cur);
|
||||
// Make it an event (can't fail - no allocation)
|
||||
// event system will call our timer_sys_event_free on event delivery.
|
||||
eventOS_event_send_timer_allocated(&cur->event);
|
||||
} else {
|
||||
cur->timer_sys_launch_time -= ticks;
|
||||
// List is ordered, so as soon as we see a later event, we're done.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,16 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "eventOS_event.h"
|
||||
|
||||
/* We borrow base event storage, including its list link, and add a time field */
|
||||
typedef struct sys_timer_struct_s {
|
||||
arm_event_storage_t event;
|
||||
uint32_t launch_time; // tick value
|
||||
uint32_t period;
|
||||
} sys_timer_struct_s;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize system timer
|
||||
* */
|
||||
|
|
@ -28,6 +38,10 @@ extern void timer_sys_init(void);
|
|||
extern uint32_t timer_get_runtime_ticks(void);
|
||||
int8_t timer_sys_wakeup(void);
|
||||
void timer_sys_disable(void);
|
||||
void timer_sys_event_free(struct arm_event_storage *event);
|
||||
|
||||
// This require lock to be held
|
||||
void timer_sys_event_cancel_critical(struct arm_event_storage *event);
|
||||
|
||||
/**
|
||||
* System Timer update and synch after sleep
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1954,7 +1954,7 @@ INCLUDE_FILE_PATTERNS =
|
|||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED =
|
||||
PREDEFINED = DOXYGEN
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
|
|
|
|||
|
|
@ -1,31 +1,14 @@
|
|||
ARM IPV6/6LoWPAN stack.
|
||||
=======================
|
||||
|
||||
This repository contains the ARM IPv6/6LoWPAN Stack for mbed OS.
|
||||
This repository contains the ARM IPv6/6LoWPAN/Thread Stack for mbed OS.
|
||||
|
||||

|
||||
|
||||
mbed OS is now a Thread Certified Component. Using IPv6 with 6LoWPAN as the foundation, Thread technology provides a low-power, self-healing mesh network designed for the home.
|
||||
|
||||
The documentation is hosted in http://docs.mbed.com/projects/arm-ipv66lowpan-stack/
|
||||
|
||||
On mbed OS, the preferred usage is through [mbed Mesh API](https://github.com/ARMmbed/mbed-mesh-api) that provides the required wrappers between the socket abstraction layer and this stack.
|
||||
|
||||
To see, how the 6LoWPAN Stack works, check the example application [mbed-client-example-6lowpan](https://github.com/ARMmbed/mbed-client-example-6lowpan).
|
||||
|
||||
You can find he known limitations here: [sal-iface-6lowpan](https://github.com/ARMmbed/sal-iface-6lowpan).
|
||||
|
||||
## Changes in Nanostack 4.0:
|
||||
|
||||
### New APIs:
|
||||
|
||||
- MLE router and host lifetime configuration API
|
||||
- MLE neighbor limits configuration API
|
||||
- MLE token bucket configuration API
|
||||
- API for adding/deleting routes
|
||||
- FHSS API
|
||||
|
||||
### Other changes:
|
||||
|
||||
- Function `arm_nwk_6lowpan_link_scan_paramameter_set()` renamed to `arm_nwk_6lowpan_link_scan_parameter_set()` (due to misspelling)
|
||||
- Channel mask settings API changed
|
||||
- The parameters of function `cca_start()` changed
|
||||
|
||||
For instructions on updating your modules, see https://docs.mbed.com/docs/arm-ipv66lowpan-stack/en/latest/api_changes_to_v4_0_0/index.html.
|
||||
On mbed OS, usage is through [mbed Mesh API](https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/communication/mesh/) and [Socket API](https://docs.mbed.com/docs/mbed-os-api-reference/en/latest/APIs/communication/network_sockets/).
|
||||
|
||||
To see, how the 6LoWPAN Stack works, check the example application [mbed-os-example-mesh-minimal](https://github.com/ARMmbed/mbed-os-example-mesh-minimal).
|
||||
|
|
|
|||
|
|
@ -43,4 +43,6 @@ The reference manual contains several chapters; you can read them in sequence, b
|
|||
|
||||
13. [**Thread Related APIs**](thread_APIs.md):Read this to familiarize yourself with the Thread protocol related APIs.
|
||||
|
||||
14. [**Load balancing API**](17_API_load_balancer.md):Read this to familiarize yourself with the Load balancing API
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ An application should register at least one event handler. The tasklets are then
|
|||
The following is a prototype of a tasklet:
|
||||
|
||||
```
|
||||
void tasklet (arm_event_s *)
|
||||
void tasklet (arm_event_t *)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`arm_event_s`|A pointer to the event structure that contains the event information.
|
||||
`arm_event_t`|A pointer to the event structure that contains the event information.
|
||||
|
||||
|
||||
The most important event information is the event type. There are four main types of events that a tasklet may receive. _Table 3-2_ lists the event types.
|
||||
|
|
@ -43,7 +43,7 @@ The most important event information is the event type. There are four main type
|
|||
|
||||
Event type|Description
|
||||
----------|-----------
|
||||
`ARM_LIB_TASKLET_INIT_EVENT`|Can be used as an initialization event to a tasklet, when it is created. Initialization event will be called only once.
|
||||
`ARM_LIB_TASKLET_INIT_EVENT`|Can be used as an initialization event to a tasklet, when it is created. The initialization event is called only once.
|
||||
`ARM_LIB_NWK_INTERFACE_EVENT`|These event types give information about networking bootstrap to the application layer.
|
||||
`ARM_LIB_SYSTEM_TIMER_EVENT`|These events are user-launched timer events. They are used for timing events on an application.
|
||||
`APPLICATION_EVENT`|These events are sent from another tasklet and they do not originate from the stack. These are used for communicating between tasklets.
|
||||
|
|
@ -54,7 +54,7 @@ The rest of the information is stored in the event structure received by the tas
|
|||
The following example shows the basic structure of an empty tasklet:
|
||||
|
||||
```
|
||||
void tasklet(arm_event_s *event)
|
||||
void tasklet(arm_event_t *event)
|
||||
{
|
||||
switch(event->event_type) {
|
||||
case ARM_LIB_TASKLET_INIT_EVENT:
|
||||
|
|
@ -84,7 +84,7 @@ To register a tasklet handler:
|
|||
```
|
||||
int8_t eventOS_event_handler_create
|
||||
(
|
||||
void (*tasklet_func_ptr)(arm_event_s*),
|
||||
void (*tasklet_func_ptr)(arm_event_t*),
|
||||
uint8_t init_event_type
|
||||
)
|
||||
```
|
||||
|
|
@ -114,7 +114,7 @@ typedef struct arm_event_s
|
|||
void *data_ptr;
|
||||
arm_library_event_priority_e priority;
|
||||
uint32_t event_data;
|
||||
} arm_event_s;
|
||||
} arm_event_t;
|
||||
```
|
||||
|
||||
Member|Description
|
||||
|
|
@ -124,7 +124,7 @@ Member|Description
|
|||
`event_type`|Represents the `typecast arm_library_event_type_e`.
|
||||
`event_id`|Timer ID, NWK interface ID or an application-specific ID.
|
||||
`data_ptr`|Application's ability to share a data pointer tasklet with a tasklet.
|
||||
`priority`|Task priority.
|
||||
`priority`|Event priority.
|
||||
`event_data`|Extra event data. Used in network events.
|
||||
|
||||
### Reference events
|
||||
|
|
@ -228,6 +228,7 @@ Name|Value
|
|||
----|-----
|
||||
`receiver`|Tasklet ID for the selected tasklet.
|
||||
`sender`|Tasklet ID for the sender.
|
||||
`priority`|Relative delivery priority (low, medium or high)
|
||||
`event_type`|Developer-defined event type.
|
||||
`event_data`|Developer can give a 32-bit data value, if required.
|
||||
`event_id`|Developer-defined ID.
|
||||
|
|
@ -240,7 +241,7 @@ To send an event:
|
|||
```
|
||||
int8_t eventOS_event_send
|
||||
(
|
||||
arm_event_s *event
|
||||
const arm_event_t *event
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -259,14 +260,48 @@ An example of sending an event from interrupt:
|
|||
```
|
||||
void xx_button_interrupt_handler(void)
|
||||
{
|
||||
arm_event_s event = {0};
|
||||
arm_event_t event = {0};
|
||||
/*Example of sending event to the application.
|
||||
event.event is user-defined event.
|
||||
In this application S1_BUTTON event is sent when IRQD interrupt occurs */
|
||||
event.receiver = main_tasklet_id
|
||||
event.sender = main_tasklet_id;
|
||||
event.priority = ARM_LIB_MED_PRIORITY_EVENT;
|
||||
event.event_type = APPLICATION_EVENT;
|
||||
event.event_id = S1_BUTTON;
|
||||
eventOS_event_send(&event);
|
||||
}
|
||||
```
|
||||
|
||||
To end a user-allocated event, avoiding the possibility of memory
|
||||
allocation failure:
|
||||
|
||||
```
|
||||
void eventOS_event_send_user_allocated
|
||||
(
|
||||
arm_event_storage_t *event
|
||||
)
|
||||
```
|
||||
|
||||
This sends an event, but without taking a copy of the event data. The event
|
||||
structure must remain valid until the event is delivered. See the
|
||||
documentation comments on the declaration for more details.
|
||||
|
||||
To send periodic events or events after a timeout, refer to [Library Timer API](10_API_timer.md).
|
||||
|
||||
### Cancelling an event
|
||||
|
||||
To cancel and event or timer before it is executed, call `eventOS_cancel()`
|
||||
|
||||
```
|
||||
void eventOS_cancel(arm_event_storage_t *event);
|
||||
```
|
||||
|
||||
Queued events are removed from the event-loop queue and/or the timer queue.
|
||||
Passing a NULL pointer is allowed, and it does nothing.
|
||||
|
||||
Event pointers are valid from the time they are queued until the event has stopped running or is cancelled.
|
||||
Cancelling a currently running event is only useful when you want to stop scheduling it, provided that it is on a periodic timer;
|
||||
it has no other effect.
|
||||
|
||||
Cancelling an already cancelled or already run single-shot event is undefined behaviour.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Network Definition APIs
|
||||
Network Definition APIs
|
||||
======================
|
||||
|
||||
This chapter describes the Network API that includes functionalities, such as network tasks, network authentication, and security. It contains the following sections:
|
||||
|
|
@ -231,14 +231,16 @@ To set a callback for storing PANA key material, use the following function. Bef
|
|||
```
|
||||
int8_t pana_client_nvm_callback_set
|
||||
(
|
||||
void (*passed_fptr)(pana_client_nvm_update_process_t),
|
||||
pana_client_session_update_cb *nvm_update,
|
||||
pana_client_session_get_cb *nvm_get,
|
||||
uint8_t * nvm_static_buffer
|
||||
);
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`passed_fptr`|A pointer to the callback function.
|
||||
`nvm_update`|A pointer to the callback function for session udate and removal.
|
||||
`nvm_get`|A pointer to the callback function for read session from NVM.
|
||||
`nvm_static_buffer`|A pointer to the allocated buffer. The required size is 86 bytes.
|
||||
|
||||
<dl>
|
||||
|
|
@ -253,14 +255,14 @@ The callback function is called whenever the stack acquires new keys. The parame
|
|||
typedef enum pana_client_nvm_update_process_t
|
||||
{
|
||||
PANA_CLIENT_SESSION_UPDATE,
|
||||
PANA_CLIENT_SESSION_SEQ_UPDATE,
|
||||
PANA_CLIENT_SESSION_REMOVE,
|
||||
}pana_client_nvm_update_process_t;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`PANA_CLIENT_SESSION_UPDATE`|Full update of PANA session information.
|
||||
`PANA_CLIENT_SESSION_SEQ_UPDATE`|An update of the REQ and RES sequence number of a PANA key pull or push operation.
|
||||
`PANA_CLIENT_SESSION_REMOVE`|Current session for the given PAN ID can be removed.
|
||||
|
||||
When a callback takes place with the parameter `PANA_CLIENT_SESSION_UPDATE`, the first 16 bytes in the data buffer are PANA session address and the following 70 bytes PANA session keys. The session address is associated with the node's parent address, so that is most probably required only on star topology networks. On the mesh network, the parent address can change, so storing the session address is unnecessary.
|
||||
|
||||
|
|
@ -271,41 +273,31 @@ An example of a session saving functionality when the session address is not sto
|
|||
```
|
||||
#define PANA_SESSION_ADDRESS_SIZE 16
|
||||
#define PANA_SESSION_KEY_SIZE 70
|
||||
void pana_resume_callback(pana_client_nvm_update_process_t event)
|
||||
void pana_resume_callback(uint16_t pan_id, pana_client_nvm_update_process_t event)
|
||||
{
|
||||
if (PANA_CLIENT_SESSION_UPDATE == event) {
|
||||
// store now the Session keys, skip the session address
|
||||
//Discover by given pan-id
|
||||
write_to_storage(nvm_static_buffer+PANA_SESSION_ADDRESS_SIZE, PANA_SESSION_KEY_SIZE);
|
||||
} else if (PANA_CLIENT_SESSION_UPDATE == event) {
|
||||
//Discover by given pan-id and remove from NVM
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To resume the PANA session:
|
||||
An example for session get callback:
|
||||
|
||||
```
|
||||
int8_t net_pana_client_session_nvm_data_load
|
||||
(
|
||||
uint8_t *data_buffer,
|
||||
uint8_t *session_address,
|
||||
int8_t interface_id
|
||||
);
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`data_buffer`|A pointer to the PANA session keys.
|
||||
`session_address`|A pointer to the PANA session address, or NULL if no session address information is stored.
|
||||
`interface_id`|The interface ID for a 6LoWPAN interface.
|
||||
|
||||
When you give a `NULL` pointer to `session_address`, the function only restores the PANA keys and can then associate with any parent from the same network. This functionality is required on the mesh topology.
|
||||
|
||||
A client can keep track of a single PANA session or multiple PANA sessions using the enumeration below. Single session mode is set by default.
|
||||
|
||||
```
|
||||
typedef enum {
|
||||
NET_PANA_SINGLE_SESSION,
|
||||
NET_PANA_MULTI_SESSION,
|
||||
} net_pana_session_mode_e;
|
||||
bool pana_nvm_read_callback(uint16_t pan_id)
|
||||
{
|
||||
//Discover by given pan-id and remove from NVM
|
||||
if (discover_session_from_nvm_by_pan_id(pan_id)) {
|
||||
|
||||
//Write session to static memory buffer
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
#### Server side API
|
||||
|
|
@ -319,15 +311,19 @@ The next step is to set a PANA key update callback that receives the key materia
|
|||
```
|
||||
int8_t pana_server_nvm_callback_set
|
||||
(
|
||||
uint16_t (*passed_fptr)(pana_nvm_update_process_t),
|
||||
pana_server_update_cb *update_cb,
|
||||
pana_server_session_get_cb *nvm_get,
|
||||
pana_server_session_get_by_id_cb *nvm_session_get,
|
||||
uint8_t * nvm_static_buffer
|
||||
);
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`passed_fptr`|A pointer to the callback function.
|
||||
`nvm_static_buffer`|A pointer to the buffer used to store the PANA keys.
|
||||
`update_cb`|A pointer to the callback function.
|
||||
`nvm_get`|A pointer to the callback function to read the client session by session address.
|
||||
`nvm_session_get`|A pointer to the callback function to read the client session by PANA session ID.
|
||||
`nvm_static_buffer`|A pointer to the buffer used for storing the PANA keys.
|
||||
|
||||
<dl>
|
||||
<dt>Return value:</dt>
|
||||
|
|
@ -342,7 +338,6 @@ typedef enum pana_nvm_update_process_t
|
|||
{
|
||||
PANA_SERVER_MATERIAL_UPDATE,
|
||||
PANA_SERVER_CLIENT_SESSION_UPDATE,
|
||||
PANA_SERVER_CLIENT_SESSION_SEQ_UPDATE,
|
||||
PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE,
|
||||
}pana_nvm_update_process_t;
|
||||
```
|
||||
|
|
@ -351,19 +346,19 @@ Parameter|Description
|
|||
---------|-----------
|
||||
`PANA_SERVER_MATERIAL_UPDATE`|An update of the PANA server security material.
|
||||
`PANA_SERVER_CLIENT_SESSION_UPDATE`|An update of the PANA client session.
|
||||
`PANA_SERVER_CLIENT_SESSION_SEQ_UPDATE`|A sequence number update of the PANA client session.
|
||||
`PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE`|Removes the PANA client session.
|
||||
|
||||
The buffer that is used to transfer data from the PANA process to the storage can contain server keys or client session data. When the server keys are stored, the buffer size is 90 bytes. On the client sessions, it depends on the event that the buffer contains.
|
||||
|
||||
When client session data is stored, the buffer is divided into the following parts:
|
||||
|
||||
1. Session addresses, 20 bytes, containing the following parts:
|
||||
1. 16 bytes offset, 2 bytes.
|
||||
1. Session addresses, 24 bytes, containing the following parts:
|
||||
1. 16-bit offset, 2 bytes.
|
||||
2. Client session IPv6 address, 16 bytes.
|
||||
3. Client port number, 2 bytes.
|
||||
4. Pana session Id, 4-bytes
|
||||
2. PANA client session data, 33 bytes.
|
||||
3. PANA client session private keys, 63 bytes.
|
||||
3. PANA client session private keys, 59 bytes.
|
||||
|
||||
Not all segments are valid by each call. The parameter that is passed to the callback function defines the parts that are valid. _Table 3-12_ defines the segments.
|
||||
|
||||
|
|
@ -376,7 +371,7 @@ Not all segments are valid by each call. The parameter that is passed to the cal
|
|||
|`PANA_SERVER_CLIENT_SESSION_SEQ_UPDATE`|Update only the client session data. The first two segments are stored in the buffer.<br>The callback should use the offset field to determine which session data this is.|
|
||||
|`PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE`|Remove the previously stored session. Only the first segment is stored in the buffer.<br>The callback should use the offset field to determine which session data this is.|
|
||||
|
||||
The following example shows the basic functionality of the PANA server callback:
|
||||
The following example shows the basic functionality of the PANA server callbacks:
|
||||
|
||||
```
|
||||
uint16_t app_nvm_pana_update(pana_nvm_update_process_t update_type )
|
||||
|
|
@ -405,6 +400,26 @@ uint16_t app_nvm_pana_update(pana_nvm_update_process_t update_type )
|
|||
return remove_session(offset);
|
||||
}
|
||||
}
|
||||
|
||||
bool app_nvm_pana_read_session_by_session_id(uint32_t session_id)
|
||||
{
|
||||
//Discover session by address. Session id offset is 20 bytes from storaged data
|
||||
if (session_read_by_id(session_id) ) {
|
||||
//Write session data behind nvm_static_buffer
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool app_nvm_pana_read_session_by_address(uint8_t *linklocal_address)
|
||||
{
|
||||
//Discover session by address session. Address offset is 2 bytes from storaged data
|
||||
if (session_read_by_address(linklocal_address) ) {
|
||||
//Write session data behind nvm_static_buffer
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
```
|
||||
<span class="notes">**Note:** The previous example assumes that the user provides the functions `store_server_key()`, `store_new_session()`, `update_session()`, `update_session_data()` and `remove_session()`.</span>
|
||||
|
||||
|
|
@ -447,289 +462,3 @@ Parameter|Description
|
|||
<dd>0 Success.</dd>
|
||||
<dd>-1 Failure.</dd>
|
||||
</dl>
|
||||
|
||||
## General security type definitions
|
||||
|
||||
This section introduces general security type definitions.
|
||||
|
||||
### Certificate structure
|
||||
|
||||
The certificate structure comprises the following members:
|
||||
|
||||
```
|
||||
typedef struct arm_certificate_chain_entry_s
|
||||
{
|
||||
uint8_t chain_length;
|
||||
const uint8_t *cert_chain[4];
|
||||
uint16_t cert_len[4];
|
||||
const uint8_t *key_chain[4];
|
||||
} arm_certificate_chain_entry_t;
|
||||
```
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`chain_length`|Defines the length of the certificate chain.
|
||||
`cert_chain`|Defines the pointers to the certificates in chain.
|
||||
`cert_len`|Defines the certificate lengths.
|
||||
`key_chain`|Defines the private keys.
|
||||
|
||||
### TLS cipher mode structure
|
||||
|
||||
This enumeration defines the TLS cipher modes:
|
||||
|
||||
```
|
||||
typedef enum net_tls_cipher_e
|
||||
{
|
||||
NET_TLS_PSK_CIPHER,
|
||||
NET_TLS_ECC_CIPHER,
|
||||
NET_TLS_PSK_AND_ECC_CIPHER,
|
||||
} net_tls_cipher_e;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NET_TLS_PSK_CIPHER`|Means that network authentication only supports PSK.
|
||||
`NET_TLS_ECC_CIPHER`|Means that network authentication only supports ECC.
|
||||
`NET_TLS_PSK_AND_ECC_CIPHER`|Means that network authentication supports both PSK and ECC.
|
||||
|
||||
### TLS PSK info structure
|
||||
|
||||
The TLS PSK info structure comprises the following members:
|
||||
|
||||
```
|
||||
typedef struct net_tls_psk_info_s
|
||||
{
|
||||
uint32_t key_id;
|
||||
uint8_t key[16];
|
||||
} net_tls_psk_info_s;
|
||||
```
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`key_id`|Means that a PSK key ID can be `0x01-0xFFFF`. The storage size is intentionally 32 bits.
|
||||
`key`|Defines a 128-bit PSK key.
|
||||
|
||||
The 6LoWPAN stack supports two different chain certificate users:
|
||||
|
||||
- Transport Layer Security (TLS).
|
||||
- Network authentication (PANA, EAP or TLS).
|
||||
|
||||
## Ethernet interface bootstrap definition
|
||||
|
||||
This section defines the Ethernet interface bootstrap.
|
||||
|
||||
### IPv6
|
||||
|
||||
This enumeration defines the IPv6 bootstrap:
|
||||
|
||||
```
|
||||
typedef enum net_ipv6_mode_e
|
||||
{
|
||||
NET_IPV6_BOOTSTRAP_STATIC,
|
||||
NET_IPV6_BOOTSTRAP_AUTONOMOUS
|
||||
|
||||
} net_ipv6_mode_e;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NET_IPV6_BOOTSTRAP_STATIC`|Means that the application defines the IPv6 prefix.
|
||||
`NET_IPV6_BOOTSTRAP_AUTONOMOUS`|Means that the network defines the IPv6 prefix.
|
||||
|
||||
## RF 6LoWPAN interface configure definition
|
||||
|
||||
This section defines the RF 6LoWPAN interface configuration.
|
||||
|
||||
### typedef enum net_6lowpan_mode_e
|
||||
|
||||
This enumeration defines the different 6LoWPAN bootstrap or device modes:
|
||||
|
||||
```
|
||||
typedef enum net_6lowpan_mode_e
|
||||
{
|
||||
NET_6LOWPAN_BORDER_ROUTER,
|
||||
NET_6LOWPAN_ROUTER,
|
||||
NET_6LOWPAN_HOST,
|
||||
NET_6LOWPAN_SLEEPY_HOST
|
||||
NET_6LOWPAN_NETWORK_DRIVER,
|
||||
NET_6LOWPAN_SNIFFER
|
||||
|
||||
} net_6lowpan_mode_e;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NET_6LOWPAN_BORDER_ROUTER`|Is a root device for 6LoWPAN ND.
|
||||
`NET_6LOWPAN_ROUTER`|Is a router device.
|
||||
`NET_6LOWPAN_HOST`|Is a host device. This is the default setting.
|
||||
`NET_6LOWPAN_SLEEPY_HOST`|Is a sleepy host device.
|
||||
`NET_6LOWPAN_NETWORK_DRIVER`|6LoWPAN radio host device only, no bootstrap.
|
||||
`NET_6LOWPAN_SNIFFER`|Radio sniffer only, no bootstrap.
|
||||
|
||||
The `NET_6LOWPAN_SLEEPY_HOST` mode support requires MLE protocol support.
|
||||
|
||||
### typedef enum net_6lowpan_mode_extension_e
|
||||
|
||||
This enumeration defines the different 6LoWPAN bootstrap extension modes:
|
||||
|
||||
```
|
||||
typedef enum {
|
||||
NET_6LOWPAN_ND_WITHOUT_MLE,
|
||||
NET_6LOWPAN_ND_WITH_MLE,
|
||||
NET_6LOWPAN_THREAD,
|
||||
NET_6LOWPAN_ZIGBEE_IP
|
||||
} net_6lowpan_mode_extension_e;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NET_6LOWPAN_ND_WITHOUT_MLE`|Starts the 6LoWPAN-ND bootstrap without MLE (Mesh link establishment protocol).
|
||||
`NET_6LOWPAN_ND_WITH_MLE`|Starts 6LoWPAN-ND with MLE support.
|
||||
`NET_6LOWPAN_THREAD`|Starts Thread with MLE.
|
||||
`NET_6LOWPAN_ZIGBEE_IP`|Starts 6LoWPAN ZigBee-IP.
|
||||
|
||||
### typedef struct network_driver_setup_s
|
||||
|
||||
This structure defines the different 6LoWPAN radio interface setups:
|
||||
|
||||
```
|
||||
typedef struct {
|
||||
uint16_t mac_panid;
|
||||
uint16_t mac_short_adr;
|
||||
uint8_t beacon_protocol_id;
|
||||
uint8_t network_id[16];
|
||||
uint8_t beacon_payload_tlv_length;
|
||||
uint8_t *beacon_payload_tlv_ptr; /**< Optional Steering parameters */
|
||||
} network_driver_setup_s;
|
||||
```
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`mac_panid`|Link layer PAN ID. Accepted values are `<0xFFFE`.
|
||||
`mac_short_adr`|Defines the IEEE 802.15.4 Short MAC address. If the value is `<0xFFFE`, it indicates that GP16 addresses are active.
|
||||
`beacon_protocol_id`|Beacon protocol ID. ZigBee reserves the value 2. 6LoWPAN does not define any value for this, you can use any non-reserved value.
|
||||
`network_id`|A 16-byte long network ID. Used in the beacon payload.
|
||||
`beacon_payload_tlv_length`|The length of optional steering parameters.
|
||||
`beacon_payload_tlv_ptr`|A pointer to the optional steering parameters.
|
||||
|
||||
### typedef enum net_6lowpan_gp_address_mode_e
|
||||
|
||||
This enumeration defines the different addressing modes for a network interface. This setting is specific to each interface and is only applicable to a 6LoWPAN interface.
|
||||
|
||||
```
|
||||
typedef enum net_6lowpan_gp_address_mode_e
|
||||
{
|
||||
NET_6LOWPAN_GP64_ADDRESS,
|
||||
NET_6LOWPAN_GP16_ADDRESS,
|
||||
NET_6LOWPAN_MULTI_GP_ADDRESS,
|
||||
} net_6lowpan_gp_address_mode_e;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NET_6LOWPAN_GP64_ADDRESS`|Means that the interface will only register a GP64 address. This is the default setting.
|
||||
`NET_6LOWPAN_GP16_ADDRESS`|Means that the interface will only register a GP16 address.
|
||||
`NET_6LOWPAN_MULTI_GP_ADDRESS`|Means that the interface will register both GP16 and GP64 addresses.
|
||||
|
||||
The default address mode is `NET_6LOWPAN_GP64_ADDRESS`.
|
||||
|
||||
### typedef enum net_6lowpan_link_layer_sec_mode_e
|
||||
|
||||
This enumeration defines the security mode for an interface. This setting is specific to each interface and is only applicable to 6LoWPAN interfaces.
|
||||
|
||||
```
|
||||
typedef enum net_6lowpan_link_layer_sec_mode_e
|
||||
{
|
||||
NET_SEC_MODE_NO_LINK_SECURITY,
|
||||
NET_SEC_MODE_PSK_LINK_SECURITY,
|
||||
NET_SEC_MODE_PANA_LINK_SECURITY,
|
||||
} net_6lowpan_link_layer_sec_mode_e;
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NET_SEC_MODE_NO_LINK_SECURITY`|Means that the security is disabled at a link layer. This is the default setting.
|
||||
`NET_SEC_MODE_PSK_LINK_SECURITY`|Means that a PSK key defines the link security.
|
||||
`NET_SEC_MODE_PANA_LINK_SECURITY`|Means that PANA network authentication defines the link key. The client must call `arm_pana_client_library_init()` and the border router application `arm_pana_server_library_init()` to initialize the PANA protocol. The PANA Network API could be disabled by some of the stack packets and it is also possible that it only supports client mode.
|
||||
|
||||
The default setting is `NET_SEC_MODE_NO_SECURITY`.
|
||||
|
||||
### typedef struct net_link_layer_psk_security_info_s
|
||||
|
||||
This structure defines the PSK security information and comprises the following members:
|
||||
|
||||
```
|
||||
typedef struct net_link_layer_psk_security_info_s
|
||||
{
|
||||
uint8_t key_id;
|
||||
uint8_t security_key[16];
|
||||
} net_link_layer_psk_security_info_s;
|
||||
```
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`key_id`|PSK key ID of a link layer. Can be `0x01-0xFF`.
|
||||
`security_key`|Defines the 128-bit PSK key of a link layer.
|
||||
|
||||
### typedef struct border_router_setup_s
|
||||
|
||||
This structure defines the information required to set up a 6LoWPAN border router and comprises the following members:
|
||||
|
||||
```
|
||||
typedef struct border_router_setup_s
|
||||
{
|
||||
uint8_t channel;
|
||||
uint16_t mac_panid;
|
||||
uint16_t mac_short_adr;
|
||||
uint8_t beacon_protocol_id;
|
||||
uint8_t network_id[16];
|
||||
uint8_t lowpan_nd_prefix[8];
|
||||
uint16_t ra_life_time;
|
||||
uint32_t abro_version_num;
|
||||
} border_router_setup_t;
|
||||
```
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`channel`|Defines the channel used in 802.15.4 radio. Supported values are from 1 to 26.
|
||||
`mac_panid`|Link layer PAN ID. Accepted values are `<0xFFFE`.
|
||||
`mac_short_adr`|Defines IEEE 802.15.4 Short MAC address. If value is `<0xFFFE`, it indicates that GP16 addresses are active.
|
||||
`beacon_protocol_id`|Beacon protocol ID. ZigBee reserves the values from `0` to `2`. 6LoWPAN does not define any value for this, you can use any non-reserved value.
|
||||
`network_id`|A 16-byte long network ID. Used in the beacon payload.
|
||||
`lowpan_nd_prefix`|Defines the ND default prefix, ABRO, DODAG ID, and GP address.
|
||||
`ra_life_time`|Defines the ND router lifetime in seconds. ARM recommends value 180+.
|
||||
`abro_version_num`|Defines the ND ABRO version number (0 when starting a new ND setup).
|
||||
|
||||
## General network type definitions
|
||||
|
||||
This section defines general network layer types defined by the Network API.
|
||||
|
||||
### typedef enum net_security_t
|
||||
|
||||
This enumeration defines the information required to set up an id that represents a network interface and comprises the following parameters:
|
||||
|
||||
```
|
||||
typedef enum net_security_t {
|
||||
NW_NO_SECURITY = 0,
|
||||
NW_SECURITY_LEVEL_MIC32 = 1,
|
||||
NW_SECURITY_LEVEL_MIC64 = 2,
|
||||
NW_SECURITY_LEVEL_MIC128 = 3,
|
||||
NW_SECURITY_LEVEL_ENC = 4,
|
||||
NW_SECURITY_LEVEL_ENC_MIC32 = 5,
|
||||
NW_SECURITY_LEVEL_ENC_MIC64 = 6,
|
||||
NW_SECURITY_LEVEL_ENC_MIC128 = 7
|
||||
} net_security_t;
|
||||
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`NW_NO_SECURITY`|Disables network level security.
|
||||
`NW_SECURITY_LEVEL_MIC32`|Enables 32-bit Message Integrity Code (MIC) verification without encoding.
|
||||
`NW_SECURITY_LEVEL_MIC64`|Enables 64-bit MIC verification without encoding.
|
||||
`NW_SECURITY_LEVEL_MIC128`|Enables 128-bit Message Integrity Code (MIC) verification without encoding.
|
||||
`NW_SECURITY_LEVEL_ENC`|Enables AES encoding without MIC.
|
||||
`NW_SECURITY_LEVEL_ENC_MIC32`|Enables AES encoding with 32-bit MIC.
|
||||
`NW_SECURITY_LEVEL_ENC_MIC64`|Enables AES encoding with 64-bit MIC.
|
||||
`NW_SECURITY_LEVEL_ENC_MIC128`|Enables AES encoding with 128-bit MIC.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ Library Timer API
|
|||
=================
|
||||
This chapter describes the timer functionality.
|
||||
|
||||
If an application requires a timer, it can allocate one with the `eventOS_event_timer_request( )` function. Further to a successful allocation, the system timer event occurs.
|
||||
If an application requires a timer, it can allocate one with the `eventOS_event_timer_request_in( )` family of functions. Further to a successful allocation, the system timer event occurs.
|
||||
|
||||
Times are specified in ticks, which are currently 10ms, but use macros and converter functions in the header to avoid depending on this.
|
||||
|
||||
See the [Eventing API](08_API_events.md) chapter for more detail on events.
|
||||
|
||||
<span class="notes">**Note**: The library supports dynamic timer count at the application layer. The stack can multiplex a single timer for multiple purposes.</span>
|
||||
|
||||
|
|
@ -12,57 +16,167 @@ To use Library Timer API, include the following header in your application:
|
|||
|
||||
```
|
||||
#include eventOS_event_timer.h
|
||||
```
|
||||
```
|
||||
|
||||
## Read the current time
|
||||
|
||||
To read the current time:
|
||||
|
||||
```
|
||||
uint32_t eventOS_event_timer_ticks(void)
|
||||
```
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>Current time in ticks.</dd>
|
||||
</dl>
|
||||
|
||||
## Allocate timer
|
||||
|
||||
To allocate timer events:
|
||||
|
||||
```
|
||||
int8_t eventOS_event_timer_request
|
||||
arm_event_storage_t *eventOS_event_timer_request_at
|
||||
(
|
||||
uint8_t snmessage,
|
||||
uint8_t event_type,
|
||||
int8_t tasklet_id,
|
||||
uint32_t time
|
||||
const arm_event_t *event
|
||||
unt32_t at
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`snmessage`|The timer ID defined by the application.
|
||||
`event_type`|The event type to be sent to a tasklet when the timer expires. Usually `ARM_LIB_SYSTEM_TIMER_EVENT`.
|
||||
`tasklet_id`|The tasklet ID of the event receiver.
|
||||
`time`|The requested period in milliseconds. Resolution is 10ms.
|
||||
`event`|A pointer to an event to be sent.
|
||||
`at`|The time to send the event.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>0 If timer allocation was successful.</dd>
|
||||
<dd>-1 If timer allocation failed.</dd>
|
||||
<dd>A pointer to event structure, if the timer allocation was successful.</dd>
|
||||
<dd>NULL if the timer allocation failed.</dd>
|
||||
</dl>
|
||||
|
||||
Further to the allocated time period, the event OS library will transmit an event of which the sender, event type `(event->event_type)` and `event->event_id`, is indicating allocated timer identification.
|
||||
At the specified time, the event OS library will transmit the specified event.
|
||||
|
||||
## Release timer
|
||||
```
|
||||
arm_event_storage_t *eventOS_event_timer_request_in
|
||||
(
|
||||
const arm_event_t *event
|
||||
int32_t in
|
||||
)
|
||||
```
|
||||
|
||||
To cancel allocated timer events:
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`event`|A pointer to an event to be sent.
|
||||
`in`|The requested period in ticks.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>A pointer to event structure, if the timer allocation was successful.</dd>
|
||||
<dd>NULL if the timer allocation failed.</dd>
|
||||
</dl>
|
||||
|
||||
Within the chosen time period, the event OS library will transmit the specified event. Requesting two ticks means that
|
||||
the event will trigger on the second tick from now. The elapsed time between requesting and sending is 1-2 ticks.
|
||||
|
||||
```
|
||||
arm_event_storage_t *eventOS_event_timer_request_after
|
||||
(
|
||||
const arm_event_t *event
|
||||
int32_t after
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`event`|A pointer to an event to be sent.
|
||||
`after`|The requested period in ticks.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>A pointer to event structure, if the timer allocation was successful.</dd>
|
||||
<dd>NULL if the timer allocation failed.</dd>
|
||||
</dl>
|
||||
|
||||
Within the chosen time period, the event OS library will transmit the specified event. Requesting two ticks means
|
||||
the event will trigger on the second tick from now. The elapsed time between requesting and sending is 1-2 ticks.
|
||||
|
||||
```
|
||||
arm_event_storage_t *eventOS_event_timer_request_every
|
||||
(
|
||||
const arm_event_t *event
|
||||
int32_t every
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`event`|A pointer to an event to be sent.
|
||||
`every`|The requested period in ticks.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>A pointer to event structure, if the timer allocation was successful.</dd>
|
||||
<dd>NULL if the timer allocation failed.</dd>
|
||||
</dl>
|
||||
|
||||
Every chosen time period, the event OS library will transmit the specified event.
|
||||
|
||||
## Cancel timer
|
||||
|
||||
To cancel allocated timer id:
|
||||
|
||||
```
|
||||
int8_t eventOS_event_timer_cancel
|
||||
(
|
||||
uint8_t snmessage,
|
||||
uint8_t event_id,
|
||||
int8_t tasklet_id
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`snmessage`|The timer ID of the event to be cancelled.
|
||||
`event_id`|The event ID of the event to be cancelled.
|
||||
`tasklet_id`|The tasklet ID of the event receiver.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>0 If timer release was successful.</dd>
|
||||
<dd>-1 If timer release failed, timer ID is invalid or the timer is already released.</dd>
|
||||
<dd>0 If the timer cancellation was successful.</dd>
|
||||
<dd>-1 If the timer cancellation failed, timer ID is invalid or the timer is already released.</dd>
|
||||
</dl>
|
||||
|
||||
To cancel an periodic event or event by its `arm_event_storage_t *` reference, use `eventOS_cancel()` API. Refer to [Eventing API](08_API_events.md).
|
||||
|
||||
## Millisecond timeout API
|
||||
|
||||
Timeout API provides simpler API for calling functions periodically or after a timeout.
|
||||
|
||||
Two forms of timeouts are provided, periodic one and single-shot.
|
||||
```
|
||||
timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg);
|
||||
timeout_t *eventOS_timeout_every_ms(void (*callback)(void *), uint32_t every, void *arg);
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`callback`|A pointer to the function to be called.
|
||||
`ms` or `every`|The timeout or period in milliseconds.
|
||||
`arg`|An argument to be used in the function call.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>Reference to timeout structure.</dd>
|
||||
<dd>NULL on failure.</dd>
|
||||
</dl>
|
||||
|
||||
The `timeout_t` reference can be used to cancel an event before it has happened, or to cancel an periodically called event.
|
||||
|
||||
After a single shot event, or after cancelling the periodic one, the reference to `timeout_t` is invalid and should not be used.
|
||||
|
||||
To cancel the event, use:
|
||||
|
||||
```
|
||||
void eventOS_timeout_cancel(timeout_t *t);
|
||||
```
|
||||
Where `timeout_t *t` is the reference returned to you by `eventOS_timeout_ms()` or `eventOS_timeout_every_ms()`.
|
||||
|
||||
After cancelling the event, the handle is internally freed and becomes invalid and should not be used.
|
||||
|
|
|
|||
|
|
@ -233,143 +233,111 @@ Two hopping modes:
|
|||
|
||||
By default, the 6LoWPAN stack uses the single channel mode.
|
||||
|
||||
To enable the FHSS mode:
|
||||
To enable the FHSS mode, FHSS instance must be created, configured and registered to software MAC instance.
|
||||
|
||||
Create FHSS instance and set basic configuration using:
|
||||
|
||||
```
|
||||
int8_t arm_fhss_enable
|
||||
fhss_api_t *ns_fhss_create
|
||||
(
|
||||
int8_t interface_id,
|
||||
fhss_platform_functions_s *fhss_platform_functions,
|
||||
const fhss_configuration_s *fhss_configuration
|
||||
const fhss_configuration_t *fhss_configuration,
|
||||
const fhss_timer_t *fhss_timer,
|
||||
fhss_statistics_t *fhss_statistics
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Descripion
|
||||
---------|----------
|
||||
`interface_id`|The network interface ID.
|
||||
`fhss_platform_functions`|A pointer to the platform functions structure.
|
||||
`fhss_configuration`|A pointer to the FHSS configuration structure.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd> 0 on success.</dd>
|
||||
<dd>-1 in case of invalid input parameters.</dd>
|
||||
<dd>-2 if no channels are available in the channel list.</dd>
|
||||
<dd>-3 if broadcast channels or tx slots are 0 in the bootstrap mode Border Router or RF access point.</dd>
|
||||
<dd>-4 if number of super frames does not work with TX slots in the bootstrap mode Border Router or RF access point.</dd>
|
||||
<dd>-5 if the FHSS tasklet creation fails.</dd>
|
||||
<dd>-6 if the PHY driver mode cannot be changed.</dd>
|
||||
<dd>-7 if the used bootstrap mode is not supported.</dd>
|
||||
<dd>-8 if FHSS is already enabled.</dd>
|
||||
<dd>-9 if memory allocation failed.</dd>
|
||||
</dl>
|
||||
|
||||
To implement and define the FHSS platform functions, use the `fhss_platform_functions_s` structure:
|
||||
|
||||
```
|
||||
typedef struct
|
||||
{
|
||||
int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(int8_t, uint16_t), int8_t);
|
||||
int (*fhss_timer_stop)(void);
|
||||
uint32_t (*fhss_get_remaining_slots)(void);
|
||||
int (*fhss_time_measure_start)(void);
|
||||
uint32_t (*fhss_time_measure_read)(void);
|
||||
int (*fhss_time_measure_stop)(void);
|
||||
uint8_t fhss_resolution_divider;
|
||||
} fhss_platform_functions_s;
|
||||
```
|
||||
Application developer must implement FHSS platform timer functions as described below. FHSS timer uses 1us resolution if not reduced by resolution divider.
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`fhss_timer_start`|FHSS timer start platform function.
|
||||
`fhss_timer_stop`|FHSS timer stop platform function.
|
||||
`fhss_get_remaining_slots`|FHSS timer get remaining slots platform function.
|
||||
`fhss_time_measure_start`|FHSS time measure start platform function.
|
||||
`fhss_time_measure_read`|FHSS time measure read platform function.
|
||||
`fhss_time_measure_stop`|FHSS time measure stop platform function.
|
||||
`fhss_resolution_divider`|FHSS timer resolution divider.
|
||||
`fhss_timer_start` | FHSS timer start platform function.
|
||||
`fhss_timer_stop` | FHSS timer stop platform function.
|
||||
`fhss_get_remaining_slots` | FHSS timer get remaining slots platform function.
|
||||
`fhss_get_timestamp` | FHSS timer timestamp (since initialization of driver).
|
||||
`fhss_resolution_divider` | FHSS timer resolution divider.
|
||||
|
||||
FHSS configuration is always given from the border router using the `fhss_configuration_s` structure. The endpoint learns the configuration from the received synchronization message. In the initialization phase, the endpoint sets the FHSS configuration as NULL:
|
||||
|
||||
```
|
||||
typedef struct fhss_configuration_s
|
||||
{
|
||||
uint8_t fhss_number_of_bc_channels;
|
||||
uint8_t fhss_number_of_tx_slots;
|
||||
uint16_t fhss_superframe_length;
|
||||
uint8_t fhss_number_of_superframes;
|
||||
uint32_t fhss_beacon_send_interval;
|
||||
} fhss_configuration_s;
|
||||
```
|
||||
FHSS basic configuration is described below.
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`fhss_number_of_bc_channels`|Number of broadcast channels.
|
||||
`fhss_number_of_tx_slots`|Number of TX slots per channel.
|
||||
`fhss_superframe_length`|Superframe dwell time (us).
|
||||
`fhss_number_of_superframes`|Number of superframes per channel.
|
||||
`fhss_beacon_send_interval`|Interval of sending synchronization messages. This configuration is currently disabled.
|
||||
`fhss_tuning_parameters` | Tuning parameters to enhance synchronization accuracy.
|
||||
`fhss_max_synch_interval` | Maximum used interval for requesting synchronization info from FHSS parent device.
|
||||
`fhss_number_of_channel_retries` | Number of channel retries.
|
||||
`channel_mask` | Channel mask.
|
||||
|
||||
To disable the FHSS mode:
|
||||
|
||||
```
|
||||
int8_t arm_fhss_disable
|
||||
(
|
||||
int8_t interface_id,
|
||||
)
|
||||
```
|
||||
Some platform-specific tuning parameters can be provided:
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`interface_id`|The network interface ID.
|
||||
`tx_processing_delay` | Delay between data pushed to PHY TX function and TX started (Contains CSMA-CA maximum random period).
|
||||
`rx_processing_delay` | Delay between TX done (by transmitter) and received data pushed to MAC (by receiver).
|
||||
`ack_processing_delay` | Delay between TX done (by transmitter) and Ack transmission started (by receiver).
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd> 0 on success.</dd>
|
||||
<dd>-1 on fail.</dd>
|
||||
</dl>
|
||||
|
||||
### FHSS tuning parameters
|
||||
|
||||
When you have enabled FHSS, you can provide some platform-specific tuning parameters using the `arm_fhss_set_tuning_params` function:
|
||||
FHSS synchronization configuration is always given from the border router using the `ns_fhss_configuration_set` function. The endpoint learns the configuration from the received synchronization message.
|
||||
|
||||
```
|
||||
int8_t arm_fhss_set_tuning_params
|
||||
int ns_fhss_configuration_set
|
||||
(
|
||||
int8_t interface_id,
|
||||
const fhss_platform_tuning_params_s *fhss_tuning_params
|
||||
fhss_api_t *fhss_api,
|
||||
const fhss_synch_configuration_t *fhss_synch_configuration
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`interface_id`|The network interface ID.
|
||||
`fhss_tuning_params`|A pointer to the FHSS tuning parameters.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd> 0 on success.</dd>
|
||||
<dd>-1 on fail.</dd>
|
||||
</dl>
|
||||
|
||||
The FHSS device provides the tuning parameters using the `fhss_platform_tuning_params_s` structure:
|
||||
|
||||
```
|
||||
typedef struct
|
||||
{
|
||||
uint32_t synch_tx_processing_time;
|
||||
uint32_t synch_rx_processing_time;
|
||||
uint32_t data_tx_processing_time;
|
||||
uint32_t data_rx_processing_time;
|
||||
} fhss_platform_tuning_params_s;
|
||||
```
|
||||
Synchronization configuration is described below:
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`synch_tx_processing_time`|Processing delay between synch info written and TX start (us).
|
||||
`synch_rx_processing_time`|Processing delay between TX done and synch info read (us).
|
||||
`data_tx_processing_time`|Processing delay between data pushed to driver and transmission started (us).
|
||||
`data_rx_processing_time`|Processing delay between TX done and Ack TX start (us).
|
||||
`fhss_number_of_bc_channels` | Number of broadcast channels.
|
||||
`fhss_number_of_tx_slots` | Number of TX slots per channel.
|
||||
`fhss_superframe_length` | Superframe dwell time (us).
|
||||
`fhss_number_of_superframes` | Number of superframes per channel.
|
||||
|
||||
Register created FHSS instance to software MAC instance using `ns_sw_mac_fhss_register` function:
|
||||
```
|
||||
int ns_sw_mac_fhss_register
|
||||
(
|
||||
struct mac_api_s *mac_api,
|
||||
struct fhss_api *fhss_api
|
||||
)
|
||||
```
|
||||
|
||||
FHSS implements following API which is used by higher layer (software MAC):
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`fhss_is_broadcast_channel` | Checks if current channel is broadcast channel.
|
||||
`fhss_use_broadcast_queue` | Checks if broadcast queue must be used instead of unicast queue.
|
||||
`fhss_tx_handle` | Set destination channel and write synchronization info.
|
||||
`fhss_check_tx_conditions` | Check TX permission.
|
||||
`fhss_receive_frame` | Notification of received FHSS synch or synch request frame.
|
||||
`fhss_data_tx_done` | Data TX done callback.
|
||||
`fhss_data_tx_fail` | Data TX or CCA failed callback.
|
||||
`fhss_synch_state_set` | Change synchronization state.
|
||||
`fhss_read_timestamp` | Read timestamp.
|
||||
`fhss_get_retry_period` | Get retransmission period.
|
||||
`fhss_init_callbacks` | Initialize MAC functions.
|
||||
|
||||
|
||||
Software MAC implements following callbacks to serve requests from FHSS:
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`mac_read_tx_queue_size` | Read MAC TX queue size.
|
||||
`mac_read_mac_address` | Read MAC address.
|
||||
`mac_read_datarate` | Read PHY datarate.
|
||||
`mac_change_channel` | Change channel.
|
||||
`mac_send_fhss_frame` | Send FHSS frame.
|
||||
`mac_synch_lost_notification` | Send notification when FHSS synchronization is lost.
|
||||
`mac_tx_poll` | Poll TX queue.
|
||||
`mac_broadcast_notify` | Broadcast channel notification from FHSS.
|
||||
`mac_read_coordinator_mac_address` | Read coordinator MAC address.
|
||||
|
||||
To disable FHSS, instance can be deleted using `ns_fhss_delete` function.
|
||||
```
|
||||
int ns_fhss_delete
|
||||
(
|
||||
fhss_api_t *fhss_api
|
||||
)
|
||||
```
|
||||
|
||||
### Beacon protocol ID filter
|
||||
|
||||
|
|
@ -1897,7 +1865,7 @@ To set new parameters for a trickle multicast:
|
|||
void multicast_set_parameters
|
||||
(
|
||||
uint8_t i_min,
|
||||
uint8_t i_max,
|
||||
uint8_t i_doublings,
|
||||
uint8_t k,
|
||||
uint8_t timer_expirations,
|
||||
uint8_t window_expiration
|
||||
|
|
@ -1907,7 +1875,7 @@ void multicast_set_parameters
|
|||
Parameter|Description
|
||||
---------|-----------
|
||||
`i_min`|The minimum trickle timer interval (50ms resolution), so: `Imin = i_min * 50ms`.
|
||||
`i_max`|The maximum trickle timer interval as number if doubling of minimum interval.
|
||||
`i_doublings`|The maximum trickle timer interval expressed as number of doublings of minimum interval.
|
||||
`k`|A redundancy constant.
|
||||
`timer_expirations`|Number if trickle timer expires before terminating the trickle process.
|
||||
`window_expiration`|Time window state is kept after the trickle process has ended in 50ms resolution.
|
||||
|
|
|
|||
|
|
@ -69,89 +69,88 @@ Various types of network stats can be collected using the structure `typedef str
|
|||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`mac_tx_buffer_overflow`|Provides a count MAC TX queue overflow.
|
||||
`mac_tx_queue_size`|Current MAC TX queue size.
|
||||
`mac_tx_queue_peak`|MAC TX queue peak size.
|
||||
`mac_rx_count`|Number of received MAC packets.
|
||||
`mac_tx_count`|Number of transmitted MAC packets.
|
||||
`mac_bc_tx_count`|>Number of transmitted MAC broadcast packets.
|
||||
`mac_rx_drop`|Number of dropped MAC packets.
|
||||
`mac_tx_buffer_overflow` | Provides a count MAC TX queue overflow.
|
||||
`mac_tx_queue_size` | Current MAC TX queue size.
|
||||
`mac_tx_queue_peak` | MAC TX queue peak size.
|
||||
`mac_rx_count` | Number of received MAC packets.
|
||||
`mac_tx_count` | Number of transmitted MAC packets.
|
||||
`mac_bc_tx_count` | >Number of transmitted MAC broadcast packets.
|
||||
`mac_rx_drop` | Number of dropped MAC packets.
|
||||
|
||||
### MAC payload flow
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`mac_tx_bytes`|Number of bytes transmitted.
|
||||
`mac_rx_bytes`|Number of bytes received.
|
||||
`mac_tx_failed`|Number of times a transmission failed.
|
||||
`mac_tx_retry`|Number of times retries were made.
|
||||
`mac_tx_cca_cnt`|Number of times clear channel assessment was made.
|
||||
`mac_tx_failed_cca`|Number of failed CCA attempts.
|
||||
`mac_security_drop`|Number of security packets dropped.
|
||||
`mac_tx_bytes` | Number of bytes transmitted.
|
||||
`mac_rx_bytes` | Number of bytes received.
|
||||
`mac_tx_failed` | Number of times a transmission failed.
|
||||
`mac_tx_retry` | Number of times retries were made.
|
||||
`mac_tx_cca_cnt` | Number of times clear channel assessment was made.
|
||||
`mac_tx_failed_cca` | Number of failed CCA attempts.
|
||||
`mac_security_drop` | Number of security packets dropped.
|
||||
|
||||
### FHSS related statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`fhss_drift_compensation`|FHSS synchronization drift compensation (us/channel).
|
||||
`fhss_hop_count`|FHSS hop count.
|
||||
`fhss_synch_parent_rssi`|FHSS synchronization parent RSSI.
|
||||
`fhss_synch_interval`|FHSS synchronization interval (s).
|
||||
`fhss_prev_avg_synch_fix`|Average of 5 preceding synchronization fixes (us).
|
||||
`fhss_synch_lost`|FHSS synchronization lost counter.
|
||||
`fhss_drift_compensation` | FHSS synchronization drift compensation (us/channel).
|
||||
`fhss_hop_count` | FHSS hop count.
|
||||
`fhss_synch_interval` | FHSS synchronization interval (s).
|
||||
`fhss_prev_avg_synch_fix` | Average of 5 preceding synchronization fixes (us).
|
||||
`fhss_synch_lost` | FHSS synchronization lost counter.
|
||||
|
||||
### 6LoWPAN related statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`ip_rx_count`|Number of IP packets received.
|
||||
`ip_tx_count`|Number of IP packets transmitted.
|
||||
`ip_rx_drop`|Number of IP packets dropped.
|
||||
`ip_cksum_error`|IP checksum error count.
|
||||
`ip_rx_count` | Number of IP packets received.
|
||||
`ip_tx_count` | Number of IP packets transmitted.
|
||||
`ip_rx_drop` | Number of IP packets dropped.
|
||||
`ip_cksum_error` | IP checksum error count.
|
||||
|
||||
### IP payload flow
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`ip_tx_bytes`|Number of bytes transmitted as IP packets.
|
||||
`ip_rx_bytes`|Number of bytes received as IP packets.
|
||||
`ip_routed_up`|Number of bytes routed as IP packets.
|
||||
`ip_no_route`|Number of times an IP route was not found.
|
||||
`ip_tx_bytes` | Number of bytes transmitted as IP packets.
|
||||
`ip_rx_bytes` | Number of bytes received as IP packets.
|
||||
`ip_routed_up` | Number of bytes routed as IP packets.
|
||||
`ip_no_route` | Number of times an IP route was not found.
|
||||
|
||||
### Fragmentation statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`frag_rx_errors`|Fragmentation errors in reception.
|
||||
`frag_tx_errors`|Fragmentation errors in transmission.
|
||||
`frag_rx_errors` | Fragmentation errors in reception.
|
||||
`frag_tx_errors` | Fragmentation errors in transmission.
|
||||
|
||||
### RPL statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`rpl_route_routecost_better_change`|Number of times an RPL parent was changed.
|
||||
`ip_routeloop_detect`|Number of times an RPL IP loop creation was detected.
|
||||
`rpl_memory_overflow`|Total of allocations failed due RPL memory overflow.
|
||||
`rpl_parent_tx_fail`|Number of times transmission to a DODAG parent failed.
|
||||
`rpl_unknown_instance`|Number of times a packet was received with an unknown RPL Instance ID.
|
||||
`rpl_local_repair`|Number of times local repair was initiated.
|
||||
`rpl_global_repair`|Number of times global repair was initiated.
|
||||
`rpl_malformed_message`|Number of malformed RPL messages received.
|
||||
`rpl_time_no_next_hop`|Number of seconds spent with no RPL next hop.
|
||||
`rpl_total_memory`|Total memory currently allocated by RPL.
|
||||
`rpl_route_routecost_better_change` | Number of times an RPL parent was changed.
|
||||
`ip_routeloop_detect` | Number of times an RPL IP loop creation was detected.
|
||||
`rpl_memory_overflow` | Total of allocations failed due RPL memory overflow.
|
||||
`rpl_parent_tx_fail` | Number of times transmission to a DODAG parent failed.
|
||||
`rpl_unknown_instance` | Number of times a packet was received with an unknown RPL Instance ID.
|
||||
`rpl_local_repair` | Number of times local repair was initiated.
|
||||
`rpl_global_repair` | Number of times global repair was initiated.
|
||||
`rpl_malformed_message` | Number of malformed RPL messages received.
|
||||
`rpl_time_no_next_hop` | Number of seconds spent with no RPL next hop.
|
||||
`rpl_total_memory` | Total memory currently allocated by RPL.
|
||||
|
||||
### Various buffers
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`buf_alloc`|A count of buffer allocation.
|
||||
`buf_headroom_realloc`|A buffer headroom allocation count.
|
||||
`buf_headroom_shuffle`|A buffer headroom shuffling count.
|
||||
`buf_headroom_fail`|A buffer headroom failure count.
|
||||
`buf_alloc` | A count of buffer allocation.
|
||||
`buf_headroom_realloc` | A buffer headroom allocation count.
|
||||
`buf_headroom_shuffle` | A buffer headroom shuffling count.
|
||||
`buf_headroom_fail` | A buffer headroom failure count.
|
||||
|
||||
### ETX statistics
|
||||
|
||||
Member|Description
|
||||
------|-----------
|
||||
`etx_1st_parent`|Primary parent ETX.
|
||||
`etx_2nd_parent`|Secondary parent ETX.
|
||||
`etx_1st_parent` | Primary parent ETX.
|
||||
`etx_2nd_parent` | Secondary parent ETX.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,279 @@
|
|||
The Load balancing API
|
||||
==================
|
||||
|
||||
This chapter describes the functions of the load balancing layer. It contains the following sections:
|
||||
|
||||
- [_Load balancing API_](#load-balancing-api)
|
||||
- [_Load balancing activity diagram_](#load-balancing-activity-diagram)
|
||||
|
||||
## API header
|
||||
|
||||
To use the Load balancing API, include the following header:
|
||||
|
||||
```
|
||||
#include "net_load_balance_api.h"
|
||||
```
|
||||
|
||||
## Load balancing API
|
||||
|
||||
This section describes the functions of the load balancing layer where each function is presented with its valid parameters.
|
||||
|
||||
**Table 1-1 The load balancing API features and related functions**
|
||||
|
||||
Feature|API function
|
||||
-------|------------
|
||||
Load balancer creation|`net_load_balance_create()`
|
||||
Load balancer deletion|`net_load_balance_delete()`
|
||||
Callback function type definition|`net_load_balance_network_switch_notify()`
|
||||
Callback setting function|`net_load_balance_network_switch_cb_set()`
|
||||
Load balancer thresholds setter function|`net_load_balance_threshold_set()`
|
||||
Load balancer maximum probability setter function|`net_load_balance_set_max_probability()`
|
||||
Load level automatic update enabling|`net_load_balance_load_level_update_enable()`
|
||||
Load level automatic update disabling|`net_load_balance_load_level_update_disable()`
|
||||
|
||||
### Create load balancer
|
||||
|
||||
Periodic beacon interval can be used to speed up the load balancing feature. The suggested value is `True`. Beacon sending interval is (usually) very long to prevent flooding in network.
|
||||
|
||||
To enable the load balancer feature, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_create
|
||||
(
|
||||
int8_t interface_id,
|
||||
bool enable_periodic_beacon_interval
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>enable_periodic_beacon_interval</code></dt>
|
||||
<dd>Beacon interval is calculated from RPL config (Imax of the RPL DIO timer).</dd>
|
||||
<dd>True: The load balancing device advertises the network by sending periodic beacons.</dd>
|
||||
<dd>False: The load balancing is based on devices hearing beacons from other networks.</dd>
|
||||
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>0 Creation OK.</dd>
|
||||
<dd>-1 An unknown interface ID.</dd>
|
||||
<dd>-2 Out of memory.</dd>
|
||||
<dd>-3 Load balancing already active for this interface ID.</dd>
|
||||
</dl>
|
||||
|
||||
### Delete load balancer
|
||||
|
||||
To delete the load balancer, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_delete
|
||||
(
|
||||
int8_t interface_id
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>0 Delete OK.</dd>
|
||||
<dd>-1 An unknown interface ID.</dd>
|
||||
</dl>
|
||||
|
||||
### Callback function
|
||||
|
||||
To define a callback function for selecting whether a network switch is allowed or not, use the following `typedef`:
|
||||
|
||||
```
|
||||
typedef bool net_load_balance_network_switch_notify
|
||||
(
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>True: Network change is allowed.</dd>
|
||||
<dd>False: Network change is not allowed.</dd>
|
||||
</dl>
|
||||
|
||||
An example of a callback:
|
||||
|
||||
```
|
||||
bool my_decision(int8_t interface_id)
|
||||
{
|
||||
if (is_ok_to_change) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
### Use the callback
|
||||
|
||||
<span class="notes">**Note:** If the callback is not set, the load balancer changes the network automatically and the application only gets `ARM_LIB_NWK_INTERFACE_EVENT` with `event_id` of either `ARM_NWK_BOOTSTRAP_READY` or some error.</span>
|
||||
|
||||
To use the callback, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_network_switch_cb_set
|
||||
(
|
||||
int8_t interface_id,
|
||||
net_load_balance_network_switch_notify *network_switch_notify
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>network_switch_notify</code></dt>
|
||||
<dd>The callback function to be called when the load balancer is about to start the network change sequence.</dd>
|
||||
|
||||
<dt>Return value</dt>
|
||||
<dd>0 Set OK.</dd>
|
||||
<dd>-1 An unknown interface id.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
### Set the network threshold values
|
||||
|
||||
Threshold is used to limit the network changes. The difference between networks is calculated using joining priorities from network data. If the difference is less than the minimum threshold, the network change is never allowed. However, if the difference is more than the maximum threshold, the device does not necessarily change the network. Instead, the maximum probability will be used. This is described in the subsequent function description.
|
||||
|
||||
```
|
||||
if diff <= threshold_min: no change
|
||||
else if diff >= threshold_max: probability = max_probability
|
||||
else probability = (diff/(threshold_max-threshold_min))*max_probability
|
||||
```
|
||||
<span class="notes">**Note:** Suggested values are 32-64 for min and 64-96 for max. The border router must set both values to zero.</span>
|
||||
|
||||
To set the network threashold values, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_threshold_set
|
||||
(
|
||||
int8_t interface_id,
|
||||
uint8_t threshold_min,
|
||||
uint8_t threshold_max
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>threshold_min</code></dt>
|
||||
<dd>The minimum difference needed between networks to allow network change.</dd>
|
||||
|
||||
<dt><code>threshold_max</code></dt>
|
||||
<dd>The minimum difference needed to reach max probability (see <code>net_load_balance_set_max_probability</code>).</dd>
|
||||
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>0 Set OK.</dd>
|
||||
<dd>-1 An unknown interface ID.</dd>
|
||||
</dl>
|
||||
|
||||
### Set the network change max probability
|
||||
|
||||
Maximum probability is used to prevent all devices from changing network when they hear a better one. There is a specific timeout before which the network statistics are changed to all nodes in the network (depending on the hop count of nodes). If all devices changed the network, that could cause some unwanted churn. The max probability value is very much dependent on the size of the actual networks. The suggested value is between 10 and 25. The lower the value, the slower the balancing of network loads. If the value was 99 it would cause the devices to switch the networks very agressively (depending on the threshold values). The default value 25 is suitable for two-hop networks.
|
||||
|
||||
To set the maximum probability for a device to change the network, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_set_max_probability
|
||||
(
|
||||
int8_t interface_id,
|
||||
uint8_t max_p
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>max_p</code></dt>
|
||||
<dd>The maximum probability for a device to change the network. The default value is 25(%).</dd>
|
||||
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>0 Set OK.</dd>
|
||||
<dd>-1 An unknown interface ID.</dd>
|
||||
</dl>
|
||||
|
||||
### Set automatic calculation of DoDAG preference for the border router
|
||||
|
||||
<span class="notes">**Note:** This function should not do anything if the device is not a border router!</span>
|
||||
|
||||
To set automatic calculation of DoDAG preference for the border router, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_load_level_update_enable
|
||||
(
|
||||
int8_t interface_id,
|
||||
uint16_t expected_device_count
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>expected_device_count</code></dt>
|
||||
<dd>Device count when DoDAG preference goes to worst possible.</dd>
|
||||
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>0 Set OK.</dd>
|
||||
<dd>-1 An unknown interface ID.</dd>
|
||||
<dd>-2 Out of memory.</dd>
|
||||
</dl>
|
||||
|
||||
### Disable automatic calculation of DoDAG preference for the border router
|
||||
|
||||
<span class="notes">**Note:** This function should not do anything if the device is not a border router!</span>
|
||||
|
||||
To disable automatic calculation of DoDAG preference for the border router, use the following function:
|
||||
|
||||
```
|
||||
int8_t net_load_balance_load_level_update_disable
|
||||
(
|
||||
int8_t interface_id
|
||||
)
|
||||
```
|
||||
|
||||
Where:
|
||||
<dl>
|
||||
<dt><code>interface_id</code></dt>
|
||||
<dd>The network interface ID.</dd>
|
||||
|
||||
<dt><code>Return value</code></dt>
|
||||
<dd>0 Disable OK.</dd>
|
||||
<dd>-1 An unknown interface ID.</dd>
|
||||
</dl>
|
||||
|
||||
## Load balancing activity diagram
|
||||
|
||||
Here is the activity diagram of the load balancer:
|
||||
|
||||

|
||||
|
||||
Where:
|
||||
|
||||
1. Idle state indicates that a device has joined a network having `PanID=1` and the device is doing "normal" operations.
|
||||
2. `nwk_id` check is mandatory to prevent joining a wrong network.
|
||||
3. The load balancer is handling incoming beacons and deciding whether the device should change the network.
|
||||
4. If the load balancer is in block period, no beacons are handled.
|
||||
5. The difference is calculated by comparing the priority values of the networks.
|
||||
6. If the difference is less than the minimum threshold, the network change is not possible and the load balancer goes to block period state.
|
||||
7. The possibility is calculated by counting a linear probability multiplier (0..1) between the minimum and maximum threshold. If the network difference is higher than the maximum, the multiplier is 1. The multiplier is then multiplied with the maximum probability to get the possibility for the network change.
|
||||
8. A random value is generated and if it is higher than the probability, the load balancer goes to block state. Otherwise, the load balancer goes to waiting state.
|
||||
9. `Waiting for better beacons` is the active state of the load balancer, when a device is given a chance to hear better beacons. After a timeout period, the load balancer continues to the next state.
|
||||
10. In the `Query change from App` state, the application's callback function (if set) is called and if the returned value is false, the load balancer goes to block state. Otherwise, it continues to the change network state.
|
||||
11. The load balancer has got a permission to change the network. The sequence for the change starts.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
# About this document
|
||||
|
||||
This document walks you through the API changes in the Nanostack version 4.1.x in detail and helps you to update your current applications to use the new and changed APIs.
|
||||
|
||||
**New APIs:**
|
||||
|
||||
- Load balancing
|
||||
- Whiteboard API
|
||||
|
||||
**Changed APIs:**
|
||||
|
||||
- FHSS platform API
|
||||
- eDTLS API
|
||||
- dev_stat API
|
||||
|
||||
|
||||
## [**Load balancing**](17_API_load_balancer.md)
|
||||
|
||||
Load balancing (LB) is a new feature to allow devices to switch from a loaded network into a better one. Load balancing operates with given rules and developer(s) SHOULD NOT try to aim at evenly balanced networks (might cause churn).
|
||||
|
||||
To enable this feature, use the build time flag `HAVE_6LOWPAN_ND`.
|
||||
|
||||
The new LB functions are presented briefly here:
|
||||
|
||||
- `typedef bool net_load_balance_network_switch_notify(int8_t interface_id);`
|
||||
|
||||
Typedef of a callback function, that you can implement to control network switching. If you do not implement this, the network switch takes place automatically when applicable.
|
||||
|
||||
- `void net_load_balance_network_switch_cb_set(net_load_balance_network_switch_notify *network_switch_notify);`
|
||||
|
||||
A setter function to set (/unset with NULL) a callback function, which is called when the system has found a better network to join.
|
||||
|
||||
- `int8_t net_load_balance_create(int8_t interface_id, bool enable_periodic_beacon_interval);`
|
||||
|
||||
Creates and enables the load balancing feature.
|
||||
|
||||
- `int8_t net_load_balance_delete(int8_t interface_id);`
|
||||
|
||||
Deletes and disables the load balancing feature.
|
||||
|
||||
- `int8_t net_load_balance_threshold_set(int8_t interface_id, uint8_t threshold_min, uint8_t threshold_max);`
|
||||
|
||||
A setter for a threshold to control when a device can change the network. The difference (diff) of networks is counted. If the diff is smaller than the minimum treshold, nothing happens. If the diff is greater than or equal with the max threshold, the default or set probability value is used. Otherwise, min and max values affect the switch probability:
|
||||
|
||||
- If the diff is close to min -> very poor chance to switch.
|
||||
- If the diff is close to max --> almost the same probability as is set.
|
||||
|
||||
See `net_load_balance_set_max_probability` below for more details.
|
||||
|
||||
- `int8_t net_load_balance_set_max_probability(int8_t interface_id , uint8_t max_p);`
|
||||
|
||||
A setter for maximum probability for a device will switch the network. The proposed value is between 10 and 25 to prevent all devices from switching network at the same time (the default value is 25). Also a block period is activated if the device fails to change the network (this is automatic). Threshold minimum and maximum will add more probability on top of this and therefore, this value can be thought only as a maximum probability for switching.
|
||||
|
||||
- `int8_t net_load_balance_load_level_update_enable(int8_t interface_id, uint16_t expected_device_count);`
|
||||
|
||||
This needs the build time flag `HAVE_RPL`.
|
||||
|
||||
<span class="notes">**Note:** Border router (BR) feature only! Enables automatic updates of the DODAG preference, which is used to measure the quality of a network. The expected device count is calculated by network designer to set the number of devices this BR should connect. This is not a hard limit, it just tells when the designed device count has been reached!</span>
|
||||
|
||||
- `int8_t net_load_balance_load_level_update_disable(int8_t interface_id);`
|
||||
|
||||
This needs the build time flag `HAVE_RPL`.
|
||||
|
||||
<span class="notes">**Note:** Border router feature only! Disables automatic updates of DODAG preference. Also disables measurement of expected device count.</span>
|
||||
|
||||
## Whiteboard API
|
||||
|
||||
Whiteboard API is used to limit the number of devices allowed to join to network.
|
||||
|
||||
To enable this feature, use the build time flag `WHITEBOARD`.
|
||||
|
||||
The limit is needed in situations where one BR goes down and the devices connected to it start to find another networks. This can cause other BRs to have out-of-memory (OOM) situations, if there are lots of connected devices. When the limit is reached, the BR will not accept any new connection(s). If set to 0, there is no limit.
|
||||
|
||||
`void whiteboard_set_device_hard_limit(uint16_t limit);`
|
||||
|
||||
## Frequency-hopping Spread Spectrum (FHSS)
|
||||
|
||||
### FHSS platform API
|
||||
|
||||
FHSS platform API was simplified in this version of Nanostack. The FHSS time measurement functions were removed and replaced with the timestamp callback.
|
||||
|
||||
See the instructions below to fix any conflicts:
|
||||
|
||||
Remove the time measure callbacks from the FHSS platform function structure and replace them with the timestamp read callback:
|
||||
|
||||
static fhss_platform_functions_s fhss_functions = {
|
||||
&fhss_timer_start,
|
||||
&fhss_timer_stop,
|
||||
&fhss_timer_get_remaining_slots,
|
||||
+ &fhss_timestamp_read,
|
||||
- &fhss_time_measure_start,
|
||||
- &fhss_time_measure_read,
|
||||
- &fhss_time_measure_stop,
|
||||
RESOLUTION_DIVIDER
|
||||
};
|
||||
|
||||
Remove also corresponding time measure functions from the driver as they are not needed anymore.
|
||||
|
||||
The new timestamp callback function must be implemented:
|
||||
|
||||
uint32_t fhss_timestamp_read(void)
|
||||
{
|
||||
.
|
||||
.
|
||||
.
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
The timestamp function must return a 32-bit timestamp value with 1us resolution (if resolution divider is not used). The return value is time since the FHSS driver was started and a 32-bit counter is allowed to overflow.
|
||||
|
||||
## eDTLS API update
|
||||
|
||||
### eDTLS connection status update and sn_edtls_exec() call guidance
|
||||
|
||||
The eDTLS library calls the connection status callback by `EDTLS_ECC_CALCULATING` when it starts the ECC calculation. When ECC is started, the application should call the `sn_edtls_exec()` function rapidly to trigger a new event until the connection status gives `EDTLS_ECC_CALCULATION_READY`. This status means that callbacks to `sn_edtls_exec()` can be stopped.
|
||||
|
||||
The `sn_edtls_exec()` function should be called periodically using one second interval with the updated timer value, which triggers the re-transmission of the eDTLS library when needed. The `sn_edtls_exec()` should also be called when the eDTLS library has parsed the handshake message successfully (`sn_edtls_parse_data` returns 0). When the eDTLS callback has status `EDTLS_CONNECTION_OK`, `EDTLS_CONNECTION_CLOSED` or `EDTLS_CONNECTION_FAILED`, the periodical timer can be stopped until a new connection is started by the `sn_edtls_connect()` function.
|
||||
|
||||
## dev_stats_api API update
|
||||
|
||||
The `dev stats_api.h` file has been removed which means that the following functions are not available anymore:
|
||||
|
||||
- `dev_stat_internal_init()`
|
||||
- `dev_stat_get_longest_heap_sector()`
|
||||
- `dev_stat_get_runtime_seconds()`
|
||||
|
||||
The heap stats are still available when the `ns_dyn_mem_init()` call `info_pr` is defined. (`nsdynMEMLIB.h`)
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
# Device statistics
|
||||
|
||||
## dev_stat_internal_init
|
||||
|
||||
To start collecting device statistics within the device statistics structure:
|
||||
|
||||
```
|
||||
int8_t dev_stat_internal_init
|
||||
(
|
||||
dev_stat_t *info_ptr
|
||||
)
|
||||
```
|
||||
|
||||
Parameter|Description
|
||||
---------|-----------
|
||||
`info_ptr`|A pointer to the device statistics structure on application.
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>0 Success.</dd>
|
||||
|
||||
<dd>-1 Fail.</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
### dev_stat_get_longest_heap_sector
|
||||
|
||||
The following function call returns the longest available free sector size in the 6LoWPAN stack dynamic memory:
|
||||
|
||||
```
|
||||
int16_t dev_stat_get_longest_heap_sector
|
||||
(
|
||||
void
|
||||
)
|
||||
```
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>The size of the longest free sector.</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
### dev_stat_get_runtime_seconds
|
||||
|
||||
The following function call returns the runtime since last reset:
|
||||
|
||||
```
|
||||
uint32_t dev_stat_get_runtime_seconds
|
||||
(
|
||||
void
|
||||
)
|
||||
```
|
||||
|
||||
<dl>
|
||||
<dt>Return value</dt>
|
||||
<dd>The runtime since last reset.</dd>
|
||||
</dl>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue