first submission

This commit is contained in:
qiyongshuang
2023-02-01 14:19:13 +08:00
parent d534aad004
commit b79c6ac80d
3711 changed files with 745432 additions and 2 deletions
+260
View File
@@ -0,0 +1,260 @@
<?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="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" moduleId="org.eclipse.cdt.core.settings" name="obj">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" 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.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" name="obj" parent="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release">
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074." name="/" resourcePath="">
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.231146001" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.size" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level" useByScannerDiscovery="true"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format" useByScannerDiscovery="true"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.arch.rv32i" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer" useByScannerDiscovery="false" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.abi.integer.ilp32" valueType="enumerated"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name" useByScannerDiscovery="false" value="GNU MCU RISC-V GCC" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix" useByScannerDiscovery="false" value="riscv-none-embed-" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id" useByScannerDiscovery="false" value="512258282" valueType="string"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166" name="Warn on uninitialized variables (-Wuninitialized)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized" useByScannerDiscovery="true" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.xw.2092284274" name="Extra Compressed extension (RVXW)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.xw" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.saverestore.537423591" name="Small prologue/epilogue (-msave-restore)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.saverestore" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon.800724601" name="No common unitialized (-fno-common)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.nocommon" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform.1944008784" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<builder buildPath="${workspace_loc:/GPIO_Toggle}/obj" id="ilg.gnumcueclipse.managedbuild.cross.riscv.builder.1421508906" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.builder"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1244756189" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.1692176068" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths.1034038285" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Startup}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/arch/risc-v/V4A/gcc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/components/power}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/components/cpup}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/components/backtrace}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/third_party/bounds_checking_function/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/third_party/bounds_checking_function/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/utils/internal}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/arch/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/src/mm}&quot;"/>
</option>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.126366858" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1567947810" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/User}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Peripheral/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/components/backtrace}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/components/cpup}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/components/power}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/arch/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/arch/risc-v/V4A/gcc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/kernel/src/mm}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/utils/internal}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/utils}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/third_party/bounds_checking_function/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/LiteOS/third_party/bounds_checking_function/src}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.2020844713" name="Language standard" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.gnu99" valueType="enumerated"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs.177116515" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.2036806839" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1610882921" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1620074387" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections.194760422" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.paths.2057340378" name="Library search path (-L)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.paths" useByScannerDiscovery="false" valueType="libPaths"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile.1390103472" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Ld/Link.ld}&quot;"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart.913830613" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano.239404511" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys.351964161" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs.16994550" name="Other objects" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs" useByScannerDiscovery="false" valueType="userObjs"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags.1125808200" name="Linker flags (-Xlinker [option])" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags" useByScannerDiscovery="false" valueType="stringList"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.printf.103758038" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.printf" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.1859223768" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1947503520" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections.1689063433" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.paths.1029177148" name="Library search path (-L)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;../LD&quot;"/>
</option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile.1751226764" name="Script files (-T)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="Link.ld"/>
</option>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart.642896175" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.nostart" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano.1540675679" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1292785366" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1801165667" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1356766765" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source.2052761852" name="Display source (--source|-S)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.source" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders.439659821" name="Display all headers (--all-headers|-x)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.allheaders" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle.67111865" name="Demangle names (--demangle|-C)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.demangle" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers.1549373929" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.linenumbers" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide.1298918921" name="Wide lines (--wide|-w)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.wide" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble.1859590835" name="Disassemble (--disassemble|-d)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.createlisting.disassemble" useByScannerDiscovery="false" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.712424314" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format.1404031980" name="Size format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.printsize.format" useByScannerDiscovery="false"/>
</tool>
</toolChain>
</folderInfo>
<fileInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.529083857" name="ch32v20x_usb_host.h" rcbsApplicability="disable" resourcePath="Peripheral/inc/ch32v20x_usb_host.h" toolsToInvoke=""/>
<fileInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.1630706625" name="ch32v20x_usb.h" rcbsApplicability="disable" resourcePath="Peripheral/inc/ch32v20x_usb.h" toolsToInvoke=""/>
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.334436054" name="/" resourcePath="LiteOS/components/exchook">
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.2062228612" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release" unusedChildren="">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988.1812227985" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875.794002289" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142.1161644685" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414.1791600899" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639.177015924" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439.1926983693" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949.529750294" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650.1387199788" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254.984447253" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652.27813518" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968.1000577842" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487.347710818" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449.1311033037" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275.1602374020" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634.876429077" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323.517962339" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824.398117832" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429.825649012" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993.2043525793" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265.1924824097" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745.994326153" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233.1524712786" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535.1877290161" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496.768716183" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994.1606796257" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110.1143920462" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588.1603069542" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166.361141595" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.8171434" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1244756189">
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1310499878" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1791728488" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187">
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1173456351" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.108442955" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1610882921"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.976972193" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1620074387"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1510729979" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1947503520"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.312242404" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1292785366"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1021522021" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1801165667"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1317783986" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1356766765"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.1634774322" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.712424314"/>
</toolChain>
</folderInfo>
<folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.1333323521" name="/" resourcePath="LiteOS/third_party/cmsis">
<toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.100688438" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release" unusedChildren="">
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988.204242395" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875.1613118878" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142.2015860899" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414.1636977454" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639.784696137" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439.914301612" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949.1939113075" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650.2068430746" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254.1627966088" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652.891307898" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968.1492675969" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487.460427754" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449.101332093" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275.97006159" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634.1684566918" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323.1342041958" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824.1841552693" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429.1801436350" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993.643893858" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265.1997967325" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745.1939554715" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233.1342857864" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535.288958149" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496.359746984" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994.1870097564" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110.705902982" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588.827934939" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588"/>
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166.1837883347" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.440232423" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1244756189">
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1113434951" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.615957970" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187">
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.784424371" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1796908532" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1610882921"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.2119140349" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1620074387"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.957422234" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1947503520"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.940539115" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1292785366"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1092495852" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1801165667"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1656640092" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1356766765"/>
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.110026313" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.712424314"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="Startup/startup_ch32v20x_D8W.S|Startup/startup_ch32v20x.S|LiteOS/components/cppsupport|User/task_sample.c|LiteOS/kal|Peripheral|LiteOS/third_party/cmsis/CMSIS/Core|LiteOS/components/exchook|LiteOS/third_party/cmsis|User/task_sample.h|LiteOS/components/net|Debug|LiteOS/testsuits|LiteOS/components/fs" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Debug"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Peripheral"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="999.ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf.275846018" name="Executable file" projectType="ilg.gnumcueclipse.managedbuild.cross.riscv.target.elf"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.767917625;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.debug.767917625.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1375371130;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1473381709">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074;ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187;ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.2036806839">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>
+46
View File
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<projectDescription>
<name>LiteOS_m</name>
<comment/>
<projects/>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments/>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<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>
<filteredResources>
<filter>
<id>1595986042669</id>
<name/>
<type>22</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.wvproj</arguments>
</matcher>
</filter>
</filteredResources>
<linkedResources>
<link>
<name>Peripheral</name>
<type>2</type>
<location>PARENT-2-PROJECT_LOC/SRC/Peripheral</location>
</link>
<link>
<name>Debug</name>
<type>2</type>
<location>PARENT-2-PROJECT_LOC/SRC/Debug</location>
</link>
</linkedResources>
</projectDescription>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074" name="obj">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-573952389208409790" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//Peripheral/inc/ch32v20x.h=UTF-8
+16
View File
@@ -0,0 +1,16 @@
Mcu Type=CH32V20x
Address=0x08000000
Target Path=obj/LiteOS_m.hex
Erase All=true
Program=true
Verify=true
Reset=true
Vendor=WCH
Link=WCH-Link
Toolchain=RISC-V
Series=CH32V203
Description=ROM(byte): 64K, SRAM(byte): 20K, CHIP PINS: 32, GPIO PORTS: 27.\nWCH CH32V2 series of mainstream MCUs covers the needs of a large variety of applications in the industrial,medical and consumer markets. High performance with first-class peripherals and low-power,low-voltage operation is paired with a high level of integration at accessible prices with a simple architecture and easy-to-use tools.
PeripheralVersion=1.0
MCU=CH32V203RBT6
@@ -0,0 +1,397 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : core_riscv.c
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : RISC-V Core Peripheral Access Layer Source File
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/**
* @brief Return the Floating-Point Accrued Exceptions
*/
uint32_t __get_FFLAGS(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "fflags" : "=r" (result) );
return (result);
}
/**
* @brief Set the Floating-Point Accrued Exceptions
*/
void __set_FFLAGS(uint32_t value)
{
__ASM volatile ("csrw fflags, %0" : : "r" (value) );
}
/**
* @brief Return the Floating-Point Dynamic Rounding Mode
*/
uint32_t __get_FRM(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "frm" : "=r" (result) );
return (result);
}
/**
* @brief Set the Floating-Point Dynamic Rounding Mode
*/
void __set_FRM(uint32_t value)
{
__ASM volatile ("csrw frm, %0" : : "r" (value) );
}
/**
* @brief Return the Floating-Point Control and Status Register
*/
uint32_t __get_FCSR(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "fcsr" : "=r" (result) );
return (result);
}
/**
* @brief Set the Floating-Point Control and Status Register
*/
void __set_FCSR(uint32_t value)
{
__ASM volatile ("csrw fcsr, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Status Register
*/
uint32_t __get_MSTATUS(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mstatus" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Status Register
*/
void __set_MSTATUS(uint32_t value)
{
__ASM volatile ("csrw mstatus, %0" : : "r" (value) );
}
/**
* @brief Return the Machine ISA Register
*/
uint32_t __get_MISA(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "misa" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine ISA Register
*/
void __set_MISA(uint32_t value)
{
__ASM volatile ("csrw misa, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Interrupt Enable Register
*/
uint32_t __get_MIE(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mie" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine ISA Register
*/
void __set_MIE(uint32_t value)
{
__ASM volatile ("csrw mie, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Trap-Vector Base-Address Register
*/
uint32_t __get_MTVEC(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mtvec" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Trap-Vector Base-Address Register
*/
void __set_MTVEC(uint32_t value)
{
__ASM volatile ("csrw mtvec, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Seratch Register
*/
uint32_t __get_MSCRATCH(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mscratch" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Seratch Register
*/
void __set_MSCRATCH(uint32_t value)
{
__ASM volatile ("csrw mscratch, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Exception Program Register
*/
uint32_t __get_MEPC(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mepc" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Exception Program Register
*/
void __set_MEPC(uint32_t value)
{
__ASM volatile ("csrw mepc, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Cause Register
*/
uint32_t __get_MCAUSE(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mcause" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Cause Register
*/
void __set_MCAUSE(uint32_t value)
{
__ASM volatile ("csrw mcause, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Trap Value Register
*/
uint32_t __get_MTVAL(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mtval" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Trap Value Register
*/
void __set_MTVAL(uint32_t value)
{
__ASM volatile ("csrw mtval, %0" : : "r" (value) );
}
/**
* @brief Return the Machine Interrupt Pending Register
*/
uint32_t __get_MIP(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mip" : "=r" (result) );
return (result);
}
/**
* @brief Set the Machine Interrupt Pending Register
*/
void __set_MIP(uint32_t value)
{
__ASM volatile ("csrw mip, %0" : : "r" (value) );
}
/**
* @brief Return Lower 32 bits of Cycle counter
*/
uint32_t __get_MCYCLE(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mcycle" : "=r" (result) );
return (result);
}
/**
* @brief Set Lower 32 bits of Cycle counter
*/
void __set_MCYCLE(uint32_t value)
{
__ASM volatile ("csrw mcycle, %0" : : "r" (value) );
}
/**
* @brief Return Upper 32 bits of Cycle counter
*/
uint32_t __get_MCYCLEH(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mcycleh" : "=r" (result) );
return (result);
}
/**
* @brief Set Upper 32 bits of Cycle counter
*/
void __set_MCYCLEH(uint32_t value)
{
__ASM volatile ("csrw mcycleh, %0" : : "r" (value) );
}
/**
* @brief Return Lower 32 bits of Instructions-retired counter
*/
uint32_t __get_MINSTRET(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "minstret" : "=r" (result) );
return (result);
}
/**
* @brief Set Lower 32 bits of Instructions-retired counter
*/
void __set_MINSTRET(uint32_t value)
{
__ASM volatile ("csrw minstret, %0" : : "r" (value) );
}
/**
* @brief Return Upper 32 bits of Instructions-retired counter
*/
uint32_t __get_MINSTRETH(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "minstreth" : "=r" (result) );
return (result);
}
/**
* @brief Set Upper 32 bits of Instructions-retired counter
*/
void __set_MINSTRETH(uint32_t value)
{
__ASM volatile ("csrw minstreth, %0" : : "r" (value) );
}
/**
* @brief Return Vendor ID Register
*/
uint32_t __get_MVENDORID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) );
return (result);
}
/**
* @brief Return Machine Architecture ID Register
*/
uint32_t __get_MARCHID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "marchid" : "=r" (result) );
return (result);
}
/**
* @brief Return Machine Implementation ID Register
*/
uint32_t __get_MIMPID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mimpid" : "=r" (result) );
return (result);
}
/**
* @brief Return Hart ID Register
*/
uint32_t __get_MHARTID(void)
{
uint32_t result;
__ASM volatile ( "csrr %0," "mhartid" : "=r" (result) );
return (result);
}
/**
* @brief Return SP Register
*/
uint32_t __get_SP(void)
{
uint32_t result;
asm volatile (
"mv %0," "sp"
: "=r"(result)
:
);
return (result);
}
@@ -0,0 +1,294 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : core_riscv.h
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __CORE_RISCV_H__
#define __CORE_RISCV_H__
/* IO definitions */
#ifdef __cplusplus
#define __I volatile /*!< defines 'read only' permissions */
#else
#define __I volatile const /*!< defines 'read only' permissions */
#endif
#define __O volatile /*!< defines 'write only' permissions */
#define __IO volatile /*!< defines 'read / write' permissions */
/* Standard Peripheral Library old types (maintained for legacy purpose) */
typedef __I uint64_t vuc64; /* Read Only */
typedef __I uint32_t vuc32; /* Read Only */
typedef __I uint16_t vuc16; /* Read Only */
typedef __I uint8_t vuc8; /* Read Only */
typedef const uint64_t uc64; /* Read Only */
typedef const uint32_t uc32; /* Read Only */
typedef const uint16_t uc16; /* Read Only */
typedef const uint8_t uc8; /* Read Only */
typedef __I int64_t vsc64; /* Read Only */
typedef __I int32_t vsc32; /* Read Only */
typedef __I int16_t vsc16; /* Read Only */
typedef __I int8_t vsc8; /* Read Only */
typedef const int64_t sc64; /* Read Only */
typedef const int32_t sc32; /* Read Only */
typedef const int16_t sc16; /* Read Only */
typedef const int8_t sc8; /* Read Only */
typedef __IO uint64_t vu64;
typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef __IO int64_t vs64;
typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
#define RV_STATIC_INLINE static inline
/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */
typedef struct{
__I uint32_t ISR[8];
__I uint32_t IPR[8];
__IO uint32_t ITHRESDR;
__IO uint32_t RESERVED;
__IO uint32_t CFGR;
__I uint32_t GISR;
uint8_t VTFIDR[4];
uint8_t RESERVED0[12];
__IO uint32_t VTFADDR[4];
uint8_t RESERVED1[0x90];
__O uint32_t IENR[8];
uint8_t RESERVED2[0x60];
__O uint32_t IRER[8];
uint8_t RESERVED3[0x60];
__O uint32_t IPSR[8];
uint8_t RESERVED4[0x60];
__O uint32_t IPRR[8];
uint8_t RESERVED5[0x60];
__IO uint32_t IACTR[8];
uint8_t RESERVED6[0xE0];
__IO uint8_t IPRIOR[256];
uint8_t RESERVED7[0x810];
__IO uint32_t SCTLR;
}PFIC_Type;
/* memory mapped structure for SysTick */
typedef struct
{
__IO u32 CTLR;
__IO u32 SR;
__IO u64 CNT;
__IO u64 CMP;
}SysTick_Type;
#define PFIC ((PFIC_Type *) 0xE000E000 )
#define NVIC PFIC
#define NVIC_KEY1 ((uint32_t)0xFA050000)
#define NVIC_KEY2 ((uint32_t)0xBCAF0000)
#define NVIC_KEY3 ((uint32_t)0xBEEF0000)
#define SysTick ((SysTick_Type *) 0xE000F000)
/* risc-v specific functions */
RV_STATIC_INLINE void __enable_irq() { __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); }
RV_STATIC_INLINE void __disable_irq() { __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); }
RV_STATIC_INLINE void __NOP() { __asm volatile ("nop"); }
/* ########################## NVIC functions #################################### */
/*******************************************************************************
* Function Name : NVIC_EnableIRQ
* Description : Enable Interrupt
* Input : IRQn: Interrupt Numbers
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn){
NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/*******************************************************************************
* Function Name : NVIC_DisableIRQ
* Description : Disable Interrupt
* Input : IRQn: Interrupt Numbers
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/*******************************************************************************
* Function Name : NVIC_GetStatusIRQ
* Description : Get Interrupt Enable State
* Input : IRQn: Interrupt Numbers
* Return : 1: Interrupt Enable
* 0: Interrupt Disable
*******************************************************************************/
RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/*******************************************************************************
* Function Name : NVIC_GetPendingIRQ
* Description : Get Interrupt Pending State
* Input : IRQn: Interrupt Numbers
* Return : 1: Interrupt Pending Enable
* 0: Interrupt Pending Disable
*******************************************************************************/
RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/*******************************************************************************
* Function Name : NVIC_SetPendingIRQ
* Description : Set Interrupt Pending
* Input : IRQn: Interrupt Numbers
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/*******************************************************************************
* Function Name : NVIC_ClearPendingIRQ
* Description : Clear Interrupt Pending
* Input : IRQn: Interrupt Numbers
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/*******************************************************************************
* Function Name : NVIC_GetActive
* Description : Get Interrupt Active State
* Input : IRQn: Interrupt Numbers
* Return : 1: Interrupt Active
* 0: Interrupt No Active
*******************************************************************************/
RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
{
return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/*******************************************************************************
* Function Name : NVIC_SetPriority
* Description : Set Interrupt Priority
* Input : IRQn: Interrupt Numbers
* priority: bit7:pre-emption priority
* bit6-bit4: subpriority
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority)
{
NVIC->IPRIOR[(uint32_t)(IRQn)] = priority;
}
/*******************************************************************************
* Function Name : __WFI
* Description : Wait for Interrupt
* Input : None
* Return : None
*******************************************************************************/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void)
{
NVIC->SCTLR &= ~(1<<3); // wfi
asm volatile ("wfi");
}
/*******************************************************************************
* Function Name : __WFE
* Description : Wait for Events
* Input : None
* Return : None
*******************************************************************************/
__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void)
{
uint32_t t;
t = NVIC->SCTLR;
NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev)
NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5));
asm volatile ("wfi");
asm volatile ("wfi");
}
/*******************************************************************************
* Function Name : SetVTFIRQ
* Description : Set VTF Interrupt
* Input : addr��VTF interrupt service function base address.
* IRQn��Interrupt Numbers
* num��VTF Interrupt Numbers
* NewState: DISABLE or ENABLE
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){
if(num > 3) return ;
if (NewState != DISABLE)
{
NVIC->VTFIDR[num] = IRQn;
NVIC->VTFADDR[num] = ((addr&0xF00FFFFE)|0x1);
}
else{
NVIC->VTFIDR[num] = IRQn;
NVIC->VTFADDR[num] = ((addr&0xF00FFFFE)&(~0x1));
}
}
/*******************************************************************************
* Function Name : NVIC_SystemReset
* Description : Initiate a system reset request
* Input : None
* Return : None
*******************************************************************************/
RV_STATIC_INLINE void NVIC_SystemReset(void)
{
NVIC->CFGR = NVIC_KEY3|(1<<7);
}
uint32_t __get_MCAUSE(void);
uint32_t __get_MTVAL(void);
uint32_t __get_MEPC(void);
uint32_t __get_SP(void);
#endif
+1
View File
@@ -0,0 +1 @@
ENTRY( _start )␍␍__stack_size = 2048;␍␍PROVIDE( _stack_size = __stack_size );␍␍␍MEMORY␍{␍ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K␍ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K␍}␍␍␍SECTIONS␍{␍␍ .init :␍ {␍ _sinit = .;␍ . = ALIGN(4);␍ KEEP(*(SORT_NONE(.init)))␍ . = ALIGN(4);␍ _einit = .;␍ } >FLASH AT>FLASH␍␍ .vector :␍ {␍ *(.vector);␍ . = ALIGN(64);␍ } >FLASH AT>FLASH␍␍ .text :␍ {␍ . = ALIGN(4);␍ *(.text)␍ *(.text.*)␍ *(.rodata)␍ *(.rodata*)␍ *(.gnu.linkonce.t.*)␍ . = ALIGN(4);␍ } >FLASH AT>FLASH ␍␍ .fini :␍ {␍ KEEP(*(SORT_NONE(.fini)))␍ . = ALIGN(4);␍ } >FLASH AT>FLASH␍␍ PROVIDE( _etext = . );␍ PROVIDE( _eitcm = . ); ␍␍ .preinit_array :␍ {␍ PROVIDE_HIDDEN (__preinit_array_start = .);␍ KEEP (*(.preinit_array))␍ PROVIDE_HIDDEN (__preinit_array_end = .);␍ } >FLASH AT>FLASH ␍ ␍ .init_array :␍ {␍ PROVIDE_HIDDEN (__init_array_start = .);␍ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))␍ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))␍ PROVIDE_HIDDEN (__init_array_end = .);␍ } >FLASH AT>FLASH ␍ ␍ .fini_array :␍ {␍ PROVIDE_HIDDEN (__fini_array_start = .);␍ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))␍ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))␍ PROVIDE_HIDDEN (__fini_array_end = .);␍ } >FLASH AT>FLASH ␍ ␍ .ctors :␍ {␍ /* gcc uses crtbegin.o to find the start of␍ the constructors, so we make sure it is␍ first. Because this is a wildcard, it␍ doesn't matter if the user does not␍ actually link against crtbegin.o; the␍ linker won't look for a file to match a␍ wildcard. The wildcard also means that it␍ doesn't matter which directory crtbegin.o␍ is in. */␍ KEEP (*crtbegin.o(.ctors))␍ KEEP (*crtbegin?.o(.ctors))␍ /* We don't want to include the .ctor section from␍ the crtend.o file until after the sorted ctors.␍ The .ctor section from the crtend file contains the␍ end of ctors marker and it must be last */␍ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))␍ KEEP (*(SORT(.ctors.*)))␍ KEEP (*(.ctors))␍ } >FLASH AT>FLASH ␍ ␍ .dtors :␍ {␍ KEEP (*crtbegin.o(.dtors))␍ KEEP (*crtbegin?.o(.dtors))␍ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))␍ KEEP (*(SORT(.dtors.*)))␍ KEEP (*(.dtors))␍ } >FLASH AT>FLASH ␍␍ .dalign :␍ {␍ . = ALIGN(4);␍ PROVIDE(_data_vma = .);␍ } >RAM AT>FLASH ␍␍ .dlalign :␍ {␍ . = ALIGN(4); ␍ PROVIDE(_data_lma = .);␍ } >FLASH AT>FLASH␍␍ .data :␍ {␍ *(.gnu.linkonce.r.*)␍ *(.data .data.*)␍ *(.gnu.linkonce.d.*)␍ . = ALIGN(8);␍ PROVIDE( __global_pointer$ = . + 0x800 );␍ *(.sdata .sdata.*)␍ *(.sdata2.*)␍ *(.gnu.linkonce.s.*)␍ . = ALIGN(8);␍ *(.srodata.cst16)␍ *(.srodata.cst8)␍ *(.srodata.cst4)␍ *(.srodata.cst2)␍ *(.srodata .srodata.*)␍ . = ALIGN(4);␍ PROVIDE( _edata = .);␍ } >RAM AT>FLASH␍␍ .bss :␍ {␍ . = ALIGN(4);␍ PROVIDE( _sbss = .);␍ *(.sbss*)␍ *(.gnu.linkonce.sb.*)␍ *(.bss*)␍ *(.gnu.linkonce.b.*) ␍ *(COMMON*)␍ . = ALIGN(4);␍ PROVIDE( _ebss = .);␍ } >RAM AT>FLASH␍␍ PROVIDE( _end = _ebss);␍ PROVIDE( end = . );␍␍ .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :␍ {␍ PROVIDE( _heap_end = . );␍ . = ALIGN(4);␍ PROVIDE(_susrstack = . );␍ . = . + __stack_size;␍ PROVIDE( _eusrstack = .);␍ } >RAM ␍␍}␍␍␍␍
@@ -0,0 +1,39 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("backtrace") {
sources = [ "los_backtrace.c" ]
include_dirs = [
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,416 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_backtrace.h"
#include "los_task.h"
#include "los_debug.h"
#if (LOSCFG_BACKTRACE_TYPE != 0)
#if (LOSCFG_BACKTRACE_TYPE == 1)
#define OS_BACKTRACE_START 2
/* Thumb instruction, so the pc must be an odd number */
#define OS_IS_THUMB_INSTRUCTION(pc) ((pc & 0x1) == 1)
/* BL or BLX instruction flag. */
#define OS_BL_INS_MASK 0xF800
#define OS_BL_INS_HIGH 0xF800
#define OS_BL_INS_LOW 0xF000
#define OS_BLX_INX_MASK 0xFF00
#define OS_BLX_INX 0x4700
#if defined(__ICCARM__) || defined(__CC_ARM)
STATIC INLINE UINTPTR HalSpGet(VOID)
{
UINTPTR sp;
__asm("mov %0, sp" : "=r" (sp));
return sp;
}
STATIC INLINE UINTPTR HalPspGet(VOID)
{
UINTPTR psp;
__asm("mrs %0, psp" : "=r" (psp));
return psp;
}
STATIC INLINE UINTPTR HalMspGet(VOID)
{
UINTPTR msp;
__asm("mrs %0, msp" : "=r" (msp));
return msp;
}
#elif defined(__CLANG_ARM) || defined(__GNUC__)
STATIC INLINE UINTPTR HalSpGet(VOID)
{
UINTPTR sp;
__asm volatile("mov %0, sp" : "=r" (sp));
return sp;
}
STATIC INLINE UINTPTR HalPspGet(VOID)
{
UINTPTR psp;
__asm volatile("mrs %0, psp" : "=r" (psp));
return psp;
}
STATIC INLINE UINTPTR HalMspGet(VOID)
{
UINTPTR msp;
__asm volatile("mrs %0, msp" : "=r" (msp));
return msp;
}
#else
#error Unknown compiler.
#endif
STATIC INLINE BOOL OsInsIsBlOrBlx(UINTPTR addr)
{
UINT16 ins1 = *((UINT16 *)addr);
UINT16 ins2 = *((UINT16 *)(addr + 2)); /* 2: Thumb instruction is two bytes. */
if (((ins2 & OS_BL_INS_MASK) == OS_BL_INS_HIGH) &&
((ins1 & OS_BL_INS_MASK) == OS_BL_INS_LOW)) {
return TRUE;
} else if ((ins2 & OS_BLX_INX_MASK) == OS_BLX_INX) {
return TRUE;
} else {
return FALSE;
}
}
STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINTPTR SP)
{
if (SP != 0) {
*stackStart = SP;
if ((SP >= CSTACK_START_ADDR) && (SP < CSTACK_END_ADDR)) {
*stackEnd = CSTACK_END_ADDR;
} else {
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
PRINT_ERR("msp statck [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
return LOS_NOK;
}
}
} else {
if (HalSpGet() != HalPspGet()) {
*stackStart = HalMspGet();
*stackEnd = CSTACK_END_ADDR;
if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, *stackStart);
return LOS_NOK;
}
PRINTK("msp, start = %x, end = %x\n", *stackStart, *stackEnd);
} else {
*stackStart = HalPspGet();
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((*stackStart < (UINTPTR)taskCB->topOfStack) || (*stackStart >= *stackEnd)) {
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %d!\n",
taskCB->topOfStack, *stackEnd, *stackStart, taskID);
return LOS_NOK;
}
PRINTK("psp, start = %x, end = %x\n", *stackStart, *stackEnd);
}
}
return LOS_OK;
}
STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
{
UINTPTR pc;
BOOL ret;
/* The stack space pointed to by the current SP may store the LR,
so need decrease a word to PC. */
pc = *((UINTPTR *)sp) - sizeof(UINTPTR);
if (!OS_IS_THUMB_INSTRUCTION(pc)) {
return 0;
}
/* PC in thumb mode is an odd number, fix the PC address by decreasing one byte. */
pc = *((UINTPTR *)sp) - 1;
ret = OsStackDataIsCodeAddr(pc);
if (ret == FALSE) {
return 0;
}
ret = OsInsIsBlOrBlx(pc - sizeof(UINTPTR));
if (ret == FALSE) {
return 0;
}
return pc;
}
#elif (LOSCFG_BACKTRACE_TYPE == 2)
STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value);
#define OS_BACKTRACE_START 1
#define OS_RA_OFFSET 4
#define OS_FP_OFFSET 8
#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0)
#define OS_FP_CHECK(value) (((UINT32)(value) != FP_INIT_VALUE) && OS_FP_ALIGN(value))
STATIC INLINE UINTPTR OsFpGet(VOID)
{
UINTPTR fp = 0;
__asm volatile("mv %0, s0" : "=r"(fp));
dsb();
return fp;
}
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{
UNUSED(SP);
UINT32 backFp = OsFpGet();
UINT32 tmpFp;
UINT32 backRa;
UINT32 count = 0;
UINT32 index = 0;
if (LR == NULL) {
return;
}
while (OS_FP_CHECK(backFp)) {
tmpFp = backFp;
backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
if (index++ < jumpCount) {
continue;
}
LR[count] = backRa;
count++;
if ((count == LRSize) || (backFp == tmpFp) ||
(!OsStackDataIsCodeAddr(backRa))) {
break;
}
}
if (count < LRSize) {
LR[count] = 0;
}
}
#elif (LOSCFG_BACKTRACE_TYPE == 3)
#define OS_BACKTRACE_START 1
#define OS_JALX_INS_MASK 0x7F
#define OS_JAL_INS_LOW 0x6F
#define OS_JAL_16_INS_MASK 0x2001
#define OS_JALR_INS_LOW 0x67
#define OS_JALR_16_INS_MASK 0x9002
#define OS_JR_16_INS_MASK 0x8002
#define OS_J_16_INS_MASK 0xA001
STATIC INLINE BOOL OsInsIsJump(UINTPTR addr)
{
UINT16 ins1 = *((UINT16 *)addr);
UINT16 ins2 = *((UINT16 *)(addr + 2));
/* Jal ins */
if (((ins1 & OS_JALX_INS_MASK) == OS_JAL_INS_LOW) ||
((ins1 & OS_JAL_16_INS_MASK) == OS_JAL_16_INS_MASK) ||
((ins2 & OS_JAL_16_INS_MASK) == OS_JAL_16_INS_MASK)) {
return TRUE;
}
/* Jalr ins */
if (((ins1 & OS_JALX_INS_MASK) == OS_JALR_INS_LOW) ||
((ins1 & OS_JALR_16_INS_MASK) == OS_JALR_16_INS_MASK) ||
((ins2 & OS_JALR_16_INS_MASK) == OS_JALR_16_INS_MASK)) {
return TRUE;
}
/* Jr ins */
if (((ins1 & OS_JR_16_INS_MASK) == OS_JR_16_INS_MASK) ||
((ins2 & OS_JR_16_INS_MASK) == OS_JR_16_INS_MASK)) {
return TRUE;
}
/* J ins */
if (((ins1 & OS_J_16_INS_MASK) == OS_J_16_INS_MASK) ||
((ins2 & OS_J_16_INS_MASK) == OS_J_16_INS_MASK)) {
return TRUE;
}
return FALSE;
}
STATIC INLINE UINTPTR OsSpGet(VOID)
{
UINTPTR sp = 0;
__asm volatile("mv %0, sp" : "=r"(sp));
dsb();
return sp;
}
STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINTPTR SP)
{
if (SP != 0) {
*stackStart = SP;
if ((SP >= CSTACK_START_ADDR) && (SP < CSTACK_END_ADDR)) {
*stackEnd = CSTACK_END_ADDR;
} else {
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
PRINT_ERR("msp statck [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
return LOS_NOK;
}
}
} else {
if (!LOS_TaskIsRunning()) {
*stackStart = OsSpGet();
*stackEnd = CSTACK_END_ADDR;
if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
CSTACK_START_ADDR, CSTACK_END_ADDR, *stackStart);
return LOS_NOK;
}
} else {
*stackStart = OsSpGet();
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
if ((*stackStart < (UINTPTR)taskCB->topOfStack) || (*stackStart >= *stackEnd)) {
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %d!\n",
taskCB->topOfStack, *stackEnd, *stackStart, taskID);
return LOS_NOK;
}
}
}
return LOS_OK;
}
STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
{
UINTPTR pc;
BOOL ret;
pc = *((UINTPTR *)sp);
ret = OsStackDataIsCodeAddr(pc);
if (ret == FALSE) {
return 0;
}
ret = OsInsIsJump(pc - sizeof(UINTPTR));
if (ret == FALSE) {
return 0;
}
return pc;
}
#else
#error Unknown backtrace type.
#endif
#if (LOSCFG_BACKTRACE_TYPE == 1) || (LOSCFG_BACKTRACE_TYPE == 3)
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{
if (LR == NULL) {
return;
}
UINTPTR stackStart;
UINTPTR stackEnd;
UINT32 count = 0;
UINT32 index = 0;
UINTPTR sp;
UINTPTR pc;
UINT32 ret;
ret = OsStackAddrGet(&stackStart, &stackEnd, SP);
if (ret != LOS_OK) {
return;
}
/* Traverse the stack space and find the LR address. */
for (sp = stackStart; sp < stackEnd; sp += sizeof(UINTPTR)) {
pc = OsAddrIsValid(sp);
if ((pc != 0) && (count < LRSize)) {
if (index++ < jumpCount) {
continue;
}
LR[count] = pc;
count++;
if (count == LRSize) {
break;
}
}
}
if (count < LRSize) {
LR[count] = 0;
}
}
#endif
VOID LOS_BackTrace(VOID)
{
UINTPTR LR[BACKTRACE_MAX_DEPTH] = {0};
UINT32 index;
LOS_RecordLR(LR, BACKTRACE_MAX_DEPTH, OS_BACKTRACE_START, 0);
if (LOS_TaskIsRunning()) {
PRINTK("taskName = %s\n", g_losTask.runTask->taskName);
PRINTK("taskID = %u\n", g_losTask.runTask->taskID);
}
PRINTK("----- traceback start -----\r\n");
for (index = 0; index < BACKTRACE_MAX_DEPTH; index++) {
if (LR[index] == 0) {
break;
}
PRINTK("traceback %d -- lr = 0x%x\r\n", index, LR[index]);
}
PRINTK("----- traceback end -----\r\n");
}
VOID OSBackTraceInit(VOID)
{
OsBackTraceHookSet(LOS_RecordLR);
}
#endif
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_BACKTRACE_H
#define _LOS_BACKTRACE_H
#include "los_config.h"
#include "../../kernel/arch/risc-v/V4A/gcc/los_arch_interrupt.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define BACKTRACE_MAX_DEPTH LOSCFG_BACKTRACE_DEPTH
#if (LOSCFG_BACKTRACE_TYPE != 0)
#if (LOSCFG_BACKTRACE_TYPE == 1)
/* The default name of the code section and CSTACK section are given below,
and the user can adjust it according to the linker script file. */
#if defined(__ICCARM__)
/* The default code section name is .text */
#define CODE_SECTION_NAME ".text"
/* The default C stack section name is CSTACK */
#define CSTACK_SECTION_NAME "CSTACK"
#pragma section=CODE_SECTION_NAME
#pragma section=CSTACK_SECTION_NAME
/* Default only one code section. In fact, there may be more than one.
You can define more than one and modify the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME))
#define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME))
#define CSTACK_START_ADDR ((UINTPTR)__section_begin(CSTACK_SECTION_NAME))
#define CSTACK_END_ADDR ((UINTPTR)__section_end(CSTACK_SECTION_NAME))
#elif defined(__CC_ARM) || defined(__CLANG_ARM)
/* The default code section name is ER_IROM1 */
#define CODE_SECTION_NAME ER_IROM1
/* The default C stack section name is STACK */
#define CSTACK_SECTION_NAME STACK
#define SECTION_START(_name_) _name_##$$Base
#define SECTION_END(_name_) _name_##$$Limit
#define CSTACK_SECTION_START(_name_) SECTION_START(_name_)
#define CSTACK_SECTION_END(_name_) SECTION_END(_name_)
#define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base
#define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit
#define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_)
#define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_)
extern CHAR *CSTACK_SECTION_START(CSTACK_SECTION_NAME);
extern CHAR *CSTACK_SECTION_END(CSTACK_SECTION_NAME);
extern CHAR *CODE_SECTION_START(CODE_SECTION_NAME);
extern CHAR *CODE_SECTION_END(CODE_SECTION_NAME);
/* Default only one code section. In fact, there may be more than one.
You can define more than one and modify the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START(CODE_SECTION_NAME))
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END(CODE_SECTION_NAME))
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START(CSTACK_SECTION_NAME))
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END(CSTACK_SECTION_NAME))
#elif defined(__GNUC__)
/* The default code section start address */
#define CODE_SECTION_START _stext
/* The default code section end address */
#define CODE_SECTION_END _etext
/* The default C stack section start address */
#define CSTACK_SECTION_START _sstack
/* The default C stack section end address */
#define CSTACK_SECTION_END _estack
extern CHAR *CODE_SECTION_START;
extern CHAR *CODE_SECTION_END;
extern CHAR *CSTACK_SECTION_START;
extern CHAR *CSTACK_SECTION_END;
/* Default only one code section. In fact, there may be more than one.
You can define more than one and modify the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START)
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END)
#else
#error Unknown compiler.
#endif
#elif (LOSCFG_BACKTRACE_TYPE == 2) || (LOSCFG_BACKTRACE_TYPE == 3)
#if defined(__GNUC__)
/* The default code section start address */
#define CODE_SECTION_START __text_start
/* The default code section end address */
#define CODE_SECTION_END __text_end
/* The default C stack section start address */
#define CSTACK_SECTION_START __except_stack_top
/* The default C stack section end address */
#define CSTACK_SECTION_END __start_and_irq_stack_top
extern CHAR *CODE_SECTION_START;
extern CHAR *CODE_SECTION_END;
extern CHAR *CSTACK_SECTION_START;
extern CHAR *CSTACK_SECTION_END;
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START)
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END)
#else
#error Unknown compiler.
#endif
#endif
/* This function is used to judge whether the data in the stack is a code section address.
The default code section is only one, but there may be more than one. Modify the
judgment condition to support multiple code sections. */
STATIC INLINE BOOL OsStackDataIsCodeAddr(UINTPTR value)
{
if ((value >= CODE_START_ADDR) && (value < CODE_END_ADDR)) {
return TRUE;
}
return FALSE;
}
/* This function is currently used to register the memory leak check hook,
other uses do not need to be called temporarily. */
VOID OSBackTraceInit(VOID);
/* This function is used to print the function call stack. */
VOID LOS_BackTrace(VOID);
/* This function is used to record the function call stack. */
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP);
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
@@ -0,0 +1,34 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("cppsupport") {
sources = [ "los_cppsupport.c" ]
include_dirs = [ "../../utils" ]
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_cppsupport.h"
typedef VOID (*InitFunc)(VOID);
INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd)
{
UINTPTR *start;
InitFunc initFunc = NULL;
for (start = (UINTPTR *)initArrayStart; start < (UINTPTR *)initArrayEnd; start++){
initFunc = (InitFunc)(*start);
initFunc();
}
return 0;
}
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @defgroup los_cppsupport c++
* @ingroup kernel
*/
#ifndef _LOS_CPPSUPPORT_H
#define _LOS_CPPSUPPORT_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_cppsupport
* @brief System cppsupport initialization.
*
* @par Description:
* This API is used to initialize the cppsupport .
* @attention
* <ul>
* <li>initArrayStart is the start address of .init_array section,
* initArrayEnd is the end address of .init_array section.</li>
* <li>initArrayStart must be smaller than initArrayEnd,
* initArrayStart and initArrayEnd should be 4(32 bits platform) or 8(64 bits platform) bytes alignment.</li>
* </ul>
*
*
* @retval 0 always return 0.
* @par Dependency:
* <ul><li>los_cppsupport.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_CPPSUPPORT_H */
@@ -0,0 +1,39 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("cpup") {
sources = [ "los_cpup.c" ]
include_dirs = [
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,516 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_cpup.h"
#include "securec.h"
#include "los_memory.h"
#include "los_debug.h"
#include "los_tick.h"
#if (LOSCFG_BASE_CORE_CPUP == 1)
/**
* @ingroup los_cpup
* CPU usage-type macro: used for tasks.
*/
#define OS_THREAD_TYPE_TASK 0
/**
* @ingroup los_cpup
* CPU usage-type macro: used for hardware interrupts.
*/
#define OS_THREAD_TYPE_HWI 1
#define OS_CPUP_RECORD_PERIOD (g_sysClock)
LITE_OS_SEC_BSS UINT16 g_cpupInitFlg = 0;
LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL;
LITE_OS_SEC_BSS UINT64 g_lastRecordTime;
LITE_OS_SEC_BSS UINT16 g_hisPos; /* <current Sampling point of historyTime */
/*****************************************************************************
Function : OsCpupInit
Description: initialization of CPUP
Input : None
Return : LOS_OK or Error Information
*****************************************************************************/
LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit()
{
UINT32 size;
size = g_taskMaxNum * sizeof(OsCpupCB);
g_cpup = (OsCpupCB *)LOS_MemAlloc(m_aucSysMem0, size);
if (g_cpup == NULL) {
return LOS_ERRNO_CPUP_NO_MEMORY;
}
// Ignore the return code when matching CSEC rule 6.6(3).
(VOID)memset_s(g_cpup, size, 0, size);
g_cpupInitFlg = 1;
return LOS_OK;
}
/*****************************************************************************
Function : OsTskCycleStart
Description: start task to get cycles count in current task begining
Input : None
Return : None
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleStart(VOID)
{
UINT32 taskID;
if (g_cpupInitFlg == 0) {
return;
}
taskID = g_losTask.newTask->taskID;
g_cpup[taskID].cpupID = taskID;
g_cpup[taskID].startTime = LOS_SysCycleGet();
return;
}
/*****************************************************************************
Function : OsTskCycleEnd
Description: quit task and get cycle count
Input : None
Return : None
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEnd(VOID)
{
UINT32 taskID;
UINT64 cpuCycle;
if (g_cpupInitFlg == 0) {
return;
}
taskID = g_losTask.runTask->taskID;
if (g_cpup[taskID].startTime == 0) {
return;
}
cpuCycle = LOS_SysCycleGet();
if (cpuCycle < g_cpup[taskID].startTime) {
cpuCycle += g_cyclesPerTick;
}
g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime);
g_cpup[taskID].startTime = 0;
return;
}
/*****************************************************************************
Function : OsTskCycleEndStart
Description: start task to get cycles count in current task ending
Input : None
Return : None
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEndStart(VOID)
{
UINT32 taskID;
UINT64 cpuCycle;
UINT16 loopNum;
if (g_cpupInitFlg == 0) {
return;
}
taskID = g_losTask.runTask->taskID;
cpuCycle = LOS_SysCycleGet();
if (g_cpup[taskID].startTime != 0) {
if (cpuCycle < g_cpup[taskID].startTime) {
cpuCycle += g_cyclesPerTick;
}
g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime);
g_cpup[taskID].startTime = 0;
}
taskID = g_losTask.newTask->taskID;
g_cpup[taskID].cpupID = taskID;
g_cpup[taskID].startTime = cpuCycle;
if ((cpuCycle - g_lastRecordTime) > OS_CPUP_RECORD_PERIOD) {
g_lastRecordTime = cpuCycle;
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
g_cpup[loopNum].historyTime[g_hisPos] = g_cpup[loopNum].allTime;
}
if (g_hisPos == (OS_CPUP_HISTORY_RECORD_NUM - 1)) {
g_hisPos = 0;
} else {
g_hisPos++;
}
}
return;
}
LITE_OS_SEC_TEXT_MINOR static inline UINT16 OsGetPrePos(UINT16 curPos)
{
return (curPos == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : (curPos - 1);
}
LITE_OS_SEC_TEXT_MINOR static VOID OsGetPositions(UINT16 mode, UINT16* curPosAddr, UINT16* prePosAddr)
{
UINT16 curPos;
UINT16 prePos = 0;
curPos = g_hisPos;
if (mode == CPUP_IN_1S) {
curPos = OsGetPrePos(curPos);
prePos = OsGetPrePos(curPos);
} else if (mode == CPUP_LESS_THAN_1S) {
curPos = OsGetPrePos(curPos);
}
*curPosAddr = curPos;
*prePosAddr = prePos;
}
/*****************************************************************************
Function : LOS_SysCpuUsage
Description: get current CPU usage
Input : None
Return : cpupRet:current CPU usage
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysCpuUsage(VOID)
{
UINT64 cpuCycleAll = 0;
UINT32 cpupRet = 0;
UINT16 loopNum;
UINT32 intSave;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
// get end time of current task
intSave = LOS_IntLock();
OsTskCycleEnd();
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
cpuCycleAll += g_cpup[loopNum].allTime;
}
if (cpuCycleAll) {
cpupRet = LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION *
g_cpup[g_idleTaskID].allTime) / cpuCycleAll);
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
/*****************************************************************************
Function : LOS_HistorySysCpuUsage
Description: get CPU usage history
Input : mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s
Return : cpupRet:CPU usage history
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode)
{
UINT64 cpuCycleAll = 0;
UINT64 idleCycleAll = 0;
UINT32 cpupRet = 0;
UINT16 loopNum;
UINT16 curPos;
UINT16 prePos = 0;
UINT32 intSave;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
// get end time of current task
intSave = LOS_IntLock();
OsTskCycleEnd();
OsGetPositions(mode, &curPos, &prePos);
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if (mode == CPUP_IN_1S) {
cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
}
if (mode == CPUP_IN_1S) {
idleCycleAll += g_cpup[g_idleTaskID].historyTime[curPos] -
g_cpup[g_idleTaskID].historyTime[prePos];
} else {
idleCycleAll += g_cpup[g_idleTaskID].allTime - g_cpup[g_idleTaskID].historyTime[curPos];
}
if (cpuCycleAll) {
cpupRet = (LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION * idleCycleAll) / cpuCycleAll));
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
/*****************************************************************************
Function : LOS_TaskCpuUsage
Description: get CPU usage of certain task
Input : taskID : task ID
Return : cpupRet:CPU usage of certain task
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuUsage(UINT32 taskID)
{
UINT64 cpuCycleAll = 0;
UINT16 loopNum;
UINT32 intSave;
UINT32 cpupRet = 0;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
return LOS_ERRNO_CPUP_TSK_ID_INVALID;
}
if (g_cpup[taskID].cpupID != taskID) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
intSave = LOS_IntLock();
OsTskCycleEnd();
/* get total Cycle */
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {
continue;
}
cpuCycleAll += g_cpup[loopNum].allTime;
}
if (cpuCycleAll) {
cpupRet = (UINT32)((LOS_CPUP_PRECISION * g_cpup[taskID].allTime) / cpuCycleAll);
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
/*****************************************************************************
Function : LOS_HistoryTaskCpuUsage
Description: get CPU usage history of certain task
Input : taskID : task ID
: mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s
Return : cpupRet:CPU usage history of task
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode)
{
UINT64 cpuCycleAll = 0;
UINT64 cpuCycleCurTsk = 0;
UINT16 loopNum, curPos;
UINT16 prePos = 0;
UINT32 intSave;
UINT32 cpupRet = 0;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
return LOS_ERRNO_CPUP_TSK_ID_INVALID;
}
if (g_cpup[taskID].cpupID != taskID) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {
return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
}
intSave = LOS_IntLock();
OsTskCycleEnd();
OsGetPositions(mode, &curPos, &prePos);
/* get total Cycle in history */
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {
continue;
}
if (mode == CPUP_IN_1S) {
cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
}
if (mode == CPUP_IN_1S) {
cpuCycleCurTsk += g_cpup[taskID].historyTime[curPos] - g_cpup[taskID].historyTime[prePos];
} else {
cpuCycleCurTsk += g_cpup[taskID].allTime - g_cpup[taskID].historyTime[curPos];
}
if (cpuCycleAll) {
cpupRet = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll);
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return cpupRet;
}
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode)
{
UINT16 loopNum;
UINT16 curPos;
UINT16 prePos = 0;
UINT32 intSave;
UINT64 cpuCycleAll = 0;
UINT64 cpuCycleCurTsk = 0;
if (g_cpupInitFlg == 0) {
return LOS_ERRNO_CPUP_NO_INIT;
}
if (cpupInfo == NULL) {
return LOS_ERRNO_CPUP_TASK_PTR_NULL;
}
intSave = LOS_IntLock();
OsTskCycleEnd();
OsGetPositions(mode, &curPos, &prePos);
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
(g_cpup[loopNum].status == 0)) {
continue;
}
if (mode == CPUP_IN_1S) {
cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
}
for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
(g_cpup[loopNum].status == 0)) {
continue;
}
if (mode == CPUP_IN_1S) {
cpuCycleCurTsk += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
} else {
cpuCycleCurTsk += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
}
cpupInfo[loopNum].usStatus = g_cpup[loopNum].status;
if (cpuCycleAll) {
cpupInfo[loopNum].uwUsage = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll);
}
cpuCycleCurTsk = 0;
}
OsTskCycleStart();
LOS_IntRestore(intSave);
return LOS_OK;
}
/*****************************************************************************
Function : LOS_CpupUsageMonitor
Description: Get CPU usage history of certain task.
Input : type: cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE
: taskID: task ID, Only in SYS_CPU_USAGE type, taskID is invalid
: mode: mode, CPUP_IN_10S = usage in 10s, CPUP_IN_1S = usage in last 1s, CPUP_LESS_THAN_1S = less than 1s
Return : LOS_OK on success, or OS_ERROR on failure
*****************************************************************************/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID)
{
UINT32 ret;
LosTaskCB *taskCB = NULL;
switch (type) {
case SYS_CPU_USAGE:
if (mode == CPUP_IN_10S) {
PRINTK("\nSysCpuUsage in 10s: ");
} else if (mode == CPUP_IN_1S) {
PRINTK("\nSysCpuUsage in 1s: ");
} else {
PRINTK("\nSysCpuUsage in <1s: ");
}
ret = LOS_HistorySysCpuUsage(mode);
PRINTK("%d.%d", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
break;
case TASK_CPU_USAGE:
if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) {
PRINT_ERR("\nThe taskid is invalid.\n");
return OS_ERROR;
}
taskCB = OS_TCB_FROM_TID(taskID);
if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED)) {
PRINT_ERR("\nThe taskid is invalid.\n");
return OS_ERROR;
}
if (mode == CPUP_IN_10S) {
PRINTK("\nCPUusage of taskID %d in 10s: ", taskID);
} else if (mode == CPUP_IN_1S) {
PRINTK("\nCPUusage of taskID %d in 1s: ", taskID);
} else {
PRINTK("\nCPUusage of taskID %d in <1s: ", taskID);
}
ret = LOS_HistoryTaskCpuUsage(taskID, mode);
PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
break;
default:
PRINT_ERR("\nThe type is invalid.\n");
return OS_ERROR;
}
return LOS_OK;
}
#endif /* LOSCFG_BASE_CORE_CPUP */
@@ -0,0 +1,366 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @defgroup los_cpup CPU usage
* @ingroup kernel
*/
#ifndef _LOS_CPUP_H
#define _LOS_CPUP_H
#include "los_interrupt.h"
#include "los_task.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_cpup
* CPU usage error code: The request for memory fails.
*
* Value: 0x02001e00
*
* Solution: Decrease the maximum number of tasks.
*/
#define LOS_ERRNO_CPUP_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00)
/**
* @ingroup los_cpup
* CPU usage error code: The pointer to an input parameter is NULL.
*
* Value: 0x02001e01
*
* Solution: Check whether the pointer to the input parameter is usable.
*/
#define LOS_ERRNO_CPUP_TASK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x01)
/**
* @ingroup los_cpup
* CPU usage error code: The CPU usage is not initialized.
*
* Value: 0x02001e02
*
* Solution: Check whether the CPU usage is initialized.
*/
#define LOS_ERRNO_CPUP_NO_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x02)
/**
* @ingroup los_cpup
* CPU usage error code: The number of threads is invalid.
*
* Value: 0x02001e03
*
* Solution: Check whether the number of threads is applicable for the current operation.
*/
#define LOS_ERRNO_CPUP_MAXNUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x03)
/**
* @ingroup los_cpup
* CPU usage error code: The target thread is not created.
*
* Value: 0x02001e04
*
* Solution: Check whether the target thread is created.
*/
#define LOS_ERRNO_CPUP_THREAD_NO_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x04)
/**
* @ingroup los_cpup
* CPU usage error code: The target task ID is invalid.
*
* Value: 0x02001e05
*
* Solution: Check whether the target task ID is applicable for the current operation.
*/
#define LOS_ERRNO_CPUP_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x05)
/**
* @ingroup los_cpup
* Sum of cpup with all tasks. It means the value of cpup is a permillage.
*/
#define LOS_CPUP_PRECISION 1000
/**
* @ingroup los_cpup
* Multiple of current cpup precision change to percent.
*/
#define LOS_CPUP_PRECISION_MULT (LOS_CPUP_PRECISION / 100)
/**
* @ingroup los_cpup
* Number of historical running time records
*/
#define OS_CPUP_HISTORY_RECORD_NUM 10
/**
* @ingroup los_cpup
* Count the CPU usage structures of a task.
*/
typedef struct {
UINT32 cpupID; /**< Task ID */
UINT16 status; /**< Task status */
UINT64 allTime; /**< Total running time */
UINT64 startTime; /**< Time before a task is invoked */
UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM]; /**< Historical running time */
} OsCpupCB;
extern OsCpupCB *g_cpup;
/**
* @ingroup los_cpup
* @brief Initialization cpup.
*
* @par Description:
* This API is used to initialization cpup.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param None.
*
* @retval UINT32 Initialization result.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern UINT32 OsCpupInit(VOID);
/**
* @ingroup los_cpup
* @brief Start task to get cycles count in current task ending.
*
* @par Description:
* This API is used to start task to get cycles count in current task ending.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param None.
*
* @retval None.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern VOID OsTskCycleEndStart(VOID);
/**
* @ingroup los_cpup
* Count the CPU usage structures of all tasks.
*/
typedef struct tagCpupInfo {
UINT16 usStatus; /**< save the cur task status */
UINT32 uwUsage; /**< Usage. The value range is [0,1000]. */
} CPUP_INFO_S;
/**
* @ingroup los_monitor
* Type of the CPU usage query.
*/
typedef enum {
SYS_CPU_USAGE = 0, /* system cpu occupancy rate */
TASK_CPU_USAGE, /* task cpu occupancy rate */
} CPUP_TYPE_E;
/**
* @ingroup los_monitor
* Mode of the CPU usage query.
*/
typedef enum {
CPUP_IN_10S = 0, /* cpu occupancy rate in 10s */
CPUP_IN_1S, /* cpu occupancy rate in 1s */
CPUP_LESS_THAN_1S, /* cpu occupancy rate less than 1s, if the input mode is none of them, it will be this. */
} CPUP_MODE_E;
/**
* @ingroup los_cpup
* @brief Obtain the current CPU usage.
*
* @par Description:
* This API is used to obtain the current CPU usage.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, error codes will be returned.</li>
* <li> The precision of the CPU usage can be adjusted by changing the value of the CPUP_PRECISION macro.</li>
* </ul>
*
* @param None.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #cpup [0,1000], current CPU usage, of which the precision is adjustable.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_SysCpuUsage
*/
extern UINT32 LOS_SysCpuUsage(VOID);
/**
* @ingroup los_cpup
* @brief Obtain the historical CPU usage.
*
* @par Description:
* This API is used to obtain the historical CPU usage.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.</li>
* </ul>
*
* @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s will be
* obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained. Other values
* indicate that the CPU usage in the period that is less than 1s will be obtained.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #cpup [0,1000], historical CPU usage, of which the precision is adjustable.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_HistoryTaskCpuUsage
*/
extern UINT32 LOS_HistorySysCpuUsage(UINT16 mode);
/**
* @ingroup los_cpup
* @brief Obtain the CPU usage of a specified task.
*
* @par Description:
* This API is used to obtain the CPU usage of a task specified by a passed-in task ID.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.</li>
* <li>The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise,
* the CPU usage fails to be obtained.</li>
* </ul>
*
* @param taskID [IN] UINT32. Task ID.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #OS_ERRNO_CPUP_TSK_ID_INVALID 0x02001e05: The target task ID is invalid.
* @retval #OS_ERRNO_CPUP_THREAD_NO_CREATED 0x02001e04: The target thread is not created.
* @retval #cpup [0,1000], CPU usage of the specified task.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_HistoryTaskCpuUsage
*/
extern UINT32 LOS_TaskCpuUsage(UINT32 taskID);
/**
* @ingroup los_cpup
* @brief Obtain the historical CPU usage of a specified task.
*
* @par Description:
* This API is used to obtain the historical CPU usage of a task specified by a passed-in task ID.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise,
* the CPU usage fails to be obtained.</li>
* <li>The passed-in task ID must be valid and the task specified by the task ID must be created. Otherwise,
* the CPU usage fails to be obtained.</li>
* </ul>
*
* @param taskID [IN] UINT32. Task ID.
* @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s
* will be obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained.
* Other values indicate that the CPU usage in the period that is less than 1s will be obtained.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #OS_ERRNO_CPUP_TSK_ID_INVALID 0x02001e05: The target task ID is invalid.
* @retval #OS_ERRNO_CPUP_THREAD_NO_CREATED 0x02001e04: The target thread is not created.
* @retval #cpup [0,1000], CPU usage of the specified task.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_HistorySysCpuUsage
*/
extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode);
/**
* @ingroup los_cpup
* @brief Obtain the CPU usage of all tasks.
*
* @par Description:
* This API is used to obtain the CPU usage of all tasks according to maximum number of threads.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, the CPU usage fails to be obtained.</li>
* <li>The input parameter pointer must not be NULL, Otherwise, the CPU usage fails to be obtained.</li>
* </ul>
*
* @param cpupInfo [OUT]Type. CPUP_INFO_S* Pointer to the task CPUP information structure to be obtained.
* @param mode [IN] UINT16. Task mode. The parameter value 0 indicates that the CPU usage within 10s
* will be obtained, and the parameter value 1 indicates that the CPU usage in the former 1s will be obtained.
* Other values indicate that the CPU usage in the period that is less than 1s will be obtained.
*
* @retval #OS_ERRNO_CPUP_NO_INIT 0x02001e02: The CPU usage is not initialized.
* @retval #OS_ERRNO_CPUP_TASK_PTR_NULL 0x02001e01: The input parameter pointer is NULL.
* @retval #LOS_OK 0x00000000: The CPU usage of all tasks is successfully obtained.
* @par Dependency:
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @see LOS_SysCpuUsage
*/
extern UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode);
/**
* @ingroup los_monitor
* @brief Obtain CPU usage history of certain task.
*
* @par Description:
* This API is used to obtain CPU usage history of certain task.
* @attention
* <ul>
* <li>This API can be called only after the CPU usage is initialized. Otherwise, -1 will be returned.</li>
* <li> Only in SYS_CPU_USAGE type, uwTaskID is invalid.</li>
* </ul>
*
* @param type [IN] cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE
* @param mode [IN] mode,CPUP_IN_10S = usage in 10s,CPUP_IN_1S = usage in last 1s,
* CPUP_LESS_THAN_1S = less than 1s, if the input mode is none of them, it will be as CPUP_LESS_THAN_1S.
* @param taskID [IN] task ID, Only in SYS_CPU_USAGE type, taskID is invalid
*
* @retval #OS_ERROR -1:CPU usage info obtain failed.
* @retval #LOS_OK 0:CPU usage info is successfully obtained.
* @par Dependency:
* <ul><li>los_monitor.h: the header file that contains the API declaration.</li></ul>
* @see LOS_CpupUsageMonitor
*/
extern UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_CPUP_H */
@@ -0,0 +1,41 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("exchook") {
sources = [
"los_exc_info.c",
"los_exchook.c",
]
include_dirs = [
"../../kernel/arch/include",
"../../kernel/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,298 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_exc_info.h"
#include "securec.h"
#include "los_debug.h"
#include "los_interrupt.h"
#include "los_task.h"
#include "los_exchook.h"
#include "los_membox.h"
#include "los_memory.h"
#if (LOSCFG_PLATFORM_EXC == 1)
#define EXC_MSG_ARRAY_INIT_VALUE 0xff
#define EXC_INT_STATUS_LEN (OS_NVIC_INT_ENABLE_SIZE + OS_NVIC_INT_PEND_SIZE + \
OS_NVIC_INT_ACT_SIZE + OS_NVIC_INT_PRI_SIZE + \
OS_NVIC_EXCPRI_SIZE + OS_NVIC_SHCSR_SIZE + \
OS_NVIC_INT_CTRL_SIZE)
UINT32 g_excQueueMaxNum;
UINT32 g_excMemMaxNum;
VOID *g_excContent = NULL;
UINT32 g_excArraySize = MAX_EXC_MEM_SIZE;
UINT8 g_excMsgArray[MAX_EXC_MEM_SIZE];
STATIC ExcInfoArray g_excArray[OS_EXC_TYPE_MAX];
STATIC UINT32 OsExcSaveIntStatus(UINT32 type, VOID *arg)
{
UINT32 ret;
UINTPTR excContentEnd = (UINTPTR)MAX_INT_INFO_SIZE + (UINTPTR)g_excContent;
(VOID)arg;
*((UINT32 *)g_excContent) = type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = EXC_INT_STATUS_LEN;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
/* save IRQ ENABLE reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_SETENA_BASE, OS_NVIC_INT_ENABLE_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_ENABLE_SIZE;
/* save IRQ PEND reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_SETPEND_BASE, OS_NVIC_INT_PEND_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_PEND_SIZE;
/* save IRQ ACTIVE reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_INT_ACT_BASE, OS_NVIC_INT_ACT_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_ACT_SIZE;
/* save IRQ Priority reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_PRI_BASE, OS_NVIC_INT_PRI_SIZE);
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_PRI_SIZE;
/* save Exception Priority reg group */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_EXCPRI_BASE, OS_NVIC_EXCPRI_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_EXCPRI_SIZE;
/* save IRQ Handler & SHCSR */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_SHCSR, OS_NVIC_SHCSR_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_SHCSR_SIZE;
/* save IRQ Control & ICSR */
ret = memcpy_s(g_excContent, excContentEnd - (UINTPTR)g_excContent,
(const VOID *)OS_NVIC_INT_CTRL, OS_NVIC_INT_CTRL_SIZE);
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + OS_NVIC_INT_CTRL_SIZE;
return LOS_OK;
}
STATIC UINT32 OsExcMemMsgGet(UINT32 type, VOID *arg)
{
UINT32 count;
UINT32 memNum = *(UINT32 *)arg;
UINTPTR memMsgEnd = (UINTPTR)g_excContent + MAX_MEM_INFO_SIZE;
*((UINT32 *)g_excContent) = type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = sizeof(MemInfoCB) * memNum;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
count = OsMemboxExcInfoGet(memNum, g_excContent);
if (count < memNum) {
g_excContent = (UINT8 *)g_excContent + sizeof(MemInfoCB) * count;
(VOID)OsMemExcInfoGet(memNum - count, g_excContent);
}
g_excContent = (VOID *)memMsgEnd;
return LOS_OK;
}
STATIC UINT32 OsExcContentGet(UINT32 type, VOID *arg)
{
UINTPTR excContentEnd = MAX_EXC_MEM_SIZE + (UINTPTR)g_excMsgArray;
errno_t ret;
(VOID)arg;
/* save exception info */
*((UINT32 *)g_excContent) = type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = sizeof(ExcInfo) + sizeof(EXC_CONTEXT_S);
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
ret = memcpy_s((VOID *)g_excContent, excContentEnd - (UINTPTR)g_excContent,
(VOID *)&g_excInfo, sizeof(ExcInfo));
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + sizeof(ExcInfo);
ret = memcpy_s((VOID *)g_excContent, excContentEnd - (UINTPTR)g_excContent,
g_excInfo.context, sizeof(EXC_CONTEXT_S));
if (ret != EOK) {
return LOS_NOK;
}
g_excContent = (UINT8 *)g_excContent + sizeof(EXC_CONTEXT_S);
return LOS_OK;
}
STATIC UINT32 OsExcHookFunc(UINT32 type, UINT32 index, UINT32 loop, UINT32 len, EXC_INFO_SAVE_CALLBACK func)
{
UINT32 i;
*((UINT32 *)g_excContent) = (UINT32)type;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
*((UINT32 *)g_excContent) = len * loop;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
for (i = index; i < loop; i++) {
(VOID)func(i, g_excContent);
g_excContent = (UINT8 *)g_excContent + len;
}
return LOS_OK;
}
#if (LOSCFG_BASE_IPC_QUEUE == 1)
STATIC UINT32 OsExcQueueMsgGet(UINT32 type, VOID *arg)
{
UINT32 len = sizeof(QUEUE_INFO_S);
UINT32 loop = *(UINT32 *)arg;
return OsExcHookFunc(type, 1, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_QueueInfoGet);
}
#endif
STATIC UINT32 OsExcTaskMsgGet(UINT32 type, VOID *arg)
{
UINT32 len = sizeof(TSK_INFO_S);
UINT32 loop = *(UINT32 *)arg;
return OsExcHookFunc(type, 0, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_TaskInfoGet);
}
#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
STATIC UINT32 OsExcTskSwitchMsgGet(UINT32 type, VOID *arg)
{
UINT32 len;
UINT32 loop;
UINT32 taskSwitchCount;
TaskSwitchInfo *taskSwitchInfo = NULL;
UINT32 i;
/* not necessary, just for macro int library */
taskSwitchInfo = (TaskSwitchInfo *)arg;
taskSwitchCount = taskSwitchInfo->cntInfo.maxCnt;
len = sizeof(UINT32) + (sizeof(CHAR) * LOS_TASK_NAMELEN);
if (taskSwitchInfo->cntInfo.isFull) {
i = taskSwitchInfo->idx;
loop = i + taskSwitchCount;
} else {
i = 0;
loop = taskSwitchInfo->idx;
}
return OsExcHookFunc(type, i, loop, len, (EXC_INFO_SAVE_CALLBACK)LOS_TaskSwitchInfoGet);
}
#endif
VOID OsExcRegister(ExcInfoType type, EXC_INFO_SAVE_CALLBACK func, VOID *arg)
{
ExcInfoArray *excInfo = NULL;
if ((type >= OS_EXC_TYPE_MAX) || (func == NULL)) {
PRINT_ERR("HalExcRegister ERROR!\n");
return;
}
excInfo = &(g_excArray[type]);
if (excInfo->valid == TRUE) {
return;
}
excInfo->type = type;
excInfo->fnExcInfoCb = func;
excInfo->arg = arg;
excInfo->valid = TRUE;
}
STATIC VOID OsExcMsgDump(VOID)
{
UINT32 index;
/* Ignore the return code when matching CSEC rule 6.6(4). */
(VOID)memset_s(g_excMsgArray, g_excArraySize, EXC_MSG_ARRAY_INIT_VALUE, g_excArraySize);
*((UINT32 *)g_excContent) = MAX_EXC_MEM_SIZE; /* The total length of exception information. */
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
for (index = 0; index < OS_EXC_TYPE_MAX; index++) {
if (!g_excArray[index].valid) {
continue;
}
g_excArray[index].fnExcInfoCb(g_excArray[index].type, g_excArray[index].arg);
}
*((UINT32 *)g_excContent) = OS_EXC_TYPE_MAX;
g_excContent = (UINT8 *)g_excContent + sizeof(UINT32);
return;
}
VOID OsExcMsgDumpInit(VOID)
{
g_excQueueMaxNum = LOSCFG_BASE_IPC_QUEUE_LIMIT;
g_excMemMaxNum = OS_SYS_MEM_NUM;
g_excContent = (VOID *)g_excMsgArray;
OsExcRegister(OS_EXC_TYPE_CONTEXT, OsExcContentGet, NULL);
OsExcRegister(OS_EXC_TYPE_TSK, OsExcTaskMsgGet, &g_taskMaxNum);
#if (LOSCFG_BASE_IPC_QUEUE == 1)
OsExcRegister(OS_EXC_TYPE_QUE, OsExcQueueMsgGet, &g_excQueueMaxNum);
#endif
OsExcRegister(OS_EXC_TYPE_NVIC, OsExcSaveIntStatus, NULL);
#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
OsExcRegister(OS_EXC_TYPE_TSK_SWITCH, OsExcTskSwitchMsgGet, &g_taskSwitchInfo);
#endif
OsExcRegister(OS_EXC_TYPE_MEM, OsExcMemMsgGet, &g_excMemMaxNum);
(VOID)LOS_RegExcHook(EXC_INTERRUPT, (ExcHookFn)OsExcMsgDump);
}
#endif
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_config.h"
#include "los_task.h"
#include "los_queue.h"
#include "los_memory.h"
#include "los_arch_interrupt.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if (LOSCFG_PLATFORM_EXC == 1)
#define INFO_TYPE_AND_SIZE 8
#define MAX_SCENE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(ExcInfo) + sizeof(EXC_CONTEXT_S))
#define MAX_TSK_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(TSK_INFO_S) * (LOSCFG_BASE_CORE_TSK_LIMIT + 1))
#if (LOSCFG_BASE_IPC_QUEUE == 1)
#define MAX_QUEUE_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(QUEUE_INFO_S) * LOSCFG_BASE_IPC_QUEUE_LIMIT)
#else
#define MAX_QUEUE_INFO_SIZE (0)
#endif
#if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
#define MAX_SWITCH_INFO_SIZE (INFO_TYPE_AND_SIZE + (sizeof(UINT32) + sizeof(CHAR) * LOS_TASK_NAMELEN) * OS_TASK_SWITCH_INFO_COUNT)
#else
#define MAX_SWITCH_INFO_SIZE (0)
#endif
#define MAX_MEM_INFO_SIZE (INFO_TYPE_AND_SIZE + sizeof(MemInfoCB) * OS_SYS_MEM_NUM)
#define MAX_EXC_MEM_SIZE (INFO_TYPE_AND_SIZE + MAX_SCENE_INFO_SIZE + MAX_TSK_INFO_SIZE + MAX_QUEUE_INFO_SIZE + MAX_INT_INFO_SIZE + MAX_SWITCH_INFO_SIZE + MAX_MEM_INFO_SIZE)
typedef enum {
OS_EXC_TYPE_CONTEXT = 0,
OS_EXC_TYPE_TSK = 1,
OS_EXC_TYPE_QUE = 2,
OS_EXC_TYPE_NVIC = 3,
OS_EXC_TYPE_TSK_SWITCH = 4,
OS_EXC_TYPE_MEM = 5,
OS_EXC_TYPE_MAX = 6
} ExcInfoType;
typedef struct {
ExcInfoType flag;
UINT32 length;
ExcInfo info;
EXC_CONTEXT_S context;
} ExcContextInfoArray;
typedef struct {
ExcInfoType flag;
UINT32 length;
TSK_INFO_S taskInfo[LOSCFG_BASE_CORE_TSK_LIMIT + 1];
} ExcTaskInfoArray;
typedef struct {
ExcInfoType flag;
UINT32 length;
QUEUE_INFO_S queueInfo[LOSCFG_BASE_CORE_TSK_LIMIT];
} ExcQueueInfoArray;
typedef struct {
UINT32 totalLen;
ExcContextInfoArray excInfo;
ExcTaskInfoArray taskInfo;
ExcQueueInfoArray queueInfo;
} ExcMsgArray;
typedef UINT32 (*EXC_INFO_SAVE_CALLBACK)(UINT32, VOID *);
typedef struct {
ExcInfoType type;
UINT32 valid;
EXC_INFO_SAVE_CALLBACK fnExcInfoCb;
VOID *arg;
} ExcInfoArray;
VOID OsExcMsgDumpInit(VOID);
extern UINT8 g_excMsgArray[MAX_EXC_MEM_SIZE];
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
@@ -0,0 +1,136 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_exchook.h"
#include "los_context.h"
#ifndef LOSCFG_BASE_EXC_HOOK_LIMIT
#define LOSCFG_BASE_EXC_HOOK_LIMIT 16
#endif
struct Node {
ExcHookFn excHookFn;
struct Node *next;
};
STATIC struct Node g_excNodes[LOSCFG_BASE_EXC_HOOK_LIMIT];
STATIC struct Node *g_excHeads[EXC_TYPE_END + 1]; /* EXC_TYPE_END is used for the free list. */
STATIC VOID DoExcHookInRegOrder(EXC_TYPE excType, struct Node *node)
{
if (node != NULL) {
DoExcHookInRegOrder(excType, node->next);
node->excHookFn(excType);
}
}
STATIC VOID DoExcHook(EXC_TYPE excType)
{
UINT32 intSave;
if (excType >= EXC_TYPE_END) {
return;
}
intSave = LOS_IntLock();
DoExcHookInRegOrder(excType, g_excHeads[excType]);
LOS_IntRestore(intSave);
}
STATIC struct Node *GetFreeNode(VOID)
{
struct Node *node = NULL;
int i;
if (g_excHeads[EXC_TYPE_END] == NULL) {
if (g_excNodes[0].excHookFn != NULL) {
/* no free node now */
return NULL;
} else {
/* Initialize the free list */
for (i = 0; i < LOSCFG_BASE_EXC_HOOK_LIMIT; ++i) {
g_excNodes[i].next = g_excHeads[EXC_TYPE_END];
g_excHeads[EXC_TYPE_END] = &g_excNodes[i];
}
OsExcHookRegister(DoExcHook);
}
}
node = g_excHeads[EXC_TYPE_END];
g_excHeads[EXC_TYPE_END] = node->next;
return node;
}
UINT32 LOS_RegExcHook(EXC_TYPE excType, ExcHookFn excHookFn)
{
UINT32 intSave;
struct Node *node = NULL;
if (excType >= EXC_TYPE_END || excHookFn == NULL) {
return LOS_ERRNO_SYS_PTR_NULL;
}
intSave = LOS_IntLock();
node = GetFreeNode();
if (node == NULL) {
LOS_IntRestore(intSave);
return LOS_ERRNO_SYS_HOOK_IS_FULL;
}
node->excHookFn = excHookFn;
node->next = g_excHeads[excType];
g_excHeads[excType] = node;
LOS_IntRestore(intSave);
return LOS_OK;
}
UINT32 LOS_UnRegExcHook(EXC_TYPE excType, ExcHookFn excHookFn)
{
UINT32 intSave;
struct Node *node = NULL;
struct Node *preNode = NULL;
if (excType >= EXC_TYPE_END || excHookFn == NULL) {
return LOS_ERRNO_SYS_PTR_NULL;
}
intSave = LOS_IntLock();
for (node = g_excHeads[excType]; node != NULL; node = node->next) {
if (node->excHookFn == excHookFn) {
if (preNode) {
preNode->next = node->next;
} else {
g_excHeads[excType] = node->next;
}
node->excHookFn = NULL;
node->next = g_excHeads[EXC_TYPE_END];
g_excHeads[EXC_TYPE_END] = node;
}
preNode = node;
}
LOS_IntRestore(intSave);
return LOS_OK;
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @defgroup los_exchook Exception hooks
* @ingroup kernel
*/
#ifndef _LOS_EXCHOOK_H
#define _LOS_EXCHOOK_H
#include "los_tick.h"
#include "los_debug.h"
#include "los_arch_interrupt.h"
#include "los_interrupt.h"
#include "los_task.h"
#include "los_queue.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_exchook
* @brief: System exception hooks register function.
*
* @par Description:
* This API is used to register exception hooks.
* Hooks will be invoked in reverse order.
*
* @attention:
* <ul><li>This function should not be call in excHookFn.</li></ul>
*
* @param: None.
*
* @retval: LOS_OK success.
* LOS_ERRNO_SYS_HOOK_IS_FULL too many hooks registered. @see LOSCFG_BASE_EXC_HOOK_LIMIT
* LOS_ERRNO_SYS_PTR_NULL excHookFn is null or invalid excType.
*
* @par Dependency:
* <ul><li>los_exchook.h: the header file that contains the API declaration.</li></ul>
* @see None.
*
* */
extern UINT32 LOS_RegExcHook(EXC_TYPE excType, ExcHookFn excHookFn);
/**
* @ingroup los_exchook
* @brief: System exception hooks unregister function.
*
* @par Description:
* This API is used to unregister exception hooks.
*
* @attention:
* <ul><li>This function should not be call in excHookFn.</li></ul>
*
* @param: None.
*
* @retval: LOS_OK success.
* LOS_ERRNO_SYS_PTR_NULL excHookFn is null or invalid excType.
*
* @par Dependency:
* <ul><li>los_exchook.h: the header file that contains the API declaration.</li></ul>
* @see None.
*
* */
extern UINT32 LOS_UnRegExcHook(EXC_TYPE excType, ExcHookFn excHookFn);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_EXCHOOK_H */
@@ -0,0 +1,60 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("fs_operations") {
sources = [
"./fs.c",
]
include_dirs = [
"../../../kernel/arch/include",
"../../../kernel/include",
"../../../utils",
"../../../kal/posix/include",
"./",
]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
declare_args() {
enable_ohos_kernel_liteos_m_fatfs = true
enable_ohos_kernel_liteos_m_littlefs = true
}
group("fs") {
deps = []
deps += [ ".:fs_operations" ]
if (enable_ohos_kernel_liteos_m_fatfs == true) {
deps += [ "fatfs:fatfs" ]
}
if (enable_ohos_kernel_liteos_m_littlefs == true) {
deps += [ "littlefs:littlefs" ]
}
}
@@ -0,0 +1,51 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("fatfs") {
sources = [
"//third_party/FatFs/source/diskio.c",
"//third_party/FatFs/source/ff.c",
"//third_party/FatFs/source/ffsystem.c",
"//third_party/FatFs/source/ffunicode.c",
"fatfs.c",
]
include_dirs = [
"../",
"../../../kernel/arch/include",
"../../../kernel/include",
"../../../utils",
"../../../kal/cmsis",
"../../../kal/posix/include",
"//third_party/bounds_checking_function/include",
"//third_party/FatFs/source/",
]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FATFS_H
#define _FATFS_H
#include "fcntl.h"
#include "dirent.h"
#include "unistd.h"
#include "sys/mount.h"
#include "sys/stat.h"
#include "sys/statfs.h"
#include "fs_config.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#ifndef FAT_MAX_OPEN_FILES
#define FAT_MAX_OPEN_FILES 50
#endif /* FAT_MAX_OPEN_FILES */
/* Format options */
#define FMT_FAT 0x01
#define FMT_FAT32 0x02
#define FMT_ANY 0x07
int fatfs_mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data);
int fatfs_umount(const char *target);
int fatfs_umount2(const char *target, int flag);
int fatfs_open(const char *path, int oflag, ...);
int fatfs_close(int fd);
ssize_t fatfs_read(int fd, void *buf, size_t nbyte);
ssize_t fatfs_write(int fd, const void *buf, size_t nbyte);
off_t fatfs_lseek(int fd, off_t offset, int whence);
int fatfs_unlink(const char *path);
int fatfs_fstat(int fd, struct stat *buf);
int fatfs_stat(const char *path, struct stat *buf);
int fatfs_fsync(int fd);
int fatfs_mkdir(const char *path, mode_t mode);
DIR *fatfs_opendir(const char *dirName);
struct dirent *fatfs_readdir(DIR *dir);
int fatfs_closedir(DIR *dir);
int fatfs_rmdir(const char *path);
int fatfs_rename(const char *oldName, const char *newName);
int fatfs_statfs(const char *path, struct statfs *buf);
int fatfs_ftruncate(int fd, off_t length);
/**
* @brief divide a physical drive (SD card, U disk, and MMC card), this function is OHOS-specific
* @param pdrv physical drive number.
* @param partTbl list of partition size to create on the drive.
* -- item is <= 100: specifies the partition size in percentage of the entire drive space.
* -- item is > 100: specifies number of sectors.
* @return fdisk result
* @retval -1 fdisk error
* @retval 0 fdisk successful
*/
int fatfs_fdisk(int pdrv, const unsigned int *partTbl);
/**
* @brief format FAT device (SD card, U disk, and MMC card), this function is OHOS-specific
* @param dev device name.
* @param sectors sectors per cluster, can be 0 OR power of 2. The sector size for standard FAT volumes is 512 bytes.
* -- sector number is 0 OR >128: automatically choose the appropriate cluster size.
* -- sector number is 1 ~ 128: cluster size = sectors per cluster * 512B.
* @param option file system type.
* -- FMT_FAT
* -- FMT_FAT32
* -- FMT_ANY
* @return format result
* @retval -1 format error
* @retval 0 format successful
*/
int fatfs_format(const char *dev, int sectors, int option);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _FATFS_H */
@@ -0,0 +1,552 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs_operations.h"
#include "los_config.h"
#ifdef LOSCFG_SUPPORT_FATFS
#include "fatfs.h"
#endif
#include "dirent.h"
#include "errno.h"
#include "fcntl.h"
#include "securec.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/mount.h"
#include "sys/statfs.h"
#include "sys/stat.h"
#include "unistd.h"
struct FsMap g_fsmap[MAX_FILESYSTEM_LEN] = {0};
struct FsMap *g_fs = NULL;
#ifdef LOSCFG_NET_LWIP_SACK
#include "lwip/lwipopts.h"
#include "lwip/sockets.h"
#define CONFIG_NSOCKET_DESCRIPTORS LWIP_CONFIG_NUM_SOCKETS
#else
#define CONFIG_NSOCKET_DESCRIPTORS 0
#endif
#define CONFIG_NFILE_DESCRIPTORS FAT_MAX_OPEN_FILES /* only for random currently */
#ifdef LOSCFG_RANDOM_DEV
#include "hks_client.h"
#define RANDOM_DEV_FD CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS
#define RANDOM_DEV_PATH "/dev/random"
#endif
#define FREE_AND_SET_NULL(ptr) do { \
free(ptr); \
ptr = NULL; \
} while (0)
#ifdef LOSCFG_RANDOM_DEV
/**
* @brief Get canonical form of a given path based on cwd(Current working directory).
*
* @param cwd Indicates the current working directory.
* @param path Indicates the path to be canonicalization.
* @param buf Indicates the pointer to the buffer where the result will be return.
* @param bufSize Indicates the size of the buffer.
* @return Returns the length of the canonical path.
*
* @attention if path is an absolute path, cwd is ignored. if cwd if not specified, it is assumed to be root('/').
* if the buffer is not big enough the result will be truncated, but the return value will always be the
* length of the canonical path.
*/
static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, size_t bufSize)
{
size_t offset;
if (!path) {
path = "";
}
if (!cwd || path[0] == '/') {
cwd = "";
}
offset = strlen("///") + 1; // three '/' and one '\0'
size_t tmpLen = strlen(cwd) + strlen(path) + offset;
char *tmpBuf = (char *)malloc(tmpLen);
if (tmpBuf == NULL) {
return FS_SUCCESS;
}
if (-1 == sprintf_s(tmpBuf, tmpLen, "/%s/%s/", cwd, path)) {
free(tmpBuf);
return FS_SUCCESS;
}
char *p;
/* replace /./ to / */
offset = strlen("/./") - 1;
while ((p = strstr(tmpBuf, "/./")) != NULL) {
if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
free(tmpBuf);
return FS_SUCCESS;
}
}
/* replace // to / */
while ((p = strstr(tmpBuf, "//")) != NULL) {
if (EOK != memmove_s(p, tmpLen - (p - tmpBuf), p + 1, tmpLen - (p - tmpBuf) - 1)) {
free(tmpBuf);
return FS_SUCCESS;
}
}
/* handle /../ (e.g., replace /aa/bb/../ to /aa/) */
offset = strlen("/../") - 1;
while ((p = strstr(tmpBuf, "/../")) != NULL) {
char *start = p;
while (start > tmpBuf && *(start - 1) != '/') {
--start;
}
if (EOK != memmove_s(start, tmpLen - (start - tmpBuf), p + offset, tmpLen - (p - tmpBuf) - offset)) {
free(tmpBuf);
return FS_SUCCESS;
}
}
size_t totalLen = strlen(tmpBuf);
/* strip the last / */
if (totalLen > 1 && tmpBuf[totalLen - 1] == '/') {
tmpBuf[--totalLen] = 0;
}
if (!buf || bufSize == 0) {
free(tmpBuf);
return totalLen;
}
if (EOK != memcpy_s(buf, bufSize, tmpBuf, (((totalLen + 1) > bufSize) ? bufSize : (totalLen + 1)))) {
free(tmpBuf);
return FS_SUCCESS;
}
buf[bufSize - 1] = 0;
free(tmpBuf);
return totalLen;
}
#endif
static void InitMountInfo(void)
{
#if (LOSCFG_SUPPORT_FATFS == 1)
extern struct MountOps g_fatfsMnt;
extern struct FileOps g_fatfsFops;
g_fsmap[0].fileSystemtype = strdup("fat");
g_fsmap[0].fsMops = &g_fatfsMnt;
g_fsmap[0].fsFops = &g_fatfsFops;
#endif
#if (LOSCFG_SUPPORT_LITTLEFS == 1)
extern struct MountOps g_lfsMnt;
extern struct FileOps g_lfsFops;
g_fsmap[1].fileSystemtype = strdup("littlefs");
g_fsmap[1].fsMops = &g_lfsMnt;
g_fsmap[1].fsFops = &g_lfsFops;
#endif
}
static struct FsMap *MountFindfs(const char *fileSystemtype)
{
struct FsMap *m = NULL;
for (int i = 0; i < MAX_FILESYSTEM_LEN; i++) {
m = &(g_fsmap[i]);
if (m->fileSystemtype && strcmp(fileSystemtype, m->fileSystemtype) == 0) {
return m;
}
}
return NULL;
}
int mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data)
{
static int initFlag = 0;
if (initFlag == 0) {
InitMountInfo();
initFlag = 1;
}
g_fs = MountFindfs(filesystemtype);
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Mount == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Mount(source, target, filesystemtype, mountflags, data);
}
int umount(const char *target)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Umount == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Umount(target);
}
int umount2(const char *target, int flag)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Umount2 == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Umount2(target, flag);
}
int open(const char *path, int oflag, ...)
{
#ifdef LOSCFG_RANDOM_DEV
unsigned flags = O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_LARGEFILE | O_TRUNC | O_EXCL | O_DIRECTORY;
if ((unsigned)oflag & ~flags) {
errno = EINVAL;
return FS_FAILURE;
}
size_t pathLen = strlen(path) + 1;
char *canonicalPath = (char *)malloc(pathLen);
if (!canonicalPath) {
errno = ENOMEM;
return FS_FAILURE;
}
if (GetCanonicalPath(NULL, path, canonicalPath, pathLen) == 0) {
FREE_AND_SET_NULL(canonicalPath);
errno = ENOMEM;
return FS_FAILURE;
}
if (strcmp(canonicalPath, RANDOM_DEV_PATH) == 0) {
FREE_AND_SET_NULL(canonicalPath);
if ((O_ACCMODE & (unsigned)oflag) != O_RDONLY) {
errno = EPERM;
return FS_FAILURE;
}
if ((unsigned)oflag & O_DIRECTORY) {
errno = ENOTDIR;
return FS_FAILURE;
}
return RANDOM_DEV_FD;
}
if (strcmp(canonicalPath, "/") == 0 || strcmp(canonicalPath, "/dev") == 0) {
FREE_AND_SET_NULL(canonicalPath);
if ((unsigned)oflag & O_DIRECTORY) {
errno = EPERM;
return FS_FAILURE;
}
errno = EISDIR;
return FS_FAILURE;
}
FREE_AND_SET_NULL(canonicalPath);
#endif
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Open == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Open(path, oflag);
}
int close(int fd)
{
#ifdef LOSCFG_RANDOM_DEV
if (fd == RANDOM_DEV_FD) {
return FS_SUCCESS;
}
#endif
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return closesocket(fd);
}
#endif
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Close == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Close(fd);
}
ssize_t read(int fd, void *buf, size_t nbyte)
{
#ifdef LOSCFG_RANDOM_DEV
if (fd == RANDOM_DEV_FD) {
if (nbyte == 0) {
return FS_SUCCESS;
}
if (buf == NULL) {
errno = EINVAL;
return FS_FAILURE;
}
if (nbyte > 1024) {
nbyte = 1024; /* hks_generate_random: random_size must <= 1024 */
}
struct hks_blob key = {HKS_BLOB_TYPE_RAW, (uint8_t *)buf, nbyte};
if (hks_generate_random(&key) != 0) {
errno = EIO;
return FS_FAILURE;
}
return (ssize_t)nbyte;
}
#endif
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return recv(fd, buf, nbyte, 0);
}
#endif
if (g_fs->fsFops == NULL || g_fs->fsFops->Read == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
return g_fs->fsFops->Read(fd, buf, nbyte);
}
ssize_t write(int fd, const void *buf, size_t nbyte)
{
#ifdef LOSCFG_RANDOM_DEV
if (fd == RANDOM_DEV_FD) {
errno = EBADF; /* "/dev/random" is readonly */
return FS_FAILURE;
}
#endif
#ifdef LOSCFG_NET_LWIP_SACK
if (fd >= CONFIG_NFILE_DESCRIPTORS && fd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) {
return send(fd, buf, nbyte, 0);
}
#endif
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Write == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Write(fd, buf, nbyte);
}
off_t lseek(int fd, off_t offset, int whence)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Seek == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Seek(fd, offset, whence);
}
int unlink(const char *path)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Unlink == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Unlink(path);
}
int fstat(int fd, struct stat *buf)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Fstat == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Fstat(fd, buf);
}
int stat(const char *path, struct stat *buf)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Getattr == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Getattr(path, buf);
}
int fsync(int fd)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Fsync == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Fsync(fd);
}
int mkdir(const char *path, mode_t mode)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Mkdir == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Mkdir(path, mode);
}
DIR *opendir(const char *dirName)
{
if (g_fs == NULL) {
errno = ENODEV;
return NULL;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Opendir == NULL) {
errno = ENOSYS;
return NULL;
}
return g_fs->fsFops->Opendir(dirName);
}
struct dirent *readdir(DIR *dir)
{
if (g_fs == NULL) {
errno = ENODEV;
return NULL;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Readdir == NULL) {
errno = ENOSYS;
return NULL;
}
return g_fs->fsFops->Readdir(dir);
}
int closedir(DIR *dir)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Closedir == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Closedir(dir);
}
int rmdir(const char *path)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Rmdir == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Rmdir(path);
}
int rename(const char *oldName, const char *newName)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Rename == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Rename(oldName, newName);
}
int statfs(const char *path, struct statfs *buf)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsMops == NULL || g_fs->fsMops->Statfs == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsMops->Statfs(path, buf);
}
int ftruncate(int fd, off_t length)
{
if (g_fs == NULL) {
errno = ENODEV;
return FS_FAILURE;
}
if (g_fs->fsFops == NULL || g_fs->fsFops->Ftruncate == NULL) {
errno = ENOSYS;
return FS_FAILURE;
}
return g_fs->fsFops->Ftruncate(fd, length);
}
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FS_OPERATIONS_H_
#define _FS_OPERATIONS_H_
#include "fcntl.h"
#include "dirent.h"
#include "unistd.h"
#include "sys/mount.h"
#include "sys/stat.h"
#include "sys/statfs.h"
#define FS_SUCCESS 0
#define FS_FAILURE (-1)
#define MAX_FILESYSTEM_LEN 2
struct MountOps {
int (*Mount)(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags,
const void *data);
int (*Umount)(const char* target);
int (*Umount2)(const char* target, int flag);
int (*Statfs)(const char *path, struct statfs *buf);
};
struct FsMap {
const char *fileSystemtype;
const struct MountOps *fsMops;
const struct FileOps *fsFops;
};
struct FileOps {
int (*Open)(const char *path, int openFlag, ...);
int (*Close)(int fd);
int (*Unlink)(const char *fileName);
int (*Rmdir)(const char *dirName);
int (*Mkdir)(const char *dirName, mode_t mode);
struct dirent *(*Readdir)(DIR *dir);
DIR *(*Opendir)(const char *dirName);
int (*Closedir)(DIR *dir);
int (*Read)(int fd, void *buf, size_t len);
int (*Write)(int fd, const void *buf, size_t len);
off_t (*Seek)(int fd, off_t offset, int whence);
int (*Getattr)(const char *path, struct stat *buf);
int (*Rename)(const char *oldName, const char *newName);
int (*Fsync)(int fd);
int (*Fstat)(int fd, struct stat *buf);
int (*Stat)(const char *path, struct stat *buf);
int (*Ftruncate)(int fd, off_t length);
};
#endif /* _FS_OPERATIONS_H_ */
@@ -0,0 +1,49 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("littlefs") {
sources = [
"lfs_api.c",
"//third_party/littlefs/lfs.c",
"//third_party/littlefs/lfs_util.c",
]
include_dirs = [
"../../../kernel/arch/include",
"../../../kernel/include",
"../../../utils",
"../../../kal/cmsis",
"../../../kal/posix/include",
"./",
"../",
"//third_party/littlefs",
]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
@@ -0,0 +1,769 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _GNU_SOURCE 1
#include "lfs_api.h"
#include "los_config.h"
#include "securec.h"
lfs_t g_lfs;
FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0};
struct FileOpInfo g_fsOp[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
static LittleFsHandleStruct g_handle[LITTLE_FS_MAX_OPEN_FILES] = {0};
struct dirent g_nameValue;
static pthread_mutex_t g_FslocalMutex = PTHREAD_MUTEX_INITIALIZER;
static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a","/b","/c"};
LittleFsHandleStruct *LfsAllocFd(const char *fileName, int *fd)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) {
if (g_handle[i].useFlag == 0) {
*fd = i;
g_handle[i].useFlag = 1;
g_handle[i].pathName = strdup(fileName);
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_handle[i]);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
*fd = INVALID_FD;
return NULL;
}
static void LfsFreeFd(int fd)
{
pthread_mutex_lock(&g_FslocalMutex);
g_handle[fd].useFlag = 0;
if (g_handle[fd].pathName != NULL) {
free((void *)g_handle[fd].pathName);
g_handle[fd].pathName = NULL;
}
if (g_handle[fd].lfsHandle != NULL) {
g_handle[fd].lfsHandle = NULL;
}
pthread_mutex_unlock(&g_FslocalMutex);
}
BOOL CheckFileIsOpen(const char *fileName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LITTLE_FS_MAX_OPEN_FILES; i++) {
if (g_handle[i].useFlag == 1) {
if (strcmp(g_handle[i].pathName, fileName) == 0) {
pthread_mutex_unlock(&g_FslocalMutex);
return TRUE;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return FALSE;
}
static BOOL LfsFdIsValid(int fd)
{
if (fd >= LITTLE_FS_MAX_OPEN_FILES || fd < 0) {
return FALSE;
}
if (g_handle[fd].lfsHandle == NULL) {
return FALSE;
}
return TRUE;
}
FileDirInfo *GetFreeDir(const char *dirName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
if (g_lfsDir[i].useFlag == 0) {
g_lfsDir[i].useFlag = 1;
g_lfsDir[i].dirName = strdup(dirName);
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_lfsDir[i]);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return NULL;
}
void FreeDirInfo(const char *dirName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
if (g_lfsDir[i].useFlag == 1 && strcmp(g_lfsDir[i].dirName, dirName) == 0) {
g_lfsDir[i].useFlag = 0;
if (g_lfsDir[i].dirName) {
free(g_lfsDir[i].dirName);
g_lfsDir[i].dirName = NULL;
}
pthread_mutex_unlock(&g_FslocalMutex);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
}
BOOL CheckDirIsOpen(const char *dirName)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {
if (g_lfsDir[i].useFlag == 1) {
if (strcmp(g_lfsDir[i].dirName, dirName) == 0) {
pthread_mutex_unlock(&g_FslocalMutex);
return TRUE;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return FALSE;
}
int GetFirstLevelPathLen(const char *pathName)
{
int len = 1;
for (int i = 1; i < strlen(pathName) + 1; i++) {
if (pathName[i] == '/') {
break;
}
len++;
}
return len;
}
BOOL CheckPathIsMounted(const char *pathName, struct FileOpInfo **fileOpInfo)
{
char tmpName[LITTLEFS_MAX_LFN_LEN] = {0};
int len = GetFirstLevelPathLen(pathName);
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 1) {
(void)strncpy_s(tmpName, LITTLEFS_MAX_LFN_LEN, pathName, len);
if (strcmp(tmpName, g_fsOp[i].dirName) == 0) {
*fileOpInfo = &(g_fsOp[i]);
pthread_mutex_unlock(&g_FslocalMutex);
return TRUE;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return FALSE;
}
struct FileOpInfo *AllocMountRes(const char* target, const struct FileOps *fileOps)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 0 && strcmp(target, g_littlefsMntName[i]) == 0) {
g_fsOp[i].useFlag = 1;
g_fsOp[i].fsVops = fileOps;
g_fsOp[i].dirName = strdup(target);
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_fsOp[i]);
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return NULL;
}
int SetDefaultMountPath(int pathNameIndex, const char* target)
{
if (pathNameIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
return VFS_ERROR;
}
pthread_mutex_lock(&g_FslocalMutex);
g_littlefsMntName[pathNameIndex] = strdup(target);
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_OK;
}
struct FileOpInfo *GetMountRes(const char *target, int *mountIndex)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 1) {
if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
*mountIndex = i;
pthread_mutex_unlock(&g_FslocalMutex);
return &(g_fsOp[i]);
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return NULL;
}
int FreeMountResByIndex(int mountIndex)
{
if (mountIndex < 0 || mountIndex >= LOSCFG_LFS_MAX_MOUNT_SIZE) {
return VFS_ERROR;
}
pthread_mutex_lock(&g_FslocalMutex);
if (g_fsOp[mountIndex].useFlag == 1 && g_fsOp[mountIndex].dirName != NULL) {
g_fsOp[mountIndex].useFlag = 0;
free(g_fsOp[mountIndex].dirName);
g_fsOp[mountIndex].dirName = NULL;
}
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_OK;
}
int FreeMountRes(const char *target)
{
pthread_mutex_lock(&g_FslocalMutex);
for (int i = 0; i < LOSCFG_LFS_MAX_MOUNT_SIZE; i++) {
if (g_fsOp[i].useFlag == 1) {
if (g_fsOp[i].dirName && strcmp(target, g_fsOp[i].dirName) == 0) {
g_fsOp[i].useFlag = 0;
free(g_fsOp[i].dirName);
g_fsOp[i].dirName = NULL;
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_OK;
}
}
}
pthread_mutex_unlock(&g_FslocalMutex);
return VFS_ERROR;
}
static int ConvertFlagToLfsOpenFlag (int oflags)
{
int lfsOpenFlag = 0;
if (oflags & O_CREAT) {
lfsOpenFlag |= LFS_O_CREAT;
}
if (oflags & O_EXCL) {
lfsOpenFlag |= LFS_O_EXCL;
}
if (oflags & O_TRUNC) {
lfsOpenFlag |= LFS_O_TRUNC;
}
if (oflags & O_APPEND) {
lfsOpenFlag |= LFS_O_APPEND;
}
if (oflags & O_RDWR) {
lfsOpenFlag |= LFS_O_RDWR;
}
if (oflags & O_WRONLY) {
lfsOpenFlag |= LFS_O_WRONLY;
}
if (oflags & O_RDONLY) {
lfsOpenFlag |= LFS_O_RDONLY;
}
return lfsOpenFlag;
}
static int LittlefsErrno(int result)
{
return (result < 0) ? -result : result;
}
const struct MountOps g_lfsMnt = {
.Mount = LfsMount,
.Umount = LfsUmount,
};
const struct FileOps g_lfsFops = {
.Mkdir = LfsMkdir,
.Unlink = LfsUnlink,
.Rmdir = LfsRmdir,
.Opendir = LfsOpendir,
.Readdir = LfsReaddir,
.Closedir = LfsClosedir,
.Open = LfsOpen,
.Close = LfsClose,
.Write = LfsWrite,
.Read = LfsRead,
.Seek = LfsSeek,
.Rename = LfsRename,
.Getattr = LfsStat,
.Fsync = LfsFsync,
};
int LfsMount(const char *source, const char *target, const char *fileSystemType, unsigned long mountflags,
const void *data)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (target == NULL || fileSystemType == NULL || data == NULL) {
errno = EFAULT;
ret = VFS_ERROR;
goto errout;
}
if (strcmp(fileSystemType, "littlefs") != 0) {
errno = ENODEV;
ret = VFS_ERROR;
goto errout;
}
if (CheckPathIsMounted(target, &fileOpInfo)) {
errno = EBUSY;
ret = VFS_ERROR;
goto errout;
}
// select free mount resource
fileOpInfo = AllocMountRes(target, &g_lfsFops);
if (fileOpInfo == NULL) {
errno = ENODEV;
ret = VFS_ERROR;
goto errout;
}
ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
if (ret != 0) {
ret = lfs_format(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
if (ret == 0) {
ret = lfs_mount(&(fileOpInfo->lfsInfo), (struct lfs_config*)data);
}
}
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
errout:
return ret;
}
int LfsUmount(const char *target)
{
int ret;
int mountIndex = -1;
struct FileOpInfo *fileOpInfo = NULL;
if (target == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
fileOpInfo = GetMountRes(target, &mountIndex);
if (fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_unmount(&(fileOpInfo->lfsInfo));
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
(void)FreeMountResByIndex(mountIndex);
return ret;
}
int LfsUnlink(const char *fileName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (fileName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(fileName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_remove(&(fileOpInfo->lfsInfo), fileName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsMkdir(const char *dirName, mode_t mode)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (dirName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_mkdir(&(fileOpInfo->lfsInfo), dirName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsRmdir(const char *dirName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (dirName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_remove(&(fileOpInfo->lfsInfo), dirName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
DIR *LfsOpendir(const char *dirName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (dirName == NULL) {
errno = EFAULT;
goto errout;
}
if (CheckPathIsMounted(dirName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
goto errout;
}
if (CheckDirIsOpen(dirName)) {
errno = EBUSY;
goto errout;
}
FileDirInfo *dirInfo = GetFreeDir(dirName);
if (dirInfo == NULL) {
errno = ENFILE;
goto errout;
}
ret = lfs_dir_open(&(fileOpInfo->lfsInfo), (lfs_dir_t *)(&(dirInfo->dir)), dirName);
if (ret != 0) {
FreeDirInfo(dirName);
errno = LittlefsErrno(ret);
goto errout;
}
dirInfo->lfsHandle = &(fileOpInfo->lfsInfo);
return (DIR *)dirInfo;
errout:
return NULL;
}
struct dirent *LfsReaddir(DIR *dir)
{
int ret;
struct lfs_info lfsInfo;
FileDirInfo *dirInfo = (FileDirInfo *)dir;
if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
errno = EBADF;
return NULL;
}
ret = lfs_dir_read(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)), &lfsInfo);
if (ret == TRUE) {
pthread_mutex_lock(&g_FslocalMutex);
(void)strncpy_s(g_nameValue.d_name, sizeof(g_nameValue.d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
if (lfsInfo.type == LFS_TYPE_DIR) {
g_nameValue.d_type = DT_DIR;
} else if (lfsInfo.type == LFS_TYPE_REG) {
g_nameValue.d_type = DT_REG;
}
g_nameValue.d_reclen = lfsInfo.size;
pthread_mutex_unlock(&g_FslocalMutex);
return &g_nameValue;
}
if (ret != 0) {
errno = LittlefsErrno(ret);
}
return NULL;
}
int LfsClosedir(DIR *dir)
{
int ret;
FileDirInfo *dirInfo = (FileDirInfo *)dir;
if (dirInfo == NULL || dirInfo->lfsHandle == NULL) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_dir_close(dirInfo->lfsHandle, (lfs_dir_t *)(&(dirInfo->dir)));
FreeDirInfo(dirInfo->dirName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsOpen(const char *pathName, int openFlag, int mode)
{
int fd = INVALID_FD;
int err = INVALID_FD;
struct FileOpInfo *fileOpInfo = NULL;
if (pathName == NULL) {
errno = EFAULT;
goto errout;
}
if (CheckPathIsMounted(pathName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
goto errout;
}
// if file is already open, return invalid fd
if (CheckFileIsOpen(pathName)) {
errno = EBUSY;
goto errout;
}
LittleFsHandleStruct *fsHandle = LfsAllocFd(pathName, &fd);
if (fd == INVALID_FD) {
errno = ENFILE;
goto errout;
}
int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
err = lfs_file_open(&(fileOpInfo->lfsInfo), &(fsHandle->file), pathName, lfsOpenFlag);
if (err != 0) {
LfsFreeFd(fd);
errno = LittlefsErrno(err);
goto errout;
}
g_handle[fd].lfsHandle = &(fileOpInfo->lfsInfo);
return fd;
errout:
return INVALID_FD;
}
int LfsRead(int fd, void *buf, unsigned int len)
{
int ret;
if (buf == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_file_read(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
if (ret < 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsWrite(int fd, const void *buf, unsigned int len)
{
int ret;
if (buf == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_file_write(g_handle[fd].lfsHandle, &(g_handle[fd].file), buf, len);
if (ret < 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
off_t LfsSeek(int fd, off_t offset, int whence)
{
off_t ret;
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = (off_t)lfs_file_seek(g_handle[fd].lfsHandle, &(g_handle[fd].file), offset, whence);
if (ret < 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsClose(int fd)
{
int ret;
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
pthread_mutex_lock(&g_FslocalMutex);
ret = lfs_file_close(g_handle[fd].lfsHandle, &(g_handle[fd].file));
pthread_mutex_unlock(&g_FslocalMutex);
LfsFreeFd(fd);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsRename(const char *oldName, const char *newName)
{
int ret;
struct FileOpInfo *fileOpInfo = NULL;
if (oldName == NULL || newName == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(oldName, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_rename(&(fileOpInfo->lfsInfo), oldName, newName);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsStat(const char *path, struct stat *buf)
{
int ret;
struct lfs_info info;
struct FileOpInfo *fileOpInfo = NULL;
if (path == NULL || buf == NULL) {
errno = EFAULT;
return VFS_ERROR;
}
if (CheckPathIsMounted(path, &fileOpInfo) == FALSE || fileOpInfo == NULL) {
errno = ENOENT;
return VFS_ERROR;
}
ret = lfs_stat(&(fileOpInfo->lfsInfo), path, &info);
if (ret == 0) {
buf->st_size = info.size;
} else {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
int LfsFsync(int fd)
{
int ret;
if (LfsFdIsValid(fd) == FALSE) {
errno = EBADF;
return VFS_ERROR;
}
ret = lfs_file_sync(g_handle[fd].lfsHandle, &(g_handle[fd].file));
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = VFS_ERROR;
}
return ret;
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LFS_API_H_
#define _LFS_API_H_
#include "bits/alltypes.h"
#include "fcntl.h"
#include "sys/stat.h"
#include "dirent.h"
#include "errno.h"
#include "fs_operations.h"
#include "lfs.h"
#include "lfs_util.h"
#include "memory.h"
#include "pthread.h"
#define INVALID_FD (-1)
typedef unsigned mode_t;
#ifndef VFS_ERROR
#define VFS_ERROR (-1)
#endif
#ifndef VFS_OK
#define VFS_OK 0
#endif
typedef struct {
uint8_t useFlag;
const char *pathName;
lfs_t *lfsHandle;
lfs_file_t file;
} LittleFsHandleStruct;
struct FileOpInfo {
uint8_t useFlag;
const struct FileOps *fsVops;
char *dirName;
lfs_t lfsInfo;
};
typedef struct {
uint8_t useFlag;
char *dirName;
lfs_t *lfsHandle;
lfs_dir_t dir;
} FileDirInfo;
#define LITTLE_FS_MAX_OPEN_FILES 100
#define LITTLE_FS_STANDARD_NAME_LENGTH 50
#define LITTLE_FS_MAX_NAME_LEN 255
#define MAX_DEF_BUF_NUM 21
#define MAX_BUFFER_LEN 100
#define MAX_WRITE_FILE_LEN 500
#define MAX_READ_FILE_LEN 500
#define LITTLEFS_MAX_LFN_LEN 255
#ifndef LFS_MAX_OPEN_DIRS
#define LFS_MAX_OPEN_DIRS 10
#endif
LittleFsHandleStruct *GetFreeFd(int *fd);
int InitMountInfo(const char *fileSystemType, const struct MountOps *fsMops);
int LfsMount(const char *source, const char *target, const char *fileSystemType, unsigned long mountflags,
const void *data);
int LfsUmount(const char *target);
int LfsUnlink(const char *fileName);
int LfsMkdir(const char *dirName, mode_t mode);
int LfsRmdir(const char *dirName);
DIR *LfsOpendir(const char *dirName);
struct dirent *LfsReaddir(DIR *dir);
int LfsClosedir(DIR *dir);
int LfsOpen(const char *pathName, int openFlag, int mode);
int LfsRead(int fd, void *buf, unsigned int len);
int LfsWrite(int fd, const void *buf, unsigned int len);
off_t LfsSeek(int fd, off_t offset, int whence);
int LfsClose(int fd);
int LfsRename(const char *oldName, const char *newName);
int LfsStat(const char *path, struct stat *buf);
int LfsFsync(int fd);
int SetDefaultMountPath(int pathNameIndex, const char* target);
const struct FsMap *MountFindfs(const char *filesystemtype);
#endif /* _LFS_API_H_ */
@@ -0,0 +1,50 @@
# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("lwip_porting.gni")
import("//third_party/lwip/lwip.gni")
config("lwip_depends") {
defines = [ "_BSD_SOURCE = 1" ]
}
static_library("lwip") {
include_dirs = [
"//kernel/liteos_m/kal/posix/include",
"//kernel/liteos_m/kernel/arch/include",
]
include_dirs += LWIP_PORTING_INCLUDE_DIRS
include_dirs += LWIP_INCLUDE_DIRS
sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES
configs += [ ":lwip_depends" ]
deps = [ "//kernel/liteos_m/kal/posix" ]
}
@@ -0,0 +1,178 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <lwip/sys.h>
#include <lwip/etharp.h>
#include <lwip/netifapi.h>
#include <lwip/priv/api_msg.h>
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
static struct netif *netif_find_by_name(const char *name)
{
struct netif *netif = NULL;
LWIP_ASSERT_CORE_LOCKED();
if (name == NULL) {
return NULL;
}
NETIF_FOREACH(netif) {
if (strcmp("lo", name) == 0 && (netif->name[0] == 'l' && netif->name[1] == 'o')) {
LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found lo\n"));
return netif;
}
if (strcmp(netif->full_name, name) == 0) {
LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: found %s\n", name));
return netif;
}
}
LWIP_DEBUGF(NETIF_DEBUG, ("netif_find_by_name: didn't find %s\n", name));
return NULL;
}
static err_t netifapi_do_find_by_name(struct tcpip_api_call_data *m)
{
/* cast through void* to silence alignment warnings.
* We know it works because the structs have been instantiated as struct netifapi_msg */
struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
msg->netif = netif_find_by_name(msg->msg.ifs.name);
return ERR_OK;
}
struct netif *netifapi_netif_find_by_name(const char *name)
{
struct netif *netif = NULL;
NETIFAPI_VAR_DECLARE(msg);
NETIFAPI_VAR_ALLOC(msg);
NETIFAPI_VAR_REF(msg).netif = NULL;
#if LWIP_MPU_COMPATIBLE
if (strncpy_s(NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE, name, NETIF_NAMESIZE - 1)) {
NETIFAPI_VAR_FREE(msg);
return netif;
}
NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0';
#else
NETIFAPI_VAR_REF(msg).msg.ifs.name = (char *)name;
#endif /* LWIP_MPU_COMPATIBLE */
(void)tcpip_api_call(netifapi_do_find_by_name, &API_VAR_REF(msg).call);
netif = msg.netif;
NETIFAPI_VAR_FREE(msg);
return netif;
}
#if LWIP_IPV6
int ip6addr_aton(const char *cp, ip6_addr_t *addr)
{
const int ipv6_blocks = 8;
u16_t current_block_index = 0;
u16_t current_block_value = 0;
u16_t addr16[ipv6_blocks];
u16_t *a16 = (u16_t *)addr->addr;
int squash_pos = ipv6_blocks;
int i;
const char *sc = cp;
const char *ss = cp-1;
for (; ; sc++) {
if (current_block_index >= ipv6_blocks) {
return 0; // address too long
}
if (*sc == 0) {
if (sc - ss == 1) {
if (squash_pos != current_block_index) {
return 0; // empty address or address ends with a single ':'
} // else address ends with one valid "::"
} else {
addr16[current_block_index++] = current_block_value;
}
break;
} else if (*sc == ':') {
if (sc - ss == 1) {
if (sc != cp || sc[1] != ':') {
return 0; // address begins with a single ':' or contains ":::"
} // else address begins with one valid "::"
} else {
addr16[current_block_index++] = current_block_value;
}
if (sc[1] == ':') {
if (squash_pos != ipv6_blocks) {
return 0; // more than one "::"
}
squash_pos = current_block_index;
sc++;
}
ss = sc; // ss points to the recent ':' position
current_block_value = 0;
} else if (lwip_isxdigit(*sc) && (sc - ss) < 5) { // 4 hex-digits at most
current_block_value = (current_block_value << 4) +
(*sc | ('a' - 'A')) - '0' - ('a' - '9' - 1) * (*sc >= 'A');
#if LWIP_IPV4
} else if (*sc == '.' && current_block_index < ipv6_blocks - 1) {
ip4_addr_t ip4;
int ret = ip4addr_aton(ss+1, &ip4);
if (!ret) {
return 0;
}
ip4.addr = lwip_ntohl(ip4.addr);
addr16[current_block_index++] = (u16_t)(ip4.addr >> 16);
addr16[current_block_index++] = (u16_t)(ip4.addr);
break;
#endif /* LWIP_IPV4 */
} else {
return 0; // unexpected char or too many digits
}
}
if (squash_pos == ipv6_blocks && current_block_index != ipv6_blocks) {
return 0; // address too short
}
if (squash_pos != ipv6_blocks && current_block_index == ipv6_blocks) {
return 0; // unexpected "::" in address
}
for (i = 0; i < squash_pos; ++i) {
a16[i] = lwip_htons(addr16[i]);
}
for (; i < ipv6_blocks - current_block_index + squash_pos; ++i) {
a16[i] = 0;
}
for (; i < ipv6_blocks; ++i) {
a16[i] = lwip_htons(addr16[i - ipv6_blocks + current_block_index]);
}
return 1;
}
#endif /* LWIP_IPV6 */
@@ -0,0 +1,41 @@
# Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
LWIP_PORTING_DIR = "//kernel/liteos_m/components/net/lwip-2.1"
LWIP_PORTING_INCLUDE_DIRS = [ "$LWIP_PORTING_DIR/porting/include" ]
LWIP_PORTING_FILES = [
"$LWIP_PORTING_DIR/porting/src/driverif.c",
"$LWIP_PORTING_DIR/porting/src/lwip_init.c",
"$LWIP_PORTING_DIR/porting/src/netdb_porting.c",
"$LWIP_PORTING_DIR/porting/src/sockets_porting.c",
"$LWIP_PORTING_DIR/porting/src/sys_arch.c",
"$LWIP_PORTING_DIR/enhancement/src/fixme.c",
]
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_CC_H_
#define _LWIP_PORTING_CC_H_
#ifdef LITTLE_ENDIAN
#undef LITTLE_ENDIAN
#endif
#ifdef BIG_ENDIAN
#undef BIG_ENDIAN
#endif
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include "securec.h"
#include "memory_pool.h"
#ifdef htons
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#endif
#define SOCKLEN_T_DEFINED
#define SA_FAMILY_T_DEFINED
#define IN_PORT_T_DEFINED
#define LWIP_TIMEVAL_PRIVATE 0
#define LWIP_ERRNO_STDINCLUDE
#define LWIP_SOCKET_STDINCLUDE
#define LWIP_DNS_API_DEFINE_ERRORS 0
#define LWIP_DNS_API_DEFINE_FLAGS 0
#define LWIP_DNS_API_DECLARE_STRUCTS 0
#define LWIP_DNS_API_DECLARE_H_ERRNO 0
#ifndef __SIZEOF_POINTER__
#define __SIZEOF_POINTER__ 4 // 32 bit system
#endif
#define LOS_TASK_STATUS_DETACHED 0x0100 // reserved
#if defined(__arm__) && defined(__ARMCC_VERSION)
/* Keil uVision4 tools */
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(fld) fld
#define ALIGNED(n) __align(n)
#elif defined (__IAR_SYSTEMS_ICC__)
/* IAR Embedded Workbench tools */
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(fld) fld
// #error NEEDS ALIGNED
#else
/* GCC tools (CodeSourcery) */
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(fld) fld
#define ALIGNED(n) __attribute__((aligned (n)))
#endif
#define LWIP_RAND rand
extern void HilogPrintf(const char *fmt, ...);
#ifndef HILOG_INFO
#define HILOG_INFO(...)
#ifndef HILOG_MODULE_APP
#define HILOG_MODULE_APP 0
#endif
#endif
#ifndef HILOG_ERROR
#define HILOG_ERROR(...)
#endif
#define LWIP_PLATFORM_DIAG(vars) HilogPrintf vars
#define LWIP_PLATFORM_ASSERT(x) do {HILOG_ERROR(HILOG_MODULE_APP, \
"Assertion \"%s\" errno %d line %d in %s\n", \
x, errno, __LINE__, __FILE__);} while (0)
#define mem_clib_malloc LWIP_MEM_ALLOC
#define mem_clib_free LWIP_MEM_FREE
#define mem_clib_calloc LWIP_MEM_CALLOC
#define init_waitqueue_head(...)
#define poll_check_waiters(...)
#define IOCTL_CMD_CASE_HANDLER()
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.114.114")))
#define DNS_SERVER_ADDRESS_SECONDARY(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("114.114.115.115")))
#endif /* _LWIP_PORTING_CC_H_ */
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_PERF_H_
#define _LWIP_PORTING_PERF_H_
#if LWIP_PERF
#define PERF_START do { /* something to do */ } while (0)
#define PERF_STOP(x) do { /* something to do */ } while (0)
#endif
#endif /* _LWIP_PORTING_PERF_H_ */
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_SYS_ARCH_H_
#define _LWIP_PORTING_SYS_ARCH_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Mutex
*/
typedef uint32_t sys_mutex_t;
/**
* Semaphore
*/
typedef uint32_t sys_sem_t;
/**
* MessageBox
*/
typedef uint32_t sys_mbox_t;
/**
* Protector
*/
typedef void *sys_prot_t;
/**
* Thread
*/
typedef uint32_t sys_thread_t;
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_SYS_ARCH_H_ */
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_INET_H_
#define _LWIP_PORTING_INET_H_
#include <arpa/inet.h>
#include <netinet/in.h>
#include_next <lwip/inet.h>
#if LWIP_IPV4
#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) \
((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) \
(ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
/* directly map this to the lwip internal functions */
#define inet_addr(cp) ipaddr_addr(cp)
#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr))
#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) \
{(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
(target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
(target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
(target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) \
{(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
(target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
(target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
(target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3]; \
ip6_addr_clear_zone(target_ip6addr);}
#endif /* LWIP_IPV6 */
#endif /* _LWIP_PORTING_INET_H_ */
@@ -0,0 +1,298 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_LWIPOPTS_H_
#define _LWIP_PORTING_LWIPOPTS_H_
// lwIP debug options, comment the ones you don't want
#define LWIP_DEBUG 0
#if LWIP_DEBUG
#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define IGMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define DRIVERIF_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TIMERS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_ERR_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_SACK_DEBUG LWIP_DBG_OFF
#define TCP_TLP_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF
#define AUTOIP_DEBUG LWIP_DBG_OFF
#define DNS_DEBUG LWIP_DBG_OFF
#define TFTP_DEBUG LWIP_DBG_OFF
#define SYS_ARCH_DEBUG LWIP_DBG_OFF
#define SNTP_DEBUG LWIP_DBG_OFF
#define IP6_DEBUG LWIP_DBG_OFF
#define DHCP6_DEBUG LWIP_DBG_OFF
#define DRV_STS_DEBUG LWIP_DBG_OFF
#endif
// Options only in new opt.h
#define LWIP_SOCKET_SELECT 0
#define LWIP_SOCKET_POLL 1
// Options in old opt.h that differs from new opt.h
#define MEM_ALIGNMENT __SIZEOF_POINTER__
#define MEMP_NUM_NETDB 8
#define IP_REASS_MAXAGE 3
#define IP_SOF_BROADCAST 1
#define IP_SOF_BROADCAST_RECV 1
#define LWIP_MULTICAST_PING 1
#define LWIP_RAW 1
#define LWIP_DHCP_AUTOIP_COOP_TRIES 64
#define TCP_LISTEN_BACKLOG 1
#define TCP_DEFAULT_LISTEN_BACKLOG 16
#define LWIP_WND_SCALE 1
#define TCP_RCV_SCALE 7
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define LWIP_NETCONN_FULLDUPLEX 1 // Caution
#define LWIP_COMPAT_SOCKETS 2
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_TCP_KEEPALIVE 1
#define RECV_BUFSIZE_DEFAULT 65535
#define SO_REUSE_RXTOALL 1
#define LWIP_CHECKSUM_ON_COPY 1
#define LWIP_IPV6 1
#define LWIP_IPV6_NUM_ADDRESSES 5
#define LWIP_ND6_NUM_PREFIXES 10
#define LWIP_IPV6_DHCP6 1
#define LWIP_IPV6_DHCP6_STATEFUL 1
// Options in old lwipopts.h
#define ARP_QUEUEING 1
#define DEFAULT_ACCEPTMBOX_SIZE 32
#define DEFAULT_RAW_RECVMBOX_SIZE 128
#define DEFAULT_TCP_RECVMBOX_SIZE 128
#define DEFAULT_UDP_RECVMBOX_SIZE 128
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
#define ETH_PAD_SIZE 2
#define IP_REASS_MAX_PBUFS (((65535) / (IP_FRAG_MAX_MTU - 20 - 8) + 1) * MEMP_NUM_REASSDATA)
#define LWIP_COMPAT_SOCKETS 2
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF
#define LWIP_DHCP 1
#define LWIP_DNS 1
#define LWIP_ETHERNET 1
#define LWIP_HAVE_LOOPIF 1
#define LWIP_IGMP 1
#define LWIP_NETIF_API 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_POSIX_SOCKETS_IO_NAMES 0
#define LWIP_RAW 1
#define LWIP_SOCKET_OFFSET FAT_MAX_OPEN_FILES
#define LWIP_SO_RCVBUF 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_SNDTIMEO 1
#define LWIP_STATS_DISPLAY 1
#define MEM_LIBC_MALLOC 1
#define MEMP_NUM_ARP_QUEUE (65535 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8))
#define MEMP_NUM_NETBUF (65535 * 3 * LWIP_CONFIG_NUM_SOCKETS / (IP_FRAG_MAX_MTU - 20 - 8))
#define MEMP_NUM_NETCONN LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_PBUF LWIP_CONFIG_NUM_SOCKETS*2
#define MEMP_NUM_RAW_PCB LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_REASSDATA (IP_REASS_MAX_MEM_SIZE / 65535)
#define MEMP_NUM_TCPIP_MSG_API 64
#define MEMP_NUM_TCPIP_MSG_INPKT 512
#define MEMP_NUM_TCP_PCB LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_TCP_PCB_LISTEN LWIP_CONFIG_NUM_SOCKETS
#define MEMP_NUM_TCP_SEG (((TCP_SND_BUF * 3 / 2) + TCP_WND) * LWIP_CONFIG_NUM_SOCKETS / TCP_MSS)
#define MEMP_NUM_UDP_PCB LWIP_CONFIG_NUM_SOCKETS
#define MEM_SIZE (4*1024*1024) // (512*1024)
#define PBUF_POOL_BUFSIZE 1550
#define PBUF_POOL_SIZE 64
#define SO_REUSE 1
#define TCPIP_MBOX_SIZE 512
#define TCPIP_THREAD_PRIO 5
#define TCPIP_THREAD_STACKSIZE 0x6000
#define TCP_MAXRTX 64
#define TCP_MSS 1400
#define TCP_SND_BUF 65535
#define TCP_SND_QUEUELEN (8 * TCP_SND_BUF) / TCP_MSS
#define TCP_TTL 255
#define TCP_WND 32768
#define UDP_TTL 255
// Options in old lwipopts.h but kept in Defaults with new opt.h
#define IP_FORWARD 0
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_ICMP 1
#define LWIP_NETCONN 1
#define LWIP_SOCKET 1
#define LWIP_STATS 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define NO_SYS 0
#define TCP_QUEUE_OOSEQ LWIP_TCP
// Change some options for lwIP 2.1.2
#undef TCP_MAXRTX
#define TCP_MAXRTX 12
#undef LWIP_COMPAT_SOCKETS
#define LWIP_COMPAT_SOCKETS 0
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + (LWIP_IPV6 * LWIP_IPV6_DHCP6))
#undef DEFAULT_ACCEPTMBOX_SIZE
#define DEFAULT_ACCEPTMBOX_SIZE LWIP_CONFIG_NUM_SOCKETS
#undef TCP_MSS
#define TCP_MSS (IP_FRAG_MAX_MTU - 20 - 20)
#undef IP_SOF_BROADCAST_RECV
#define IP_SOF_BROADCAST_RECV 0
/**
* Defines whether to enable debugging for driver module.
*/
#ifndef DRIVERIF_DEBUG
#define DRIVERIF_DEBUG LWIP_DBG_OFF
#endif
// Options for old lwipopts.h
#define IP_FRAG_MAX_MTU 1500
#define LWIP_CONFIG_NUM_SOCKETS 128
#define IP_REASS_MAX_MEM_SIZE (MEM_SIZE / 4)
// Options for enhancement code, same for old lwipopts.h
#define LWIP_NETIF_PROMISC 1
#define LWIP_TFTP LOSCFG_NET_LWIP_SACK_TFTP
#define LWIP_DHCPS 1
#define LWIP_ENABLE_NET_CAPABILITY 1
#define LWIP_ENABLE_CAP_NET_BROADCAST 0
// Options for GT
#undef LWIP_NETIF_PROMISC
#define LWIP_NETIF_PROMISC 0
#undef LWIP_ICMP
#define LWIP_ICMP 0
#undef LWIP_DHCP
#define LWIP_DHCP 0
#undef LWIP_IGMP
#define LWIP_IGMP 0
#undef LWIP_IPV6
#define LWIP_IPV6 0
#undef LWIP_IPV6_DHCP6
#define LWIP_IPV6_DHCP6 0
#undef TCP_SND_BUF
#define TCP_SND_BUF (65535 / 3)
#undef TCP_WND
#define TCP_WND ((TCP_SND_BUF * 2) / 3)
#undef TCP_SND_QUEUELEN
#define TCP_SND_QUEUELEN (2 * (TCP_SND_BUF / TCP_MSS))
#undef MEMP_NUM_NETDB
#define MEMP_NUM_NETDB 1
#undef MEMP_NUM_ARP_QUEUE
#define MEMP_NUM_ARP_QUEUE 4
#undef MEMP_NUM_NETBUF
#define MEMP_NUM_NETBUF 12
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 32
#undef MEMP_NUM_PBUF
#define MEMP_NUM_PBUF 0
#undef PBUF_POOL_SIZE
#define PBUF_POOL_SIZE 0
#undef MEMP_NUM_RAW_PCB
#define MEMP_NUM_RAW_PCB 8
#undef MEMP_NUM_REASSDATA
#define MEMP_NUM_REASSDATA 12
#undef MEMP_NUM_TCPIP_MSG_API
#define MEMP_NUM_TCPIP_MSG_API 32
#undef MEMP_NUM_TCPIP_MSG_INPKT
#define MEMP_NUM_TCPIP_MSG_INPKT 32
#undef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB 8
#undef MEMP_NUM_TCP_PCB_LISTEN
#define MEMP_NUM_TCP_PCB_LISTEN 4
#undef MEMP_NUM_TCP_SEG
#define MEMP_NUM_TCP_SEG 64
#undef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB 4
#undef TCPIP_THREAD_STACKSIZE
#define TCPIP_THREAD_STACKSIZE 0x1000
#undef LWIP_SOCKET_SELECT
#define LWIP_SOCKET_SELECT 1
// use PBUF_RAM instead of PBUF_POOL in udp_input
#define USE_PBUF_RAM_UDP_INPUT 1
#endif /* _LWIP_PORTING_LWIPOPTS_H_ */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_NETDB_H_
#define _LWIP_PORTING_NETDB_H_
#include <netdb.h>
#include_next <lwip/netdb.h>
#endif /* _LWIP_PORTING_NETDB_H_ */
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_NETIF_H_
#define _LWIP_PORTING_NETIF_H_
#include <net/if.h>
#include <netinet/ip.h>
#define netif_find netifapi_netif_find_by_name
#if LWIP_DHCPS
#define LWIP_NETIF_CLIENT_DATA_INDEX_DHCP LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, \
LWIP_NETIF_CLIENT_DATA_INDEX_DHCPS
#endif
#define linkoutput linkoutput; \
void (*drv_send)(struct netif *netif, struct pbuf *p); \
u8_t (*drv_set_hwaddr)(struct netif *netif, u8_t *addr, u8_t len); \
void (*drv_config)(struct netif *netif, u32_t config_flags, u8_t setBit); \
char full_name[IFNAMSIZ]; \
u16_t link_layer_type
#include_next <lwip/netif.h>
#undef linkoutput
#if LWIP_DHCPS
#undef LWIP_NETIF_CLIENT_DATA_INDEX_DHCP
#endif
#include <lwip/etharp.h>
#ifdef __cplusplus
extern "C" {
#endif
// redefine NETIF_NAMESIZE which was defined in netif.h
#undef NETIF_NAMESIZE
#define NETIF_NAMESIZE IFNAMSIZ
#define LOOPBACK_IF 0
#define ETHERNET_DRIVER_IF 1
#define WIFI_DRIVER_IF 801
#define BT_PROXY_IF 802
err_t driverif_init(struct netif *netif);
void driverif_input(struct netif *netif, struct pbuf *p);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_NETIF_H_ */
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_NETIFAPI_H_
#define _LWIP_PORTING_NETIFAPI_H_
#include_next <lwip/netifapi.h>
#ifdef __cplusplus
extern "C" {
#endif
err_t netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num);
err_t netifapi_dhcps_stop(struct netif *netif);
#define netifapi_dhcp_cleanup(n) netifapi_netif_common(n, dhcp_cleanup, NULL)
#define netifapi_dhcp_is_bound(n) netifapi_netif_common(n, NULL, dhcp_is_bound)
void netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr);
struct netif *netifapi_netif_find_by_name(const char *name);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_NETIFAPI_H_ */
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LWIP_PORTING_SOCKETS_H_
#define _LWIP_PORTING_SOCKETS_H_
#include <sys/socket.h>
#include <poll.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <limits.h>
#include <fcntl.h>
#include_next <lwip/sockets.h>
#include <fatfs.h>
#ifdef __cplusplus
extern "C" {
#endif
#if FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
#error "external FD_SETSIZE too small for number of sockets"
#else
#define LWIP_SELECT_MAXNFDS FD_SETSIZE
#endif
#if IOV_MAX > 0xFFFF
#error "IOV_MAX larger than supported by LwIP"
#endif
#if LWIP_UDP && LWIP_UDPLITE
#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
#endif
// For BSD 4.4 socket sa_len compatibility
#define DF_NADDR(addr)
#define SA_LEN(addr, _) (IP_IS_V4_VAL(addr) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
#define sa_len sa_data[0] * 0 + SA_LEN(naddr, _)
#define sin_len sin_zero[0]
#define sin6_len sin6_addr.s6_addr[0]
// for sockets.c, TCP_KEEPALIVE is not supported currently
#define TCP_KEEPALIVE 0xFF
#define SIN_ZERO_LEN 8
int closesocket(int sockfd);
int ioctlsocket(int s, long cmd, void *argp);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_PORTING_SOCKETS_H_ */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LITEOS_M_LWIPOPTS_H__
#define __LITEOS_M_LWIPOPTS_H__
// Just redirect
#include "lwip/lwipopts.h"
#endif // __LITEOS_M_LWIPOPTS_H__
@@ -0,0 +1,357 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <lwip/sys.h>
#include <lwip/netif.h>
#include <lwip/snmp.h>
#include <lwip/etharp.h>
#include <lwip/sockets.h>
#include <lwip/snmp.h>
#include <lwip/etharp.h>
#include <lwip/ethip6.h>
#define LWIP_NETIF_HOSTNAME_DEFAULT "default"
#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 100000000 // 100Mbps
#define link_rx_drop cachehit
#define link_rx_overrun cachehit
#define LWIP_STATIC static
#define NETIF_NAME_PREFIX_MAX_LENGTH 10
#define NETIF_NAME_PREFIX_ETH "eth"
#define NETIF_NAME_PREFIX_WIFI "wlan"
#define NETIF_NAME_PREFIX_BT "bt"
#ifndef LWIP_NETIF_IFINDEX_MAX_EX
#define LWIP_NETIF_IFINDEX_MAX_EX 255
#endif
LWIP_STATIC void driverif_get_ifname_prefix(struct netif *netif, char *prefix, int prefixLen)
{
if (prefix == NULL || netif == NULL) {
LWIP_ASSERT("invalid param", 0);
return;
}
switch (netif->link_layer_type) {
case ETHERNET_DRIVER_IF:
strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_ETH);
break;
case WIFI_DRIVER_IF:
strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_WIFI);
break;
case BT_PROXY_IF:
strcpy_s(prefix, prefixLen, NETIF_NAME_PREFIX_BT);
break;
default:
LWIP_ASSERT("invalid link_layer_type", 0);
break;
}
}
LWIP_STATIC void driverif_init_ifname(struct netif *netif)
{
struct netif *tmpnetif = NULL;
char prefix[NETIF_NAME_PREFIX_MAX_LENGTH] = {0};
driverif_get_ifname_prefix(netif, prefix, NETIF_NAME_PREFIX_MAX_LENGTH);
netif->name[0] = prefix[0];
netif->name[1] = prefix[1];
if (netif->full_name[0] != '\0') {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("netif already has fullname %s\n", netif->full_name));
return;
}
for (int i = 0; i < LWIP_NETIF_IFINDEX_MAX_EX; ++i) {
if (snprintf_s(netif->full_name, sizeof(netif->full_name), sizeof(netif->full_name) - 1,
"%s%d", prefix, i) < 0) {
break;
}
NETIF_FOREACH(tmpnetif) {
if (strcmp(tmpnetif->full_name, netif->full_name) == 0) {
break;
}
}
if (tmpnetif == NULL) {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("set fullname success %s\n", netif->full_name));
return;
}
}
netif->full_name[0] = '\0';
}
/*
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this driverif
* @param p the MAC packet to send (e.g. IP packet including MAC_addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
LWIP_STATIC err_t driverif_output(struct netif *netif, struct pbuf *p)
{
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_output : send packet pbuf 0x%p of length %"U16_F" through netif 0x%p\n", \
(void *)p, p->tot_len, (void *)netif));
#if PF_PKT_SUPPORT
if (all_pkt_raw_pcbs != NULL) {
p->flags = (u16_t)(p->flags & ~(PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST | PBUF_FLAG_HOST));
p->flags |= PBUF_FLAG_OUTGOING;
(void)raw_pkt_input(p, netif, NULL);
}
#endif
#if ETH_PAD_SIZE
(void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
netif->drv_send(netif, p);
#if ETH_PAD_SIZE
(void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
void driverif_input_proc(struct netif *netif, struct pbuf *p)
{
u16_t ethhdr_type;
struct eth_hdr *ethhdr = NULL;
err_t ret = ERR_VAL;
ethhdr = (struct eth_hdr *)p->payload;
ethhdr_type = ntohs(ethhdr->type);
switch (ethhdr_type) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_IPV6:
case ETHTYPE_ARP:
#if ETHARP_SUPPORT_VLAN
case ETHTYPE_VLAN:
#endif /* ETHARP_SUPPORT_VLAN */
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F"\n", ethhdr_type));
/* full packet send to tcpip_thread to process */
if (netif->input != NULL) {
ret = netif->input(p, netif);
}
if (ret != ERR_OK) {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
if (ret == ERR_MEM) {
MIB2_STATS_NETIF_INC(netif, ifinoverruns);
LINK_STATS_INC(link.link_rx_overrun);
}
} else {
LINK_STATS_INC(link.recv);
}
break;
default:
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is of unsupported type %"U16_F"\n", \
ethhdr_type));
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
break;
}
}
/*
* This function should be called by network driver to pass the input packet to LwIP.
* Before calling this API, driver has to keep the packet in pbuf structure. Driver has to
* call pbuf_alloc() with type as PBUF_RAM to create pbuf structure. Then driver
* has to pass the pbuf structure to this API. This will add the pbuf into the TCPIP thread.
* Once this packet is processed by TCPIP thread, pbuf will be freed. Driver is not required to
* free the pbuf.
*
* @param netif the lwip network interface structure for this driverif
* @param p packet in pbuf structure format
*/
void driverif_input(struct netif *netif, struct pbuf *p)
{
#if PF_PKT_SUPPORT
#if (DRIVERIF_DEBUG & LWIP_DBG_OFF)
u16_t ethhdr_type;
struct eth_hdr* ethhdr = NULL;
#endif
err_t ret = ERR_VAL;
#endif
LWIP_ERROR("driverif_input : invalid arguments", ((netif != NULL) && (p != NULL)), return);
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : going to receive input packet. netif 0x%p, pbuf 0x%p, \
packet_length %"U16_F"\n", (void *)netif, (void *)p, p->tot_len));
/* points to packet payload, which starts with an Ethernet header */
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
if (p->len < SIZEOF_ETH_HDR) {
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
return;
}
#if PF_PKT_SUPPORT
#if (DRIVERIF_DEBUG & LWIP_DBG_OFF)
ethhdr = (struct eth_hdr *)p->payload;
ethhdr_type = ntohs(ethhdr->type);
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet of type %"U16_F" netif->input=%p\n", \
ethhdr_type, netif->input));
#endif
/* full packet send to tcpip_thread to process */
if (netif->input) {
ret = netif->input(p, netif);
}
if (ret != ERR_OK) {
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input: IP input error\n"));
(void)pbuf_free(p);
LINK_STATS_INC(link.drop);
LINK_STATS_INC(link.link_rx_drop);
if (ret == ERR_MEM) {
LINK_STATS_INC(link.link_rx_overrun);
}
} else {
LINK_STATS_INC(link.recv);
}
#else
driverif_input_proc(netif, p);
#endif
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_input : received packet is processed\n"));
}
/*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this driverif
* @return ERR_OK if the loopif is initialized
* ERR_MEM on Allocation Failure
* any other err_t on error
*/
err_t driverif_init(struct netif *netif)
{
u16_t link_layer_type;
if (netif == NULL) {
return ERR_IF;
}
link_layer_type = netif->link_layer_type;
LWIP_ERROR("driverif_init : invalid link_layer_type in netif", \
((link_layer_type == ETHERNET_DRIVER_IF) \
|| (link_layer_type == WIFI_DRIVER_IF \
|| link_layer_type == BT_PROXY_IF)), \
return ERR_IF);
LWIP_ERROR("driverif_init : netif hardware length is greater than maximum supported", \
(netif->hwaddr_len <= NETIF_MAX_HWADDR_LEN), return ERR_IF);
LWIP_ERROR("driverif_init : drv_send is null", (netif->drv_send != NULL), return ERR_IF);
#if LWIP_NETIF_PROMISC
LWIP_ERROR("driverif_init : drv_config is null", (netif->drv_config != NULL), return ERR_IF);
#endif
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = LWIP_NETIF_HOSTNAME_DEFAULT;
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->output = etharp_output;
netif->linkoutput = driverif_output;
/* init the netif's full name */
driverif_init_ifname(netif);
/* maximum transfer unit */
netif->mtu = IP_FRAG_MAX_MTU;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
#if DRIVER_STATUS_CHECK
NETIF_FLAG_DRIVER_RDY |
#endif
#if LWIP_IGMP
NETIF_FLAG_IGMP |
#endif
/**
@page RFC-2710 RFC-2710
@par Compliant Sections
Section 5. Node State Transition Diagram
@par Behavior Description
MLD messages are sent for multicast addresses whose scope is 2
(link-local), including Solicited-Node multicast addresses.\n
Behavior:Stack will send MLD6 report /Done to solicited node multicast address
if the LWIP_MLD6_ENABLE_MLD_ON_DAD is enabled. By default, this is disabled.
*/
/* Enable sending MLD report /done for solicited address during neighbour discovery */
#if LWIP_IPV6 && LWIP_IPV6_MLD
#if LWIP_MLD6_ENABLE_MLD_ON_DAD
NETIF_FLAG_MLD6 |
#endif /* LWIP_MLD6_ENABLE_MLD_ON_DAD */
#endif
NETIF_FLAG_LINK_UP;
#if DRIVER_STATUS_CHECK
netif->waketime = -1;
#endif /* DRIVER_STATUS_CHECK */
LWIP_DEBUGF(DRIVERIF_DEBUG, ("driverif_init : Initialized netif 0x%p\n", (void *)netif));
return ERR_OK;
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include "lwip/tcpip.h"
#include "ohos_init.h"
void TcpIpPortingInit()
{
tcpip_init(NULL, NULL);
}
SYSEX_SERVICE_INIT(TcpIpPortingInit);
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip/netdb.h"
#if LWIP_DNS && LWIP_SOCKET
struct hostent *gethostbyname(const char *name)
{
if (name == NULL) {
return NULL;
}
return lwip_gethostbyname(name);
}
int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result,
int *h_errnop)
{
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
}
void freeaddrinfo(struct addrinfo *res)
{
lwip_freeaddrinfo(res);
}
int getaddrinfo(const char *restrict nodename, const char *restrict servname, const struct addrinfo *restrict hints,
struct addrinfo **restrict res)
{
return lwip_getaddrinfo(nodename, servname, hints, res);
}
#endif
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip/priv/sockets_priv.h"
#include <lwip/sockets.h>
#if !LWIP_COMPAT_SOCKETS
#if LWIP_SOCKET
#define CHECK_NULL_PTR(ptr) do { if ((ptr) == NULL) { set_errno(EFAULT); return -1; } } while (0)
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
return lwip_accept(s, addr, addrlen);
}
int bind(int s, const struct sockaddr *name, socklen_t namelen)
{
CHECK_NULL_PTR(name);
if (namelen < sizeof(*name)) {
set_errno(EINVAL);
return -1;
}
return lwip_bind(s, name, namelen);
}
int shutdown(int s, int how)
{
return lwip_shutdown(s, how);
}
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
{
CHECK_NULL_PTR(name);
CHECK_NULL_PTR(namelen);
return lwip_getpeername(s, name, namelen);
}
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
{
CHECK_NULL_PTR(name);
CHECK_NULL_PTR(namelen);
return lwip_getsockname(s, name, namelen);
}
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
{
return lwip_getsockopt(s, level, optname, optval, optlen);
}
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
{
return lwip_setsockopt(s, level, optname, optval, optlen);
}
int closesocket(int s)
{
return lwip_close(s);
}
int connect(int s, const struct sockaddr *name, socklen_t namelen)
{
CHECK_NULL_PTR(name);
if (namelen < sizeof(*name)) {
set_errno(EINVAL);
return -1;
}
return lwip_connect(s, name, namelen);
}
int listen(int s, int backlog)
{
return lwip_listen(s, backlog);
}
ssize_t recv(int s, void *mem, size_t len, int flags)
{
CHECK_NULL_PTR(mem);
return lwip_recv(s, mem, len, flags);
}
ssize_t recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
CHECK_NULL_PTR(mem);
return lwip_recvfrom(s, mem, len, flags, from, fromlen);
}
ssize_t recvmsg(int s, struct msghdr *message, int flags)
{
CHECK_NULL_PTR(message);
if (message->msg_iovlen) {
CHECK_NULL_PTR(message->msg_iov);
}
return lwip_recvmsg(s, message, flags);
}
ssize_t send(int s, const void *dataptr, size_t size, int flags)
{
CHECK_NULL_PTR(dataptr);
return lwip_send(s, dataptr, size, flags);
}
ssize_t sendmsg(int s, const struct msghdr *message, int flags)
{
return lwip_sendmsg(s, message, flags);
}
ssize_t sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen)
{
CHECK_NULL_PTR(dataptr);
if (to && tolen < sizeof(*to)) {
set_errno(EINVAL);
return -1;
}
return lwip_sendto(s, dataptr, size, flags, to, tolen);
}
int socket(int domain, int type, int protocol)
{
return lwip_socket(domain, type, protocol);
}
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
return lwip_inet_ntop(af, src, dst, size);
}
int inet_pton(int af, const char *src, void *dst)
{
return lwip_inet_pton(af, src, dst);
}
int ioctlsocket(int s, long cmd, void *argp)
{
return lwip_ioctl(s, cmd, argp);
}
#if LWIP_SOCKET_SELECT
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout)
{
return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
}
#endif
#if LWIP_SOCKET_POLL
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
return lwip_poll(fds, nfds, timeout);
}
#endif
unsigned int if_nametoindex(const char *ifname)
{
return lwip_if_nametoindex(ifname);
}
#endif
#endif /* !LWIP_COMPAT_SOCKETS */
@@ -0,0 +1,344 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#include <lwip/debug.h>
#include <los_task.h>
#include <los_tick.h>
#include <los_queue.h>
#include <los_sem.h>
#include <los_mux.h>
#include "cmsis_os2.h"
#include <los_tick.h>
#include <los_config.h>
#ifndef LOSCFG_KERNEL_SMP
#define LOSCFG_KERNEL_SMP 0
#endif
#if (LOSCFG_KERNEL_SMP)
SPIN_LOCK_INIT(arch_protect_spin);
static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
static int lwprot_count = 0;
#endif /* LOSCFG_KERNEL_SMP */
#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div))
#define LWIP_LOG_BUF_SIZE 64
/**
* Thread and System misc
*/
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio)
{
UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID;
UINT32 ret;
TSK_INIT_PARAM_S task = {0};
/* Create host Task */
task.pfnTaskEntry = (TSK_ENTRY_FUNC)thread;
task.uwStackSize = stackSize;
task.pcName = (char *)name;
task.usTaskPrio = prio;
task.uwArg = (UINTPTR)arg;
task.uwResved = LOS_TASK_STATUS_DETACHED;
ret = LOS_TaskCreate(&taskID, &task);
if (ret != LOS_OK) {
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret));
return -1;
}
return taskID;
}
void sys_init(void)
{
/* set rand seed to make random sequence diff on every startup */
UINT32 seedlsb = (UINT32)LOS_SysCycleGet();
srand(seedlsb);
}
u32_t sys_now(void)
{
/* Lwip docs mentioned like wraparound is not a problem in this funtion */
return (u32_t)osKernelGetTickCount();
}
/**
* Protector
*/
sys_prot_t sys_arch_protect(void)
{
#if (LOSCFG_KERNEL_SMP)
/* Note that we are using spinlock instead of mutex for LiteOS-SMP here:
* 1. spinlock is more effective for short critical region protection.
* 2. this function is called only in task context, not in interrupt handler.
* so it's not needed to disable interrupt.
*/
if (lwprot_thread != LOS_CurTaskIDGet()) {
/* We are locking the spinlock where it has not been locked before
* or is being locked by another thread */
LOS_SpinLock(&arch_protect_spin);
lwprot_thread = LOS_CurTaskIDGet();
lwprot_count = 1;
} else {
/* It is already locked by THIS thread */
lwprot_count++;
}
#else
LOS_TaskLock();
#endif /* LOSCFG_KERNEL_SMP */
return 0; /* return value is unused */
}
void sys_arch_unprotect(sys_prot_t pval)
{
LWIP_UNUSED_ARG(pval);
#if (LOSCFG_KERNEL_SMP)
if (lwprot_thread == LOS_CurTaskIDGet()) {
lwprot_count--;
if (lwprot_count == 0) {
lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
LOS_SpinUnlock(&arch_protect_spin);
}
}
#else
LOS_TaskUnlock();
#endif /* LOSCFG_KERNEL_SMP */
}
/**
* MessageBox
*/
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
{
CHAR qName[] = "lwIP";
UINT32 ret = LOS_QueueCreate(qName, (UINT16)size, mbox, 0, sizeof(void *));
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_CB_UNAVAILABLE:
case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY:
return ERR_MEM;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueCreate error %u\n", __FUNCTION__, ret));
return ERR_ARG;
}
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
/* Caution: the second parameter is NOT &msg */
UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), LOS_WAIT_FOREVER);
if (ret != LOS_OK) {
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret));
}
}
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
/* Caution: the second parameter is NOT &msg */
UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), 0);
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_ISFULL:
return ERR_MEM;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret));
return ERR_ARG;
}
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
{
return ERR_ARG;
}
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
{
void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), tick ? (UINT32)tick : LOS_WAIT_FOREVER);
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_ISEMPTY:
case LOS_ERRNO_QUEUE_TIMEOUT:
return SYS_ARCH_TIMEOUT;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret));
return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
}
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), 0);
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_QUEUE_ISEMPTY:
return SYS_MBOX_EMPTY;
case LOS_ERRNO_QUEUE_TIMEOUT:
return SYS_ARCH_TIMEOUT;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret));
return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */
}
void sys_mbox_free(sys_mbox_t *mbox)
{
(void)LOS_QueueDelete(*mbox);
}
int sys_mbox_valid(sys_mbox_t *mbox)
{
QUEUE_INFO_S queueInfo;
return LOS_OK == LOS_QueueInfoGet(*mbox, &queueInfo);
}
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
*mbox = LOSCFG_BASE_IPC_QUEUE_LIMIT;
}
/**
* Semaphore
*/
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
{
UINT32 ret = LOS_SemCreate(count, sem);
if (ret != LOS_OK) {
return ERR_ARG;
}
return ERR_OK;
}
void sys_sem_signal(sys_sem_t *sem)
{
(void)LOS_SemPost(*sem);
}
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs)
{
UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
UINT32 ret = LOS_SemPend(*sem, tick ? (UINT32)tick : LOS_WAIT_FOREVER); // timeoutMs 0 means wait forever
switch (ret) {
case LOS_OK:
return ERR_OK;
case LOS_ERRNO_SEM_TIMEOUT:
return SYS_ARCH_TIMEOUT;
default:
break;
}
LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_SemPend error %u\n", __FUNCTION__, ret));
return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
}
void sys_sem_free(sys_sem_t *sem)
{
(void)LOS_SemDelete(*sem);
}
int sys_sem_valid(sys_sem_t *sem)
{
return *sem != LOSCFG_BASE_IPC_SEM_LIMIT;
}
void sys_sem_set_invalid(sys_sem_t *sem)
{
*sem = LOSCFG_BASE_IPC_SEM_LIMIT;
}
/**
* Mutex
*/
err_t sys_mutex_new(sys_mutex_t *mutex)
{
UINT32 ret = LOS_MuxCreate(mutex);
if (ret != LOS_OK) {
return ERR_ARG;
}
return ERR_OK;
}
void sys_mutex_lock(sys_mutex_t *mutex)
{
(void)LOS_MuxPend(*mutex, LOS_WAIT_FOREVER);
}
void sys_mutex_unlock(sys_mutex_t *mutex)
{
(void)LOS_MuxPost(*mutex);
}
void sys_mutex_free(sys_mutex_t *mutex)
{
(void)LOS_MuxDelete(*mutex);
}
int sys_mutex_valid(sys_mutex_t *mutex)
{
return *mutex != LOSCFG_BASE_IPC_MUX_LIMIT;
}
void sys_mutex_set_invalid(sys_mutex_t *mutex)
{
*mutex = LOSCFG_BASE_IPC_MUX_LIMIT;
}
void HilogPrintf(const char *fmt, ...)
{
if ((fmt == NULL) || (strlen(fmt) == 0)) {
return;
}
int len;
char buf[LWIP_LOG_BUF_SIZE] = {0};
va_list ap;
va_start(ap, fmt);
len = vsprintf_s(buf, sizeof(buf) - 1, fmt, ap);
va_end(ap);
if (len < 0) {
HILOG_INFO(HILOG_MODULE_APP, "log param invalid or buf is not enough.");
return;
}
HILOG_INFO(HILOG_MODULE_APP, buf);
}
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LWIP_TEST_H
#define LWIP_TEST_H
#include "lwip/arch.h"
#include "lwip/sockets.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include "securec.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int g_testCase;
extern int g_testError;
extern int g_testTemp;
#define LWIP_TEST_RET_OK 0
#define LWIP_TEST_RET_ERR 1
#define LOCALHOST "127.0.0.1"
#define STACK_IP LOCALHOST
#define STACK_PORT 2277
#define PEER_PORT STACK_PORT
#define SERVER_PORT STACK_PORT
#define CLIENT_PORT 2288
#define PEER_IP LOCALHOST
#define BUF_SIZE (128 * 1)
#define IOV_LENGTH 2
#define STACK_TEST_SIZE (0x800UL)
#define ICUNIT_ASSERT_NOT_EQUAL(a, b, c) if ((a) == (b)) { \
g_testError = (c); \
LWIP_ASSERT("lwip test", 0); \
}
#define ICUNIT_ASSERT_EQUAL(a, b, c) if ((a) != (b)) { \
g_testError = (c); \
LWIP_ASSERT("lwip test", 0); \
}
#define LogPrintln(fmt, ...) \
HILOG_INFO(HILOG_MODULE_APP, fmt "%c", \
##__VA_ARGS__, \
('\n' == " "fmt[sizeof(" "fmt)-2]) ? '\0' : '\n') // trailing newline is auto appended
#ifdef __cplusplus
}
#endif
#endif /* LWIP_TEST_H */
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#define TEST_CASE 110
int SocketTest(void)
{
LogPrintln("net_socket_test_001.c enter");
g_testCase = TEST_CASE;
int fd = socket(0, 0, 0);
LWIP_ASSERT("socket invalid param.", fd == -1);
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define MSG "Hi, I am UDP"
#define TEST_CASE 120
static char g_buf[BUF_SIZE + 1] = { 0 };
void UdpTestTask(void *p)
{
(void)p;
LogPrintln("net_socket_test_002.c enter");
g_testCase = TEST_CASE;
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
struct msghdr msg = { 0 };
struct iovec iov[IOV_LENGTH] = { 0 };
int recvCount = 0;
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
LWIP_ASSERT("socket invalid param.", sfd != -1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LWIP_ASSERT("socket invalid param.", ret == 0);
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), MSG);
ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr,
(socklen_t)sizeof(clnAddr));
LWIP_ASSERT("socket invalid param.", ret != -1);
ret = ioctlsocket(sfd, FIONREAD, &recvCount);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
LogPrintln("udp recv count %d", recvCount);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
LWIP_ASSERT("socket invalid param.", ret == strlen(MSG));
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), MSG);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = IOV_LENGTH;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(MSG);
ret = sendmsg(sfd, &msg, 0);
LWIP_ASSERT("socket invalid param.", ret == IOV_LENGTH * strlen(MSG));
/* recvmsg */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
LWIP_ASSERT("socket invalid param.", ret == IOV_LENGTH * strlen(MSG));
/* close socket */
ret = closesocket(sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
return;
}
int UdpTest()
{
int ret = sys_thread_new("udp_test", UdpTestTask, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return ret;
}
@@ -0,0 +1,251 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 130
static char g_buf[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct msghdr msg = { 0 };
struct iovec iov[IOV_LENGTH] = { 0 };
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG);
ret = send(sfd, g_buf, strlen(SRV_MSG), 0);
LogPrintln("server send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 5);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("server recv on socket %d: %d", sfd, ret);
LogPrintln("ser:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 6);
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = IOV_LENGTH;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(SRV_MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(SRV_MSG);
ret = sendmsg(sfd, &msg, 0);
LogPrintln("sendmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(SRV_MSG), 7);
/* recvmsg */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
LogPrintln("recvmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(CLI_MSG), 8);
ret = shutdown(sfd, SHUT_RDWR);
LogPrintln("shutdown socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 9);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 11);
return 0;
}
static int SampleTcpClient()
{
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
int ret;
struct msghdr msg = { 0 };
struct iovec iov[IOV_LENGTH] = { 0 };
struct sockaddr addr;
socklen_t addrLen = sizeof(addr);
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(PEER_PORT);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* test getpeername */
ret = getpeername(sfd, &addr, &addrLen);
LogPrintln("getpeername %d %s:%d: %d", \
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 12);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 13);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(PEER_IP), 14);
/* test getsockname */
ret = getsockname(sfd, &addr, &addrLen);
LogPrintln("getsockname %d %s:%d: %d", \
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 15);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 16);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(STACK_IP), 17);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG);
ret = send(sfd, g_buf, strlen(CLI_MSG), 0);
LogPrintln("client send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 18);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("client recv on socket %d: %d", sfd, ret);
LogPrintln("cli:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 19);
/* sendmsg */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG);
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = IOV_LENGTH;
iov[0].iov_base = g_buf;
iov[0].iov_len = strlen(CLI_MSG);
iov[1].iov_base = g_buf;
iov[1].iov_len = strlen(CLI_MSG);
ret = sendmsg(sfd, &msg, 0);
LogPrintln("sendmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 2 * strlen(CLI_MSG), 20);
/* recvmsg */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
msg.msg_name = &clnAddr;
msg.msg_namelen = sizeof(clnAddr);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
iov[0].iov_base = g_buf;
iov[0].iov_len = sizeof(g_buf);
ret = recvmsg(sfd, &msg, 0);
LogPrintln("recvmsg on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, IOV_LENGTH * strlen(SRV_MSG), 21);
ret = shutdown(sfd, SHUT_RDWR);
LogPrintln("shutdown socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 22);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTest()
{
LogPrintln("net_socket_test_003.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#define TEST_CASE 140
#define OPT_TIMEOUT 1000
int SockOptTest()
{
LogPrintln("net_socket_test_004.c enter");
g_testCase = TEST_CASE;
int ret, error, flag;
struct timeval timeout;
socklen_t len;
int fd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(fd, -1, 1);
error = -1;
len = sizeof(error);
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", \
fd, ret, error, len, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ICUNIT_ASSERT_EQUAL(error, 0, 3);
len = sizeof(timeout);
ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, 4);
timeout.tv_sec = OPT_TIMEOUT;
len = sizeof(timeout);
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, len);
ICUNIT_ASSERT_EQUAL(ret, 0, 5);
(void)memset_s(&timeout, len, 0, len);
ret = getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, &len);
ICUNIT_ASSERT_EQUAL(ret, 0, 6);
ICUNIT_ASSERT_EQUAL(timeout.tv_sec, OPT_TIMEOUT, 7);
error = -1;
len = sizeof(error);
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
LogPrintln("getsockopt(%d, SOL_SOCKET, SO_ERROR, &error, &len)=%d, error=%d, len=%d, errno=%d", \
fd, ret, error, len, errno);
ICUNIT_ASSERT_EQUAL(ret, 0, 8);
ICUNIT_ASSERT_EQUAL(error, 0, 9);
flag = 1;
ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
LogPrintln("setsockopt(TCP_NODELAY) ret=%d", ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 10);
ret = closesocket(fd);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#define TEST_CASE 150
int ByteOrderTest(void)
{
LogPrintln("net_socket_test_005.c enter");
#if BYTE_ORDER == LITTLE_ENDIAN
g_testCase = TEST_CASE + 1;
uint32_t hl = ntohl(0x12345678);
ICUNIT_ASSERT_EQUAL(hl, 0x78563412, 1);
uint32_t nl = htonl(0x12345678);
ICUNIT_ASSERT_EQUAL(nl, 0x78563412, 2);
uint16_t hs = ntohs(0x1234);
ICUNIT_ASSERT_EQUAL(hs, 0x3412, 3);
uint16_t ns = htons(0x1234);
ICUNIT_ASSERT_EQUAL(ns, 0x3412, 4);
#else
g_testCase = TEST_CASE;
uint32_t hl = ntohl(0x12345678);
ICUNIT_ASSERT_EQUAL(hl, 0x12345678, 5);
uint32_t nl = htonl(0x12345678);
ICUNIT_ASSERT_EQUAL(nl, 0x12345678, 6);
uint16_t hs = ntohs(0x1234);
ICUNIT_ASSERT_EQUAL(hs, 0x1234, 7);
uint16_t ns = htons(0x1234);
ICUNIT_ASSERT_EQUAL(ns, 0x1234, 8);
#endif
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#define TEST_CASE 160
#define TEMP_BUF_SIZE 32
int InetTest()
{
LogPrintln("net_socket_test_006.c enter");
g_testCase = TEST_CASE;
struct in_addr in;
int ret = inet_pton(AF_INET, "300.10.10.10", &in);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
ret = inet_pton(AF_INET, "10.11.12.13", &in);
ICUNIT_ASSERT_EQUAL(ret, 1, 2);
#if BYTE_ORDER == LITTLE_ENDIAN
g_testCase++;
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0d0c0b0a, 3);
#else
ICUNIT_ASSERT_EQUAL(in.s_addr, 0x0a0b0c0d, 4);
#endif
const char *p = inet_ntoa(in);
ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, 5);
char buf[TEMP_BUF_SIZE];
p = inet_ntop(AF_INET, &in, buf, sizeof(buf));
ICUNIT_ASSERT_EQUAL(p, buf, 6);
ICUNIT_ASSERT_EQUAL(strcmp(p, "10.11.12.13"), 0, 7);
return LWIP_TEST_RET_OK;
}
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
static char g_buf[BUF_SIZE + 1] = { 0 };
static char g_buf_temp[BUF_SIZE + 1] = { 0 };
#define SEND_UDP_COUNT 10000 // send count
#define TEST_CASE 170
static void UdpTestMoreTask(void *p)
{
(void)p;
LogPrintln("net_socket_test_007.c enter");
if (g_testCase < TEST_CASE) {
g_testCase = TEST_CASE;
} else {
g_testCase++;
}
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
int i;
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
LWIP_ASSERT("socket invalid param.", sfd != -1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LWIP_ASSERT("socket invalid param.", ret == 0);
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP);
clnAddr.sin_port = htons(PEER_PORT);
if (g_buf_temp[0] == '\0') {
for (i = 0; i < BUF_SIZE; i++) {
g_buf_temp[i] = 'U';
}
g_buf_temp[BUF_SIZE] = '\0';
}
LogPrintln("udp begin send");
for (i = 0; i < SEND_UDP_COUNT; i++) {
ret = memcpy_s(g_buf, sizeof(g_buf), g_buf_temp, sizeof(g_buf_temp));
ICUNIT_ASSERT_EQUAL(ret, EOK, 1);
ret = sendto(sfd, g_buf, BUF_SIZE, 0, (struct sockaddr*)&clnAddr, (socklen_t)sizeof(clnAddr));
LWIP_ASSERT("socket invalid param.", ret != -1);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
LWIP_ASSERT("socket invalid param.", ret == BUF_SIZE);
}
LogPrintln("udp end send");
/* close socket */
ret = closesocket(sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
}
void UdpTestMore()
{
int ret;
ret = sys_thread_new("udp_more", UdpTestMoreTask, NULL,
STACK_TEST_SIZE * 2, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10);
}
@@ -0,0 +1,185 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SEND_TCP_COUNT 1000 // send count
#define STACK_PORT_8 2288
#define TEST_CASE 180
static char g_serverSendBuf[BUF_SIZE + 1] = { 0 };
static char g_clientRecvBuf[BUF_SIZE + 1] = { 0 };
static void InitMsgBuf()
{
int i;
if (g_serverSendBuf[0] != '\0') {
return;
}
for (i = 0; i < BUF_SIZE; i++) {
g_serverSendBuf[i] = 'S';
}
g_serverSendBuf[BUF_SIZE] = '\0';
}
static int SampleTcpServer()
{
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
int i;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_8);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
for (i = 0; i < SEND_TCP_COUNT; i++) {
/* send */
ret = send(sfd, g_serverSendBuf, BUF_SIZE, 0);
ICUNIT_ASSERT_EQUAL(ret, BUF_SIZE, 5);
}
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 7);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
return 0;
}
static int SampleTcpClient()
{
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
int i;
struct sockaddr addr;
socklen_t addrLen = sizeof(addr);
int recvCount = 0;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 7);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_8);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 8);
/* test getpeername */
ret = getpeername(sfd, &addr, &addrLen);
LogPrintln("getpeername %d %s:%d: %d",
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 9);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 10);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(PEER_IP), 11);
/* test getsockname */
ret = getsockname(sfd, &addr, &addrLen);
LogPrintln("getsockname %d %s:%d: %d",
sfd, inet_ntoa(((struct sockaddr_in*)&addr)->sin_addr), ntohs(((struct sockaddr_in*)&addr)->sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 12);
ICUNIT_ASSERT_EQUAL(addrLen, sizeof(struct sockaddr_in), 13);
ICUNIT_ASSERT_EQUAL(((struct sockaddr_in*)&addr)->sin_addr.s_addr, \
inet_addr(STACK_IP), 14);
LogPrintln("tcp begin recv");
for (i = 0; i < 2 * SEND_TCP_COUNT; i++) {
/* recv */
(void)memset_s(g_clientRecvBuf, sizeof(g_clientRecvBuf), 0, sizeof(g_clientRecvBuf));
ret = recv(sfd, g_clientRecvBuf, BUF_SIZE, 0);
recvCount += ret;
if (recvCount >= BUF_SIZE * SEND_TCP_COUNT) {
LogPrintln("client recv on socket %d: %d, i = %d", sfd, recvCount, i);
break;
}
}
ICUNIT_ASSERT_EQUAL(recvCount, BUF_SIZE * SEND_TCP_COUNT, recvCount);
LogPrintln("tcp end recv");
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 17);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTestMore()
{
LogPrintln("net_socket_test_008.c enter");
if (g_testCase < TEST_CASE) {
g_testCase = TEST_CASE;
}
int ret;
InitMsgBuf();
ret = sys_thread_new("tcp_server_more", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 17);
ret = sys_thread_new("tcp_client_more", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 18);
}
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 190
#define STACK_PORT_9 2299
#define TIME_OUT 10 // timeout 10s
static char g_buf[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
#if LWIP_SOCKET_SELECT
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
fd_set fdsr;
struct timeval tv;
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_9);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
FD_ZERO(&fdsr);
FD_SET(lsfd, &fdsr);
// timeout setting
tv.tv_sec = TIME_OUT;
tv.tv_usec = 0;
ret = select(lsfd + 1, &fdsr, NULL, NULL, &tv);
if (ret < 0) {
LogPrintln("select error");
ICUNIT_ASSERT_EQUAL(-1, 0, 4);
} else if (ret == 0) {
LogPrintln("select timeout");
ICUNIT_ASSERT_EQUAL(-1, 0, 5);
}
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 6);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), SRV_MSG);
ret = send(sfd, g_buf, strlen(SRV_MSG), 0);
LogPrintln("server send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 7);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 9);
#endif
return 0;
}
static int SampleTcpClient()
{
#if LWIP_SOCKET_SELECT
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_9);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("client recv on socket %d: %d", sfd, ret);
LogPrintln("cli:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 12);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13);
#endif
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTestSelect()
{
LogPrintln("net_socket_test_009.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_select", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_select", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,160 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 200
#define STACK_PORT_10 2230
#define POLL_OPEN_MAX 10
#define TIME_OUT (1000 * 10) // timeout 10s
static char g_buf[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
#if LWIP_SOCKET_POLL
g_testCase++;
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct pollfd client[POLL_OPEN_MAX] = {0};
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create server socket inet stream: %d", lsfd);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_10);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("bind socket %d to %s:%d: %d", lsfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
LogPrintln("listen socket %d: %d", lsfd, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
client[0].fd = lsfd;
client[0].events = POLLIN;
ret = poll(client, 1, TIME_OUT);
if (ret < 0) {
LogPrintln("poll error");
ICUNIT_ASSERT_EQUAL(-1, 0, 4);
} else if (ret == 0) {
LogPrintln("poll timeout");
ICUNIT_ASSERT_EQUAL(-1, 0, 5);
}
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
LogPrintln("accept socket %d: %d <%s:%d>", lsfd, sfd, inet_ntoa(clnAddr.sin_addr), ntohs(clnAddr.sin_port));
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 6);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recv(sfd, g_buf, sizeof(g_buf), 0);
LogPrintln("server recv on socket %d: %d", sfd, ret);
LogPrintln("ser:%s", g_buf);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 7);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 9);
#endif
return 0;
}
static int SampleTcpClient()
{
#if LWIP_SOCKET_POLL
g_testCase++;
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
LogPrintln("create client socket inet stream: %d", sfd);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_10);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LogPrintln("connect socket %d to %s:%d: %d", sfd, inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port), ret);
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* send */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), CLI_MSG);
ret = send(sfd, g_buf, strlen(CLI_MSG), 0);
LogPrintln("client send on socket %d: %d", sfd, ret);
ICUNIT_ASSERT_EQUAL(ret, strlen(CLI_MSG), 12);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13);
#endif
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
(void)SampleTcpClient();
}
void TcpTestPoll()
{
LogPrintln("net_socket_test_010.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_poll", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_poll", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,449 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include <lwip/netif.h>
#include <lwip/netifapi.h>
#include <lwip/pbuf.h>
#include <lwip/ip4_addr.h>
#include <lwip/ip4.h>
#include <lwip/ip.h>
#include <lwip/def.h>
#include <lwip/udp.h>
#include <lwip/inet_chksum.h>
#include "lwip/prot/iana.h"
#define MSG "Hi, I am testing BT netif."
#define STACK_IP_BT "192.168.167.1"
#define PEER_IP_BT "100.100.100.100"
#define GATEWAY_IP_BT "192.168.167.239"
#define NETIF_MAC "121212"
#define PEER_MAC "454545"
#define NETIF_NAME_BT "bt1000"
#define TEST_CASE 210
static char g_buf[BUF_SIZE + 1] = { 0 };
struct netif *btProxyNf = NULL;
static void ReplayArpTask();
static void ArpPackageProc(struct netif *netif, struct pbuf *p);
extern void driverif_input(struct netif *netif, struct pbuf *p);
static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p);
static void ReplayUdpEncodeEthernet(struct netif *netif, struct pbuf *p)
{
int ret;
ret = pbuf_add_header(p, SIZEOF_ETH_HDR);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
struct eth_hdr *ethhdr;
ethhdr = (struct eth_hdr *)p->payload;
ethhdr->type = lwip_htons(ETHTYPE_IP);
SMEMCPY(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
SMEMCPY(&ethhdr->src, PEER_MAC, ETH_HWADDR_LEN);
driverif_input(netif, p);
}
static void ReplayUdpEncodeIp(struct pbuf *p, ip4_addr_t *src, ip4_addr_t *dest)
{
struct ip_hdr *iphdr;
int ret;
#if CHECKSUM_GEN_IP_INLINE
u32_t chk_sum = 0;
#endif /* CHECKSUM_GEN_IP_INLINE */
// ip header
ret = pbuf_add_header(p, IP_HLEN);
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
iphdr = (struct ip_hdr *)p->payload;
IPH_TTL_SET(iphdr, UDP_TTL);
IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += PP_NTOHS(IP_PROTO_UDP | (ttl << 8));
#endif /* CHECKSUM_GEN_IP_INLINE */
/* dest cannot be NULL here */
ip4_addr_copy(iphdr->dest, *dest);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
#endif /* CHECKSUM_GEN_IP_INLINE */
u16_t ip_hlen = IP_HLEN;
IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
IPH_TOS_SET(iphdr, 0);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
#endif /* CHECKSUM_GEN_IP_INLINE */
IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
#if CHECKSUM_GEN_IP_INLINE
chk_sum += iphdr->_len;
#endif /* CHECKSUM_GEN_IP_INLINE */
IPH_OFFSET_SET(iphdr, 0);
IPH_ID_SET(iphdr, lwip_htons(0));
#if CHECKSUM_GEN_IP_INLINE
chk_sum += iphdr->_id;
#endif /* CHECKSUM_GEN_IP_INLINE */
ip4_addr_copy(iphdr->src, *src);
#if CHECKSUM_GEN_IP_INLINE
chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + chk_sum;
chk_sum = ~chk_sum;
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
iphdr->_chksum = (u16_t)chk_sum; /* network order */
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF
else {
IPH_CHKSUM_SET(iphdr, 0);
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_IP_INLINE */
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
}
#endif /* CHECKSUM_GEN_IP */
#endif /* CHECKSUM_GEN_IP_INLINE */
ReplayUdpEncodeEthernet(btProxyNf, p);
}
static void ReplayUdp(void *ptemp)
{
struct udp_hdr *udphdr;
ip4_addr_t sipaddr, dipaddr;
int size = strlen(MSG);
int ret;
(void)ptemp;
LogPrintln("encode udp replay packet");
inet_pton(AF_INET, PEER_IP_BT, &sipaddr);
inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
u16_t chksum = LWIP_CHKSUM_COPY(p->payload, MSG, size);
// udp header
ret = pbuf_add_header(p, UDP_HLEN);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
udphdr = (struct udp_hdr *)p->payload;
udphdr->src = lwip_htons(STACK_PORT);
udphdr->dest = lwip_htons(STACK_PORT);
udphdr->len = lwip_htons(p->tot_len);
/* in UDP, 0 checksum means 'no checksum' */
u16_t udpchksum = ip_chksum_pseudo_partial(p, IP_PROTO_UDP, p->tot_len, UDP_HLEN, &sipaddr, &dipaddr);
u32_t acc = udpchksum + (u16_t)~(chksum);
udpchksum = FOLD_U32T(acc);
if (udpchksum == 0x0000) {
udpchksum = 0xffff;
}
udphdr->chksum = udpchksum;
udphdr->chksum = 0;
ReplayUdpEncodeIp(p, &sipaddr, &dipaddr);
}
static void ReplayUdpTask()
{
int ret;
ret = sys_thread_new("replay_udp", ReplayUdp, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 3);
}
static void ParsePackageIpUdp(struct netif *netif, struct pbuf *btBuf)
{
// get scr_addr and dest_addr from ip head
const struct ip_hdr *iphdr;
iphdr = (const struct ip_hdr *)btBuf->payload;
ip4_addr_p_t ip4_addr_scr = iphdr->src;
ip4_addr_p_t ip4_addr_dest = iphdr->dest;
char buf[32];
int dataLen;
// get scr_port and dest port from tcp head
u16_t scr_port, dest_port;
void *data;
struct udp_hdr *udphdr;
udphdr = (struct udp_hdr *)((u8_t *)iphdr + IPH_HL_BYTES(iphdr));
scr_port = udphdr->src;
dest_port = udphdr->dest;
data = (void *)((u8_t *)udphdr + UDP_HLEN);
LogPrintln("======Bt netif send package======");
LogPrintln("netif full name %s", netif->full_name);
(void)inet_ntop(AF_INET, &ip4_addr_scr.addr, buf, sizeof(buf));
LogPrintln("package src ip %s", buf);
(void)inet_ntop(AF_INET, &ip4_addr_dest.addr, buf, sizeof(buf));
LogPrintln("package dest ip %s", buf);
LogPrintln("package src port %d", lwip_ntohs(scr_port));
LogPrintln("package dest port %d", lwip_ntohs(dest_port));
LogPrintln("send data %s", (char *)data);
dataLen = lwip_ntohs(udphdr->len) - UDP_HLEN;
LogPrintln("send data length %d", dataLen);
ICUNIT_ASSERT_EQUAL(dataLen, strlen(MSG), 4);
LogPrintln("=================================");
// 回应udp报文
ReplayUdpTask();
}
static void ParsePackageEthernet(struct netif *netif, struct pbuf *p)
{
u16_t next_hdr_offset = SIZEOF_ETH_HDR;
// get src mac and dest mac
struct eth_hdr *ethhdr;
ethhdr = (struct eth_hdr *)p->payload;
u16_t type = ethhdr->type;
LogPrintln("ParsePackageEthernet type is %d", type);
switch (type) {
#if LWIP_IPV4 && LWIP_ARP
/* IP packet? */
case PP_HTONS(ETHTYPE_IP): // 0x0008
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
return;
}
/* skip Ethernet header (min. size checked above) */
if (pbuf_remove_header(p, next_hdr_offset)) {
return;
} else {
/* pass to IP layer */
ParsePackageIpUdp(netif, p);
}
break;
case PP_HTONS(ETHTYPE_ARP): // 0x0608
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
return;
}
/* skip Ethernet header (min. size checked above) */
if (pbuf_remove_header(p, next_hdr_offset)) {
return;
} else {
/* pass p to ARP module */
LogPrintln("recv arp packet");
ArpPackageProc(netif, p);
}
break;
#endif /* LWIP_IPV4 && LWIP_ARP */
default:
LogPrintln("type is other %d", type);
break;
}
}
static void BtProxySend(struct netif *netif, struct pbuf *p)
{
if (netif == NULL || p == NULL) {
LogPrintln("%s : netif = NUll or p = NULL!", __func__);
return;
}
#if ETH_PAD_SIZE
(void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
ParsePackageEthernet(netif, p);
}
static struct netif *CreateBtNetIf()
{
struct netif *btNetif = NULL;
btNetif = (struct netif *)malloc(sizeof(struct netif));
if (btNetif == NULL) {
LogPrintln("%s fail : netif malloc fail!", __func__);
LWIP_ASSERT("btNetif malloc fail.", 0);
return NULL;
}
(void)memset_s(btNetif, sizeof(struct netif), 0, sizeof(struct netif));
btNetif->drv_send = BtProxySend;
btNetif->link_layer_type = BT_PROXY_IF;
btNetif->hwaddr_len = ETH_HWADDR_LEN;
(void)memcpy_s(&btNetif->hwaddr, sizeof(btNetif->hwaddr), NETIF_MAC, ETH_HWADDR_LEN);
(void)memcpy_s(&btNetif->full_name, sizeof(btNetif->full_name), NETIF_NAME_BT, sizeof(NETIF_NAME_BT));
ip4_addr_t gw, ipaddr, netmask;
IP4_ADDR(&gw, 192, 168, 167, 239);
IP4_ADDR(&ipaddr, 192, 168, 167, 1);
IP4_ADDR(&netmask, 255, 255, 255, 255);
int ret = 0;
if ((ret = netifapi_netif_add(btNetif, &ipaddr, &netmask, &gw, btNetif, driverif_init, tcpip_input)) != ERR_OK) {
LogPrintln("%s : netifapi_netif_add fail!,ret=%d", __func__, ret);
LWIP_ASSERT("btNetif add fail.", 0);
return NULL;
}
LogPrintln("netifapi_netif_add success!");
netif_set_link_up(btNetif);
netifapi_netif_set_up(btNetif);
return btNetif;
}
static void UdpTestNetifTask(void *p)
{
(void)p;
LogPrintln("net_socket_test_011.c enter");
g_testCase = TEST_CASE;
int sfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
struct ifreq nif;
int ret;
// 注册网卡
btProxyNf = CreateBtNetIf();
/* socket creation */
sfd = socket(AF_INET, SOCK_DGRAM, 0);
LWIP_ASSERT("socket invalid param.", sfd != -1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP_BT);
srvAddr.sin_port = htons(STACK_PORT);
ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
LWIP_ASSERT("socket invalid param.", ret == 0);
/* 指定网卡接口 */
char *inface = NETIF_NAME_BT;
(void)strcpy_s(nif.ifr_name, sizeof(nif.ifr_name), inface);
if (setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&nif, sizeof(nif)) < 0) {
LogPrintln("set intaface fail");
LWIP_ASSERT("set intaface fail.", 0);
}
/* send */
clnAddr.sin_family = AF_INET;
clnAddr.sin_addr.s_addr = inet_addr(PEER_IP_BT);
clnAddr.sin_port = htons(PEER_PORT);
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
(void)strcpy_s(g_buf, sizeof(g_buf), MSG);
ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr,
(socklen_t)sizeof(clnAddr));
LogPrintln("client send success: %d", sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
/* recv */
(void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
&clnAddrLen);
LWIP_ASSERT("socket invalid param.", ret == strlen(MSG));
LogPrintln("cli recv: %s", g_buf);
/* close socket */
ret = closesocket(sfd);
LWIP_ASSERT("socket invalid param.", ret != -1);
return;
}
int UdpTestNetif()
{
int ret = sys_thread_new("udp_test_netif", UdpTestNetifTask, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return ret;
}
static void ArpPackageProc(struct netif *netif, struct pbuf *p)
{
struct etharp_hdr *hdr;
ip4_addr_t sipaddr, dipaddr;
hdr = (struct etharp_hdr *)p->payload;
if (hdr->opcode != PP_HTONS(ARP_REQUEST)) {
LogPrintln("opcode %d is not arp request", hdr->opcode);
return;
}
inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr);
inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
if (memcmp(&hdr->dipaddr, &sipaddr, sizeof(ip4_addr_t)) != EOK) {
LogPrintln("hdr->dipaddr %u is invalid", hdr->dipaddr);
return;
}
// 回应arp报文
ReplayArpTask();
}
static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p)
{
int ret;
ret = pbuf_add_header(p, SIZEOF_ETH_HDR);
ICUNIT_ASSERT_EQUAL(ret, 0, 1);
struct eth_hdr *ethhdr;
ethhdr = (struct eth_hdr *)p->payload;
ethhdr->type = lwip_htons(ETHTYPE_ARP);
SMEMCPY(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
SMEMCPY(&ethhdr->src, PEER_MAC, ETH_HWADDR_LEN);
driverif_input(netif, p);
}
static void ReplayArp(void *ptemp)
{
struct etharp_hdr *hdr;
ip4_addr_t sipaddr, dipaddr;
(void)ptemp;
LogPrintln("encode arp replay packet");
inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr);
inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
struct pbuf *p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
hdr = (struct etharp_hdr *)p->payload;
hdr->opcode = PP_HTONS(ARP_REPLY);
/* Write the ARP MAC-Addresses */
SMEMCPY(&hdr->shwaddr, PEER_MAC, ETH_HWADDR_LEN);
SMEMCPY(&hdr->dhwaddr, NETIF_MAC, ETH_HWADDR_LEN);
/* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
* structure packing. */
IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, &sipaddr);
IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, &dipaddr);
hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET);
hdr->proto = PP_HTONS(ETHTYPE_IP);
/* set hwlen and protolen */
hdr->hwlen = ETH_HWADDR_LEN;
hdr->protolen = sizeof(ip4_addr_t);
ReplayArpEncodeEthernet(btProxyNf, p);
}
static void ReplayArpTask()
{
int ret;
ret = sys_thread_new("replay_arp", ReplayArp, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
}
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define SRV_MSG "Hi, I am TCP server"
#define CLI_MSG "Hi, I am TCP client"
#define TEST_CASE 220
#define TEST_COUNT 100
#define STACK_PORT_TCP_DUP_START 3000
static int g_portServer = STACK_PORT_TCP_DUP_START;
static int g_portClient = STACK_PORT_TCP_DUP_START;
static char g_bufServer[BUF_SIZE + 1] = { 0 };
static char g_bufClient[BUF_SIZE + 1] = { 0 };
static int SampleTcpServer()
{
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(g_portServer);
g_portServer++;
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
/* send */
(void)memset_s(g_bufServer, sizeof(g_bufServer), 0, sizeof(g_bufServer));
(void)strcpy_s(g_bufServer, sizeof(g_bufServer), SRV_MSG);
ret = send(sfd, g_bufServer, strlen(SRV_MSG), 0);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 5);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 10);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 11);
return 0;
}
static int SampleTcpClient()
{
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret;
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 10);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(g_portClient);
g_portClient++;
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 11);
/* recv */
(void)memset_s(g_bufClient, sizeof(g_bufClient), 0, sizeof(g_bufClient));
ret = recv(sfd, g_bufClient, sizeof(g_bufClient), 0);
ICUNIT_ASSERT_EQUAL(ret, strlen(SRV_MSG), 19);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
g_testCase++;
int i;
for (i = 0; i < TEST_COUNT; i++) {
(void)SampleTcpServer();
}
LogPrintln("tcp server g_portServer = %d", g_portServer);
}
static void TcpClientRoutine(void *p)
{
(void)p;
g_testCase++;
int i;
for (i = 0; i < TEST_COUNT; i++) {
(void)SampleTcpClient();
}
LogPrintln("tcp server g_portClient = %d", g_portClient);
}
void TcpTestDup()
{
LogPrintln("net_socket_test_012.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_dup", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_dup", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lwip_test.h"
#include "lwipopts.h"
#include <arch/sys_arch.h>
#include <lwip/sys.h>
#define TEST_CASE 230
#define STACK_PORT_TCP_LONG 2231
#define TCP_LONG_BUF_SIZE (2 * 1024)
static int SampleTcpServer()
{
int sfd, lsfd;
struct sockaddr_in srvAddr = { 0 };
struct sockaddr_in clnAddr = { 0 };
socklen_t clnAddrLen = sizeof(clnAddr);
int ret;
static char serverBuf[TCP_LONG_BUF_SIZE] = {0};
/* tcp server */
lsfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(lsfd, -1, 1);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(STACK_IP);
srvAddr.sin_port = htons(STACK_PORT_TCP_LONG);
ret = bind(lsfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 2);
ret = listen(lsfd, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, 3);
sfd = accept(lsfd, (struct sockaddr*)&clnAddr, &clnAddrLen);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 4);
/* send */
ret = send(sfd, serverBuf, TCP_LONG_BUF_SIZE, 0);
ICUNIT_ASSERT_EQUAL(ret, TCP_LONG_BUF_SIZE, 6);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 7);
ret = closesocket(lsfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 8);
return 0;
}
static int SampleTcpClient()
{
int sfd;
struct sockaddr_in srvAddr = { 0 };
int ret, i;
int recvCount = 0;
static char clientBuf[TCP_LONG_BUF_SIZE] = {0};
/* tcp client connection */
sfd = socket(AF_INET, SOCK_STREAM, 0);
ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, 9);
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.s_addr = inet_addr(PEER_IP);
srvAddr.sin_port = htons(STACK_PORT_TCP_LONG);
ret = connect(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
ICUNIT_ASSERT_EQUAL(ret, 0, 10);
/* recv */
for (i = 0; i < TCP_LONG_BUF_SIZE; i++) {
ret = recv(sfd, clientBuf, TCP_LONG_BUF_SIZE, 0);
recvCount += ret;
if (recvCount >= TCP_LONG_BUF_SIZE) {
LogPrintln("client recv on socket %d: %d, i = %d", sfd, recvCount, i);
break;
}
}
ICUNIT_ASSERT_NOT_EQUAL(i, TCP_LONG_BUF_SIZE, 12);
ret = closesocket(sfd);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 13);
return 0;
}
static void TcpServerRoutine(void *p)
{
(void)p;
g_testCase++;
(void)SampleTcpServer();
}
static void TcpClientRoutine(void *p)
{
(void)p;
g_testCase++;
(void)SampleTcpClient();
}
void TcpTestLong()
{
LogPrintln("net_socket_test_013.c enter");
g_testCase = TEST_CASE;
int ret;
ret = sys_thread_new("tcp_server_long", TcpServerRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
ret = sys_thread_new("tcp_client_long", TcpClientRoutine, NULL,
STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 24);
}
@@ -0,0 +1,145 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sys/socket.h"
#include "hos_cmsis_adp.h"
#define LWIP_TEST_TIMEOUT 1000 // timeout 1s
#define LWIP_TEST_COUNT_FLAG 100
#define SOCKET_TEST 310
#define UDP_TEST 320
#define TCP_TEST 330
#define OPT_TEST 340
#define ORDER_TEST 350
#define INET_TEST 360
#define UDP_MORE_TEST 370
#define TCP_MORE_TEST 380
#define TCP_SELECT_TEST 390
#define TCP_POLL_TEST 400
#define NETIF_TEST 410
#define TCP_DUP_TEST 420
#define TCP_LONG_TEST 430
int g_lwipTimerCount = 0;
int g_testCase = LWIP_TEST_COUNT_FLAG;
int g_testError = 0;
int g_testTemp = LWIP_TEST_COUNT_FLAG;
extern void abort(void);
extern int SocketTest(void);
extern int UdpTest(void);
extern void TcpTest();
extern int SockOptTest();
extern int ByteOrderTest(void);
extern int InetTest();
extern int UdpTestMore(void);
extern void TcpTestMore();
extern void TcpTestSelect();
extern void TcpTestPoll();
extern int UdpTestNetif(void);
extern void TcpTestDup();
extern void TcpTestLong();
// time out 1s
static void LwipTestTimeoutCallback(void const *argument)
{
g_lwipTimerCount++;
switch (g_lwipTimerCount) {
case SOCKET_TEST:
SocketTest();
break;
case UDP_TEST:
UdpTest();
break;
case TCP_TEST:
TcpTest();
break;
case OPT_TEST:
SockOptTest();
break;
case ORDER_TEST:
ByteOrderTest();
break;
case INET_TEST:
InetTest();
break;
case UDP_MORE_TEST:
UdpTestMore();
break;
case TCP_MORE_TEST:
TcpTestMore();
break;
case TCP_SELECT_TEST:
TcpTestSelect();
break;
case TCP_POLL_TEST:
TcpTestPoll();
break;
case NETIF_TEST:
UdpTestNetif();
break;
case TCP_DUP_TEST:
TcpTestDup();
break;
case TCP_LONG_TEST:
TcpTestLong();
break;
default:
break;
}
}
osTimerId_t g_lwipTestTimerId = NULL;
void LwipTestStartTimer(uint32_t timeout)
{
osStatus_t status;
if (g_lwipTestTimerId != NULL) {
status = osTimerStart(g_lwipTestTimerId, timeout);
if (status != osOK) {
return;
}
} else {
g_lwipTestTimerId = osTimerNew((osTimerFunc_t)LwipTestTimeoutCallback, osTimerPeriodic, NULL, NULL);
if (g_lwipTestTimerId == NULL) {
return;
}
status = osTimerStart(g_lwipTestTimerId, timeout);
if (status != osOK) {
return;
}
}
}
void LwipTestEnter()
{
LwipTestStartTimer(LWIP_TEST_TIMEOUT);
}
@@ -0,0 +1,39 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("pm") {
sources = [ "los_pm.c" ]
include_dirs = [
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
"//third_party/bounds_checking_function/include",
]
}
@@ -0,0 +1,663 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_pm.h"
#include "securec.h"
#include "los_sched.h"
#include "los_timer.h"
#include "los_memory.h"
#if (LOSCFG_KERNEL_PM == 1)
#define OS_PM_NODE_FREE 0x80000000U
#define OS_PM_LOCK_MAX 0xFFFFU
typedef UINT32 (*Suspend)(VOID);
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
typedef struct {
CHAR *name;
UINT32 count;
LOS_DL_LIST list;
} OsPmLockCB;
#endif
typedef struct {
LOS_SysSleepEnum pmMode;
LOS_SysSleepEnum sysMode;
UINT16 lock;
BOOL isWake;
LosPmDevice *device;
LosPmSysctrl *sysctrl;
LosPmTickTimer *tickTimer;
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
UINT64 enterSleepTime;
#endif
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
LOS_DL_LIST lockList;
#endif
} LosPmCB;
STATIC LosPmCB g_pmCB;
STATIC LosPmSysctrl *g_sysctrl = NULL;
STATIC UINT64 g_pmSleepTime;
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
STATIC VOID OsPmTickTimerStart(LosPmCB *pm)
{
UINT32 intSave;
UINT64 currTime, sleepTime, realSleepTime;
LosPmTickTimer *tickTimer = pm->tickTimer;
intSave = LOS_IntLock();
/* Restore the main CPU frequency */
sleepTime = tickTimer->timerCycleGet();
tickTimer->timerStop();
realSleepTime = OS_SYS_CYCLE_TO_NS(sleepTime, tickTimer->freq);
realSleepTime = OS_SYS_NS_TO_CYCLE(realSleepTime, OS_SYS_CLOCK);
currTime = pm->enterSleepTime + realSleepTime;
pm->enterSleepTime = 0;
OsSchedTimerBaseReset(currTime);
OsSchedUpdateExpireTime(currTime, FALSE);
tickTimer->tickUnlock();
LOS_IntRestore(intSave);
return;
}
STATIC VOID OsPmTickTimerStop(LosPmCB *pm)
{
UINT64 sleepCycle;
UINT64 realSleepTime = g_pmSleepTime;
LosPmTickTimer *tickTimer = pm->tickTimer;
if (realSleepTime == 0) {
return;
}
sleepCycle = OS_SYS_CYCLE_TO_NS(realSleepTime, OS_SYS_CLOCK);
sleepCycle = OS_SYS_NS_TO_CYCLE(sleepCycle, tickTimer->freq);
/* The main CPU reduces the frequency */
pm->enterSleepTime = OsGetCurrSchedTimeCycle();
tickTimer->tickLock();
tickTimer->timerStart(sleepCycle);
return;
}
#endif
STATIC VOID OsPmTickTimerResume(LosPmCB *pm)
{
if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->tickTimer->tickUnlock != NULL)) {
pm->tickTimer->tickUnlock();
} else {
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
/* Sys tick timer is restored from low power mode */
if (pm->enterSleepTime != 0) {
OsPmTickTimerStart(pm);
}
#endif
}
}
STATIC VOID OsPmCpuResume(LosPmCB *pm)
{
if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) {
pm->sysctrl->normalResume();
} else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) {
pm->sysctrl->lightResume();
} else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) {
pm->sysctrl->deepResume();
}
}
STATIC Suspend OsPmCpuSuspend(LosPmCB *pm)
{
Suspend sysSuspend = NULL;
/* cpu enter low power mode */
LOS_ASSERT(pm->sysctrl != NULL);
if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) {
sysSuspend = pm->sysctrl->normalSuspend;
} else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) {
sysSuspend = pm->sysctrl->lightSuspend;
} else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) {
sysSuspend = pm->sysctrl->deepSuspend;
} else {
sysSuspend = pm->sysctrl->shutdownSuspend;
}
LOS_ASSERT(sysSuspend != NULL);
return sysSuspend;
}
STATIC VOID OsPmTickTimerSuspend(LosPmCB *pm)
{
if (((pm->sysMode == LOS_SYS_DEEP_SLEEP) || (pm->sysMode == LOS_SYS_SHUTDOWN)) &&
(pm->tickTimer->tickLock != NULL)) {
pm->tickTimer->tickLock();
} else {
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
/* Sys tick timer enter low power mode */
if (pm->tickTimer == NULL) {
return;
}
if ((pm->tickTimer->timerStart != NULL) &&
(pm->tickTimer->timerStop != NULL) &&
(pm->tickTimer->timerCycleGet == NULL) &&
(pm->tickTimer->freq != 0)) {
OsPmTickTimerStop(pm);
}
#endif
}
}
STATIC VOID OsPmEnter(BOOL isIdle)
{
UINT32 ret;
UINT32 intSave;
Suspend sysSuspend = NULL;
LosPmCB *pm = &g_pmCB;
BOOL isTaskLock = FALSE;
intSave = LOS_IntLock();
pm->sysMode = pm->pmMode;
if (isIdle) {
if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->sysMode != LOS_SYS_LIGHT_SLEEP)) {
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
}
} else {
if ((pm->sysMode != LOS_SYS_DEEP_SLEEP) && (pm->sysMode != LOS_SYS_SHUTDOWN)) {
LOS_IntRestore(intSave);
return;
}
}
if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) || (pm->sysMode == LOS_SYS_LIGHT_SLEEP)) {
if (pm->lock > 0) {
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
}
} else if (pm->lock > 0) {
LOS_IntRestore(intSave);
return;
}
if (pm->sysMode != LOS_SYS_NORMAL_SLEEP) {
pm->isWake = FALSE;
LOS_TaskLock();
isTaskLock = TRUE;
ret = pm->device->suspend((UINT32)pm->sysMode);
if (ret != LOS_OK) {
goto EXIT;
}
}
OsPmTickTimerSuspend(pm);
sysSuspend = OsPmCpuSuspend(pm);
LOS_IntRestore(intSave);
if (!isTaskLock || (isTaskLock && !pm->isWake)) {
(VOID)sysSuspend();
}
intSave = LOS_IntLock();
OsPmCpuResume(pm);
OsPmTickTimerResume(pm);
if (pm->sysMode != LOS_SYS_NORMAL_SLEEP) {
pm->device->resume((UINT32)pm->sysMode);
}
if (pm->pmMode == LOS_SYS_DEEP_SLEEP) {
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
}
EXIT:
LOS_IntRestore(intSave);
if (isTaskLock) {
LOS_TaskUnlock();
}
return;
}
STATIC VOID OsPmTask(VOID)
{
OsPmEnter(FALSE);
}
STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)
{
UINT32 intSave;
if ((device->suspend == NULL) || (device->resume == NULL)) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
intSave = LOS_IntLock();
pm->device = device;
LOS_IntRestore(intSave);
return LOS_OK;
}
STATIC UINT32 OsPmTickTimerRegister(LosPmCB *pm, LosPmTickTimer *tickTimer)
{
UINT32 intSave;
intSave = LOS_IntLock();
#if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
pm->enterSleepTime = 0;
#endif
pm->tickTimer = tickTimer;
LOS_IntRestore(intSave);
return LOS_OK;
}
STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)
{
UINT32 intSave;
if (sysctrl->normalSuspend == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
intSave = LOS_IntLock();
pm->sysctrl = sysctrl;
LOS_IntRestore(intSave);
return LOS_OK;
}
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node)
{
LosPmCB *pm = &g_pmCB;
if (node == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
switch (type) {
case LOS_PM_TYPE_DEVICE:
return OsPmDeviceRegister(pm, (LosPmDevice *)node);
case LOS_PM_TYPE_TICK_TIMER:
return OsPmTickTimerRegister(pm, (LosPmTickTimer *)node);
case LOS_PM_TYPE_SYSCTRL:
return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node);
default:
break;
}
return LOS_ERRNO_PM_INVALID_TYPE;
}
STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, LosPmDevice *device)
{
UINT32 intSave;
intSave = LOS_IntLock();
if (pm->device == device) {
pm->device = NULL;
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
LOS_IntRestore(intSave);
return LOS_OK;
}
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_INVALID_NODE;
}
STATIC UINT32 OsPmTickTimerUnregister(LosPmCB *pm, LosPmTickTimer *tickTimer)
{
UINT32 intSave;
intSave = LOS_IntLock();
if (pm->tickTimer == tickTimer) {
pm->tickTimer = NULL;
if ((pm->pmMode != LOS_SYS_NORMAL_SLEEP) && (pm->pmMode != LOS_SYS_LIGHT_SLEEP)) {
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
}
LOS_IntRestore(intSave);
return LOS_OK;
}
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_INVALID_NODE;
}
STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)
{
UINT32 intSave;
VOID *freeNode = NULL;
intSave = LOS_IntLock();
if (pm->sysctrl == sysctrl) {
if (pm->sysctrl == g_sysctrl) {
freeNode = (VOID *)pm->sysctrl;
g_sysctrl = NULL;
}
pm->sysctrl = NULL;
LOS_IntRestore(intSave);
if (freeNode != NULL) {
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, freeNode);
}
return LOS_OK;
}
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_INVALID_NODE;
}
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node)
{
LosPmCB *pm = &g_pmCB;
if (node == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
switch (type) {
case LOS_PM_TYPE_DEVICE:
return OsPmDeviceUnregister(pm, (LosPmDevice *)node);
case LOS_PM_TYPE_TICK_TIMER:
return OsPmTickTimerUnregister(pm, (LosPmTickTimer *)node);
case LOS_PM_TYPE_SYSCTRL:
return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node);
default:
break;
}
return LOS_ERRNO_PM_INVALID_TYPE;
}
VOID LOS_PmWakeSet(VOID)
{
UINT32 intSave;
LosPmCB *pm = &g_pmCB;
intSave = LOS_IntLock();
pm->isWake = TRUE;
LOS_IntRestore(intSave);
return;
}
LOS_SysSleepEnum LOS_PmModeGet(VOID)
{
LOS_SysSleepEnum mode;
LosPmCB *pm = &g_pmCB;
UINT32 intSave = LOS_IntLock();
mode = pm->pmMode;
LOS_IntRestore(intSave);
return mode;
}
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode)
{
UINT32 intSave;
UINT32 taskID;
UINT32 ret;
LosPmCB *pm = &g_pmCB;
INT32 sleepMode = (INT32)mode;
TSK_INIT_PARAM_S taskInitParam = { 0 };
if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) {
return LOS_ERRNO_PM_INVALID_MODE;
}
intSave = LOS_IntLock();
if ((mode != LOS_SYS_NORMAL_SLEEP) && (pm->device == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_DEVICE_NULL;
}
if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_HANDLER_NULL;
}
if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_HANDLER_NULL;
}
if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_HANDLER_NULL;
}
if ((mode == LOS_SYS_DEEP_SLEEP) || (mode == LOS_SYS_SHUTDOWN)) {
if ((pm->tickTimer == NULL) ||
(pm->tickTimer->tickLock == NULL) ||
(pm->tickTimer->tickUnlock == NULL)) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_TICK_TIMER_NULL;
}
}
pm->pmMode = mode;
LOS_IntRestore(intSave);
if ((mode == LOS_SYS_DEEP_SLEEP) || (mode == LOS_SYS_SHUTDOWN)) {
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsPmTask;
taskInitParam.uwStackSize = LOSCFG_KERNEL_PM_TASK_STACKSIZE;
taskInitParam.pcName = "pm";
taskInitParam.usTaskPrio = LOSCFG_KERNEL_PM_TASK_PTIORITY;
ret = LOS_TaskCreate(&taskID, &taskInitParam);
if (ret != LOS_OK) {
return ret;
}
}
return LOS_OK;
}
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
VOID LOS_PmLockInfoShow(VOID)
{
UINT32 intSave;
LosPmCB *pm = &g_pmCB;
OsPmLockCB *lock = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
PRINTK("Name Count\n\r");
intSave = LOS_IntLock();
while (list != head) {
lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
PRINTK("%-30s%5u\n\r", lock->name, lock->count);
list = list->pstNext;
}
LOS_IntRestore(intSave);
return;
}
#endif
UINT32 LOS_PmLockRequest(const CHAR *name)
{
UINT32 intSave;
UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
LosPmCB *pm = &g_pmCB;
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
OsPmLockCB *listNode = NULL;
OsPmLockCB *lock = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
if (name == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
#endif
intSave = LOS_IntLock();
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
while (list != head) {
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
if (strcmp(name, listNode->name) == 0) {
lock = listNode;
break;
}
list = list->pstNext;
}
if (lock == NULL) {
lock = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(OsPmLockCB));
if (lock == NULL) {
LOS_IntRestore(intSave);
return LOS_NOK;
}
lock->name = (CHAR *)name;
lock->count = 1;
LOS_ListTailInsert(head, &lock->list);
} else if (lock->count < OS_PM_LOCK_MAX) {
lock->count++;
}
#endif
if (pm->lock < OS_PM_LOCK_MAX) {
pm->lock++;
ret = LOS_OK;
}
LOS_IntRestore(intSave);
return ret;
}
UINT32 LOS_PmLockRelease(const CHAR *name)
{
UINT32 intSave;
UINT32 ret = LOS_ERRNO_PM_NOT_LOCK;
LosPmCB *pm = &g_pmCB;
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
OsPmLockCB *lock = NULL;
OsPmLockCB *listNode = NULL;
LOS_DL_LIST *head = &pm->lockList;
LOS_DL_LIST *list = head->pstNext;
VOID *lockFree = NULL;
if (name == NULL) {
return LOS_ERRNO_PM_INVALID_PARAM;
}
#endif
intSave = LOS_IntLock();
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
while (list != head) {
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
if (strcmp(name, listNode->name) == 0) {
lock = listNode;
break;
}
list = list->pstNext;
}
if (lock == NULL) {
LOS_IntRestore(intSave);
return LOS_ERRNO_PM_NOT_LOCK;
} else if (lock->count > 0) {
lock->count--;
if (lock->count == 0) {
LOS_ListDelete(&lock->list);
lockFree = lock;
}
}
#endif
if (pm->lock > 0) {
pm->lock--;
ret = LOS_OK;
}
LOS_IntRestore(intSave);
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
#endif
return ret;
}
STATIC VOID OsPmSleepTimeSet(UINT64 sleepTime)
{
g_pmSleepTime = sleepTime;
}
UINT32 OsPmInit(VOID)
{
UINT32 ret;
LosPmCB *pm = &g_pmCB;
(VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
LOS_ListInit(&pm->lockList);
#endif
ret = OsSchedRealSleepTimeSet(OsPmSleepTimeSet);
if (ret != LOS_OK) {
return ret;
}
ret = OsPmEnterHandlerSet(OsPmEnter);
if (ret != LOS_OK) {
return ret;
}
g_sysctrl = (LosPmSysctrl *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(LosPmSysctrl));
if (g_sysctrl == NULL) {
return LOS_NOK;
}
(VOID)memset_s(g_sysctrl, sizeof(LosPmSysctrl), 0, sizeof(LosPmSysctrl));
g_sysctrl->normalSuspend = HalEnterSleep;
ret = LOS_PmRegister(LOS_PM_TYPE_SYSCTRL, (VOID *)g_sysctrl);
if (ret != LOS_OK) {
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, g_sysctrl);
g_sysctrl = NULL;
}
return ret;
}
#endif
@@ -0,0 +1,326 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_PM_H
#define _LOS_PM_H
#include "los_config.h"
#include "los_compiler.h"
#include "los_list.h"
#include "los_error.h"
/**
* @ingroup los_pm
* Pm error code: Invalid low power mode.
*
* Value: 0x02002001
*
*/
#define LOS_ERRNO_PM_INVALID_MODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x01)
/**
* @ingroup los_pm
* Pm error code: Invalid input parameter.
*
* Value: 0x02002002
*
*/
#define LOS_ERRNO_PM_INVALID_PARAM LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x02)
/**
* @ingroup los_pm
* Pm error code: The current mode is unlocked.
*
* Value: 0x02002003
*
*/
#define LOS_ERRNO_PM_NOT_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x03)
/**
* @ingroup los_pm
* Pm error code: The lock limit has been exceeded.
*
* Value: 0x02002004
*
*/
#define LOS_ERRNO_PM_LOCK_LIMIT LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x04)
/**
* @ingroup los_pm
* Pm error code: Invalid device node.
*
* Value: 0x02002005
*
*/
#define LOS_ERRNO_PM_INVALID_NODE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x05)
/**
* @ingroup los_pm
* Pm error code: Invalid type.
*
* Value: 0x02002006
*
*/
#define LOS_ERRNO_PM_INVALID_TYPE LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x06)
/**
* @ingroup los_pm
* Pm error code: The hook for mode is not implemented.
*
* Value: 0x02002007
*
*/
#define LOS_ERRNO_PM_HANDLER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x07)
/**
* @ingroup los_pm
* Pm error code: Deep and shutdown must implement the Tick Timer related interface.
*
* Value: 0x02002008
*
*/
#define LOS_ERRNO_PM_TICK_TIMER_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x08)
/**
* @ingroup los_pm
* Pm error code: Device is not registered.
*
* Value: 0x02002009
*
*/
#define LOS_ERRNO_PM_DEVICE_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_PM, 0x09)
typedef enum {
LOS_SYS_NORMAL_SLEEP = 0,
LOS_SYS_LIGHT_SLEEP,
LOS_SYS_DEEP_SLEEP,
LOS_SYS_SHUTDOWN,
} LOS_SysSleepEnum;
typedef enum {
LOS_PM_TYPE_DEVICE = 0,
LOS_PM_TYPE_TICK_TIMER,
LOS_PM_TYPE_SYSCTRL,
} LOS_PmNodeType;
typedef struct {
UINT32 (*suspend)(UINT32 mode);
VOID (*resume)(UINT32 mode);
} LosPmDevice;
typedef struct {
UINT32 freq; /* The frequency of the low power timer */
VOID (*timerStart)(UINT64); /* Start the low power timer */
VOID (*timerStop)(VOID); /* Stop the low power timer */
UINT64 (*timerCycleGet)(VOID); /* Gets the running time of the low power timer in unit cycle */
VOID (*tickLock)(VOID); /* Pause the system tick timer */
VOID (*tickUnlock)(VOID); /* Restore the system tick timer */
} LosPmTickTimer;
typedef struct {
UINT32 (*normalSuspend)(VOID);
VOID (*normalResume)(VOID);
UINT32 (*lightSuspend)(VOID);
VOID (*lightResume)(VOID);
UINT32 (*deepSuspend)(VOID);
VOID (*deepResume)(VOID);
UINT32 (*shutdownSuspend)(VOID);
VOID (*shutdownResume)(VOID);
} LosPmSysctrl;
/**
* @ingroup los_pm
* @brief Initialize system low power frame.
*
* @par Description:
* This API is used to initialize the system low power frame.
*
* @attention None.
*
* @param None.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see
*/
UINT32 OsPmInit(VOID);
/**
* @ingroup los_pm
* @brief Register a power management node.
*
* @par Description:
* This API is used to register a power management node.
*
* @attention None.
*
* @param type [IN] The types supported by the PM module.
* @param node [IN] power management node.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmUnregister
*/
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node);
/**
* @ingroup los_pm
* @brief Unregister a power management node.
*
* @par Description:
* This API is used to unregister a power management node.
*
* @attention None.
*
* @param type [IN] The types supported by the PM module.
* @param node [IN] power management node.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmRegister
*/
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node);
/**
* @ingroup los_pm
* @brief Set the system wake up flag.
*
* @par Description:
* This API is used to set the system wake-up flag.
*
* @attention None.
*
* @param None.
*
* @retval None.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see
*/
VOID LOS_PmWakeSet(VOID);
/**
* @ingroup los_pm
* @brief Get the low power mode of the current system.
*
* @par Description:
* This API is used to get the low power mode of the current system.
*
* @attention None.
*
* @param None.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmModeSet
*/
LOS_SysSleepEnum LOS_PmModeGet(VOID);
/**
* @ingroup los_pm
* @brief Set low power mode.
*
* @par Description:
* This API is used to set low power mode.
*
* @attention None.
*
* @param mode [IN] low power mode.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmModeGet
*/
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode);
/**
* @ingroup los_pm
* @brief Request to obtain the lock in current mode, so that the system will not enter
* this mode when it enters the idle task next time.
*
* @par Description:
* This API is used to obtain the lock in current mode.
*
* @attention None.
*
* @param name [IN] Who requests the lock.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRelease
*/
UINT32 LOS_PmLockRequest(const CHAR *name);
/**
* @ingroup los_pm
* @brief Release the lock in current mode so that the next time the system enters
* the idle task, it will enter this mode.
*
* @par Description:
* This API is used to release the lock in current mode.
*
* @attention None.
*
* @param name [IN] Who releases the lock.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRequest
*/
UINT32 LOS_PmLockRelease(const CHAR *name);
#if (LOSCFG_KERNEL_PM_DEBUG == 1)
/**
* @ingroup los_pm
* @brief Output the locking information of the pm lock.
*
* @par Description:
* This API is used to output the locking information of the pm lock.
*
* @attention None.
*
* @param None.
*
* @retval error code, LOS_OK means success.
* @par Dependency:
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
* @see LOS_PmLockRequest
*/
VOID LOS_PmLockInfoShow(VOID);
#endif
#endif
@@ -0,0 +1,47 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("//build/lite/config/component/lite_component.gni")
declare_args() {
enable_ohos_kernel_liteos_m_cmsis = true
enable_ohos_kernel_liteos_m_posix = true
}
lite_component("kal") {
features = []
if (enable_ohos_kernel_liteos_m_cmsis == true) {
features += [ "cmsis" ]
}
if (enable_ohos_kernel_liteos_m_posix == true) {
features += [ "posix" ]
}
}
@@ -0,0 +1,48 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("cmsis") {
sources = [ "cmsis_liteos2.c" ]
include_dirs = [
"//third_party/bounds_checking_function/include",
"../../kernel/include",
"../../kernel/arch/include",
"../../utils",
]
public_configs = [ ":include" ]
}
config("include") {
include_dirs = [
".",
"//third_party/cmsis/CMSIS/RTOS2/Include",
]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CMSIS_OS_H_
#define CMSIS_OS_H_
#include "los_config.h"
#if (CMSIS_OS_VER == 1)
#error "cmsis version 1.0 is not supported now!"
#elif (CMSIS_OS_VER == 2)
#include "cmsis_os2.h"
#endif
#endif /* CMSIS_OS_H_ */
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../../../third_party/cmsis/CMSIS/RTOS2/Include/cmsis_os2.h"
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HOS_CMSIS_ADP_H
#define HOS_CMSIS_ADP_H
#include "cmsis_os.h"
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
typedef struct {
osSemaphoreAttr_t attr;
UINT32 maxCount;
UINT32 initialCount;
} SemaphoreEx;
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _KAL_H
#define _KAL_H
#include "los_config.h"
#include "los_compiler.h"
#include "cmsis_os2.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
/**
* @brief Enumerates timer permissions.
*
* @since 1.0
* @version 1.0
*/
typedef enum {
/** The timer is not allowed to wake up the RTOS. */
osTimerRousesIgnore = 0,
/** The timer is allowed to wake up the RTOS. */
osTimerRousesAllow = 1
} osTimerRouses_t;
/**
* @brief Enumerates timer alignment modes.
*
*/
typedef enum {
/** The timer ignores alignment. */
osTimerAlignIgnore = 0,
/** The timer allows alignment. */
osTimerAlignAllow = 1
} osTimerAlign_t;
osTimerId_t osTimerExtNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr,
osTimerRouses_t ucRouses, osTimerAlign_t ucSensitive);
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _KAL_H */
@@ -0,0 +1,60 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
config("include") {
include_dirs = [ "include" ]
}
static_library("posix") {
sources = [
"src/errno.c",
"src/libc.c",
"src/malloc.c",
"src/mqueue.c",
"src/pthread.c",
"src/pthread_attr.c",
"src/pthread_cond.c",
"src/pthread_mutex.c",
"src/semaphore.c",
"src/time.c",
]
include_dirs = [
"../../kernel/arch/include",
"../../kernel/include",
"../../utils",
]
public_configs = [ ":include" ]
public_deps = [
"//third_party/musl/porting/liteos_m/kernel",
"//third_party/bounds_checking_function:libsec_static",
]
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBC_H_
#define LIBC_H_
#ifdef __cplusplus
extern "C" {
#endif
const char *libc_get_version_string(void);
int libc_get_version(void);
#ifdef __cplusplus
}
#endif
#endif // LIBC_H_
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include "los_interrupt.h"
#include "los_task.h"
/* the specific errno get or set in interrupt service routine */
static int g_isrErrno;
int *__errno_location(void)
{
LosTaskCB *runTask = NULL;
if (OS_INT_INACTIVE) {
runTask = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
return &runTask->errorNo;
} else {
return &g_isrErrno;
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <libc.h>
#include "libc_config.h"
/**
* get libc version string.
* @return libc version string. the format is <major>.<minor>.<patch>[-<platform>[-<desc>]]
*/
const char *libc_get_version_string(void)
{
return LIBC_VERSION_STR;
}
/**
* get libc version code.
* @return libc version code. the format is 0x00XXYYZZ, XX is major version, YY is minor version and ZZ is patch version
*/
int libc_get_version(void)
{
return LIBC_VERSION_NUM;
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBC_CONFIG_H_
#define LIBC_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LIBC_VERSION_STR
#define LIBC_VERSION_STR "1.0.0-LiteOS_M"
#endif
#ifndef LIBC_VERSION_NUM
#define LIBC_VERSION_NUM 0x00010000
#endif
#ifdef __cplusplus
}
#endif
#endif // LIBC_CONFIG_H_
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "securec.h"
#include "los_config.h"
#include "los_memory.h"
void *calloc(size_t nitems, size_t size)
{
size_t real_size;
void *ptr = NULL;
if (nitems == 0 || size == 0) {
return NULL;
}
real_size = (size_t)(nitems * size);
ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, real_size);
if (ptr != NULL) {
(void)memset_s(ptr, real_size, 0, real_size);
}
return ptr;
}
void free(void *ptr)
{
if (ptr == NULL) {
return;
}
LOS_MemFree(OS_SYS_MEM_ADDR, ptr);
}
void *malloc(size_t size)
{
if (size == 0) {
return NULL;
}
return LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
}
void *zalloc(size_t size)
{
void *ptr = NULL;
if (size == 0) {
return NULL;
}
ptr = LOS_MemAlloc(OS_SYS_MEM_ADDR, size);
if (ptr != NULL) {
(void)memset_s(ptr, size, 0, size);
}
return ptr;
}
void *memalign(size_t boundary, size_t size)
{
if (size == 0) {
return NULL;
}
return LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, boundary);
}
void *realloc(void *ptr, size_t size)
{
if (ptr == NULL) {
return malloc(size);
}
if (size == 0) {
free(ptr);
return NULL;
}
return LOS_MemRealloc(OS_SYS_MEM_ADDR, ptr, size);
}
@@ -0,0 +1,616 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mqueue_impl.h"
#include "time_internal.h"
/* GLOBALS */
STATIC struct mqarray g_queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT];
STATIC pthread_mutex_t g_mqueueMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
int MapMqErrno(UINT32 err)
{
if (err == LOS_OK) {
return ENOERR;
}
switch (err) {
case LOS_ERRNO_QUEUE_INVALID:
case LOS_ERRNO_QUEUE_WRITE_PTR_NULL:
case LOS_ERRNO_QUEUE_WRITESIZE_ISZERO:
case LOS_ERRNO_QUEUE_SIZE_TOO_BIG:
case LOS_ERRNO_QUEUE_CREAT_PTR_NULL:
case LOS_ERRNO_QUEUE_PARA_ISZERO:
case LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG:
errno = EINVAL;
break;
case LOS_ERRNO_QUEUE_ISFULL:
case LOS_ERRNO_QUEUE_ISEMPTY:
errno = EAGAIN;
break;
case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY:
errno = ENOSPC;
break;
case LOS_ERRNO_QUEUE_TIMEOUT:
errno = ETIMEDOUT;
break;
case LOS_ERRNO_QUEUE_CB_UNAVAILABLE:
errno = ENFILE;
break;
case LOS_ERRNO_QUEUE_READ_IN_INTERRUPT:
case LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT:
errno = EINTR;
break;
default:
errno = EINVAL;
break;
}
return errno;
}
STATIC INLINE INT32 MqNameCheck(const CHAR *mqName)
{
if (mqName == NULL) {
errno = EINVAL;
return -1;
}
if (strlen(mqName) == 0) {
errno = EINVAL;
return -1;
}
if (strlen(mqName) > (PATH_MAX - 1)) {
errno = ENAMETOOLONG;
return -1;
}
return 0;
}
STATIC INLINE UINT32 GetMqueueCBByID(UINT32 queueID, LosQueueCB **queueCB)
{
LosQueueCB *tmpQueueCB = NULL;
if (queueCB == NULL) {
errno = EINVAL;
return LOS_ERRNO_QUEUE_READ_PTR_NULL;
}
tmpQueueCB = GET_QUEUE_HANDLE(queueID);
if ((GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) || (tmpQueueCB->queueID != queueID)) {
return LOS_ERRNO_QUEUE_INVALID;
}
*queueCB = tmpQueueCB;
return LOS_OK;
}
STATIC INLINE struct mqarray *GetMqueueCBByName(const CHAR *name)
{
UINT32 index;
UINT32 mylen = strlen(name);
for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {
if ((g_queueTable[index].mq_name == NULL) || (strlen(g_queueTable[index].mq_name) != mylen)) {
continue;
}
if (strncmp(name, (const CHAR *)(g_queueTable[index].mq_name), mylen) == 0) {
return &(g_queueTable[index]);
}
}
return NULL;
}
STATIC INT32 DoMqueueDelete(struct mqarray *mqueueCB)
{
UINT32 ret;
if (mqueueCB->mq_name != NULL) {
LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name);
mqueueCB->mq_name = NULL;
}
mqueueCB->mqcb = NULL;
ret = LOS_QueueDelete(mqueueCB->mq_id);
switch (ret) {
case LOS_OK:
return 0;
case LOS_ERRNO_QUEUE_NOT_FOUND:
case LOS_ERRNO_QUEUE_NOT_CREATE:
case LOS_ERRNO_QUEUE_IN_TSKUSE:
case LOS_ERRNO_QUEUE_IN_TSKWRITE:
errno = EAGAIN;
return -1;
default:
errno = EINVAL;
return -1;
}
}
STATIC int SaveMqueueName(const CHAR *mqName, struct mqarray *mqueueCB)
{
size_t nameLen;
nameLen = strlen(mqName); /* sys_mq_open has checked name and name length */
mqueueCB->mq_name = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, nameLen + 1);
if (mqueueCB->mq_name == NULL) {
errno = ENOMEM;
return LOS_NOK;
}
if (strncpy_s(mqueueCB->mq_name, (nameLen + 1), mqName, nameLen) != EOK) {
LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name);
mqueueCB->mq_name = NULL;
errno = EINVAL;
return LOS_NOK;
}
mqueueCB->mq_name[nameLen] = '\0';
return LOS_OK;
}
STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR *mqName, INT32 openFlag)
{
struct mqarray *mqueueCB = NULL;
UINT32 mqueueID;
UINT32 err = LOS_QueueCreate(NULL, attr->mq_maxmsg, &mqueueID, 0, attr->mq_msgsize);
if (MapMqErrno(err) != ENOERR) {
goto ERROUT;
}
if (g_queueTable[GET_QUEUE_INDEX(mqueueID)].mqcb == NULL) {
mqueueCB = &(g_queueTable[GET_QUEUE_INDEX(mqueueID)]);
mqueueCB->mq_id = mqueueID;
}
if (mqueueCB == NULL) {
errno = EINVAL;
goto ERROUT;
}
if (SaveMqueueName(mqName, mqueueCB) != LOS_OK) {
goto ERROUT;
}
if (GetMqueueCBByID(mqueueCB->mq_id, &(mqueueCB->mqcb)) != LOS_OK) {
errno = ENOSPC;
goto ERROUT;
}
mqueueCB->mq_personal = (struct mqpersonal *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct mqpersonal));
if (mqueueCB->mq_personal == NULL) {
(VOID)LOS_QueueDelete(mqueueCB->mq_id);
mqueueCB->mqcb->queue = NULL;
mqueueCB->mqcb = NULL;
errno = ENOSPC;
goto ERROUT;
}
mqueueCB->unlinkflag = FALSE;
mqueueCB->mq_personal->mq_status = MQ_USE_MAGIC;
mqueueCB->mq_personal->mq_next = NULL;
mqueueCB->mq_personal->mq_posixdes = mqueueCB;
mqueueCB->mq_personal->mq_flags = (INT32)((UINT32)openFlag | ((UINT32)attr->mq_flags & (UINT32)FNONBLOCK));
return mqueueCB->mq_personal;
ERROUT:
if ((mqueueCB != NULL) && (mqueueCB->mq_name != NULL)) {
LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name);
mqueueCB->mq_name = NULL;
}
return (struct mqpersonal *)-1;
}
STATIC struct mqpersonal *DoMqueueOpen(struct mqarray *mqueueCB, INT32 openFlag)
{
struct mqpersonal *privateMqPersonal = NULL;
/* already have the same name of g_squeuetable */
if (mqueueCB->unlinkflag == TRUE) {
errno = EINVAL;
goto ERROUT;
}
/* alloc mqprivate and add to mqarray */
privateMqPersonal = (struct mqpersonal *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct mqpersonal));
if (privateMqPersonal == NULL) {
errno = ENOSPC;
goto ERROUT;
}
privateMqPersonal->mq_next = mqueueCB->mq_personal;
mqueueCB->mq_personal = privateMqPersonal;
privateMqPersonal->mq_posixdes = mqueueCB;
privateMqPersonal->mq_flags = openFlag;
privateMqPersonal->mq_status = MQ_USE_MAGIC;
return privateMqPersonal;
ERROUT:
return (struct mqpersonal *)-1;
}
mqd_t mq_open(const char *mqName, int openFlag, ...)
{
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = (struct mqpersonal *)-1;
struct mq_attr *attr = NULL;
struct mq_attr defaultAttr = { 0, MQ_MAX_MSG_NUM, MQ_MAX_MSG_LEN, 0, {0} };
va_list ap;
if (MqNameCheck(mqName) == -1) {
return (mqd_t)-1;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
mqueueCB = GetMqueueCBByName(mqName);
if ((UINT32)openFlag & (UINT32)O_CREAT) {
if (mqueueCB != NULL) {
if (((UINT32)openFlag & (UINT32)O_EXCL)) {
errno = EEXIST;
goto OUT;
}
privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag);
} else {
va_start(ap, openFlag);
(VOID)va_arg(ap, int);
attr = va_arg(ap, struct mq_attr *);
va_end(ap);
if (attr != NULL) {
(VOID)memcpy_s(&defaultAttr, sizeof(struct mq_attr), attr, sizeof(struct mq_attr));
if ((defaultAttr.mq_maxmsg < 0) || (defaultAttr.mq_maxmsg > (long int)USHRT_MAX) ||
(defaultAttr.mq_msgsize < 0) || (defaultAttr.mq_msgsize > (long int)(USHRT_MAX - sizeof(UINT32)))) {
errno = EINVAL;
goto OUT;
}
}
privateMqPersonal = DoMqueueCreate(&defaultAttr, mqName, openFlag);
}
} else {
if (mqueueCB == NULL) {
errno = ENOENT;
goto OUT;
}
privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag);
}
OUT:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return (mqd_t)privateMqPersonal;
}
int mq_close(mqd_t personal)
{
INT32 ret = 0;
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
struct mqpersonal *tmp = NULL;
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
goto OUT_UNLOCK;
}
mqueueCB = privateMqPersonal->mq_posixdes;
if (mqueueCB->mq_personal == NULL) {
errno = EBADF;
goto OUT_UNLOCK;
}
/* find the personal and remove */
if (mqueueCB->mq_personal == privateMqPersonal) {
mqueueCB->mq_personal = privateMqPersonal->mq_next;
} else {
for (tmp = mqueueCB->mq_personal; tmp->mq_next != NULL; tmp = tmp->mq_next) {
if (tmp->mq_next == privateMqPersonal) {
break;
}
}
if (tmp->mq_next == NULL) {
errno = EBADF;
goto OUT_UNLOCK;
}
tmp->mq_next = privateMqPersonal->mq_next;
}
/* flag no use */
privateMqPersonal->mq_status = 0;
/* free the personal */
ret = LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal);
if (ret != LOS_OK) {
errno = EFAULT;
ret = -1;
goto OUT_UNLOCK;
}
if ((mqueueCB->unlinkflag == TRUE) && (mqueueCB->mq_personal == NULL)) {
ret = DoMqueueDelete(mqueueCB);
}
OUT_UNLOCK:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return ret;
}
int OsMqGetAttr(mqd_t personal, struct mq_attr *mqAttr)
{
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
if (mqAttr == NULL) {
errno = EINVAL;
return -1;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return -1;
}
mqueueCB = privateMqPersonal->mq_posixdes;
mqAttr->mq_maxmsg = mqueueCB->mqcb->queueLen;
mqAttr->mq_msgsize = mqueueCB->mqcb->queueSize - sizeof(UINT32);
mqAttr->mq_curmsgs = mqueueCB->mqcb->readWriteableCnt[OS_QUEUE_READ];
mqAttr->mq_flags = privateMqPersonal->mq_flags;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return 0;
}
int OsMqSetAttr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *mqOldAttr)
{
struct mqpersonal *privateMqPersonal = NULL;
if (mqSetAttr == NULL) {
errno = EINVAL;
return -1;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return -1;
}
if (mqOldAttr != NULL) {
(VOID)OsMqGetAttr((mqd_t)privateMqPersonal, mqOldAttr);
}
privateMqPersonal->mq_flags = (INT32)((UINT32)privateMqPersonal->mq_flags & (UINT32)(~FNONBLOCK)); /* clear */
if (((UINT32)mqSetAttr->mq_flags & (UINT32)FNONBLOCK) == (UINT32)FNONBLOCK) {
privateMqPersonal->mq_flags = (INT32)((UINT32)privateMqPersonal->mq_flags | (UINT32)FNONBLOCK);
}
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return 0;
}
int mq_getsetattr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
{
if (new == NULL) {
return OsMqGetAttr(mqd, old);
}
return OsMqSetAttr(mqd, new, old);
}
int mq_getattr(mqd_t mqd, struct mq_attr *attr)
{
return mq_getsetattr(mqd, 0, attr);
}
int mq_setattr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
{
return mq_getsetattr(mqd, new, old);
}
int mq_unlink(const char *mqName)
{
INT32 ret = 0;
struct mqarray *mqueueCB = NULL;
if (MqNameCheck(mqName) == -1) {
return -1;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
mqueueCB = GetMqueueCBByName(mqName);
if (mqueueCB == NULL) {
errno = ENOENT;
goto ERROUT_UNLOCK;
}
if (mqueueCB->mq_personal != NULL) {
mqueueCB->unlinkflag = TRUE;
} else {
ret = DoMqueueDelete(mqueueCB);
}
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return ret;
ERROUT_UNLOCK:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return -1;
}
STATIC INT32 ConvertTimeout(long flags, const struct timespec *absTimeout, UINT64 *ticks)
{
if ((UINT32)flags & (UINT32)FNONBLOCK) {
*ticks = LOS_NO_WAIT;
return 0;
}
if (absTimeout == NULL) {
*ticks = LOS_WAIT_FOREVER;
return 0;
}
if (!ValidTimeSpec(absTimeout)) {
errno = EINVAL;
return -1;
}
*ticks = OsTimeSpec2Tick(absTimeout);
return 0;
}
STATIC INLINE BOOL MqParamCheck(mqd_t personal, const char *msg, size_t msgLen)
{
(void)personal;
if ((msg == NULL) || (msgLen == 0)) {
errno = EINVAL;
return FALSE;
}
return TRUE;
}
#define OS_MQ_GOTO_ERROUT_UNLOCK_IF(expr, errcode) \
if (expr) { \
errno = errcode; \
goto ERROUT_UNLOCK; \
}
#define OS_MQ_GOTO_ERROUT_IF(expr, errcode) \
if (expr) { \
errno = errcode; \
goto ERROUT; \
}
int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio,
const struct timespec *absTimeout)
{
UINT32 mqueueID, err;
UINT64 absTicks;
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
OS_MQ_GOTO_ERROUT_IF(!MqParamCheck(personal, msg, msgLen), errno);
OS_MQ_GOTO_ERROUT_IF(msgPrio > (MQ_PRIO_MAX - 1), EINVAL);
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
OS_MQ_GOTO_ERROUT_UNLOCK_IF(privateMqPersonal->mq_status != MQ_USE_MAGIC, EBADF);
mqueueCB = privateMqPersonal->mq_posixdes;
OS_MQ_GOTO_ERROUT_UNLOCK_IF(msgLen > (size_t)(mqueueCB->mqcb->queueSize - sizeof(UINT32)), EMSGSIZE);
OS_MQ_GOTO_ERROUT_UNLOCK_IF((((UINT32)privateMqPersonal->mq_flags & (UINT32)O_WRONLY) != (UINT32)O_WRONLY) &&
(((UINT32)privateMqPersonal->mq_flags & (UINT32)O_RDWR) != (UINT32)O_RDWR),
EBADF);
OS_MQ_GOTO_ERROUT_UNLOCK_IF(ConvertTimeout(privateMqPersonal->mq_flags, absTimeout, &absTicks) == -1, errno);
mqueueID = mqueueCB->mq_id;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
err = LOS_QueueWriteCopy(mqueueID, (VOID *)msg, (UINT32)msgLen, (UINT32)absTicks);
if (MapMqErrno(err) != ENOERR) {
goto ERROUT;
}
return 0;
ERROUT_UNLOCK:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
ERROUT:
return -1;
}
ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio,
const struct timespec *absTimeout)
{
UINT32 mqueueID, err;
UINT32 receiveLen;
UINT64 absTicks;
struct mqarray *mqueueCB = NULL;
struct mqpersonal *privateMqPersonal = NULL;
if (!MqParamCheck(personal, msg, msgLen)) {
goto ERROUT;
}
if (msgPrio != NULL) {
*msgPrio = 0;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = (struct mqpersonal *)personal;
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
goto ERROUT_UNLOCK;
}
mqueueCB = privateMqPersonal->mq_posixdes;
if (msgLen < (size_t)(mqueueCB->mqcb->queueSize - sizeof(UINT32))) {
errno = EMSGSIZE;
goto ERROUT_UNLOCK;
}
if (((UINT32)privateMqPersonal->mq_flags & (UINT32)O_WRONLY) == (UINT32)O_WRONLY) {
errno = EBADF;
goto ERROUT_UNLOCK;
}
if (ConvertTimeout(privateMqPersonal->mq_flags, absTimeout, &absTicks) == -1) {
goto ERROUT_UNLOCK;
}
receiveLen = msgLen;
mqueueID = mqueueCB->mq_id;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
err = LOS_QueueReadCopy(mqueueID, (VOID *)msg, &receiveLen, (UINT32)absTicks);
if (MapMqErrno(err) == ENOERR) {
return (ssize_t)receiveLen;
} else {
goto ERROUT;
}
ERROUT_UNLOCK:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
ERROUT:
return -1;
}
/* not support the prio */
int mq_send(mqd_t personal, const char *msg_ptr, size_t msg_len, unsigned int msg_prio)
{
return mq_timedsend(personal, msg_ptr, msg_len, msg_prio, NULL);
}
ssize_t mq_receive(mqd_t personal, char *msg_ptr, size_t msg_len, unsigned int *msg_prio)
{
return mq_timedreceive(personal, msg_ptr, msg_len, msg_prio, NULL);
}
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MQUEUE_IMPL_H
#define _MQUEUE_IMPL_H
#define _GNU_SOURCE
#include <mqueue.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <securec.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/select.h>
#include "los_queue.h"
#include "los_memory.h"
#include "los_task.h"
#include "los_compiler.h"
#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail, PointOrNot) \
(((UINT32)(PointOrNot) << 2) | ((UINT32)(HeadOrTail) << 1) | (ReadOrWrite))
#define OS_QUEUE_READ_WRITE_GET(type) ((type) & (0x01))
#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1))
#define OS_QUEUE_READ_TAIL (OS_QUEUE_READ | (OS_QUEUE_TAIL << 1))
#define OS_QUEUE_WRITE_HEAD (OS_QUEUE_WRITE | (OS_QUEUE_HEAD << 1))
#define OS_QUEUE_WRITE_TAIL (OS_QUEUE_WRITE | (OS_QUEUE_TAIL << 1))
#define OS_QUEUE_OPERATE_GET(type) ((type) & (0x03))
#define OS_QUEUE_IS_POINT(type) ((type) & (0x04))
#define OS_QUEUE_IS_READ(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_READ)
#define OS_QUEUE_IS_WRITE(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_WRITE)
#define OS_READWRITE_LEN 2
/**
* @ingroup mqueue
* Maximum number of messages in a message queue
*/
#define MQ_MAX_MSG_NUM 16
/**
* @ingroup mqueue
* Maximum size of a single message in a message queue
*/
#define MQ_MAX_MSG_LEN 64
#define ENOERR 0
/* CONSTANTS */
#define MQ_USE_MAGIC 0x89abcdef
#define MQ_PRIO_MAX 1
#define FNONBLOCK O_NONBLOCK
#define QUEUE_SPLIT_BIT 16
#define SET_QUEUE_ID(count, queueID) (((count) << QUEUE_SPLIT_BIT) | (queueID))
/**
* @ingroup los_queue
* get the queue index
*/
#define GET_QUEUE_INDEX(queueID) ((queueID) & ((1U << QUEUE_SPLIT_BIT) - 1))
/**
* @ingroup los_queue
* get the queue count
*/
#define GET_QUEUE_COUNT(queueID) ((queueID) >> QUEUE_SPLIT_BIT)
/**
* @ingroup los_queue
* Obtain the head node in a queue doubly linked list.
*/
#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE])
#define STATIC static
#define INLINE inline
typedef union send_receive_t {
unsigned oth : 3;
unsigned grp : 6;
unsigned usr : 9;
short data;
} mode_s;
/* TYPE DEFINITIONS */
struct mqarray {
UINT32 mq_id : 31;
UINT32 unlinkflag : 1;
char *mq_name;
UINT32 unlink_ref;
mode_s mode_data; /* mode data of mqueue */
uid_t euid; /* euid of mqueue */
gid_t egid; /* egid of mqueue */
fd_set mq_fdset; /* mqueue sysFd bit map */
LosQueueCB *mqcb;
struct mqpersonal *mq_personal;
};
struct mqpersonal {
struct mqarray *mq_posixdes;
struct mqpersonal *mq_next;
int mq_flags;
int mq_mode; /* Mode of mqueue */
UINT32 mq_status;
UINT32 mq_refcount;
};
#endif
@@ -0,0 +1,234 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pthread.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <securec.h>
#include "los_config.h"
#include "los_task.h"
#define PTHREAD_NAMELEN 16
typedef struct {
void *(*startRoutine)(void *);
void *param;
char name[PTHREAD_NAMELEN];
}PthreadData;
static void *PthreadEntry(UINT32 param)
{
PthreadData *pthreadData = (PthreadData *)(UINTPTR)param;
void *(*startRoutine)(void *) = pthreadData->startRoutine;
void *ret = startRoutine(pthreadData->param);
free(pthreadData);
return ret;
}
static inline int IsPthread(pthread_t thread)
{
return ((UINT32)thread <= LOSCFG_BASE_CORE_TSK_LIMIT) &&
(OS_TCB_FROM_TID((UINT32)thread)->taskEntry == PthreadEntry);
}
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*startRoutine)(void *), void *arg)
{
TSK_INIT_PARAM_S taskInitParam = {0};
PthreadData *pthreadData = NULL;
UINT32 taskID;
if ((thread == NULL) || (startRoutine == NULL)) {
return EINVAL;
}
taskInitParam.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
if (attr) {
if (attr->detachstate == PTHREAD_CREATE_DETACHED) {
return ENOTSUP;
}
if (attr->stackaddr_set) {
return ENOTSUP;
}
if (attr->stacksize_set) {
taskInitParam.uwStackSize = attr->stacksize;
}
taskInitParam.usTaskPrio = (UINT16)attr->schedparam.sched_priority;
}
pthreadData = (PthreadData *)malloc(sizeof(PthreadData));
if (pthreadData == NULL) {
return ENOMEM;
}
pthreadData->startRoutine = startRoutine;
pthreadData->param = arg;
taskInitParam.pcName = pthreadData->name;
taskInitParam.pfnTaskEntry = PthreadEntry;
taskInitParam.uwArg = (UINT32)(UINTPTR)pthreadData;
if (LOS_TaskCreateOnly(&taskID, &taskInitParam) != LOS_OK) {
free(pthreadData);
return EINVAL;
}
/* set pthread default name */
(void)sprintf_s(taskInitParam.pcName, PTHREAD_NAMELEN, "pthread%u", taskID);
(void)LOS_TaskResume(taskID);
*thread = (pthread_t)taskID;
return 0;
}
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)
{
if ((param == NULL) || (param->sched_priority < OS_TASK_PRIORITY_HIGHEST) ||
(param->sched_priority >= OS_TASK_PRIORITY_LOWEST) || !IsPthread(thread)) {
return EINVAL;
}
/* Only support SCHED_RR policy now */
if (policy != SCHED_RR) {
return ENOTSUP;
}
if (LOS_TaskPriSet((UINT32)thread, (UINT16)param->sched_priority) != LOS_OK) {
return EINVAL;
}
return 0;
}
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
{
UINT32 prio;
if ((policy == NULL) || (param == NULL) || !IsPthread(thread)) {
return EINVAL;
}
prio = LOS_TaskPriGet((UINT32)thread);
if (prio == OS_INVALID) {
return EINVAL;
}
*policy = SCHED_RR;
param->sched_priority = prio;
return 0;
}
pthread_t pthread_self(void)
{
return (pthread_t)LOS_CurTaskIDGet();
}
int pthread_cancel(pthread_t thread)
{
if (!IsPthread(thread)) {
return EINVAL;
}
return ENOSYS;
}
int pthread_join(pthread_t thread, void **retval)
{
UINT32 taskStatus;
if (!IsPthread(thread)) {
return EINVAL;
}
if (retval) {
/* retrieve thread exit code is not supported currently */
return ENOTSUP;
}
if (thread == pthread_self()) {
return EDEADLK;
}
while (LOS_TaskStatusGet((UINT32)thread, &taskStatus) == LOS_OK) {
(void)LOS_TaskDelay(10); /* 10: Waiting for the end of thread execution. */
}
return 0;
}
int pthread_detach(pthread_t thread)
{
if (!IsPthread(thread)) {
return EINVAL;
}
return ENOSYS;
}
void pthread_exit(void *retVal)
{
(void)retVal;
LosTaskCB *tcb = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
free((PthreadData *)(UINTPTR)tcb->arg);
(void)LOS_TaskDelete(LOS_CurTaskIDGet());
}
int pthread_setname_np(pthread_t thread, const char *name)
{
char *taskName = LOS_TaskNameGet((UINT32)thread);
if (taskName == NULL || !IsPthread(thread)) {
return EINVAL;
}
if (strnlen(name, PTHREAD_NAMELEN) >= PTHREAD_NAMELEN) {
return ERANGE;
}
(void)strcpy_s(taskName, PTHREAD_NAMELEN, name);
return 0;
}
int pthread_getname_np(pthread_t thread, char *buf, size_t buflen)
{
int ret;
const char *name = LOS_TaskNameGet((UINT32)thread);
if (name == NULL || !IsPthread(thread)) {
return EINVAL;
}
if (buflen > strlen(name)) {
ret = strcpy_s(buf, buflen, name);
if (ret == 0) {
return 0;
}
}
return ERANGE;
}
@@ -0,0 +1,233 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pthread.h"
#include <errno.h>
#include <limits.h>
#include "los_config.h"
int pthread_attr_init(pthread_attr_t *attr)
{
if (attr == NULL) {
return EINVAL;
}
attr->detachstate = PTHREAD_CREATE_JOINABLE;
attr->schedpolicy = SCHED_RR;
attr->schedparam.sched_priority = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;
attr->inheritsched = PTHREAD_INHERIT_SCHED;
attr->scope = PTHREAD_SCOPE_PROCESS;
attr->stackaddr_set = 0;
attr->stackaddr = NULL;
attr->stacksize_set = 1;
attr->stacksize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
return 0;
}
int pthread_attr_destroy(pthread_attr_t *attr)
{
if (attr == NULL) {
return EINVAL;
}
/* Nothing to do here... */
return 0;
}
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachState)
{
if ((attr != NULL) && ((detachState == PTHREAD_CREATE_JOINABLE) || (detachState == PTHREAD_CREATE_DETACHED))) {
attr->detachstate = (UINT32)detachState;
return 0;
}
return EINVAL;
}
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachState)
{
if ((attr == NULL) || (detachState == NULL)) {
return EINVAL;
}
*detachState = (int)attr->detachstate;
return 0;
}
int pthread_attr_setscope(pthread_attr_t *attr, int scope)
{
if (attr == NULL) {
return EINVAL;
}
if (scope == PTHREAD_SCOPE_PROCESS) {
attr->scope = (unsigned int)scope;
return 0;
}
if (scope == PTHREAD_SCOPE_SYSTEM) {
return ENOTSUP;
}
return EINVAL;
}
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
{
if ((attr == NULL) || (scope == NULL)) {
return EINVAL;
}
*scope = (int)attr->scope;
return 0;
}
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
{
if ((attr != NULL) && ((inherit == PTHREAD_INHERIT_SCHED) || (inherit == PTHREAD_EXPLICIT_SCHED))) {
attr->inheritsched = (UINT32)inherit;
return 0;
}
return EINVAL;
}
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
{
if ((attr == NULL) || (inherit == NULL)) {
return EINVAL;
}
*inherit = (int)attr->inheritsched;
return 0;
}
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
if ((attr != NULL) && (policy == SCHED_RR)) {
attr->schedpolicy = SCHED_RR;
return 0;
}
return EINVAL;
}
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
{
if ((attr == NULL) || (policy == NULL)) {
return EINVAL;
}
*policy = (int)attr->schedpolicy;
return 0;
}
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
{
if ((attr == NULL) || (param == NULL)) {
return EINVAL;
} else if ((param->sched_priority < LOS_TASK_PRIORITY_HIGHEST) ||
(param->sched_priority >= LOS_TASK_PRIORITY_LOWEST)) {
return ENOTSUP;
}
attr->schedparam = *param;
return 0;
}
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
{
if ((attr == NULL) || (param == NULL)) {
return EINVAL;
}
*param = attr->schedparam;
return 0;
}
/*
* Set starting address of stack. Whether this is at the start or end of
* the memory block allocated for the stack depends on whether the stack
* grows up or down.
*/
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackAddr)
{
if (attr == NULL) {
return EINVAL;
}
attr->stackaddr_set = 1;
attr->stackaddr = stackAddr;
return 0;
}
int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackAddr)
{
if (((attr != NULL) && (stackAddr != NULL)) && attr->stackaddr_set) {
*stackAddr = attr->stackaddr;
return 0;
}
return EINVAL; /* Stack address not set, return EINVAL. */
}
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stackSize)
{
/* Reject inadequate stack sizes */
if ((attr == NULL) || (stackSize < PTHREAD_STACK_MIN)) {
return EINVAL;
}
attr->stacksize_set = 1;
attr->stacksize = stackSize;
return 0;
}
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stackSize)
{
/* Reject attempts to get a stack size when one has not been set. */
if ((attr == NULL) || (stackSize == NULL) || (!attr->stacksize_set)) {
return EINVAL;
}
*stackSize = attr->stacksize;
return 0;
}
@@ -0,0 +1,288 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "time_internal.h"
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <securec.h>
#include "los_config.h"
#include "los_task.h"
#include <los_swtmr.h>
#include "los_atomic.h"
#include "los_event.h"
typedef struct {
volatile INT32 *realValue;
INT32 value;
UINT32 clearEvent;
} EventCond;
#define INLINE inline
#define BROADCAST_EVENT 1
#define COND_COUNTER_STEP 0x0004U
#define COND_FLAGS_MASK 0x0003U
#define COND_COUNTER_MASK (~COND_FLAGS_MASK)
int pthread_condattr_destroy(pthread_condattr_t *attr)
{
if (attr == NULL) {
return EINVAL;
}
return 0;
}
int pthread_condattr_init(pthread_condattr_t *attr)
{
if (attr == NULL) {
return EINVAL;
}
return 0;
}
STATIC INLINE INT32 CondInitCheck(const pthread_cond_t *cond)
{
if ((cond->event.stEventList.pstPrev == NULL) &&
(cond->event.stEventList.pstNext == NULL)) {
return 1;
}
return 0;
}
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
int ret = ENOERR;
if (cond == NULL) {
return EINVAL;
}
(VOID)attr;
(VOID)LOS_EventInit(&(cond->event));
cond->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
if (cond->mutex == NULL) {
return ENOMEM;
}
(VOID)pthread_mutex_init(cond->mutex, NULL);
cond->value = 0;
(VOID)pthread_mutex_lock(cond->mutex);
cond->count = 0;
(VOID)pthread_mutex_unlock(cond->mutex);
return ret;
}
int pthread_cond_destroy(pthread_cond_t *cond)
{
if (cond == NULL) {
return EINVAL;
}
if (CondInitCheck(cond)) {
return ENOERR;
}
if (LOS_EventDestroy(&cond->event) != LOS_OK) {
return EBUSY;
}
if (pthread_mutex_destroy(cond->mutex) != ENOERR) {
PRINT_ERR("%s mutex destroy fail!\n", __FUNCTION__);
return EINVAL;
}
free(cond->mutex);
cond->mutex = NULL;
return ENOERR;
}
STATIC VOID PthreadCountSub(pthread_cond_t *cond)
{
(VOID)pthread_mutex_lock(cond->mutex);
if (cond->count > 0) {
cond->count--;
}
(VOID)pthread_mutex_unlock(cond->mutex);
}
int pthread_cond_broadcast(pthread_cond_t *cond)
{
int ret = ENOERR;
if (cond == NULL) {
return EINVAL;
}
(VOID)pthread_mutex_lock(cond->mutex);
if (cond->count > 0) {
cond->count = 0;
(VOID)pthread_mutex_unlock(cond->mutex);
(VOID)LOS_EventWrite(&(cond->event), BROADCAST_EVENT);
return ret;
}
(VOID)pthread_mutex_unlock(cond->mutex);
return ret;
}
int pthread_cond_signal(pthread_cond_t *cond)
{
int ret = ENOERR;
if (cond == NULL) {
return EINVAL;
}
(VOID)pthread_mutex_lock(cond->mutex);
if (cond->count > 0) {
cond->count--;
(VOID)pthread_mutex_unlock(cond->mutex);
// This should modify to once.
(VOID)LOS_EventWrite(&(cond->event), BROADCAST_EVENT);
return ret;
}
(VOID)pthread_mutex_unlock(cond->mutex);
return ret;
}
STATIC INT32 ProcessReturnVal(pthread_cond_t *cond, INT32 val)
{
INT32 ret;
switch (val) {
/* 0: event does not occur */
case 0:
case BROADCAST_EVENT:
ret = ENOERR;
break;
case LOS_ERRNO_EVENT_READ_TIMEOUT:
PthreadCountSub(cond);
ret = ETIMEDOUT;
break;
default:
PthreadCountSub(cond);
ret = EINVAL;
break;
}
return ret;
}
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *absTime)
{
UINT32 absTicks;
INT32 ret;
if ((cond == NULL) || (mutex == NULL) || (absTime == NULL)) {
return EINVAL;
}
if (CondInitCheck(cond)) {
ret = pthread_cond_init(cond, NULL);
if (ret != ENOERR) {
return ret;
}
}
(VOID)pthread_mutex_lock(cond->mutex);
cond->count++;
(VOID)pthread_mutex_unlock(cond->mutex);
if ((absTime->tv_sec == 0) && (absTime->tv_nsec == 0)) {
return ETIMEDOUT;
}
if (!ValidTimeSpec(absTime)) {
return EINVAL;
}
absTicks = OsTimeSpec2Tick(absTime);
if (pthread_mutex_unlock(mutex) != ENOERR) {
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
}
ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, absTicks);
if (pthread_mutex_lock(mutex) != ENOERR) {
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
}
ret = ProcessReturnVal(cond, ret);
return ret;
}
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
int ret;
if ((cond == NULL) || (mutex == NULL)) {
return EINVAL;
}
if (CondInitCheck(cond)) {
ret = pthread_cond_init(cond, NULL);
if (ret != ENOERR) {
return ret;
}
}
(VOID)pthread_mutex_lock(cond->mutex);
cond->count++;
(VOID)pthread_mutex_unlock(cond->mutex);
if (pthread_mutex_unlock(mutex) != ENOERR) {
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
}
ret = (INT32)LOS_EventRead(&(cond->event), 0x0f, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
if (pthread_mutex_lock(mutex) != ENOERR) {
PRINT_ERR("%s: %d failed\n", __FUNCTION__, __LINE__);
}
switch (ret) {
/* 0: event does not occur */
case 0:
case BROADCAST_EVENT:
ret = ENOERR;
break;
default:
PthreadCountSub(cond);
ret = EINVAL;
break;
}
return ret;
}
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <pthread.h>
#include <time.h>
#include "los_compiler.h"
#include "los_mux.h"
#include "errno.h"
#define OS_SYS_NS_PER_MSECOND 1000000
#define OS_SYS_NS_PER_SECOND 1000000000
static inline int MapError(UINT32 err)
{
switch (err) {
case LOS_OK:
return 0;
case LOS_ERRNO_MUX_PEND_INTERR:
return EPERM;
case LOS_ERRNO_MUX_PEND_IN_LOCK:
return EDEADLK;
case LOS_ERRNO_MUX_PENDED:
case LOS_ERRNO_MUX_UNAVAILABLE:
return EBUSY;
case LOS_ERRNO_MUX_TIMEOUT:
return ETIMEDOUT;
case LOS_ERRNO_MUX_ALL_BUSY:
return EAGAIN;
case LOS_ERRNO_MUX_INVALID:
default:
return EINVAL;
}
}
/* Initialize mutex. If mutexAttr is NULL, use default attributes. */
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
{
UINT32 muxHandle;
UINT32 ret;
if (mutexAttr != NULL) {
return EOPNOTSUPP;
}
ret = LOS_MuxCreate(&muxHandle);
if (ret != LOS_OK) {
return MapError(ret);
}
mutex->magic = _MUX_MAGIC;
mutex->handle = muxHandle;
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
ret = LOS_MuxDelete(mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
mutex->handle = _MUX_INVALID_HANDLE;
return 0;
}
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *absTimeout)
{
UINT32 ret;
UINT32 timeout;
UINT64 timeoutNs;
struct timespec curTime = {0};
if ((mutex->magic != _MUX_MAGIC) || (absTimeout->tv_nsec < 0) || (absTimeout->tv_nsec >= OS_SYS_NS_PER_SECOND)) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
}
ret = clock_gettime(CLOCK_REALTIME, &curTime);
if (ret != LOS_OK) {
return EINVAL;
}
timeoutNs = (absTimeout->tv_sec - curTime.tv_sec) * OS_SYS_NS_PER_SECOND + (absTimeout->tv_nsec - curTime.tv_nsec);
if (timeoutNs <= 0) {
return ETIMEDOUT;
}
timeout = (timeoutNs + (OS_SYS_NS_PER_MSECOND - 1)) / OS_SYS_NS_PER_MSECOND;
ret = LOS_MuxPend(mutex->handle, timeout);
return MapError(ret);
}
/* Lock mutex, waiting for it if necessary. */
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
}
ret = LOS_MuxPend(mutex->handle, LOS_WAIT_FOREVER);
return MapError(ret);
}
int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
if (mutex->handle == _MUX_INVALID_HANDLE) {
ret = LOS_MuxCreate(&mutex->handle);
if (ret != LOS_OK) {
return MapError(ret);
}
}
ret = LOS_MuxPend(mutex->handle, 0);
return MapError(ret);
}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
UINT32 ret;
if (mutex->magic != _MUX_MAGIC) {
return EINVAL;
}
ret = LOS_MuxPost(mutex->handle);
return MapError(ret);
}
@@ -0,0 +1,206 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <semaphore.h>
#include <errno.h>
#include "los_sem.h"
#include "time_internal.h"
#define _SEM_MAGIC 0xEBCFDEA1
#define s_magic __val[0]
#define s_handle __val[1]
static inline int MapError(UINT32 err)
{
switch (err) {
case LOS_OK:
return 0;
case LOS_ERRNO_SEM_INVALID:
case LOS_ERRNO_SEM_UNAVAILABLE:
return EINVAL;
case LOS_ERRNO_SEM_ALL_BUSY:
return ENOSPC;
case LOS_ERRNO_SEM_OVERFLOW:
return ENOMEM;
case LOS_ERRNO_SEM_PENDED:
return EBUSY;
case LOS_ERRNO_SEM_PEND_IN_LOCK:
return EPERM;
case LOS_ERRNO_SEM_PEND_INTERR:
return EINTR;
case LOS_ERRNO_SEM_TIMEOUT:
return ETIMEDOUT;
default:
return EINVAL;
}
}
int sem_init(sem_t *sem, int shared, unsigned int value)
{
UINT32 semHandle = 0;
UINT32 ret;
(VOID)shared;
if ((sem == NULL) || (value >= OS_SEM_COUNTING_MAX_COUNT)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemCreate(value, &semHandle);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
sem->s_magic = _SEM_MAGIC;
sem->s_handle = (int)semHandle;
return 0;
}
int sem_destroy(sem_t *sem)
{
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemDelete((UINT32)sem->s_handle);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
int sem_wait(sem_t *sem)
{
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemPend((UINT32)sem->s_handle, LOS_WAIT_FOREVER);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
int sem_post(sem_t *sem)
{
UINT32 ret;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemPost((UINT32)sem->s_handle);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
static long long GetTickTimeFromNow(const struct timespec *absTimeSpec)
{
struct timespec tsNow = { 0 };
long long ns;
long long tick;
clock_gettime(CLOCK_REALTIME, &tsNow);
ns = (absTimeSpec->tv_sec - tsNow.tv_sec) * OS_SYS_NS_PER_SECOND + (absTimeSpec->tv_nsec - tsNow.tv_nsec);
/* Round up for ticks */
tick = (ns * LOSCFG_BASE_CORE_TICK_PER_SECOND + (OS_SYS_NS_PER_SECOND - 1)) / OS_SYS_NS_PER_SECOND;
return tick;
}
int sem_timedwait(sem_t *sem, const struct timespec *timeout)
{
UINT32 ret;
long long tickCnt;
if ((sem == NULL) || (sem->s_magic != _SEM_MAGIC)) {
errno = EINVAL;
return -1;
}
if (!ValidTimeSpec(timeout)) {
errno = EINVAL;
return -1;
}
tickCnt = GetTickTimeFromNow(timeout);
if (tickCnt < 0) {
errno = ETIMEDOUT;
return -1;
}
if (tickCnt > LOS_WAIT_FOREVER) {
tickCnt = LOS_WAIT_FOREVER;
}
ret = LOS_SemPend((UINT32)sem->s_handle, (UINT32)tickCnt);
if (ret != LOS_OK) {
errno = MapError(ret);
return -1;
}
return 0;
}
int sem_getvalue(sem_t *sem, int *currVal)
{
UINT32 ret;
if ((sem == NULL) || (currVal == NULL)) {
errno = EINVAL;
return -1;
}
ret = LOS_SemGetValue(sem->s_handle, currVal);
if (ret) {
errno = EINVAL;
return -1;
}
return LOS_OK;
}
@@ -0,0 +1,663 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _GNU_SOURCE
#include <time.h>
#include <sys/time.h>
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include "time_internal.h"
#include "los_debug.h"
#include "los_task.h"
#include "los_swtmr.h"
#include "los_tick.h"
#include "los_context.h"
/* accumulative time delta from discontinuous modify */
STATIC struct timespec g_accDeltaFromSet;
STATIC const UINT16 g_daysInMonth[2][13] = {
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
STATIC const UINT8 g_montbl[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/*
* Time zone information, stored in seconds,
* negative values indicate the east of UTC,
* positive values indicate the west of UTC.
*/
long timezone = -8 * 60 * 60; // defaults to CST: 8 hours east of the Prime Meridian
/* internal shared struct tm object for localtime and gmtime */
static struct tm g_tm;
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
UINT64 nseconds;
UINT64 tick;
UINT32 ret;
const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
if (!ValidTimeSpec(rqtp)) {
errno = EINVAL;
return -1;
}
nseconds = (UINT64)rqtp->tv_sec * OS_SYS_NS_PER_SECOND + rqtp->tv_nsec;
tick = (nseconds + nsPerTick - 1) / nsPerTick; // Round up for ticks
if (tick >= UINT32_MAX) {
errno = EINVAL;
return -1;
}
/* PS: skip the first tick because it is NOT a full tick. */
ret = LOS_TaskDelay(tick ? (UINT32)(tick + 1) : 0);
if (ret == LOS_OK || ret == LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK) {
if (rmtp) {
rmtp->tv_sec = rmtp->tv_nsec = 0;
}
return 0;
}
/* sleep in interrupt context or in task sched lock state */
errno = EPERM;
return -1;
}
int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *restrict timerID)
{
UINT32 ret;
UINT32 swtmrID;
if (!timerID || (clockID != CLOCK_REALTIME)) {
errno = EINVAL;
return -1;
}
if (!evp || evp->sigev_notify != SIGEV_THREAD || evp->sigev_notify_attributes) {
errno = ENOTSUP;
return -1;
}
ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)evp->sigev_notify_function,
&swtmrID, (UINT32)(UINTPTR)evp->sigev_value.sival_ptr
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
, OS_SWTMR_ROUSES_IGNORE, OS_SWTMR_ALIGN_INSENSITIVE
#endif
);
if (ret != LOS_OK) {
errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
return -1;
}
*timerID = (timer_t)(UINTPTR)swtmrID;
return 0;
}
int timer_delete(timer_t timerID)
{
UINT32 swtmrID = (UINT32)(UINTPTR)timerID;
if (LOS_SwtmrDelete(swtmrID) != LOS_OK) {
errno = EINVAL;
return -1;
}
return 0;
}
int timer_settime(timer_t timerID, int flags,
const struct itimerspec *restrict value,
struct itimerspec *restrict oldValue)
{
UINT32 intSave;
UINT32 swtmrID = (UINT32)(UINTPTR)timerID;
SWTMR_CTRL_S *swtmr = NULL;
UINT32 interval, expiry, ret;
if (flags != 0) {
/* flags not supported currently */
errno = ENOSYS;
return -1;
}
if (value == NULL) {
errno = EINVAL;
return -1;
}
if (!ValidTimeSpec(&value->it_value) || !ValidTimeSpec(&value->it_interval)) {
errno = EINVAL;
return -1;
}
expiry = OsTimeSpec2Tick(&value->it_value);
interval = OsTimeSpec2Tick(&value->it_interval);
/* if specified interval, it must be same with expiry due to the limitation of liteos-m */
if (interval && interval != expiry) {
errno = ENOTSUP;
return -1;
}
if (oldValue) {
(VOID)timer_gettime(timerID, oldValue);
}
ret = LOS_SwtmrStop(swtmrID);
if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
errno = EINVAL;
return -1;
}
intSave = LOS_IntLock();
swtmr = OS_SWT_FROM_SID(swtmrID);
swtmr->ucMode = (interval ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE);
swtmr->uwInterval = (interval ? interval : expiry);
LOS_IntRestore(intSave);
if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) {
/*
* 1) when expiry is 0, means timer should be stopped.
* 2) If timer is ticking, stopping timer is already done before.
* 3) If timer is created but not ticking, return 0 as well.
*/
return 0;
}
if (LOS_SwtmrStart(swtmr->usTimerID) != LOS_OK) {
errno = EINVAL;
return -1;
}
return 0;
}
int timer_gettime(timer_t timerID, struct itimerspec *value)
{
UINT32 tick = 0;
SWTMR_CTRL_S *swtmr = NULL;
UINT32 swtmrID = (UINT32)(UINTPTR)timerID;
UINT32 ret;
if (value == NULL) {
errno = EINVAL;
return -1;
}
swtmr = OS_SWT_FROM_SID(swtmrID);
/* get expire time */
ret = LOS_SwtmrTimeGet(swtmr->usTimerID, &tick);
if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
errno = EINVAL;
return -1;
}
OsTick2TimeSpec(&value->it_value, tick);
OsTick2TimeSpec(&value->it_interval, (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ? 0 : swtmr->uwInterval);
return 0;
}
int timer_getoverrun(timer_t timerID)
{
(void)timerID;
errno = ENOSYS;
return -1;
}
STATIC VOID OsGetHwTime(struct timespec *hwTime)
{
UINT64 cycle = LOS_SysCycleGet();
UINT64 nowNsec = (cycle / OS_SYS_CLOCK) * OS_SYS_NS_PER_SECOND +
(cycle % OS_SYS_CLOCK) * OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK;
hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND;
hwTime->tv_nsec = nowNsec % OS_SYS_NS_PER_SECOND;
}
STATIC VOID OsGetRealTime(struct timespec *realTime)
{
UINT32 intSave;
struct timespec hwTime = {0};
OsGetHwTime(&hwTime);
intSave = LOS_IntLock();
realTime->tv_nsec = hwTime.tv_nsec + g_accDeltaFromSet.tv_nsec;
realTime->tv_sec = hwTime.tv_sec + g_accDeltaFromSet.tv_sec + (realTime->tv_nsec >= OS_SYS_NS_PER_SECOND);
realTime->tv_nsec %= OS_SYS_NS_PER_SECOND;
LOS_IntRestore(intSave);
}
STATIC VOID OsSetRealTime(const struct timespec *realTime)
{
UINT32 intSave;
struct timespec hwTime = {0};
OsGetHwTime(&hwTime);
intSave = LOS_IntLock();
g_accDeltaFromSet.tv_nsec = realTime->tv_nsec - hwTime.tv_nsec;
g_accDeltaFromSet.tv_sec = realTime->tv_sec - hwTime.tv_sec - (g_accDeltaFromSet.tv_nsec < 0);
g_accDeltaFromSet.tv_nsec = (g_accDeltaFromSet.tv_nsec + OS_SYS_NS_PER_SECOND) % OS_SYS_NS_PER_SECOND;
LOS_IntRestore(intSave);
}
int clock_settime(clockid_t clockID, const struct timespec *tp)
{
if (!ValidTimeSpec(tp)) {
errno = EINVAL;
return -1;
}
switch (clockID) {
case CLOCK_REALTIME:
/* we only support the realtime clock currently */
OsSetRealTime(tp);
return 0;
case CLOCK_MONOTONIC_COARSE:
case CLOCK_REALTIME_COARSE:
case CLOCK_MONOTONIC_RAW:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
case CLOCK_THREAD_CPUTIME_ID:
errno = ENOTSUP;
return -1;
case CLOCK_MONOTONIC:
default:
errno = EINVAL;
return -1;
}
}
int clock_gettime(clockid_t clockID, struct timespec *tp)
{
if (tp == NULL) {
errno = EINVAL;
return -1;
}
switch (clockID) {
case CLOCK_MONOTONIC_RAW:
case CLOCK_MONOTONIC:
case CLOCK_MONOTONIC_COARSE:
OsGetHwTime(tp);
return 0;
case CLOCK_REALTIME:
case CLOCK_REALTIME_COARSE:
OsGetRealTime(tp);
return 0;
case CLOCK_THREAD_CPUTIME_ID:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
errno = ENOTSUP;
return -1;
default:
errno = EINVAL;
return -1;
}
}
int clock_getres(clockid_t clockID, struct timespec *tp)
{
if (tp == NULL) {
errno = EINVAL;
return -1;
}
switch (clockID) {
case CLOCK_MONOTONIC_RAW:
case CLOCK_MONOTONIC:
case CLOCK_REALTIME:
case CLOCK_MONOTONIC_COARSE:
case CLOCK_REALTIME_COARSE:
tp->tv_nsec = OS_SYS_NS_PER_SECOND / OS_SYS_CLOCK;
tp->tv_sec = 0;
return 0;
case CLOCK_THREAD_CPUTIME_ID:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
errno = ENOTSUP;
return -1;
default:
errno = EINVAL;
return -1;
}
}
int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
{
switch (clk) {
case CLOCK_REALTIME:
if (flags == 0) {
/* we only support the realtime clock currently */
return nanosleep(req, rem);
}
/* fallthrough */
case CLOCK_MONOTONIC_COARSE:
case CLOCK_REALTIME_COARSE:
case CLOCK_MONOTONIC_RAW:
case CLOCK_MONOTONIC:
case CLOCK_PROCESS_CPUTIME_ID:
case CLOCK_BOOTTIME:
case CLOCK_REALTIME_ALARM:
case CLOCK_BOOTTIME_ALARM:
case CLOCK_SGI_CYCLE:
case CLOCK_TAI:
if (flags == 0 || flags == TIMER_ABSTIME) {
return ENOTSUP;
}
/* fallthrough */
case CLOCK_THREAD_CPUTIME_ID:
default:
return EINVAL;
}
}
clock_t clock(void)
{
clock_t clk;
struct timespec hwTime;
OsGetHwTime(&hwTime);
clk = hwTime.tv_sec * CLOCKS_PER_SEC;
clk += hwTime.tv_nsec / (OS_SYS_NS_PER_SECOND / CLOCKS_PER_SEC);
return clk;
}
time_t time(time_t *timer)
{
struct timespec ts;
if (-1 == clock_gettime(CLOCK_REALTIME, &ts)) {
return (time_t)-1;
}
if (timer != NULL) {
*timer = ts.tv_sec;
}
return ts.tv_sec;
}
/*
* Compute the `struct tm' representation of T,
* offset OFFSET seconds east of UTC,
* and store year, yday, mon, mday, wday, hour, min, sec into *TP.
* Return nonzero if successful.
*/
static INT32 ConvertSecs2Utc(time_t t, INT32 offset, struct tm *tp)
{
time_t days;
time_t rem;
time_t year;
time_t month;
time_t yearGuess;
days = t / SECS_PER_DAY;
rem = t % SECS_PER_DAY;
rem += offset;
while (rem < 0) {
rem += SECS_PER_DAY;
--days;
}
while (rem >= SECS_PER_DAY) {
rem -= SECS_PER_DAY;
++days;
}
tp->tm_hour = rem / SECS_PER_HOUR;
rem %= SECS_PER_HOUR;
tp->tm_min = rem / SECS_PER_MIN;
tp->tm_sec = rem % SECS_PER_MIN;
/* January 1, 1970 was a Thursday. */
tp->tm_wday = (BEGIN_WEEKDAY + days) % DAYS_PER_WEEK;
if (tp->tm_wday < 0) {
tp->tm_wday += DAYS_PER_WEEK;
}
year = EPOCH_YEAR;
while ((days < 0) ||
(days >= (IS_LEAP_YEAR (year) ? DAYS_PER_LEAP_YEAR : DAYS_PER_NORMAL_YEAR))) {
/* Guess a corrected year, assuming 365 days per year. */
yearGuess = year + days / DAYS_PER_NORMAL_YEAR - (days % DAYS_PER_NORMAL_YEAR < 0);
/* Adjust days and year to match the guessed year. */
days -= ((yearGuess - year) * DAYS_PER_NORMAL_YEAR +
LEAPS_THRU_END_OF (yearGuess - 1) -
LEAPS_THRU_END_OF (year - 1));
year = yearGuess;
}
tp->tm_year = year - TM_YEAR_BASE;
if (tp->tm_year != year - TM_YEAR_BASE) {
return 0;
}
tp->tm_yday = days;
const UINT16 *daysInMonth = g_daysInMonth[IS_LEAP_YEAR(year)];
/* valid month value is 0-11 */
for (month = 11; days < (long int) daysInMonth[month]; --month) {
continue;
}
days -= daysInMonth[month];
tp->tm_mon = month;
tp->tm_mday = days + 1;
tp->__tm_gmtoff = offset;
tp->__tm_zone = NULL;
tp->tm_isdst = 0;
return 1;
}
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
if ((timep == NULL) || (result == NULL)) {
errno = EFAULT;
return NULL;
}
if (!ConvertSecs2Utc(*timep, 0, result)) {
errno = EINVAL;
return NULL;
}
return result;
}
struct tm *gmtime(const time_t *timer)
{
return gmtime_r(timer, &g_tm);
}
struct tm *localtime_r(const time_t *timep, struct tm *result)
{
if ((timep == NULL) || (result == NULL)) {
errno = EFAULT;
return NULL;
}
if (!ConvertSecs2Utc(*timep, -timezone, result)) {
errno = EINVAL;
return NULL;
}
return result;
}
struct tm *localtime(const time_t *timer)
{
return localtime_r(timer, &g_tm);
}
static time_t ConvertUtc2Secs(struct tm *tm)
{
time_t seconds = 0;
INT32 month = 0;
UINT8 leap = 0;
INT32 year = (EPOCH_YEAR - TM_YEAR_BASE);
while (year < tm->tm_year) {
seconds += SECS_PER_NORMAL_YEAR;
if (IS_LEAP_YEAR(year + TM_YEAR_BASE)) {
seconds += SECS_PER_DAY;
}
year++;
}
if (IS_LEAP_YEAR(tm->tm_year + TM_YEAR_BASE)) {
leap = 1;
}
while (month < tm->tm_mon) {
if ((month == 1) && leap) {
seconds += (g_montbl[month] + 1) * SECS_PER_DAY;
} else {
seconds += g_montbl[month] * SECS_PER_DAY;
}
month++;
}
seconds += (tm->tm_mday - 1) * SECS_PER_DAY;
seconds += tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MIN + tm->tm_sec;
seconds -= tm->__tm_gmtoff; // sub time zone to get UTC time
return seconds;
}
time_t mktime(struct tm *tmptr)
{
time_t timeInSeconds;
if (tmptr == NULL) {
errno = EFAULT;
return (time_t)-1;
}
/* tm_isdst is not supported and is ignored */
if (tmptr->tm_year < (EPOCH_YEAR - TM_YEAR_BASE) ||
tmptr->__tm_gmtoff > (-TIME_ZONE_MIN * SECS_PER_MIN) ||
tmptr->__tm_gmtoff < (-TIME_ZONE_MAX * SECS_PER_MIN) ||
tmptr->tm_sec > 60 || tmptr->tm_sec < 0 || /* Seconds [0-60] */
tmptr->tm_min > 59 || tmptr->tm_min < 0 || /* Minutes [0-59] */
tmptr->tm_hour > 23 || tmptr->tm_hour < 0 || /* Hours [0-23] */
tmptr->tm_mday > 31 || tmptr->tm_mday < 1 || /* Day of the month [1-31] */
tmptr->tm_mon > 11 || tmptr->tm_mon < 0) { /* Month [0-11] */
errno = EOVERFLOW;
return (time_t)-1;
}
timeInSeconds = ConvertUtc2Secs(tmptr);
/* normalize tm_wday and tm_yday */
ConvertSecs2Utc(timeInSeconds, tmptr->__tm_gmtoff, tmptr);
return timeInSeconds;
}
int gettimeofday(struct timeval *tv, void *ptz)
{
struct timespec ts;
struct timezone *tz = (struct timezone *)ptz;
if (tv != NULL) {
if (-1 == clock_gettime(CLOCK_REALTIME, &ts)) {
return -1;
}
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / OS_SYS_NS_PER_US;
}
if (tz != NULL) {
tz->tz_minuteswest = timezone / SECS_PER_MIN;
tz->tz_dsttime = 0;
}
return 0;
}
int settimeofday(const struct timeval *tv, const struct timezone *tz)
{
struct timespec ts;
INT32 rtcTimeZone = timezone;
if (tv == NULL) {
errno = EFAULT;
return -1;
}
if (tz != NULL) {
if ((tz->tz_minuteswest >= TIME_ZONE_MIN) &&
(tz->tz_minuteswest <= TIME_ZONE_MAX)) {
rtcTimeZone = tz->tz_minuteswest * SECS_PER_MIN;
} else {
errno = EINVAL;
return -1;
}
}
if (tv->tv_usec >= OS_SYS_US_PER_SECOND) {
errno = EINVAL;
return -1;
}
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US;
if (-1 == clock_settime(CLOCK_REALTIME, &ts)) {
return -1;
}
timezone = rtcTimeZone;
return 0;
}
int usleep(unsigned useconds)
{
struct timespec specTime = { 0 };
UINT64 nanoseconds = (UINT64)useconds * OS_SYS_NS_PER_US;
specTime.tv_sec = (time_t)(nanoseconds / OS_SYS_NS_PER_SECOND);
specTime.tv_nsec = (long)(nanoseconds % OS_SYS_NS_PER_SECOND);
return nanosleep(&specTime, NULL);
}
unsigned sleep(unsigned seconds)
{
struct timespec specTime = { 0 };
UINT64 nanoseconds = (UINT64)seconds * OS_SYS_NS_PER_SECOND;
specTime.tv_sec = (time_t)(nanoseconds / OS_SYS_NS_PER_SECOND);
specTime.tv_nsec = (long)(nanoseconds % OS_SYS_NS_PER_SECOND);
return nanosleep(&specTime, NULL);
}
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TIME_IMPL_H
#define _TIME_IMPL_H
#include <time.h>
#include <sys/time.h>
#include <stdint.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include "los_debug.h"
#include "los_task.h"
#include "los_swtmr.h"
#include "los_timer.h"
#include "los_context.h"
#include "los_compiler.h"
#define OS_SYS_NS_PER_US 1000
#define OS_SYS_NS_PER_SECOND 1000000000
#define OS_SYS_US_PER_SECOND 1000000
#define OS_SYS_MS_PER_SECOND 1000
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define SECS_PER_MIN 60
#define MINS_PER_HOUR 60
#define SECS_PER_HOUR 3600 /* 60 * 60 */
#define SECS_PER_DAY 86400 /* 60 * 60 * 24 */
#define SECS_PER_NORMAL_YEAR 31536000 /* 60 * 60 * 24 * 365 */
#define DAYS_PER_WEEK 7
#define DAYS_PER_NORMAL_YEAR 365
#define DAYS_PER_LEAP_YEAR 366
#define BEGIN_WEEKDAY 4
#define TIME_ZONE_MAX 720 /* UTC-12:00 , the last time zone */
#define TIME_ZONE_MIN (-840) /* UTC+14:00 , the first time zone */
/*
* Nonzero if YEAR is a leap year (every 4 years,
* except every 100th isn't, and every 400th is).
*/
#ifndef IS_LEAP_YEAR
#define IS_LEAP_YEAR(year) \
(((year) % 4 == 0) && (((year) % 100 != 0) || ((year) % 400 == 0)))
#endif
#define DIV(a, b) (((a) / (b)) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
/* internal functions */
STATIC INLINE BOOL ValidTimeSpec(const struct timespec *tp)
{
/* Fail a NULL pointer */
if (tp == NULL) {
return FALSE;
}
/* Fail illegal nanosecond values */
if ((tp->tv_nsec < 0) || (tp->tv_nsec >= OS_SYS_NS_PER_SECOND) || (tp->tv_sec < 0)) {
return FALSE;
}
return TRUE;
}
STATIC INLINE UINT32 OsTimeSpec2Tick(const struct timespec *tp)
{
UINT64 tick, ns;
ns = (UINT64)tp->tv_sec * OS_SYS_NS_PER_SECOND + tp->tv_nsec;
/* Round up for ticks */
tick = (ns * LOSCFG_BASE_CORE_TICK_PER_SECOND + (OS_SYS_NS_PER_SECOND - 1)) / OS_SYS_NS_PER_SECOND;
if (tick > LOS_WAIT_FOREVER) {
tick = LOS_WAIT_FOREVER;
}
return (UINT32)tick;
}
STATIC INLINE VOID OsTick2TimeSpec(struct timespec *tp, UINT32 tick)
{
UINT64 ns = ((UINT64)tick * OS_SYS_NS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND;
tp->tv_sec = (time_t)(ns / OS_SYS_NS_PER_SECOND);
tp->tv_nsec = (long)(ns % OS_SYS_NS_PER_SECOND);
}
#endif
@@ -0,0 +1,70 @@
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("kernel") {
sources = [
"src/los_event.c",
"src/los_init.c",
"src/los_mux.c",
"src/los_queue.c",
"src/los_sem.c",
"src/los_swtmr.c",
"src/los_task.c",
"src/los_tick.c",
"src/los_sched.c",
"src/los_sortlink.c",
"src/mm/los_membox.c",
"src/mm/los_memory.c",
]
include_dirs = [
"include",
"arch/include",
"../components/cpup",
"../components/exchook",
"../components/backtrace",
"../components/power",
"../utils",
"//third_party/bounds_checking_function/include",
]
if ("$board_cpu" == "cortex-m3") {
deps = [ "arch/arm/cortex-m3/gcc/:arch" ]
} else if ("$board_cpu" == "cortex-m4") {
deps = [ "arch/arm/cortex-m4/gcc/:arch" ]
} else if ("$board_cpu" == "cortex-m7") {
deps = [ "arch/arm/cortex-m7/gcc/:arch" ]
} else if ("$board_cpu" == "cortex-m33") {
deps = [ "arch/arm/cortex-m33/gcc/:arch" ]
} else if ("$board_cpu" == "") {
if ("$board_arch" == "rv32imac" || "$board_arch" == "rv32imafdc") {
deps = [ "arch/risc-v/riscv32/gcc:arch" ]
}
}
}
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_ARCH_H
#define _LOS_ARCH_H
#include "los_config.h"
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
VOID HalArchInit(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_ARCH_H */
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_ATOMIC_H
#define _LOS_ATOMIC_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_ATOMIC_H */
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @defgroup los_context hardware
* @ingroup kernel
*/
#ifndef _LOS_CONTEXT_H
#define _LOS_CONTEXT_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_context
* @brief: Task stack initialization.
*
* @par Description:
* This API is used to initialize the task stack.
*
* @attention:
* <ul><li>None.</li></ul>
*
* @param taskID [IN] Type#UINT32: TaskID.
* @param stackSize [IN] Type#UINT32: Total size of the stack.
* @param topStack [IN] Type#VOID *: Top of task's stack.
*
* @retval: context Type#TaskContext *.
* @par Dependency:
* <ul><li>los_context.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack);
/**
* @ingroup los_context
* @brief: Function to sys exit.
*
* @par Description:
* This API is used to sys exit.
*
* @attention:
* <ul><li>None.</li></ul>
*
* @param None.
*
* @retval: None.
* @par Dependency:
* <ul><li>los_context.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
LITE_OS_SEC_TEXT_MINOR NORETURN VOID HalSysExit(VOID);
/**
* @ingroup los_context
* @brief: Task scheduling Function.
*
* @par Description:
* This API is used to scheduling task.
*
* @attention:
* <ul><li>None.</li></ul>
*
* @param None.
*
* @retval: None.
* @par Dependency:
* <ul><li>los_context.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern VOID HalTaskSchedule(VOID);
typedef VOID (*OS_TICK_HANDLER)(VOID);
UINT32 HalStartSchedule(OS_TICK_HANDLER handler);
UINT32 HalIntLock(VOID);
#define LOS_IntLock HalIntLock
VOID HalIntRestore(UINT32 intSave);
#define LOS_IntRestore HalIntRestore
UINT32 HalIntUnLock(VOID);
#define LOS_IntUnLock HalIntUnLock
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_CONTEXT_H */
@@ -0,0 +1,146 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_INTERRUPT_H
#define _LOS_INTERRUPT_H
#include "los_config.h"
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* *
* @ingroup los_interrupt
* Configuration item for interrupt with argument
*/
#ifndef OS_HWI_WITH_ARG
#define OS_HWI_WITH_ARG 0
#endif
typedef UINT32 HWI_HANDLE_T;
typedef UINT16 HWI_PRIOR_T;
typedef UINT16 HWI_MODE_T;
typedef UINT32 HWI_ARG_T;
#if (OS_HWI_WITH_ARG == 1)
typedef VOID (*HWI_PROC_FUNC)(VOID *parm);
#else
typedef VOID (*HWI_PROC_FUNC)(void);
#endif
/* stack protector */
extern UINT32 __stack_chk_guard;
extern VOID __stack_chk_fail(VOID);
VOID HalIntEnter(VOID);
VOID HalIntExit(VOID);
UINT32 HalIsIntActive(VOID);
#define OS_INT_ACTIVE (HalIsIntActive())
#define OS_INT_INACTIVE (!(OS_INT_ACTIVE))
#define LOS_HwiCreate HalHwiCreate
#define LOS_HwiDelete HalHwiDelete
/**
* @ingroup los_interrupt
* @brief Delete hardware interrupt.
*
* @par Description:
* This API is used to delete hardware interrupt.
*
* @attention
* <ul>
* <li>The hardware interrupt module is usable only when the configuration item for hardware interrupt tailoring is enabled.</li>
* <li>Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. The value range applicable for a Cortex-A7 platform is [32,95].</li>
* <li>OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.</li>
* <li>Before executing an interrupt on a platform, refer to the chip manual of the platform.</li>
* </ul>
*
* @param hwiNum [IN] Type#HWI_HANDLE_T: hardware interrupt number. The value range applicable for a Cortex-A7 platform is [32,95].
*
* @retval #OS_ERRNO_HWI_NUM_INVALID 0x02000900: Invalid interrupt number.
* @retval #LOS_OK 0 : The interrupt is successfully delete.
* @par Dependency:
* <ul><li>los_interrupt.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum);
/**
* @ingroup los_interrupt
* @brief Create a hardware interrupt.
*
* @par Description:
* This API is used to configure a hardware interrupt and register a hardware interrupt handling function.
*
* @attention
* <ul>
* <li>The hardware interrupt module is usable only when the configuration item for hardware interrupt tailoring is enabled.</li>
* <li>Hardware interrupt number value range: [OS_USER_HWI_MIN,OS_USER_HWI_MAX]. The value range applicable for a Cortex-A7 platform is [32,95].</li>
* <li>OS_HWI_MAX_NUM specifies the maximum number of interrupts that can be created.</li>
* <li>Before executing an interrupt on a platform, refer to the chip manual of the platform.</li>
* </ul>
*
* @param hwiNum [IN] Type#HWI_HANDLE_T: hardware interrupt number. The value range applicable for a Cortex-A7 platform is [32,95].
* @param hwiPrio [IN] Type#HWI_PRIOR_T: hardware interrupt priority. Ignore this parameter temporarily.
* @param mode [IN] Type#HWI_MODE_T: hardware interrupt mode. Ignore this parameter temporarily.
* @param handler [IN] Type#HWI_PROC_FUNC: interrupt handler used when a hardware interrupt is triggered.
* @param arg [IN] Type#HWI_ARG_T: input parameter of the interrupt handler used when a hardware interrupt is triggered.
*
* @retval #OS_ERRNO_HWI_PROC_FUNC_NULL 0x02000901: Null hardware interrupt handling function.
* @retval #OS_ERRNO_HWI_NUM_INVALID 0x02000900: Invalid interrupt number.
* @retval #OS_ERRNO_HWI_NO_MEMORY 0x02000903: Insufficient memory for hardware interrupt creation.
* @retval #OS_ERRNO_HWI_ALREADY_CREATED 0x02000904: The interrupt handler being created has already been created.
* @retval #LOS_OK 0 : The interrupt is successfully created.
* @par Dependency:
* <ul><li>los_interrupt.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
extern UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum,
HWI_PRIOR_T hwiPrio,
HWI_MODE_T mode,
HWI_PROC_FUNC handler,
HWI_ARG_T arg);
VOID HalDisplayTaskInfo(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_INTERRUPT_H */
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @defgroup memory protection
* @ingroup kernel
*/
#ifndef _LOS_MPU_H
#define _LOS_MPU_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
typedef enum {
MPU_RW_BY_PRIVILEGED_ONLY = 0,
MPU_RW_ANY = 1,
MPU_RO_BY_PRIVILEGED_ONLY = 2,
MPU_RO_ANY = 3,
} MpuAccessPermission;
typedef enum {
MPU_EXECUTABLE = 0,
MPU_NON_EXECUTABLE = 1,
} MpuExecutable;
typedef enum {
MPU_NO_SHARE = 0,
MPU_SHARE = 1,
} MpuShareability;
typedef enum {
MPU_MEM_ON_CHIP_ROM = 0,
MPU_MEM_ON_CHIP_RAM = 1,
MPU_MEM_XIP_PSRAM = 2,
MPU_MEM_XIP_NOR_FLASH = 3,
MPU_MEM_SHARE_MEM = 4,
} MpuMemType;
typedef struct {
UINT32 baseAddr;
UINT64 size; /* armv7 size == 2^x (5 <= x <= 32) 128B - 4GB */
MpuAccessPermission permission;
MpuExecutable executable;
MpuShareability shareability;
MpuMemType memType;
} MPU_CFG_PARA;
VOID HalMpuEnable(UINT32 defaultRegionEnable);
VOID HalMpuDisable();
UINT32 HalMpuSetRegion(UINT32 regionId, MPU_CFG_PARA *para);
UINT32 HalMpuDisableRegion(UINT32 regionId);
INT32 HalMpuUnusedRegionGet(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_MPU_H */
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_TIMER_H
#define _LOS_TIMER_H
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define TICK_CHECK 0x4000000
#define CYCLE_CHECK 0xFFFFFFFFU
#define SHIFT_32_BIT 32
#define MAX_HOUR 24
#define MAX_MINUTES 60
#define MAX_SECONDS 60
#define MILSEC 1000
#define RTC_WAKEUPCLOCK_RTCCLK 32768
#define RTC_WAKEUPCLOCK_RTCCLK_DIV 16
#define RTC_CALIBRATE_SLEEP_TIME 8
#define MACHINE_CYCLE_DEALAY_TIMES (LOSCFG_BASE_CORE_TICK_PER_SECOND << 2)
VOID HalTickLock(VOID);
VOID HalTickUnlock(VOID);
UINT32 HalEnterSleep(VOID);
/**
* @ingroup los_timer
* @brief Get systick cycle.
*
* @par Description:
* This API is used to get systick cycle and return current tick period.
*
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param: period [OUT] current tick period.
*
* @retval current tick count.
*
* @par Dependency:
* <ul><li>los_timer.h: the header file that contains the API declaration.</li></ul>
* @see
*/
UINT64 HalGetTickCycle(UINT32 *period);
/**
* @ingroup los_timer
* @brief reconfig systick, and clear SysTick_IRQn.
*
* @par Description:
* <ul>
* <li>This API is used to reconfig systick, and clear SysTick_IRQn.</li>
* </ul>
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param nextResponseTime [IN] tick period
*
* @retval None.
* @par Dependency:
* <ul><li>los_timer.h: the header file that contains the API declaration.</li></ul>
* @see None
*/
extern VOID HalSysTickReload(UINT64 nextResponseTime);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_TIMER_H */
@@ -0,0 +1,129 @@
/*
* Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_ARCH_CONTEXT_H
#define _LOS_ARCH_CONTEXT_H
#include "los_compiler.h"
#include "los_context.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//#define ARCH_RISCV_FPU
/**
* @ingroup los_hw
*/
typedef unsigned long STACK_TYPE;
typedef struct {
STACK_TYPE epc; /* epc - epc - program counter */
STACK_TYPE ra; /* x1 - ra - return address for jumps */
STACK_TYPE t0; /* x5 - t0 - temporary register 0 */
STACK_TYPE t1; /* x6 - t1 - temporary register 1 */
STACK_TYPE t2; /* x7 - t2 - temporary register 2 */
STACK_TYPE s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */
STACK_TYPE s1; /* x9 - s1 - saved register 1 */
STACK_TYPE a0; /* x10 - a0 - return value or function argument 0 */
STACK_TYPE a1; /* x11 - a1 - return value or function argument 1 */
STACK_TYPE a2; /* x12 - a2 - function argument 2 */
STACK_TYPE a3; /* x13 - a3 - function argument 3 */
STACK_TYPE a4; /* x14 - a4 - function argument 4 */
STACK_TYPE a5; /* x15 - a5 - function argument 5 */
#ifndef __riscv_32e
STACK_TYPE a6; /* x16 - a6 - function argument 6 */
STACK_TYPE a7; /* x17 - s7 - function argument 7 */
STACK_TYPE s2; /* x18 - s2 - saved register 2 */
STACK_TYPE s3; /* x19 - s3 - saved register 3 */
STACK_TYPE s4; /* x20 - s4 - saved register 4 */
STACK_TYPE s5; /* x21 - s5 - saved register 5 */
STACK_TYPE s6; /* x22 - s6 - saved register 6 */
STACK_TYPE s7; /* x23 - s7 - saved register 7 */
STACK_TYPE s8; /* x24 - s8 - saved register 8 */
STACK_TYPE s9; /* x25 - s9 - saved register 9 */
STACK_TYPE s10; /* x26 - s10 - saved register 10 */
STACK_TYPE s11; /* x27 - s11 - saved register 11 */
STACK_TYPE t3; /* x28 - t3 - temporary register 3 */
STACK_TYPE t4; /* x29 - t4 - temporary register 4 */
STACK_TYPE t5; /* x30 - t5 - temporary register 5 */
STACK_TYPE t6; /* x31 - t6 - temporary register 6 */
#endif
STACK_TYPE mstatus; /* - machine status register */
#ifdef ARCH_RISCV_FPU
STACK_TYPE f0;
STACK_TYPE f1;
STACK_TYPE f2;
STACK_TYPE f3;
STACK_TYPE f4;
STACK_TYPE f5;
STACK_TYPE f6;
STACK_TYPE f7;
STACK_TYPE f8;
STACK_TYPE f9;
STACK_TYPE f10;
STACK_TYPE f11;
STACK_TYPE f12;
STACK_TYPE f13;
STACK_TYPE f14;
STACK_TYPE f15;
STACK_TYPE f16;
STACK_TYPE f17;
STACK_TYPE f18;
STACK_TYPE f19;
STACK_TYPE f20;
STACK_TYPE f21;
STACK_TYPE f22;
STACK_TYPE f23;
STACK_TYPE f24;
STACK_TYPE f25;
STACK_TYPE f26;
STACK_TYPE f27;
STACK_TYPE f28;
STACK_TYPE f29;
STACK_TYPE f30;
STACK_TYPE f31;
#endif
} TaskContext;
extern VOID HalStartToRun(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_HW_H */
@@ -0,0 +1,207 @@
/*
* Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_HWI_H
#define _LOS_HWI_H
#include "ch32v20x.h"
#include "los_compiler.h"
#include "los_config.h"
#include "los_interrupt.h"
#include "los_arch_context.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_hwi
* Count of Nuclei system interrupt vector.
*/
#define SOC_INT_MAX 103
#define OS_RISCV_SYS_VECTOR_CNT 16
/**
* @ingroup los_hwi
* Count of Nuclei interrupt vector maxium, which is configurable.
*/
#define OS_RISCV_CUSTOM_IRQ_VECTOR_CNT SOC_INT_MAX
/**
* @ingroup los_hwi
* Count of Nuclei interrupt vector.
*/
#define OS_RISCV_VECTOR_CNT (OS_RISCV_SYS_VECTOR_CNT + OS_RISCV_CUSTOM_IRQ_VECTOR_CNT)
/**
* Maximum number of supported hardware devices that generate hardware interrupts.
*/
#define OS_HWI_MAX_NUM (OS_RISCV_VECTOR_CNT-1)
extern VOID HalHwiDefaultHandler(VOID);
/**
* @ingroup los_hwi
* Hardware interrupt error code: Invalid interrupt number.
*
* Value: 0x02000900
*
* Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable
* for a risc-v platform is [0, OS_RISCV_VECTOR_CNT].
*/
#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00)
/**
* @ingroup los_hwi
* Hardware interrupt error code: Null hardware interrupt handling function.
*
* Value: 0x02000901
*
* Solution: Pass in a valid non-null hardware interrupt handling function.
*/
#define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01)
/**
* @ingroup los_hwi
* Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation.
*
* Value: 0x02000902
*
* Solution: Increase the configured maximum number of supported hardware interrupts.
*/
#define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02)
/**
* @ingroup los_hwi
* Hardware interrupt error code: Insufficient memory for hardware interrupt initialization.
*
* Value: 0x02000903
*
* Solution: Expand the configured memory.
*/
#define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03)
/**
* @ingroup los_hwi
* Hardware interrupt error code: The interrupt has already been created.
*
* Value: 0x02000904
*
* Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
*/
#define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04)
/**
* @ingroup los_hwi
* Hardware interrupt error code: Invalid interrupt priority.
*
* Value: 0x02000905
*
* Solution: Ensure that the interrupt priority is valid.
*/
#define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05)
/**
* @ingroup los_hwi
* Hardware interrupt error code: Incorrect interrupt creation mode.
*
* Value: 0x02000906
*
* Solution: The interrupt creation mode can be only set to ECLIC_NON_VECTOR_INTERRUPT or ECLIC_VECTOR_INTERRUPT of which the
* value can be 0 or 1.
*/
#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06)
/**
* @ingroup los_hwi
* Hardware interrupt error code: The interrupt has already been created as a fast interrupt.
*
* Value: 0x02000907
*
* Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
*/
#define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07)
/**
* @ingroup los_hwi
* Hardware interrupt error code: The API is called during an interrupt, which is forbidden.
*
* Value: 0x02000908
*
* * Solution: Do not call the API during an interrupt.
*/
#define OS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08)
/**
* @ingroup los_hwi
* Hardware interrupt error code:the hwi support SHARED error.
*
* Value: 0x02000909
*
* * Solution:check the input params hwiMode and irqParam of HalHwiCreate or HalHwiDelete whether adapt the current
* hwi.
*/
#define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09)
/**
* @ingroup los_hwi
* Hardware interrupt error code:Invalid interrupt Arg.
*
* Value: 0x0200090a
*
* * Solution:check the interrupt Arg, Arg should only be ECLIC_LEVEL_TRIGGER, ECLIC_POSTIVE_EDGE_TRIGGER or
* ECLIC_NEGTIVE_EDGE_TRIGGER.
*/
#define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a)
/**
* @ingroup los_hwi
* Hardware interrupt error code:The interrupt corresponded to the hwi number or devid has not been created.
*
* Value: 0x0200090b
*
* * Solution:check the hwi number or devid, make sure the hwi number or devid need to delete.
*/
#define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b)
extern UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp);
extern VOID DisplayTaskInfo(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_HWI_H */
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_ARCH_TIMER_H
#define _LOS_ARCH_TIMER_H
#include "los_config.h"
#include "los_compiler.h"
#include "los_context.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
UINT32 HalTickStart(OS_TICK_HANDLER handler);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_ARCH_TIMER_H */
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2021 Nuclei 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
*
* 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.
*/
#include "los_task.h"
#include "los_memory.h"
#include "los_timer.h"
#include "los_sched.h"
#include "los_interrupt.h"
#include "ch32v20x.h"
#include "los_arch_context.h"
#include "los_arch_interrupt.h"
#include "los_arch_timer.h"
#include "riscv_bits.h"
#include "riscv_encoding.h"
extern VOID HalHwiInit(VOID);
#define INITIAL_MSTATUS 0x1880 //( MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL)
#define ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
LITE_OS_SEC_TEXT_INIT VOID HalArchInit(VOID)
{
HalHwiInit();
}
LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID)
{
HalIntLock();
while (1) {
}
}
LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack)
{
UINT32 index;
UINT8 *stk = 0;
TaskContext *context = NULL;
/* initialize the task stack, write magic num to stack top */
*((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD;
stk = ((UINT8 *)topStack) + stackSize + sizeof(STACK_TYPE);
stk = (UINT8 *)ALIGN_DOWN((uintptr_t)stk, REGBYTES);
context = (TaskContext *)(stk - sizeof(TaskContext));
for (index = 1; index < sizeof(TaskContext)/ sizeof(STACK_TYPE); index ++) {
((STACK_TYPE *)context)[index] = OS_TASK_STACK_INIT;
}
context->ra = (STACK_TYPE)HalSysExit;
context->a0 = (STACK_TYPE)taskID;
context->epc = (STACK_TYPE)OsTaskEntry;
context->mstatus = INITIAL_MSTATUS;
return (VOID *)context;
}
extern LosTask g_losTask;
LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler)
{
UINT32 ret;
(VOID)LOS_IntLock();
ret = HalTickStart(handler);
if (ret != LOS_OK) {
return ret;
}
OsSchedStart();
HalStartToRun();
return LOS_OK; /* never return */
}
VOID HalTaskSchedule(VOID)
{
// printf("sw\r\n");
NVIC_SetPendingIRQ(Software_IRQn);
}
VOID HalTaskSwitch(VOID)
{
OsSchedTaskSwitch();
/* Set newTask to runTask */
g_losTask.runTask = g_losTask.newTask;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

Some files were not shown because too many files have changed in this diff Show More