mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2025-11-16 12:34:48 +00:00
add SMP, Modules, and more processor/tools releases
This commit is contained in:
238
ports/cortex_a9/ac6/example_build/sample_threadx/.cproject
Normal file
238
ports/cortex_a9/ac6/example_build/sample_threadx/.cproject
Normal file
@@ -0,0 +1,238 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.debug.base.1025296520">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.base.1025296520" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.debug.base.1025296520" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.base.1025296520." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.323848371" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.577788986" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-A9.NoFPU" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.2114828810" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.867254844" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.2012923809" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.323848371.1548806269" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/sample_threadx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.1721512389" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.114782258" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.1761409455" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1798518755" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a9" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.1125361312" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1070893797" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.1927884242" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1498096289" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_generic}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_port}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.904753152" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.664809547" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.924824072" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1069377025" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.1555411179" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.1007894450" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.1820500228" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a9" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.969773893" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="none" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.776520171" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.1333768272" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.429021326" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1024953339" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.88740108" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.entry.1032206829" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="Vectors" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.linker.option.scatter.1463218579" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.linker.libs.402211535" name="User library files" superClass="com.arm.tool.c.linker.libs" useByScannerDiscovery="false" valueType="libs">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/Debug/tx.a}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.linker.v6.option.suppress.1394753016" name="Suppress (--diag_suppress)" superClass="com.arm.tool.linker.v6.option.suppress" useByScannerDiscovery="false" value="L6306W" valueType="string"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.1637267746" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="reset.S|crt0.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.release.base.1700101495">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.release.base.1700101495" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.release.base.1700101495" name="Release" parent="com.arm.eclipse.build.config.v6.exe.release.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.release.base.1700101495." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.exe.release.base.var.arm_compiler_6-6.93780758" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.exe.release.base.var.arm_compiler_6-6">
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.exe.release.base.var.arm_compiler_6-6.93780758.1638782686" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/sample_threadx}/Release" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.387488755" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="false" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.1160612426" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.optlevel.1619513859" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.optlevel.high" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1399251123" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.980720404" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.optlevel.1556967535" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.optlevel.high" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.1952449360" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.623890739" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.892368789" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.2131111372" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="reset.S|crt0.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="sample_threadx.com.arm.eclipse.build.project.v6.exe.836597981" name="Executable"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
</cproject>
|
||||
27
ports/cortex_a9/ac6/example_build/sample_threadx/.project
Normal file
27
ports/cortex_a9/ac6/example_build/sample_threadx/.project
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sample_threadx</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.arm.debug.ds.nature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
|
||||
<configuration id="com.arm.eclipse.build.config.v6.exe.debug.base.1025296520" name="Debug">
|
||||
|
||||
<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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="644718835926971002" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="Arm Compiler 6 Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.c.ac6"/>
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.cpp.ac6"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration id="com.arm.eclipse.build.config.v6.exe.release.base.1700101495" name="Release">
|
||||
|
||||
<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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="660969458915133332" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="Arm Compiler 6 Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.c.ac6"/>
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.cpp.ac6"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.arm.debugger.launcher2">
|
||||
<mapAttribute key="AverageDurationTracker">
|
||||
<mapEntry key="*Fetching Data Model" value="1378150"/>
|
||||
<mapEntry key="*list global low level symbols" value="21564975"/>
|
||||
<mapEntry key="*loading values from target" value="7776688"/>
|
||||
<mapEntry key="*updating expressions" value="27512028"/>
|
||||
<mapEntry key="AddEventObserver" value="4211900"/>
|
||||
<mapEntry key="compute execution mode" value="935450"/>
|
||||
<mapEntry key="continue" value="14592456"/>
|
||||
<mapEntry key="get capabilities" value="253100"/>
|
||||
<mapEntry key="get execution addresss" value="628306"/>
|
||||
<mapEntry key="get source lines" value="1058048"/>
|
||||
<mapEntry key="initialize command help" value="88628650"/>
|
||||
<mapEntry key="interrupt" value="22067168"/>
|
||||
<mapEntry key="list breakpoint options" value="856712"/>
|
||||
<mapEntry key="list breakpoints" value="1006150"/>
|
||||
<mapEntry key="list instruction sets" value="1024400"/>
|
||||
<mapEntry key="list signals" value="6135650"/>
|
||||
<mapEntry key="list watchpoint options" value="3158500"/>
|
||||
<mapEntry key="list watchpoints" value="765800"/>
|
||||
<mapEntry key="loadfile" value="106797550"/>
|
||||
<mapEntry key="set CWD" value="4052800"/>
|
||||
<mapEntry key="set debug-from" value="1734100"/>
|
||||
<mapEntry key="start" value="112610250"/>
|
||||
<mapEntry key="waitForTargetToStop" value="49529750"/>
|
||||
</mapAttribute>
|
||||
<intAttribute key="DEBUG_TAB..RESOURCES.COUNT" value="0"/>
|
||||
<intAttribute key="FILES.CONNECT_TO_GDB_SERVER.RESOURCES.COUNT" value="0"/>
|
||||
<intAttribute key="FILES.DEBUG_EXISTING_ANDROID.RESOURCES.COUNT" value="0"/>
|
||||
<listAttribute key="FILES.DEBUG_RESIDENT_ANDROID"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.DEBUG_RESIDENT_APP"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="APPLICATION_ON_TARGET"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.COUNT" value="2"/>
|
||||
<listAttribute key="FILES.DOWNLOAD_AND_DEBUG"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.TYPE" value="TARGET_DOWNLOAD_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.COUNT" value="3"/>
|
||||
<listAttribute key="FILES.DOWNLOAD_DEBUG"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.TYPE" value="TARGET_DOWNLOAD_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.VALUE" value=""/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
|
||||
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.VALUE" value=""/>
|
||||
<intAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.COUNT" value="3"/>
|
||||
<intAttribute key="FILES.DOWNLOAD_DEBUG_ANDROID.RESOURCES.COUNT" value="0"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.VALUE" value="${workspace_loc:/sample_threadx/Debug/sample_threadx.axf}"/>
|
||||
<intAttribute key="FILES.ICE_DEBUG.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.COUNT" value="1"/>
|
||||
<listAttribute key="FILES.ICE_DEBUG_WITH_TRACE">
|
||||
<listEntry value="ON_DEMAND_LOAD"/>
|
||||
<listEntry value="ALSO_LOAD_SYMBOLS"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
|
||||
<stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.VALUE" value=""/>
|
||||
<intAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.COUNT" value="1"/>
|
||||
<stringAttribute key="FILES.SELECTED_DEBUG_OPEATION" value="ICE_DEBUG"/>
|
||||
<stringAttribute key="HOST_WORKING_DIR" value="${workspace_loc}"/>
|
||||
<booleanAttribute key="HOST_WORKING_DIR_USE_DEFAULT" value="true"/>
|
||||
<booleanAttribute key="KEY_COMMANDS_AFTER_CONNECT" value="false"/>
|
||||
<stringAttribute key="KEY_COMMANDS_AFTER_CONNECT_TEXT" value=""/>
|
||||
<booleanAttribute key="KEY_COMMANDS_AS_CONNECT" value="false"/>
|
||||
<booleanAttribute key="RSE_USE_HOSTNAME" value="true"/>
|
||||
<stringAttribute key="TCP_DISABLE_EXTENDED_MODE" value="true"/>
|
||||
<booleanAttribute key="TCP_KILL_ON_EXIT" value="false"/>
|
||||
<booleanAttribute key="VFS_ENABLED" value="true"/>
|
||||
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
|
||||
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
|
||||
<stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> </breakpoints> "/>
|
||||
<stringAttribute key="config_db_activity_name" value="Debug Cortex-A9"/>
|
||||
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option dtsl_config_script model_params config_file setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
|
||||
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
|
||||
<stringAttribute key="config_db_platform_name" value="Arm FVP (Installed with Arm DS) - VE_Cortex_A9x1"/>
|
||||
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
|
||||
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
|
||||
<stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp_installedwitharmds_/ve_cortex_a9x1"/>
|
||||
<stringAttribute key="config_file" value="CDB://cadi_config.xml"/>
|
||||
<booleanAttribute key="connectOnly" value="false"/>
|
||||
<listAttribute key="debugger.view.ExpressionsView">
|
||||
<listEntry value="thread_0_counter"/>
|
||||
<listEntry value="thread_1_counter"/>
|
||||
<listEntry value="thread_1_messages_sent"/>
|
||||
<listEntry value="thread_2_counter"/>
|
||||
<listEntry value="thread_2_messages_received"/>
|
||||
<listEntry value="thread_3_counter"/>
|
||||
<listEntry value="thread_4_counter"/>
|
||||
<listEntry value="thread_5_counter"/>
|
||||
<listEntry value="thread_6_counter"/>
|
||||
<listEntry value="thread_7_counter"/>
|
||||
</listAttribute>
|
||||
<mapAttribute key="debugger.view.ExpressionsView.ExpressionsData">
|
||||
<mapEntry key="0" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="1" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="2" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="3" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="4" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="5" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="6" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="7" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="8" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
<mapEntry key="9" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	true	200	-1	true	1	false	true	90	-1	true	2	true	true	108	-1	true	3	true	true	57	-1	true	4	true	true	50	-1	true	5	true	true	37	-1	true	6	true	true	91	-1	true	7	true	true	53	-1	true"/>
|
||||
<booleanAttribute key="debugger.view.expression.DrawAsHex" value="false"/>
|
||||
<stringAttribute key="dtsl_config" value="DtslScript"/>
|
||||
<stringAttribute key="dtsl_config_script" value="CDB://dtsl_config_script.py"/>
|
||||
<stringAttribute key="dtsl_options_file" value="default"/>
|
||||
<stringAttribute key="dtsl_tracecapture_option" value="options.traceBuffer.traceCaptureDevice"/>
|
||||
<stringAttribute key="launch_configuration_version" value="2020.0"/>
|
||||
<booleanAttribute key="linuxOS" value="false"/>
|
||||
<stringAttribute key="model_params" value=""/>
|
||||
<booleanAttribute key="runAfterConnect" value="false"/>
|
||||
<listAttribute key="setup">
|
||||
<listEntry value="CDB://../../../Scripts/rtsm_launcher.py"/>
|
||||
<listEntry value="FVP_VE_Cortex-A9x1"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="single_platform" value="true"/>
|
||||
<stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/>
|
||||
<stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,369 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD thread_0;
|
||||
TX_THREAD thread_1;
|
||||
TX_THREAD thread_2;
|
||||
TX_THREAD thread_3;
|
||||
TX_THREAD thread_4;
|
||||
TX_THREAD thread_5;
|
||||
TX_THREAD thread_6;
|
||||
TX_THREAD thread_7;
|
||||
TX_QUEUE queue_0;
|
||||
TX_SEMAPHORE semaphore_0;
|
||||
TX_MUTEX mutex_0;
|
||||
TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
TX_BYTE_POOL byte_pool_0;
|
||||
TX_BLOCK_POOL block_pool_0;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
ULONG thread_0_counter;
|
||||
ULONG thread_1_counter;
|
||||
ULONG thread_1_messages_sent;
|
||||
ULONG thread_2_counter;
|
||||
ULONG thread_2_messages_received;
|
||||
ULONG thread_3_counter;
|
||||
ULONG thread_4_counter;
|
||||
ULONG thread_5_counter;
|
||||
ULONG thread_6_counter;
|
||||
ULONG thread_7_counter;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
CHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create the main thread. */
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
|
||||
/* Allocate the stack for thread 1. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
message queue. It is also interesting to note that these threads have a time
|
||||
slice. */
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 2. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 3. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
An interesting thing here is that both threads share the same instruction area. */
|
||||
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 4. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 6. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 7. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for 10 ticks. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Set event flag 0 to wakeup thread 5. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sends messages to a queue shared by thread 2. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the message sent. */
|
||||
thread_1_messages_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG received_message;
|
||||
UINT status;
|
||||
|
||||
/* This thread retrieves messages placed on the queue by thread 1. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Retrieve a message from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status and make sure the message is what we
|
||||
expected. */
|
||||
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
|
||||
break;
|
||||
|
||||
/* Otherwise, all is okay. Increment the received message count. */
|
||||
thread_2_messages_received++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_3_and_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 3 and thread 4. As the loop
|
||||
below shows, these function compete for ownership of semaphore_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 3)
|
||||
thread_3_counter++;
|
||||
else
|
||||
thread_4_counter++;
|
||||
|
||||
/* Get the semaphore with suspension. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the semaphore. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the semaphore. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_flags;
|
||||
|
||||
|
||||
/* This thread simply waits for an event in a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_6_and_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 6 and thread 7. As the loop
|
||||
below shows, these function compete for ownership of mutex_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 6)
|
||||
thread_6_counter++;
|
||||
else
|
||||
thread_7_counter++;
|
||||
|
||||
/* Get the mutex with suspension. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Get the mutex again with suspension. This shows
|
||||
that an owning thread may retrieve the mutex it
|
||||
owns multiple times. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
;*******************************************************
|
||||
; Copyright (c) 2011-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
; Use, modification and redistribution of this file is subject to your possession of a
|
||||
; valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
; and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
;*******************************************************
|
||||
|
||||
; Scatter-file for Cortex-A9 bare-metal example on Versatile Express
|
||||
|
||||
; This scatter-file places application code, data, stack and heap at suitable addresses in the memory map.
|
||||
|
||||
; Versatile Express with Cortex-A9 has 1GB SDRAM at 0x60000000 to 0x9FFFFFFF, which this scatter-file uses.
|
||||
|
||||
|
||||
SDRAM 0x80000000 0x20000000
|
||||
{
|
||||
VECTORS +0
|
||||
{
|
||||
* (VECTORS, +FIRST) ; Vector table and other (assembler) startup code
|
||||
* (InRoot$$Sections) ; All (library) code that must be in a root region
|
||||
}
|
||||
|
||||
RO_CODE +0
|
||||
{ * (+RO-CODE) } ; Application RO code (.text)
|
||||
|
||||
RO_DATA +0
|
||||
{ * (+RO-DATA) } ; Application RO data (.constdata)
|
||||
|
||||
RW_DATA +0
|
||||
{ * (+RW) } ; Application RW data (.data)
|
||||
|
||||
ZI_DATA +0
|
||||
{ * (+ZI) } ; Application ZI data (.bss)
|
||||
|
||||
ARM_LIB_HEAP 0x80040000 EMPTY 0x00040000 ; Application heap
|
||||
{ }
|
||||
|
||||
ARM_LIB_STACK 0x80090000 EMPTY 0x00010000 ; Application (SVC mode) stack
|
||||
{ }
|
||||
|
||||
;IRQ_STACK 0x800A0000 EMPTY -0x00010000 ; IRQ mode stack
|
||||
;{ }
|
||||
|
||||
TTB 0x80100000 EMPTY 0x4000 ; Level-1 Translation Table for MMU
|
||||
{ }
|
||||
}
|
||||
359
ports/cortex_a9/ac6/example_build/sample_threadx/startup.S
Normal file
359
ports/cortex_a9/ac6/example_build/sample_threadx/startup.S
Normal file
@@ -0,0 +1,359 @@
|
||||
//----------------------------------------------------------------
|
||||
// Cortex-A9 Embedded example - Startup Code
|
||||
//
|
||||
// Copyright (c) 2005-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
|
||||
// Standard definitions of mode bits and interrupt (I & F) flags in PSRs
|
||||
|
||||
#define Mode_USR 0x10
|
||||
#define Mode_FIQ 0x11
|
||||
#define Mode_IRQ 0x12
|
||||
#define Mode_SVC 0x13
|
||||
#define Mode_ABT 0x17
|
||||
#define Mode_UND 0x1B
|
||||
#define Mode_SYS 0x1F
|
||||
|
||||
#define I_Bit 0x80 // When I bit is set, IRQ is disabled
|
||||
#define F_Bit 0x40 // When F bit is set, FIQ is disabled
|
||||
|
||||
|
||||
.section VECTORS, "ax"
|
||||
.align 3
|
||||
.cfi_sections .debug_frame // put stack frame info into .debug_frame instead of .eh_frame
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Entry point for the Reset handler
|
||||
//----------------------------------------------------------------
|
||||
|
||||
.global Vectors
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Exception Vector Table
|
||||
//----------------------------------------------------------------
|
||||
// Note: LDR PC instructions are used here, though branch (B) instructions
|
||||
// could also be used, unless the exception handlers are >32MB away.
|
||||
|
||||
Vectors:
|
||||
LDR PC, Reset_Addr
|
||||
LDR PC, Undefined_Addr
|
||||
LDR PC, SVC_Addr
|
||||
LDR PC, Prefetch_Addr
|
||||
LDR PC, Abort_Addr
|
||||
B . // Reserved vector
|
||||
LDR PC, IRQ_Addr
|
||||
LDR PC, FIQ_Addr
|
||||
|
||||
|
||||
.balign 4
|
||||
Reset_Addr:
|
||||
.word Reset_Handler
|
||||
Undefined_Addr:
|
||||
//.word Undefined_Handler
|
||||
.word __tx_undefined
|
||||
SVC_Addr:
|
||||
//.word SVC_Handler
|
||||
.word __tx_swi_interrupt
|
||||
Prefetch_Addr:
|
||||
//.word Prefetch_Handler
|
||||
.word __tx_prefetch_handler
|
||||
Abort_Addr:
|
||||
//.word Abort_Handler
|
||||
.word __tx_abort_handler
|
||||
IRQ_Addr:
|
||||
//.word IRQ_Handler
|
||||
.word __tx_irq_handler
|
||||
FIQ_Addr:
|
||||
//.word FIQ_Handler
|
||||
.word __tx_fiq_handler
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Exception Handlers
|
||||
//----------------------------------------------------------------
|
||||
|
||||
Undefined_Handler:
|
||||
B Undefined_Handler
|
||||
SVC_Handler:
|
||||
B SVC_Handler
|
||||
Prefetch_Handler:
|
||||
B Prefetch_Handler
|
||||
Abort_Handler:
|
||||
B Abort_Handler
|
||||
IRQ_Handler:
|
||||
B IRQ_Handler
|
||||
FIQ_Handler:
|
||||
B FIQ_Handler
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Reset Handler
|
||||
//----------------------------------------------------------------
|
||||
Reset_Handler:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Disable caches, MMU and branch prediction in case they were left enabled from an earlier run
|
||||
// This does not need to be done from a cold reset
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
BIC r0, r0, #0x1 // Clear M bit 0 to disable MMU
|
||||
BIC r0, r0, #(0x1 << 11) // Clear Z bit 11 to disable branch prediction
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
// The MMU is enabled later, before calling main(). Caches and branch prediction are enabled inside main(),
|
||||
// after the MMU has been enabled and scatterloading has been performed.
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Initialize Supervisor Mode Stack
|
||||
// Note stack must be 8 byte aligned.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR SP, =Image$$ARM_LIB_STACK$$ZI$$Limit
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Invalidate Data and Instruction TLBs and branch predictor
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MOV r0,#0
|
||||
MCR p15, 0, r0, c8, c7, 0 // I-TLB and D-TLB invalidation
|
||||
MCR p15, 0, r0, c7, c5, 6 // BPIALL - Invalidate entire branch predictor array
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Set Vector Base Address Register (VBAR) to point to this application's vector table
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR r0, =Vectors
|
||||
MCR p15, 0, r0, c12, c0, 0
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Cache Invalidation code for Cortex-A9
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Invalidate L1 Instruction Cache
|
||||
|
||||
MRC p15, 1, r0, c0, c0, 1 // Read Cache Level ID Register (CLIDR)
|
||||
TST r0, #0x3 // Harvard Cache?
|
||||
MOV r0, #0 // SBZ
|
||||
MCRNE p15, 0, r0, c7, c5, 0 // ICIALLU - Invalidate instruction cache and flush branch target cache
|
||||
|
||||
// Invalidate Data/Unified Caches
|
||||
|
||||
MRC p15, 1, r0, c0, c0, 1 // Read CLIDR
|
||||
ANDS r3, r0, #0x07000000 // Extract coherency level
|
||||
MOV r3, r3, LSR #23 // Total cache levels << 1
|
||||
BEQ Finished // If 0, no need to clean
|
||||
|
||||
MOV r10, #0 // R10 holds current cache level << 1
|
||||
Loop1:
|
||||
ADD r2, r10, r10, LSR #1 // R2 holds cache "Set" position
|
||||
MOV r1, r0, LSR r2 // Bottom 3 bits are the Cache-type for this level
|
||||
AND r1, r1, #7 // Isolate those lower 3 bits
|
||||
CMP r1, #2
|
||||
BLT Skip // No cache or only instruction cache at this level
|
||||
|
||||
MCR p15, 2, r10, c0, c0, 0 // Write the Cache Size selection register
|
||||
ISB // ISB to sync the change to the CacheSizeID reg
|
||||
MRC p15, 1, r1, c0, c0, 0 // Reads current Cache Size ID register
|
||||
AND r2, r1, #7 // Extract the line length field
|
||||
ADD r2, r2, #4 // Add 4 for the line length offset (log2 16 bytes)
|
||||
LDR r4, =0x3FF
|
||||
ANDS r4, r4, r1, LSR #3 // R4 is the max number on the way size (right aligned)
|
||||
CLZ r5, r4 // R5 is the bit position of the way size increment
|
||||
LDR r7, =0x7FFF
|
||||
ANDS r7, r7, r1, LSR #13 // R7 is the max number of the index size (right aligned)
|
||||
|
||||
Loop2:
|
||||
MOV r9, r4 // R9 working copy of the max way size (right aligned)
|
||||
|
||||
Loop3:
|
||||
ORR r11, r10, r9, LSL r5 // Factor in the Way number and cache number into R11
|
||||
ORR r11, r11, r7, LSL r2 // Factor in the Set number
|
||||
MCR p15, 0, r11, c7, c6, 2 // Invalidate by Set/Way
|
||||
SUBS r9, r9, #1 // Decrement the Way number
|
||||
BGE Loop3
|
||||
SUBS r7, r7, #1 // Decrement the Set number
|
||||
BGE Loop2
|
||||
Skip:
|
||||
ADD r10, r10, #2 // Increment the cache number
|
||||
CMP r3, r10
|
||||
BGT Loop1
|
||||
|
||||
Finished:
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// MMU Configuration
|
||||
// Set translation table base
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// Two translation tables are supported, TTBR0 and TTBR1
|
||||
// Configure translation table base (TTB) control register cp15,c2
|
||||
// to a value of all zeros, indicates we are using TTB register 0.
|
||||
|
||||
MOV r0,#0x0
|
||||
MCR p15, 0, r0, c2, c0, 2
|
||||
|
||||
// write the address of our page table base to TTB register 0
|
||||
LDR r0,=Image$$TTB$$ZI$$Base
|
||||
MOV r1, #0x08 // RGN=b01 (outer cacheable write-back cached, write allocate)
|
||||
// S=0 (translation table walk to non-shared memory)
|
||||
ORR r1,r1,#0x40 // IRGN=b01 (inner cacheability for the translation table walk is Write-back Write-allocate)
|
||||
|
||||
ORR r0,r0,r1
|
||||
MCR p15, 0, r0, c2, c0, 0
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// PAGE TABLE generation
|
||||
|
||||
// Generate the page tables
|
||||
// Build a flat translation table for the whole address space.
|
||||
// ie: Create 4096 1MB sections from 0x000xxxxx to 0xFFFxxxxx
|
||||
|
||||
|
||||
// 31 20 19 18 17 16 15 14 12 11 10 9 8 5 4 3 2 1 0
|
||||
// |section base address| 0 0 |nG| S |AP2| TEX | AP | P | Domain | XN | C B | 1 0|
|
||||
//
|
||||
// Bits[31:20] - Top 12 bits of VA is pointer into table
|
||||
// nG[17]=0 - Non global, enables matching against ASID in the TLB when set.
|
||||
// S[16]=0 - Indicates normal memory is shared when set.
|
||||
// AP2[15]=0
|
||||
// AP[11:10]=11 - Configure for full read/write access in all modes
|
||||
// TEX[14:12]=000
|
||||
// CB[3:2]= 00 - Set attributes to Strongly-ordered memory.
|
||||
// (except for the code segment descriptor, see below)
|
||||
// IMPP[9]=0 - Ignored
|
||||
// Domain[5:8]=1111 - Set all pages to use domain 15
|
||||
// XN[4]=1 - Execute never on Strongly-ordered memory
|
||||
// Bits[1:0]=10 - Indicate entry is a 1MB section
|
||||
//----------------------------------------------------------------
|
||||
LDR r0,=Image$$TTB$$ZI$$Base
|
||||
LDR r1,=0xfff // loop counter
|
||||
LDR r2,=0b00000000000000000000110111100010
|
||||
|
||||
// r0 contains the address of the translation table base
|
||||
// r1 is loop counter
|
||||
// r2 is level1 descriptor (bits 19:0)
|
||||
|
||||
// use loop counter to create 4096 individual table entries.
|
||||
// this writes from address 'Image$$TTB$$ZI$$Base' +
|
||||
// offset 0x3FFC down to offset 0x0 in word steps (4 bytes)
|
||||
|
||||
init_ttb_1:
|
||||
ORR r3, r2, r1, LSL#20 // R3 now contains full level1 descriptor to write
|
||||
ORR r3, r3, #0b0000000010000 // Set XN bit
|
||||
STR r3, [r0, r1, LSL#2] // Str table entry at TTB base + loopcount*4
|
||||
SUBS r1, r1, #1 // Decrement loop counter
|
||||
BPL init_ttb_1
|
||||
|
||||
// In this example, the 1MB section based at '__code_start' is setup specially as cacheable (write back mode).
|
||||
// TEX[14:12]=001 and CB[3:2]= 11, Outer and inner write back, write allocate normal memory.
|
||||
LDR r1,=Image$$VECTORS$$Base // Base physical address of code segment
|
||||
LSR r1, #20 // Shift right to align to 1MB boundaries
|
||||
ORR r3, r2, r1, LSL#20 // Setup the initial level1 descriptor again
|
||||
ORR r3, r3, #0b0000000001100 // Set CB bits
|
||||
ORR r3, r3, #0b1000000000000 // Set TEX bit 12
|
||||
STR r3, [r0, r1, LSL#2] // str table entry
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Setup domain control register - Enable all domains to client mode
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c3, c0, 0 // Read Domain Access Control Register
|
||||
LDR r0, =0x55555555 // Initialize every domain entry to b01 (client)
|
||||
MCR p15, 0, r0, c3, c0, 0 // Write Domain Access Control Register
|
||||
|
||||
#if defined(__ARM_NEON) || defined(__ARM_FP)
|
||||
//----------------------------------------------------------------
|
||||
// Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11.
|
||||
// Enables Full Access i.e. in both privileged and non privileged modes
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 2 // Read Coprocessor Access Control Register (CPACR)
|
||||
ORR r0, r0, #(0xF << 20) // Enable access to CP 10 & 11
|
||||
MCR p15, 0, r0, c1, c0, 2 // Write Coprocessor Access Control Register (CPACR)
|
||||
ISB
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Switch on the VFP and NEON hardware
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MOV r0, #0x40000000
|
||||
VMSR FPEXC, r0 // Write FPEXC register, EN bit set
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable MMU and branch to __main
|
||||
// Leaving the caches disabled until after scatter loading.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
LDR r12,=__main
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
BIC r0, r0, #(0x1 << 12) // Clear I bit 12 to disable I Cache
|
||||
BIC r0, r0, #(0x1 << 2) // Clear C bit 2 to disable D Cache
|
||||
BIC r0, r0, #0x2 // Clear A bit 1 to disable strict alignment fault checking
|
||||
ORR r0, r0, #0x1 // Set M bit 0 to enable MMU before scatter loading
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
// Now the MMU is enabled, virtual to physical address translations will occur. This will affect the next
|
||||
// instruction fetch.
|
||||
//
|
||||
// The two instructions currently in the pipeline will have been fetched before the MMU was enabled.
|
||||
// The branch to __main is safe because the Virtual Address (VA) is the same as the Physical Address (PA)
|
||||
// (flat mapping) of this code that enables the MMU and performs the branch
|
||||
|
||||
BX r12 // Branch to __main C library entry point
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable caches and branch prediction
|
||||
// This code must be run from a privileged mode
|
||||
//----------------------------------------------------------------
|
||||
|
||||
.section ENABLECACHES,"ax"
|
||||
.align 3
|
||||
|
||||
.global enable_caches
|
||||
.type enable_caches, "function"
|
||||
.cfi_startproc
|
||||
enable_caches:
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable caches and branch prediction
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 0 // Read System Control Register
|
||||
ORR r0, r0, #(0x1 << 12) // Set I bit 12 to enable I Cache
|
||||
ORR r0, r0, #(0x1 << 2) // Set C bit 2 to enable D Cache
|
||||
ORR r0, r0, #(0x1 << 11) // Set Z bit 11 to enable branch prediction
|
||||
MCR p15, 0, r0, c1, c0, 0 // Write System Control Register
|
||||
ISB
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Enable L1 D-side prefetch (A9 specific)
|
||||
//----------------------------------------------------------------
|
||||
|
||||
MRC p15, 0, r0, c1, c0, 1 // Read Auxiliary Control Register
|
||||
ORR r0, r0, #(0x1 << 2) // Set DP bit 2 to enable L1 Dside prefetch
|
||||
MCR p15, 0, r0, c1, c0, 1 // Write Auxiliary Control Register
|
||||
ISB
|
||||
|
||||
BX lr
|
||||
.cfi_endproc
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Initialize */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_initialize.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
|
||||
.arm
|
||||
|
||||
SVC_MODE = 0xD3 @ Disable IRQ/FIQ SVC mode
|
||||
IRQ_MODE = 0xD2 @ Disable IRQ/FIQ IRQ mode
|
||||
FIQ_MODE = 0xD1 @ Disable IRQ/FIQ FIQ mode
|
||||
SYS_MODE = 0xDF @ Disable IRQ/FIQ SYS mode
|
||||
FIQ_STACK_SIZE = 512 @ FIQ stack size
|
||||
IRQ_STACK_SIZE = 1024 @ IRQ stack size
|
||||
SYS_STACK_SIZE = 1024 @ System stack size
|
||||
@
|
||||
@
|
||||
.global _tx_thread_system_stack_ptr
|
||||
.global _tx_initialize_unused_memory
|
||||
.global _tx_thread_context_save
|
||||
.global _tx_thread_context_restore
|
||||
.global _tx_timer_interrupt
|
||||
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.global $_tx_initialize_low_level
|
||||
.type $_tx_initialize_low_level,function
|
||||
$_tx_initialize_low_level:
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_initialize_low_level @ Call _tx_initialize_low_level function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_initialize_low_level Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is responsible for any low-level processor */
|
||||
@/* initialization, including setting up interrupt vectors, setting */
|
||||
@/* up a periodic timer interrupt source, saving the system stack */
|
||||
@/* pointer for use in ISR processing later, and finding the first */
|
||||
@/* available RAM memory address for tx_application_define. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_initialize_low_level(VOID)
|
||||
@{
|
||||
.global _tx_initialize_low_level
|
||||
.type _tx_initialize_low_level,function
|
||||
_tx_initialize_low_level:
|
||||
@
|
||||
@ /* We must be in SVC mode at this point! */
|
||||
@
|
||||
@ /* Setup various stack pointers. */
|
||||
@
|
||||
LDR r1, =Image$$ARM_LIB_STACK$$ZI$$Limit @ Get pointer to stack area
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
@
|
||||
@ /* Setup the system mode stack for nested interrupt support */
|
||||
@
|
||||
LDR r2, =SYS_STACK_SIZE @ Pickup stack size
|
||||
MOV r3, #SYS_MODE @ Build SYS mode CPSR
|
||||
MSR CPSR_c, r3 @ Enter SYS mode
|
||||
SUB r1, r1, #1 @ Backup 1 byte
|
||||
BIC r1, r1, #7 @ Ensure 8-byte alignment
|
||||
MOV sp, r1 @ Setup SYS stack pointer
|
||||
SUB r1, r1, r2 @ Calculate start of next stack
|
||||
#endif
|
||||
|
||||
LDR r2, =FIQ_STACK_SIZE @ Pickup stack size
|
||||
MOV r0, #FIQ_MODE @ Build FIQ mode CPSR
|
||||
MSR CPSR, r0 @ Enter FIQ mode
|
||||
SUB r1, r1, #1 @ Backup 1 byte
|
||||
BIC r1, r1, #7 @ Ensure 8-byte alignment
|
||||
MOV sp, r1 @ Setup FIQ stack pointer
|
||||
SUB r1, r1, r2 @ Calculate start of next stack
|
||||
LDR r2, =IRQ_STACK_SIZE @ Pickup IRQ stack size
|
||||
MOV r0, #IRQ_MODE @ Build IRQ mode CPSR
|
||||
MSR CPSR, r0 @ Enter IRQ mode
|
||||
SUB r1, r1, #1 @ Backup 1 byte
|
||||
BIC r1, r1, #7 @ Ensure 8-byte alignment
|
||||
MOV sp, r1 @ Setup IRQ stack pointer
|
||||
SUB r3, r1, r2 @ Calculate end of IRQ stack
|
||||
MOV r0, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR, r0 @ Enter SVC mode
|
||||
LDR r2, =Image$$ARM_LIB_STACK$$Base @ Pickup stack bottom
|
||||
CMP r3, r2 @ Compare the current stack end with the bottom
|
||||
_stack_error_loop:
|
||||
BLT _stack_error_loop @ If the IRQ stack exceeds the stack bottom, just sit here!
|
||||
@
|
||||
@ /* Save the system stack pointer. */
|
||||
@ _tx_thread_system_stack_ptr = (VOID_PTR) (sp);
|
||||
@
|
||||
LDR r2, =_tx_thread_system_stack_ptr @ Pickup stack pointer
|
||||
STR r1, [r2] @ Save the system stack
|
||||
@
|
||||
@ /* Save the first available memory address. */
|
||||
@ _tx_initialize_unused_memory = (VOID_PTR) _end;
|
||||
@
|
||||
LDR r1, =Image$$ZI_DATA$$ZI$$Limit @ Get end of non-initialized RAM area
|
||||
LDR r2, =_tx_initialize_unused_memory @ Pickup unused memory ptr address
|
||||
ADD r1, r1, #8 @ Increment to next free word
|
||||
STR r1, [r2] @ Save first free memory address
|
||||
@
|
||||
@ /* Setup Timer for periodic interrupts. */
|
||||
@
|
||||
@ /* Done, return to caller. */
|
||||
@
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
@
|
||||
@
|
||||
@/* Define shells for each of the interrupt vectors. */
|
||||
@
|
||||
.global __tx_undefined
|
||||
__tx_undefined:
|
||||
B __tx_undefined @ Undefined handler
|
||||
@
|
||||
.global __tx_swi_interrupt
|
||||
__tx_swi_interrupt:
|
||||
B __tx_swi_interrupt @ Software interrupt handler
|
||||
@
|
||||
.global __tx_prefetch_handler
|
||||
__tx_prefetch_handler:
|
||||
B __tx_prefetch_handler @ Prefetch exception handler
|
||||
@
|
||||
.global __tx_abort_handler
|
||||
__tx_abort_handler:
|
||||
B __tx_abort_handler @ Abort exception handler
|
||||
@
|
||||
.global __tx_reserved_handler
|
||||
__tx_reserved_handler:
|
||||
B __tx_reserved_handler @ Reserved exception handler
|
||||
@
|
||||
.global __tx_irq_processing_return
|
||||
.type __tx_irq_processing_return,function
|
||||
.global __tx_irq_handler
|
||||
__tx_irq_handler:
|
||||
@
|
||||
@ /* Jump to context save to save system context. */
|
||||
B _tx_thread_context_save
|
||||
__tx_irq_processing_return:
|
||||
@
|
||||
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. In
|
||||
@ addition, IRQ interrupts may be re-enabled - with certain restrictions -
|
||||
@ if nested IRQ interrupts are desired. Interrupts may be re-enabled over
|
||||
@ small code sequences where lr is saved before enabling interrupts and
|
||||
@ restored after interrupts are again disabled. */
|
||||
@
|
||||
@ /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
|
||||
@ from IRQ mode with interrupts disabled. This routine switches to the
|
||||
@ system mode and returns with IRQ interrupts enabled.
|
||||
@
|
||||
@ NOTE: It is very important to ensure all IRQ interrupts are cleared
|
||||
@ prior to enabling nested IRQ interrupts. */
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
BL _tx_thread_irq_nesting_start
|
||||
#endif
|
||||
@
|
||||
@ /* For debug purpose, execute the timer interrupt processing here. In
|
||||
@ a real system, some kind of status indication would have to be checked
|
||||
@ before the timer interrupt handler could be called. */
|
||||
@
|
||||
BL _tx_timer_interrupt @ Timer interrupt handler
|
||||
@
|
||||
@
|
||||
@ /* If interrupt nesting was started earlier, the end of interrupt nesting
|
||||
@ service must be called before returning to _tx_thread_context_restore.
|
||||
@ This routine returns in processing in IRQ mode with interrupts disabled. */
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
BL _tx_thread_irq_nesting_end
|
||||
#endif
|
||||
@
|
||||
@ /* Jump to context restore to restore system context. */
|
||||
B _tx_thread_context_restore
|
||||
@
|
||||
@
|
||||
@ /* This is an example of a vectored IRQ handler. */
|
||||
@
|
||||
@ .global __tx_example_vectored_irq_handler
|
||||
@__tx_example_vectored_irq_handler:
|
||||
@
|
||||
@
|
||||
@ /* Save initial context and call context save to prepare for
|
||||
@ vectored ISR execution. */
|
||||
@
|
||||
@ STMDB sp!, {r0-r3} @ Save some scratch registers
|
||||
@ MRS r0, SPSR @ Pickup saved SPSR
|
||||
@ SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
@ STMDB sp!, {r0, r10, r12, lr} @ Store other scratch registers
|
||||
@ BL _tx_thread_vectored_context_save @ Vectored context save
|
||||
@
|
||||
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. In
|
||||
@ addition, IRQ interrupts may be re-enabled - with certain restrictions -
|
||||
@ if nested IRQ interrupts are desired. Interrupts may be re-enabled over
|
||||
@ small code sequences where lr is saved before enabling interrupts and
|
||||
@ restored after interrupts are again disabled. */
|
||||
@
|
||||
@
|
||||
@ /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
|
||||
@ from IRQ mode with interrupts disabled. This routine switches to the
|
||||
@ system mode and returns with IRQ interrupts enabled.
|
||||
@
|
||||
@ NOTE: It is very important to ensure all IRQ interrupts are cleared
|
||||
@ prior to enabling nested IRQ interrupts. */
|
||||
@#ifdef TX_ENABLE_IRQ_NESTING
|
||||
@ BL _tx_thread_irq_nesting_start
|
||||
@#endif
|
||||
@
|
||||
@ /* Application IRQ handlers can be called here! */
|
||||
@
|
||||
@ /* If interrupt nesting was started earlier, the end of interrupt nesting
|
||||
@ service must be called before returning to _tx_thread_context_restore.
|
||||
@ This routine returns in processing in IRQ mode with interrupts disabled. */
|
||||
@#ifdef TX_ENABLE_IRQ_NESTING
|
||||
@ BL _tx_thread_irq_nesting_end
|
||||
@#endif
|
||||
@
|
||||
@ /* Jump to context restore to restore system context. */
|
||||
@ B _tx_thread_context_restore
|
||||
@
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
.global __tx_fiq_handler
|
||||
.global __tx_fiq_processing_return
|
||||
__tx_fiq_handler:
|
||||
@
|
||||
@ /* Jump to fiq context save to save system context. */
|
||||
B _tx_thread_fiq_context_save
|
||||
__tx_fiq_processing_return:
|
||||
@
|
||||
@ /* At this point execution is still in the FIQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. */
|
||||
@
|
||||
@ /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start
|
||||
@ from FIQ mode with interrupts disabled. This routine switches to the
|
||||
@ system mode and returns with FIQ interrupts enabled.
|
||||
@
|
||||
@ NOTE: It is very important to ensure all FIQ interrupts are cleared
|
||||
@ prior to enabling nested FIQ interrupts. */
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
BL _tx_thread_fiq_nesting_start
|
||||
#endif
|
||||
@
|
||||
@ /* Application FIQ handlers can be called here! */
|
||||
@
|
||||
@ /* If interrupt nesting was started earlier, the end of interrupt nesting
|
||||
@ service must be called before returning to _tx_thread_fiq_context_restore. */
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
BL _tx_thread_fiq_nesting_end
|
||||
#endif
|
||||
@
|
||||
@ /* Jump to fiq context restore to restore system context. */
|
||||
B _tx_thread_fiq_context_restore
|
||||
@
|
||||
@
|
||||
#else
|
||||
.global __tx_fiq_handler
|
||||
__tx_fiq_handler:
|
||||
B __tx_fiq_handler @ FIQ interrupt handler
|
||||
#endif
|
||||
@
|
||||
@
|
||||
BUILD_OPTIONS:
|
||||
.word _tx_build_options @ Reference to bring in
|
||||
VERSION_ID:
|
||||
.word _tx_version_id @ Reference to bring in
|
||||
|
||||
|
||||
|
||||
212
ports/cortex_a9/ac6/example_build/tx/.cproject
Normal file
212
ports/cortex_a9/ac6/example_build/tx/.cproject
Normal file
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.debug.base.1507005551">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.base.1507005551" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.debug.base.1507005551" name="Debug" parent="com.arm.eclipse.build.config.v6.lib.debug.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.1507005551." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1022814766" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.688166309" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-A9.VFPv3_FP16.Neon" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.floatabi.197203083" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.inst.552700328" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.1623863720" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1022814766.195306460" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/tx}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.1164059605" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.100103692" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.775437314" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.957518664" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a9" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.fpu.1476959906" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="neon-fp16" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.floatabi.2113301488" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.inst.36110020" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1498990421" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_generic}""/>
|
||||
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_port}""/>
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.536480260" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1961882835" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.262825882" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1390685682" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.596919840" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.1155866423" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.1741335442" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-a9" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.fpu.169397194" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="neon-fp16" valueType="string"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.floatabi.1378563076" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.inst.213408634" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.options.debug.level.383141003" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1847017761" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.1124663047" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.1439633481" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.release.base.1262125868">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.release.base.1262125868" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.release.base.1262125868" name="Release" parent="com.arm.eclipse.build.config.v6.lib.release.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.release.base.1262125868." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.lib.release.base.var.arm_compiler_6-6.492969017" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.release.base.var.arm_compiler_6-6">
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.lib.release.base.var.arm_compiler_6-6.492969017.371110606" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/tx}/Release" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.1194834518" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="false" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.1411448201" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.optlevel.1844241431" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.optlevel.high" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1030569593" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.605804138" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.optlevel.1586474276" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.optlevel.high" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.297367297" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.420936661" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.2145383118" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.1866033223" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<project id="tx.com.arm.eclipse.build.project.v6.lib.1408735755" name="Static Library"/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
|
||||
<configuration configurationName="Debug">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/tx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration configurationName="Release">
|
||||
|
||||
<resource resourceType="PROJECT" workspacePath="/tx"/>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
|
||||
</cproject>
|
||||
48
ports/cortex_a9/ac6/example_build/tx/.project
Normal file
48
ports/cortex_a9/ac6/example_build/tx/.project
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tx</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>inc_generic</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/inc</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>inc_port</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/inc</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_generic</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/src</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_port</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/src</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
|
||||
<configuration id="com.arm.eclipse.build.config.v6.lib.debug.base.1507005551" name="Debug">
|
||||
|
||||
<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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="703084510452960996" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="Arm Compiler 6 Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.c.ac6"/>
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.cpp.ac6"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
<configuration id="com.arm.eclipse.build.config.v6.lib.release.base.1262125868" name="Release">
|
||||
|
||||
<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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="660969458915133332" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="Arm Compiler 6 Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.c.ac6"/>
|
||||
|
||||
<language-scope id="com.arm.eclipse.builder.armcc.lang.cpp.ac6"/>
|
||||
|
||||
</provider>
|
||||
|
||||
</extension>
|
||||
|
||||
</configuration>
|
||||
|
||||
</project>
|
||||
323
ports/cortex_a9/ac6/inc/tx_port.h
Normal file
323
ports/cortex_a9/ac6/inc/tx_port.h
Normal file
@@ -0,0 +1,323 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-A9/AC6 */
|
||||
/* 6.0.1 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains data type definitions that make the ThreadX */
|
||||
/* real-time kernel function identically on a variety of different */
|
||||
/* processor architectures. For example, the size or number of bits */
|
||||
/* in an "int" data type vary between microprocessor architectures and */
|
||||
/* even C compilers for the same microprocessor. ThreadX does not */
|
||||
/* directly use native C data types. Instead, ThreadX creates its */
|
||||
/* own special types that can be mapped to actual data types by this */
|
||||
/* file to guarantee consistency in the interface and functionality. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
|
||||
/* Determine if the optional ThreadX user define file should be used. */
|
||||
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* Yes, include the user defines in tx_user.h. The defines in this file may
|
||||
alternately be defined on the command line. */
|
||||
|
||||
#include "tx_user.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define ThreadX basic types for this port. */
|
||||
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
|
||||
/* Define the priority levels for ThreadX. Legal values range
|
||||
from 32 to 1024 and MUST be evenly divisible by 32. */
|
||||
|
||||
#ifndef TX_MAX_PRIORITIES
|
||||
#define TX_MAX_PRIORITIES 32
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
|
||||
thread creation is less than this value, the thread create call will return an error. */
|
||||
|
||||
#ifndef TX_MINIMUM_STACK
|
||||
#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the system timer thread's default stack size and priority. These are only applicable
|
||||
if TX_TIMER_PROCESS_IN_ISR is not defined. */
|
||||
|
||||
#ifndef TX_TIMER_THREAD_STACK_SIZE
|
||||
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
|
||||
#endif
|
||||
|
||||
#ifndef TX_TIMER_THREAD_PRIORITY
|
||||
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define various constants for the ThreadX ARM port. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
|
||||
#else
|
||||
#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */
|
||||
#endif
|
||||
#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */
|
||||
|
||||
|
||||
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
|
||||
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
|
||||
source constants would be:
|
||||
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
|
||||
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TX_TRACE_TIME_SOURCE
|
||||
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
|
||||
#endif
|
||||
#ifndef TX_TRACE_TIME_MASK
|
||||
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the port specific options for the _tx_build_options variable. This variable indicates
|
||||
how the ThreadX library was built. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_FIQ_ENABLED 1
|
||||
#else
|
||||
#define TX_FIQ_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
#define TX_IRQ_NESTING_ENABLED 2
|
||||
#else
|
||||
#define TX_IRQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
#define TX_FIQ_NESTING_ENABLED 4
|
||||
#else
|
||||
#define TX_FIQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED
|
||||
|
||||
|
||||
/* Define the in-line initialization constant so that modules with in-line
|
||||
initialization capabilities can prevent their initialization from being
|
||||
a function call. */
|
||||
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
|
||||
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
|
||||
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
|
||||
define is negated, thereby forcing the stack fill which is necessary for the stack checking
|
||||
logic. */
|
||||
|
||||
#ifdef TX_ENABLE_STACK_CHECKING
|
||||
#undef TX_DISABLE_STACK_FILLING
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the TX_THREAD control block extensions for this port. The main reason
|
||||
for the multiple macros is so that backward compatibility can be maintained with
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#define TX_THREAD_EXTENSION_0
|
||||
#define TX_THREAD_EXTENSION_1
|
||||
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable;
|
||||
#define TX_THREAD_EXTENSION_3
|
||||
|
||||
|
||||
/* Define the port extensions of the remaining ThreadX objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_EXTENSION
|
||||
#define TX_BYTE_POOL_EXTENSION
|
||||
#define TX_EVENT_FLAGS_GROUP_EXTENSION
|
||||
#define TX_MUTEX_EXTENSION
|
||||
#define TX_QUEUE_EXTENSION
|
||||
#define TX_SEMAPHORE_EXTENSION
|
||||
#define TX_TIMER_EXTENSION
|
||||
|
||||
|
||||
/* Define the user extension field of the thread control block. Nothing
|
||||
additional is needed for this port so it is defined as white space. */
|
||||
|
||||
#ifndef TX_THREAD_USER_EXTENSION
|
||||
#define TX_THREAD_USER_EXTENSION
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
|
||||
tx_thread_shell_entry, and tx_thread_terminate. */
|
||||
|
||||
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object creation extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object deletion extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Determine if the ARM architecture has the CLZ instruction. This is available on
|
||||
architectures v5 and above. If available, redefine the macro for calculating the
|
||||
lowest bit set. */
|
||||
|
||||
#if __TARGET_ARCH_ARM > 4
|
||||
|
||||
#ifndef __thumb__
|
||||
|
||||
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
|
||||
asm volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); \
|
||||
b = 31 - b;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define ThreadX interrupt lockout and restore macros for protection on
|
||||
access of critical kernel information. The restore interrupt macro must
|
||||
restore the interrupt posture of the running thread prior to the value
|
||||
present prior to the disable macro. In most cases, the save area macro
|
||||
is used to define a local function save area for the disable and restore
|
||||
macros. */
|
||||
|
||||
#ifdef __thumb__
|
||||
|
||||
unsigned int _tx_thread_interrupt_disable(void);
|
||||
unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
|
||||
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
|
||||
|
||||
#else
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save, tx_temp;
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID if ": "=r" (interrupt_save) );
|
||||
#else
|
||||
#define TX_DISABLE asm volatile (" MRS %0,CPSR; CPSID i ": "=r" (interrupt_save) );
|
||||
#endif
|
||||
|
||||
#define TX_RESTORE asm volatile (" MSR CPSR_c,%0 "::"r" (interrupt_save) );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define VFP extension for the Cortex-A9. Each is assumed to be called in the context of the executing
|
||||
thread. */
|
||||
|
||||
void tx_thread_vfp_enable(void);
|
||||
void tx_thread_vfp_disable(void);
|
||||
|
||||
|
||||
/* Define the interrupt lockout macros for each ThreadX object. */
|
||||
|
||||
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
|
||||
#define TX_BYTE_POOL_DISABLE TX_DISABLE
|
||||
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
|
||||
#define TX_MUTEX_DISABLE TX_DISABLE
|
||||
#define TX_QUEUE_DISABLE TX_DISABLE
|
||||
#define TX_SEMAPHORE_DISABLE TX_DISABLE
|
||||
|
||||
|
||||
/* Define the version ID of ThreadX. This may be utilized by the application. */
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-A9/AC6 Version 6.0.1 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
342
ports/cortex_a9/ac6/readme_threadx.txt
Normal file
342
ports/cortex_a9/ac6/readme_threadx.txt
Normal file
@@ -0,0 +1,342 @@
|
||||
Microsoft's Azure RTOS ThreadX for Cortex-A9
|
||||
|
||||
Using ARM Compiler 6 & DS
|
||||
|
||||
1. Import the ThreadX Projects
|
||||
|
||||
In order to build the ThreadX library and the ThreadX demonstration, first import
|
||||
the 'tx' and 'sample_threadx' projects (located in the "example_build" directory)
|
||||
into your DS workspace.
|
||||
|
||||
|
||||
2. Building the ThreadX run-time Library
|
||||
|
||||
Building the ThreadX library is easy; simply right-click the Eclipse project
|
||||
"tx" and then select the "Build Project" button. You should now observe the compilation
|
||||
and assembly of the ThreadX library. This project build produces the ThreadX
|
||||
library file tx.a.
|
||||
|
||||
|
||||
3. Demonstration System
|
||||
|
||||
The ThreadX demonstration is designed to execute under the DS debugger on the
|
||||
VE_Cortex-A9 Bare Metal simulator.
|
||||
|
||||
Building the demonstration is easy; simply right-click the Eclipse project
|
||||
"sample_threadx" and then select the "Build Project" button. You should now observe
|
||||
the compilation and assembly of the ThreadX demonstration. This project build produces
|
||||
the ThreadX library file sample_threadx.axf. Next, expand the demo ThreadX project folder
|
||||
in the Project Explorer window, right-click on the 'cortex-a9_tx.launch' file, click
|
||||
'Debug As', and then click 'cortex-a9_tx' from the submenu. This will cause the
|
||||
debugger to load the sample_threadx.axf ELF file and run to main. You are now ready
|
||||
to execute the ThreadX demonstration.
|
||||
|
||||
|
||||
4. System Initialization
|
||||
|
||||
The entry point in ThreadX for the Cortex-A9 using ARM tools is at label
|
||||
"Vectors". This is defined within startup.S in the sample_threadx project. In addition,
|
||||
this is where all static and global pre-set C variable initialization processing
|
||||
takes place.
|
||||
|
||||
This is also where initialization of a periodic timer interrupt source should take
|
||||
place.
|
||||
|
||||
In addition, _tx_initialize_low_level defines the first available address
|
||||
for use by the application, which is supplied as the sole input parameter
|
||||
to your application definition function, tx_application_define.
|
||||
|
||||
|
||||
5. Register Usage and Stack Frames
|
||||
|
||||
The AC6 compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch
|
||||
registers for each function. All other registers used by a C function must
|
||||
be preserved by the function. ThreadX takes advantage of this in situations
|
||||
where a context switch happens as a result of making a ThreadX service call
|
||||
(which is itself a C function). In such cases, the saved context of a thread
|
||||
is only the non-scratch registers.
|
||||
|
||||
The following defines the saved context stack frames for context switches
|
||||
that occur as a result of interrupt handling or from thread-level API calls.
|
||||
All suspended threads have one of these two types of stack frames. The top
|
||||
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
|
||||
associated thread control block TX_THREAD.
|
||||
|
||||
|
||||
|
||||
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
|
||||
|
||||
0x00 1 0
|
||||
0x04 CPSR CPSR
|
||||
0x08 r0 (a1) a9 (v1)
|
||||
0x0C r1 (a2) r5 (v2)
|
||||
0x10 r2 (a3) r6 (v3)
|
||||
0x14 r3 (a4) r7 (v4)
|
||||
0x18 a9 (v1) r8 (v5)
|
||||
0x1C r5 (v2) r9 (v6)
|
||||
0x20 r6 (v3) r10 (v7)
|
||||
0x24 r7 (v4) r11 (fp)
|
||||
0x28 r8 (v5) r14 (lr)
|
||||
0x2C r9 (v6)
|
||||
0x30 r10 (v7)
|
||||
0x34 r11 (fp)
|
||||
0x38 r12 (ip)
|
||||
0x3C r14 (lr)
|
||||
0x40 PC
|
||||
|
||||
|
||||
6. Improving Performance
|
||||
|
||||
The distribution version of ThreadX is built without any compiler
|
||||
optimizations. This makes it easy to debug because you can trace or set
|
||||
|
||||
In addition, you can eliminate the ThreadX basic API error checking by
|
||||
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
|
||||
defined.
|
||||
|
||||
|
||||
7. Interrupt Handling
|
||||
|
||||
ThreadX provides complete and high-performance interrupt handling for Cortex-A9
|
||||
targets. There are a certain set of requirements that are defined in the
|
||||
following sub-sections:
|
||||
|
||||
|
||||
7.1 Vector Area
|
||||
|
||||
The Cortex-A9 vectors start at address zero. The demonstration system startup
|
||||
reset.S file contains the vectors and is loaded at address zero. On actual
|
||||
hardware platforms, this area might have to be copied to address 0.
|
||||
|
||||
|
||||
7.2 IRQ ISRs
|
||||
|
||||
ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports
|
||||
nested IRQ interrupts. The following sub-sections define the IRQ capabilities.
|
||||
|
||||
|
||||
7.2.1 Standard IRQ ISRs
|
||||
|
||||
The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ
|
||||
interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following
|
||||
is the default IRQ handler defined in tx_initialize_low_level.S:
|
||||
|
||||
.global __tx_irq_handler
|
||||
.global __tx_irq_processing_return
|
||||
__tx_irq_handler:
|
||||
@
|
||||
@ /* Jump to context save to save system context. */
|
||||
B _tx_thread_context_save @ Jump to the context save
|
||||
__tx_irq_processing_return:
|
||||
@
|
||||
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. Note
|
||||
@ that IRQ interrupts are still disabled upon return from the context
|
||||
@ save function. */
|
||||
@
|
||||
@ /* Application ISR call(s) go here! */
|
||||
@
|
||||
@ /* Jump to context restore to restore system context. */
|
||||
B _tx_thread_context_restore
|
||||
|
||||
|
||||
7.2.2 Vectored IRQ ISRs
|
||||
|
||||
The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified
|
||||
by the particular implementation. The following is an example IRQ handler defined in
|
||||
tx_initialize_low_level.S:
|
||||
|
||||
.global __tx_irq_example_handler
|
||||
__tx_irq_example_handler:
|
||||
@
|
||||
@ /* Call context save to save system context. */
|
||||
|
||||
STMDB sp!, {r0-r3} @ Save some scratch registers
|
||||
MRS r0, SPSR @ Pickup saved SPSR
|
||||
SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
STMDB sp!, {r0, r10, r12, lr} @ Store other scratch registers
|
||||
BL _tx_thread_vectored_context_save @ Call the vectored IRQ context save
|
||||
@
|
||||
@ /* At this point execution is still in the IRQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. Note
|
||||
@ that IRQ interrupts are still disabled upon return from the context
|
||||
@ save function. */
|
||||
@
|
||||
@ /* Application ISR call goes here! */
|
||||
@
|
||||
@ /* Jump to context restore to restore system context. */
|
||||
B _tx_thread_context_restore
|
||||
|
||||
|
||||
7.2.3 Nested IRQ Support
|
||||
|
||||
By default, nested IRQ interrupt support is not enabled. To enable nested
|
||||
IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING
|
||||
defined. With this defined, two new IRQ interrupt management services are
|
||||
available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end.
|
||||
These function should be called between the IRQ context save and restore
|
||||
calls.
|
||||
|
||||
Execution between the calls to _tx_thread_irq_nesting_start and
|
||||
_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved
|
||||
by switching from IRQ mode to SYS mode and enabling IRQ interrupts.
|
||||
The SYS mode stack is used during the SYS mode operation, which was
|
||||
setup in tx_initialize_low_level.S. When nested IRQ interrupts are no
|
||||
longer required, calling the _tx_thread_irq_nesting_end service disables
|
||||
nesting by disabling IRQ interrupts and switching back to IRQ mode in
|
||||
preparation for the IRQ context restore service.
|
||||
|
||||
The following is an example of enabling IRQ nested interrupts in a standard
|
||||
IRQ handler:
|
||||
|
||||
.global __tx_irq_handler
|
||||
.global __tx_irq_processing_return
|
||||
__tx_irq_handler:
|
||||
@
|
||||
@ /* Jump to context save to save system context. */
|
||||
B _tx_thread_context_save
|
||||
__tx_irq_processing_return:
|
||||
@
|
||||
@ /* Enable nested IRQ interrupts. NOTE: Since this service returns
|
||||
@ with IRQ interrupts enabled, all IRQ interrupt sources must be
|
||||
@ cleared prior to calling this service. */
|
||||
BL _tx_thread_irq_nesting_start
|
||||
@
|
||||
@ /* Application ISR call(s) go here! */
|
||||
@
|
||||
@ /* Disable nested IRQ interrupts. The mode is switched back to
|
||||
@ IRQ mode and IRQ interrupts are disable upon return. */
|
||||
BL _tx_thread_irq_nesting_end
|
||||
@
|
||||
@ /* Jump to context restore to restore system context. */
|
||||
B _tx_thread_context_restore
|
||||
|
||||
|
||||
7.3 FIQ Interrupts
|
||||
|
||||
By default, FIQ interrupts are left alone by ThreadX. Of course, this
|
||||
means that the application is fully responsible for enabling the FIQ interrupt
|
||||
and saving/restoring any registers used in the FIQ ISR processing. To globally
|
||||
enable FIQ interrupts, the application should enable FIQ interrupts at the
|
||||
beginning of each thread or before any threads are created in tx_application_define.
|
||||
In addition, the application must ensure that no ThreadX service calls are made
|
||||
from default FIQ ISRs, which is located in tx_initialize_low_level.S.
|
||||
|
||||
|
||||
7.3.1 Managed FIQ Interrupts
|
||||
|
||||
Full ThreadX management of FIQ interrupts is provided if the ThreadX sources
|
||||
are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built
|
||||
this way, the FIQ interrupt handlers are very similar to the IRQ interrupt
|
||||
handlers defined previously. The following is default FIQ handler
|
||||
defined in tx_initialize_low_level.S:
|
||||
|
||||
|
||||
.global __tx_fiq_handler
|
||||
.global __tx_fiq_processing_return
|
||||
__tx_fiq_handler:
|
||||
@
|
||||
@ /* Jump to fiq context save to save system context. */
|
||||
B _tx_thread_fiq_context_save
|
||||
__tx_fiq_processing_return:
|
||||
@
|
||||
@ /* At this point execution is still in the FIQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. */
|
||||
@
|
||||
@ /* Application FIQ handlers can be called here! */
|
||||
@
|
||||
@ /* Jump to fiq context restore to restore system context. */
|
||||
B _tx_thread_fiq_context_restore
|
||||
|
||||
|
||||
7.3.1.1 Nested FIQ Support
|
||||
|
||||
By default, nested FIQ interrupt support is not enabled. To enable nested
|
||||
FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING
|
||||
defined. With this defined, two new FIQ interrupt management services are
|
||||
available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end.
|
||||
These function should be called between the FIQ context save and restore
|
||||
calls.
|
||||
|
||||
Execution between the calls to _tx_thread_fiq_nesting_start and
|
||||
_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved
|
||||
by switching from FIQ mode to SYS mode and enabling FIQ interrupts.
|
||||
The SYS mode stack is used during the SYS mode operation, which was
|
||||
setup in tx_initialize_low_level.S. When nested FIQ interrupts are no longer required,
|
||||
calling the _tx_thread_fiq_nesting_end service disables nesting by disabling
|
||||
FIQ interrupts and switching back to FIQ mode in preparation for the FIQ
|
||||
context restore service.
|
||||
|
||||
The following is an example of enabling FIQ nested interrupts in the
|
||||
typical FIQ handler:
|
||||
|
||||
|
||||
.global __tx_fiq_handler
|
||||
.global __tx_fiq_processing_return
|
||||
__tx_fiq_handler:
|
||||
@
|
||||
@ /* Jump to fiq context save to save system context. */
|
||||
B _tx_thread_fiq_context_save
|
||||
__tx_fiq_processing_return:
|
||||
@
|
||||
@ /* At this point execution is still in the FIQ mode. The CPSR, point of
|
||||
@ interrupt, and all C scratch registers are available for use. */
|
||||
@
|
||||
@ /* Enable nested FIQ interrupts. NOTE: Since this service returns
|
||||
@ with FIQ interrupts enabled, all FIQ interrupt sources must be
|
||||
@ cleared prior to calling this service. */
|
||||
BL _tx_thread_fiq_nesting_start
|
||||
@
|
||||
@ /* Application FIQ handlers can be called here! */
|
||||
@
|
||||
@ /* Disable nested FIQ interrupts. The mode is switched back to
|
||||
@ FIQ mode and FIQ interrupts are disable upon return. */
|
||||
BL _tx_thread_fiq_nesting_end
|
||||
@
|
||||
@ /* Jump to fiq context restore to restore system context. */
|
||||
B _tx_thread_fiq_context_restore
|
||||
|
||||
|
||||
8. ThreadX Timer Interrupt
|
||||
|
||||
ThreadX requires a periodic interrupt source to manage all time-slicing,
|
||||
thread sleeps, timeouts, and application timers. Without such a timer
|
||||
interrupt source, these services are not functional but the remainder of
|
||||
ThreadX will still run.
|
||||
|
||||
To add the timer interrupt processing, simply make a call to
|
||||
_tx_timer_interrupt in the IRQ processing. An example of this can be
|
||||
found in the file tx_initialize_low_level.S for the demonstration system.
|
||||
|
||||
|
||||
9. VFP Support
|
||||
|
||||
By default, VFP support is disabled for each thread. If saving the context of the VFP registers
|
||||
is needed, the following API call must be made from the context of the application thread - before
|
||||
the VFP usage:
|
||||
|
||||
void tx_thread_vfp_enable(void);
|
||||
|
||||
After this API is called in the application, VFP registers will be saved/restored for this thread if it
|
||||
is preempted via an interrupt. All other suspension of the this thread will not require the VFP registers
|
||||
to be saved/restored.
|
||||
|
||||
To disable VFP register context saving, simply call the following API:
|
||||
|
||||
void tx_thread_vfp_disable(void);
|
||||
|
||||
|
||||
10. Revision History
|
||||
|
||||
For generic code revision information, please refer to the readme_threadx_generic.txt
|
||||
file, which is included in your distribution. The following details the revision
|
||||
information associated with this specific port of ThreadX:
|
||||
|
||||
06/30/2020 Initial ThreadX 6.0.1 version for Cortex-A9 using AC6 tools.
|
||||
|
||||
|
||||
Copyright(c) 1996-2020 Microsoft Corporation
|
||||
|
||||
|
||||
https://azure.com/rtos
|
||||
|
||||
256
ports/cortex_a9/ac6/src/tx_thread_context_restore.S
Normal file
256
ports/cortex_a9/ac6/src/tx_thread_context_restore.S
Normal file
@@ -0,0 +1,256 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
.arm
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
SVC_MODE = 0xD3 @ Disable IRQ/FIQ, SVC mode
|
||||
IRQ_MODE = 0xD2 @ Disable IRQ/FIQ, IRQ mode
|
||||
#else
|
||||
SVC_MODE = 0x93 @ Disable IRQ, SVC mode
|
||||
IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
|
||||
#endif
|
||||
@
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_thread_execute_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
.global _tx_thread_preempt_disable
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_context_restore Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function restores the interrupt context if it is processing a */
|
||||
@/* nested interrupt. If not, it returns to the interrupt thread if no */
|
||||
@/* preemption is necessary. Otherwise, if preemption is necessary or */
|
||||
@/* if no thread was running, the function returns to the scheduler. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* _tx_thread_schedule Thread scheduling routine */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs Interrupt Service Routines */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_context_restore(VOID)
|
||||
@{
|
||||
.global _tx_thread_context_restore
|
||||
.type _tx_thread_context_restore,function
|
||||
_tx_thread_context_restore:
|
||||
@
|
||||
@ /* Lockout interrupts. */
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Disable IRQ interrupts
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR exit function to indicate an ISR is complete. */
|
||||
@
|
||||
BL _tx_execution_isr_exit @ Call the ISR exit function
|
||||
#endif
|
||||
@
|
||||
@ /* Determine if interrupts are nested. */
|
||||
@ if (--_tx_thread_system_state)
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
LDR r2, [r3] @ Pickup system state
|
||||
SUB r2, r2, #1 @ Decrement the counter
|
||||
STR r2, [r3] @ Store the counter
|
||||
CMP r2, #0 @ Was this the first interrupt?
|
||||
BEQ __tx_thread_not_nested_restore @ If so, not a nested restore
|
||||
@
|
||||
@ /* Interrupts are nested. */
|
||||
@
|
||||
@ /* Just recover the saved registers and return to the point of
|
||||
@ interrupt. */
|
||||
@
|
||||
LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
|
||||
MSR SPSR_cxsf, r0 @ Put SPSR back
|
||||
LDMIA sp!, {r0-r3} @ Recover r0-r3
|
||||
MOVS pc, lr @ Return to point of interrupt
|
||||
@
|
||||
@ }
|
||||
__tx_thread_not_nested_restore:
|
||||
@
|
||||
@ /* Determine if a thread was interrupted and no preemption is required. */
|
||||
@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|
||||
@ || (_tx_thread_preempt_disable))
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1] @ Pickup actual current thread pointer
|
||||
CMP r0, #0 @ Is it NULL?
|
||||
BEQ __tx_thread_idle_system_restore @ Yes, idle system was interrupted
|
||||
@
|
||||
LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address
|
||||
LDR r2, [r3] @ Pickup actual preempt disable flag
|
||||
CMP r2, #0 @ Is it set?
|
||||
BNE __tx_thread_no_preempt_restore @ Yes, don't preempt this thread
|
||||
LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr
|
||||
LDR r2, [r3] @ Pickup actual execute thread pointer
|
||||
CMP r0, r2 @ Is the same thread highest priority?
|
||||
BNE __tx_thread_preempt_restore @ No, preemption needs to happen
|
||||
@
|
||||
@
|
||||
__tx_thread_no_preempt_restore:
|
||||
@
|
||||
@ /* Restore interrupted thread or ISR. */
|
||||
@
|
||||
@ /* Pickup the saved stack pointer. */
|
||||
@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
|
||||
@
|
||||
@ /* Recover the saved context and return to the point of interrupt. */
|
||||
@
|
||||
LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
|
||||
MSR SPSR_cxsf, r0 @ Put SPSR back
|
||||
LDMIA sp!, {r0-r3} @ Recover r0-r3
|
||||
MOVS pc, lr @ Return to point of interrupt
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
__tx_thread_preempt_restore:
|
||||
@
|
||||
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
|
||||
MOV r1, lr @ Save lr (point of interrupt)
|
||||
MOV r2, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r2 @ Enter SVC mode
|
||||
STR r1, [sp, #-4]! @ Save point of interrupt
|
||||
STMDB sp!, {r4-r12, lr} @ Save upper half of registers
|
||||
MOV r4, r3 @ Save SPSR in r4
|
||||
MOV r2, #IRQ_MODE @ Build IRQ mode CPSR
|
||||
MSR CPSR_c, r2 @ Enter IRQ mode
|
||||
LDMIA sp!, {r0-r3} @ Recover r0-r3
|
||||
MOV r5, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r5 @ Enter SVC mode
|
||||
STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1] @ Pickup current thread pointer
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
LDR r2, [r0, #144] @ Pickup the VFP enabled flag
|
||||
CMP r2, #0 @ Is the VFP enabled?
|
||||
BEQ _tx_skip_irq_vfp_save @ No, skip VFP IRQ save
|
||||
VMRS r2, FPSCR @ Pickup the FPSCR
|
||||
STR r2, [sp, #-4]! @ Save FPSCR
|
||||
VSTMDB sp!, {D16-D31} @ Save D16-D31
|
||||
VSTMDB sp!, {D0-D15} @ Save D0-D15
|
||||
_tx_skip_irq_vfp_save:
|
||||
#endif
|
||||
|
||||
MOV r3, #1 @ Build interrupt stack type
|
||||
STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR
|
||||
STR sp, [r0, #8] @ Save stack pointer in thread control
|
||||
@ block
|
||||
@
|
||||
@ /* Save the remaining time-slice and disable it. */
|
||||
@ if (_tx_timer_time_slice)
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address
|
||||
LDR r2, [r3] @ Pickup time-slice
|
||||
CMP r2, #0 @ Is it active?
|
||||
BEQ __tx_thread_dont_save_ts @ No, don't save it
|
||||
@
|
||||
@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
@ _tx_timer_time_slice = 0;
|
||||
@
|
||||
STR r2, [r0, #24] @ Save thread's time-slice
|
||||
MOV r2, #0 @ Clear value
|
||||
STR r2, [r3] @ Disable global time-slice flag
|
||||
@
|
||||
@ }
|
||||
__tx_thread_dont_save_ts:
|
||||
@
|
||||
@
|
||||
@ /* Clear the current task pointer. */
|
||||
@ _tx_thread_current_ptr = TX_NULL;
|
||||
@
|
||||
MOV r0, #0 @ NULL value
|
||||
STR r0, [r1] @ Clear current thread pointer
|
||||
@
|
||||
@ /* Return to the scheduler. */
|
||||
@ _tx_thread_schedule();
|
||||
@
|
||||
B _tx_thread_schedule @ Return to scheduler
|
||||
@ }
|
||||
@
|
||||
__tx_thread_idle_system_restore:
|
||||
@
|
||||
@ /* Just return back to the scheduler! */
|
||||
@
|
||||
MOV r0, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r0 @ Enter SVC mode
|
||||
B _tx_thread_schedule @ Return to scheduler
|
||||
@}
|
||||
|
||||
|
||||
|
||||
202
ports/cortex_a9/ac6/src/tx_thread_context_save.S
Normal file
202
ports/cortex_a9/ac6/src/tx_thread_context_save.S
Normal file
@@ -0,0 +1,202 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
@
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global __tx_irq_processing_return
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_context_save Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function saves the context of an executing thread in the */
|
||||
@/* beginning of interrupt processing. The function also ensures that */
|
||||
@/* the system stack is used upon return to the calling ISR. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_context_save(VOID)
|
||||
@{
|
||||
.global _tx_thread_context_save
|
||||
.type _tx_thread_context_save,function
|
||||
_tx_thread_context_save:
|
||||
@
|
||||
@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
|
||||
@ out, we are in IRQ mode, and all registers are intact. */
|
||||
@
|
||||
@ /* Check for a nested interrupt condition. */
|
||||
@ if (_tx_thread_system_state++)
|
||||
@ {
|
||||
@
|
||||
STMDB sp!, {r0-r3} @ Save some working registers
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable FIQ interrupts
|
||||
#endif
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
LDR r2, [r3] @ Pickup system state
|
||||
CMP r2, #0 @ Is this the first interrupt?
|
||||
BEQ __tx_thread_not_nested_save @ Yes, not a nested context save
|
||||
@
|
||||
@ /* Nested interrupt condition. */
|
||||
@
|
||||
ADD r2, r2, #1 @ Increment the interrupt counter
|
||||
STR r2, [r3] @ Store it back in the variable
|
||||
@
|
||||
@ /* Save the rest of the scratch registers on the stack and return to the
|
||||
@ calling ISR. */
|
||||
@
|
||||
MRS r0, SPSR @ Pickup saved SPSR
|
||||
SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
STMDB sp!, {r0, r10, r12, lr} @ Store other registers
|
||||
@
|
||||
@ /* Return to the ISR. */
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
B __tx_irq_processing_return @ Continue IRQ processing
|
||||
@
|
||||
__tx_thread_not_nested_save:
|
||||
@ }
|
||||
@
|
||||
@ /* Otherwise, not nested, check to see if a thread was running. */
|
||||
@ else if (_tx_thread_current_ptr)
|
||||
@ {
|
||||
@
|
||||
ADD r2, r2, #1 @ Increment the interrupt counter
|
||||
STR r2, [r3] @ Store it back in the variable
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1] @ Pickup current thread pointer
|
||||
CMP r0, #0 @ Is it NULL?
|
||||
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
|
||||
@ scheduling loop - nothing needs saving!
|
||||
@
|
||||
@ /* Save minimal context of interrupted thread. */
|
||||
@
|
||||
MRS r2, SPSR @ Pickup saved SPSR
|
||||
SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
STMDB sp!, {r2, r10, r12, lr} @ Store other registers
|
||||
@
|
||||
@ /* Save the current stack pointer in the thread's control block. */
|
||||
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
|
||||
@
|
||||
@ /* Switch to the system stack. */
|
||||
@ sp = _tx_thread_system_stack_ptr@
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
B __tx_irq_processing_return @ Continue IRQ processing
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
@
|
||||
__tx_thread_idle_system_save:
|
||||
@
|
||||
@ /* Interrupt occurred in the scheduling loop. */
|
||||
@
|
||||
@ /* Not much to do here, just adjust the stack pointer, and return to IRQ
|
||||
@ processing. */
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
ADD sp, sp, #16 @ Recover saved registers
|
||||
B __tx_irq_processing_return @ Continue IRQ processing
|
||||
@
|
||||
@ }
|
||||
@}
|
||||
|
||||
|
||||
|
||||
259
ports/cortex_a9/ac6/src/tx_thread_fiq_context_restore.S
Normal file
259
ports/cortex_a9/ac6/src/tx_thread_fiq_context_restore.S
Normal file
@@ -0,0 +1,259 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
@
|
||||
SVC_MODE = 0xD3 @ SVC mode
|
||||
FIQ_MODE = 0xD1 @ FIQ mode
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
THUMB_MASK = 0x20 @ Thumb bit mask
|
||||
IRQ_MODE_BITS = 0x12 @ IRQ mode bits
|
||||
@
|
||||
@
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_thread_system_stack_ptr
|
||||
.global _tx_thread_execute_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
.global _tx_thread_preempt_disable
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_context_restore Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function restores the fiq interrupt context when processing a */
|
||||
@/* nested interrupt. If not, it returns to the interrupt thread if no */
|
||||
@/* preemption is necessary. Otherwise, if preemption is necessary or */
|
||||
@/* if no thread was running, the function returns to the scheduler. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* _tx_thread_schedule Thread scheduling routine */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* FIQ ISR Interrupt Service Routines */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_fiq_context_restore(VOID)
|
||||
@{
|
||||
.global _tx_thread_fiq_context_restore
|
||||
.type _tx_thread_fiq_context_restore,function
|
||||
_tx_thread_fiq_context_restore:
|
||||
@
|
||||
@ /* Lockout interrupts. */
|
||||
@
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR exit function to indicate an ISR is complete. */
|
||||
@
|
||||
BL _tx_execution_isr_exit @ Call the ISR exit function
|
||||
#endif
|
||||
@
|
||||
@ /* Determine if interrupts are nested. */
|
||||
@ if (--_tx_thread_system_state)
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
LDR r2, [r3] @ Pickup system state
|
||||
SUB r2, r2, #1 @ Decrement the counter
|
||||
STR r2, [r3] @ Store the counter
|
||||
CMP r2, #0 @ Was this the first interrupt?
|
||||
BEQ __tx_thread_fiq_not_nested_restore @ If so, not a nested restore
|
||||
@
|
||||
@ /* Interrupts are nested. */
|
||||
@
|
||||
@ /* Just recover the saved registers and return to the point of
|
||||
@ interrupt. */
|
||||
@
|
||||
LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
|
||||
MSR SPSR_cxsf, r0 @ Put SPSR back
|
||||
LDMIA sp!, {r0-r3} @ Recover r0-r3
|
||||
MOVS pc, lr @ Return to point of interrupt
|
||||
@
|
||||
@ }
|
||||
__tx_thread_fiq_not_nested_restore:
|
||||
@
|
||||
@ /* Determine if a thread was interrupted and no preemption is required. */
|
||||
@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|
||||
@ || (_tx_thread_preempt_disable))
|
||||
@ {
|
||||
@
|
||||
LDR r1, [sp] @ Pickup the saved SPSR
|
||||
MOV r2, #MODE_MASK @ Build mask to isolate the interrupted mode
|
||||
AND r1, r1, r2 @ Isolate mode bits
|
||||
CMP r1, #IRQ_MODE_BITS @ Was an interrupt taken in IRQ mode before we
|
||||
@ got to context save? */
|
||||
BEQ __tx_thread_fiq_no_preempt_restore @ Yes, just go back to point of interrupt
|
||||
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1] @ Pickup actual current thread pointer
|
||||
CMP r0, #0 @ Is it NULL?
|
||||
BEQ __tx_thread_fiq_idle_system_restore @ Yes, idle system was interrupted
|
||||
|
||||
LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address
|
||||
LDR r2, [r3] @ Pickup actual preempt disable flag
|
||||
CMP r2, #0 @ Is it set?
|
||||
BNE __tx_thread_fiq_no_preempt_restore @ Yes, don't preempt this thread
|
||||
LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr
|
||||
LDR r2, [r3] @ Pickup actual execute thread pointer
|
||||
CMP r0, r2 @ Is the same thread highest priority?
|
||||
BNE __tx_thread_fiq_preempt_restore @ No, preemption needs to happen
|
||||
|
||||
|
||||
__tx_thread_fiq_no_preempt_restore:
|
||||
@
|
||||
@ /* Restore interrupted thread or ISR. */
|
||||
@
|
||||
@ /* Pickup the saved stack pointer. */
|
||||
@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
|
||||
@
|
||||
@ /* Recover the saved context and return to the point of interrupt. */
|
||||
@
|
||||
LDMIA sp!, {r0, lr} @ Recover SPSR, POI, and scratch regs
|
||||
MSR SPSR_cxsf, r0 @ Put SPSR back
|
||||
LDMIA sp!, {r0-r3} @ Recover r0-r3
|
||||
MOVS pc, lr @ Return to point of interrupt
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
__tx_thread_fiq_preempt_restore:
|
||||
@
|
||||
LDMIA sp!, {r3, lr} @ Recover temporarily saved registers
|
||||
MOV r1, lr @ Save lr (point of interrupt)
|
||||
MOV r2, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r2 @ Enter SVC mode
|
||||
STR r1, [sp, #-4]! @ Save point of interrupt
|
||||
STMDB sp!, {r4-r12, lr} @ Save upper half of registers
|
||||
MOV r4, r3 @ Save SPSR in r4
|
||||
MOV r2, #FIQ_MODE @ Build FIQ mode CPSR
|
||||
MSR CPSR_c, r2 @ Reenter FIQ mode
|
||||
LDMIA sp!, {r0-r3} @ Recover r0-r3
|
||||
MOV r5, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r5 @ Enter SVC mode
|
||||
STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1] @ Pickup current thread pointer
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
LDR r2, [r0, #144] @ Pickup the VFP enabled flag
|
||||
CMP r2, #0 @ Is the VFP enabled?
|
||||
BEQ _tx_skip_fiq_vfp_save @ No, skip VFP IRQ save
|
||||
VMRS r2, FPSCR @ Pickup the FPSCR
|
||||
STR r2, [sp, #-4]! @ Save FPSCR
|
||||
VSTMDB sp!, {D16-D31} @ Save D16-D31
|
||||
VSTMDB sp!, {D0-D15} @ Save D0-D15
|
||||
_tx_skip_fiq_vfp_save:
|
||||
#endif
|
||||
|
||||
MOV r3, #1 @ Build interrupt stack type
|
||||
STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR
|
||||
STR sp, [r0, #8] @ Save stack pointer in thread control
|
||||
@ block */
|
||||
@
|
||||
@ /* Save the remaining time-slice and disable it. */
|
||||
@ if (_tx_timer_time_slice)
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address
|
||||
LDR r2, [r3] @ Pickup time-slice
|
||||
CMP r2, #0 @ Is it active?
|
||||
BEQ __tx_thread_fiq_dont_save_ts @ No, don't save it
|
||||
@
|
||||
@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
@ _tx_timer_time_slice = 0;
|
||||
@
|
||||
STR r2, [r0, #24] @ Save thread's time-slice
|
||||
MOV r2, #0 @ Clear value
|
||||
STR r2, [r3] @ Disable global time-slice flag
|
||||
@
|
||||
@ }
|
||||
__tx_thread_fiq_dont_save_ts:
|
||||
@
|
||||
@
|
||||
@ /* Clear the current task pointer. */
|
||||
@ _tx_thread_current_ptr = TX_NULL;
|
||||
@
|
||||
MOV r0, #0 @ NULL value
|
||||
STR r0, [r1] @ Clear current thread pointer
|
||||
@
|
||||
@ /* Return to the scheduler. */
|
||||
@ _tx_thread_schedule();
|
||||
@
|
||||
B _tx_thread_schedule @ Return to scheduler
|
||||
@ }
|
||||
@
|
||||
__tx_thread_fiq_idle_system_restore:
|
||||
@
|
||||
@ /* Just return back to the scheduler! */
|
||||
@
|
||||
ADD sp, sp, #24 @ Recover FIQ stack space
|
||||
MOV r3, #SVC_MODE @ Build SVC mode CPSR
|
||||
MSR CPSR_c, r3 @ Lockout interrupts
|
||||
B _tx_thread_schedule @ Return to scheduler
|
||||
@
|
||||
@}
|
||||
|
||||
203
ports/cortex_a9/ac6/src/tx_thread_fiq_context_save.S
Normal file
203
ports/cortex_a9/ac6/src/tx_thread_fiq_context_save.S
Normal file
@@ -0,0 +1,203 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
.global __tx_fiq_processing_return
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_context_save Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function saves the context of an executing thread in the */
|
||||
@/* beginning of interrupt processing. The function also ensures that */
|
||||
@/* the system stack is used upon return to the calling ISR. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@ VOID _tx_thread_fiq_context_save(VOID)
|
||||
@{
|
||||
.global _tx_thread_fiq_context_save
|
||||
.type _tx_thread_fiq_context_save,function
|
||||
_tx_thread_fiq_context_save:
|
||||
@
|
||||
@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
|
||||
@ out, we are in IRQ mode, and all registers are intact. */
|
||||
@
|
||||
@ /* Check for a nested interrupt condition. */
|
||||
@ if (_tx_thread_system_state++)
|
||||
@ {
|
||||
@
|
||||
STMDB sp!, {r0-r3} @ Save some working registers
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
LDR r2, [r3] @ Pickup system state
|
||||
CMP r2, #0 @ Is this the first interrupt?
|
||||
BEQ __tx_thread_fiq_not_nested_save @ Yes, not a nested context save
|
||||
@
|
||||
@ /* Nested interrupt condition. */
|
||||
@
|
||||
ADD r2, r2, #1 @ Increment the interrupt counter
|
||||
STR r2, [r3] @ Store it back in the variable
|
||||
@
|
||||
@ /* Save the rest of the scratch registers on the stack and return to the
|
||||
@ calling ISR. */
|
||||
@
|
||||
MRS r0, SPSR @ Pickup saved SPSR
|
||||
SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
STMDB sp!, {r0, r10, r12, lr} @ Store other registers
|
||||
@
|
||||
@ /* Return to the ISR. */
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
B __tx_fiq_processing_return @ Continue FIQ processing
|
||||
@
|
||||
__tx_thread_fiq_not_nested_save:
|
||||
@ }
|
||||
@
|
||||
@ /* Otherwise, not nested, check to see if a thread was running. */
|
||||
@ else if (_tx_thread_current_ptr)
|
||||
@ {
|
||||
@
|
||||
ADD r2, r2, #1 @ Increment the interrupt counter
|
||||
STR r2, [r3] @ Store it back in the variable
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1] @ Pickup current thread pointer
|
||||
CMP r0, #0 @ Is it NULL?
|
||||
BEQ __tx_thread_fiq_idle_system_save @ If so, interrupt occurred in
|
||||
@ @ scheduling loop - nothing needs saving!
|
||||
@
|
||||
@ /* Save minimal context of interrupted thread. */
|
||||
@
|
||||
MRS r2, SPSR @ Pickup saved SPSR
|
||||
SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
STMDB sp!, {r2, lr} @ Store other registers, Note that we don't
|
||||
@ @ need to save sl and ip since FIQ has
|
||||
@ @ copies of these registers. Nested
|
||||
@ @ interrupt processing does need to save
|
||||
@ @ these registers.
|
||||
@
|
||||
@ /* Save the current stack pointer in the thread's control block. */
|
||||
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
|
||||
@
|
||||
@ /* Switch to the system stack. */
|
||||
@ sp = _tx_thread_system_stack_ptr;
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
B __tx_fiq_processing_return @ Continue FIQ processing
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
@
|
||||
__tx_thread_fiq_idle_system_save:
|
||||
@
|
||||
@ /* Interrupt occurred in the scheduling loop. */
|
||||
@
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
@
|
||||
@ /* Not much to do here, save the current SPSR and LR for possible
|
||||
@ use in IRQ interrupted in idle system conditions, and return to
|
||||
@ FIQ interrupt processing. */
|
||||
@
|
||||
MRS r0, SPSR @ Pickup saved SPSR
|
||||
SUB lr, lr, #4 @ Adjust point of interrupt
|
||||
STMDB sp!, {r0, lr} @ Store other registers that will get used
|
||||
@ @ or stripped off the stack in context
|
||||
@ @ restore
|
||||
B __tx_fiq_processing_return @ Continue FIQ processing
|
||||
@
|
||||
@ }
|
||||
@}
|
||||
|
||||
116
ports/cortex_a9/ac6/src/tx_thread_fiq_nesting_end.S
Normal file
116
ports/cortex_a9/ac6/src/tx_thread_fiq_nesting_end.S
Normal file
@@ -0,0 +1,116 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
DISABLE_INTS = 0x80 @ Disable IRQ interrupts
|
||||
#endif
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
FIQ_MODE_BITS = 0x11 @ FIQ mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_nesting_end Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is called by the application from FIQ mode after */
|
||||
@/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */
|
||||
@/* processing from system mode back to FIQ mode prior to the ISR */
|
||||
@/* calling _tx_thread_fiq_context_restore. Note that this function */
|
||||
@/* assumes the system stack pointer is in the same position after */
|
||||
@/* nesting start function was called. */
|
||||
@/* */
|
||||
@/* This function assumes that the system mode stack pointer was setup */
|
||||
@/* during low-level initialization (tx_initialize_low_level.s). */
|
||||
@/* */
|
||||
@/* This function returns with FIQ interrupts disabled. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_fiq_nesting_end(VOID)
|
||||
@{
|
||||
.global _tx_thread_fiq_nesting_end
|
||||
.type _tx_thread_fiq_nesting_end,function
|
||||
_tx_thread_fiq_nesting_end:
|
||||
MOV r3,lr @ Save ISR return address
|
||||
MRS r0, CPSR @ Pickup the CPSR
|
||||
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
|
||||
MSR CPSR_c, r0 @ Disable interrupts
|
||||
LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
|
||||
@ 8-byte alignment logic)
|
||||
BIC r0, r0, #MODE_MASK @ Clear mode bits
|
||||
ORR r0, r0, #FIQ_MODE_BITS @ Build IRQ mode CPSR
|
||||
MSR CPSR_c, r0 @ Reenter IRQ mode
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
108
ports/cortex_a9/ac6/src/tx_thread_fiq_nesting_start.S
Normal file
108
ports/cortex_a9/ac6/src/tx_thread_fiq_nesting_start.S
Normal file
@@ -0,0 +1,108 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
FIQ_DISABLE = 0x40 @ FIQ disable bit
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
SYS_MODE_BITS = 0x1F @ System mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_fiq_nesting_start Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is called by the application from FIQ mode after */
|
||||
@/* _tx_thread_fiq_context_save has been called and switches the FIQ */
|
||||
@/* processing to the system mode so nested FIQ interrupt processing */
|
||||
@/* is possible (system mode has its own "lr" register). Note that */
|
||||
@/* this function assumes that the system mode stack pointer was setup */
|
||||
@/* during low-level initialization (tx_initialize_low_level.s). */
|
||||
@/* */
|
||||
@/* This function returns with FIQ interrupts enabled. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_fiq_nesting_start(VOID)
|
||||
@{
|
||||
.global _tx_thread_fiq_nesting_start
|
||||
.type _tx_thread_fiq_nesting_start,function
|
||||
_tx_thread_fiq_nesting_start:
|
||||
MOV r3,lr @ Save ISR return address
|
||||
MRS r0, CPSR @ Pickup the CPSR
|
||||
BIC r0, r0, #MODE_MASK @ Clear the mode bits
|
||||
ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR
|
||||
MSR CPSR_c, r0 @ Enter system mode
|
||||
STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
|
||||
@ and push r1 just to keep 8-byte alignment
|
||||
BIC r0, r0, #FIQ_DISABLE @ Build enable FIQ CPSR
|
||||
MSR CPSR_c, r0 @ Enter system mode
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
115
ports/cortex_a9/ac6/src/tx_thread_interrupt_control.S
Normal file
115
ports/cortex_a9/ac6/src/tx_thread_interrupt_control.S
Normal file
@@ -0,0 +1,115 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h" */
|
||||
@
|
||||
|
||||
INT_MASK = 0x03F
|
||||
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_control
|
||||
$_tx_thread_interrupt_control:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_interrupt_control @ Call _tx_thread_interrupt_control function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_interrupt_control Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is responsible for changing the interrupt lockout */
|
||||
@/* posture of the system. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* new_posture New interrupt lockout posture */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* old_posture Old interrupt lockout posture */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* Application Code */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@UINT _tx_thread_interrupt_control(UINT new_posture)
|
||||
@{
|
||||
.global _tx_thread_interrupt_control
|
||||
.type _tx_thread_interrupt_control,function
|
||||
_tx_thread_interrupt_control:
|
||||
@
|
||||
@ /* Pickup current interrupt lockout posture. */
|
||||
@
|
||||
MRS r3, CPSR @ Pickup current CPSR
|
||||
MOV r2, #INT_MASK @ Build interrupt mask
|
||||
AND r1, r3, r2 @ Clear interrupt lockout bits
|
||||
ORR r1, r1, r0 @ Or-in new interrupt lockout bits
|
||||
@
|
||||
@ /* Apply the new interrupt posture. */
|
||||
@
|
||||
MSR CPSR_c, r1 @ Setup new CPSR
|
||||
BIC r0, r3, r2 @ Return previous interrupt mask
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
113
ports/cortex_a9/ac6/src/tx_thread_interrupt_disable.S
Normal file
113
ports/cortex_a9/ac6/src/tx_thread_interrupt_disable.S
Normal file
@@ -0,0 +1,113 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_disable
|
||||
$_tx_thread_interrupt_disable:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_interrupt_disable @ Call _tx_thread_interrupt_disable function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_interrupt_disable Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is responsible for disabling interrupts */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* old_posture Old interrupt lockout posture */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* Application Code */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@UINT _tx_thread_interrupt_disable(void)
|
||||
@{
|
||||
.global _tx_thread_interrupt_disable
|
||||
.type _tx_thread_interrupt_disable,function
|
||||
_tx_thread_interrupt_disable:
|
||||
@
|
||||
@ /* Pickup current interrupt lockout posture. */
|
||||
@
|
||||
MRS r0, CPSR @ Pickup current CPSR
|
||||
@
|
||||
@ /* Mask interrupts. */
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ
|
||||
#else
|
||||
CPSID i @ Disable IRQ
|
||||
#endif
|
||||
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
104
ports/cortex_a9/ac6/src/tx_thread_interrupt_restore.S
Normal file
104
ports/cortex_a9/ac6/src/tx_thread_interrupt_restore.S
Normal file
@@ -0,0 +1,104 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_interrupt_restore
|
||||
$_tx_thread_interrupt_restore:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_interrupt_restore @ Call _tx_thread_interrupt_restore function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_interrupt_restore Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is responsible for restoring interrupts to the state */
|
||||
@/* returned by a previous _tx_thread_interrupt_disable call. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* old_posture Old interrupt lockout posture */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* Application Code */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@UINT _tx_thread_interrupt_restore(UINT old_posture)
|
||||
@{
|
||||
.global _tx_thread_interrupt_restore
|
||||
.type _tx_thread_interrupt_restore,function
|
||||
_tx_thread_interrupt_restore:
|
||||
@
|
||||
@ /* Apply the new interrupt posture. */
|
||||
@
|
||||
MSR CPSR_c, r0 @ Setup new CPSR
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
115
ports/cortex_a9/ac6/src/tx_thread_irq_nesting_end.S
Normal file
115
ports/cortex_a9/ac6/src/tx_thread_irq_nesting_end.S
Normal file
@@ -0,0 +1,115 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
|
||||
#else
|
||||
DISABLE_INTS = 0x80 @ Disable IRQ interrupts
|
||||
#endif
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
IRQ_MODE_BITS = 0x12 @ IRQ mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_irq_nesting_end Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is called by the application from IRQ mode after */
|
||||
@/* _tx_thread_irq_nesting_start has been called and switches the IRQ */
|
||||
@/* processing from system mode back to IRQ mode prior to the ISR */
|
||||
@/* calling _tx_thread_context_restore. Note that this function */
|
||||
@/* assumes the system stack pointer is in the same position after */
|
||||
@/* nesting start function was called. */
|
||||
@/* */
|
||||
@/* This function assumes that the system mode stack pointer was setup */
|
||||
@/* during low-level initialization (tx_initialize_low_level.s). */
|
||||
@/* */
|
||||
@/* This function returns with IRQ interrupts disabled. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_irq_nesting_end(VOID)
|
||||
@{
|
||||
.global _tx_thread_irq_nesting_end
|
||||
.type _tx_thread_irq_nesting_end,function
|
||||
_tx_thread_irq_nesting_end:
|
||||
MOV r3,lr @ Save ISR return address
|
||||
MRS r0, CPSR @ Pickup the CPSR
|
||||
ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
|
||||
MSR CPSR_c, r0 @ Disable interrupts
|
||||
LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
|
||||
@ 8-byte alignment logic)
|
||||
BIC r0, r0, #MODE_MASK @ Clear mode bits
|
||||
ORR r0, r0, #IRQ_MODE_BITS @ Build IRQ mode CPSR
|
||||
MSR CPSR_c, r0 @ Reenter IRQ mode
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
108
ports/cortex_a9/ac6/src/tx_thread_irq_nesting_start.S
Normal file
108
ports/cortex_a9/ac6/src/tx_thread_irq_nesting_start.S
Normal file
@@ -0,0 +1,108 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
IRQ_DISABLE = 0x80 @ IRQ disable bit
|
||||
MODE_MASK = 0x1F @ Mode mask
|
||||
SYS_MODE_BITS = 0x1F @ System mode bits
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_irq_nesting_start Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is called by the application from IRQ mode after */
|
||||
@/* _tx_thread_context_save has been called and switches the IRQ */
|
||||
@/* processing to the system mode so nested IRQ interrupt processing */
|
||||
@/* is possible (system mode has its own "lr" register). Note that */
|
||||
@/* this function assumes that the system mode stack pointer was setup */
|
||||
@/* during low-level initialization (tx_initialize_low_level.s). */
|
||||
@/* */
|
||||
@/* This function returns with IRQ interrupts enabled. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_irq_nesting_start(VOID)
|
||||
@{
|
||||
.global _tx_thread_irq_nesting_start
|
||||
.type _tx_thread_irq_nesting_start,function
|
||||
_tx_thread_irq_nesting_start:
|
||||
MOV r3,lr @ Save ISR return address
|
||||
MRS r0, CPSR @ Pickup the CPSR
|
||||
BIC r0, r0, #MODE_MASK @ Clear the mode bits
|
||||
ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR
|
||||
MSR CPSR_c, r0 @ Enter system mode
|
||||
STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
|
||||
@ and push r1 just to keep 8-byte alignment
|
||||
BIC r0, r0, #IRQ_DISABLE @ Build enable IRQ CPSR
|
||||
MSR CPSR_c, r0 @ Enter system mode
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX r3 @ Return to caller
|
||||
#else
|
||||
MOV pc, r3 @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
254
ports/cortex_a9/ac6/src/tx_thread_schedule.S
Normal file
254
ports/cortex_a9/ac6/src/tx_thread_schedule.S
Normal file
@@ -0,0 +1,254 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
@
|
||||
.global _tx_thread_execute_ptr
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_schedule
|
||||
.type $_tx_thread_schedule,function
|
||||
$_tx_thread_schedule:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_schedule @ Call _tx_thread_schedule function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_schedule Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function waits for a thread control block pointer to appear in */
|
||||
@/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
|
||||
@/* in the variable, the corresponding thread is resumed. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
@/* _tx_thread_system_return Return to system from thread */
|
||||
@/* _tx_thread_context_restore Restore thread's context */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_schedule(VOID)
|
||||
@{
|
||||
.global _tx_thread_schedule
|
||||
.type _tx_thread_schedule,function
|
||||
_tx_thread_schedule:
|
||||
@
|
||||
@ /* Enable interrupts. */
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSIE if @ Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSIE i @ Enable IRQ interrupts
|
||||
#endif
|
||||
@
|
||||
@ /* Wait for a thread to execute. */
|
||||
@ do
|
||||
@ {
|
||||
LDR r1, =_tx_thread_execute_ptr @ Address of thread execute ptr
|
||||
@
|
||||
__tx_thread_schedule_loop:
|
||||
@
|
||||
LDR r0, [r1] @ Pickup next thread to execute
|
||||
CMP r0, #0 @ Is it NULL?
|
||||
BEQ __tx_thread_schedule_loop @ If so, keep looking for a thread
|
||||
@
|
||||
@ }
|
||||
@ while(_tx_thread_execute_ptr == TX_NULL);
|
||||
@
|
||||
@ /* Yes! We have a thread to execute. Lockout interrupts and
|
||||
@ transfer control to it. */
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Disable IRQ interrupts
|
||||
#endif
|
||||
@
|
||||
@ /* Setup the current thread pointer. */
|
||||
@ _tx_thread_current_ptr = _tx_thread_execute_ptr;
|
||||
@
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread
|
||||
STR r0, [r1] @ Setup current thread pointer
|
||||
@
|
||||
@ /* Increment the run count for this thread. */
|
||||
@ _tx_thread_current_ptr -> tx_thread_run_count++;
|
||||
@
|
||||
LDR r2, [r0, #4] @ Pickup run counter
|
||||
LDR r3, [r0, #24] @ Pickup time-slice for this thread
|
||||
ADD r2, r2, #1 @ Increment thread run-counter
|
||||
STR r2, [r0, #4] @ Store the new run counter
|
||||
@
|
||||
@ /* Setup time-slice, if present. */
|
||||
@ _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
|
||||
@
|
||||
LDR r2, =_tx_timer_time_slice @ Pickup address of time-slice
|
||||
@ variable
|
||||
LDR sp, [r0, #8] @ Switch stack pointers
|
||||
STR r3, [r2] @ Setup time-slice
|
||||
@
|
||||
@ /* Switch to the thread's stack. */
|
||||
@ sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
|
||||
@
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the thread entry function to indicate the thread is executing. */
|
||||
@
|
||||
MOV r5, r0 @ Save r0
|
||||
BL _tx_execution_thread_enter @ Call the thread execution enter function
|
||||
MOV r0, r5 @ Restore r0
|
||||
#endif
|
||||
@
|
||||
@ /* Determine if an interrupt frame or a synchronous task suspension frame
|
||||
@ is present. */
|
||||
@
|
||||
LDMIA sp!, {r4, r5} @ Pickup the stack type and saved CPSR
|
||||
CMP r4, #0 @ Check for synchronous context switch
|
||||
BEQ _tx_solicited_return
|
||||
MSR SPSR_cxsf, r5 @ Setup SPSR for return
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
LDR r1, [r0, #144] @ Pickup the VFP enabled flag
|
||||
CMP r1, #0 @ Is the VFP enabled?
|
||||
BEQ _tx_skip_interrupt_vfp_restore @ No, skip VFP interrupt restore
|
||||
VLDMIA sp!, {D0-D15} @ Recover D0-D15
|
||||
VLDMIA sp!, {D16-D31} @ Recover D16-D31
|
||||
LDR r4, [sp], #4 @ Pickup FPSCR
|
||||
VMSR FPSCR, r4 @ Restore FPSCR
|
||||
_tx_skip_interrupt_vfp_restore:
|
||||
#endif
|
||||
LDMIA sp!, {r0-r12, lr, pc}^ @ Return to point of thread interrupt
|
||||
|
||||
_tx_solicited_return:
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
LDR r1, [r0, #144] @ Pickup the VFP enabled flag
|
||||
CMP r1, #0 @ Is the VFP enabled?
|
||||
BEQ _tx_skip_solicited_vfp_restore @ No, skip VFP solicited restore
|
||||
VLDMIA sp!, {D8-D15} @ Recover D8-D15
|
||||
VLDMIA sp!, {D16-D31} @ Recover D16-D31
|
||||
LDR r4, [sp], #4 @ Pickup FPSCR
|
||||
VMSR FPSCR, r4 @ Restore FPSCR
|
||||
_tx_skip_solicited_vfp_restore:
|
||||
#endif
|
||||
MSR CPSR_cxsf, r5 @ Recover CPSR
|
||||
LDMIA sp!, {r4-r11, lr} @ Return to thread synchronously
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@
|
||||
@}
|
||||
@
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
|
||||
.global tx_thread_vfp_enable
|
||||
.type tx_thread_vfp_enable,function
|
||||
tx_thread_vfp_enable:
|
||||
MRS r2, CPSR @ Pickup the CPSR
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Enable IRQ interrupts
|
||||
#endif
|
||||
LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address
|
||||
LDR r1, [r0] @ Pickup current thread pointer
|
||||
CMP r1, #0 @ Check for NULL thread pointer
|
||||
BEQ __tx_no_thread_to_enable @ If NULL, skip VFP enable
|
||||
MOV r0, #1 @ Build enable value
|
||||
STR r0, [r1, #144] @ Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
|
||||
__tx_no_thread_to_enable:
|
||||
MSR CPSR_cxsf, r2 @ Recover CPSR
|
||||
BX LR @ Return to caller
|
||||
|
||||
.global tx_thread_vfp_disable
|
||||
.type tx_thread_vfp_disable,function
|
||||
tx_thread_vfp_disable:
|
||||
MRS r2, CPSR @ Pickup the CPSR
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Enable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Enable IRQ interrupts
|
||||
#endif
|
||||
LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address
|
||||
LDR r1, [r0] @ Pickup current thread pointer
|
||||
CMP r1, #0 @ Check for NULL thread pointer
|
||||
BEQ __tx_no_thread_to_disable @ If NULL, skip VFP disable
|
||||
MOV r0, #0 @ Build disable value
|
||||
STR r0, [r1, #144] @ Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
|
||||
__tx_no_thread_to_disable:
|
||||
MSR CPSR_cxsf, r2 @ Recover CPSR
|
||||
BX LR @ Return to caller
|
||||
|
||||
#endif
|
||||
|
||||
178
ports/cortex_a9/ac6/src/tx_thread_stack_build.S
Normal file
178
ports/cortex_a9/ac6/src/tx_thread_stack_build.S
Normal file
@@ -0,0 +1,178 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
.arm
|
||||
|
||||
SVC_MODE = 0x13 @ SVC mode
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled
|
||||
#else
|
||||
CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled
|
||||
#endif
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.global $_tx_thread_stack_build
|
||||
.type $_tx_thread_stack_build,function
|
||||
$_tx_thread_stack_build:
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_stack_build @ Call _tx_thread_stack_build function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_stack_build Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function builds a stack frame on the supplied thread's stack. */
|
||||
@/* The stack frame results in a fake interrupt return to the supplied */
|
||||
@/* function pointer. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* thread_ptr Pointer to thread control blk */
|
||||
@/* function_ptr Pointer to return function */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* _tx_thread_create Create thread service */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
|
||||
@{
|
||||
.global _tx_thread_stack_build
|
||||
.type _tx_thread_stack_build,function
|
||||
_tx_thread_stack_build:
|
||||
@
|
||||
@
|
||||
@ /* Build a fake interrupt frame. The form of the fake interrupt stack
|
||||
@ on the Cortex-A9 should look like the following after it is built:
|
||||
@
|
||||
@ Stack Top: 1 Interrupt stack frame type
|
||||
@ CPSR Initial value for CPSR
|
||||
@ a1 (r0) Initial value for a1
|
||||
@ a2 (r1) Initial value for a2
|
||||
@ a3 (r2) Initial value for a3
|
||||
@ a4 (r3) Initial value for a4
|
||||
@ v1 (r4) Initial value for v1
|
||||
@ v2 (r5) Initial value for v2
|
||||
@ v3 (r6) Initial value for v3
|
||||
@ v4 (r7) Initial value for v4
|
||||
@ v5 (r8) Initial value for v5
|
||||
@ sb (r9) Initial value for sb
|
||||
@ sl (r10) Initial value for sl
|
||||
@ fp (r11) Initial value for fp
|
||||
@ ip (r12) Initial value for ip
|
||||
@ lr (r14) Initial value for lr
|
||||
@ pc (r15) Initial value for pc
|
||||
@ 0 For stack backtracing
|
||||
@
|
||||
@ Stack Bottom: (higher memory address) */
|
||||
@
|
||||
LDR r2, [r0, #16] @ Pickup end of stack area
|
||||
BIC r2, r2, #7 @ Ensure 8-byte alignment
|
||||
SUB r2, r2, #76 @ Allocate space for the stack frame
|
||||
@
|
||||
@ /* Actually build the stack frame. */
|
||||
@
|
||||
MOV r3, #1 @ Build interrupt stack type
|
||||
STR r3, [r2, #0] @ Store stack type
|
||||
MOV r3, #0 @ Build initial register value
|
||||
STR r3, [r2, #8] @ Store initial r0
|
||||
STR r3, [r2, #12] @ Store initial r1
|
||||
STR r3, [r2, #16] @ Store initial r2
|
||||
STR r3, [r2, #20] @ Store initial r3
|
||||
STR r3, [r2, #24] @ Store initial r4
|
||||
STR r3, [r2, #28] @ Store initial r5
|
||||
STR r3, [r2, #32] @ Store initial r6
|
||||
STR r3, [r2, #36] @ Store initial r7
|
||||
STR r3, [r2, #40] @ Store initial r8
|
||||
STR r3, [r2, #44] @ Store initial r9
|
||||
LDR r3, [r0, #12] @ Pickup stack starting address
|
||||
STR r3, [r2, #48] @ Store initial r10 (sl)
|
||||
LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace
|
||||
STR r3, [r2, #60] @ Store initial r14 (lr)
|
||||
MOV r3, #0 @ Build initial register value
|
||||
STR r3, [r2, #52] @ Store initial r11
|
||||
STR r3, [r2, #56] @ Store initial r12
|
||||
STR r1, [r2, #64] @ Store initial pc
|
||||
STR r3, [r2, #68] @ 0 for back-trace
|
||||
MRS r1, CPSR @ Pickup CPSR
|
||||
BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR
|
||||
ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled
|
||||
STR r3, [r2, #4] @ Store initial CPSR
|
||||
@
|
||||
@ /* Setup stack pointer. */
|
||||
@ thread_ptr -> tx_thread_stack_ptr = r2;
|
||||
@
|
||||
STR r2, [r0, #8] @ Save stack pointer in thread's
|
||||
@ control block
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
||||
179
ports/cortex_a9/ac6/src/tx_thread_system_return.S
Normal file
179
ports/cortex_a9/ac6/src/tx_thread_system_return.S
Normal file
@@ -0,0 +1,179 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@#include "tx_timer.h"
|
||||
@
|
||||
.arm
|
||||
@
|
||||
@
|
||||
.global _tx_thread_current_ptr
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_thread_schedule
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.global $_tx_thread_system_return
|
||||
.type $_tx_thread_system_return,function
|
||||
$_tx_thread_system_return:
|
||||
.thumb
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_thread_system_return @ Call _tx_thread_system_return function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_system_return Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function is target processor specific. It is used to transfer */
|
||||
@/* control from a thread back to the ThreadX system. Only a */
|
||||
@/* minimal context is saved since the compiler assumes temp registers */
|
||||
@/* are going to get slicked by a function call anyway. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* _tx_thread_schedule Thread scheduling loop */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ThreadX components */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_system_return(VOID)
|
||||
@{
|
||||
.global _tx_thread_system_return
|
||||
.type _tx_thread_system_return,function
|
||||
_tx_thread_system_return:
|
||||
@
|
||||
@ /* Save minimal context on the stack. */
|
||||
@
|
||||
STMDB sp!, {r4-r11, lr} @ Save minimal context
|
||||
|
||||
LDR r4, =_tx_thread_current_ptr @ Pickup address of current ptr
|
||||
LDR r5, [r4] @ Pickup current thread pointer
|
||||
|
||||
#ifdef TX_ENABLE_VFP_SUPPORT
|
||||
LDR r1, [r5, #144] @ Pickup the VFP enabled flag
|
||||
CMP r1, #0 @ Is the VFP enabled?
|
||||
BEQ _tx_skip_solicited_vfp_save @ No, skip VFP solicited save
|
||||
VMRS r1, FPSCR @ Pickup the FPSCR
|
||||
STR r1, [sp, #-4]! @ Save FPSCR
|
||||
VSTMDB sp!, {D16-D31} @ Save D16-D31
|
||||
VSTMDB sp!, {D8-D15} @ Save D8-D15
|
||||
_tx_skip_solicited_vfp_save:
|
||||
#endif
|
||||
|
||||
MOV r0, #0 @ Build a solicited stack type
|
||||
MRS r1, CPSR @ Pickup the CPSR
|
||||
STMDB sp!, {r0-r1} @ Save type and CPSR
|
||||
@
|
||||
@ /* Lockout interrupts. */
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
#else
|
||||
CPSID i @ Disable IRQ interrupts
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the thread exit function to indicate the thread is no longer executing. */
|
||||
@
|
||||
BL _tx_execution_thread_exit @ Call the thread exit function
|
||||
#endif
|
||||
MOV r3, r4 @ Pickup address of current ptr
|
||||
MOV r0, r5 @ Pickup current thread pointer
|
||||
LDR r2, =_tx_timer_time_slice @ Pickup address of time slice
|
||||
LDR r1, [r2] @ Pickup current time slice
|
||||
@
|
||||
@ /* Save current stack and switch to system stack. */
|
||||
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
|
||||
@ sp = _tx_thread_system_stack_ptr;
|
||||
@
|
||||
STR sp, [r0, #8] @ Save thread stack pointer
|
||||
@
|
||||
@ /* Determine if the time-slice is active. */
|
||||
@ if (_tx_timer_time_slice)
|
||||
@ {
|
||||
@
|
||||
MOV r4, #0 @ Build clear value
|
||||
CMP r1, #0 @ Is a time-slice active?
|
||||
BEQ __tx_thread_dont_save_ts @ No, don't save the time-slice
|
||||
@
|
||||
@ /* Save time-slice for the thread and clear the current time-slice. */
|
||||
@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
@ _tx_timer_time_slice = 0;
|
||||
@
|
||||
STR r4, [r2] @ Clear time-slice
|
||||
STR r1, [r0, #24] @ Save current time-slice
|
||||
@
|
||||
@ }
|
||||
__tx_thread_dont_save_ts:
|
||||
@
|
||||
@ /* Clear the current thread pointer. */
|
||||
@ _tx_thread_current_ptr = TX_NULL;
|
||||
@
|
||||
STR r4, [r3] @ Clear current thread pointer
|
||||
B _tx_thread_schedule @ Jump to scheduler!
|
||||
@
|
||||
@}
|
||||
|
||||
189
ports/cortex_a9/ac6/src/tx_thread_vectored_context_save.S
Normal file
189
ports/cortex_a9/ac6/src/tx_thread_vectored_context_save.S
Normal file
@@ -0,0 +1,189 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Thread */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
.global _tx_thread_system_state
|
||||
.global _tx_thread_current_ptr
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
|
||||
@ since it will never be called 16-bit mode. */
|
||||
@
|
||||
.arm
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_thread_vectored_context_save Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function saves the context of an executing thread in the */
|
||||
@/* beginning of interrupt processing. The function also ensures that */
|
||||
@/* the system stack is used upon return to the calling ISR. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* ISRs */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_thread_vectored_context_save(VOID)
|
||||
@{
|
||||
.global _tx_thread_vectored_context_save
|
||||
.type _tx_thread_vectored_context_save,function
|
||||
_tx_thread_vectored_context_save:
|
||||
@
|
||||
@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
|
||||
@ out, we are in IRQ mode, and all registers are intact. */
|
||||
@
|
||||
@ /* Check for a nested interrupt condition. */
|
||||
@ if (_tx_thread_system_state++)
|
||||
@ {
|
||||
@
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if @ Disable IRQ and FIQ interrupts
|
||||
#endif
|
||||
LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
|
||||
LDR r2, [r3, #0] @ Pickup system state
|
||||
CMP r2, #0 @ Is this the first interrupt?
|
||||
BEQ __tx_thread_not_nested_save @ Yes, not a nested context save
|
||||
@
|
||||
@ /* Nested interrupt condition. */
|
||||
@
|
||||
ADD r2, r2, #1 @ Increment the interrupt counter
|
||||
STR r2, [r3, #0] @ Store it back in the variable
|
||||
@
|
||||
@ /* Note: Minimal context of interrupted thread is already saved. */
|
||||
@
|
||||
@ /* Return to the ISR. */
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
MOV pc, lr @ Return to caller
|
||||
@
|
||||
__tx_thread_not_nested_save:
|
||||
@ }
|
||||
@
|
||||
@ /* Otherwise, not nested, check to see if a thread was running. */
|
||||
@ else if (_tx_thread_current_ptr)
|
||||
@ {
|
||||
@
|
||||
ADD r2, r2, #1 @ Increment the interrupt counter
|
||||
STR r2, [r3, #0] @ Store it back in the variable
|
||||
LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
|
||||
LDR r0, [r1, #0] @ Pickup current thread pointer
|
||||
CMP r0, #0 @ Is it NULL?
|
||||
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
|
||||
@ scheduling loop - nothing needs saving!
|
||||
@
|
||||
@ /* Note: Minimal context of interrupted thread is already saved. */
|
||||
@
|
||||
@ /* Save the current stack pointer in the thread's control block. */
|
||||
@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
|
||||
@
|
||||
@ /* Switch to the system stack. */
|
||||
@ sp = _tx_thread_system_stack_ptr;
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
MOV pc, lr @ Return to caller
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
@
|
||||
__tx_thread_idle_system_save:
|
||||
@
|
||||
@ /* Interrupt occurred in the scheduling loop. */
|
||||
@
|
||||
@ /* Not much to do here, just adjust the stack pointer, and return to IRQ
|
||||
@ processing. */
|
||||
@
|
||||
MOV r10, #0 @ Clear stack limit
|
||||
|
||||
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
@
|
||||
@ /* Call the ISR enter function to indicate an ISR is executing. */
|
||||
@
|
||||
PUSH {lr} @ Save ISR lr
|
||||
BL _tx_execution_isr_enter @ Call the ISR enter function
|
||||
POP {lr} @ Recover ISR lr
|
||||
#endif
|
||||
|
||||
ADD sp, sp, #32 @ Recover saved registers
|
||||
MOV pc, lr @ Return to caller
|
||||
@
|
||||
@ }
|
||||
@}
|
||||
|
||||
279
ports/cortex_a9/ac6/src/tx_timer_interrupt.S
Normal file
279
ports/cortex_a9/ac6/src/tx_timer_interrupt.S
Normal file
@@ -0,0 +1,279 @@
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
@/* */
|
||||
@/* This software is licensed under the Microsoft Software License */
|
||||
@/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
@/* and in the root directory of this software. */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@/** */
|
||||
@/** ThreadX Component */
|
||||
@/** */
|
||||
@/** Timer */
|
||||
@/** */
|
||||
@/**************************************************************************/
|
||||
@/**************************************************************************/
|
||||
@
|
||||
@#define TX_SOURCE_CODE
|
||||
@
|
||||
@
|
||||
@/* Include necessary system files. */
|
||||
@
|
||||
@#include "tx_api.h"
|
||||
@#include "tx_timer.h"
|
||||
@#include "tx_thread.h"
|
||||
@
|
||||
@
|
||||
.arm
|
||||
|
||||
@
|
||||
@/* Define Assembly language external references... */
|
||||
@
|
||||
.global _tx_timer_time_slice
|
||||
.global _tx_timer_system_clock
|
||||
.global _tx_timer_current_ptr
|
||||
.global _tx_timer_list_start
|
||||
.global _tx_timer_list_end
|
||||
.global _tx_timer_expired_time_slice
|
||||
.global _tx_timer_expired
|
||||
.global _tx_thread_time_slice
|
||||
@
|
||||
@
|
||||
@
|
||||
@/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for
|
||||
@ applications calling this function from to 16-bit Thumb mode. */
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.global $_tx_timer_interrupt
|
||||
.type $_tx_timer_interrupt,function
|
||||
$_tx_timer_interrupt:
|
||||
BX pc @ Switch to 32-bit mode
|
||||
NOP @
|
||||
.arm
|
||||
STMFD sp!, {lr} @ Save return address
|
||||
BL _tx_timer_interrupt @ Call _tx_timer_interrupt function
|
||||
LDMFD sp!, {lr} @ Recover saved return address
|
||||
BX lr @ Return to 16-bit caller
|
||||
@
|
||||
@
|
||||
.text
|
||||
.align 2
|
||||
@/**************************************************************************/
|
||||
@/* */
|
||||
@/* FUNCTION RELEASE */
|
||||
@/* */
|
||||
@/* _tx_timer_interrupt Cortex-A9/AC6 */
|
||||
@/* 6.0.1 */
|
||||
@/* AUTHOR */
|
||||
@/* */
|
||||
@/* William E. Lamie, Microsoft Corporation */
|
||||
@/* */
|
||||
@/* DESCRIPTION */
|
||||
@/* */
|
||||
@/* This function processes the hardware timer interrupt. This */
|
||||
@/* processing includes incrementing the system clock and checking for */
|
||||
@/* time slice and/or timer expiration. If either is found, the */
|
||||
@/* interrupt context save/restore functions are called along with the */
|
||||
@/* expiration functions. */
|
||||
@/* */
|
||||
@/* INPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* OUTPUT */
|
||||
@/* */
|
||||
@/* None */
|
||||
@/* */
|
||||
@/* CALLS */
|
||||
@/* */
|
||||
@/* _tx_thread_time_slice Time slice interrupted thread */
|
||||
@/* _tx_timer_expiration_process Timer expiration processing */
|
||||
@/* */
|
||||
@/* CALLED BY */
|
||||
@/* */
|
||||
@/* interrupt vector */
|
||||
@/* */
|
||||
@/* RELEASE HISTORY */
|
||||
@/* */
|
||||
@/* DATE NAME DESCRIPTION */
|
||||
@/* */
|
||||
@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
@/* */
|
||||
@/**************************************************************************/
|
||||
@VOID _tx_timer_interrupt(VOID)
|
||||
@{
|
||||
.global _tx_timer_interrupt
|
||||
.type _tx_timer_interrupt,function
|
||||
_tx_timer_interrupt:
|
||||
@
|
||||
@ /* Upon entry to this routine, it is assumed that context save has already
|
||||
@ been called, and therefore the compiler scratch registers are available
|
||||
@ for use. */
|
||||
@
|
||||
@ /* Increment the system clock. */
|
||||
@ _tx_timer_system_clock++;
|
||||
@
|
||||
LDR r1, =_tx_timer_system_clock @ Pickup address of system clock
|
||||
LDR r0, [r1] @ Pickup system clock
|
||||
ADD r0, r0, #1 @ Increment system clock
|
||||
STR r0, [r1] @ Store new system clock
|
||||
@
|
||||
@ /* Test for time-slice expiration. */
|
||||
@ if (_tx_timer_time_slice)
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice
|
||||
LDR r2, [r3] @ Pickup time-slice
|
||||
CMP r2, #0 @ Is it non-active?
|
||||
BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing
|
||||
@
|
||||
@ /* Decrement the time_slice. */
|
||||
@ _tx_timer_time_slice--;
|
||||
@
|
||||
SUB r2, r2, #1 @ Decrement the time-slice
|
||||
STR r2, [r3] @ Store new time-slice value
|
||||
@
|
||||
@ /* Check for expiration. */
|
||||
@ if (__tx_timer_time_slice == 0)
|
||||
@
|
||||
CMP r2, #0 @ Has it expired?
|
||||
BNE __tx_timer_no_time_slice @ No, skip expiration processing
|
||||
@
|
||||
@ /* Set the time-slice expired flag. */
|
||||
@ _tx_timer_expired_time_slice = TX_TRUE;
|
||||
@
|
||||
LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag
|
||||
MOV r0, #1 @ Build expired value
|
||||
STR r0, [r3] @ Set time-slice expiration flag
|
||||
@
|
||||
@ }
|
||||
@
|
||||
__tx_timer_no_time_slice:
|
||||
@
|
||||
@ /* Test for timer expiration. */
|
||||
@ if (*_tx_timer_current_ptr)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address
|
||||
LDR r0, [r1] @ Pickup current timer
|
||||
LDR r2, [r0] @ Pickup timer list entry
|
||||
CMP r2, #0 @ Is there anything in the list?
|
||||
BEQ __tx_timer_no_timer @ No, just increment the timer
|
||||
@
|
||||
@ /* Set expiration flag. */
|
||||
@ _tx_timer_expired = TX_TRUE;
|
||||
@
|
||||
LDR r3, =_tx_timer_expired @ Pickup expiration flag address
|
||||
MOV r2, #1 @ Build expired value
|
||||
STR r2, [r3] @ Set expired flag
|
||||
B __tx_timer_done @ Finished timer processing
|
||||
@
|
||||
@ }
|
||||
@ else
|
||||
@ {
|
||||
__tx_timer_no_timer:
|
||||
@
|
||||
@ /* No timer expired, increment the timer pointer. */
|
||||
@ _tx_timer_current_ptr++;
|
||||
@
|
||||
ADD r0, r0, #4 @ Move to next timer
|
||||
@
|
||||
@ /* Check for wraparound. */
|
||||
@ if (_tx_timer_current_ptr == _tx_timer_list_end)
|
||||
@
|
||||
LDR r3, =_tx_timer_list_end @ Pickup address of timer list end
|
||||
LDR r2, [r3] @ Pickup list end
|
||||
CMP r0, r2 @ Are we at list end?
|
||||
BNE __tx_timer_skip_wrap @ No, skip wraparound logic
|
||||
@
|
||||
@ /* Wrap to beginning of list. */
|
||||
@ _tx_timer_current_ptr = _tx_timer_list_start;
|
||||
@
|
||||
LDR r3, =_tx_timer_list_start @ Pickup address of timer list start
|
||||
LDR r0, [r3] @ Set current pointer to list start
|
||||
@
|
||||
__tx_timer_skip_wrap:
|
||||
@
|
||||
STR r0, [r1] @ Store new current timer pointer
|
||||
@ }
|
||||
@
|
||||
__tx_timer_done:
|
||||
@
|
||||
@
|
||||
@ /* See if anything has expired. */
|
||||
@ if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag
|
||||
LDR r2, [r3] @ Pickup time-slice expired flag
|
||||
CMP r2, #0 @ Did a time-slice expire?
|
||||
BNE __tx_something_expired @ If non-zero, time-slice expired
|
||||
LDR r1, =_tx_timer_expired @ Pickup address of other expired flag
|
||||
LDR r0, [r1] @ Pickup timer expired flag
|
||||
CMP r0, #0 @ Did a timer expire?
|
||||
BEQ __tx_timer_nothing_expired @ No, nothing expired
|
||||
@
|
||||
__tx_something_expired:
|
||||
@
|
||||
@
|
||||
STMDB sp!, {r0, lr} @ Save the lr register on the stack
|
||||
@ and save r0 just to keep 8-byte alignment
|
||||
@
|
||||
@ /* Did a timer expire? */
|
||||
@ if (_tx_timer_expired)
|
||||
@ {
|
||||
@
|
||||
LDR r1, =_tx_timer_expired @ Pickup address of expired flag
|
||||
LDR r0, [r1] @ Pickup timer expired flag
|
||||
CMP r0, #0 @ Check for timer expiration
|
||||
BEQ __tx_timer_dont_activate @ If not set, skip timer activation
|
||||
@
|
||||
@ /* Process timer expiration. */
|
||||
@ _tx_timer_expiration_process();
|
||||
@
|
||||
BL _tx_timer_expiration_process @ Call the timer expiration handling routine
|
||||
@
|
||||
@ }
|
||||
__tx_timer_dont_activate:
|
||||
@
|
||||
@ /* Did time slice expire? */
|
||||
@ if (_tx_timer_expired_time_slice)
|
||||
@ {
|
||||
@
|
||||
LDR r3, =_tx_timer_expired_time_slice @ Pickup address of time-slice expired
|
||||
LDR r2, [r3] @ Pickup the actual flag
|
||||
CMP r2, #0 @ See if the flag is set
|
||||
BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing
|
||||
@
|
||||
@ /* Time slice interrupted thread. */
|
||||
@ _tx_thread_time_slice();
|
||||
@
|
||||
BL _tx_thread_time_slice @ Call time-slice processing
|
||||
@
|
||||
@ }
|
||||
@
|
||||
__tx_timer_not_ts_expiration:
|
||||
@
|
||||
LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for
|
||||
@ the 8-byte stack alignment
|
||||
@
|
||||
@ }
|
||||
@
|
||||
__tx_timer_nothing_expired:
|
||||
@
|
||||
#ifdef __THUMB_INTERWORK
|
||||
BX lr @ Return to caller
|
||||
#else
|
||||
MOV pc, lr @ Return to caller
|
||||
#endif
|
||||
@
|
||||
@}
|
||||
|
||||
Reference in New Issue
Block a user