Merge pull request #4345 from ARMmbed/nanostack_update

Nanostack update
pull/4332/merge
Sam Grove 2017-05-26 17:01:29 -05:00 committed by GitHub
commit ef7ab92cb8
218 changed files with 3725 additions and 1777 deletions

View File

@ -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="&quot;${ARMCC_INCLUDE}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/libService/libService}&quot;"/>
</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="&quot;${ARMCC_INCLUDE}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/libService/libService}&quot;"/>
</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>

View File

@ -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>

View File

@ -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}}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

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

View File

@ -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();
}

View File

@ -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_*/

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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.
![](docs/img/thread_certified.png)
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).

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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:
![nw-arc](img/load_balancer_activity_diagram.png)
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.

View File

@ -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`)

View File

@ -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